CUBRID Engine  latest
object_primitive.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_primitive.c - This file contains code for handling the values of
21  * primitive types in memory and for conversion between
22  * the disk representation.
23  */
24 
25 #ident "$Id$"
26 
27 #include "config.h"
28 
29 
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 
34 #include "object_primitive.h"
35 
36 #include "area_alloc.h"
37 #include "db_value_printer.hpp"
38 #include "db_json.hpp"
39 #include "elo.h"
40 #include "error_manager.h"
41 #include "file_io.h"
42 #include "mem_block.hpp"
43 #include "object_domain.h"
44 #include "object_representation.h"
45 #include "set_object.h"
46 #include "string_buffer.hpp"
47 #include "string_opfunc.h"
48 #include "system_parameter.h"
49 #include "tz_support.h"
50 
51 #include <utility>
52 
53 #if !defined (SERVER_MODE)
54 #include "work_space.h"
55 #include "virtual_object.h"
56 #include "transform_cl.h"
57 #include "dbi.h"
58 #endif /* !defined (SERVER_MODE) */
59 
60 #include "dbtype.h"
62 
63 #if defined (SUPPRESS_STRLEN_WARNING)
64 #define strlen(s1) ((int) strlen(s1))
65 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
66 
67 #if !defined(SERVER_MODE)
68 extern unsigned int db_on_server;
69 #endif
70 
71 #define MR_CMP(d1, d2) \
72  ((d1) < (d2) ? DB_LT : (d1) > (d2) ? DB_GT : DB_EQ)
73 
74 #define MR_CMP_RETURN_CODE(c) \
75  ((c) < 0 ? DB_LT : (c) > 0 ? DB_GT : DB_EQ)
76 
77 /*
78  * MR_OID_SIZE
79  * Hack so we don't have to conditionalize the type vector.
80  * On the server we don't have the structure definition for this.
81  */
82 #if !defined (SERVER_MODE)
83 #define MR_OID_SIZE sizeof(WS_MEMOID)
84 #else
85 #define MR_OID_SIZE 0
86 #endif
87 
88 #define VALUE_AREA_COUNT 1024
89 
90 /*
91  * PR_OID_PROMOTION_DEFAULT
92  *
93  * It is intended to allow some control over whether or not OIDs read
94  * by "readval" are automatically promoted to MOPs or not. This
95  * is used to prevent cluttering up the workspace with MOPs when we
96  * don't really need them. When this is enabled, callers of "readval"
97  * had better be prepared to see DB_VALUE structures containing unswizzled
98  * OIDs rather than MOPs. Not intended for use by by real applications.
99  * Think about this more, this may also be the mechanism by which the server
100  * can control reading of object values.
101  *
102  * Note that this makes sense only for the "readval" function, the "readmem
103  * function must be building a workspace instance memory representation
104  * and oid promotion cannot be controlled there.
105  *
106  */
107 #if defined (SERVER_MODE)
108 #define PR_INHIBIT_OID_PROMOTION_DEFAULT 1
109 #else
110 #define PR_INHIBIT_OID_PROMOTION_DEFAULT 0
111 #endif
112 
113 /*
114  * These are currently fixed length widets of length DB_NUMERIC_BUF_SIZE.
115  * Ultimately they may be of variable size based on the precision and scale,
116  * in antipication of that move, use the followign function for copying.
117  */
118 #define OR_NUMERIC_SIZE(precision) DB_NUMERIC_BUF_SIZE
119 #define MR_NUMERIC_SIZE(precision) DB_NUMERIC_BUF_SIZE
120 
121 #define STR_SIZE(prec, codeset) \
122  (((codeset) == INTL_CODESET_RAW_BITS) ? ((prec+7)/8) : \
123  INTL_CODESET_MULT (codeset) * (prec))
124 
125 
126 #define BITS_IN_BYTE 8
127 #define BITS_TO_BYTES(bit_cnt) (((bit_cnt) + 7) / 8)
128 
129 /* left for future extension */
130 #define DO_CONVERSION_TO_SRVR_STR(codeset) false
131 #define DO_CONVERSION_TO_SQLTEXT(codeset) false
132 
133 #define DB_DOMAIN_INIT_CHAR(value, precision) \
134  do { \
135  (value)->domain.general_info.type = DB_TYPE_CHAR; \
136  (value)->domain.general_info.is_null = 1; \
137  (value)->domain.char_info.length = \
138  (precision) == DB_DEFAULT_PRECISION ? \
139  TP_FLOATING_PRECISION_VALUE : (precision); \
140  (value)->need_clear = false; \
141  (value)->data.ch.info.codeset = LANG_SYS_CODESET; \
142  (value)->domain.char_info.collation_id = LANG_SYS_COLLATION; \
143  } while (0)
144 
145 
146 #define IS_FLOATING_PRECISION(prec) \
147  ((prec) == TP_FLOATING_PRECISION_VALUE)
148 
149 // *INDENT-OFF*
150 pr_type::pr_type (const char * name_arg, DB_TYPE id_arg, int varp_arg, int size_arg, int disksize_arg, int align_arg,
151  initmem_function_type initmem_f_arg, initval_function_type initval_f_arg,
152  setmem_function_type setmem_f_arg, getmem_function_type getmem_f_arg,
153  setval_function_type setval_f_arg, data_lengthmem_function_type data_lengthmem_f_arg,
154  data_lengthval_function_type data_lengthval_f_arg, data_writemem_function_type data_writemem_f_arg,
155  data_readmem_function_type data_readmem_f_arg, data_writeval_function_type data_writeval_f_arg,
156  data_readval_function_type data_readval_f_arg, index_lengthmem_function_type index_lengthmem_f_arg,
157  index_lengthval_function_type index_lengthval_f_arg,
158  index_writeval_function_type index_writeval_f_arg, index_readval_function_type index_readval_f_arg,
159  index_cmpdisk_function_type index_cmpdisk_f_arg, freemem_function_type freemem_f_arg,
160  data_cmpdisk_function_type data_cmpdisk_f_arg, cmpval_function_type cmpval_f_arg)
161  : name {name_arg}
162  , id {id_arg}
163  , variable_p {varp_arg}
164  , size {size_arg}
165  , disksize {disksize_arg}
166  , alignment {align_arg}
167  , f_initmem {initmem_f_arg}
168  , f_initval {initval_f_arg}
169  , f_setmem {setmem_f_arg}
170  , f_getmem {getmem_f_arg}
171  , f_setval {setval_f_arg}
172  , f_data_lengthmem {data_lengthmem_f_arg}
173  , f_data_lengthval {data_lengthval_f_arg}
174  , f_data_writemem {data_writemem_f_arg}
175  , f_data_readmem {data_readmem_f_arg}
176  , f_data_writeval {data_writeval_f_arg}
177  , f_data_readval {data_readval_f_arg}
178  , f_index_lengthmem {index_lengthmem_f_arg}
179  , f_index_lengthval {index_lengthval_f_arg}
180  , f_index_writeval {index_writeval_f_arg}
181  , f_index_readval {index_readval_f_arg}
182  , f_index_cmpdisk {index_cmpdisk_f_arg}
183  , f_freemem {freemem_f_arg}
184  , f_data_cmpdisk {data_cmpdisk_f_arg}
185  , f_cmpval {cmpval_f_arg}
186  {
187  }
188 
189 void
191 {
192  f_data_cmpdisk = data_cmpdisk_arg;
193 }
194 
197 {
198  return f_data_cmpdisk;
199 }
200 
201 void
203 {
204  f_cmpval = cmpval_arg;
205 }
206 
209 {
210  return f_cmpval;
211 }
212 // *INDENT-ON*
213 
214 static void mr_initmem_string (void *mem, TP_DOMAIN * domain);
215 static int mr_setmem_string (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
216 static int mr_getmem_string (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
217 static int mr_data_lengthmem_string (void *memptr, TP_DOMAIN * domain, int disk);
218 static int mr_index_lengthmem_string (void *memptr, TP_DOMAIN * domain);
219 static void mr_data_writemem_string (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
220 static void mr_data_readmem_string (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
221 static void mr_freemem_string (void *memptr);
222 static void mr_initval_string (DB_VALUE * value, int precision, int scale);
223 static int mr_setval_string (DB_VALUE * dest, const DB_VALUE * src, bool copy);
224 static int mr_data_lengthval_string (DB_VALUE * value, int disk);
225 static int mr_data_writeval_string (OR_BUF * buf, DB_VALUE * value);
226 static int mr_data_readval_string (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
227  char *copy_buf, int copy_buf_len);
228 static int mr_index_lengthval_string (DB_VALUE * value);
229 static int mr_index_writeval_string (OR_BUF * buf, DB_VALUE * value);
230 static int mr_index_readval_string (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
231  char *copy_buf, int copy_buf_len);
232 static int mr_lengthval_string_internal (DB_VALUE * value, int disk, int align);
233 static int mr_writeval_string_internal (OR_BUF * buf, DB_VALUE * value, int align);
234 static int mr_readval_string_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
235  char *copy_buf, int copy_buf_len, int align);
236 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_string (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
237  int total_order, int *start_colp);
238 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_string (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
239  int total_order, int *start_colp);
240 static DB_VALUE_COMPARE_RESULT mr_cmpval_string (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
241  int total_order, int *start_colp, int collation);
242 #if defined (ENABLE_UNUSED_FUNCTION)
243 static int mr_cmpval_string2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order,
244  int *start_colp);
245 #endif
246 static void mr_initmem_char (void *memptr, TP_DOMAIN * domain);
247 static int mr_setmem_char (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
248 static int mr_getmem_char (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
249 static int mr_data_lengthmem_char (void *memptr, TP_DOMAIN * domain, int disk);
250 static int mr_index_lengthmem_char (void *memptr, TP_DOMAIN * domain);
251 static void mr_data_writemem_char (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
252 static void mr_data_readmem_char (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
253 static void mr_freemem_char (void *memptr);
254 static void mr_initval_char (DB_VALUE * value, int precision, int scale);
255 static int mr_setval_char (DB_VALUE * dest, const DB_VALUE * src, bool copy);
256 static int mr_data_lengthval_char (DB_VALUE * value, int disk);
257 static int mr_data_writeval_char (OR_BUF * buf, DB_VALUE * value);
258 static int mr_writeval_char_internal (OR_BUF * buf, DB_VALUE * value, int align);
259 static int mr_data_readval_char (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
260  char *copy_buf, int copy_buf_len);
261 static int mr_readval_char_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
262  char *copy_buf, int copy_buf_len, int align);
263 static int mr_index_lengthval_char (DB_VALUE * value);
264 static int mr_index_writeval_char (OR_BUF * buf, DB_VALUE * value);
265 static int mr_index_readval_char (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
266  char *copy_buf, int copy_buf_len);
267 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_char (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
268  int total_order, int *start_colp);
269 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_char (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
270  int total_order, int *start_colp);
271 static DB_VALUE_COMPARE_RESULT mr_cmpval_char (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
272  int *start_colp, int collation);
273 static DB_VALUE_COMPARE_RESULT mr_cmpdisk_char_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
274  int total_order, int *start_colp, int align);
275 #if defined (ENABLE_UNUSED_FUNCTION)
276 static int mr_cmpval_char2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order,
277  int *start_colp);
278 #endif
279 static void mr_initmem_nchar (void *memptr, TP_DOMAIN * domain);
280 static int mr_setmem_nchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
281 static int mr_getmem_nchar (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
282 static int mr_data_lengthmem_nchar (void *memptr, TP_DOMAIN * domain, int disk);
283 static int mr_index_lengthmem_nchar (void *memptr, TP_DOMAIN * domain);
284 static void mr_data_writemem_nchar (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
285 static void mr_data_readmem_nchar (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
286 static void mr_freemem_nchar (void *memptr);
287 static void mr_initval_nchar (DB_VALUE * value, int precision, int scale);
288 static int mr_setval_nchar (DB_VALUE * dest, const DB_VALUE * src, bool copy);
289 static int mr_data_lengthval_nchar (DB_VALUE * value, int disk);
290 static int mr_data_writeval_nchar (OR_BUF * buf, DB_VALUE * value);
291 static int mr_writeval_nchar_internal (OR_BUF * buf, DB_VALUE * value, int align);
292 static int mr_data_readval_nchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
293  char *copy_buf, int copy_buf_len);
294 static int mr_readval_nchar_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
295  char *copy_buf, int copy_buf_len, int align);
296 static int mr_index_lengthval_nchar (DB_VALUE * value);
297 static int mr_index_writeval_nchar (OR_BUF * buf, DB_VALUE * value);
298 static int mr_index_readval_nchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
299  char *copy_buf, int copy_buf_len);
300 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_nchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
301  int total_order, int *start_colp);
302 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_nchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
303  int total_order, int *start_colp);
304 static DB_VALUE_COMPARE_RESULT mr_cmpdisk_nchar_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
305  int total_order, int *start_colp, int align);
306 static DB_VALUE_COMPARE_RESULT mr_cmpval_nchar (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
307  int *start_colp, int collation);
308 #if defined (ENABLE_UNUSED_FUNCTION)
309 static int mr_cmpval_nchar2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order,
310  int *start_colp);
311 #endif
312 static void mr_initmem_varnchar (void *mem, TP_DOMAIN * domain);
313 static int mr_setmem_varnchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
314 static int mr_getmem_varnchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
315 static int mr_data_lengthmem_varnchar (void *memptr, TP_DOMAIN * domain, int disk);
316 static int mr_index_lengthmem_varnchar (void *memptr, TP_DOMAIN * domain);
317 static void mr_data_writemem_varnchar (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
318 static void mr_data_readmem_varnchar (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
319 static void mr_freemem_varnchar (void *memptr);
320 static void mr_initval_varnchar (DB_VALUE * value, int precision, int scale);
321 static int mr_setval_varnchar (DB_VALUE * dest, const DB_VALUE * src, bool copy);
322 static int mr_data_lengthval_varnchar (DB_VALUE * value, int disk);
323 static int mr_data_writeval_varnchar (OR_BUF * buf, DB_VALUE * value);
324 static int mr_data_readval_varnchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
325  char *copy_buf, int copy_buf_len);
326 static int mr_index_lengthval_varnchar (DB_VALUE * value);
327 static int mr_index_writeval_varnchar (OR_BUF * buf, DB_VALUE * value);
328 static int mr_index_readval_varnchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
329  char *copy_buf, int copy_buf_len);
330 static int mr_lengthval_varnchar_internal (DB_VALUE * value, int disk, int align);
331 static int mr_writeval_varnchar_internal (OR_BUF * buf, DB_VALUE * value, int align);
332 static int mr_readval_varnchar_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
333  char *copy_buf, int copy_buf_len, int align);
334 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_varnchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
335  int total_order, int *start_colp);
336 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_varnchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
337  int total_order, int *start_colp);
338 static DB_VALUE_COMPARE_RESULT mr_cmpval_varnchar (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
339  int total_order, int *start_colp, int collation);
340 #if defined (ENABLE_UNUSED_FUNCTION)
341 static int mr_cmpval_varnchar2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order,
342  int *start_colp);
343 #endif
344 static void mr_initmem_bit (void *memptr, TP_DOMAIN * domain);
345 static int mr_setmem_bit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
346 static int mr_getmem_bit (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
347 static int mr_data_lengthmem_bit (void *memptr, TP_DOMAIN * domain, int disk);
348 static void mr_data_writemem_bit (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
349 static void mr_data_readmem_bit (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
350 static void mr_freemem_bit (void *memptr);
351 static void mr_initval_bit (DB_VALUE * value, int precision, int scale);
352 static int mr_setval_bit (DB_VALUE * dest, const DB_VALUE * src, bool copy);
353 static int mr_data_lengthval_bit (DB_VALUE * value, int disk);
354 static int mr_data_writeval_bit (OR_BUF * buf, DB_VALUE * value);
355 static int mr_writeval_bit_internal (OR_BUF * buf, DB_VALUE * value, int align);
356 static int mr_data_readval_bit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
357  char *copy_buf, int copy_buf_len);
358 static int mr_readval_bit_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
359  char *copy_buf, int copy_buf_len, int align);
360 static int mr_index_lengthmem_bit (void *memptr, TP_DOMAIN * domain);
361 static int mr_index_lengthval_bit (DB_VALUE * value);
362 static int mr_index_writeval_bit (OR_BUF * buf, DB_VALUE * value);
363 static int mr_index_readval_bit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy,
364  char *copy_buf, int copy_buf_len);
365 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_bit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
366  int total_order, int *start_colp);
367 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_bit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
368  int total_order, int *start_colp);
369 static DB_VALUE_COMPARE_RESULT mr_cmpdisk_bit_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
370  int total_order, int *start_colp, int align);
371 static DB_VALUE_COMPARE_RESULT mr_cmpval_bit (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
372  int *start_colp, int collation);
373 static DB_VALUE_COMPARE_RESULT mr_cmpval_bit2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion,
374  int total_order, int *start_colp);
375 static void mr_initmem_varbit (void *mem, TP_DOMAIN * domain);
376 static int mr_setmem_varbit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
377 static int mr_getmem_varbit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
378 static int mr_data_lengthmem_varbit (void *memptr, TP_DOMAIN * domain, int disk);
379 static int mr_index_lengthmem_varbit (void *memptr, TP_DOMAIN * domain);
380 static void mr_data_writemem_varbit (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
381 static void mr_data_readmem_varbit (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
382 static void mr_freemem_varbit (void *memptr);
383 static void mr_initval_varbit (DB_VALUE * value, int precision, int scale);
384 static int mr_setval_varbit (DB_VALUE * dest, const DB_VALUE * src, bool copy);
385 static int mr_data_lengthval_varbit (DB_VALUE * value, int disk);
386 static int mr_data_writeval_varbit (OR_BUF * buf, DB_VALUE * value);
387 static int mr_data_readval_varbit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
388  char *copy_buf, int copy_buf_len);
389 static int mr_index_lengthval_varbit (DB_VALUE * value);
390 static int mr_index_writeval_varbit (OR_BUF * buf, DB_VALUE * value);
391 static int mr_index_readval_varbit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
392  char *copy_buf, int copy_buf_len);
393 static int mr_lengthval_varbit_internal (DB_VALUE * value, int disk, int align);
394 static int mr_writeval_varbit_internal (OR_BUF * buf, DB_VALUE * value, int align);
395 static int mr_readval_varbit_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
396  char *copy_buf, int copy_buf_len, int align);
397 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_varbit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
398  int total_order, int *start_colp);
399 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_varbit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
400  int total_order, int *start_colp);
401 static DB_VALUE_COMPARE_RESULT mr_cmpval_varbit (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
402  int *start_colp, int collation);
403 static DB_VALUE_COMPARE_RESULT mr_cmpval_varbit2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion,
404  int total_order, int *start_colp);
405 
406 static void mr_initmem_null (void *mem, TP_DOMAIN * domain);
407 static int mr_setmem_null (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
408 static int mr_getmem_null (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
409 static void mr_data_writemem_null (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
410 static void mr_data_readmem_null (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
411 static void mr_initval_null (DB_VALUE * value, int precision, int scale);
412 static int mr_setval_null (DB_VALUE * dest, const DB_VALUE * src, bool copy);
413 static int mr_data_writeval_null (OR_BUF * buf, DB_VALUE * value);
414 static int mr_data_readval_null (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
415  char *copy_buf, int copy_buf_len);
416 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_null (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
417  int total_order, int *start_colp);
418 static DB_VALUE_COMPARE_RESULT mr_cmpval_null (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
419  int *start_colp, int collation);
420 static void mr_initmem_int (void *mem, TP_DOMAIN * domain);
421 static int mr_setmem_int (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
422 static int mr_getmem_int (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
423 static void mr_data_writemem_int (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
424 static void mr_data_readmem_int (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
425 static void mr_initval_int (DB_VALUE * value, int precision, int scale);
426 static int mr_setval_int (DB_VALUE * dest, const DB_VALUE * src, bool copy);
427 static int mr_data_writeval_int (OR_BUF * buf, DB_VALUE * value);
428 static int mr_data_readval_int (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
429  int copy_buf_len);
430 static int mr_index_writeval_int (OR_BUF * buf, DB_VALUE * value);
431 static int mr_index_readval_int (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
432  char *copy_buf, int copy_buf_len);
433 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_int (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
434  int total_order, int *start_colp);
435 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_int (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
436  int total_order, int *start_colp);
437 static DB_VALUE_COMPARE_RESULT mr_cmpval_int (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
438  int *start_colp, int collation);
439 static void mr_initmem_short (void *mem, TP_DOMAIN * domain);
440 static int mr_setmem_short (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
441 static int mr_getmem_short (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
442 static void mr_data_writemem_short (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
443 static void mr_data_readmem_short (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
444 static void mr_initval_short (DB_VALUE * value, int precision, int scale);
445 static int mr_setval_short (DB_VALUE * dest, const DB_VALUE * src, bool copy);
446 static int mr_data_writeval_short (OR_BUF * buf, DB_VALUE * value);
447 static int mr_data_readval_short (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
448  char *copy_buf, int copy_buf_len);
449 static int mr_index_writeval_short (OR_BUF * buf, DB_VALUE * value);
450 static int mr_index_readval_short (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
451  char *copy_buf, int copy_buf_len);
452 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_short (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
453  int total_order, int *start_colp);
454 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_short (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
455  int total_order, int *start_colp);
456 static DB_VALUE_COMPARE_RESULT mr_cmpval_short (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
457  int *start_colp, int collation);
458 static void mr_initmem_bigint (void *mem, TP_DOMAIN * domain);
459 static int mr_setmem_bigint (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
460 static int mr_getmem_bigint (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
461 static void mr_data_writemem_bigint (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
462 static void mr_data_readmem_bigint (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
463 static void mr_initval_bigint (DB_VALUE * value, int precision, int scale);
464 static int mr_setval_bigint (DB_VALUE * dest, const DB_VALUE * src, bool copy);
465 static int mr_data_writeval_bigint (OR_BUF * buf, DB_VALUE * value);
466 static int mr_data_readval_bigint (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
467  char *copy_buf, int copy_buf_len);
468 static int mr_index_writeval_bigint (OR_BUF * buf, DB_VALUE * value);
469 static int mr_index_readval_bigint (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
470  char *copy_buf, int copy_buf_len);
471 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_bigint (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
472  int total_order, int *start_colp);
473 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_bigint (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
474  int total_order, int *start_colp);
475 static DB_VALUE_COMPARE_RESULT mr_cmpval_bigint (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
476  int *start_colp, int collation);
477 static void mr_initmem_float (void *mem, TP_DOMAIN * domain);
478 static int mr_setmem_float (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
479 static int mr_getmem_float (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
480 static void mr_data_writemem_float (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
481 static void mr_data_readmem_float (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
482 static void mr_initval_float (DB_VALUE * value, int precision, int scale);
483 static int mr_setval_float (DB_VALUE * dest, const DB_VALUE * src, bool copy);
484 static int mr_data_writeval_float (OR_BUF * buf, DB_VALUE * value);
485 static int mr_data_readval_float (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
486  char *copy_buf, int copy_buf_len);
487 static int mr_index_writeval_float (OR_BUF * buf, DB_VALUE * value);
488 static int mr_index_readval_float (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
489  char *copy_buf, int copy_buf_len);
490 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_float (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
491  int total_order, int *start_colp);
492 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_float (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
493  int total_order, int *start_colp);
494 static DB_VALUE_COMPARE_RESULT mr_cmpval_float (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
495  int *start_colp, int collation);
496 static void mr_initmem_double (void *mem, TP_DOMAIN * domain);
497 static int mr_setmem_double (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
498 static int mr_getmem_double (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
499 static void mr_data_writemem_double (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
500 static void mr_data_readmem_double (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
501 static void mr_initval_double (DB_VALUE * value, int precision, int scale);
502 static int mr_setval_double (DB_VALUE * dest, const DB_VALUE * src, bool copy);
503 static int mr_data_writeval_double (OR_BUF * buf, DB_VALUE * value);
504 static int mr_data_readval_double (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
505  char *copy_buf, int copy_buf_len);
506 static int mr_index_writeval_double (OR_BUF * buf, DB_VALUE * value);
507 static int mr_index_readval_double (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
508  char *copy_buf, int copy_buf_len);
509 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_double (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
510  int total_order, int *start_colp);
511 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_double (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
512  int total_order, int *start_colp);
513 static DB_VALUE_COMPARE_RESULT mr_cmpval_double (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
514  int *start_colp, int collation);
515 static void mr_initmem_time (void *mem, TP_DOMAIN * domain);
516 static int mr_setmem_time (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
517 static int mr_getmem_time (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
518 static void mr_data_writemem_time (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
519 static void mr_data_readmem_time (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
520 static void mr_initval_time (DB_VALUE * value, int precision, int scale);
521 static int mr_setval_time (DB_VALUE * dest, const DB_VALUE * src, bool copy);
522 static int mr_data_writeval_time (OR_BUF * buf, DB_VALUE * value);
523 static int mr_data_readval_time (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
524  char *copy_buf, int copy_buf_len);
525 static int mr_index_writeval_time (OR_BUF * buf, DB_VALUE * value);
526 static int mr_index_readval_time (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
527  char *copy_buf, int copy_buf_len);
528 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_time (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
529  int total_order, int *start_colp);
530 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_time (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
531  int total_order, int *start_colp);
532 static DB_VALUE_COMPARE_RESULT mr_cmpval_time (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
533  int *start_colp, int collation);
534 
535 static void mr_initmem_utime (void *mem, TP_DOMAIN * domain);
536 static int mr_setmem_utime (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
537 static int mr_getmem_utime (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
538 static int mr_getmem_timestampltz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
539 static void mr_data_writemem_utime (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
540 static void mr_data_readmem_utime (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
541 static void mr_initval_utime (DB_VALUE * value, int precision, int scale);
542 static void mr_initval_timestampltz (DB_VALUE * value, int precision, int scale);
543 static int mr_setval_utime (DB_VALUE * dest, const DB_VALUE * src, bool copy);
544 static int mr_setval_timestampltz (DB_VALUE * dest, const DB_VALUE * src, bool copy);
545 static int mr_data_writeval_utime (OR_BUF * buf, DB_VALUE * value);
546 static int mr_data_readval_utime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
547  char *copy_buf, int copy_buf_len);
548 static int mr_data_readval_timestampltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
549  char *copy_buf, int copy_buf_len);
550 static int mr_index_writeval_utime (OR_BUF * buf, DB_VALUE * value);
551 static int mr_index_readval_utime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
552  char *copy_buf, int copy_buf_len);
553 static int mr_index_readval_timestampltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
554  char *copy_buf, int copy_buf_len);
555 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_utime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
556  int total_order, int *start_colp);
557 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_utime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
558  int total_order, int *start_colp);
559 static DB_VALUE_COMPARE_RESULT mr_cmpval_utime (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
560  int *start_colp, int collation);
561 
562 static void mr_initmem_timestamptz (void *mem, TP_DOMAIN * domain);
563 static int mr_setmem_timestamptz (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
564 static int mr_getmem_timestamptz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
565 static void mr_data_writemem_timestamptz (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
566 static void mr_data_readmem_timestamptz (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
567 static void mr_initval_timestamptz (DB_VALUE * value, int precision, int scale);
568 static int mr_setval_timestamptz (DB_VALUE * dest, const DB_VALUE * src, bool copy);
569 static int mr_data_writeval_timestamptz (OR_BUF * buf, DB_VALUE * value);
570 static int mr_data_readval_timestamptz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
571  char *copy_buf, int copy_buf_len);
572 static int mr_index_writeval_timestamptz (OR_BUF * buf, DB_VALUE * value);
573 static int mr_index_readval_timestamptz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
574  char *copy_buf, int copy_buf_len);
575 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_timestamptz (void *mem1, void *mem2, TP_DOMAIN * domain,
576  int do_coercion, int total_order, int *start_colp);
577 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_timestamptz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
578  int total_order, int *start_colp);
579 static DB_VALUE_COMPARE_RESULT mr_cmpval_timestamptz (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
580  int total_order, int *start_colp, int collation);
581 
582 static void mr_initmem_datetime (void *memptr, TP_DOMAIN * domain);
583 static void mr_initval_datetime (DB_VALUE * value, int precision, int scale);
584 static void mr_initval_datetimeltz (DB_VALUE * value, int precision, int scale);
585 static int mr_setmem_datetime (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
586 static int mr_getmem_datetime (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
587 static int mr_getmem_datetimeltz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
588 static int mr_setval_datetime (DB_VALUE * dest, const DB_VALUE * src, bool copy);
589 static int mr_setval_datetimeltz (DB_VALUE * dest, const DB_VALUE * src, bool copy);
590 static void mr_data_writemem_datetime (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
591 static void mr_data_readmem_datetime (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
592 static int mr_data_writeval_datetime (OR_BUF * buf, DB_VALUE * value);
593 static int mr_data_readval_datetime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
594  char *copy_buf, int copy_buf_len);
595 static int mr_data_readval_datetimeltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
596  char *copy_buf, int copy_buf_len);
597 static int mr_index_writeval_datetime (OR_BUF * buf, DB_VALUE * value);
598 static int mr_index_readval_datetime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
599  char *copy_buf, int copy_buf_len);
600 static int mr_index_readval_datetimeltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
601  char *copy_buf, int copy_buf_len);
602 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_datetime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
603  int total_order, int *start_colp);
604 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_datetime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
605  int total_order, int *start_colp);
606 static DB_VALUE_COMPARE_RESULT mr_cmpval_datetime (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
607  int total_order, int *start_colp, int collation);
608 
609 static void mr_initmem_datetimetz (void *memptr, TP_DOMAIN * domain);
610 static void mr_initval_datetimetz (DB_VALUE * value, int precision, int scale);
611 static int mr_setmem_datetimetz (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
612 static int mr_getmem_datetimetz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
613 static int mr_setval_datetimetz (DB_VALUE * dest, const DB_VALUE * src, bool copy);
614 static void mr_data_writemem_datetimetz (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
615 static void mr_data_readmem_datetimetz (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
616 static int mr_data_writeval_datetimetz (OR_BUF * buf, DB_VALUE * value);
617 static int mr_data_readval_datetimetz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
618  char *copy_buf, int copy_buf_len);
619 static int mr_index_writeval_datetimetz (OR_BUF * buf, DB_VALUE * value);
620 static int mr_index_readval_datetimetz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
621  char *copy_buf, int copy_buf_len);
622 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_datetimetz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
623  int total_order, int *start_colp);
624 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_datetimetz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
625  int total_order, int *start_colp);
626 static DB_VALUE_COMPARE_RESULT mr_cmpval_datetimetz (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
627  int total_order, int *start_colp, int collation);
628 
629 static void mr_initmem_money (void *memptr, TP_DOMAIN * domain);
630 static int mr_setmem_money (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
631 static int mr_getmem_money (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
632 static void mr_data_writemem_money (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
633 static void mr_data_readmem_money (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
634 static void mr_initval_money (DB_VALUE * value, int precision, int scale);
635 static int mr_setval_money (DB_VALUE * dest, const DB_VALUE * src, bool copy);
636 static int mr_data_writeval_money (OR_BUF * buf, DB_VALUE * value);
637 static int mr_data_readval_money (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
638  char *copy_buf, int copy_buf_len);
639 static int mr_index_writeval_money (OR_BUF * buf, DB_VALUE * value);
640 static int mr_index_readval_money (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
641  char *copy_buf, int copy_buf_len);
642 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_money (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
643  int total_order, int *start_colp);
644 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_money (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
645  int total_order, int *start_colp);
646 static DB_VALUE_COMPARE_RESULT mr_cmpval_money (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
647  int *start_colp, int collation);
648 static void mr_initmem_date (void *mem, TP_DOMAIN * domain);
649 static int mr_setmem_date (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
650 static int mr_getmem_date (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
651 static void mr_data_writemem_date (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
652 static void mr_data_readmem_date (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
653 static void mr_initval_date (DB_VALUE * value, int precision, int scale);
654 static int mr_setval_date (DB_VALUE * dest, const DB_VALUE * src, bool copy);
655 static int mr_data_writeval_date (OR_BUF * buf, DB_VALUE * value);
656 static int mr_data_readval_date (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
657  char *copy_buf, int copy_buf_len);
658 static int mr_index_writeval_date (OR_BUF * buf, DB_VALUE * value);
659 static int mr_index_readval_date (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
660  char *copy_buf, int copy_buf_len);
661 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_date (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
662  int total_order, int *start_colp);
663 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_date (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
664  int total_order, int *start_colp);
665 static DB_VALUE_COMPARE_RESULT mr_cmpval_date (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
666  int *start_colp, int collation);
667 static void mr_null_oid (OID * oid);
668 static void mr_initmem_object (void *mem, TP_DOMAIN * domain);
669 static void mr_initval_object (DB_VALUE * value, int precision, int scale);
670 static int mr_setmem_object (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
671 static int mr_getmem_object (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
672 static int mr_setval_object (DB_VALUE * dest, const DB_VALUE * src, bool copy);
673 static int mr_data_lengthval_object (DB_VALUE * value, int disk);
674 static void mr_data_writemem_object (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
675 static void mr_data_readmem_object (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
676 static int mr_data_writeval_object (OR_BUF * buf, DB_VALUE * value);
677 static int mr_data_readval_object (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
678  char *copy_buf, int copy_buf_len);
679 static int mr_index_writeval_object (OR_BUF * buf, DB_VALUE * value);
680 static int mr_index_readval_object (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
681  char *copy_buf, int copy_buf_len);
682 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_object (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
683  int total_order, int *start_colp);
684 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_object (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
685  int total_order, int *start_colp);
686 static DB_VALUE_COMPARE_RESULT mr_cmpval_object (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
687  int *start_colp, int collation);
688 static void mr_initmem_elo (void *memptr, TP_DOMAIN * domain);
689 static void mr_initval_elo (DB_VALUE * value, int precision, int scale);
690 static int mr_setmem_elo (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
691 static int mr_setval_elo (DB_VALUE * dest, const DB_VALUE * src, bool copy);
692 static int mr_data_lengthmem_elo (void *memptr, TP_DOMAIN * domain, int disk);
693 static void mr_data_writemem_elo (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
694 static void mr_data_readmem_elo (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
695 static int mr_getmem_elo (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
696 static int getmem_elo_with_type (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy, DB_TYPE type);
697 static void peekmem_elo (OR_BUF * buf, DB_ELO * elo);
698 static int mr_data_lengthval_elo (DB_VALUE * value, int disk);
699 static int mr_data_writeval_elo (OR_BUF * buf, DB_VALUE * value);
700 static int mr_data_readval_elo (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
701  int copy_buf_len);
702 static int setval_elo_with_type (DB_VALUE * dest, const DB_VALUE * src, bool copy, DB_TYPE type);
703 static int readval_elo_with_type (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
704  char *copy_buf, int copy_buf_len, DB_TYPE type);
705 static void mr_freemem_elo (void *memptr);
706 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_elo (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
707  int total_order, int *start_colp);
708 static DB_VALUE_COMPARE_RESULT mr_cmpval_elo (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
709  int *start_colp, int collation);
710 
711 static void mr_initval_blob (DB_VALUE * value, int precision, int scale);
712 static int mr_getmem_blob (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
713 static int mr_setval_blob (DB_VALUE * dest, const DB_VALUE * src, bool copy);
714 static int mr_data_readval_blob (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
715  char *copy_buf, int copy_buf_len);
716 
717 static void mr_initval_clob (DB_VALUE * value, int precision, int scale);
718 static int mr_getmem_clob (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
719 static int mr_setval_clob (DB_VALUE * dest, const DB_VALUE * src, bool copy);
720 static int mr_data_readval_clob (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
721  char *copy_buf, int copy_buf_len);
722 
723 static void mr_initval_variable (DB_VALUE * value, int precision, int scale);
724 static int mr_setval_variable (DB_VALUE * dest, const DB_VALUE * src, bool copy);
725 static int mr_data_lengthval_variable (DB_VALUE * value, int disk);
726 static int mr_data_writeval_variable (OR_BUF * buf, DB_VALUE * value);
727 static int mr_data_readval_variable (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
728  char *copy_buf, int copy_buf_len);
729 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_variable (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
730  int total_order, int *start_colp);
731 static DB_VALUE_COMPARE_RESULT mr_cmpval_variable (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
732  int total_order, int *start_colp, int collation);
733 static void mr_initmem_sub (void *mem, TP_DOMAIN * domain);
734 static void mr_initval_sub (DB_VALUE * value, int precision, int scale);
735 static int mr_setmem_sub (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
736 static int mr_getmem_sub (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
737 static int mr_setval_sub (DB_VALUE * dest, const DB_VALUE * src, bool copy);
738 static int mr_data_lengthmem_sub (void *mem, TP_DOMAIN * domain, int disk);
739 static void mr_data_writemem_sub (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
740 static void mr_data_readmem_sub (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
741 static int mr_data_lengthval_sub (DB_VALUE * value, int disk);
742 static int mr_data_writeval_sub (OR_BUF * buf, DB_VALUE * value);
743 static int mr_data_readval_sub (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
744  int copy_buf_len);
745 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_sub (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
746  int total_order, int *start_colp);
747 static DB_VALUE_COMPARE_RESULT mr_cmpval_sub (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
748  int *start_colp, int collation);
749 static void mr_initmem_ptr (void *memptr, TP_DOMAIN * domain);
750 static void mr_initval_ptr (DB_VALUE * value, int precision, int scale);
751 static int mr_setmem_ptr (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
752 static int mr_getmem_ptr (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
753 static int mr_setval_ptr (DB_VALUE * dest, const DB_VALUE * src, bool copy);
754 static int mr_data_lengthmem_ptr (void *memptr, TP_DOMAIN * domain, int disk);
755 static void mr_data_writemem_ptr (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
756 static void mr_data_readmem_ptr (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
757 static int mr_data_lengthval_ptr (DB_VALUE * value, int disk);
758 static int mr_data_writeval_ptr (OR_BUF * buf, DB_VALUE * value);
759 static int mr_data_readval_ptr (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
760  int copy_buf_len);
761 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_ptr (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
762  int total_order, int *start_colp);
763 static DB_VALUE_COMPARE_RESULT mr_cmpval_ptr (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
764  int *start_colp, int collation);
765 static void mr_initmem_error (void *memptr, TP_DOMAIN * domain);
766 static void mr_initval_error (DB_VALUE * value, int precision, int scale);
767 static int mr_setmem_error (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
768 static int mr_getmem_error (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
769 static int mr_setval_error (DB_VALUE * dest, const DB_VALUE * src, bool copy);
770 static int mr_data_lengthmem_error (void *memptr, TP_DOMAIN * domain, int disk);
771 static int mr_data_lengthval_error (DB_VALUE * value, int disk);
772 static void mr_data_writemem_error (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
773 static void mr_data_readmem_error (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
774 static int mr_data_writeval_error (OR_BUF * buf, DB_VALUE * value);
775 static int mr_data_readval_error (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
776  char *copy_buf, int copy_buf_len);
777 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_error (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
778  int total_order, int *start_colp);
779 static DB_VALUE_COMPARE_RESULT mr_cmpval_error (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
780  int *start_colp, int collation);
781 static void mr_initmem_oid (void *memptr, TP_DOMAIN * domain);
782 static void mr_initval_oid (DB_VALUE * value, int precision, int scale);
783 static int mr_setmem_oid (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
784 static int mr_getmem_oid (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
785 static int mr_setval_oid (DB_VALUE * dest, const DB_VALUE * src, bool copy);
786 static void mr_data_writemem_oid (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
787 static void mr_data_readmem_oid (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
788 static int mr_data_writeval_oid (OR_BUF * buf, DB_VALUE * value);
789 static int mr_data_readval_oid (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
790  int copy_buf_len);
791 static int mr_index_writeval_oid (OR_BUF * buf, DB_VALUE * value);
792 static int mr_index_readval_oid (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
793  char *copy_buf, int copy_buf_len);
794 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_oid (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
795  int total_order, int *start_colp);
796 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_oid (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
797  int total_order, int *start_colp);
798 static DB_VALUE_COMPARE_RESULT mr_cmpval_oid (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
799  int *start_colp, int collation);
800 static void mr_initmem_set (void *memptr, TP_DOMAIN * domain);
801 static void mr_initval_set (DB_VALUE * value, int precision, int scale);
802 static int mr_setmem_set (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
803 static int mr_getmem_set (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
804 static int mr_setval_set_internal (DB_VALUE * dest, const DB_VALUE * src, bool copy, DB_TYPE set_type);
805 static int mr_setval_set (DB_VALUE * dest, const DB_VALUE * src, bool copy);
806 static int mr_data_lengthmem_set (void *memptr, TP_DOMAIN * domain, int disk);
807 static void mr_data_writemem_set (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
808 static void mr_data_readmem_set (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
809 static int mr_data_lengthval_set (DB_VALUE * value, int disk);
810 static int mr_data_writeval_set (OR_BUF * buf, DB_VALUE * value);
811 static int mr_data_readval_set (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
812  int copy_buf_len);
813 static void mr_freemem_set (void *memptr);
814 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_set (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
815  int total_order, int *start_colp);
816 static DB_VALUE_COMPARE_RESULT mr_cmpval_set (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
817  int *start_colp, int collation);
818 static void mr_initval_multiset (DB_VALUE * value, int precision, int scale);
819 static int mr_getmem_multiset (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
820 static int mr_setval_multiset (DB_VALUE * dest, const DB_VALUE * src, bool copy);
821 static void mr_initval_sequence (DB_VALUE * value, int precision, int scale);
822 static int mr_getmem_sequence (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
823 static int mr_setval_sequence (DB_VALUE * dest, const DB_VALUE * src, bool copy);
824 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_sequence (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
825  int total_order, int *start_colp);
826 static DB_VALUE_COMPARE_RESULT mr_cmpval_sequence (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
827  int total_order, int *start_colp, int collation);
828 static void mr_initval_midxkey (DB_VALUE * value, int precision, int scale);
829 static int mr_setval_midxkey (DB_VALUE * dest, const DB_VALUE * src, bool copy);
830 static int mr_data_lengthmem_midxkey (void *memptr, TP_DOMAIN * domain, int disk);
831 static int mr_index_lengthmem_midxkey (void *memptr, TP_DOMAIN * domain);
832 static int mr_data_lengthval_midxkey (DB_VALUE * value, int disk);
833 static int mr_index_lengthval_midxkey (DB_VALUE * value);
834 static int mr_data_writeval_midxkey (OR_BUF * buf, DB_VALUE * value);
835 static int mr_index_writeval_midxkey (OR_BUF * buf, DB_VALUE * value);
836 static int mr_data_readval_midxkey (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
837  char *copy_buf, int copy_buf_len);
838 static int mr_index_readval_midxkey (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
839  char *copy_buf, int copy_buf_len);
840 static DB_VALUE_COMPARE_RESULT pr_midxkey_compare_element (char *mem1, char *mem2, TP_DOMAIN * dom1, TP_DOMAIN * dom2,
841  int do_coercion, int total_order);
842 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_midxkey (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
843  int total_order, int *start_colp);
844 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_midxkey (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
845  int total_order, int *start_colp);
846 static DB_VALUE_COMPARE_RESULT mr_cmpval_midxkey (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
847  int total_order, int *start_colp, int collation);
848 static void mr_initval_vobj (DB_VALUE * value, int precision, int scale);
849 static int mr_setval_vobj (DB_VALUE * dest, const DB_VALUE * src, bool copy);
850 static int mr_data_readval_vobj (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
851  char *copy_buf, int copy_buf_len);
852 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_vobj (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
853  int total_order, int *start_colp);
854 static DB_VALUE_COMPARE_RESULT mr_cmpval_vobj (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
855  int *start_colp, int collation);
856 static void mr_initmem_numeric (void *memptr, TP_DOMAIN * domain);
857 static int mr_setmem_numeric (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
858 static int mr_getmem_numeric (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
859 static int mr_data_lengthmem_numeric (void *mem, TP_DOMAIN * domain, int disk);
860 static int mr_index_lengthmem_numeric (void *mem, TP_DOMAIN * domain);
861 static void mr_data_writemem_numeric (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
862 static void mr_data_readmem_numeric (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
863 static void mr_initval_numeric (DB_VALUE * value, int precision, int scale);
864 static int mr_setval_numeric (DB_VALUE * dest, const DB_VALUE * src, bool copy);
865 static int mr_data_lengthval_numeric (DB_VALUE * value, int disk);
866 static int mr_data_writeval_numeric (OR_BUF * buf, DB_VALUE * value);
867 static int mr_data_readval_numeric (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
868  char *copy_buf, int copy_buf_len);
869 static int mr_index_lengthval_numeric (DB_VALUE * value);
870 static int mr_index_writeval_numeric (OR_BUF * buf, DB_VALUE * value);
871 static int mr_index_readval_numeric (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
872  char *copy_buf, int copy_buf_len);
873 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_numeric (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
874  int total_order, int *start_colp);
875 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_numeric (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
876  int total_order, int *start_colp);
877 static DB_VALUE_COMPARE_RESULT mr_cmpval_numeric (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
878  int total_order, int *start_colp, int collation);
879 static void mr_initmem_resultset (void *mem, TP_DOMAIN * domain);
880 static int mr_setmem_resultset (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
881 static int mr_getmem_resultset (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
882 static void mr_data_writemem_resultset (OR_BUF * buf, void *mem, TP_DOMAIN * domain);
883 static void mr_data_readmem_resultset (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
884 static void mr_initval_resultset (DB_VALUE * value, int precision, int scale);
885 static int mr_setval_resultset (DB_VALUE * dest, const DB_VALUE * src, bool copy);
886 static int mr_data_writeval_resultset (OR_BUF * buf, DB_VALUE * value);
887 static int mr_data_readval_resultset (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
888  char *copy_buf, int copy_buf_len);
889 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_resultset (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
890  int total_order, int *start_colp);
891 static DB_VALUE_COMPARE_RESULT mr_cmpval_resultset (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
892  int total_order, int *start_colp, int collation);
893 
894 static int pr_midxkey_get_vals_size (TP_DOMAIN * domains, DB_VALUE * dbvals, int total);
895 static int pr_midxkey_get_element_internal (const DB_MIDXKEY * midxkey, int index, DB_VALUE * value, bool copy,
896  int *prev_indexp, char **prev_ptrp);
897 static void mr_initmem_enumeration (void *mem, TP_DOMAIN * domain);
898 static void mr_initval_enumeration (DB_VALUE * value, int precision, int scale);
899 static int mr_setmem_enumeration (void *mem, TP_DOMAIN * domain, DB_VALUE * value);
900 static int mr_getmem_enumeration (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
901 static int mr_setval_enumeration (DB_VALUE * dest, const DB_VALUE * src, bool copy);
902 static void mr_data_writemem_enumeration (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
903 static void mr_data_readmem_enumeration (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size);
904 static int mr_setval_enumeration_internal (DB_VALUE * value, TP_DOMAIN * domain, unsigned short index, int size,
905  bool copy, char *copy_buf, int copy_buf_len);
906 static int mr_data_readval_enumeration (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
907  char *copy_buf, int copy_buf_len);
908 static int mr_data_writeval_enumeration (OR_BUF * buf, DB_VALUE * value);
909 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_enumeration (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
910  int total_order, int *start_colp);
911 static DB_VALUE_COMPARE_RESULT mr_cmpval_enumeration (DB_VALUE * value1, DB_VALUE * value2, int do_coercion,
912  int total_order, int *start_colp, int collation);
913 static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_enumeration (void *mem1, void *mem2, TP_DOMAIN * domain,
914  int do_coercion, int total_order, int *start_colp);
915 static int mr_index_writeval_enumeration (OR_BUF * buf, DB_VALUE * value);
916 static int mr_index_readval_enumeration (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
917  char *copy_buf, int copy_buf_len);
918 
919 static int pr_write_compressed_string_to_buffer (OR_BUF * buf, const char *compressed_string, int compressed_length,
920  int decompressed_length, int alignment);
921 static int pr_write_uncompressed_string_to_buffer (OR_BUF * buf, const char *string, int size, int align);
922 
923 static void mr_initmem_json (void *mem, TP_DOMAIN * domain);
924 static int mr_setmem_json (void *memptr, TP_DOMAIN * domain, DB_VALUE * value);
925 static int mr_getmem_json (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy);
926 static int mr_data_lengthmem_json (void *memptr, TP_DOMAIN * domain, int disk);
927 static void mr_data_writemem_json (OR_BUF * buf, void *memptr, TP_DOMAIN * domain);
928 static void mr_data_readmem_json (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size);
929 static void mr_freemem_json (void *memptr);
930 static void mr_initval_json (DB_VALUE * value, int precision, int scale);
931 static int mr_setval_json (DB_VALUE * dest, const DB_VALUE * src, bool copy);
932 static int mr_data_lengthval_json (DB_VALUE * value, int disk);
933 static int mr_data_writeval_json (OR_BUF * buf, DB_VALUE * value);
934 static int mr_data_readval_json (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy,
935  char *copy_buf, int copy_buf_len);
936 static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_json (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion,
937  int total_order, int *start_colp);
938 static DB_VALUE_COMPARE_RESULT mr_cmpval_json (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order,
939  int *start_colp, int collation);
940 /*
941  * Value_area
942  * Area used for allocation of value containers that may be given out
943  * to database applications.
944  */
945 static AREA *Value_area = NULL;
946 
948 
951  "*NULL*", DB_TYPE_NULL, 0, 0, 0, 0,
957  NULL, /* data_lengthmem */
958  NULL, /* data_lengthval */
963  NULL, /* index_lenghmem */
964  NULL, /* index_lenghval */
965  NULL, /* index_writeval */
966  NULL, /* index_readval */
967  NULL, /* index_cmpdisk */
968  NULL, /* freemem */
971 };
972 
974 
976  "integer", DB_TYPE_INTEGER, 0, sizeof (int), sizeof (int), 4,
982  NULL, /* data_lengthmem */
983  NULL, /* data_lengthval */
988  NULL, /* index_lengthmem */
989  NULL, /* index_lengthval */
993  NULL, /* freemem */
996 };
997 
999 
1001  "smallint", DB_TYPE_SHORT, 0, sizeof (short), sizeof (short), 2,
1007  NULL, /* data_lengthmem */
1008  NULL, /* data_lengthval */
1013  NULL, /* index_lengthmem */
1014  NULL, /* index_lengthval */
1018  NULL, /* freemem */
1021 };
1022 
1024 
1026  "bigint", DB_TYPE_BIGINT, 0, sizeof (DB_BIGINT), sizeof (DB_BIGINT), 4,
1032  NULL, /* data_lengthmem */
1033  NULL, /* data_lengthval */
1038  NULL, /* index_lengthmem */
1039  NULL, /* index_lengthval */
1043  NULL, /* freemem */
1046 };
1047 
1049 
1051  "float", DB_TYPE_FLOAT, 0, sizeof (float), sizeof (float), 4,
1057  NULL, /* data_lengthmem */
1058  NULL, /* data_lengthval */
1063  NULL, /* index_lengthmem */
1064  NULL, /* index_lengthval */
1068  NULL, /* freemem */
1071 };
1072 
1074 
1076  "double", DB_TYPE_DOUBLE, 0, sizeof (double), sizeof (double), 4,
1082  NULL, /* data_lengthmem */
1083  NULL, /* data_lenghtval */
1088  NULL, /* index_lenghtmem */
1089  NULL, /* index_lenghtval */
1093  NULL, /* freemem */
1096 };
1097 
1099 
1101  "time", DB_TYPE_TIME, 0, sizeof (DB_TIME), OR_TIME_SIZE, 4,
1107  NULL, /* data_lengthmem */
1108  NULL, /* data_lengthval */
1113  NULL, /* index_lenghmem */
1114  NULL, /* index_lenghval */
1118  NULL, /* freemem */
1121 };
1122 
1124 
1126  "timestamp", DB_TYPE_TIMESTAMP, 0, sizeof (DB_UTIME), OR_UTIME_SIZE, 4,
1132  NULL, /* data_lengthmem */
1133  NULL, /* data_lengthval */
1138  NULL, /* index_lenghmem */
1139  NULL, /* index_lenghval */
1143  NULL, /* freemem */
1146 };
1147 
1149 
1151  "timestamptz", DB_TYPE_TIMESTAMPTZ, 0, sizeof (DB_TIMESTAMPTZ), OR_TIMESTAMPTZ_SIZE, 4,
1157  NULL, /* data_lengthmem */
1158  NULL, /* data_lengthval */
1163  NULL, /* index_lenghmem */
1164  NULL, /* index_lenghval */
1168  NULL, /* freemem */
1171 };
1172 
1174 
1175 /* timestamp with locale time zone has the same storage and primitives as
1176  * (simple) timestamp */
1178  "timestampltz", DB_TYPE_TIMESTAMPLTZ, 0, sizeof (DB_UTIME), OR_UTIME_SIZE, 4,
1184  NULL, /* data_lengthmem */
1185  NULL, /* data_lengthval */
1190  NULL, /* index_lenghmem */
1191  NULL, /* index_lenghval */
1195  NULL, /* freemem */
1198 };
1199 
1201  "datetime", DB_TYPE_DATETIME, 0, sizeof (DB_DATETIME), OR_DATETIME_SIZE, 4,
1207  NULL, /* data_lengthmem */
1208  NULL, /* data_lengthval */
1213  NULL, /* index_lenghmem */
1214  NULL, /* index_lenghval */
1218  NULL, /* freemem */
1221 };
1222 
1224 
1226  "datetimetz", DB_TYPE_DATETIMETZ, 0, sizeof (DB_DATETIMETZ), OR_DATETIMETZ_SIZE, 4,
1232  NULL, /* data_lengthmem */
1233  NULL, /* data_lengthval */
1238  NULL, /* index_lenghmem */
1239  NULL, /* index_lenghval */
1243  NULL, /* freemem */
1246 };
1247 
1249 
1250 /* datetime with locale time zone has the same storage and primitives as
1251  * (simple) datetime */
1253  "datetimeltz", DB_TYPE_DATETIMELTZ, 0, sizeof (DB_DATETIME), OR_DATETIME_SIZE, 4,
1259  NULL, /* data_lengthmem */
1260  NULL, /* data_lengthval */
1265  NULL, /* index_lenghmem */
1266  NULL, /* index_lenghval */
1270  NULL, /* freemem */
1273 };
1274 
1276 
1278  "monetary", DB_TYPE_MONETARY, 0, sizeof (DB_MONETARY), OR_MONETARY_SIZE, 4,
1284  NULL, /* data_lengthmem */
1285  NULL, /* data_lengthval */
1290  NULL, /* index_lenghmem */
1291  NULL, /* index_lenghval */
1295  NULL, /* freemem */
1298 };
1299 
1301 
1303  "date", DB_TYPE_DATE, 0, sizeof (DB_DATE), OR_DATE_SIZE, 4,
1309  NULL, /* data_lengthmem */
1310  NULL, /* data_lengthval */
1315  NULL, /* data_lengthmem */
1316  NULL, /* data_lengthval */
1320  NULL, /* freemem */
1323 };
1324 
1326 
1327 /*
1328  * tp_Object
1329  *
1330  * ALERT!!! We set the alignment for OIDs to 8 even though they only have an
1331  * int and two shorts. This is done because the WS_MEMOID has a pointer
1332  * following the OID and it must be on an 8 byte boundary for the Alpha boxes.
1333  */
1334 
1336  "object", DB_TYPE_OBJECT, 0, MR_OID_SIZE, OR_OID_SIZE, 4,
1342  NULL, /* data_lengthmem */
1348  NULL, /* data_lengthmem */
1349  NULL, /* data_lengthval */
1353  NULL, /* freemem */
1356 };
1357 
1359 
1360 PR_TYPE tp_Elo = { /* todo: remove me */
1361  "*elo*", DB_TYPE_ELO, 1, sizeof (DB_ELO *), 0, 8,
1364  mr_setmem_elo,
1365  mr_getmem_elo,
1366  mr_setval_elo,
1373  NULL, /* index_lengthmem */
1374  NULL, /* index_lengthval */
1375  NULL, /* index_writeval */
1376  NULL, /* index_readval */
1377  NULL, /* index_cmpdisk */
1381 };
1382 
1384 
1386  "blob", DB_TYPE_BLOB, 1, sizeof (DB_ELO *), 0, 8,
1389  mr_setmem_elo,
1398  NULL, /* index_lengthmem */
1399  NULL, /* index_lengthval */
1400  NULL, /* index_writeval */
1401  NULL, /* index_readval */
1402  NULL, /* index_cmpdisk */
1406 };
1407 
1409 
1411  "clob", DB_TYPE_CLOB, 1, sizeof (DB_ELO *), 0, 8,
1414  mr_setmem_elo,
1423  NULL, /* index_lengthmem */
1424  NULL, /* index_lengthval */
1425  NULL, /* index_writeval */
1426  NULL, /* index_readval */
1427  NULL, /* index_cmpdisk */
1431 };
1432 
1434 
1436  "*variable*", DB_TYPE_VARIABLE, 1, sizeof (DB_VALUE), 0, 4,
1437  NULL, /* initmem */
1439  NULL, /* setmem */
1440  NULL, /* getmem */
1442  NULL, /* data_lengthmem */
1444  NULL, /* data_writemem */
1445  NULL, /* data_readmem */
1448  NULL, /* index_lengthmem */
1449  NULL, /* index_lengthval */
1450  NULL, /* index_writeval */
1451  NULL, /* index_readval */
1452  NULL, /* index_cmpdisk */
1453  NULL, /* freemem */
1456 };
1457 
1459 
1461  "*substructure*", DB_TYPE_SUB, 1, sizeof (void *), 0, 8,
1464  mr_setmem_sub,
1465  mr_getmem_sub,
1466  mr_setval_sub,
1473  NULL, /* index_lengthmem */
1474  NULL, /* index_lengthval */
1475  NULL, /* index_writeval */
1476  NULL, /* index_readval */
1477  NULL, /* index_cmpdisk */
1478  NULL, /* freemem */
1481 };
1482 
1484 
1486  "*pointer*", DB_TYPE_POINTER, 0, sizeof (void *), 0, 4,
1489  mr_setmem_ptr,
1490  mr_getmem_ptr,
1491  mr_setval_ptr,
1498  NULL, /* index_lengthmem */
1499  NULL, /* index_lengthval */
1500  NULL, /* index_writeval */
1501  NULL, /* index_readval */
1502  NULL, /* index_cmpdisk */
1503  NULL, /* freeemem */
1506 };
1507 
1509 
1511  "*error*", DB_TYPE_ERROR, 0, sizeof (int), 0, 4,
1523  NULL, /* index_lengthmem */
1524  NULL, /* index_lengthval */
1525  NULL, /* index_writeval */
1526  NULL, /* index_readval */
1527  NULL, /* index_cmpdisk */
1528  NULL, /* freemem */
1531 };
1532 
1534 
1535 /*
1536  * tp_Oid
1537  *
1538  * ALERT!!! We set the alignment for OIDs to 8 even though they only have an
1539  * int and two shorts. This is done because the WS_MEMOID has a pointer
1540  * following the OID and it must be on an 8 byte boundary for the Alpha boxes.
1541  */
1543  "*oid*", DB_TYPE_OID, 0, sizeof (OID), OR_OID_SIZE, 4,
1546  mr_setmem_oid,
1547  mr_getmem_oid,
1548  mr_setval_oid,
1549  NULL, /* lengthmem */
1550  NULL, /* lengthval */
1555  NULL, /* index_lengthmem */
1556  NULL, /* index_lengthval */
1560  NULL, /* freemem */
1563 };
1564 
1566 
1568  "set", DB_TYPE_SET, 1, sizeof (SETOBJ *), 0, 4,
1571  mr_setmem_set,
1572  mr_getmem_set,
1573  mr_setval_set,
1580  NULL, /* index_lengthmem */
1581  NULL, /* index_lengthval */
1582  NULL, /* index_writeval */
1583  NULL, /* index_readval */
1584  NULL, /* index_cmpdisk */
1588 };
1589 
1591 
1593  "multiset", DB_TYPE_MULTISET, 1, sizeof (SETOBJ *), 0, 4,
1596  mr_setmem_set,
1605  NULL, /* index_lengthmem */
1606  NULL, /* index_lengthval */
1607  NULL, /* index_writeval */
1608  NULL, /* index_readval */
1609  NULL, /* index_cmpdisk */
1613 };
1614 
1616 
1618  "sequence", DB_TYPE_SEQUENCE, 1, sizeof (SETOBJ *), 0, 4,
1621  mr_setmem_set,
1630  NULL, /* index_lengthmem */
1631  NULL, /* index_lengthval */
1632  NULL, /* index_writeval */
1633  NULL, /* index_readval */
1634  NULL, /* index_cmpdisk */
1638 };
1639 
1641 
1643  "midxkey", DB_TYPE_MIDXKEY, 1, 0, 0, 1,
1644  NULL, /* initmem */
1646  NULL, /* setmem */
1647  NULL, /* getmem_midxkey */
1651  NULL, /* data_writemem */
1652  NULL, /* data_readmem */
1660  NULL, /* freemem */
1663 };
1664 
1666 
1668  "*vobj*", DB_TYPE_VOBJ, 1, sizeof (SETOBJ *), 0, 8,
1671  mr_setmem_set,
1680  NULL, /* index_lengthmem */
1681  NULL, /* index_lengthval */
1682  NULL, /* index_writeval */
1683  NULL, /* index_readval */
1684  NULL, /* index_cmpdisk */
1688 };
1689 
1691 
1693  "numeric", DB_TYPE_NUMERIC, 0, 0, 0, 1,
1710  NULL, /* freemem */
1713 };
1714 
1716 
1718  "enum", DB_TYPE_ENUMERATION, 0, sizeof (unsigned short), sizeof (unsigned short), sizeof (unsigned short),
1724  NULL, /* use disksize */
1725  NULL, /* use_disksize */
1730  NULL, /* use disksize */
1731  NULL, /* use disksize */
1735  NULL, /* free mem not deeded for short */
1738 };
1739 
1741 
1742 
1743 /*
1744  * tp_Type_id_map
1745  * This quickly maps a type identifier to a type structure.
1746  * This is dependent on the ordering of the DB_TYPE union so take
1747  * care when modifying either of these. It would be safer to build
1748  * this at run time.
1749  */
1751  &tp_Null,
1752  &tp_Integer,
1753  &tp_Float,
1754  &tp_Double,
1755  &tp_String,
1756  &tp_Object,
1757  &tp_Set,
1758  &tp_Multiset,
1759  &tp_Sequence,
1760  &tp_Elo,
1761  &tp_Time,
1762  &tp_Utime,
1763  &tp_Date,
1764  &tp_Monetary,
1765  &tp_Variable,
1766  &tp_Substructure,
1767  &tp_Pointer,
1768  &tp_Error,
1769  &tp_Short,
1770  &tp_Vobj,
1771  &tp_Oid,
1772  &tp_Null, /* place holder for DB_TYPE_DB_VALUE */
1773  &tp_Numeric,
1774  &tp_Bit,
1775  &tp_VarBit,
1776  &tp_Char,
1777  &tp_NChar,
1778  &tp_VarNChar,
1779  &tp_ResultSet,
1780  &tp_Midxkey,
1781  &tp_Null,
1782  &tp_Bigint,
1783  &tp_Datetime,
1784  &tp_Blob,
1785  &tp_Clob,
1786  &tp_Enumeration,
1787  &tp_Timestamptz,
1788  &tp_Timestampltz,
1789  &tp_Datetimetz,
1790  &tp_Datetimeltz,
1791  &tp_Json,
1792 };
1793 
1795  "resultset", DB_TYPE_RESULTSET, 0, sizeof (DB_RESULTSET), sizeof (DB_RESULTSET), 4,
1801  NULL, /* data_lengthmem */
1802  NULL, /* data_lengthval */
1807  NULL, /* index_lengthmem */
1808  NULL, /* index_lengthval */
1809  NULL, /* index_writeval */
1810  NULL, /* index_readval */
1811  NULL, /* index_cmpdisk */
1812  NULL, /* freemem */
1815 };
1816 
1818 
1819 /*
1820  * DB_VALUE MAINTENANCE
1821  */
1822 
1823 
1824 /*
1825  * pr_area_init - Initialize the area for allocation of value containers.
1826  * return: NO_ERROR or error code.
1827  * Note:
1828  * This must be called at a suitable point in system initialization.
1829  */
1830 int
1832 {
1833  Value_area = area_create ("Value containers", sizeof (DB_VALUE), VALUE_AREA_COUNT);
1834  if (Value_area == NULL)
1835  {
1836  assert (er_errid () != NO_ERROR);
1837  return er_errid ();
1838  }
1839 
1840  return NO_ERROR;
1841 }
1842 
1843 /*
1844  * pr_area_final - Finalize the area for allocation of value containers.
1845  * return: none.
1846  */
1847 void
1849 {
1850  if (Value_area != NULL)
1851  {
1852  area_destroy (Value_area);
1853  Value_area = NULL;
1854  }
1855 }
1856 
1857 /*
1858  * pr_make_value - create an internal value container
1859  * return: new value container
1860  * Note:
1861  * The value is allocated within the main workspace blocks so that
1862  * it will not serve as a root for the garbage collector.
1863  */
1864 DB_VALUE *
1866 {
1867  DB_VALUE *value;
1868 
1869  value = (DB_VALUE *) db_private_alloc (NULL, sizeof (DB_VALUE));
1870 
1871  if (value != NULL)
1872  {
1874  }
1875 
1876  return value;
1877 }
1878 
1879 /*
1880  * pr_make_ext_value - creates an external value container suitable for
1881  * passing beyond the interface layer to application programs.
1882  * return: new value container
1883  * Note:
1884  * It is allocated in the special Value_area so that it will serve as
1885  * a root to the garbage collector if the value contains a MOP.
1886  */
1887 DB_VALUE *
1889 {
1890  DB_VALUE *value;
1891 
1892  value = (DB_VALUE *) area_alloc (Value_area);
1893  if (value != NULL)
1894  {
1896  }
1897  return value;
1898 }
1899 
1900 /*
1901  * pr_clear_value - clear an internal or external DB_VALUE and
1902  * initialize it to the NULL state.
1903  * return: NO_ERROR
1904  * value(in/out): value to initialize
1905  * Note:
1906  * Any external allocations (strings, sets, etc) will be freed.
1907  *
1908  * There is too much type specific stuff in here. We need to create a
1909  * "freeval" type vector function to do this work.
1910  */
1911 int
1913 {
1914  char *midxkey_buf = NULL;
1915  const char *char_medium_buf = NULL;
1916  bool need_clear;
1917  DB_TYPE db_type;
1918 
1919  if (value == NULL)
1920  {
1921  return NO_ERROR; /* do nothing */
1922  }
1923 
1924  db_type = DB_VALUE_DOMAIN_TYPE (value);
1925 
1926  need_clear = true;
1927 
1928  if (DB_IS_NULL (value))
1929  {
1930  need_clear = false;
1931  if (value->need_clear)
1932  {
1934  { /* need to check */
1935  if ((QSTR_IS_ANY_CHAR_OR_BIT (db_type) && value->data.ch.medium.buf != NULL)
1936  || db_type == DB_TYPE_ENUMERATION)
1937  {
1938  need_clear = true; /* need to free Empty-string */
1939  }
1940  }
1941  }
1942  }
1943 
1944  if (need_clear == false)
1945  {
1946  return NO_ERROR; /* do nothing */
1947  }
1948 
1949  switch (db_type)
1950  {
1951  case DB_TYPE_JSON:
1952  if (value->need_clear)
1953  {
1954  if (value->data.json.document != NULL)
1955  {
1957  value->data.json.document = NULL;
1958  }
1959  if (value->data.json.schema_raw != NULL)
1960  {
1961  db_private_free (NULL, const_cast < char *>(value->data.json.schema_raw));
1962  value->data.json.schema_raw = NULL;
1963  }
1964  }
1965  else
1966  {
1967  value->data.json.document = NULL;
1968  value->data.json.schema_raw = NULL;
1969  }
1970  break;
1971 
1972  case DB_TYPE_OBJECT:
1973  /* we need to be sure to NULL the object pointer so that this db_value does not cause garbage collection problems
1974  * by retaining an object pointer. */
1975  value->data.op = NULL;
1976  break;
1977 
1978  case DB_TYPE_SET:
1979  case DB_TYPE_MULTISET:
1980  case DB_TYPE_SEQUENCE:
1981  case DB_TYPE_VOBJ:
1982  set_free (db_get_set (value));
1983  value->data.set = NULL;
1984  break;
1985 
1986  case DB_TYPE_MIDXKEY:
1987  midxkey_buf = value->data.midxkey.buf;
1988  if (midxkey_buf != NULL)
1989  {
1990  if (value->need_clear)
1991  {
1992  db_private_free_and_init (NULL, midxkey_buf);
1993  }
1994  /*
1995  * Ack, phfffft!!! why should we have to know about the
1996  * internals here?
1997  */
1998  value->data.midxkey.buf = NULL;
1999  }
2000  break;
2001 
2002  case DB_TYPE_VARCHAR:
2003  case DB_TYPE_CHAR:
2004  case DB_TYPE_NCHAR:
2005  case DB_TYPE_VARNCHAR:
2006  case DB_TYPE_BIT:
2007  case DB_TYPE_VARBIT:
2008  char_medium_buf = value->data.ch.medium.buf;
2009  if (char_medium_buf != NULL)
2010  {
2011  if (value->need_clear)
2012  {
2013  // here is safe to const_cast since the ownership was handed over by setting need_clear flag to true
2014  char *temp = CONST_CAST (char *, char_medium_buf);
2016  }
2017  /*
2018  * Ack, phfffft!!! why should we have to know about the
2019  * internals here?
2020  */
2021  value->data.ch.medium.buf = NULL;
2022  }
2023 
2024  /* Clear the compressed string since we are here for DB_TYPE_VARCHAR and DB_TYPE_VARNCHAR. */
2025  if (db_type == DB_TYPE_VARNCHAR || db_type == DB_TYPE_VARCHAR)
2026  {
2027  char *compressed_str = DB_GET_COMPRESSED_STRING (value);
2028  if (compressed_str != NULL)
2029  {
2030  if (value->data.ch.info.compressed_need_clear != 0)
2031  {
2032  // here is safe to const_cast since the ownership was handed over by setting need_clear flag to true
2033  db_private_free_and_init (NULL, compressed_str);
2034  }
2035  }
2036  db_set_compressed_string (value, NULL, 0, false);
2037  }
2038  else if (db_type == DB_TYPE_CHAR || db_type == DB_TYPE_NCHAR)
2039  {
2040  assert (value->data.ch.info.compressed_need_clear == 0);
2041  char *compressed_str = value->data.ch.medium.compressed_buf;
2042  if (compressed_str != NULL)
2043  {
2044  if (value->data.ch.info.compressed_need_clear != 0)
2045  {
2046  db_private_free_and_init (NULL, compressed_str);
2047  }
2048  }
2049 
2050  }
2051  break;
2052 
2053  case DB_TYPE_BLOB:
2054  case DB_TYPE_CLOB:
2055  if (value->need_clear)
2056  {
2057  elo_free_structure (db_get_elo (value));
2058  }
2059  break;
2060 
2061  case DB_TYPE_ENUMERATION:
2062  if (value->need_clear)
2063  {
2064  // here is safe to const_cast since the ownership was handed over by setting need_clear flag to true
2065  char *temp = CONST_CAST (char *, db_get_enum_string (value));
2066  if (temp != NULL)
2067  {
2069  }
2070  }
2071  db_make_enumeration (value, 0, NULL, 0, db_get_enum_codeset (value), db_get_enum_collation (value));
2072  break;
2073 
2074  default:
2075  break;
2076  }
2077 
2078  /* always make sure the value gets cleared */
2079  PRIM_SET_NULL (value);
2080  value->need_clear = false;
2081 
2082  return NO_ERROR;
2083 }
2084 
2085 /*
2086  * pr_clear_value_vector - clear a vector of db_values
2087  * references
2088  * return: void
2089  * value(in/out): vector of values
2090  */
2091 /* *INDENT-OFF* */
2092 void
2093 pr_clear_value_vector (std::vector<DB_VALUE> &value_vector)
2094 {
2095  for (DB_VALUE &dbval : value_vector)
2096  {
2097  pr_clear_value (&dbval);
2098  }
2099 }
2100 /* *INDENT-ON* */
2101 
2102 /*
2103  * pr_free_value - free an internval value container any anything that it
2104  * references
2105  * return: NO_ERROR if successful, error code otherwise
2106  * value(in/out): value to clear & free
2107  */
2108 int
2110 {
2111  int error = NO_ERROR;
2112 
2113  if (value != NULL)
2114  {
2115  /* some redundant checking but I want the semantics isolated */
2116  error = pr_clear_value (value);
2117  db_private_free_and_init (NULL, value);
2118  }
2119  return error;
2120 }
2121 
2122 /*
2123  * pr_free_ext_value - free an external value container and anything that it
2124  * references.
2125  * return:
2126  * value(in/out): external value to clear & free
2127  * Note:
2128  * Identical to pr_free_value except that it frees the value to the
2129  * Value_area instead of to the workspace.
2130  */
2131 int
2133 {
2134  int error = NO_ERROR;
2135 
2136  if (value != NULL)
2137  {
2138  /* some redundant checking but I want the semantics isolated */
2139  error = pr_clear_value (value);
2140  (void) area_free (Value_area, (void *) value);
2141  }
2142  return error;
2143 }
2144 
2145 /*
2146  * pr_clone_value - copy the contents of one value container to another.
2147  * return: none
2148  * src(in): source value
2149  * dest(out): destination value
2150  * Note:
2151  * For types that contain external allocations (like strings).
2152  * The contents are copied.
2153  */
2154 int
2155 pr_clone_value (const DB_VALUE * src, DB_VALUE * dest)
2156 {
2157  PR_TYPE *type;
2158  DB_TYPE src_dbtype;
2159 
2160  if (dest != NULL)
2161  {
2162  if (src == NULL)
2163  {
2164  db_make_null (dest);
2165  }
2166  else
2167  {
2168  src_dbtype = DB_VALUE_DOMAIN_TYPE (src);
2169 
2170  if (DB_IS_NULL (src))
2171  {
2172  db_value_domain_init (dest, src_dbtype, DB_VALUE_PRECISION (src), DB_VALUE_SCALE (src));
2173  }
2174  else if (src != dest)
2175  {
2176  type = pr_type_from_id (src_dbtype);
2177  if (type != NULL)
2178  {
2179  /*
2180  * Formerly called "initval" here but that was removed as
2181  * "setval" is supposed to properly initialize the
2182  * destination domain. No need to do it twice.
2183  * Make sure the COPY flag is set in the setval call.
2184  */
2185  type->setval (dest, src, true);
2186  }
2187  else
2188  {
2189  /*
2190  * can only get here in error conditions, initialize to NULL
2191  */
2192  db_make_null (dest);
2193  }
2194  }
2195  }
2196  }
2197 
2198  return NO_ERROR;
2199 }
2200 
2201 /*
2202  * pr_copy_value - This creates a new internal value container with a copy
2203  * of the contents of the source container.
2204  * return: new value
2205  * value(in): value to copy
2206  */
2207 DB_VALUE *
2209 {
2210  DB_VALUE *new_ = NULL;
2211 
2212  if (value != NULL)
2213  {
2214  new_ = pr_make_value ();
2215  if (pr_clone_value (value, new_) != NO_ERROR)
2216  {
2217  /*
2218  * oh well, couldn't allocate storage for the clone.
2219  * Note that pr_free_value can only return errors in the
2220  * case where the value has been initialized so it won't
2221  * stomp on the error code if we call it here
2222  */
2223  pr_free_value (new_);
2224  new_ = NULL;
2225  }
2226  }
2227  return new_;
2228 }
2229 
2230 /*
2231  * TYPE NULL
2232  */
2233 
2234 /*
2235  * This is largely a placeholder type that does nothing except assert
2236  * that the size of a NULL value is zero.
2237  * The "mem" functions are no-ops since NULL is not a valid domain type.
2238  * The "value" functions don't do much, they just make sure the value
2239  * domain is initialized.
2240  *
2241  */
2242 
2243 /*
2244  * mr_initmem_null - dummy function
2245  * return:
2246  * memptr():
2247  */
2248 static void
2249 mr_initmem_null (void *memptr, TP_DOMAIN * domain)
2250 {
2251 }
2252 
2253 /*
2254  * mr_setmem_null - dummy function
2255  * return:
2256  * memptr():
2257  * domain():
2258  * value():
2259  */
2260 static int
2261 mr_setmem_null (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
2262 {
2263  return NO_ERROR;
2264 }
2265 
2266 /*
2267  * mr_getmem_null - dummy function
2268  * return:
2269  * memptr():
2270  * domain():
2271  * value():
2272  * copy():
2273  */
2274 static int
2275 mr_getmem_null (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
2276 {
2277  db_make_null (value);
2278  return NO_ERROR;
2279 }
2280 
2281 /*
2282  * mr_writemem_null - dummy function
2283  * return:
2284  * buf():
2285  * memptr():
2286  * domain():
2287  */
2288 static void
2289 mr_data_writemem_null (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
2290 {
2291 }
2292 
2293 /*
2294  * mr_readmem_null - dummy function
2295  * return:
2296  * buf():
2297  * memptr():
2298  * domain():
2299  * size():
2300  */
2301 static void
2302 mr_data_readmem_null (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
2303 {
2304 }
2305 
2306 static void
2307 mr_initval_null (DB_VALUE * value, int precision, int scale)
2308 {
2309  db_value_domain_init (value, DB_TYPE_NULL, precision, scale);
2310 }
2311 
2312 /*
2313  * mr_setval_null - dummy function
2314  * return:
2315  * dest():
2316  * src():
2317  * copy():
2318  */
2319 static int
2320 mr_setval_null (DB_VALUE * dest, const DB_VALUE * src, bool copy)
2321 {
2322  mr_initval_null (dest, 0, 0);
2323  return NO_ERROR;
2324 }
2325 
2326 /*
2327  * mr_writeval_null - dummy function
2328  * return:
2329  * buf():
2330  * value():
2331  */
2332 static int
2334 {
2335  return NO_ERROR;
2336 }
2337 
2338 /*
2339  * mr_readval_null - dummy function
2340  * return:
2341  * buf():
2342  * value():
2343  * domain():
2344  * size():
2345  * copy():
2346  * copy_buf():
2347  * copy_buf_len():
2348  */
2349 static int
2350 mr_data_readval_null (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2351  int copy_buf_len)
2352 {
2353  if (value)
2354  {
2355  db_make_null (value);
2356  value->need_clear = false;
2357  }
2358  return NO_ERROR;
2359 }
2360 
2361 /*
2362  * mr_cmpdisk_null - dummy function
2363  * return:
2364  * mem1():
2365  * mem2():
2366  * domain():
2367  * do_coercion():
2368  * total_order():
2369  * start_colp():
2370  */
2372 mr_data_cmpdisk_null (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2373 {
2374  assert (domain != NULL);
2375 
2376  return DB_UNK;
2377 }
2378 
2379 /*
2380  * mr_cmpval_null - dummy function
2381  * return:
2382  * value1():
2383  * value2():
2384  * do_coercion():
2385  * total_order():
2386  * start_colp():
2387  */
2389 mr_cmpval_null (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
2390 {
2391  return DB_UNK;
2392 }
2393 
2394 
2395 /*
2396  * TYPE INTEGER
2397  *
2398  * Your basic 32 bit signed integral value.
2399  * At the storage level, we don't really care whether it is signed or unsigned.
2400  */
2401 
2402 static void
2403 mr_initmem_int (void *mem, TP_DOMAIN * domain)
2404 {
2405  *(int *) mem = 0;
2406 }
2407 
2408 static int
2409 mr_setmem_int (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
2410 {
2411  if (value != NULL)
2412  *(int *) mem = db_get_int (value);
2413  else
2414  mr_initmem_int (mem, domain);
2415 
2416  return NO_ERROR;
2417 }
2418 
2419 static int
2420 mr_getmem_int (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
2421 {
2422  return db_make_int (value, *(int *) mem);
2423 }
2424 
2425 static void
2426 mr_data_writemem_int (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
2427 {
2428  or_put_int (buf, *(int *) mem);
2429 }
2430 
2431 static void
2432 mr_data_readmem_int (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
2433 {
2434  int rc = NO_ERROR;
2435 
2436  if (mem == NULL)
2437  {
2438  or_advance (buf, tp_Integer.disksize);
2439  }
2440  else
2441  {
2442  *(int *) mem = or_get_int (buf, &rc);
2443  }
2444 }
2445 
2446 static void
2447 mr_initval_int (DB_VALUE * value, int precision, int scale)
2448 {
2449  db_value_domain_init (value, DB_TYPE_INTEGER, precision, scale);
2450  db_make_int (value, 0);
2451 }
2452 
2453 static int
2454 mr_setval_int (DB_VALUE * dest, const DB_VALUE * src, bool copy)
2455 {
2456  if (src && !DB_IS_NULL (src))
2457  {
2458  return db_make_int (dest, db_get_int (src));
2459  }
2460  else
2461  {
2463  }
2464 }
2465 
2466 static int
2468 {
2469  return or_put_int (buf, db_get_int (value));
2470 }
2471 
2472 static int
2473 mr_data_readval_int (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2474  int copy_buf_len)
2475 {
2476  int temp_int, rc = NO_ERROR;
2477 
2478  if (value == NULL)
2479  {
2480  rc = or_advance (buf, tp_Integer.disksize);
2481  }
2482  else
2483  {
2484  temp_int = or_get_int (buf, &rc);
2485  if (rc == NO_ERROR)
2486  {
2487  db_make_int (value, temp_int);
2488  }
2489  value->need_clear = false;
2490  }
2491  return rc;
2492 }
2493 
2494 static int
2496 {
2497  int i;
2498 
2499  i = db_get_int (value);
2500 
2501  return or_put_data (buf, (char *) (&i), tp_Integer.disksize);
2502 }
2503 
2504 static int
2505 mr_index_readval_int (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2506  int copy_buf_len)
2507 {
2508  int i, rc = NO_ERROR;
2509 
2510  if (value == NULL)
2511  {
2512  rc = or_advance (buf, tp_Integer.disksize);
2513  }
2514  else
2515  {
2516  rc = or_get_data (buf, (char *) (&i), tp_Integer.disksize);
2517  if (rc == NO_ERROR)
2518  {
2519  db_make_int (value, i);
2520  }
2521  value->need_clear = false;
2522  }
2523  return rc;
2524 }
2525 
2527 mr_index_cmpdisk_int (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2528 {
2529  int i1, i2;
2530 
2531  assert (domain != NULL);
2532 
2533  COPYMEM (int, &i1, mem1);
2534  COPYMEM (int, &i2, mem2);
2535 
2536  return MR_CMP (i1, i2);
2537 }
2538 
2540 mr_data_cmpdisk_int (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2541 {
2542  int i1, i2;
2543 
2544  assert (domain != NULL);
2545 
2546  i1 = OR_GET_INT (mem1);
2547  i2 = OR_GET_INT (mem2);
2548 
2549  return MR_CMP (i1, i2);
2550 }
2551 
2553 mr_cmpval_int (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
2554 {
2555  int i1, i2;
2556 
2557  i1 = db_get_int (value1);
2558  i2 = db_get_int (value2);
2559 
2560  return MR_CMP (i1, i2);
2561 }
2562 
2563 /*
2564  * TYPE SHORT
2565  *
2566  * Your basic 16 bit signed integral value.
2567  */
2568 
2569 static void
2570 mr_initmem_short (void *mem, TP_DOMAIN * domain)
2571 {
2572  *(short *) mem = 0;
2573 }
2574 
2575 static int
2576 mr_setmem_short (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
2577 {
2578  if (value == NULL)
2579  mr_initmem_short (mem, domain);
2580  else
2581  *(short *) mem = db_get_short (value);
2582 
2583  return NO_ERROR;
2584 }
2585 
2586 static int
2587 mr_getmem_short (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
2588 {
2589  return db_make_short (value, *(short *) mem);
2590 }
2591 
2592 static void
2593 mr_data_writemem_short (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
2594 {
2595  short *mem = (short *) memptr;
2596 
2597  or_put_short (buf, *mem);
2598 }
2599 
2600 static void
2601 mr_data_readmem_short (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
2602 {
2603  int rc = NO_ERROR;
2604 
2605  if (mem == NULL)
2606  {
2607  or_advance (buf, tp_Short.disksize);
2608  }
2609  else
2610  {
2611  *(short *) mem = or_get_short (buf, &rc);
2612  }
2613 }
2614 
2615 static void
2616 mr_initval_short (DB_VALUE * value, int precision, int scale)
2617 {
2618  db_value_domain_init (value, DB_TYPE_SHORT, precision, scale);
2619  db_make_short (value, 0);
2620 }
2621 
2622 static int
2623 mr_setval_short (DB_VALUE * dest, const DB_VALUE * src, bool copy)
2624 {
2625  if (src && !DB_IS_NULL (src))
2626  {
2627  return db_make_short (dest, db_get_short (src));
2628  }
2629  else
2630  {
2632  }
2633 }
2634 
2635 static int
2637 {
2638  return or_put_short (buf, db_get_short (value));
2639 }
2640 
2641 static int
2642 mr_data_readval_short (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2643  int copy_buf_len)
2644 {
2645  int rc = NO_ERROR;
2646  short s;
2647 
2648  if (value == NULL)
2649  {
2650  rc = or_advance (buf, tp_Short.disksize);
2651  }
2652  else
2653  {
2654  s = (short) or_get_short (buf, &rc);
2655  if (rc == NO_ERROR)
2656  {
2657  db_make_short (value, s);
2658  }
2659  value->need_clear = false;
2660  }
2661 
2662  return rc;
2663 }
2664 
2665 static int
2667 {
2668  short s;
2669 
2670  s = db_get_short (value);
2671 
2672  return or_put_data (buf, (char *) (&s), tp_Short.disksize);
2673 }
2674 
2675 static int
2676 mr_index_readval_short (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2677  int copy_buf_len)
2678 {
2679  int rc = NO_ERROR;
2680  short s;
2681 
2682  if (value == NULL)
2683  {
2684  rc = or_advance (buf, tp_Short.disksize);
2685  }
2686  else
2687  {
2688  rc = or_get_data (buf, (char *) (&s), tp_Short.disksize);
2689  if (rc == NO_ERROR)
2690  {
2691  db_make_short (value, s);
2692  }
2693  value->need_clear = false;
2694  }
2695 
2696  return rc;
2697 }
2698 
2700 mr_index_cmpdisk_short (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2701 {
2702  short s1, s2;
2703 
2704  assert (domain != NULL);
2705 
2706  COPYMEM (short, &s1, mem1);
2707  COPYMEM (short, &s2, mem2);
2708 
2709  return MR_CMP (s1, s2);
2710 }
2711 
2713 mr_data_cmpdisk_short (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2714 {
2715  short s1, s2;
2716 
2717  assert (domain != NULL);
2718 
2719  s1 = OR_GET_SHORT (mem1);
2720  s2 = OR_GET_SHORT (mem2);
2721 
2722  return MR_CMP (s1, s2);
2723 }
2724 
2726 mr_cmpval_short (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
2727 {
2728  short s1, s2;
2729 
2730  s1 = db_get_short (value1);
2731  s2 = db_get_short (value2);
2732 
2733  return MR_CMP (s1, s2);
2734 }
2735 
2736 /*
2737  * TYPE BIGINT
2738  *
2739  * Your basic 64 bit signed integral value.
2740  * At the storage level, we don't really care whether it is signed or unsigned.
2741  */
2742 
2743 static void
2744 mr_initmem_bigint (void *mem, TP_DOMAIN * domain)
2745 {
2746  *(DB_BIGINT *) mem = 0;
2747 }
2748 
2749 static int
2750 mr_setmem_bigint (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
2751 {
2752  if (value != NULL)
2753  *(DB_BIGINT *) mem = db_get_bigint (value);
2754  else
2755  mr_initmem_bigint (mem, domain);
2756 
2757  return NO_ERROR;
2758 }
2759 
2760 static int
2761 mr_getmem_bigint (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
2762 {
2763  return db_make_bigint (value, *(DB_BIGINT *) mem);
2764 }
2765 
2766 static void
2767 mr_data_writemem_bigint (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
2768 {
2769  or_put_bigint (buf, *(DB_BIGINT *) mem);
2770 }
2771 
2772 static void
2773 mr_data_readmem_bigint (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
2774 {
2775  int rc = NO_ERROR;
2776 
2777  if (mem == NULL)
2778  {
2779  or_advance (buf, tp_Bigint.disksize);
2780  }
2781  else
2782  {
2783  *(DB_BIGINT *) mem = or_get_bigint (buf, &rc);
2784  }
2785 }
2786 
2787 static void
2788 mr_initval_bigint (DB_VALUE * value, int precision, int scale)
2789 {
2790  db_value_domain_init (value, DB_TYPE_BIGINT, precision, scale);
2791  db_make_bigint (value, 0);
2792 }
2793 
2794 static int
2795 mr_setval_bigint (DB_VALUE * dest, const DB_VALUE * src, bool copy)
2796 {
2797  if (src && !DB_IS_NULL (src))
2798  {
2799  return db_make_bigint (dest, db_get_bigint (src));
2800  }
2801  else
2802  {
2804  }
2805 }
2806 
2807 static int
2809 {
2810  return or_put_bigint (buf, db_get_bigint (value));
2811 }
2812 
2813 static int
2814 mr_data_readval_bigint (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2815  int copy_buf_len)
2816 {
2817  int rc = NO_ERROR;
2818  DB_BIGINT temp_int;
2819 
2820  if (value == NULL)
2821  {
2822  rc = or_advance (buf, tp_Bigint.disksize);
2823  }
2824  else
2825  {
2826  temp_int = or_get_bigint (buf, &rc);
2827  if (rc == NO_ERROR)
2828  {
2829  db_make_bigint (value, temp_int);
2830  }
2831  value->need_clear = false;
2832  }
2833  return rc;
2834 }
2835 
2836 static int
2838 {
2839  DB_BIGINT bi;
2840 
2841  bi = db_get_bigint (value);
2842 
2843  return or_put_data (buf, (char *) (&bi), tp_Bigint.disksize);
2844 }
2845 
2846 static int
2847 mr_index_readval_bigint (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2848  int copy_buf_len)
2849 {
2850  int rc = NO_ERROR;
2851  DB_BIGINT bi;
2852 
2853  if (value == NULL)
2854  {
2855  rc = or_advance (buf, tp_Bigint.disksize);
2856  }
2857  else
2858  {
2859  rc = or_get_data (buf, (char *) (&bi), tp_Bigint.disksize);
2860  if (rc == NO_ERROR)
2861  {
2862  db_make_bigint (value, bi);
2863  }
2864  value->need_clear = false;
2865  }
2866 
2867  return rc;
2868 }
2869 
2871 mr_index_cmpdisk_bigint (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2872 {
2873  DB_BIGINT i1, i2;
2874 
2875  assert (domain != NULL);
2876 
2877  COPYMEM (DB_BIGINT, &i1, mem1);
2878  COPYMEM (DB_BIGINT, &i2, mem2);
2879 
2880  return MR_CMP (i1, i2);
2881 }
2882 
2884 mr_data_cmpdisk_bigint (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
2885 {
2886  DB_BIGINT i1, i2;
2887 
2888  assert (domain != NULL);
2889 
2890  OR_GET_BIGINT (mem1, &i1);
2891  OR_GET_BIGINT (mem2, &i2);
2892 
2893  return MR_CMP (i1, i2);
2894 }
2895 
2897 mr_cmpval_bigint (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
2898  int collation)
2899 {
2900  DB_BIGINT i1, i2;
2901 
2902  i1 = db_get_bigint (value1);
2903  i2 = db_get_bigint (value2);
2904 
2905  return MR_CMP (i1, i2);
2906 }
2907 
2908 /*
2909  * TYPE FLOAT
2910  *
2911  * IEEE single precision floating point values.
2912  */
2913 
2914 static void
2915 mr_initmem_float (void *mem, TP_DOMAIN * domain)
2916 {
2917  *(float *) mem = 0.0;
2918 }
2919 
2920 static int
2921 mr_setmem_float (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
2922 {
2923  if (value == NULL)
2924  {
2925  mr_initmem_float (mem, domain);
2926  }
2927  else
2928  {
2929  *(float *) mem = db_get_float (value);
2930  }
2931 
2932  return NO_ERROR;
2933 }
2934 
2935 static int
2936 mr_getmem_float (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
2937 {
2938  return db_make_float (value, *(float *) mem);
2939 }
2940 
2941 static void
2942 mr_data_writemem_float (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
2943 {
2944  or_put_float (buf, *(float *) mem);
2945 }
2946 
2947 static void
2948 mr_data_readmem_float (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
2949 {
2950  int rc = NO_ERROR;
2951 
2952  if (mem == NULL)
2953  {
2954  or_advance (buf, tp_Float.disksize);
2955  }
2956  else
2957  {
2958  *(float *) mem = or_get_float (buf, &rc);
2959  }
2960 }
2961 
2962 static void
2963 mr_initval_float (DB_VALUE * value, int precision, int scale)
2964 {
2965  db_make_float (value, 0.0);
2966  value->need_clear = false;
2967 }
2968 
2969 static int
2970 mr_setval_float (DB_VALUE * dest, const DB_VALUE * src, bool copy)
2971 {
2972  if (src && !DB_IS_NULL (src))
2973  {
2974  return db_make_float (dest, db_get_float (src));
2975  }
2976  else
2977  {
2979  }
2980 }
2981 
2982 static int
2984 {
2985  return or_put_float (buf, db_get_float (value));
2986 }
2987 
2988 static int
2989 mr_data_readval_float (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
2990  int copy_buf_len)
2991 {
2992  float temp;
2993  int rc = NO_ERROR;
2994 
2995  if (value == NULL)
2996  {
2997  rc = or_advance (buf, tp_Float.disksize);
2998  }
2999  else
3000  {
3001  temp = or_get_float (buf, &rc);
3002  if (rc == NO_ERROR)
3003  {
3004  db_make_float (value, temp);
3005  }
3006  value->need_clear = false;
3007  }
3008  return rc;
3009 }
3010 
3011 static int
3013 {
3014  float f;
3015 
3016  f = db_get_float (value);
3017 
3018  return or_put_data (buf, (char *) (&f), tp_Float.disksize);
3019 }
3020 
3021 static int
3022 mr_index_readval_float (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3023  int copy_buf_len)
3024 {
3025  float f;
3026  int rc = NO_ERROR;
3027 
3028  if (value == NULL)
3029  {
3030  rc = or_advance (buf, tp_Float.disksize);
3031  }
3032  else
3033  {
3034  rc = or_get_data (buf, (char *) (&f), tp_Float.disksize);
3035  if (rc == NO_ERROR)
3036  {
3037  db_make_float (value, f);
3038  }
3039  value->need_clear = false;
3040  }
3041 
3042  return rc;
3043 }
3044 
3046 mr_index_cmpdisk_float (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3047 {
3048  float f1, f2;
3049 
3050  assert (domain != NULL);
3051 
3052  COPYMEM (float, &f1, mem1);
3053  COPYMEM (float, &f2, mem2);
3054 
3055  return MR_CMP (f1, f2);
3056 }
3057 
3059 mr_data_cmpdisk_float (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3060 {
3061  float f1, f2;
3062 
3063  assert (domain != NULL);
3064 
3065  OR_GET_FLOAT (mem1, &f1);
3066  OR_GET_FLOAT (mem2, &f2);
3067 
3068  return MR_CMP (f1, f2);
3069 }
3070 
3072 mr_cmpval_float (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
3073 {
3074  float f1, f2;
3075 
3076  f1 = db_get_float (value1);
3077  f2 = db_get_float (value2);
3078 
3079  return MR_CMP (f1, f2);
3080 }
3081 
3082 /*
3083  * TYPE DOUBLE
3084  *
3085  * IEEE double precision floating vlaues.
3086  * Remember the pointer here isn't necessarily valid as a "double*"
3087  * because the value may be packed into the object such that it
3088  * doesn't fall on a double word boundary.
3089  *
3090  */
3091 
3092 static void
3093 mr_initmem_double (void *mem, TP_DOMAIN * domain)
3094 {
3095  double d = 0.0;
3096 
3097  OR_MOVE_DOUBLE (&d, mem);
3098 }
3099 
3100 static int
3101 mr_setmem_double (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
3102 {
3103  double d;
3104 
3105  if (value == NULL)
3106  {
3107  mr_initmem_double (mem, domain);
3108  }
3109  else
3110  {
3111  d = db_get_double (value);
3112  OR_MOVE_DOUBLE (&d, mem);
3113  }
3114  return NO_ERROR;
3115 }
3116 
3117 static int
3118 mr_getmem_double (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3119 {
3120  double d = 0;
3121 
3122  OR_MOVE_DOUBLE (mem, &d);
3123  return db_make_double (value, d);
3124 }
3125 
3126 static void
3127 mr_data_writemem_double (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
3128 {
3129  double d = 0;
3130 
3131  OR_MOVE_DOUBLE (mem, &d);
3132  or_put_double (buf, d);
3133 }
3134 
3135 static void
3136 mr_data_readmem_double (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
3137 {
3138  double d;
3139  int rc = NO_ERROR;
3140 
3141  if (mem == NULL)
3142  {
3143  or_advance (buf, tp_Double.disksize);
3144  }
3145  else
3146  {
3147  d = or_get_double (buf, &rc);
3148  OR_MOVE_DOUBLE (&d, mem);
3149  }
3150 }
3151 
3152 static void
3153 mr_initval_double (DB_VALUE * value, int precision, int scale)
3154 {
3155  db_value_domain_init (value, DB_TYPE_DOUBLE, precision, scale);
3156  db_make_double (value, 0.0);
3157 }
3158 
3159 static int
3160 mr_setval_double (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3161 {
3162  if (src && !DB_IS_NULL (src))
3163  {
3164  return db_make_double (dest, db_get_double (src));
3165  }
3166  else
3167  {
3169  }
3170 }
3171 
3172 static int
3174 {
3175  return or_put_double (buf, db_get_double (value));
3176 }
3177 
3178 static int
3179 mr_data_readval_double (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3180  int copy_buf_len)
3181 {
3182  double temp;
3183  int rc = NO_ERROR;
3184 
3185  if (value == NULL)
3186  {
3187  rc = or_advance (buf, tp_Double.disksize);
3188  }
3189  else
3190  {
3191  temp = or_get_double (buf, &rc);
3192  if (rc == NO_ERROR)
3193  {
3194  db_make_double (value, temp);
3195  }
3196  value->need_clear = false;
3197  }
3198 
3199  return rc;
3200 }
3201 
3202 static int
3204 {
3205  double d;
3206 
3207  d = db_get_double (value);
3208 
3209  return or_put_data (buf, (char *) (&d), tp_Double.disksize);
3210 }
3211 
3212 static int
3213 mr_index_readval_double (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3214  int copy_buf_len)
3215 {
3216  double d;
3217  int rc = NO_ERROR;
3218 
3219  if (value == NULL)
3220  {
3221  rc = or_advance (buf, tp_Double.disksize);
3222  }
3223  else
3224  {
3225  rc = or_get_data (buf, (char *) (&d), tp_Double.disksize);
3226  if (rc == NO_ERROR)
3227  {
3228  db_make_double (value, d);
3229  }
3230  value->need_clear = false;
3231  }
3232 
3233  return rc;
3234 }
3235 
3237 mr_index_cmpdisk_double (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3238 {
3239  double d1, d2;
3240 
3241  assert (domain != NULL);
3242 
3243  COPYMEM (double, &d1, mem1);
3244  COPYMEM (double, &d2, mem2);
3245 
3246  return MR_CMP (d1, d2);
3247 }
3248 
3250 mr_data_cmpdisk_double (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3251 {
3252  double d1, d2;
3253 
3254  assert (domain != NULL);
3255 
3256  OR_GET_DOUBLE (mem1, &d1);
3257  OR_GET_DOUBLE (mem2, &d2);
3258 
3259  return MR_CMP (d1, d2);
3260 }
3261 
3263 mr_cmpval_double (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
3264  int collation)
3265 {
3266  double d1, d2;
3267 
3268  d1 = db_get_double (value1);
3269  d2 = db_get_double (value2);
3270 
3271  return MR_CMP (d1, d2);
3272 }
3273 
3274 /*
3275  * TYPE TIME
3276  *
3277  * 32 bit seconds counter. Interpreted as an offset within a given day.
3278  * Probably not general enough currently to be used an an interval type?
3279  *
3280  */
3281 
3282 static void
3283 mr_initmem_time (void *mem, TP_DOMAIN * domain)
3284 {
3285  *(DB_TIME *) mem = 0;
3286 }
3287 
3288 static int
3289 mr_setmem_time (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
3290 {
3291  if (value == NULL)
3292  mr_initmem_time (mem, domain);
3293  else
3294  *(DB_TIME *) mem = *db_get_time (value);
3295 
3296  return NO_ERROR;
3297 }
3298 
3299 static int
3300 mr_getmem_time (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3301 {
3302  (void) db_value_put_encoded_time (value, (DB_TIME *) mem);
3303  value->need_clear = false;
3304  return NO_ERROR;
3305 }
3306 
3307 static void
3308 mr_data_writemem_time (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
3309 {
3310  or_put_time (buf, (DB_TIME *) mem);
3311 }
3312 
3313 static void
3314 mr_data_readmem_time (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
3315 {
3316  if (mem == NULL)
3317  {
3318  or_advance (buf, tp_Time.disksize);
3319  }
3320  else
3321  {
3322  or_get_time (buf, (DB_TIME *) mem);
3323  }
3324 }
3325 
3326 static void
3327 mr_initval_time (DB_VALUE * value, int precision, int scale)
3328 {
3329  DB_TIME tm = 0;
3330 
3331  db_value_put_encoded_time (value, &tm);
3332  value->need_clear = false;
3333 }
3334 
3335 static int
3336 mr_setval_time (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3337 {
3338  int error;
3339 
3340  if (DB_IS_NULL (src))
3341  {
3343  }
3344  else
3345  {
3346  error = db_value_put_encoded_time (dest, db_get_time (src));
3347  }
3348  return error;
3349 }
3350 
3351 static int
3353 {
3354  return or_put_time (buf, db_get_time (value));
3355 }
3356 
3357 static int
3358 mr_data_readval_time (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3359  int copy_buf_len)
3360 {
3361  DB_TIME tm;
3362  int rc = NO_ERROR;
3363 
3364  if (value == NULL)
3365  {
3366  rc = or_advance (buf, tp_Time.disksize);
3367  }
3368  else
3369  {
3370  rc = or_get_time (buf, &tm);
3371  if (rc == NO_ERROR)
3372  {
3373  db_value_put_encoded_time (value, &tm);
3374  }
3375  value->need_clear = false;
3376  }
3377  return rc;
3378 }
3379 
3380 static int
3382 {
3383  DB_TIME *tm;
3384 
3385  tm = db_get_time (value);
3386 
3387  return or_put_data (buf, (char *) tm, tp_Time.disksize);
3388 }
3389 
3390 static int
3391 mr_index_readval_time (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3392  int copy_buf_len)
3393 {
3394  DB_TIME tm;
3395  int rc = NO_ERROR;
3396 
3397  if (value == NULL)
3398  {
3399  rc = or_advance (buf, tp_Time.disksize);
3400  }
3401  else
3402  {
3403  rc = or_get_data (buf, (char *) (&tm), tp_Time.disksize);
3404  if (rc == NO_ERROR)
3405  {
3406  db_value_put_encoded_time (value, &tm);
3407  }
3408  value->need_clear = false;
3409  }
3410 
3411  return rc;
3412 }
3413 
3415 mr_index_cmpdisk_time (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3416 {
3417  DB_TIME t1, t2;
3418 
3419  assert (domain != NULL);
3420 
3421  COPYMEM (DB_TIME, &t1, mem1);
3422  COPYMEM (DB_TIME, &t2, mem2);
3423 
3424  return MR_CMP (t1, t2);
3425 }
3426 
3428 mr_data_cmpdisk_time (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3429 {
3430  DB_TIME t1, t2;
3431 
3432  assert (domain != NULL);
3433 
3434  OR_GET_TIME (mem1, &t1);
3435  OR_GET_TIME (mem2, &t2);
3436 
3437  return MR_CMP (t1, t2);
3438 }
3439 
3441 mr_cmpval_time (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
3442 {
3443  const DB_TIME *t1, *t2;
3444 
3445  t1 = db_get_time (value1);
3446  t2 = db_get_time (value2);
3447 
3448  return MR_CMP (*t1, *t2);
3449 }
3450 
3451 /*
3452  * TYPE UTIME
3453  *
3454  * "Universal" time, more recently known as a "timestamp".
3455  * These are 32 bit encoded values that contain both a date and time
3456  * identification.
3457  * The encoding is the standard Unix "time_t" format.
3458  */
3459 
3460 static void
3461 mr_initmem_utime (void *mem, TP_DOMAIN * domain)
3462 {
3463  *(DB_UTIME *) mem = 0;
3464 }
3465 
3466 static int
3467 mr_setmem_utime (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
3468 {
3469  if (value == NULL)
3470  mr_initmem_utime (mem, domain);
3471  else
3472  *(DB_UTIME *) mem = *db_get_timestamp (value);
3473 
3474  return NO_ERROR;
3475 }
3476 
3477 static int
3478 mr_getmem_utime (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3479 {
3480  int error;
3481 
3482  error = db_make_utime (value, *(DB_UTIME *) mem);
3483  value->need_clear = false;
3484  return error;
3485 }
3486 
3487 static int
3488 mr_getmem_timestampltz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3489 {
3490  int error;
3491 
3492  error = db_make_timestampltz (value, *(DB_UTIME *) mem);
3493  value->need_clear = false;
3494  return error;
3495 }
3496 
3497 static void
3498 mr_data_writemem_utime (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
3499 {
3500  or_put_utime (buf, (DB_UTIME *) mem);
3501 }
3502 
3503 static void
3504 mr_data_readmem_utime (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
3505 {
3506  if (mem == NULL)
3507  {
3508  or_advance (buf, tp_Utime.disksize);
3509  }
3510  else
3511  {
3512  or_get_utime (buf, (DB_UTIME *) mem);
3513  }
3514 }
3515 
3516 static void
3517 mr_initval_utime (DB_VALUE * value, int precision, int scale)
3518 {
3519  db_make_utime (value, 0);
3520  value->need_clear = false;
3521 }
3522 
3523 static void
3524 mr_initval_timestampltz (DB_VALUE * value, int precision, int scale)
3525 {
3526  db_make_timestampltz (value, 0);
3527  value->need_clear = false;
3528 }
3529 
3530 static int
3531 mr_setval_utime (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3532 {
3533  int error;
3534 
3535  if (DB_IS_NULL (src))
3536  {
3538  }
3539  else
3540  {
3541  error = db_make_utime (dest, *db_get_timestamp (src));
3542  }
3543  return error;
3544 }
3545 
3546 static int
3547 mr_setval_timestampltz (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3548 {
3549  int error;
3550 
3551  if (DB_IS_NULL (src))
3552  {
3554  }
3555  else
3556  {
3557  error = db_make_timestampltz (dest, *db_get_timestamp (src));
3558  }
3559  return error;
3560 }
3561 
3562 static int
3564 {
3565  return or_put_utime (buf, db_get_timestamp (value));
3566 }
3567 
3568 static int
3569 mr_data_readval_utime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3570  int copy_buf_len)
3571 {
3572  DB_UTIME utm;
3573  int rc = NO_ERROR;
3574 
3575  if (value == NULL)
3576  {
3577  rc = or_advance (buf, tp_Utime.disksize);
3578  }
3579  else
3580  {
3581  rc = or_get_utime (buf, &utm);
3582  if (rc == NO_ERROR)
3583  {
3584  db_make_utime (value, utm);
3585  }
3586  value->need_clear = false;
3587  }
3588  return rc;
3589 }
3590 
3591 static int
3592 mr_data_readval_timestampltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3593  int copy_buf_len)
3594 {
3595  DB_UTIME utm;
3596  int rc = NO_ERROR;
3597 
3598  if (value == NULL)
3599  {
3600  rc = or_advance (buf, tp_Timestampltz.disksize);
3601  }
3602  else
3603  {
3604  rc = or_get_utime (buf, &utm);
3605  db_make_timestampltz (value, utm);
3606  value->need_clear = false;
3607  }
3608  return rc;
3609 }
3610 
3611 static int
3613 {
3614  DB_UTIME *utm;
3615 
3616  utm = db_get_timestamp (value);
3617 
3618  return or_put_data (buf, (char *) utm, tp_Utime.disksize);
3619 }
3620 
3621 static int
3622 mr_index_readval_utime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3623  int copy_buf_len)
3624 {
3625  DB_UTIME utm;
3626  int rc = NO_ERROR;
3627 
3628  if (value == NULL)
3629  {
3630  rc = or_advance (buf, tp_Utime.disksize);
3631  }
3632  else
3633  {
3634  rc = or_get_data (buf, (char *) (&utm), tp_Utime.disksize);
3635  if (rc == NO_ERROR)
3636  {
3637  db_make_utime (value, utm);
3638  }
3639  value->need_clear = false;
3640  }
3641 
3642  return rc;
3643 }
3644 
3645 static int
3646 mr_index_readval_timestampltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3647  int copy_buf_len)
3648 {
3649  DB_UTIME utm;
3650  int rc = NO_ERROR;
3651 
3652  if (value == NULL)
3653  {
3654  rc = or_advance (buf, tp_Timestampltz.disksize);
3655  }
3656  else
3657  {
3658  rc = or_get_data (buf, (char *) (&utm), tp_Timestampltz.disksize);
3659  if (rc == NO_ERROR)
3660  {
3661  db_make_timestampltz (value, utm);
3662  }
3663  value->need_clear = false;
3664  }
3665 
3666  return rc;
3667 }
3668 
3670 mr_index_cmpdisk_utime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3671 {
3672  DB_UTIME utm1, utm2;
3673 
3674  assert (domain != NULL);
3675 
3676  COPYMEM (DB_UTIME, &utm1, mem1);
3677  COPYMEM (DB_UTIME, &utm2, mem2);
3678 
3679  return MR_CMP (utm1, utm2);
3680 }
3681 
3683 mr_data_cmpdisk_utime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
3684 {
3685  DB_TIMESTAMP ts1, ts2;
3686 
3687  assert (domain != NULL);
3688 
3689  OR_GET_UTIME (mem1, &ts1);
3690  OR_GET_UTIME (mem2, &ts2);
3691 
3692  return MR_CMP (ts1, ts2);
3693 }
3694 
3696 mr_cmpval_utime (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
3697 {
3698  const DB_TIMESTAMP *ts1, *ts2;
3699 
3700  ts1 = db_get_timestamp (value1);
3701  ts2 = db_get_timestamp (value2);
3702 
3703  return MR_CMP (*ts1, *ts2);
3704 }
3705 
3706 /*
3707  * TYPE TIMESTAMPTZ
3708  *
3709  * This stores a TIMESTAMP and a zone identifier
3710  * The requirement is 4 (TIMESTAMP) + 2 bytes (zone id)
3711  * The encoding of TIMESTAMP is the standard Unix "time_t" format.
3712  */
3713 
3714 static void
3715 mr_initmem_timestamptz (void *mem, TP_DOMAIN * domain)
3716 {
3717  DB_TIMESTAMPTZ *ts_tz = (DB_TIMESTAMPTZ *) mem;
3718 
3719  ts_tz->timestamp = 0;
3720  ts_tz->tz_id = 0;
3721 }
3722 
3723 static int
3724 mr_setmem_timestamptz (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
3725 {
3726  if (value == NULL)
3727  {
3728  mr_initmem_timestamptz (mem, domain);
3729  }
3730  else
3731  {
3732  *(DB_TIMESTAMPTZ *) mem = *db_get_timestamptz (value);
3733  }
3734 
3735  return NO_ERROR;
3736 }
3737 
3738 static int
3739 mr_getmem_timestamptz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3740 {
3741  int error;
3742 
3743  error = db_make_timestamptz (value, (DB_TIMESTAMPTZ *) mem);
3744  return error;
3745 }
3746 
3747 static void
3748 mr_data_writemem_timestamptz (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
3749 {
3750  or_put_timestamptz (buf, (DB_TIMESTAMPTZ *) mem);
3751 }
3752 
3753 static void
3754 mr_data_readmem_timestamptz (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
3755 {
3756  if (mem == NULL)
3757  {
3758  or_advance (buf, tp_Timestamptz.disksize);
3759  }
3760  else
3761  {
3762  or_get_timestamptz (buf, (DB_TIMESTAMPTZ *) mem);
3763  }
3764 }
3765 
3766 static void
3767 mr_initval_timestamptz (DB_VALUE * value, int precision, int scale)
3768 {
3769  DB_TIMESTAMPTZ ts_tz;
3770 
3771  mr_initmem_timestamptz (&ts_tz, NULL);
3772  db_make_timestamptz (value, &ts_tz);
3773 }
3774 
3775 static int
3776 mr_setval_timestamptz (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3777 {
3778  int error;
3779 
3780  if (DB_IS_NULL (src))
3781  {
3783  }
3784  else
3785  {
3786  error = db_make_timestamptz (dest, db_get_timestamptz (src));
3787  }
3788  return error;
3789 }
3790 
3791 static int
3793 {
3794  return or_put_timestamptz (buf, db_get_timestamptz (value));
3795 }
3796 
3797 static int
3798 mr_data_readval_timestamptz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3799  int copy_buf_len)
3800 {
3801  DB_TIMESTAMPTZ ts_tz;
3802  int rc = NO_ERROR;
3803 
3804  if (value == NULL)
3805  {
3806  rc = or_advance (buf, tp_Timestamptz.disksize);
3807  }
3808  else
3809  {
3810  rc = or_get_timestamptz (buf, &ts_tz);
3811  db_make_timestamptz (value, &ts_tz);
3812  }
3813  return rc;
3814 }
3815 
3816 static int
3818 {
3819  DB_TIMESTAMPTZ *ts_tz;
3820  int rc = NO_ERROR;
3821 
3822  ts_tz = db_get_timestamptz (value);
3823 
3824  assert (tp_Timestamptz.disksize == (tp_Utime.disksize + tp_Integer.disksize));
3825 
3826  rc = or_put_data (buf, (char *) (&ts_tz->timestamp), tp_Utime.disksize);
3827  if (rc == NO_ERROR)
3828  {
3829  rc = or_put_data (buf, (char *) (&ts_tz->tz_id), tp_Integer.disksize);
3830  }
3831 
3832  return rc;
3833 }
3834 
3835 static int
3836 mr_index_readval_timestamptz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
3837  int copy_buf_len)
3838 {
3839  DB_TIMESTAMPTZ ts_tz;
3840  int rc = NO_ERROR;
3841 
3842  if (value == NULL)
3843  {
3844  rc = or_advance (buf, tp_Timestamptz.disksize);
3845  }
3846  else
3847  {
3848  rc = or_get_data (buf, (char *) (&ts_tz), tp_Timestamptz.disksize);
3849  if (rc == NO_ERROR)
3850  {
3851  db_make_timestamptz (value, &ts_tz);
3852  }
3853  value->need_clear = false;
3854  }
3855 
3856  return rc;
3857 }
3858 
3860 mr_index_cmpdisk_timestamptz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
3861  int *start_colp)
3862 {
3863  DB_UTIME utm1, utm2;
3864 
3865  assert (domain != NULL);
3866 
3867  /* TIMESTAMP with TZ compares the same as TIMESTAMP (zone is not taken into account) */
3868  COPYMEM (DB_UTIME, &utm1, mem1);
3869  COPYMEM (DB_UTIME, &utm2, mem2);
3870 
3871  return MR_CMP (utm1, utm2);
3872 }
3873 
3875 mr_data_cmpdisk_timestamptz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
3876  int *start_colp)
3877 {
3878  DB_TIMESTAMP ts1, ts2;
3879 
3880  assert (domain != NULL);
3881 
3882  /* TIMESTAMP with TZ compares the same as TIMESTAMP (zone is not taken into account) */
3883  OR_GET_UTIME (mem1, &ts1);
3884  OR_GET_UTIME (mem2, &ts2);
3885 
3886  return MR_CMP (ts1, ts2);
3887 }
3888 
3890 mr_cmpval_timestamptz (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
3891  int collation)
3892 {
3893  const DB_TIMESTAMPTZ *ts_tz1, *ts_tz2;
3894 
3895  /* TIMESTAMP with TZ compares the same as TIMESTAMP (zone is not taken into account); the first component of
3896  * TIMESTAMPTZ is a TIMESTAMP, it is safe to use the TIMESTAMP part of DB_DATA union to read it */
3897  ts_tz1 = db_get_timestamptz (value1);
3898  ts_tz2 = db_get_timestamptz (value2);
3899 
3900 #if defined (SA_MODE)
3901  if (tz_Compare_timestamptz_tz_id == true && ts_tz1->tz_id != ts_tz2->tz_id)
3902  {
3903  return DB_NE;
3904  }
3905 #endif
3906 
3907  return MR_CMP (ts_tz1->timestamp, ts_tz2->timestamp);
3908 }
3909 
3910 /*
3911  * TYPE DATETIME
3912  *
3913  */
3914 
3915 static void
3916 mr_initmem_datetime (void *memptr, TP_DOMAIN * domain)
3917 {
3918  DB_DATETIME *mem = (DB_DATETIME *) memptr;
3919 
3920  mem->date = 0;
3921  mem->time = 0;
3922 }
3923 
3924 static void
3925 mr_initval_datetime (DB_VALUE * value, int precision, int scale)
3926 {
3927  DB_DATETIME dt;
3928 
3929  mr_initmem_datetime (&dt, NULL);
3930  db_make_datetime (value, &dt);
3931  value->need_clear = false;
3932 }
3933 
3934 static void
3935 mr_initval_datetimeltz (DB_VALUE * value, int precision, int scale)
3936 {
3937  DB_DATETIME dt;
3938 
3939  mr_initmem_datetime (&dt, NULL);
3940  db_make_datetimeltz (value, &dt);
3941  value->need_clear = false;
3942 }
3943 
3944 static int
3945 mr_setmem_datetime (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
3946 {
3947  if (value == NULL)
3948  {
3949  mr_initmem_datetime (mem, domain);
3950  }
3951  else
3952  {
3953  *(DB_DATETIME *) mem = *db_get_datetime (value);
3954  }
3955 
3956  return NO_ERROR;
3957 }
3958 
3959 static int
3960 mr_getmem_datetime (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3961 {
3962  return db_make_datetime (value, (DB_DATETIME *) mem);
3963 }
3964 
3965 static int
3966 mr_getmem_datetimeltz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
3967 {
3968  return db_make_datetimeltz (value, (DB_DATETIME *) mem);
3969 }
3970 
3971 static int
3972 mr_setval_datetime (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3973 {
3974  int error;
3975 
3976  if (DB_IS_NULL (src))
3977  {
3979  }
3980  else
3981  {
3982  error = db_make_datetime (dest, db_get_datetime (src));
3983  }
3984  return error;
3985 }
3986 
3987 static int
3988 mr_setval_datetimeltz (DB_VALUE * dest, const DB_VALUE * src, bool copy)
3989 {
3990  int error;
3991 
3992  if (DB_IS_NULL (src))
3993  {
3995  }
3996  else
3997  {
3998  error = db_make_datetimeltz (dest, db_get_datetime (src));
3999  }
4000  return error;
4001 }
4002 
4003 static void
4004 mr_data_writemem_datetime (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
4005 {
4006  or_put_datetime (buf, (DB_DATETIME *) mem);
4007 }
4008 
4009 static void
4010 mr_data_readmem_datetime (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
4011 {
4012  if (mem == NULL)
4013  {
4014  or_advance (buf, tp_Datetime.disksize);
4015  }
4016  else
4017  {
4018  or_get_datetime (buf, (DB_DATETIME *) mem);
4019  }
4020 }
4021 
4022 static int
4024 {
4025  return or_put_datetime (buf, db_get_datetime (value));
4026 }
4027 
4028 static int
4029 mr_data_readval_datetime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4030  int copy_buf_len)
4031 {
4032  DB_DATETIME datetime;
4033  int rc = NO_ERROR;
4034 
4035  if (value == NULL)
4036  {
4037  rc = or_advance (buf, tp_Datetime.disksize);
4038  }
4039  else
4040  {
4041  rc = or_get_datetime (buf, &datetime);
4042  if (rc == NO_ERROR)
4043  {
4044  db_make_datetime (value, &datetime);
4045  }
4046  value->need_clear = false;
4047  }
4048  return rc;
4049 }
4050 
4051 static int
4052 mr_data_readval_datetimeltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4053  int copy_buf_len)
4054 {
4055  DB_DATETIME datetime;
4056  int rc = NO_ERROR;
4057 
4058  if (value == NULL)
4059  {
4060  rc = or_advance (buf, tp_Datetimeltz.disksize);
4061  }
4062  else
4063  {
4064  rc = or_get_datetime (buf, &datetime);
4065  db_make_datetimeltz (value, &datetime);
4066  }
4067  return rc;
4068 }
4069 
4070 static int
4072 {
4073  DB_DATETIME *datetime;
4074  int rc = NO_ERROR;
4075 
4076  datetime = db_get_datetime (value);
4077 
4078  assert (tp_Datetime.disksize == (tp_Date.disksize + tp_Time.disksize));
4079 
4080  rc = or_put_data (buf, (char *) (&datetime->date), tp_Date.disksize);
4081  if (rc == NO_ERROR)
4082  {
4083  rc = or_put_data (buf, (char *) (&datetime->time), tp_Time.disksize);
4084  }
4085 
4086  return rc;
4087 }
4088 
4089 static int
4090 mr_index_readval_datetime (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4091  int copy_buf_len)
4092 {
4093  DB_DATETIME datetime;
4094  int rc = NO_ERROR;
4095 
4096  assert (tp_Datetime.disksize == (tp_Date.disksize + tp_Time.disksize));
4097 
4098  if (value == NULL)
4099  {
4100  rc = or_advance (buf, tp_Datetime.disksize);
4101  }
4102  else
4103  {
4104  rc = or_get_data (buf, (char *) (&datetime.date), tp_Date.disksize);
4105  if (rc == NO_ERROR)
4106  {
4107  rc = or_get_data (buf, (char *) (&datetime.time), tp_Time.disksize);
4108  }
4109 
4110  if (rc == NO_ERROR)
4111  {
4112  db_make_datetime (value, &datetime);
4113  }
4114  value->need_clear = false;
4115  }
4116 
4117  return rc;
4118 }
4119 
4120 static int
4121 mr_index_readval_datetimeltz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4122  int copy_buf_len)
4123 {
4124  DB_DATETIME datetime;
4125  int rc = NO_ERROR;
4126 
4127  assert (tp_Datetimeltz.disksize == (tp_Date.disksize + tp_Time.disksize));
4128 
4129  if (value == NULL)
4130  {
4131  rc = or_advance (buf, tp_Datetimeltz.disksize);
4132  }
4133  else
4134  {
4135  rc = or_get_data (buf, (char *) (&datetime.date), tp_Date.disksize);
4136  if (rc == NO_ERROR)
4137  {
4138  rc = or_get_data (buf, (char *) (&datetime.time), tp_Time.disksize);
4139  }
4140 
4141  if (rc == NO_ERROR)
4142  {
4143  db_make_datetimeltz (value, &datetime);
4144  }
4145  value->need_clear = false;
4146  }
4147 
4148  return rc;
4149 }
4150 
4152 mr_index_cmpdisk_datetime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
4153  int *start_colp)
4154 {
4156  DB_DATETIME dt1, dt2;
4157 
4158  assert (domain != NULL);
4159 
4160  if (mem1 == mem2)
4161  {
4162  return DB_EQ;
4163  }
4164 
4165  COPYMEM (unsigned int, &dt1.date, (char *)mem1 + OR_DATETIME_DATE);
4166  COPYMEM (unsigned int, &dt1.time, (char *) mem1 + OR_DATETIME_TIME);
4167  COPYMEM (unsigned int, &dt2.date, (char *) mem2 + OR_DATETIME_DATE);
4168  COPYMEM (unsigned int, &dt2.time, (char *) mem2 + OR_DATETIME_TIME);
4169 
4170  if (dt1.date < dt2.date)
4171  {
4172  c = DB_LT;
4173  }
4174  else if (dt1.date > dt2.date)
4175  {
4176  c = DB_GT;
4177  }
4178  else
4179  {
4180  if (dt1.time < dt2.time)
4181  {
4182  c = DB_LT;
4183  }
4184  else if (dt1.time > dt2.time)
4185  {
4186  c = DB_GT;
4187  }
4188  else
4189  {
4190  c = DB_EQ;
4191  }
4192  }
4193 
4194  return c;
4195 }
4196 
4198 mr_data_cmpdisk_datetime (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
4199 {
4201  DB_DATETIME dt1, dt2;
4202 
4203  assert (domain != NULL);
4204 
4205  if (mem1 == mem2)
4206  {
4207  return DB_EQ;
4208  }
4209 
4210  OR_GET_DATETIME (mem1, &dt1);
4211  OR_GET_DATETIME (mem2, &dt2);
4212 
4213  if (dt1.date < dt2.date)
4214  {
4215  c = DB_LT;
4216  }
4217  else if (dt1.date > dt2.date)
4218  {
4219  c = DB_GT;
4220  }
4221  else
4222  {
4223  if (dt1.time < dt2.time)
4224  {
4225  c = DB_LT;
4226  }
4227  else if (dt1.time > dt2.time)
4228  {
4229  c = DB_GT;
4230  }
4231  else
4232  {
4233  c = DB_EQ;
4234  }
4235  }
4236 
4237  return c;
4238 }
4239 
4241 mr_cmpval_datetime (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
4242  int collation)
4243 {
4244  const DB_DATETIME *dt1, *dt2;
4246 
4247  dt1 = db_get_datetime (value1);
4248  dt2 = db_get_datetime (value2);
4249 
4250  if (dt1->date < dt2->date)
4251  {
4252  c = DB_LT;
4253  }
4254  else if (dt1->date > dt2->date)
4255  {
4256  c = DB_GT;
4257  }
4258  else
4259  {
4260  if (dt1->time < dt2->time)
4261  {
4262  c = DB_LT;
4263  }
4264  else if (dt1->time > dt2->time)
4265  {
4266  c = DB_GT;
4267  }
4268  else
4269  {
4270  c = DB_EQ;
4271  }
4272  }
4273 
4274  return c;
4275 }
4276 
4277 /*
4278  * TYPE DATETIMETZ
4279  *
4280  */
4281 
4282 static void
4283 mr_initmem_datetimetz (void *memptr, TP_DOMAIN * domain)
4284 {
4285  DB_DATETIMETZ *mem = (DB_DATETIMETZ *) memptr;
4286 
4287  mem->datetime.date = 0;
4288  mem->datetime.time = 0;
4289  mem->tz_id = 0;
4290 }
4291 
4292 static void
4293 mr_initval_datetimetz (DB_VALUE * value, int precision, int scale)
4294 {
4295  DB_DATETIMETZ dt_tz;
4296 
4297  mr_initmem_datetimetz (&dt_tz, NULL);
4298  db_make_datetimetz (value, &dt_tz);
4299 }
4300 
4301 static int
4302 mr_setmem_datetimetz (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
4303 {
4304  if (value == NULL)
4305  {
4306  mr_initmem_datetimetz (mem, NULL);
4307  }
4308  else
4309  {
4310  *(DB_DATETIMETZ *) mem = *db_get_datetimetz (value);
4311  }
4312 
4313  return NO_ERROR;
4314 }
4315 
4316 static int
4317 mr_getmem_datetimetz (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
4318 {
4319  return db_make_datetimetz (value, (DB_DATETIMETZ *) mem);
4320 }
4321 
4322 static int
4323 mr_setval_datetimetz (DB_VALUE * dest, const DB_VALUE * src, bool copy)
4324 {
4325  int error;
4326 
4327  if (DB_IS_NULL (src))
4328  {
4330  }
4331  else
4332  {
4333  error = db_make_datetimetz (dest, db_get_datetimetz (src));
4334  }
4335  return error;
4336 }
4337 
4338 static void
4339 mr_data_writemem_datetimetz (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
4340 {
4341  or_put_datetimetz (buf, (DB_DATETIMETZ *) mem);
4342 }
4343 
4344 static void
4345 mr_data_readmem_datetimetz (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
4346 {
4347  if (mem == NULL)
4348  {
4349  or_advance (buf, tp_Datetimetz.disksize);
4350  }
4351  else
4352  {
4353  or_get_datetimetz (buf, (DB_DATETIMETZ *) mem);
4354  }
4355 }
4356 
4357 static int
4359 {
4360  return or_put_datetimetz (buf, db_get_datetimetz (value));
4361 }
4362 
4363 static int
4364 mr_data_readval_datetimetz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4365  int copy_buf_len)
4366 {
4367  DB_DATETIMETZ datetimetz;
4368  int rc = NO_ERROR;
4369 
4370  if (value == NULL)
4371  {
4372  rc = or_advance (buf, tp_Datetimetz.disksize);
4373  }
4374  else
4375  {
4376  rc = or_get_datetimetz (buf, &datetimetz);
4377  db_make_datetimetz (value, &datetimetz);
4378  }
4379  return rc;
4380 }
4381 
4382 static int
4384 {
4385  DB_DATETIMETZ *datetimetz;
4386  int rc = NO_ERROR;
4387 
4388  datetimetz = db_get_datetimetz (value);
4389 
4390  assert (tp_Datetimetz.disksize == (tp_Date.disksize + tp_Time.disksize + tp_Integer.disksize));
4391 
4392  rc = or_put_data (buf, (char *) (&datetimetz->datetime.date), tp_Date.disksize);
4393  if (rc == NO_ERROR)
4394  {
4395  rc = or_put_data (buf, (char *) (&datetimetz->datetime.time), tp_Time.disksize);
4396  if (rc == NO_ERROR)
4397  {
4398  rc = or_put_data (buf, (char *) (&datetimetz->tz_id), tp_Integer.disksize);
4399  }
4400  }
4401 
4402  return rc;
4403 }
4404 
4405 static int
4406 mr_index_readval_datetimetz (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4407  int copy_buf_len)
4408 {
4409  DB_DATETIMETZ datetimetz;
4410  int rc = NO_ERROR;
4411 
4412  assert (tp_Datetimetz.disksize == (tp_Date.disksize + tp_Time.disksize + tp_Integer.disksize));
4413 
4414  if (value == NULL)
4415  {
4416  rc = or_advance (buf, tp_Datetimetz.disksize);
4417  }
4418  else
4419  {
4420  rc = or_get_data (buf, (char *) (&datetimetz.datetime.date), tp_Date.disksize);
4421  if (rc == NO_ERROR)
4422  {
4423  rc = or_get_data (buf, (char *) (&datetimetz.datetime.time), tp_Time.disksize);
4424  if (rc == NO_ERROR)
4425  {
4426  rc = or_get_data (buf, (char *) (&datetimetz.tz_id), tp_Integer.disksize);
4427  }
4428  }
4429 
4430  if (rc == NO_ERROR)
4431  {
4432  db_make_datetimetz (value, &datetimetz);
4433  }
4434  value->need_clear = false;
4435  }
4436 
4437  return rc;
4438 }
4439 
4441 mr_index_cmpdisk_datetimetz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
4442  int *start_colp)
4443 {
4444  /* DATETIMETZ compares the same as DATETIME (tz_id is ignored) */
4445  return mr_index_cmpdisk_datetime (mem1, mem2, domain, do_coercion, total_order, start_colp);
4446 }
4447 
4449 mr_data_cmpdisk_datetimetz (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
4450  int *start_colp)
4451 {
4452  /* DATETIMETZ compares the same as DATETIME (tz_id is ignored) */
4453  return mr_data_cmpdisk_datetime (mem1, mem2, domain, do_coercion, total_order, start_colp);
4454 }
4455 
4457 mr_cmpval_datetimetz (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
4458  int collation)
4459 {
4460  const DB_DATETIMETZ *dt_tz1, *dt_tz2;
4461  const DB_DATETIME *dt1, *dt2;
4463 
4464  dt_tz1 = db_get_datetimetz (value1);
4465  dt_tz2 = db_get_datetimetz (value2);
4466 
4467  dt1 = &(dt_tz1->datetime);
4468  dt2 = &(dt_tz2->datetime);
4469 
4470 #if defined (SA_MODE)
4471  if (tz_Compare_datetimetz_tz_id == true && dt_tz1->tz_id != dt_tz2->tz_id)
4472  {
4473  return DB_NE;
4474  }
4475 #endif /* SA_MODE */
4476 
4477  if (dt1->date < dt2->date)
4478  {
4479  c = DB_LT;
4480  }
4481  else if (dt1->date > dt2->date)
4482  {
4483  c = DB_GT;
4484  }
4485  else
4486  {
4487  if (dt1->time < dt2->time)
4488  {
4489  c = DB_LT;
4490  }
4491  else if (dt1->time > dt2->time)
4492  {
4493  c = DB_GT;
4494  }
4495  else
4496  {
4497  c = DB_EQ;
4498  }
4499  }
4500 
4501  return c;
4502 }
4503 
4504 /*
4505  * TYPE MONETARY
4506  *
4507  * Practically useless combination of an IEEE double with a currency tag.
4508  * Should consider re-implementing this using fixed precision numerics
4509  * now that we have them.
4510  * Because of double allignment problems, never access the amount field
4511  * with a structure dereference.
4512  */
4513 
4514 static void
4515 mr_initmem_money (void *memptr, TP_DOMAIN * domain)
4516 {
4517  DB_MONETARY *mem = (DB_MONETARY *) memptr;
4518 
4519  double d = 0.0;
4520 
4521  mem->type = DB_CURRENCY_DEFAULT;
4522  OR_MOVE_DOUBLE (&d, &mem->amount);
4523 }
4524 
4525 static int
4526 mr_setmem_money (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
4527 {
4528  DB_MONETARY *mem = (DB_MONETARY *) memptr;
4529  DB_MONETARY *money;
4530 
4531  if (value == NULL)
4532  {
4533  mr_initmem_money (mem, domain);
4534  }
4535  else
4536  {
4537  money = db_get_monetary (value);
4538  mem->type = money->type;
4539  OR_MOVE_DOUBLE (&money->amount, &mem->amount);
4540  }
4541  return NO_ERROR;
4542 }
4543 
4544 static int
4545 mr_getmem_money (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
4546 {
4547  int error = NO_ERROR;
4548  DB_MONETARY *mem = (DB_MONETARY *) memptr;
4549  double amt = 0;
4550 
4551  OR_MOVE_DOUBLE (&mem->amount, &amt);
4552  error = db_make_monetary (value, mem->type, amt);
4553  value->need_clear = false;
4554  return error;
4555 }
4556 
4557 static void
4558 mr_data_writemem_money (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
4559 {
4560  or_put_monetary (buf, (DB_MONETARY *) mem);
4561 }
4562 
4563 static void
4564 mr_data_readmem_money (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
4565 {
4566  if (mem == NULL)
4567  {
4568  or_advance (buf, tp_Monetary.disksize);
4569  }
4570  else
4571  {
4572  or_get_monetary (buf, (DB_MONETARY *) mem);
4573  }
4574 }
4575 
4576 static void
4577 mr_initval_money (DB_VALUE * value, int precision, int scale)
4578 {
4579  db_make_monetary (value, DB_CURRENCY_DEFAULT, 0.0);
4580  value->need_clear = false;
4581 }
4582 
4583 static int
4584 mr_setval_money (DB_VALUE * dest, const DB_VALUE * src, bool copy)
4585 {
4586  int error;
4587  DB_MONETARY *money;
4588 
4589  if (DB_IS_NULL (src) || ((money = db_get_monetary (src)) == NULL))
4590  {
4592  }
4593  else
4594  {
4595  error = db_make_monetary (dest, money->type, money->amount);
4596  }
4597  return error;
4598 }
4599 
4600 static int
4602 {
4603  return or_put_monetary (buf, db_get_monetary (value));
4604 }
4605 
4606 static int
4607 mr_data_readval_money (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4608  int copy_buf_len)
4609 {
4610  DB_MONETARY money;
4611  int rc = NO_ERROR;
4612 
4613  if (value == NULL)
4614  {
4615  rc = or_advance (buf, tp_Monetary.disksize);
4616  }
4617  else
4618  {
4619  rc = or_get_monetary (buf, &money);
4620  if (rc == NO_ERROR)
4621  {
4622  db_make_monetary (value, money.type, money.amount);
4623  }
4624  value->need_clear = false;
4625  }
4626  return rc;
4627 }
4628 
4629 static int
4631 {
4632  DB_MONETARY *money;
4633  int rc = NO_ERROR;
4634 
4635  money = db_get_monetary (value);
4636 
4637  rc = or_put_data (buf, (char *) (&money->type), tp_Integer.disksize);
4638  if (rc == NO_ERROR)
4639  {
4640  rc = or_put_data (buf, (char *) (&money->amount), tp_Double.disksize);
4641  }
4642 
4643  return rc;
4644 }
4645 
4646 static int
4647 mr_index_readval_money (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4648  int copy_buf_len)
4649 {
4650  DB_MONETARY money;
4651  int rc = NO_ERROR;
4652 
4653  if (value == NULL)
4654  {
4655  rc = or_advance (buf, tp_Monetary.disksize);
4656  }
4657  else
4658  {
4659  rc = or_get_data (buf, (char *) (&money.type), tp_Integer.disksize);
4660  if (rc == NO_ERROR)
4661  {
4662  rc = or_get_data (buf, (char *) (&money.amount), tp_Double.disksize);
4663  }
4664 
4665  if (rc == NO_ERROR)
4666  {
4667  db_make_monetary (value, money.type, money.amount);
4668  }
4669  value->need_clear = false;
4670  }
4671 
4672  return rc;
4673 }
4674 
4676 mr_index_cmpdisk_money (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
4677 {
4678  DB_MONETARY m1, m2;
4679 
4680  assert (domain != NULL);
4681 
4682  COPYMEM (double, &m1.amount, (char *) mem1 + tp_Integer.disksize);
4683  COPYMEM (double, &m2.amount, (char *) mem2 + tp_Integer.disksize);
4684 
4685  return MR_CMP (m1.amount, m2.amount);
4686 }
4687 
4689 mr_data_cmpdisk_money (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
4690 {
4691  DB_MONETARY m1, m2;
4692 
4693  assert (domain != NULL);
4694 
4695  OR_GET_MONETARY (mem1, &m1);
4696  OR_GET_MONETARY (mem2, &m2);
4697 
4698  return MR_CMP (m1.amount, m2.amount);
4699 }
4700 
4702 mr_cmpval_money (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
4703 {
4704  const DB_MONETARY *m1, *m2;
4705 
4706  m1 = db_get_monetary (value1);
4707  m2 = db_get_monetary (value2);
4708 
4709  return MR_CMP (m1->amount, m2->amount);
4710 }
4711 
4712 /*
4713  * TYPE DATE
4714  *
4715  * 32 bit day counter, commonly called a "julian" date.
4716  */
4717 
4718 static void
4719 mr_initmem_date (void *mem, TP_DOMAIN * domain)
4720 {
4721  *(DB_DATE *) mem = 0;
4722 }
4723 
4724 static int
4725 mr_setmem_date (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
4726 {
4727  if (value == NULL)
4728  mr_initmem_date (mem, domain);
4729  else
4730  *(DB_DATE *) mem = *db_get_date (value);
4731 
4732  return NO_ERROR;
4733 }
4734 
4735 static int
4736 mr_getmem_date (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
4737 {
4738  return db_value_put_encoded_date (value, (DB_DATE *) mem);
4739 }
4740 
4741 static void
4742 mr_data_writemem_date (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
4743 {
4744  or_put_date (buf, (DB_DATE *) mem);
4745 }
4746 
4747 static void
4748 mr_data_readmem_date (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
4749 {
4750  if (mem == NULL)
4751  {
4752  or_advance (buf, tp_Date.disksize);
4753  }
4754  else
4755  {
4756  or_get_date (buf, (DB_DATE *) mem);
4757  }
4758 }
4759 
4760 static void
4761 mr_initval_date (DB_VALUE * value, int precision, int scale)
4762 {
4763  db_value_put_encoded_date (value, 0);
4764  value->need_clear = false;
4765 }
4766 
4767 static int
4768 mr_setval_date (DB_VALUE * dest, const DB_VALUE * src, bool copy)
4769 {
4770  int error;
4771 
4772  if (DB_IS_NULL (src))
4773  {
4775  }
4776  else
4777  {
4778  error = db_value_put_encoded_date (dest, db_get_date (src));
4779  }
4780  return error;
4781 }
4782 
4783 static int
4785 {
4786  return or_put_date (buf, db_get_date (value));
4787 }
4788 
4789 static int
4790 mr_data_readval_date (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4791  int copy_buf_len)
4792 {
4793  DB_DATE dt;
4794  int rc = NO_ERROR;
4795 
4796  if (value == NULL)
4797  {
4798  rc = or_advance (buf, tp_Date.disksize);
4799  }
4800  else
4801  {
4802  rc = or_get_date (buf, &dt);
4803  if (rc == NO_ERROR)
4804  {
4805  db_value_put_encoded_date (value, &dt);
4806  }
4807  value->need_clear = false;
4808  }
4809  return rc;
4810 }
4811 
4812 static int
4814 {
4815  DB_DATE *dt;
4816 
4817  dt = db_get_date (value);
4818 
4819  return or_put_data (buf, (char *) dt, tp_Date.disksize);
4820 }
4821 
4822 static int
4823 mr_index_readval_date (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
4824  int copy_buf_len)
4825 {
4826  DB_DATE dt;
4827  int rc = NO_ERROR;
4828 
4829  if (value == NULL)
4830  {
4831  rc = or_advance (buf, tp_Date.disksize);
4832  }
4833  else
4834  {
4835  rc = or_get_data (buf, (char *) (&dt), tp_Date.disksize);
4836  if (rc == NO_ERROR)
4837  {
4838  db_value_put_encoded_date (value, &dt);
4839  }
4840  value->need_clear = false;
4841  }
4842 
4843  return rc;
4844 }
4845 
4847 mr_index_cmpdisk_date (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
4848 {
4849  DB_DATE d1, d2;
4850 
4851  assert (domain != NULL);
4852 
4853  COPYMEM (DB_DATE, &d1, mem1);
4854  COPYMEM (DB_DATE, &d2, mem2);
4855 
4856  return MR_CMP (d1, d2);
4857 }
4858 
4860 mr_data_cmpdisk_date (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
4861 {
4862  DB_DATE d1, d2;
4863 
4864  assert (domain != NULL);
4865 
4866  OR_GET_DATE (mem1, &d1);
4867  OR_GET_DATE (mem2, &d2);
4868 
4869  return MR_CMP (d1, d2);
4870 }
4871 
4873 mr_cmpval_date (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
4874 {
4875  const DB_DATE *d1, *d2;
4876 
4877  d1 = db_get_date (value1);
4878  d2 = db_get_date (value2);
4879 
4880  return MR_CMP (*d1, *d2);
4881 }
4882 
4883 /*
4884  * TYPE OBJECT
4885  */
4886 
4887 /*
4888  * This is a bit different than the other primitive types in that the memory
4889  * value and the DB_VALUE representations are not the same. The memory value
4890  * will be represented with a WS_MEMOID structure to avoid creating MOPs until
4891  * they are actually needed.
4892  *
4893  * These types are not available on the server since there is no workspace
4894  * over there. Although in standalone mode, we could promote OIDs to MOPs
4895  * on both sides, use the db_on_server flag to control this so we make
4896  * both sides behave similarly even though we're in standalone mode.
4897  * The "mem" functions will in general be commented out since they
4898  * call things that don't exist on the server. THe "val" functions will
4899  * exist so that things tagged as DB_TYPE_OBJECT can be read as OID values.
4900  *
4901  */
4902 
4903 
4904 /*
4905  * mr_null_oid - This is used to set an OID to the NULL state.
4906  * return: void
4907  * oid(out): oid to initialize
4908  * Note:
4909  * SET_OID_NULL does the actual work by setting the volid to -1 but it
4910  * leaves garbage in the other fields which can be stored on disk and
4911  * generally looks alarming when you encounter it later. Before
4912  * calling SET_OID_NULL, initialize the fields to nice zero values.
4913  * Should be an inline function.
4914  */
4915 static void
4917 {
4918  oid->pageid = 0;
4919  oid->volid = 0;
4920  oid->slotid = 0;
4921 
4922  OID_SET_NULL (oid);
4923 }
4924 
4925 static void
4926 mr_initmem_object (void *memptr, TP_DOMAIN * domain)
4927 {
4928  /* there is no use for initmem on the server */
4929 #if !defined (SERVER_MODE)
4930  WS_MEMOID *mem = (WS_MEMOID *) memptr;
4931 
4932  mr_null_oid (&mem->oid);
4933  mem->pointer = NULL;
4934 #endif
4935 }
4936 
4937 /*
4938  * Can get here on the server when dispatching from set element domains.
4939  * Always represent object values as OIDs on the server.
4940  */
4941 
4942 static void
4943 mr_initval_object (DB_VALUE * value, int precision, int scale)
4944 {
4945  OID oid;
4946 
4947 #if !defined (SERVER_MODE)
4948  if (db_on_server)
4949  {
4950  db_value_domain_init (value, DB_TYPE_OID, precision, scale);
4951  OID_SET_NULL (&oid);
4952  db_make_oid (value, &oid);
4953  }
4954  else
4955  {
4956  db_value_domain_init (value, DB_TYPE_OBJECT, precision, scale);
4957  db_make_object (value, NULL);
4958  }
4959 #else /* SERVER_MODE */
4960  db_value_domain_init (value, DB_TYPE_OID, precision, scale);
4961  OID_SET_NULL (&oid);
4962  db_make_oid (value, &oid);
4963 #endif /* !SERVER_MODE */
4964 }
4965 
4966 static int
4967 mr_setmem_object (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
4968 {
4969  /* there is no need for setmem on the server */
4970 #if !defined (SERVER_MODE)
4971  WS_MEMOID *mem = (WS_MEMOID *) memptr;
4972  OID *oid;
4973  MOP op;
4974 
4975  if (value == NULL)
4976  {
4977  mr_null_oid (&mem->oid);
4978  mem->pointer = NULL;
4979  }
4980  else
4981  {
4982  op = db_get_object (value);
4983  if (op == NULL)
4984  {
4985  mr_initmem_object (mem, domain);
4986  }
4987  else
4988  {
4989  oid = WS_OID (op);
4990  mem->oid.volid = oid->volid;
4991  mem->oid.pageid = oid->pageid;
4992  mem->oid.slotid = oid->slotid;
4993  if (op->is_temp)
4994  {
4995  mem->pointer = NULL;
4996  }
4997  else
4998  {
4999  mem->pointer = op;
5000  }
5001  }
5002  }
5003 #endif /* !SERVER_MODE */
5004  return NO_ERROR;
5005 }
5006 
5007 static int
5008 mr_getmem_object (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
5009 {
5010  int error = NO_ERROR;
5011 
5012  /* there is no need for getmem on the server */
5013 #if !defined (SERVER_MODE)
5014  WS_MEMOID *mem = (WS_MEMOID *) memptr;
5015  MOP op;
5016 
5017  op = mem->pointer;
5018  if (op == NULL)
5019  {
5020  if (!OID_ISNULL (&mem->oid))
5021  {
5022  op = ws_mop (&mem->oid, NULL);
5023  if (op != NULL)
5024  {
5025  mem->pointer = op;
5026  error = db_make_object (value, op);
5027  }
5028  else
5029  {
5030  assert (er_errid () != NO_ERROR);
5031  error = er_errid ();
5032  (void) db_make_object (value, NULL);
5033  }
5034  }
5035  }
5036  else
5037  error = db_make_object (value, op);
5038 #endif /* !SERVER_MODE */
5039 
5040  return error;
5041 }
5042 
5043 
5044 static int
5045 mr_setval_object (DB_VALUE * dest, const DB_VALUE * src, bool copy)
5046 {
5047  int error = NO_ERROR;
5048  OID *oid;
5049 
5050 #if !defined (SERVER_MODE)
5051  if (DB_IS_NULL (src))
5052  {
5053  db_make_null (dest);
5054  }
5055  /* can get here on the server when dispatching through set element domains */
5056  else if (DB_VALUE_TYPE (src) == DB_TYPE_OID)
5057  {
5058  /* make sure that the target type is set properly */
5060  oid = (OID *) db_get_oid (src);
5061  error = db_make_oid (dest, oid);
5062  }
5063  else if (DB_VALUE_TYPE (src) == DB_TYPE_OBJECT)
5064  {
5065  /* If we're logically on the server, we probably shouldn't have gotten here but if we do, don't continue with the
5066  * object representation, de-swizzle it back to an OID. */
5067  if (db_on_server)
5068  {
5069  DB_OBJECT *obj;
5070  /* what should this do for ISVID mops? */
5071  obj = db_get_object (src);
5073  oid = WS_OID (obj);
5074  error = db_make_oid (dest, oid);
5075  }
5076  else
5077  {
5079  error = db_make_object (dest, db_get_object (src));
5080  }
5081  }
5082 #else /* SERVER_MODE */
5083  /*
5084  * If we're really on the server, we can only get here when dispatching
5085  * through set element domains. The value must contain an OID.
5086  */
5087  if (DB_IS_NULL (src) || DB_VALUE_TYPE (src) != DB_TYPE_OID)
5088  {
5089  db_make_null (dest);
5090  }
5091  else
5092  {
5093  oid = (OID *) db_get_oid (src);
5094  error = db_make_oid (dest, oid);
5095  }
5096 #endif /* !SERVER_MODE */
5097 
5098  return error;
5099 }
5100 
5101 
5102 
5103 static int
5105 {
5106  return tp_Oid.disksize;
5107 }
5108 
5109 /*
5110  * mr_lengthval_object - checks if the object is virtual or not. and returns
5111  * property type size.
5112  * return: If it is virtual object returns calculated the DB_TYPE_VOBJ
5113  * packed size. returns DB_TYPE_OID otherwise
5114  * value(in): value to get length
5115  * disk(in): indicator that it is disk object
5116  */
5117 static int
5119 {
5120 #if !defined (SERVER_MODE)
5121  MOP mop;
5122 #endif
5123  int size;
5124 
5125  if (disk)
5126  {
5127  size = OR_OID_SIZE;
5128  }
5129  else
5130  {
5131  size = MR_OID_SIZE;
5132  }
5133 
5134 #if !defined (SERVER_MODE)
5135  if (DB_VALUE_TYPE (value) == DB_TYPE_OBJECT && disk)
5136  {
5137  mop = db_get_object (value);
5138  if ((mop == NULL) || (WS_IS_DELETED (mop)))
5139  {
5140  /* The size of a NULL is OR_OID_SIZE, which is already set (from Jeff L.) */
5141  }
5142  else if (WS_ISVID (mop))
5143  {
5144  DB_VALUE vmop_seq;
5145  int error;
5146 
5147  error = vid_object_to_vobj (mop, &vmop_seq);
5148  if (error >= 0)
5149  {
5150  size = mr_data_lengthval_set (&vmop_seq, disk);
5151  pr_clear_value (&vmop_seq);
5152  }
5153  }
5154  }
5155 #endif
5156 
5157  return size;
5158 }
5159 
5160 static void
5161 mr_data_writemem_object (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
5162 {
5163 #if !defined (SERVER_MODE) /* there is no need for writemem on the server */
5164  WS_MEMOID *mem = (WS_MEMOID *) memptr;
5165  OID *oidp;
5166 
5167  oidp = NULL;
5168  if (mem != NULL)
5169  {
5170  oidp = &mem->oid;
5171  }
5172 
5173  if (oidp == NULL)
5174  {
5175  /* construct an unbound oid */
5176  oidp = (OID *) (&oid_Null_oid);
5177  }
5178  else if (OID_ISTEMP (oidp))
5179  {
5180  /* Temporary oid, must get a permanent one. This should only happen if the MOID has a valid MOP. Check for
5181  * deletion */
5182  if ((mem->pointer == NULL) || (WS_IS_DELETED (mem->pointer)))
5183  {
5184  oidp = (OID *) (&oid_Null_oid);
5186  }
5187  else
5188  {
5189  oidp = WS_OID (mem->pointer);
5190  if (OID_ISTEMP (oidp))
5191  {
5192  /* a MOP with a temporary OID, make an entry in the OID fixup table if we have one, otherwise, stop and
5193  * assign a permanent one. */
5194  oidp = tf_need_permanent_oid (buf, mem->pointer);
5195  if (oidp == NULL)
5196  {
5197  /* normally would have used or_abort by now */
5198  oidp = (OID *) (&oid_Null_oid);
5199  }
5200  }
5201  }
5202  }
5203  else
5204  {
5205  /* normal OID check for deletion */
5206  if ((mem->pointer != NULL) && (WS_IS_DELETED (mem->pointer)))
5207  {
5208  oidp = (OID *) (&oid_Null_oid);
5209  }
5210  }
5211 
5212  or_put_oid (buf, oidp);
5213 
5214 #else /* SERVER_MODE */
5215  /* should never get here but in case we do, dump a NULL OID into the buffer. */
5216  printf ("mr_writemem_object: called on the server !\n");
5217  or_put_oid (buf, (OID *) (&oid_Null_oid));
5218 #endif /* !SERVER_MODE */
5219 }
5220 
5221 
5222 static void
5223 mr_data_readmem_object (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
5224 {
5225 #if !defined (SERVER_MODE) /* there is no need for readmem on the server ??? */
5226  WS_MEMOID *mem = (WS_MEMOID *) memptr;
5227 
5228  if (mem != NULL)
5229  {
5230  or_get_oid (buf, &mem->oid);
5231  mem->pointer = NULL;
5232  }
5233  else
5234  {
5235  or_advance (buf, tp_Object.disksize);
5236  }
5237 #else
5238  /* shouldn't get here but if we do, just skip over it */
5239  printf ("mr_readmem_object: called on the server !\n");
5240  or_advance (buf, tp_Object.disksize);
5241 #endif
5242 
5243 }
5244 
5245 static int
5247 {
5248  return mr_index_writeval_oid (buf, value);
5249 }
5250 
5251 static int
5253 {
5254 #if !defined (SERVER_MODE)
5255  MOP mop;
5256 #endif
5257  OID *oidp = NULL;
5258  int rc = NO_ERROR;
5259 
5260 #if !defined (SERVER_MODE)
5262  {
5263  if (DB_VALUE_TYPE (value) == DB_TYPE_OID)
5264  {
5265  oidp = db_get_oid (value);
5266  rc = or_put_oid (buf, oidp);
5267  return rc;
5268  }
5269  else
5270  {
5271  return ER_FAILED;
5272  }
5273  }
5274  if (DB_VALUE_TYPE (value) == DB_TYPE_OBJECT)
5275  {
5276  mop = db_get_object (value);
5277  if ((mop == NULL) || (WS_IS_DELETED (mop)))
5278  {
5279  rc = or_put_oid (buf, (OID *) (&oid_Null_oid));
5280  }
5281  else if (WS_ISVID (mop))
5282  {
5283  DB_VALUE vmop_seq;
5284  int error;
5285 
5286  error = vid_object_to_vobj (mop, &vmop_seq);
5287  if (error >= 0)
5288  {
5289  rc = mr_data_writeval_set (buf, &vmop_seq);
5290  pr_clear_value (&vmop_seq);
5291  }
5292  else
5293  {
5294  rc = ER_FAILED;
5295  }
5296  }
5297  else
5298  {
5299  oidp = WS_OID (mop);
5300  if (OID_ISTEMP (oidp))
5301  {
5302  /* a MOP with a temporary OID, make an entry in the OID fixup table if we have one, otherwise, stop and
5303  * assign a permanent one. */
5304  oidp = tf_need_permanent_oid (buf, mop);
5305  if (oidp == NULL)
5306  {
5307  /* normally would have used or_abort by now */
5308  oidp = (OID *) (&oid_Null_oid);
5309  }
5310  }
5311  rc = or_put_oid (buf, oidp);
5312  }
5313  }
5314  else if (DB_VALUE_TYPE (value) == DB_TYPE_OID)
5315  {
5316  oidp = db_get_oid (value);
5317  rc = or_put_oid (buf, oidp);
5318  }
5319  else
5320  {
5321  /* should never get here ! */
5322  rc = or_put_oid (buf, (OID *) (&oid_Null_oid));
5323  }
5324 #else /* SERVER_MODE */
5325  /* on the server, the value must contain an OID */
5326  oidp = db_get_oid (value);
5327  rc = or_put_oid (buf, oidp);
5328 #endif /* !SERVER_MODE */
5329  return rc;
5330 }
5331 
5332 
5333 
5334 static int
5335 mr_index_readval_object (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
5336  int copy_buf_len)
5337 {
5338  return mr_index_readval_oid (buf, value, domain, size, copy, copy_buf, copy_buf_len);
5339 }
5340 
5341 static int
5342 mr_data_readval_object (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
5343  int copy_buf_len)
5344 {
5345  OID oid;
5346  int rc = NO_ERROR;
5347 
5348 #if !defined (SERVER_MODE)
5349  if (value == NULL)
5350  {
5351  rc = or_advance (buf, tp_Object.disksize);
5352  }
5353  else
5354  {
5356  {
5357  /* basically the same as mr_readval_server_oid, don't promote OIDs */
5359  rc = or_get_oid (buf, &oid);
5360  db_make_oid (value, &oid);
5361  }
5362  else
5363  {
5365 
5366  rc = or_get_oid (buf, &oid);
5367  /*
5368  * if the OID is NULL, leave the value with the NULL bit set
5369  * and don't bother to put the OID inside.
5370  * I added this because it seemed logical, does it break anything ?
5371  */
5372  if (!OID_ISNULL (&oid))
5373  {
5374  db_make_object (value, ws_mop (&oid, NULL));
5375  if (db_get_object (value) == NULL)
5376  {
5377  or_abort (buf);
5378  return ER_FAILED;
5379  }
5380  }
5381  }
5382  }
5383 #else /* SERVER_MODE */
5384  /* on the server, we only read OIDs */
5385  if (value == NULL)
5386  {
5387  rc = or_advance (buf, tp_Object.disksize);
5388  }
5389  else
5390  {
5392  rc = or_get_oid (buf, &oid);
5393  /* should we be checking for the NULL OID here ? */
5394  db_make_oid (value, &oid);
5395  }
5396 #endif /* !SERVER_MODE */
5397  return rc;
5398 }
5399 
5401 mr_index_cmpdisk_object (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
5402 {
5403  assert (domain != NULL);
5404 
5405  return mr_index_cmpdisk_oid (mem1, mem2, domain, do_coercion, total_order, start_colp);
5406 }
5407 
5409 mr_data_cmpdisk_object (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
5410 {
5412  OID o1, o2;
5413  int oidc;
5414 
5415  assert (domain != NULL);
5416 
5417  OR_GET_OID (mem1, &o1);
5418  OR_GET_OID (mem2, &o2);
5419  /* if we ever store virtual objects, this will need to be changed. However, since its known the only disk
5420  * representation of objects is an OID, this is a valid optimization */
5421 
5422  oidc = oid_compare (&o1, &o2);
5423  c = MR_CMP_RETURN_CODE (oidc);
5424 
5425  return c;
5426 }
5427 
5429 mr_cmpval_object (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
5430  int collation)
5431 {
5432 #if defined (SERVER_MODE)
5433  const OID *o1, *o2;
5434  int oidc;
5435 
5436  /*
5437  * we need to be careful here because even though the domain may
5438  * say object, it may really be an OID (especially on the server).
5439  */
5440  if (DB_VALUE_DOMAIN_TYPE (value1) == DB_TYPE_OID)
5441  {
5442  o1 = db_get_oid (value1);
5443  }
5444  else
5445  {
5446  assert (false);
5447  o1 = &oid_Null_oid;
5448  }
5449 
5450  if (DB_VALUE_DOMAIN_TYPE (value2) == DB_TYPE_OID)
5451  {
5452  o2 = db_get_oid (value2);
5453  }
5454  else
5455  {
5456  assert (false);
5457  o2 = &oid_Null_oid;
5458  }
5459 
5460  oidc = oid_compare (o1, o2);
5461  return MR_CMP_RETURN_CODE (oidc);
5462 #else /* !SERVER_MODE */
5463  /* on the client, we must also handle virtual db_object types */
5465  OID *o1 = NULL, *o2 = NULL;
5466  DB_OBJECT *mop1 = NULL, *mop2 = NULL, *class1, *class2;
5467  int virtual_ = 0;
5468  int nonupdate = 0;
5469  DB_VALUE keys1, keys2;
5470 
5471  /*
5472  * we need to be careful here because even though the domain may
5473  * say object, it may really be an OID (especially on the server).
5474  */
5475  if (DB_VALUE_DOMAIN_TYPE (value1) == DB_TYPE_OID)
5476  {
5477  o1 = db_get_oid (value1);
5478  }
5479  else
5480  {
5481  mop1 = db_get_object (value1);
5482  if (WS_ISVID (mop1))
5483  {
5484  if (db_is_updatable_object (mop1))
5485  {
5486  mop1 = db_real_instance (mop1);
5487  }
5488  else
5489  {
5490  nonupdate = 1;
5491  }
5492 
5493  if (mop1 != NULL)
5494  {
5495  if (WS_ISVID (mop1))
5496  {
5497  /* non updateble object or proxy object */
5498  virtual_ = 1;
5499  }
5500  else
5501  {
5502  o1 = WS_OID (mop1);
5503  }
5504  }
5505  else
5506  {
5507  o1 = (OID *) (&oid_Null_oid);
5508  }
5509  }
5510  else
5511  {
5512  o1 = WS_OID (mop1);
5513  }
5514  }
5515 
5516  if (DB_VALUE_DOMAIN_TYPE (value2) == DB_TYPE_OID)
5517  {
5518  o2 = db_get_oid (value2);
5519  }
5520  else
5521  {
5522  mop2 = db_get_object (value2);
5523  if (WS_ISVID (mop2))
5524  {
5525  if (db_is_updatable_object (mop2))
5526  {
5527  mop2 = db_real_instance (mop2);
5528  }
5529  else
5530  {
5531  nonupdate += 2;
5532  }
5533 
5534  if (mop2 != NULL)
5535  {
5536  if (WS_ISVID (mop2))
5537  {
5538  /* non updateble object or proxy object */
5539  virtual_ += 2;
5540  }
5541  else
5542  {
5543  o2 = WS_OID (mop2);
5544  }
5545  }
5546  else
5547  {
5548  o2 = (OID *) (&oid_Null_oid);
5549  }
5550  }
5551  else
5552  {
5553  o2 = WS_OID (mop2);
5554  }
5555  }
5556 
5557  if (virtual_ == 0)
5558  {
5559  int oidc = oid_compare (o1, o2);
5560  return MR_CMP_RETURN_CODE (oidc);
5561  }
5562 
5563  if (mop1 == mop2)
5564  {
5565  return DB_EQ; /* an optimization */
5566  }
5567 
5568  if (virtual_ == 1)
5569  {
5570  return DB_LT; /* consistent comparison of oids and */
5571  }
5572  if (virtual_ == 2)
5573  {
5574  return DB_GT; /* non-oid based vobjs, they are never equal */
5575  }
5576 
5577  /* virtual must be 3, meaning both objects are either proxies or non-updatable objects */
5578 
5579  if (nonupdate == 1)
5580  {
5581  return DB_LT; /* again, a consistent comparison */
5582  }
5583 
5584  if (nonupdate == 2)
5585  {
5586  return DB_GT; /* for proxy mop and non-updatable mop */
5587  }
5588 
5589  if (nonupdate == 0)
5590  {
5591  int oidc;
5592  /*
5593  * comparing two proxy mops, the must both be from the
5594  * same proxy class. Compare the proxy classes oids.
5595  * Note class mops are never virtual mops.
5596  */
5597  class1 = db_get_class (mop1);
5598  class2 = db_get_class (mop2);
5599  o1 = (class1) ? WS_OID (class1) : (OID *) (&oid_Null_oid);
5600  o2 = (class2) ? WS_OID (class2) : (OID *) (&oid_Null_oid);
5601  oidc = oid_compare (o1, o2);
5602  c = MR_CMP_RETURN_CODE (oidc);
5603 
5604  /*
5605  * as long as the result is not equal, we are done
5606  * If its equal, we need to continue with a key test below.
5607  */
5608  if (c != DB_EQ)
5609  {
5610  return c;
5611  }
5612  }
5613 
5614  /*
5615  * here, nonupdate must be 3 or 0 and
5616  * we must have two non-updatable mops, or two proxy mops
5617  * from the same proxy. Consequently, their keys are comparable
5618  * to identify the object.
5619  */
5620  vid_get_keys (mop1, &keys1);
5621  vid_get_keys (mop2, &keys2);
5622  return tp_value_compare (&keys1, &keys2, do_coercion, total_order);
5623 #endif /* SERVER_MODE */
5624 }
5625 
5626 
5627 
5628 
5629 #if !defined (SERVER_MODE)
5630 
5631 
5632 #endif /* !SERVER_MODE */
5633 
5634 static void
5635 mr_initmem_elo (void *memptr, TP_DOMAIN * domain)
5636 {
5637  if (memptr != NULL)
5638  {
5639  *((DB_ELO **) memptr) = NULL;
5640  }
5641 }
5642 
5643 static void
5644 mr_initval_elo (DB_VALUE * value, int precision, int scale)
5645 {
5646  /* should not be called */
5647  assert (0);
5648 }
5649 
5650 static void
5651 mr_initval_blob (DB_VALUE * value, int precision, int scale)
5652 {
5653  DB_ELO *null_elo = NULL;
5654  db_value_domain_init (value, DB_TYPE_BLOB, precision, scale);
5655  db_make_elo (value, DB_TYPE_BLOB, null_elo);
5656 }
5657 
5658 static void
5659 mr_initval_clob (DB_VALUE * value, int precision, int scale)
5660 {
5661  DB_ELO *null_elo = NULL;
5662  db_value_domain_init (value, DB_TYPE_CLOB, precision, scale);
5663  db_make_elo (value, DB_TYPE_CLOB, null_elo);
5664 }
5665 
5666 static int
5667 mr_setmem_elo (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
5668 {
5669  int rc;
5670  DB_ELO *elo, *e;
5671 
5672  if (memptr != NULL)
5673  {
5674  mr_freemem_elo (memptr);
5675  mr_initmem_elo (memptr, domain);
5676 
5677  if (value != NULL && (e = db_get_elo (value)) != NULL)
5678  {
5679  elo = (DB_ELO *) db_private_alloc (NULL, sizeof (DB_ELO));
5680  if (elo == NULL)
5681  {
5682  return ((er_errid () == NO_ERROR) ? ER_FAILED : er_errid ());
5683  }
5684  rc = elo_copy_structure (e, elo);
5685  if (rc != NO_ERROR)
5686  {
5687  if (elo != NULL)
5688  {
5690  }
5691  return rc;
5692  }
5693 
5694  *((DB_ELO **) memptr) = elo;
5695  }
5696  }
5697  else
5698  {
5699  assert_release (0);
5700  }
5701 
5702  return NO_ERROR;
5703 }
5704 
5705 static int
5706 getmem_elo_with_type (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy, DB_TYPE type)
5707 {
5708  DB_ELO *elo;
5709  int r = NO_ERROR;
5710 
5711  if (memptr == NULL)
5712  {
5713  db_make_null (value);
5714  return r;
5715  }
5716 
5717  elo = *((DB_ELO **) memptr);
5718 
5719  if (elo == NULL || elo->size < 0)
5720  {
5721  db_make_null (value);
5722  return r;
5723  }
5724 
5725  if (copy)
5726  {
5727  DB_ELO e;
5728 
5729  r = elo_copy_structure (elo, &e);
5730  if (r == NO_ERROR)
5731  {
5732  db_make_elo (value, type, &e);
5733  value->need_clear = true;
5734  }
5735  }
5736  else
5737  {
5738  db_make_elo (value, type, elo);
5739  }
5740 
5741  return r;
5742 }
5743 
5744 static int
5745 mr_getmem_elo (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
5746 {
5747  /* should not happen */
5748  assert (0);
5749  return ER_FAILED;
5750 }
5751 
5752 static int
5753 mr_getmem_blob (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
5754 {
5755  return getmem_elo_with_type (memptr, domain, value, copy, DB_TYPE_BLOB);
5756 }
5757 
5758 static int
5759 mr_getmem_clob (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
5760 {
5761  return getmem_elo_with_type (memptr, domain, value, copy, DB_TYPE_CLOB);
5762 }
5763 
5764 static int
5765 setval_elo_with_type (DB_VALUE * dest, const DB_VALUE * src, bool copy, DB_TYPE type)
5766 {
5767  int r = NO_ERROR;
5768 
5769  if (DB_IS_NULL (src) || db_get_elo (src) == NULL)
5770  {
5771  db_make_null (dest);
5772  return NO_ERROR;
5773  }
5774 
5775  if (copy)
5776  {
5777  DB_ELO elo;
5778  DB_ELO *e = db_get_elo (src);
5779 
5780  r = elo_copy_structure (e, &elo);
5781  if (r == NO_ERROR)
5782  {
5783  db_make_elo (dest, type, &elo);
5784  dest->need_clear = true;
5785  }
5786  }
5787  else
5788  {
5789  db_make_elo (dest, type, db_get_elo (src));
5790  }
5791 
5792  return r;
5793 }
5794 
5795 static int
5796 mr_setval_elo (DB_VALUE * dest, const DB_VALUE * src, bool copy)
5797 {
5798  assert (0);
5799  return ER_FAILED;
5800 }
5801 
5802 static int
5803 mr_setval_blob (DB_VALUE * dest, const DB_VALUE * src, bool copy)
5804 {
5805  return setval_elo_with_type (dest, src, copy, DB_TYPE_BLOB);
5806 }
5807 
5808 static int
5809 mr_setval_clob (DB_VALUE * dest, const DB_VALUE * src, bool copy)
5810 {
5811  return setval_elo_with_type (dest, src, copy, DB_TYPE_CLOB);
5812 }
5813 
5814 static int
5815 mr_data_lengthmem_elo (void *memptr, TP_DOMAIN * domain, int disk)
5816 {
5817  int len = 0;
5818 
5819  if (!disk)
5820  {
5821  assert (tp_Elo.size == tp_Blob.size);
5822  assert (tp_Blob.size == tp_Clob.size);
5823  len = tp_Elo.size;
5824  }
5825  else if (memptr != NULL)
5826  {
5827  DB_ELO *elo = *((DB_ELO **) memptr);
5828 
5829  if (elo != NULL && elo->type != ELO_NULL)
5830  {
5831  len = (OR_BIGINT_SIZE
5834  }
5835  }
5836  else
5837  {
5838  assert_release (0);
5839  }
5840 
5841  return len;
5842 }
5843 
5844 static int
5845 mr_data_lengthval_elo (DB_VALUE * value, int disk)
5846 {
5847  DB_ELO *elo;
5848 
5849  if (value != NULL)
5850  {
5851  elo = db_get_elo (value);
5852  return mr_data_lengthmem_elo ((void *) &elo, NULL, disk);
5853  }
5854  else
5855  {
5856  return 0;
5857  }
5858 }
5859 
5860 static void
5861 mr_data_writemem_elo (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
5862 {
5863  DB_ELO *elo;
5864 
5865  if (memptr == NULL)
5866  {
5867  assert_release (0);
5868  return;
5869  }
5870 
5871  elo = *((DB_ELO **) memptr);
5872 
5873  if (elo != NULL && elo->type != ELO_NULL)
5874  {
5875  /* size */
5876  or_put_bigint (buf, elo->size);
5877 
5878  /* locator */
5879  assert (elo->locator != NULL);
5881  if (elo->locator != NULL)
5882  {
5883  or_put_string_aligned (buf, elo->locator);
5884  }
5885 
5886  /* meta_data */
5888  if (elo->meta_data != NULL)
5889  {
5890  or_put_string_aligned (buf, elo->meta_data);
5891  }
5892 
5893  /* type */
5894  or_put_int (buf, elo->type);
5895  }
5896 }
5897 
5898 static void
5899 peekmem_elo (OR_BUF * buf, DB_ELO * elo)
5900 {
5901  int locator_len, meta_data_len;
5902  int rc = NO_ERROR;
5903 
5904  /* size */
5905  elo->size = or_get_bigint (buf, &rc);
5906 
5907  if (rc != NO_ERROR)
5908  {
5909  assert (false);
5910  goto error;
5911  }
5912 
5913  /* locator */
5914  locator_len = or_get_int (buf, &rc);
5915  if (rc != NO_ERROR)
5916  {
5917  assert (false);
5918  goto error;
5919  }
5920  if (locator_len > 0)
5921  {
5922  elo->locator = buf->ptr;
5923  }
5924  else
5925  {
5926  assert (false);
5927  goto error;
5928  }
5929  rc = or_advance (buf, locator_len);
5930  if (rc != NO_ERROR)
5931  {
5932  assert (false);
5933  goto error;
5934  }
5935 
5936  /* meta_data */
5937  meta_data_len = or_get_int (buf, &rc);
5938  if (rc != NO_ERROR)
5939  {
5940  assert (false);
5941  goto error;
5942  }
5943  if (meta_data_len > 0)
5944  {
5945  elo->meta_data = buf->ptr;
5946  }
5947  else
5948  {
5949  elo->meta_data = NULL;
5950  }
5951  rc = or_advance (buf, meta_data_len);
5952  if (rc != NO_ERROR)
5953  {
5954  assert (false);
5955  goto error;
5956  }
5957 
5958  /* type */
5959  elo->type = (DB_ELO_TYPE) or_get_int (buf, &rc);
5960  if (rc != NO_ERROR)
5961  {
5962  assert (false);
5963  goto error;
5964  }
5965 
5966  return;
5967 
5968 error:
5969  elo->locator = NULL;
5970  elo->meta_data = NULL;
5971  elo->size = 0;
5972  elo->type = ELO_NULL;
5973 }
5974 
5975 static void
5976 mr_data_readmem_elo (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
5977 {
5978  DB_ELO *elo;
5979  DB_ELO e;
5980  int rc = NO_ERROR;
5981 
5982  if (size == 0)
5983  {
5984  return;
5985  }
5986 
5987  if (memptr == NULL)
5988  {
5989  or_advance (buf, size);
5990  return;
5991  }
5992 
5993  elo = (DB_ELO *) db_private_alloc (NULL, sizeof (DB_ELO));
5994  if (elo == NULL)
5995  {
5996  or_abort (buf);
5997  }
5998  else
5999  {
6000  peekmem_elo (buf, &e);
6001 
6002  rc = elo_copy_structure (&e, elo);
6003  if (rc != NO_ERROR)
6004  {
6006  or_abort (buf);
6007  }
6008  }
6009 
6010  *((DB_ELO **) memptr) = elo;
6011 }
6012 
6013 static int
6015 {
6016  DB_ELO *elo;
6017 
6018  elo = db_get_elo (value);
6019  mr_data_writemem_elo (buf, (void *) &elo, NULL);
6020  return NO_ERROR;
6021 }
6022 
6023 static int
6024 readval_elo_with_type (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6025  int copy_buf_len, DB_TYPE type)
6026 {
6027  int rc = NO_ERROR;
6028 
6029  if (value == NULL)
6030  {
6031  rc = or_advance (buf, size);
6032  return rc;
6033  }
6034 
6035  if (size != 0)
6036  {
6037  if (copy)
6038  {
6039  DB_ELO *e = NULL;
6040 
6041  mr_data_readmem_elo (buf, (void *) &e, NULL, size);
6042  /* structure copy - to value->data.elo */
6043  rc = db_make_elo (value, type, e);
6044  if (e != NULL)
6045  {
6047  }
6048 
6049  value->need_clear = true;
6050  }
6051  else
6052  {
6053  DB_ELO elo;
6054 
6055  peekmem_elo (buf, &elo);
6056  /* structure copy - to value->data.elo */
6057  rc = db_make_elo (value, type, &elo);
6058  }
6059  }
6060 
6061  return rc;
6062 }
6063 
6064 static int
6065 mr_data_readval_elo (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6066  int copy_buf_len)
6067 {
6068  /* should not happen */
6069  assert (0);
6070  return ER_FAILED;
6071 }
6072 
6073 static int
6074 mr_data_readval_blob (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6075  int copy_buf_len)
6076 {
6077  return readval_elo_with_type (buf, value, domain, size, copy, copy_buf, copy_buf_len, DB_TYPE_BLOB);
6078 }
6079 
6080 static int
6081 mr_data_readval_clob (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6082  int copy_buf_len)
6083 {
6084  return readval_elo_with_type (buf, value, domain, size, copy, copy_buf, copy_buf_len, DB_TYPE_CLOB);
6085 }
6086 
6087 static void
6088 mr_freemem_elo (void *memptr)
6089 {
6090  DB_ELO *elo;
6091 
6092  if (memptr != NULL)
6093  {
6094  elo = *((DB_ELO **) memptr);
6095 
6096  if (elo != NULL)
6097  {
6098  elo_free_structure (elo);
6100  }
6101  }
6102 }
6103 
6105 mr_data_cmpdisk_elo (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6106 {
6107  assert (domain != NULL);
6108 
6109  /*
6110  * don't know how to do this since elo's should find their way into
6111  * listfiles and such.
6112  */
6113  return DB_UNK;
6114 }
6115 
6117 mr_cmpval_elo (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
6118 {
6119  DB_ELO *elo1, *elo2;
6120 
6121  elo1 = db_get_elo (value1);
6122  elo2 = db_get_elo (value2);
6123 
6124  /* use address for collating sequence */
6125  return MR_CMP ((UINTPTR) elo1, (UINTPTR) elo2);
6126 }
6127 
6128 /*
6129  * TYPE VARIABLE
6130  *
6131  * Currently this can only be used internally for class objects. I think
6132  * this is useful enough to make a general purpose thing.
6133  * Implemented with the DB_VALUE (like set elements) which means that we
6134  * will always create MOPs for variable values that are object references.
6135  * If this gets to be a big deal, will need to define another union
6136  * like DB_MEMORY_VALUE that has a local OID cache like the attribute
6137  * values do.
6138  * These were once just stubs that didn't do anything since the class
6139  * transformer called the pr_write_va/rtype etc. functions directly. If
6140  * they can be regular types for object attributes, we need to support
6141  * an mr_ interface as well.
6142  *
6143  * NOTE: These are still stubs, need to think about other ramifications
6144  * in the schema level before making these public.
6145  */
6146 
6147 static void
6148 mr_initval_variable (DB_VALUE * value, int precision, int scale)
6149 {
6150  mr_initval_null (value, precision, scale);
6151 }
6152 
6153 static int
6154 mr_setval_variable (DB_VALUE * dest, const DB_VALUE * src, bool copy)
6155 {
6156  mr_initval_null (dest, 0, 0);
6157  return NO_ERROR;
6158 }
6159 
6160 static int
6162 {
6163  return 0;
6164 }
6165 
6166 static int
6168 {
6169  return NO_ERROR;
6170 }
6171 
6172 static int
6173 mr_data_readval_variable (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6174  int copy_buf_len)
6175 {
6176  return NO_ERROR;
6177 }
6178 
6180 mr_data_cmpdisk_variable (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6181 {
6182  assert (domain != NULL);
6183 
6184  return DB_UNK;
6185 }
6186 
6188 mr_cmpval_variable (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
6189  int collation)
6190 {
6191  return DB_UNK;
6192 }
6193 
6194 /*
6195  * TYPE SUBSTRUCTURE
6196  *
6197  * Only for meta objects. Might want to extend.
6198  * This really only serves as a placeholder in the type table. These
6199  * functions should never be referenced through the usual channels.
6200  */
6201 
6202 static void
6203 mr_initmem_sub (void *mem, TP_DOMAIN * domain)
6204 {
6205 }
6206 
6207 static void
6208 mr_initval_sub (DB_VALUE * value, int precision, int scale)
6209 {
6210  db_value_domain_init (value, DB_TYPE_SUB, precision, scale);
6211 }
6212 
6213 static int
6214 mr_setmem_sub (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
6215 {
6216  return NO_ERROR;
6217 }
6218 
6219 static int
6220 mr_getmem_sub (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
6221 {
6222  return NO_ERROR;
6223 }
6224 
6225 static int
6226 mr_setval_sub (DB_VALUE * dest, const DB_VALUE * src, bool copy)
6227 {
6228  return NO_ERROR;
6229 }
6230 
6231 static int
6232 mr_data_lengthmem_sub (void *mem, TP_DOMAIN * domain, int disk)
6233 {
6234  return 0;
6235 }
6236 
6237 static int
6238 mr_data_lengthval_sub (DB_VALUE * value, int disk)
6239 {
6240  return 0;
6241 }
6242 
6243 static void
6244 mr_data_writemem_sub (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
6245 {
6246 }
6247 
6248 static void
6249 mr_data_readmem_sub (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
6250 {
6251 }
6252 
6253 static int
6255 {
6256  return NO_ERROR;
6257 }
6258 
6259 static int
6260 mr_data_readval_sub (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6261  int copy_buf_len)
6262 {
6263  return NO_ERROR;
6264 }
6265 
6267 mr_data_cmpdisk_sub (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6268 {
6269  assert (domain != NULL);
6270 
6271  return DB_UNK;
6272 }
6273 
6275 mr_cmpval_sub (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
6276 {
6277  return DB_UNK;
6278 }
6279 
6280 /*
6281  * TYPE POINTER
6282  *
6283  * These exist only so that method arguments can have arbitrary pointer
6284  * values. You cannot create an attribute that has a pointer value since
6285  * these are not persistent values. Pointer values are used internally
6286  * by the object templates to keep place holders to other templates
6287  * that need to be expanded into objects.
6288  *
6289  */
6290 
6291 static void
6292 mr_initmem_ptr (void *memptr, TP_DOMAIN * domain)
6293 {
6294  void **mem = (void **) memptr;
6295 
6296  *mem = NULL;
6297 }
6298 
6299 static void
6300 mr_initval_ptr (DB_VALUE * value, int precision, int scale)
6301 {
6302  db_value_domain_init (value, DB_TYPE_POINTER, precision, scale);
6303  db_make_pointer (value, NULL);
6304 }
6305 
6306 static int
6307 mr_setmem_ptr (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
6308 {
6309  void **mem = (void **) memptr;
6310 
6311  if (value == NULL)
6312  {
6313  mr_initmem_ptr (mem, domain);
6314  }
6315  else
6316  {
6317  *mem = db_get_pointer (value);
6318  }
6319  return NO_ERROR;
6320 }
6321 
6322 static int
6323 mr_getmem_ptr (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
6324 {
6325  void **mem = (void **) memptr;
6326 
6327  return db_make_pointer (value, *mem);
6328 }
6329 
6330 static int
6331 mr_setval_ptr (DB_VALUE * dest, const DB_VALUE * src, bool copy)
6332 {
6333  if (DB_IS_NULL (src))
6334  {
6335  db_make_null (dest);
6336  return NO_ERROR;
6337  }
6338  else
6339  {
6340  return db_make_pointer (dest, db_get_pointer (src));
6341  }
6342 }
6343 
6344 static int
6345 mr_data_lengthmem_ptr (void *memptr, TP_DOMAIN * domain, int disk)
6346 {
6347  return 0;
6348 }
6349 
6350 static int
6351 mr_data_lengthval_ptr (DB_VALUE * value, int disk)
6352 {
6353  void *ptr;
6354 
6355  if (value != NULL)
6356  {
6357  ptr = db_get_pointer (value);
6358  return mr_data_lengthmem_ptr (&ptr, NULL, disk);
6359  }
6360  else
6361  {
6362  return NO_ERROR;
6363  }
6364 }
6365 
6366 static void
6367 mr_data_writemem_ptr (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
6368 {
6369 }
6370 
6371 static void
6372 mr_data_readmem_ptr (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
6373 {
6374  void **mem = (void **) memptr;
6375 
6376  *mem = NULL;
6377 }
6378 
6379 static int
6381 {
6382  return NO_ERROR;
6383 }
6384 
6385 static int
6386 mr_data_readval_ptr (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6387  int copy_buf_len)
6388 {
6389  if (value)
6390  {
6392  }
6393  return NO_ERROR;
6394 }
6395 
6397 mr_data_cmpdisk_ptr (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6398 {
6399  assert (domain != NULL);
6400 
6401  /* don't know how to unpack pointers */
6402  return DB_UNK;
6403 }
6404 
6406 mr_cmpval_ptr (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
6407 {
6408  void *p1, *p2;
6409 
6410  p1 = db_get_pointer (value1);
6411  p2 = db_get_pointer (value2);
6412 
6413  /* use address for collating sequence */
6414  return MR_CMP ((UINTPTR) p1, (UINTPTR) p2);
6415 }
6416 
6417 /*
6418  * TYPE ERROR
6419  *
6420  * This is used only for method arguments, they cannot be attribute values.
6421  */
6422 
6423 static void
6424 mr_initmem_error (void *memptr, TP_DOMAIN * domain)
6425 {
6426  int *mem = (int *) memptr;
6427 
6428  *mem = NO_ERROR;
6429 }
6430 
6431 static void
6432 mr_initval_error (DB_VALUE * value, int precision, int scale)
6433 {
6434  db_value_domain_init (value, DB_TYPE_ERROR, precision, scale);
6435  db_make_error (value, NO_ERROR);
6436 }
6437 
6438 static int
6439 mr_setmem_error (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
6440 {
6441  int *mem = (int *) memptr;
6442 
6443  if (value == NULL)
6444  {
6445  mr_initmem_error (mem, domain);
6446  }
6447  else
6448  {
6449  *mem = db_get_error (value);
6450  }
6451  return NO_ERROR;
6452 }
6453 
6454 static int
6455 mr_getmem_error (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
6456 {
6457  int *mem = (int *) memptr;
6458 
6459  return db_make_error (value, *mem);
6460 }
6461 
6462 static int
6463 mr_setval_error (DB_VALUE * dest, const DB_VALUE * src, bool copy)
6464 {
6465  if (DB_IS_NULL (src))
6466  {
6467  db_make_null (dest);
6468  return NO_ERROR;
6469  }
6470  else
6471  {
6472  return db_make_error (dest, db_get_error (src));
6473  }
6474 }
6475 
6476 static int
6477 mr_data_lengthmem_error (void *memptr, TP_DOMAIN * domain, int disk)
6478 {
6479  return 0;
6480 }
6481 
6482 static int
6484 {
6485  int error;
6486 
6487  if (value != NULL)
6488  {
6489  error = db_get_error (value);
6490  return mr_data_lengthmem_error (&error, NULL, disk);
6491  }
6492  else
6493  {
6494  return NO_ERROR;
6495  }
6496 }
6497 
6498 static void
6499 mr_data_writemem_error (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
6500 {
6501 }
6502 
6503 static void
6504 mr_data_readmem_error (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
6505 {
6506  int *mem = (int *) memptr;
6507 
6508  *mem = NO_ERROR;
6509 }
6510 
6511 static int
6513 {
6514  return NO_ERROR;
6515 }
6516 
6517 static int
6518 mr_data_readval_error (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6519  int copy_buf_len)
6520 {
6521  if (value)
6522  {
6524  db_make_error (value, NO_ERROR);
6525  }
6526  return NO_ERROR;
6527 }
6528 
6530 mr_data_cmpdisk_error (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6531 {
6532  assert (domain != NULL);
6533 
6534  /* don't know how to unpack errors */
6535  return DB_UNK;
6536 }
6537 
6539 mr_cmpval_error (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
6540 {
6541  int e1, e2;
6542 
6543  e1 = db_get_error (value1);
6544  e2 = db_get_error (value2);
6545 
6546  return MR_CMP (e1, e2);
6547 }
6548 
6549 
6550 /*
6551  * TYPE OID
6552  *
6553  * DB_TYPE_OID is not really a "domain" type, it is rather a physical
6554  * representation of an object domain. Due to the way we dispatch
6555  * on DB_TYPE_ codes however, we need a fleshed out type vector
6556  * for this.
6557  *
6558  * This is used by the server where we have no DB_OBJECT handles.
6559  * It can also be used on the client in places where we defer
6560  * the "swizzling" of OID references (e.g. inside sets).
6561  *
6562  * We don't have to handle the case where values come in with DB_TYPE_OBJECT
6563  * as we do in the _object handlers, true ?
6564  *
6565  */
6566 
6567 static void
6568 mr_initmem_oid (void *memptr, TP_DOMAIN * domain)
6569 {
6570  OID *mem = (OID *) memptr;
6571 
6572  mr_null_oid (mem);
6573 }
6574 
6575 static void
6576 mr_initval_oid (DB_VALUE * value, int precision, int scale)
6577 {
6578  OID oid;
6579 
6580  mr_null_oid (&oid);
6581  db_value_domain_init (value, DB_TYPE_OID, precision, scale);
6582  db_make_oid (value, &oid);
6583 }
6584 
6585 static int
6586 mr_setmem_oid (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
6587 {
6588  OID *mem = (OID *) memptr;
6589  OID *oid;
6590 
6591  if (value == NULL)
6592  {
6593  mr_initmem_oid (mem, domain);
6594  }
6595  else
6596  {
6597  oid = db_get_oid (value);
6598  if (oid)
6599  {
6600  mem->volid = oid->volid;
6601  mem->pageid = oid->pageid;
6602  mem->slotid = oid->slotid;
6603  }
6604  else
6605  {
6606  return ER_FAILED;
6607  }
6608  }
6609  return NO_ERROR;
6610 }
6611 
6612 static int
6613 mr_getmem_oid (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
6614 {
6615  OID *mem = (OID *) memptr;
6616  OID oid;
6617 
6618  oid.volid = mem->volid;
6619  oid.pageid = mem->pageid;
6620  oid.slotid = mem->slotid;
6621  return db_make_oid (value, &oid);
6622 }
6623 
6624 static int
6625 mr_setval_oid (DB_VALUE * dest, const DB_VALUE * src, bool copy)
6626 {
6627  OID *oid;
6628 
6629  if (DB_IS_NULL (src))
6630  {
6631  db_make_null (dest);
6632  return NO_ERROR;
6633  }
6634  else
6635  {
6636  oid = (OID *) db_get_oid (src);
6637  return db_make_oid (dest, oid);
6638  }
6639 }
6640 
6641 static void
6642 mr_data_writemem_oid (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
6643 {
6644  OID *mem = (OID *) memptr;
6645 
6646  or_put_oid (buf, mem);
6647 }
6648 
6649 static void
6650 mr_data_readmem_oid (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
6651 {
6652  OID *mem = (OID *) memptr;
6653  OID oid;
6654 
6655  if (mem != NULL)
6656  {
6657  or_get_oid (buf, mem);
6658  }
6659  else
6660  {
6661  or_get_oid (buf, &oid); /* skip over it */
6662  }
6663 }
6664 
6665 static int
6667 {
6668  return (or_put_oid (buf, db_get_oid (value)));
6669 }
6670 
6671 static int
6672 mr_data_readval_oid (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6673  int copy_buf_len)
6674 {
6675  OID oid;
6676  int rc = NO_ERROR;
6677 
6678  if (value != NULL)
6679  {
6681  rc = or_get_oid (buf, &oid);
6682  db_make_oid (value, &oid);
6683  }
6684  else
6685  {
6686  rc = or_advance (buf, tp_Oid.disksize);
6687  }
6688 
6689  return rc;
6690 }
6691 
6692 static int
6694 {
6695  OID *oidp = NULL;
6696  int rc = NO_ERROR;
6697 
6698  assert (DB_VALUE_TYPE (value) == DB_TYPE_OID || DB_VALUE_TYPE (value) == DB_TYPE_OBJECT);
6699 
6700  oidp = db_get_oid (value);
6701 
6702  rc = or_put_data (buf, (char *) (&oidp->pageid), tp_Integer.disksize);
6703  if (rc == NO_ERROR)
6704  {
6705  rc = or_put_data (buf, (char *) (&oidp->slotid), tp_Short.disksize);
6706  }
6707  if (rc == NO_ERROR)
6708  {
6709  rc = or_put_data (buf, (char *) (&oidp->volid), tp_Short.disksize);
6710  }
6711 
6712  return rc;
6713 }
6714 
6715 static int
6716 mr_index_readval_oid (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
6717  int copy_buf_len)
6718 {
6719  OID oid;
6720  int rc = NO_ERROR;
6721 
6722  if (value == NULL)
6723  {
6724  rc = or_advance (buf, tp_Object.disksize);
6725  }
6726  else
6727  {
6728  rc = or_get_data (buf, (char *) (&oid.pageid), tp_Integer.disksize);
6729  if (rc == NO_ERROR)
6730  {
6731  rc = or_get_data (buf, (char *) (&oid.slotid), tp_Short.disksize);
6732  }
6733  if (rc == NO_ERROR)
6734  {
6735  rc = or_get_data (buf, (char *) (&oid.volid), tp_Short.disksize);
6736  }
6737 
6738  if (rc == NO_ERROR)
6739  {
6741  db_make_oid (value, &oid);
6742  }
6743  }
6744 
6745  return rc;
6746 }
6747 
6749 mr_index_cmpdisk_oid (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6750 {
6752  OID o1, o2;
6753  int oidc;
6754 
6755  assert (domain != NULL);
6756 
6757  COPYMEM (int, &o1.pageid, (char *) mem1 + OR_OID_PAGEID);
6758  COPYMEM (short, &o1.slotid, (char *) mem1 + OR_OID_SLOTID);
6759  COPYMEM (short, &o1.volid, (char *) mem1 + OR_OID_VOLID);
6760 
6761  COPYMEM (int, &o2.pageid, (char *) mem2 + OR_OID_PAGEID);
6762  COPYMEM (short, &o2.slotid, (char *) mem2 + OR_OID_SLOTID);
6763  COPYMEM (short, &o2.volid, (char *) mem2 + OR_OID_VOLID);
6764 
6765  oidc = oid_compare (&o1, &o2);
6766  c = MR_CMP_RETURN_CODE (oidc);
6767 
6768  return c;
6769 }
6770 
6772 mr_data_cmpdisk_oid (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
6773 {
6775  OID o1, o2;
6776  int oidc;
6777 
6778  assert (domain != NULL);
6779 
6780  OR_GET_OID (mem1, &o1);
6781  OR_GET_OID (mem2, &o2);
6782 
6783  oidc = oid_compare (&o1, &o2);
6784  c = MR_CMP_RETURN_CODE (oidc);
6785 
6786  return c;
6787 }
6788 
6790 mr_cmpval_oid (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
6791 {
6793  OID *oid1, *oid2;
6794  int oidc;
6795 
6796  oid1 = db_get_oid (value1);
6797  oid2 = db_get_oid (value2);
6798 
6799  if (oid1 == NULL || oid2 == NULL)
6800  {
6801  return DB_UNK;
6802  }
6803 
6804  oidc = oid_compare (oid1, oid2);
6805  c = MR_CMP_RETURN_CODE (oidc);
6806 
6807  return c;
6808 }
6809 
6810 /*
6811  * TYPE SET
6812  *
6813  * This is easily the most complicated primitive type.
6814  * Sets are defined to be owned by an object.
6815  * They may be checked out of an object and accessed directly through the
6816  * set structure. We need to move maintenance of set ownership down
6817  * from the object layer to this layer. This will avoid a lot of special
6818  * cases for sets that now exist in the pr_ and obj_ layers.
6819  */
6820 
6821 
6822 static void
6823 mr_initmem_set (void *memptr, TP_DOMAIN * domain)
6824 {
6825  SETOBJ **mem = (SETOBJ **) memptr;
6826 
6827  *mem = NULL;
6828 }
6829 
6830 static void
6831 mr_initval_set (DB_VALUE * value, int precision, int scale)
6832 {
6833  db_value_domain_init (value, DB_TYPE_SET, precision, scale);
6834  db_make_set (value, NULL);
6835 }
6836 
6837 static int
6838 mr_setmem_set (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
6839 {
6840  SETOBJ **mem = (SETOBJ **) memptr;
6841  int error = NO_ERROR;
6842  SETOBJ *set;
6843  SETREF *ref;
6844 
6845  /*
6846  * NOTE: assumes ownership info has already been placed
6847  * in the set reference by the caller
6848  */
6849  if ((value != NULL) && ((ref = db_get_set (value)) != NULL))
6850  {
6851  set = ref->set;
6852  if (*mem != set)
6853  {
6854  if (*mem != NULL)
6855  {
6856  error = setobj_release (*mem);
6857  }
6858  *mem = set;
6859  }
6860  }
6861  else
6862  {
6863  if (*mem != NULL)
6864  {
6865  error = setobj_release (*mem);
6866  }
6867  mr_initmem_set (mem, domain);
6868  }
6869  return error;
6870 }
6871 
6872 static int
6873 mr_getmem_set (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
6874 {
6875  SETOBJ **mem = (SETOBJ **) memptr;
6876  int error = NO_ERROR;
6877  SETOBJ *set;
6878  SETREF *ref;
6879 
6880  set = *mem;
6881  if (set == NULL)
6882  {
6883  error = db_make_set (value, NULL);
6884  }
6885  else
6886  {
6887  ref = setobj_get_reference (set);
6888  if (ref)
6889  {
6890  error = db_make_set (value, ref);
6891  }
6892  else
6893  {
6894  assert (er_errid () != NO_ERROR);
6895  error = er_errid ();
6896  (void) db_make_set (value, NULL);
6897  }
6898  }
6899  /*
6900  * NOTE: assumes that ownership info will already have been set or will
6901  * be set by the caller
6902  */
6903 
6904  return error;
6905 }
6906 
6907 static int
6908 mr_setval_set_internal (DB_VALUE * dest, const DB_VALUE * src, bool copy, DB_TYPE set_type)
6909 {
6910  int error = NO_ERROR;
6911  SETREF *src_ref, *ref;
6912 
6913  if (src != NULL && !DB_IS_NULL (src) && ((src_ref = db_get_set (src)) != NULL))
6914  {
6915  if (!copy)
6916  {
6917  ref = src_ref;
6918  /* must increment the reference count */
6919  ref->ref_count++;
6920  }
6921  else
6922  {
6923  /* need to check if we have a disk_image, if so we just copy it */
6924  if (src_ref->disk_set)
6925  {
6926  ref = set_make_reference ();
6927  if (ref == NULL)
6928  {
6929  goto err_set;
6930  }
6931  else
6932  {
6933  /* Copy the bits into a freshly allocated buffer. */
6934  ref->disk_set = (char *) db_private_alloc (NULL, src_ref->disk_size);
6935  if (ref->disk_set == NULL)
6936  {
6937  goto err_set;
6938  }
6939  else
6940  {
6941  ref->need_clear = true;
6942  ref->disk_size = src_ref->disk_size;
6943  ref->disk_domain = src_ref->disk_domain;
6944  memcpy (ref->disk_set, src_ref->disk_set, src_ref->disk_size);
6945  }
6946  }
6947  }
6948  else
6949  {
6950  ref = set_copy (src_ref);
6951  if (ref == NULL)
6952  {
6953  goto err_set;
6954  }
6955  }
6956  }
6957 
6958  switch (set_type)
6959  {
6960  case DB_TYPE_SET:
6961  db_make_set (dest, ref);
6962  break;
6963  case DB_TYPE_MULTISET:
6964  db_make_multiset (dest, ref);
6965  break;
6966  case DB_TYPE_SEQUENCE:
6967  db_make_sequence (dest, ref);
6968  break;
6969  default:
6970  break;
6971  }
6972  }
6973  else
6974  {
6976  }
6977  return error;
6978 
6979 err_set:
6980  /* couldn't allocate storage for set */
6981  assert (er_errid () != NO_ERROR);
6982  error = er_errid ();
6983  switch (set_type)
6984  {
6985  case DB_TYPE_SET:
6986  db_make_set (dest, NULL);
6987  break;
6988  case DB_TYPE_MULTISET:
6989  db_make_multiset (dest, NULL);
6990  break;
6991  case DB_TYPE_SEQUENCE:
6992  db_make_sequence (dest, NULL);
6993  break;
6994  default:
6995  break;
6996  }
6997  db_make_null (dest);
6998  return error;
6999 }
7000 
7001 static int
7002 mr_setval_set (DB_VALUE * dest, const DB_VALUE * src, bool copy)
7003 {
7004  return mr_setval_set_internal (dest, src, copy, DB_TYPE_SET);
7005 }
7006 
7007 static int
7008 mr_data_lengthmem_set (void *memptr, TP_DOMAIN * domain, int disk)
7009 {
7010  int size;
7011 
7012  if (!disk)
7013  {
7014  size = tp_Set.size;
7015  }
7016  else
7017  {
7018  SETOBJ **mem = (SETOBJ **) memptr;
7019 
7020  size = or_packed_set_length (*mem, 0);
7021  }
7022 
7023  return size;
7024 }
7025 
7026 static int
7027 mr_data_lengthval_set (DB_VALUE * value, int disk)
7028 {
7029  SETREF *ref;
7030  SETOBJ *set;
7031  int size;
7032 #if !defined (SERVER_MODE)
7033  int pin;
7034 #endif
7035 
7036  size = 0;
7037 
7038  if (!disk)
7039  {
7040  size = sizeof (DB_SET *);
7041  }
7042  else
7043  {
7044  ref = db_get_set (value);
7045  if (ref != NULL)
7046  {
7047  /* should have a set_ function for this ! */
7048  if (ref->disk_set)
7049  {
7050  size = ref->disk_size;
7051  }
7052  else if (set_get_setobj (ref, &set, 0) == NO_ERROR)
7053  {
7054  if (set != NULL)
7055  {
7056  /* probably no need to pin here but it can't hurt */
7057 #if !defined (SERVER_MODE)
7058  pin = ws_pin (ref->owner, 1);
7059 #endif
7060  size = or_packed_set_length (set, 1);
7061 #if !defined (SERVER_MODE)
7062  (void) ws_pin (ref->owner, pin);
7063 #endif
7064  }
7065  }
7066  }
7067  }
7068  return size;
7069 }
7070 
7071 static void
7072 mr_data_writemem_set (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
7073 {
7074  SETOBJ **mem = (SETOBJ **) memptr;
7075 
7076  if (*mem != NULL)
7077  {
7078  /* note that we don't have to pin the object here since that will have been handled above this leve. */
7079  or_put_set (buf, *mem, 0);
7080  }
7081 }
7082 
7083 static int
7085 {
7086  SETREF *ref;
7087  SETOBJ *set;
7088  int size;
7089 #if !defined (SERVER_MODE)
7090  int pin;
7091 #endif
7092  int rc = NO_ERROR;
7093 
7094  ref = db_get_set (value);
7095  if (ref != NULL)
7096  {
7097  /* If we have a disk image of the set, we can just copy those bits here. This assumes very careful maintenance
7098  * of the disk and memory images. Currently, we only have one or the other. That is, when we transform the disk
7099  * image to memory, we clear the disk image. */
7100  if (ref->disk_set)
7101  {
7102  /* check for overflow */
7103  if ((((ptrdiff_t) (buf->endptr - buf->ptr)) < (ptrdiff_t) ref->disk_size))
7104  {
7105  return or_overflow (buf);
7106  }
7107  else
7108  {
7109  memcpy (buf->ptr, ref->disk_set, ref->disk_size);
7110  rc = or_advance (buf, ref->disk_size);
7111  }
7112  }
7113  else if (set_get_setobj (ref, &set, 0) == NO_ERROR)
7114  {
7115  if (set != NULL)
7116  {
7117  if (ref->owner == NULL)
7118  {
7119  or_put_set (buf, set, 1);
7120  }
7121  else
7122  {
7123 #if !defined (SERVER_MODE)
7124  pin = ws_pin (ref->owner, 1);
7125 #endif
7126  size = or_packed_set_length (set, 1);
7127  /* remember the Windows pointer problem ! */
7128  if (((ptrdiff_t) (buf->endptr - buf->ptr)) < (ptrdiff_t) size)
7129  {
7130  /* unpin the owner before we abort ! */
7131 #if !defined (SERVER_MODE)
7132  (void) ws_pin (ref->owner, pin);
7133 #endif
7134  return or_overflow (buf);
7135  }
7136  else
7137  {
7138  /* the buffer is ok, do the transformation */
7139  or_put_set (buf, set, 1);
7140  }
7141 #if !defined (SERVER_MODE)
7142  (void) ws_pin (ref->owner, pin);
7143 #endif
7144  }
7145  }
7146  }
7147  }
7148  return rc;
7149 }
7150 
7151 static void
7152 mr_data_readmem_set (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
7153 {
7154  SETOBJ **mem = (SETOBJ **) memptr;
7155  SETOBJ *set;
7156 
7157  if (mem == NULL)
7158  {
7159  if (size >= 0)
7160  {
7161  or_advance (buf, size);
7162  }
7163  else
7164  {
7165  set = or_get_set (buf, domain);
7166  if (set != NULL)
7167  {
7168  setobj_free (set);
7169  }
7170  }
7171  }
7172  else
7173  {
7174  if (!size)
7175  {
7176  *mem = NULL;
7177  }
7178  else
7179  {
7180  set = or_get_set (buf, domain);
7181  if (set != NULL)
7182  {
7183  *mem = set;
7184  }
7185  else
7186  {
7187  or_abort (buf);
7188  }
7189  }
7190  }
7191 }
7192 
7193 static int
7194 mr_data_readval_set (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
7195  int copy_buf_len)
7196 {
7197  SETOBJ *set;
7198  SETREF *ref;
7199  int rc = NO_ERROR;
7200 
7201  if (value == NULL)
7202  {
7203  if (size == -1)
7204  {
7205  /* don't know the true size, must unpack the set and throw it away */
7206  set = or_get_set (buf, domain);
7207  if (set != NULL)
7208  {
7209  setobj_free (set);
7210  }
7211  else
7212  {
7213  or_abort (buf);
7214  return ER_FAILED;
7215  }
7216  }
7217  else
7218  {
7219  if (size)
7220  {
7221  rc = or_advance (buf, size);
7222  }
7223  }
7224  }
7225  else
7226  {
7227  /* In some cases, like VOBJ reading, the domain passed is NULL here so be careful when initializing the value.
7228  * If it is NULL, it will be read when the set is unpacked. */
7229  if (!domain)
7230  {
7232  }
7233  else
7234  {
7235  db_value_domain_init (value, TP_DOMAIN_TYPE (domain), domain->precision, domain->scale);
7236  }
7237 
7238  /* If size is zero, we have nothing to do, if size is -1, just go ahead and unpack the set. */
7239  if (!size)
7240  {
7241  db_make_set (value, NULL);
7242  }
7243  else if (copy)
7244  {
7245  set = or_get_set (buf, domain);
7246  if (set == NULL)
7247  {
7248  or_abort (buf);
7249  return ER_FAILED;
7250  }
7251  else
7252  {
7253  ref = setobj_get_reference (set);
7254  if (ref == NULL)
7255  {
7256  or_abort (buf);
7257  return ER_FAILED;
7258  }
7259  else
7260  {
7261  switch (set_get_type (ref))
7262  {
7263  case DB_TYPE_SET:
7264  db_make_set (value, ref);
7265  break;
7266  case DB_TYPE_MULTISET:
7267  db_make_multiset (value, ref);
7268  break;
7269  case DB_TYPE_SEQUENCE:
7270  db_make_sequence (value, ref);
7271  break;
7272  default:
7273  break;
7274  }
7275  }
7276  }
7277  }
7278  else
7279  {
7280  /* copy == false, which means don't translate it into memory rep */
7281  ref = set_make_reference ();
7282  if (ref == NULL)
7283  {
7284  or_abort (buf);
7285  return ER_FAILED;
7286  }
7287  else
7288  {
7289  int disk_size;
7290  DB_TYPE set_type;
7291 
7292  if (size != -1)
7293  {
7294  char *set_st;
7295  int num_elements, has_domain, bound_bits, offset_tbl, el_tags;
7296 
7297  disk_size = size;
7298 
7299  /* unfortunately, we still need to look at the header to find out the set type. */
7300  set_st = buf->ptr;
7301  or_get_set_header (buf, &set_type, &num_elements, &has_domain, &bound_bits, &offset_tbl, &el_tags,
7302  NULL);
7303 
7304  /* reset the OR_BUF */
7305  buf->ptr = set_st;
7306  }
7307  else
7308  {
7309  /* we have to go figure the size out */
7310  disk_size = or_disk_set_size (buf, domain, &set_type);
7311  }
7312 
7313  /* Record the pointer to the disk bits */
7314  ref->disk_set = buf->ptr;
7315  ref->need_clear = false;
7316  ref->disk_size = disk_size;
7317  ref->disk_domain = domain;
7318 
7319  /* advance the buffer as if we had read the set */
7320  rc = or_advance (buf, disk_size);
7321 
7322  switch (set_type)
7323  {
7324  case DB_TYPE_SET:
7325  db_make_set (value, ref);
7326  break;
7327  case DB_TYPE_MULTISET:
7328  db_make_multiset (value, ref);
7329  break;
7330  case DB_TYPE_SEQUENCE:
7331  db_make_sequence (value, ref);
7332  break;
7333  default:
7334  break;
7335  }
7336  }
7337  }
7338  }
7339  return rc;
7340 }
7341 
7342 static void
7343 mr_freemem_set (void *memptr)
7344 {
7345  /* since we aren't explicitly setting the set to NULL, we must set up the reference structures so they will get the
7346  * new set when it is brought back in, this is the only primitive type for which the free function is semantically
7347  * different than using the setmem function with a NULL value */
7348 
7349  SETOBJ **mem = (SETOBJ **) memptr;
7350 
7351  if (*mem != NULL)
7352  {
7353  setobj_free (*mem); /* free storage, NULL references */
7354  }
7355 }
7356 
7358 mr_data_cmpdisk_set (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
7359 {
7361  SETOBJ *set1 = NULL, *set2 = NULL;
7362 
7363  assert (domain != NULL);
7364 
7365  /* is not index type */
7366  assert (!domain->is_desc && !tp_valid_indextype (TP_DOMAIN_TYPE (domain)));
7367 
7368  mem1 = or_unpack_set ((char *) mem1, &set1, domain);
7369  mem2 = or_unpack_set ((char *) mem2, &set2, domain);
7370 
7371  if (set1 == NULL || set2 == NULL)
7372  {
7373  return DB_UNK;
7374  }
7375 
7376  c = setobj_compare_order (set1, set2, do_coercion, total_order);
7377 
7378  setobj_free (set1);
7379  setobj_free (set2);
7380 
7381  return c;
7382 }
7383 
7385 mr_cmpval_set (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
7386 {
7387  return set_compare_order (db_get_set (value1), db_get_set (value2), do_coercion, total_order);
7388 }
7389 
7390 /*
7391  * TYPE MULTISET
7392  */
7393 
7394 static void
7395 mr_initval_multiset (DB_VALUE * value, int precision, int scale)
7396 {
7397  db_value_domain_init (value, DB_TYPE_MULTISET, precision, scale);
7398  db_make_multiset (value, NULL);
7399 }
7400 
7401 static int
7402 mr_getmem_multiset (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
7403 {
7404  SETOBJ **mem = (SETOBJ **) memptr;
7405  int error = NO_ERROR;
7406  SETOBJ *set;
7407  SETREF *ref;
7408 
7409  set = *mem;
7410  if (set == NULL)
7411  {
7412  error = db_make_multiset (value, NULL);
7413  }
7414  else
7415  {
7416  ref = setobj_get_reference (set);
7417  if (ref)
7418  {
7419  error = db_make_multiset (value, ref);
7420  }
7421  else
7422  {
7423  assert (er_errid () != NO_ERROR);
7424  error = er_errid ();
7425  (void) db_make_multiset (value, NULL);
7426  }
7427  }
7428  /* NOTE: assumes that ownership info will already have been set or will be set by the caller */
7429 
7430  return error;
7431 }
7432 
7433 static int
7434 mr_setval_multiset (DB_VALUE * dest, const DB_VALUE * src, bool copy)
7435 {
7436  return mr_setval_set_internal (dest, src, copy, DB_TYPE_MULTISET);
7437 }
7438 
7439 /*
7440  * TYPE SEQUENCE
7441  */
7442 
7443 static void
7444 mr_initval_sequence (DB_VALUE * value, int precision, int scale)
7445 {
7446  db_value_domain_init (value, DB_TYPE_SEQUENCE, precision, scale);
7447  db_make_sequence (value, NULL);
7448 }
7449 
7450 static int
7451 mr_getmem_sequence (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
7452 {
7453  SETOBJ **mem = (SETOBJ **) memptr;
7454  int error = NO_ERROR;
7455  SETOBJ *set;
7456  SETREF *ref;
7457 
7458  set = *mem;
7459  if (set == NULL)
7460  {
7461  error = db_make_sequence (value, NULL);
7462  }
7463  else
7464  {
7465  ref = setobj_get_reference (set);
7466  if (ref)
7467  {
7468  error = db_make_sequence (value, ref);
7469  }
7470  else
7471  {
7472  assert (er_errid () != NO_ERROR);
7473  error = er_errid ();
7474  (void) db_make_sequence (value, NULL);
7475  }
7476  }
7477  /*
7478  * NOTE: assumes that ownership info will already have been set or will
7479  * be set by the caller
7480  */
7481 
7482  return error;
7483 }
7484 
7485 static int
7486 mr_setval_sequence (DB_VALUE * dest, const DB_VALUE * src, bool copy)
7487 {
7488  return mr_setval_set_internal (dest, src, copy, DB_TYPE_SEQUENCE);
7489 }
7490 
7492 mr_data_cmpdisk_sequence (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
7493 {
7495  SETOBJ *seq1 = NULL, *seq2 = NULL;
7496 
7497  assert (domain != NULL);
7498 
7499  /* is not index type */
7500  assert (!domain->is_desc && !tp_valid_indextype (TP_DOMAIN_TYPE (domain)));
7501 
7502  mem1 = or_unpack_set ((char *) mem1, &seq1, domain);
7503  mem2 = or_unpack_set ((char *) mem2, &seq2, domain);
7504 
7505  if (seq1 == NULL || seq2 == NULL)
7506  {
7507  return DB_UNK;
7508  }
7509 
7510  c = setobj_compare_order (seq1, seq2, do_coercion, total_order);
7511 
7512  setobj_free (seq1);
7513  setobj_free (seq2);
7514 
7515  return c;
7516 }
7517 
7519 mr_cmpval_sequence (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
7520  int collation)
7521 {
7522  return set_seq_compare (db_get_set (value1), db_get_set (value2), do_coercion, total_order);
7523 }
7524 
7525 /*
7526  * TYPE MIDXKEY
7527  */
7528 
7529 static void
7530 mr_initval_midxkey (DB_VALUE * value, int precision, int scale)
7531 {
7532  DB_MIDXKEY *midxkey = NULL;
7533  db_value_domain_init (value, DB_TYPE_MIDXKEY, precision, scale);
7534  db_make_midxkey (value, midxkey);
7535 }
7536 
7537 static int
7538 mr_setval_midxkey (DB_VALUE * dest, const DB_VALUE * src, bool copy)
7539 {
7540  int error = NO_ERROR;
7541  int src_precision;
7542 
7543  DB_MIDXKEY dst_idx;
7544  DB_MIDXKEY *src_idx;
7545 
7546  if (DB_IS_NULL (src))
7547  {
7549  }
7550 
7551  /* Get information from the value. */
7552  src_idx = db_get_midxkey (src);
7553  src_precision = db_value_precision (src);
7554  if (src_idx == NULL)
7555  {
7556  return db_value_domain_init (dest, DB_TYPE_MIDXKEY, src_precision, 0);
7557  }
7558 
7559  if (src_idx->size < 0)
7560  {
7561  dst_idx.size = strlen (src_idx->buf);
7562  }
7563  else
7564  {
7565  dst_idx.size = src_idx->size;
7566  }
7567 
7568  dst_idx.ncolumns = src_idx->ncolumns;
7569 
7570  dst_idx.domain = src_idx->domain;
7571 
7572  dst_idx.min_max_val.position = src_idx->min_max_val.position;
7573  dst_idx.min_max_val.type = src_idx->min_max_val.type;
7574 
7575  /* should we be paying attention to this? it is extremely dangerous */
7576  if (!copy)
7577  {
7578  dst_idx.buf = src_idx->buf;
7579 
7580  error = db_make_midxkey (dest, &dst_idx);
7581  dest->need_clear = false;
7582  }
7583  else
7584  {
7585  dst_idx.buf = (char *) db_private_alloc (NULL, dst_idx.size);
7586  if (dst_idx.buf == NULL)
7587  {
7588  db_value_domain_init (dest, DB_TYPE_MIDXKEY, src_precision, 0);
7589 
7590  assert (er_errid () != NO_ERROR);
7591  return er_errid ();
7592  }
7593 
7594  memcpy (dst_idx.buf, src_idx->buf, dst_idx.size);
7595  error = db_make_midxkey (dest, &dst_idx);
7596  dest->need_clear = true;
7597  }
7598 
7599  return error;
7600 }
7601 
7602 static int
7604 {
7605  return mr_index_writeval_midxkey (buf, value);
7606 }
7607 
7608 static int
7610 {
7611  DB_MIDXKEY *midxkey;
7612  int rc;
7613 
7614  midxkey = db_get_midxkey (value);
7615  if (midxkey == NULL)
7616  {
7617  return ER_FAILED;
7618  }
7619 
7620  rc = or_put_data (buf, (char *) midxkey->buf, midxkey->size);
7621 
7622  return rc;
7623 }
7624 
7625 static int
7626 mr_data_readval_midxkey (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
7627  int copy_buf_len)
7628 {
7629  return mr_index_readval_midxkey (buf, value, domain, size, copy, copy_buf, copy_buf_len);
7630 }
7631 
7632 static int
7633 mr_index_readval_midxkey (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
7634  int copy_buf_len)
7635 {
7636  char *new_;
7637  DB_MIDXKEY midxkey;
7638  int rc = NO_ERROR;
7639  TP_DOMAIN *dom;
7640 
7641  if (size == -1)
7642  { /* unknown size */
7643  size = mr_index_lengthmem_midxkey (buf->ptr, domain);
7644  }
7645 
7646  if (size <= 0)
7647  {
7648  assert (false);
7649  return ER_FAILED;
7650  }
7651 
7652  if (value == NULL)
7653  {
7654  return or_advance (buf, size);
7655  }
7656 
7657  midxkey.size = size;
7658  midxkey.ncolumns = 0;
7659  midxkey.domain = domain;
7660  midxkey.min_max_val.position = -1;
7661  midxkey.min_max_val.type = MIN_COLUMN;
7662  midxkey.ncolumns = domain->precision;
7663 
7664  if (!copy)
7665  {
7666  midxkey.buf = buf->ptr;
7667  db_make_midxkey (value, &midxkey);
7668  rc = or_advance (buf, size);
7669  }
7670  else
7671  {
7672  if (copy_buf && copy_buf_len >= size)
7673  {
7674  /* read buf image into the copy_buf */
7675  new_ = copy_buf;
7676  }
7677  else
7678  {
7679  /*
7680  * Allocate storage for the string
7681  * do not include the kludge NULL terminator
7682  */
7683  new_ = (char *) db_private_alloc (NULL, size);
7684  }
7685 
7686  if (new_ == NULL)
7687  {
7688  /* need to be able to return errors ! */
7690  or_abort (buf);
7691  return ER_FAILED;
7692  }
7693  else
7694  {
7695  rc = or_get_data (buf, new_, size);
7696  if (rc == NO_ERROR)
7697  {
7698  /* round up to a word boundary */
7699  /* rc = or_get_align32 (buf); *//* need ?? */
7700  }
7701  if (rc != NO_ERROR)
7702  {
7703  if (new_ != copy_buf)
7704  {
7706  }
7707  return rc;
7708  }
7709  midxkey.buf = new_;
7710  db_make_midxkey (value, &midxkey);
7711  value->need_clear = (new_ != copy_buf) ? true : false;
7712  }
7713  }
7714 
7715  return rc;
7716 }
7717 
7719 pr_midxkey_compare_element (char *mem1, char *mem2, TP_DOMAIN * dom1, TP_DOMAIN * dom2, int do_coercion,
7720  int total_order)
7721 {
7723  DB_VALUE val1, val2;
7724  bool error = false;
7725  OR_BUF buf_val1, buf_val2;
7726  bool comparable = true;
7727 
7728  if (dom1->is_desc != dom2->is_desc)
7729  {
7730  assert (false);
7731  return DB_UNK; /* impossible case */
7732  }
7733 
7734  OR_BUF_INIT (buf_val1, mem1, -1);
7735  OR_BUF_INIT (buf_val2, mem2, -1);
7736 
7737  db_make_null (&val1);
7738  db_make_null (&val2);
7739 
7740  if (dom1->type->index_readval (&buf_val1, &val1, dom1, -1, false, NULL, 0) != NO_ERROR)
7741  {
7742  error = true;
7743  goto clean_up;
7744  }
7745 
7746  if (dom2->type->index_readval (&buf_val2, &val2, dom2, -1, false, NULL, 0) != NO_ERROR)
7747  {
7748  error = true;
7749  goto clean_up;
7750  }
7751 
7752  c = tp_value_compare_with_error (&val1, &val2, do_coercion, total_order, &comparable);
7753 
7754 clean_up:
7755  if (DB_NEED_CLEAR (&val1))
7756  {
7757  pr_clear_value (&val1);
7758  }
7759 
7760  if (DB_NEED_CLEAR (&val2))
7761  {
7762  pr_clear_value (&val2);
7763  }
7764 
7765  if (!comparable || error == true)
7766  {
7767  return DB_UNK;
7768  }
7769 
7770  return c;
7771 }
7772 
7773 
7775 pr_midxkey_compare (DB_MIDXKEY * mul1, DB_MIDXKEY * mul2, int do_coercion, int total_order, int num_index_term,
7776  int *start_colp, int *result_size1, int *result_size2, int *diff_column, bool * dom_is_desc,
7777  bool * next_dom_is_desc)
7778 {
7780  int i;
7781  int adv_size1, adv_size2;
7782  int size1, size2;
7783  TP_DOMAIN *dom1, *dom2;
7784  char *bitptr1, *bitptr2;
7785  char *mem1, *mem2;
7786  int last;
7787 
7788  assert (total_order == 1);
7789  if (total_order == 0)
7790  {
7791  /* unknown case */
7792  return DB_UNK;
7793  }
7794 
7795  assert (mul1->domain != NULL);
7797  assert (mul1->domain->setdomain != NULL);
7798 
7799  assert (mul2->domain != NULL);
7801  assert (mul2->domain->setdomain != NULL);
7802 
7803  assert (mul1->ncolumns == mul2->ncolumns);
7804  assert (mul1->domain->precision == mul2->domain->precision);
7805 
7806  /* safe guard */
7807  if (mul1->domain == NULL || TP_DOMAIN_TYPE (mul1->domain) != DB_TYPE_MIDXKEY || mul1->domain->setdomain == NULL)
7808  {
7810  return DB_UNK;
7811  }
7812 
7813  /* safe guard */
7814  if (mul2->domain == NULL || TP_DOMAIN_TYPE (mul2->domain) != DB_TYPE_MIDXKEY || mul2->domain->setdomain == NULL)
7815  {
7817  return DB_UNK;
7818  }
7819 
7820  /* safe guard */
7821  if (mul1->ncolumns != mul2->ncolumns || mul1->domain->precision != mul2->domain->precision)
7822  {
7823  return DB_UNK;
7824  }
7825 
7826 #if !defined(NDEBUG)
7827  {
7828  int dom_ncols = 0; /* init */
7829 
7830  for (dom1 = mul1->domain->setdomain; dom1; dom1 = dom1->next)
7831  {
7832  dom_ncols++;
7833  }
7834 
7835  if (dom_ncols <= 0)
7836  {
7837  assert (false);
7838  return DB_UNK;
7839  }
7840 
7841  assert (dom_ncols == mul1->domain->precision);
7842  }
7843 #endif /* NDEBUG */
7844 
7845  size1 = size2 = 0;
7846 
7847  mem1 = bitptr1 = mul1->buf;
7848  mem2 = bitptr2 = mul2->buf;
7849 
7850  adv_size1 = OR_MULTI_BOUND_BIT_BYTES (mul1->domain->precision);
7851 
7852  mem1 += adv_size1;
7853  mem2 += adv_size1;
7854  size1 += adv_size1;
7855  size2 += adv_size1;
7856 
7857  dom1 = mul1->domain->setdomain;
7858  dom2 = mul2->domain->setdomain;
7859 
7860  if (num_index_term > 0)
7861  {
7862  last = num_index_term;
7863  }
7864  else
7865  {
7866  last = mul1->ncolumns;
7867  }
7868 
7869  for (i = 0; start_colp && i < *start_colp; i++, dom1 = dom1->next, dom2 = dom2->next)
7870  {
7871  if (dom1 == NULL || dom2 == NULL || dom1->is_desc != dom2->is_desc)
7872  {
7873  assert (false);
7874  return DB_UNK;
7875  }
7876 
7877  if (OR_MULTI_ATT_IS_BOUND (bitptr1, i))
7878  {
7879  adv_size1 = pr_midxkey_element_disk_size (mem1, dom1);
7880  mem1 += adv_size1;
7881  size1 += adv_size1;
7882  }
7883 
7884  if (OR_MULTI_ATT_IS_BOUND (bitptr2, i))
7885  {
7886  adv_size2 = pr_midxkey_element_disk_size (mem2, dom2);
7887  mem2 += adv_size2;
7888  size2 += adv_size2;
7889  }
7890  }
7891 
7892  for (c = DB_EQ; i < last; i++, dom1 = dom1->next, dom2 = dom2->next)
7893  {
7894  if (dom1 == NULL || dom2 == NULL || dom1->is_desc != dom2->is_desc)
7895  {
7896  assert (false);
7897  return DB_UNK;
7898  }
7899 
7900  if (OR_MULTI_ATT_IS_BOUND (bitptr1, i) && OR_MULTI_ATT_IS_BOUND (bitptr2, i))
7901  {
7902  /* check for val1 and val2 same domain */
7903  if (dom1 == dom2 || tp_domain_match (dom1, dom2, TP_EXACT_MATCH))
7904  {
7905  c = dom1->type->index_cmpdisk (mem1, mem2, dom1, do_coercion, total_order, NULL);
7906  }
7907  else
7908  {
7909  /* coercion and comparison
7910  * val1 and val2 have different domain
7911  */
7912  c = pr_midxkey_compare_element (mem1, mem2, dom1, dom2, do_coercion, total_order);
7913  }
7914  }
7915  else
7916  {
7917  if (OR_MULTI_ATT_IS_BOUND (bitptr1, i))
7918  {
7919  /* val 1 bound, val 2 unbound */
7920  if (mul2->min_max_val.position == i)
7921  {
7922  /* safeguard */
7923  assert (mul2->min_max_val.type == MIN_COLUMN || mul2->min_max_val.type == MAX_COLUMN);
7924  if (mul2->min_max_val.type == MIN_COLUMN)
7925  {
7926  c = DB_GT;
7927  }
7928  else
7929  {
7930  c = DB_LT;
7931  }
7932  }
7933  else
7934  {
7935  c = DB_GT;
7936  }
7937  }
7938  else if (OR_MULTI_ATT_IS_BOUND (bitptr2, i))
7939  {
7940  /* val 1 unbound, val 2 bound */
7941  if (mul1->min_max_val.position == i)
7942  {
7943  /* safeguard */
7944  assert (mul1->min_max_val.type == MIN_COLUMN || mul1->min_max_val.type == MAX_COLUMN);
7945  if (mul1->min_max_val.type == MIN_COLUMN)
7946  {
7947  c = DB_LT;
7948  }
7949  else
7950  {
7951  c = DB_GT;
7952  }
7953  }
7954  else
7955  {
7956  c = DB_LT;
7957  }
7958  }
7959  else
7960  {
7961  /* val 1 unbound, val 2 unbound */
7962  /* SPECIAL_COLUMN_MIN > NULL */
7963  if (mul1->min_max_val.position == i)
7964  {
7965  if (mul2->min_max_val.position == i)
7966  {
7967  MIN_MAX_COLUMN_TYPE type1 = mul1->min_max_val.type;
7968  MIN_MAX_COLUMN_TYPE type2 = mul2->min_max_val.type;
7969  if (type1 == type2)
7970  {
7971  c = DB_EQ;
7972  }
7973  else if (type1 == MIN_COLUMN)
7974  {
7975  c = DB_LT;
7976  }
7977  else
7978  {
7979  c = DB_GT;
7980  }
7981  }
7982  else
7983  {
7984  assert (mul1->min_max_val.type == MIN_COLUMN || mul1->min_max_val.type == MAX_COLUMN);
7985  if (mul1->min_max_val.type == MIN_COLUMN)
7986  {
7987  c = DB_LT;
7988  }
7989  else
7990  {
7991  c = DB_GT;
7992  }
7993  }
7994  }
7995  else if (mul2->min_max_val.position == i)
7996  {
7997  assert (mul2->min_max_val.type == MIN_COLUMN || mul2->min_max_val.type == MAX_COLUMN);
7998  if (mul2->min_max_val.type == MIN_COLUMN)
7999  {
8000  c = DB_GT;
8001  }
8002  else
8003  {
8004  c = DB_LT;
8005  }
8006  }
8007  else
8008  {
8009  c = DB_EQ;
8010  }
8011  }
8012  }
8013 
8014  if (c != DB_EQ)
8015  {
8016  break; /* exit for-loop */
8017  }
8018 
8019  if (OR_MULTI_ATT_IS_BOUND (bitptr1, i))
8020  {
8021  adv_size1 = pr_midxkey_element_disk_size (mem1, dom1);
8022  mem1 += adv_size1;
8023  size1 += adv_size1;
8024  }
8025 
8026  if (OR_MULTI_ATT_IS_BOUND (bitptr2, i))
8027  {
8028  adv_size2 = pr_midxkey_element_disk_size (mem2, dom2);
8029  mem2 += adv_size2;
8030  size2 += adv_size2;
8031  }
8032  }
8033 
8034  if (start_colp != NULL)
8035  {
8036  if (c != DB_EQ)
8037  {
8038  /* save the start position of non-equal-value column */
8039  *start_colp = i;
8040  }
8041  }
8042 
8043  if (result_size1 != NULL)
8044  {
8045  adv_size1 = 0;
8046  if (c != DB_EQ)
8047  {
8048  if (dom1 != NULL && OR_MULTI_ATT_IS_BOUND (bitptr1, i))
8049  {
8050  adv_size1 = pr_midxkey_element_disk_size (mem1, dom1);
8051  }
8052  }
8053  *result_size1 = size1 + adv_size1;
8054  }
8055  if (result_size2 != NULL)
8056  {
8057  adv_size2 = 0;
8058  if (c != DB_EQ)
8059  {
8060  if (dom2 != NULL && OR_MULTI_ATT_IS_BOUND (bitptr2, i))
8061  {
8062  adv_size2 = pr_midxkey_element_disk_size (mem2, dom2);
8063  }
8064  }
8065  *result_size2 = size2 + adv_size2;
8066  }
8067 
8068  *diff_column = i;
8069 
8070  *dom_is_desc = *next_dom_is_desc = false;
8071 
8072  if (dom1)
8073  {
8074  if (dom1->is_desc)
8075  {
8076  *dom_is_desc = true;
8077  }
8078 
8079  if (dom1->next && dom1->next->is_desc)
8080  {
8081  *next_dom_is_desc = true;
8082  }
8083  }
8084 
8085  return c;
8086 }
8087 
8089 mr_cmpval_midxkey (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
8090  int collation)
8091 {
8093  DB_MIDXKEY *midxkey1;
8094  DB_MIDXKEY *midxkey2;
8095  int dummy_diff_column;
8096  bool dummy_dom_is_desc, dummy_next_dom_is_desc;
8097 
8098  midxkey1 = db_get_midxkey (value1);
8099  midxkey2 = db_get_midxkey (value2);
8100 
8101  if (midxkey1 == NULL || midxkey2 == NULL)
8102  {
8103  assert_release (false); /* error */
8104  return DB_UNK;
8105  }
8106 
8107  if (midxkey1 == midxkey2)
8108  {
8109  if (total_order)
8110  {
8111  return DB_EQ;
8112  }
8113 
8114  assert_release (false); /* error */
8115  return DB_UNK;
8116  }
8117 
8118  assert_release (midxkey1->domain != NULL);
8119  assert_release (midxkey1->domain->precision == midxkey1->ncolumns);
8120  assert_release (midxkey2->domain != NULL);
8121  assert_release (midxkey2->domain->precision == midxkey2->ncolumns);
8122 
8123  c = (DB_VALUE_COMPARE_RESULT) pr_midxkey_compare (midxkey1, midxkey2, do_coercion, total_order, -1, start_colp,
8124  NULL, NULL, &dummy_diff_column, &dummy_dom_is_desc,
8125  &dummy_next_dom_is_desc);
8126 
8127  assert_release (c == DB_UNK || (DB_LT <= c && c <= DB_GT));
8128 
8129  return c;
8130 }
8131 
8133 mr_data_cmpdisk_midxkey (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
8134 {
8135  assert (false);
8136 
8137  assert (domain != NULL);
8138 
8139  return mr_index_cmpdisk_midxkey (mem1, mem2, domain, do_coercion, total_order, start_colp);
8140 }
8141 
8143 mr_index_cmpdisk_midxkey (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
8144 {
8146  DB_MIDXKEY midxkey1;
8147  DB_MIDXKEY midxkey2;
8148  TP_DOMAIN *cmp_dom;
8149  int n_atts = 0;
8150  int dummy_diff_column;
8151  bool dummy_dom_is_desc = false, dummy_next_dom_is_desc;
8152 
8153  assert (false);
8154 
8155  assert (domain != NULL && !domain->is_desc);
8156 
8157  assert (mem1 != NULL);
8158  assert (mem2 != NULL);
8159 
8160  if (mem1 == NULL || mem2 == NULL)
8161  {
8162  assert (false); /* error */
8163  return DB_UNK;
8164  }
8165 
8166  if (mem1 == mem2)
8167  {
8168  if (total_order)
8169  {
8170  return DB_EQ;
8171  }
8172 
8173  assert (false); /* error */
8174  return DB_UNK;
8175  }
8176 
8177  midxkey1.buf = (char *) mem1;
8178  midxkey2.buf = (char *) mem2;
8179 
8180  n_atts = 0;
8181  for (cmp_dom = domain->setdomain; cmp_dom; cmp_dom = cmp_dom->next)
8182  {
8183  n_atts++;
8184  }
8185 
8186  midxkey1.size = midxkey2.size = -1; /* is dummy */
8187  midxkey1.ncolumns = midxkey2.ncolumns = n_atts;
8188  midxkey1.domain = midxkey2.domain = domain;
8189 
8190  c = pr_midxkey_compare (&midxkey1, &midxkey2, do_coercion, total_order, -1, start_colp, NULL, NULL,
8191  &dummy_diff_column, &dummy_dom_is_desc, &dummy_next_dom_is_desc);
8192  assert (c == DB_UNK || (DB_LT <= c && c <= DB_GT));
8193 
8194  return c;
8195 }
8196 
8197 static int
8198 mr_data_lengthmem_midxkey (void *memptr, TP_DOMAIN * domain, int disk)
8199 {
8200  return mr_index_lengthmem_midxkey (memptr, domain);
8201 }
8202 
8203 static int
8204 mr_index_lengthmem_midxkey (void *memptr, TP_DOMAIN * domain)
8205 {
8206  char *buf, *bitptr;
8207  TP_DOMAIN *dom;
8208  int idx_ncols = 0, i, adv_size;
8209  int len;
8210 
8211  /* There is no difference between the disk & memory sizes. */
8212  buf = (char *) memptr;
8213 
8214  idx_ncols = domain->precision;
8215  if (idx_ncols <= 0)
8216  {
8217  assert (false);
8218  goto exit_on_error; /* give up */
8219  }
8220 
8221 #if !defined (NDEBUG)
8222  {
8223  int dom_ncols = 0;
8224  for (dom = domain->setdomain; dom; dom = dom->next)
8225  {
8226  dom_ncols++;
8227  }
8228 
8229  if (dom_ncols <= 0)
8230  {
8231  assert (false);
8232  goto exit_on_error;
8233  }
8234  assert (dom_ncols == idx_ncols);
8235  }
8236 #endif /* NDEBUG */
8237 
8238  adv_size = OR_MULTI_BOUND_BIT_BYTES (idx_ncols);
8239 
8240  bitptr = buf;
8241  buf += adv_size;
8242  assert (CAST_BUFLEN (buf - bitptr) > 0);
8243 
8244  for (i = 0, dom = domain->setdomain; i < idx_ncols; i++, dom = dom->next)
8245  {
8246  /* check for val is NULL */
8247  if (OR_MULTI_ATT_IS_UNBOUND (bitptr, i))
8248  {
8249  continue; /* zero size; go ahead */
8250  }
8251 
8252  /* at here, val is non-NULL */
8253 
8254  adv_size = pr_midxkey_element_disk_size (buf, dom);
8255  buf += adv_size;
8256  }
8257 
8258  /* set buf size */
8259  len = CAST_BUFLEN (buf - bitptr);
8260 
8261 exit_on_end:
8262 
8263  return len;
8264 
8265 exit_on_error:
8266 
8267  len = -1; /* set error */
8268  goto exit_on_end;
8269 }
8270 
8271 static int
8273 {
8274  return mr_index_lengthval_midxkey (value);
8275 }
8276 
8277 static int
8279 {
8280  int len;
8281 
8282  if (DB_IS_NULL (value))
8283  {
8284  return 0;
8285  }
8286  len = value->data.midxkey.size;
8287 
8288  return len;
8289 }
8290 
8291 /*
8292  * TYPE VOBJ
8293  *
8294  * This is used only for virtual object keys in SQL/M.
8295  * Internal structures identical to sequences.
8296  */
8297 
8298 static void
8299 mr_initval_vobj (DB_VALUE * value, int precision, int scale)
8300 {
8301  db_value_domain_init (value, DB_TYPE_VOBJ, precision, scale);
8302 }
8303 
8304 static int
8305 mr_setval_vobj (DB_VALUE * dest, const DB_VALUE * src, bool copy)
8306 {
8307  int error;
8308 
8309  error = mr_setval_sequence (dest, src, copy);
8311 
8312  return error;
8313 }
8314 
8315 static int
8316 mr_data_readval_vobj (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
8317  int copy_buf_len)
8318 {
8319  if (mr_data_readval_set (buf, value, &tp_Sequence_domain, size, copy, copy_buf, copy_buf_len) != NO_ERROR)
8320  {
8321  return ER_FAILED;
8322  }
8323 
8324  if (value)
8325  {
8327  }
8328  return NO_ERROR;
8329 }
8330 
8332 mr_data_cmpdisk_vobj (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
8333 {
8335  SETOBJ *seq1 = NULL, *seq2 = NULL;
8336 
8337  assert (domain != NULL);
8338 
8339  /* is not index type */
8340  assert (!domain->is_desc && !tp_valid_indextype (TP_DOMAIN_TYPE (domain)));
8341 
8342  mem1 = or_unpack_set ((char *) mem1, &seq1, domain);
8343  mem2 = or_unpack_set ((char *) mem2, &seq2, domain);
8344 
8345  if (seq1 == NULL || seq2 == NULL)
8346  {
8347  return DB_UNK;
8348  }
8349 
8350  c = setvobj_compare (seq1, seq2, do_coercion, total_order);
8351 
8352  setobj_free (seq1);
8353  setobj_free (seq2);
8354 
8355  return c;
8356 }
8357 
8359 mr_cmpval_vobj (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
8360 {
8361  return vobj_compare (db_get_set (value1), db_get_set (value2), do_coercion, total_order);
8362 }
8363 
8364 /*
8365  * TYPE NUMERIC
8366  */
8367 
8368 static void
8369 mr_initmem_numeric (void *memptr, TP_DOMAIN * domain)
8370 {
8371  assert (!IS_FLOATING_PRECISION (domain->precision));
8372 
8373  memset (memptr, 0, MR_NUMERIC_SIZE (domain->precision));
8374 }
8375 
8376 /*
8377  * Due to the "within tolerance" domain comparison used during attribute
8378  * assignment validation, we may receive a numeric whose precision is less
8379  * then the actual precision of the attribute. In that case we should be doing
8380  * an on-the-fly coercion here.
8381  */
8382 static int
8383 mr_setmem_numeric (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
8384 {
8385  int error = NO_ERROR;
8386  int src_precision, src_scale, byte_size;
8387  DB_C_NUMERIC num, src_num;
8388 
8389  if (value == NULL)
8390  {
8391  mr_initmem_numeric (mem, domain);
8392  }
8393  else
8394  {
8395  src_num = db_get_numeric (value);
8396 
8397  src_precision = db_value_precision (value);
8398  src_scale = db_value_scale (value);
8399 
8400  /* this should have been handled by now */
8401  if (src_num == NULL || src_precision != domain->precision || src_scale != domain->scale)
8402  {
8403  error = ER_OBJ_DOMAIN_CONFLICT;
8404  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, "");
8405  }
8406  else
8407  {
8408  num = (DB_C_NUMERIC) mem;
8409  byte_size = MR_NUMERIC_SIZE (src_precision);
8410  memcpy (num, src_num, byte_size);
8411  }
8412  }
8413  return error;
8414 }
8415 
8416 static int
8417 mr_getmem_numeric (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
8418 {
8419  int error = NO_ERROR;
8420  DB_C_NUMERIC num;
8421 
8422  if (value == NULL)
8423  {
8424  return error;
8425  }
8426 
8427  num = (DB_C_NUMERIC) mem;
8428  error = db_make_numeric (value, num, domain->precision, domain->scale);
8429  value->need_clear = false;
8430 
8431  return error;
8432 }
8433 
8434 static void
8435 mr_data_writemem_numeric (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
8436 {
8437  int disk_size;
8438 
8439  disk_size = OR_NUMERIC_SIZE (domain->precision);
8440  or_put_data (buf, (char *) mem, disk_size);
8441 }
8442 
8443 static void
8444 mr_data_readmem_numeric (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
8445 {
8446  /* if stored size is unknown, the domain precision must be set correctly */
8447  if (size < 0)
8448  {
8449  size = OR_NUMERIC_SIZE (domain->precision);
8450  }
8451 
8452  if (mem == NULL)
8453  {
8454  if (size)
8455  {
8456  or_advance (buf, size);
8457  }
8458  }
8459  else if (size)
8460  {
8461  if (size != OR_NUMERIC_SIZE (domain->precision))
8462  {
8464  or_abort (buf);
8465  }
8466  else
8467  {
8468  or_get_data (buf, (char *) mem, size);
8469  }
8470  }
8471 }
8472 
8473 static int
8475 {
8476  return mr_data_lengthmem_numeric (mem, domain, 1);
8477 }
8478 
8479 static int
8480 mr_data_lengthmem_numeric (void *mem, TP_DOMAIN * domain, int disk)
8481 {
8482  int len;
8483 
8484  /* think about caching this in the domain so we don't have to calculate it */
8485  if (disk)
8486  {
8487  len = OR_NUMERIC_SIZE (domain->precision);
8488  }
8489  else
8490  {
8491  len = MR_NUMERIC_SIZE (domain->precision);
8492  }
8493 
8494  return len;
8495 }
8496 
8497 static void
8498 mr_initval_numeric (DB_VALUE * value, int precision, int scale)
8499 {
8500  db_value_domain_init (value, DB_TYPE_NUMERIC, precision, scale);
8501 }
8502 
8503 static int
8504 mr_setval_numeric (DB_VALUE * dest, const DB_VALUE * src, bool copy)
8505 {
8506  int error = NO_ERROR;
8507  int src_precision, src_scale;
8508  DB_C_NUMERIC src_numeric;
8509 
8510  assert (!db_value_is_corrupted (src));
8511  if (src == NULL || DB_IS_NULL (src))
8512  {
8514  }
8515  else
8516  {
8517  src_precision = db_value_precision (src);
8518  src_scale = db_value_scale (src);
8519  src_numeric = (DB_C_NUMERIC) db_get_numeric (src);
8520 
8521  if (DB_IS_NULL (src) || src_numeric == NULL)
8522  {
8523  db_value_domain_init (dest, DB_TYPE_NUMERIC, src_precision, src_scale);
8524  }
8525  else
8526  {
8527  /*
8528  * Because numerics are stored in an inline buffer, there is no
8529  * difference between the copy and non-copy operations, this may
8530  * need to change.
8531  */
8532  error = db_make_numeric (dest, src_numeric, src_precision, src_scale);
8533  }
8534  }
8535  return error;
8536 }
8537 
8538 static int
8540 {
8541  return mr_data_lengthval_numeric (value, 1);
8542 }
8543 
8544 static int
8546 {
8547  int precision, len;
8548 
8549  len = 0;
8550  if (value != NULL)
8551  {
8552  /* better have a non-NULL value by the time writeval is called ! */
8553  precision = db_value_precision (value);
8554  if (disk)
8555  {
8556  len = OR_NUMERIC_SIZE (precision);
8557  }
8558  else
8559  {
8560  len = MR_NUMERIC_SIZE (precision);
8561  }
8562  }
8563  return len;
8564 }
8565 
8566 static int
8568 {
8569  return mr_data_writeval_numeric (buf, value);
8570 }
8571 
8572 static int
8574 {
8575  DB_C_NUMERIC numeric;
8576  int precision, disk_size;
8577  int rc = NO_ERROR;
8578 
8579  if (value != NULL)
8580  {
8581  numeric = db_get_numeric (value);
8582  if (numeric != NULL)
8583  {
8584  precision = db_value_precision (value);
8585  disk_size = OR_NUMERIC_SIZE (precision);
8586  rc = or_put_data (buf, (char *) numeric, disk_size);
8587  }
8588  }
8589  return rc;
8590 }
8591 
8592 static int
8593 mr_index_readval_numeric (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
8594  int copy_buf_len)
8595 {
8596  return mr_data_readval_numeric (buf, value, domain, size, copy, copy_buf, copy_buf_len);
8597 }
8598 
8599 static int
8600 mr_data_readval_numeric (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
8601  int copy_buf_len)
8602 {
8603  int rc = NO_ERROR;
8604 
8605  if (domain == NULL)
8606  {
8607  return ER_FAILED;
8608  }
8609 
8610  /*
8611  * If size is -1, the caller doesn't know the size and we must determine
8612  * it from the domain.
8613  */
8614  if (size == -1)
8615  {
8616  size = OR_NUMERIC_SIZE (domain->precision);
8617  }
8618 
8619  if (size == 1)
8620  {
8621  size = OR_NUMERIC_SIZE (domain->precision);
8622  }
8623 
8624  if (value == NULL)
8625  {
8626  if (size)
8627  {
8628  rc = or_advance (buf, size);
8629  }
8630  }
8631  else
8632  {
8633  /*
8634  * the copy and no copy cases are identical because db_make_numeric
8635  * will copy the bits into its internal buffer.
8636  */
8637  (void) db_make_numeric (value, (DB_C_NUMERIC) buf->ptr, domain->precision, domain->scale);
8638  value->need_clear = false;
8639  rc = or_advance (buf, size);
8640  }
8641 
8642  return rc;
8643 }
8644 
8646 mr_index_cmpdisk_numeric (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
8647 {
8648  assert (domain != NULL);
8649 
8650  return mr_data_cmpdisk_numeric (mem1, mem2, domain, do_coercion, total_order, start_colp);
8651 }
8652 
8654 mr_data_cmpdisk_numeric (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
8655 {
8657  OR_BUF buf;
8658  DB_VALUE value1, value2;
8659  DB_VALUE answer;
8660  int rc = NO_ERROR;
8661 
8662  assert (domain != NULL);
8663 
8664  or_init (&buf, (char *) mem1, 0);
8665  rc = mr_data_readval_numeric (&buf, &value1, domain, -1, 0, NULL, 0);
8666  if (rc != NO_ERROR)
8667  {
8668  return DB_UNK;
8669  }
8670 
8671  or_init (&buf, (char *) mem2, 0);
8672  rc = mr_data_readval_numeric (&buf, &value2, domain, -1, 0, NULL, 0);
8673  if (rc != NO_ERROR)
8674  {
8675  return DB_UNK;
8676  }
8677 
8678  rc = numeric_db_value_compare (&value1, &value2, &answer);
8679  if (rc != NO_ERROR)
8680  {
8681  return DB_UNK;
8682  }
8683 
8684  c = MR_CMP_RETURN_CODE (db_get_int (&answer));
8685 
8686  return c;
8687 }
8688 
8690 mr_cmpval_numeric (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
8691  int collation)
8692 {
8694  DB_VALUE answer;
8695 
8696  if (numeric_db_value_compare (value1, value2, &answer) != NO_ERROR)
8697  {
8698  return DB_UNK;
8699  }
8700 
8701  if (db_get_int (&answer) < 0)
8702  {
8703  c = DB_LT;
8704  }
8705  else
8706  {
8707  if (db_get_int (&answer) > 0)
8708  {
8709  c = DB_GT;
8710  }
8711  else
8712  {
8713  c = DB_EQ;
8714  }
8715  }
8716 
8717  return c;
8718 }
8719 
8720 /*
8721  * PRIMITIVE TYPE SUPPORT ROUTINES
8722  */
8723 
8724 /*
8725  * pr_type_from_id - maps a type identifier such as DB_TYPE_INTEGER into its
8726  * corresponding primitive type descriptor structures.
8727  * return: type descriptor
8728  * id(in): type identifier constant
8729  */
8730 PR_TYPE *
8732 {
8733  PR_TYPE *type = NULL;
8734 
8735  if (id <= DB_TYPE_LAST && id != DB_TYPE_TABLE)
8736  {
8737  type = tp_Type_id_map[(int) id];
8738  }
8739 
8740  return type;
8741 }
8742 
8743 
8744 /*
8745  * pr_type_name - Returns the string type name associated with a type constant.
8746  * return: type name
8747  * id(in): type identifier constant
8748  * Note:
8749  * The string must not be freed after use.
8750  */
8751 const char *
8753 {
8754  const char *name = NULL;
8755  PR_TYPE *type;
8756 
8757  type = pr_type_from_id (id);
8758 
8759  if (type != NULL)
8760  {
8761  name = type->name;
8762  }
8763 
8764  return name;
8765 }
8766 
8767 /*
8768  * pr_is_set_type - Test to see if a type identifier is one of the set types.
8769  * return: non-zero if type is one of the set types
8770  * type(in):
8771  * Note:
8772  * Since there is an unfortunate amount of special processing for
8773  * the set types, this takes care of comparing against all three types.
8774  */
8775 bool
8777 {
8778  return TP_IS_SET_TYPE (type) || type == DB_TYPE_VOBJ;
8779 }
8780 
8781 /*
8782  * pr_is_string_type - Test to see if a type identifier is one of the string
8783  * types.
8784  * return: non-zero if type is one of the string types
8785  * type(in): type to check
8786  */
8787 int
8789 {
8790  int status = 0;
8791 
8792  if (type == DB_TYPE_VARCHAR || type == DB_TYPE_CHAR || type == DB_TYPE_VARNCHAR || type == DB_TYPE_NCHAR
8793  || type == DB_TYPE_VARBIT || type == DB_TYPE_BIT)
8794  {
8795  status = 1;
8796  }
8797 
8798  return status;
8799 }
8800 
8801 /*
8802  * pr_is_prefix_key_type -
8803  * types.
8804  * return:
8805  * type(in): type to check
8806  */
8807 int
8809 {
8810  return (type == DB_TYPE_MIDXKEY || pr_is_string_type (type));
8811 }
8812 
8813 /*
8814  * pr_is_variable_type - determine whether or not a type is fixed or variable
8815  * width on disk.
8816  * return: non-zero if this is a variable width type
8817  * id(in): type id
8818  * Note:
8819  * With the advent of parameterized types like CHAR(n), NUMERIC(p,s) etc.
8820  * this doesn't mean that all values of this type will be the same size,
8821  * it means that for any particular attribute of a class, they will all be
8822  * the same size and the value will be stored in the "fixed" region of the
8823  * disk representation.
8824  */
8825 int
8827 {
8828  PR_TYPE *type;
8829  int is_variable = 0;
8830 
8831  type = pr_type_from_id (id);
8832  if (type != NULL)
8833  {
8834  is_variable = type->variable_p;
8835  }
8836 
8837  return is_variable;
8838 }
8839 
8840 /*
8841  * pr_find_type - Locate a type descriptor given a name.
8842  * return: type structure
8843  * name(in): type name
8844  * Note:
8845  * Called by the schema manager to map a domain name into a primitive
8846  * type.
8847  * This now recognizes some alias names for a few of the types.
8848  * The aliases should be more centrally defined so the parser can
8849  * check for them.
8850  *
8851  */
8852 PR_TYPE *
8853 pr_find_type (const char *name)
8854 {
8855  PR_TYPE *type, *found;
8856  int i;
8857 
8858  if (name == NULL)
8859  {
8860  return NULL;
8861  }
8862 
8863  found = NULL;
8864  for (i = DB_TYPE_FIRST; i <= DB_TYPE_LAST && found == NULL; i++)
8865  {
8866  type = tp_Type_id_map[i];
8867  if (type->name != NULL)
8868  {
8869  if (intl_mbs_casecmp (name, type->name) == 0)
8870  {
8871  found = type;
8872  }
8873  }
8874  }
8875 
8876  /* alias kludge */
8877  if (found == NULL)
8878  {
8879  if (intl_mbs_casecmp (name, "int") == 0)
8880  {
8881  found = tp_Type_integer;
8882  }
8883  else if (intl_mbs_casecmp (name, "multi_set") == 0)
8884  {
8885  found = tp_Type_multiset;
8886  }
8887 
8888  else if (intl_mbs_casecmp (name, "short") == 0)
8889  {
8890  found = tp_Type_short;
8891  }
8892 
8893  else if (intl_mbs_casecmp (name, "string") == 0)
8894  {
8895  found = tp_Type_string;
8896  }
8897  else if (intl_mbs_casecmp (name, "utime") == 0)
8898  {
8899  found = tp_Type_utime;
8900  }
8901 
8902  else if (intl_mbs_casecmp (name, "list") == 0)
8903  {
8904  found = tp_Type_sequence;
8905  }
8906  }
8907 
8908  return found;
8909 }
8910 
8911 /*
8912  * SIZE CALCULATORS
8913  * These operation on the instance memory format of data values.
8914  */
8915 
8916 
8917 /*
8918  * pr_mem_size - Determine the number of bytes required for the memory
8919  * representation of a particular type.
8920  * return: memory size of type
8921  * type(in): PR_TYPE structure
8922  * Note:
8923  * This only determines the size for an attribute value in contiguous
8924  * memory storage for an instance.
8925  * It does not include the size of any reference memory (like strings.
8926  * For strings, it returns the size of the pointer NOT the length
8927  * of the string.
8928  *
8929  */
8930 int
8931 pr_mem_size (const PR_TYPE * type)
8932 {
8933  return type->size;
8934 }
8935 
8936 /*
8937  * DB_VALUE TRANSFORMERS
8938  *
8939  * Used in the storage of class objects.
8940  * Need to fully extend this into the variabe type above so these can
8941  * be used at attribute values as well.
8942  *
8943  * Predicate processor must be able to understand these if we can issue
8944  * queries on these.
8945  *
8946  * This needs to be merged with the partially implemented support
8947  * for tp_Type_variable above.
8948  *
8949  * These functions will be called with a DB_DATA union NOT a pointer to
8950  * the memory representation of an attribute.
8951  */
8952 
8953 
8954 /*
8955  * pr_value_mem_size - Returns the amount of storage necessary to hold the
8956  * contents of a DB_VALUE.
8957  * return: byte size used by contents of DB_VALUE
8958  * value(in): value to examine
8959  * Note:
8960  * Does not include the amount of space necessary for the DB_VALUE.
8961  * Used by some statistics modules that calculate memory sizes of structures.
8962  */
8963 int
8965 {
8966  PR_TYPE *type;
8967  DB_TYPE dbval_type;
8968 
8969  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
8970  type = pr_type_from_id (dbval_type);
8971  assert (type != NULL);
8972  if (type != NULL)
8973  {
8974  return type->get_mem_size_of_value (value);
8975  }
8976  else
8977  {
8978  return 0;
8979  }
8980 }
8981 
8982 /*
8983  * pr_midxkey_element_disk_size - returns the number of bytes that will be
8984  * written by the "index_write" type function for this memory buffer.
8985  * return: byte size of disk representation
8986  * mem(in): memory buffer
8987  * domain(in): type domain
8988  */
8989 int
8991 {
8992  /*
8993  * variable types except VARCHAR, VARNCHAR, and VARBIT
8994  * cannot be a member of midxkey
8995  */
8996  assert (!(domain->type->variable_p && !QSTR_IS_VARIABLE_LENGTH (TP_DOMAIN_TYPE (domain))));
8997 
8998  return domain->type->get_index_size_of_mem (mem, domain);
8999 }
9000 
9001 /*
9002  * pr_midxkey_get_vals_size() -
9003  * return: int
9004  * domains(in) :
9005  * dbvals(in) :
9006  * total(in) :
9007  *
9008  */
9009 
9010 static int
9011 pr_midxkey_get_vals_size (TP_DOMAIN * domains, DB_VALUE * dbvals, int total)
9012 {
9013  TP_DOMAIN *dom;
9014  int i;
9015 
9016  for (dom = domains, i = 0; dom; dom = dom->next, i++)
9017  {
9018  if (DB_IS_NULL (&dbvals[i]))
9019  {
9020  continue;
9021  }
9022 
9023  total += pr_index_writeval_disk_size (&dbvals[i]);
9024  }
9025 
9026  return total;
9027 }
9028 
9029 
9030 /*
9031  * pr_midxkey_get_element_offset - Returns element offset of midxkey
9032  * return:
9033  * midxkey(in):
9034  * index(in):
9035  */
9036 int
9038 {
9039  int idx_ncols = 0, i;
9040  int advance_size;
9041  int error = NO_ERROR;
9042 
9043  TP_DOMAIN *domain;
9044 
9045  OR_BUF buf_space;
9046  OR_BUF *buf;
9047  char *bitptr;
9048 
9049  idx_ncols = midxkey->domain->precision;
9050  if (idx_ncols <= 0)
9051  {
9052  assert (false);
9053  goto exit_on_error;
9054  }
9055 
9056  if (index >= midxkey->ncolumns)
9057  {
9058  assert (false);
9059  goto exit_on_error;
9060  }
9061 
9062  /* get bit-mask */
9063  bitptr = midxkey->buf;
9064  /* get domain list, attr number */
9065  domain = midxkey->domain->setdomain; /* first element's domain */
9066 
9067  buf = &buf_space;
9068  or_init (buf, midxkey->buf, midxkey->size);
9069 
9070  advance_size = OR_MULTI_BOUND_BIT_BYTES (idx_ncols);
9071  if (or_advance (buf, advance_size) != NO_ERROR)
9072  {
9073  goto exit_on_error;
9074  }
9075 
9076  for (i = 0; i < index; i++, domain = domain->next)
9077  {
9078  /* check for element is NULL */
9079  if (OR_MULTI_ATT_IS_UNBOUND (bitptr, i))
9080  {
9081  continue; /* skip and go ahead */
9082  }
9083 
9084  advance_size = pr_midxkey_element_disk_size (buf->ptr, domain);
9085  or_advance (buf, advance_size);
9086  }
9087 
9088  if (error != NO_ERROR)
9089  {
9090  goto exit_on_error;
9091  }
9092 
9093  return CAST_BUFLEN (buf->ptr - buf->buffer);
9094 
9095 exit_on_error:
9096 
9097  assert (false);
9098  return -1;
9099 }
9100 
9101 /*
9102  * pr_midxkey_add_prefix -
9103  *
9104  * return:
9105  * prefix(in):
9106  * postfix(in):
9107  * result(out):
9108  * n_prefix(in):
9109  */
9110 int
9111 pr_midxkey_add_prefix (DB_VALUE * result, DB_VALUE * prefix, DB_VALUE * postfix, int n_prefix)
9112 {
9113  int i, offset_postfix, offset_prefix;
9114  DB_MIDXKEY *midx_postfix, *midx_prefix;
9115  DB_MIDXKEY midx_result;
9116 
9117  assert (DB_VALUE_TYPE (prefix) == DB_TYPE_MIDXKEY);
9118  assert (DB_VALUE_TYPE (postfix) == DB_TYPE_MIDXKEY);
9119 
9120  midx_prefix = db_get_midxkey (prefix);
9121  midx_postfix = db_get_midxkey (postfix);
9122 
9123  offset_prefix = pr_midxkey_get_element_offset (midx_prefix, n_prefix);
9124  offset_postfix = pr_midxkey_get_element_offset (midx_postfix, n_prefix);
9125 
9126  midx_result.size = offset_prefix + (midx_postfix->size - offset_postfix);
9127  midx_result.buf = (char *) db_private_alloc (NULL, midx_result.size);
9128  midx_result.domain = midx_postfix->domain;
9129  midx_result.ncolumns = midx_postfix->ncolumns;
9130 
9131  memcpy (midx_result.buf, midx_prefix->buf, offset_prefix);
9132 
9133 #if !defined(NDEBUG)
9134  for (i = 0; i < n_prefix; i++)
9135  {
9136  assert (!OR_MULTI_ATT_IS_BOUND (midx_postfix->buf, i));
9137  }
9138 #endif
9139 
9140  for (i = n_prefix; i < midx_result.ncolumns; i++)
9141  {
9142  if (OR_MULTI_ATT_IS_BOUND (midx_postfix->buf, i))
9143  {
9144  OR_MULTI_ENABLE_BOUND_BIT (midx_result.buf, i);
9145  }
9146  else
9147  {
9148  OR_MULTI_CLEAR_BOUND_BIT (midx_result.buf, i);
9149  }
9150  }
9151 
9152  memcpy (midx_result.buf + offset_prefix, midx_postfix->buf + offset_postfix, midx_postfix->size - offset_postfix);
9153 
9154  midx_result.min_max_val.position = -1;
9155  midx_result.min_max_val.type = MIN_COLUMN;
9156  db_make_midxkey (result, &midx_result);
9157  result->need_clear = true;
9158 
9159  return NO_ERROR;
9160 }
9161 
9162 /*
9163  * pr_midxkey_remove_prefix -
9164  *
9165  * return:
9166  * key(in):
9167  * prefix(in):
9168  */
9169 int
9171 {
9172  DB_MIDXKEY *midx_key;
9173  int i, start, offset;
9174 
9175  midx_key = db_get_midxkey (key);
9176 
9177  start = pr_midxkey_get_element_offset (midx_key, 0);
9178  offset = pr_midxkey_get_element_offset (midx_key, prefix);
9179 
9180  memmove (midx_key->buf + start, midx_key->buf + offset, midx_key->size - offset);
9181 
9182  for (i = 0; i < prefix; i++)
9183  {
9184  OR_MULTI_CLEAR_BOUND_BIT (midx_key->buf, i);
9185  }
9186 
9187  midx_key->size = midx_key->size - offset + start;
9188 
9189  return NO_ERROR;
9190 }
9191 
9192 /*
9193  * pr_midxkey_common_prefix -
9194  *
9195  * return:
9196  * key1(in):
9197  * key2(in):
9198  */
9199 int
9201 {
9202  int diff_column, ret;
9203  bool dom_is_desc = false, next_dom_is_desc = false;
9204  DB_MIDXKEY *midx_lf_key, *midx_uf_key;
9205 
9206  assert (DB_VALUE_TYPE (key1) == DB_TYPE_MIDXKEY);
9207  assert (DB_VALUE_TYPE (key2) == DB_TYPE_MIDXKEY);
9208 
9209  diff_column = 0; /* init */
9210 
9211  midx_lf_key = db_get_midxkey (key1);
9212  midx_uf_key = db_get_midxkey (key2);
9213 
9214  ret = pr_midxkey_compare (midx_lf_key, midx_uf_key, 0, 1, -1, NULL, NULL, NULL, &diff_column, &dom_is_desc,
9215  &next_dom_is_desc);
9216 
9217  if (ret == DB_UNK)
9218  {
9219  assert (false);
9220  diff_column = 0;
9221  }
9222 
9223  return diff_column;
9224 }
9225 
9226 /*
9227  * pr_midxkey_get_element_internal()
9228  * return:
9229  * midxkey(in) :
9230  * index(in) :
9231  * value(in) :
9232  * copy(in) :
9233  * prev_indexp(in) :
9234  * prev_ptrp(in) :
9235  */
9236 
9237 static int
9238 pr_midxkey_get_element_internal (const DB_MIDXKEY * midxkey, int index, DB_VALUE * value, bool copy, int *prev_indexp,
9239  char **prev_ptrp)
9240 {
9241  int idx_ncols = 0, i;
9242  int advance_size;
9243  int error = NO_ERROR;
9244 
9245  TP_DOMAIN *domain;
9246 
9247  OR_BUF buf_space;
9248  OR_BUF *buf;
9249  char *bitptr;
9250 
9251  idx_ncols = midxkey->domain->precision;
9252  if (idx_ncols <= 0)
9253  {
9254  assert (false);
9255  goto exit_on_error;
9256  }
9257 
9258  if (index >= midxkey->ncolumns)
9259  {
9260  assert (false);
9261  goto exit_on_error;
9262  }
9263 
9264 #if !defined (NDEBUG)
9265  {
9266  int dom_ncols = 0;
9267 
9268  for (domain = midxkey->domain->setdomain; domain; domain = domain->next)
9269  {
9270  dom_ncols++;
9271  }
9272 
9273  if (dom_ncols <= 0)
9274  {
9275  assert (false);
9276  goto exit_on_error;
9277  }
9278  assert (dom_ncols == idx_ncols);
9279  }
9280 #endif /* NDEBUG */
9281 
9282  /* get bit-mask */
9283  bitptr = midxkey->buf;
9284  /* get domain list, attr number */
9285  domain = midxkey->domain->setdomain; /* first element's domain */
9286 
9287  if (OR_MULTI_ATT_IS_UNBOUND (bitptr, index))
9288  {
9289  db_make_null (value);
9290  }
9291  else
9292  {
9293  buf = NULL; /* init */
9294  i = 0; /* init */
9295 
9296  /* 1st phase: check for prev info */
9297  if (prev_indexp && prev_ptrp)
9298  {
9299  int j, offset;
9300 
9301  j = *prev_indexp;
9302  offset = CAST_BUFLEN (*prev_ptrp - midxkey->buf);
9303  if (j <= 0 || j > index || offset <= 0)
9304  { /* invalid info */
9305  /* nop */
9306  }
9307  else
9308  {
9309  buf = &buf_space;
9310  or_init (buf, *prev_ptrp, midxkey->size - offset);
9311 
9312  /* consume prev domain */
9313  for (; i < j; i++)
9314  {
9315  domain = domain->next;
9316  }
9317  }
9318  }
9319 
9320  /* 2nd phase: need to set buf info */
9321  if (buf == NULL)
9322  {
9323  buf = &buf_space;
9324  or_init (buf, midxkey->buf, midxkey->size);
9325 
9326  advance_size = OR_MULTI_BOUND_BIT_BYTES (idx_ncols);
9327  if (or_advance (buf, advance_size) != NO_ERROR)
9328  {
9329  goto exit_on_error;
9330  }
9331  }
9332 
9333  for (; i < index; i++, domain = domain->next)
9334  {
9335  /* check for element is NULL */
9336  if (OR_MULTI_ATT_IS_UNBOUND (bitptr, i))
9337  {
9338  continue; /* skip and go ahead */
9339  }
9340 
9341  advance_size = pr_midxkey_element_disk_size (buf->ptr, domain);
9342  or_advance (buf, advance_size);
9343  }
9344 
9345  error = domain->type->index_readval (buf, value, domain, -1, copy, NULL, 0);
9346  if (error != NO_ERROR)
9347  {
9348  goto exit_on_error;
9349  }
9350 
9351  /* save the next index info */
9352  if (prev_indexp && prev_ptrp)
9353  {
9354  *prev_indexp = index + 1;
9355  *prev_ptrp = buf->ptr;
9356  }
9357  }
9358 
9359 exit_on_end:
9360 
9361  return error;
9362 
9363 exit_on_error:
9364 
9365  if (error == NO_ERROR)
9366  {
9367  error = -1; /* set error */
9368  }
9369 
9370  goto exit_on_end;
9371 }
9372 
9373 /*
9374  * pr_midxkey_unique_prefix () -
9375  * return: NO_ERROR or error code.
9376  *
9377  * db_midxkey1(in) : Left side of compare.
9378  * db_midxkey2(in) : Right side of compare.
9379  * db_result(out) : midxkey such that > midxkey1, and <= midxkey2.
9380  * or < midxkey1, and >= midxkey2 (desc)
9381  *
9382  * Note:
9383  *
9384  */
9385 int
9386 pr_midxkey_unique_prefix (const DB_VALUE * db_midxkey1, const DB_VALUE * db_midxkey2, DB_VALUE * db_result)
9387 {
9388  int c = DB_UNK;
9389  int i;
9390  int size1, size2, diff_column;
9391  int result_size = 0;
9392  char *result_buf;
9393  DB_MIDXKEY *midxkey1, *midxkey2;
9394  DB_MIDXKEY result_midxkey;
9395  bool dom_is_desc = false, next_dom_is_desc = false;
9396 
9397  /* Assertions */
9398  assert (db_midxkey1 != (DB_VALUE *) NULL);
9399  assert (db_midxkey2 != (DB_VALUE *) NULL);
9400  assert (db_result != (DB_VALUE *) NULL);
9401 
9402  midxkey1 = db_get_midxkey (db_midxkey1);
9403  midxkey2 = db_get_midxkey (db_midxkey2);
9404 
9405  assert (midxkey1->size != -1);
9406  assert (midxkey2->size != -1);
9407  assert (midxkey1->ncolumns == midxkey2->ncolumns);
9408  assert (midxkey1->domain == midxkey2->domain);
9409  assert (midxkey1->domain->setdomain == midxkey2->domain->setdomain);
9410 
9411  c = pr_midxkey_compare (midxkey1, midxkey2, 0, 1, -1, NULL, &size1, &size2, &diff_column, &dom_is_desc,
9412  &next_dom_is_desc);
9413  if (dom_is_desc)
9414  {
9415  c = ((c == DB_GT) ? DB_LT : (c == DB_LT) ? DB_GT : c);
9416  }
9417 
9418  assert (c == DB_LT);
9419  if (c != DB_LT)
9420  {
9421  return (er_errid () == NO_ERROR) ? ER_FAILED : er_errid ();
9422  }
9423 
9424  if (size1 == midxkey1->size || size2 == midxkey2->size
9425  || OR_MULTI_ATT_IS_UNBOUND (midxkey1->buf, diff_column + 1)
9426  || OR_MULTI_ATT_IS_UNBOUND (midxkey2->buf, diff_column + 1))
9427  {
9428  /* not found separator: give up */
9429  pr_clone_value (db_midxkey2, db_result);
9430  }
9431  else
9432  {
9433  assert (size1 < midxkey1->size);
9434  assert (size2 < midxkey2->size);
9435 
9436  if (!next_dom_is_desc)
9437  {
9438  result_buf = midxkey2->buf;
9439  result_size = size2;
9440  }
9441  else
9442  {
9443  result_buf = midxkey1->buf;
9444  result_size = size1;
9445  }
9446 
9447  result_midxkey.buf = (char *) db_private_alloc (NULL, result_size);
9448  if (result_midxkey.buf == NULL)
9449  {
9450  /* will already be set by memory mgr */
9451  assert (er_errid () != NO_ERROR);
9452  return er_errid ();
9453  }
9454 
9455  (void) memcpy (result_midxkey.buf, result_buf, result_size);
9456  result_midxkey.size = result_size;
9457  result_midxkey.domain = midxkey2->domain;
9458  result_midxkey.ncolumns = midxkey2->ncolumns;
9459  for (i = diff_column + 1; i < result_midxkey.ncolumns; i++)
9460  {
9461  OR_MULTI_CLEAR_BOUND_BIT (result_midxkey.buf, i);
9462  }
9463 
9464  result_midxkey.min_max_val.position = -1;
9465  result_midxkey.min_max_val.type = MIN_COLUMN;
9466  db_make_midxkey (db_result, &result_midxkey);
9467 
9468  db_result->need_clear = true;
9469 
9470 #if !defined(NDEBUG)
9471  /* midxkey1 < result_midxkey */
9472  c = pr_midxkey_compare (midxkey1, &result_midxkey, 0, 1, -1, NULL, &size1, &size2, &diff_column, &dom_is_desc,
9473  &next_dom_is_desc);
9474  assert (c == DB_UNK || (DB_LT <= c && c <= DB_GT));
9475  if (dom_is_desc)
9476  {
9477  c = ((c == DB_GT) ? DB_LT : (c == DB_LT) ? DB_GT : c);
9478  }
9479  assert (c == DB_LT);
9480 
9481  /* result_midxkey <= midxkey2 */
9482  c = pr_midxkey_compare (&result_midxkey, midxkey2, 0, 1, -1, NULL, &size1, &size2, &diff_column, &dom_is_desc,
9483  &next_dom_is_desc);
9484  assert (c == DB_UNK || (DB_LT <= c && c <= DB_GT));
9485  if (dom_is_desc)
9486  {
9487  c = ((c == DB_GT) ? DB_LT : (c == DB_LT) ? DB_GT : c);
9488  }
9489 
9490  assert (c == DB_LT || c == DB_EQ);
9491 #endif
9492  }
9493 
9494  return NO_ERROR;
9495 }
9496 
9497 /*
9498  * pr_midxkey_get_element_nocopy() -
9499  * return: error code
9500  * midxkey(in) :
9501  * index(in) :
9502  * value(in) :
9503  * prev_indexp(in) :
9504  * prev_ptrp(in) :
9505  */
9506 
9507 int
9508 pr_midxkey_get_element_nocopy (const DB_MIDXKEY * midxkey, int index, DB_VALUE * value, int *prev_indexp,
9509  char **prev_ptrp)
9510 {
9511  return pr_midxkey_get_element_internal (midxkey, index, value, false /* not copy */ ,
9512  prev_indexp, prev_ptrp);
9513 }
9514 
9515 /*
9516  * pr_midxkey_init_boundbits() -
9517  * return: int
9518  * bufptr(in) :
9519  * n_atts(in) :
9520  *
9521  */
9522 
9523 int
9524 pr_midxkey_init_boundbits (char *bufptr, int n_atts)
9525 {
9526  unsigned char *bits;
9527  int i, nbytes;
9528 
9529  nbytes = OR_MULTI_BOUND_BIT_BYTES (n_atts);
9530  bits = (unsigned char *) bufptr;
9531 
9532  for (i = 0; i < nbytes; i++)
9533  {
9534  bits[i] = (unsigned char) 0;
9535  }
9536 
9537  return nbytes;
9538 }
9539 
9540 /*
9541  * pr_midxkey_add_elements() -
9542  * return:
9543  * keyval(in) :
9544  * dbvals(in) :
9545  * num_dbvals(in) :
9546  * dbvals_domain_list(in) :
9547  * domain(in) :
9548  */
9549 
9550 int
9551 pr_midxkey_add_elements (DB_VALUE * keyval, DB_VALUE * dbvals, int num_dbvals, struct tp_domain *dbvals_domain_list)
9552 {
9553  int i;
9554  TP_DOMAIN *dom;
9555  DB_MIDXKEY *midxkey;
9556  int total_size = 0;
9557  int bitmap_size = 0;
9558  char *new_IDXbuf;
9559  char *bound_bits;
9560  OR_BUF buf;
9561 
9562  /* phase 1: find old */
9563  midxkey = db_get_midxkey (keyval);
9564  if (midxkey == NULL)
9565  {
9566  return ER_FAILED;
9567  }
9568 
9569  if (midxkey->ncolumns > 0 && midxkey->size > 0)
9570  {
9571  /* bitmap is always fully sized */
9572  bitmap_size = OR_MULTI_BOUND_BIT_BYTES (midxkey->ncolumns);
9573  total_size = midxkey->size;
9574  }
9575  else
9576  {
9577  bitmap_size = OR_MULTI_BOUND_BIT_BYTES (num_dbvals);
9578  total_size = bitmap_size;
9579  }
9580 
9581  /* phase 2: calculate how many bytes need */
9582  total_size = pr_midxkey_get_vals_size (dbvals_domain_list, dbvals, total_size);
9583 
9584  /* phase 3: initialize new_IDXbuf */
9585  new_IDXbuf = (char *) db_private_alloc (NULL, total_size);
9586  if (new_IDXbuf == NULL)
9587  {
9588  goto error;
9589  }
9590 
9591  or_init (&buf, new_IDXbuf, -1);
9592  bound_bits = buf.ptr;
9593 
9594  /* phase 4: copy new_IDXbuf from old */
9595  if (midxkey->ncolumns > 0 && midxkey->size > 0)
9596  {
9597  or_put_data (&buf, midxkey->buf, midxkey->size);
9598  }
9599  else
9600  {
9601  /* bound bits */
9602  (void) pr_midxkey_init_boundbits (bound_bits, bitmap_size);
9603  or_advance (&buf, bitmap_size);
9604  }
9605 
9606  for (i = 0, dom = dbvals_domain_list; i < num_dbvals; i++, dom = dom->next)
9607  {
9608  /* check for added val is NULL */
9609  if (DB_IS_NULL (&dbvals[i]))
9610  {
9611  continue; /* skip and go ahead */
9612  }
9613 
9614  dom->type->index_writeval (&buf, &dbvals[i]);
9615 
9616  OR_ENABLE_BOUND_BIT (bound_bits, midxkey->ncolumns + i);
9617  } /* for (i = 0, ...) */
9618 
9619  assert (total_size == CAST_BUFLEN (buf.ptr - buf.buffer));
9620 
9621  /* phase 5: make new multiIDX */
9622  if (midxkey->size > 0)
9623  {
9624  db_private_free_and_init (NULL, midxkey->buf);
9625  midxkey->buf = NULL;
9626  }
9627 
9628  midxkey->buf = buf.buffer;
9629  midxkey->size = CAST_BUFLEN (buf.ptr - buf.buffer);
9630  midxkey->ncolumns += num_dbvals;
9631 
9632  return NO_ERROR;
9633 
9634 error:
9635 
9636  if (midxkey->buf)
9637  {
9638  db_private_free_and_init (NULL, midxkey->buf);
9639  midxkey->buf = NULL;
9640  }
9641  return ER_FAILED;
9642 }
9643 
9644 /*
9645  * pr_data_writeval_disk_size - returns the number of bytes that will be
9646  * written by the "writeval" type function for this value.
9647  * return: byte size of disk representation
9648  * value(in): db value
9649  * Note:
9650  * It is generally used prior to writing the value to pre-calculate the
9651  * required size.
9652  * Formerly called pr_value_disk_size.
9653  *
9654  * Note that "writeval" is used for the construction of disk objects,
9655  * and it will leave space for fixed width types that are logically
9656  * NULL. If you need a compressed representation for random values,
9657  * look at the or_put_value family of functions.
9658  */
9659 int
9661 {
9662  PR_TYPE *type;
9663  DB_TYPE dbval_type;
9664 
9665  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
9666  type = pr_type_from_id (dbval_type);
9667 
9668  assert (type != NULL);
9669 
9670  if (type)
9671  {
9672  return type->get_disk_size_of_value (value);
9673  }
9674 
9675  return 0;
9676 }
9677 
9678 /*
9679  * pr_index_writeval_disk_size - returns the number of bytes that will be
9680  * written by the "index_write" type function for this value.
9681  * return: byte size of disk representation
9682  * value(in): db value
9683  * Note:
9684  */
9685 int
9687 {
9688  PR_TYPE *type;
9689  DB_TYPE dbval_type;
9690 
9691  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
9692  type = pr_type_from_id (dbval_type);
9693 
9694  assert (type != NULL);
9695 
9696  if (type)
9697  {
9698  return type->get_index_size_of_value (value);
9699  }
9700 
9701  return 0;
9702 }
9703 
9704 void
9705 pr_data_writeval (struct or_buf *buf, DB_VALUE * value)
9706 {
9707  PR_TYPE *type;
9708  DB_TYPE dbval_type;
9709 
9710  dbval_type = DB_VALUE_DOMAIN_TYPE (value);
9711  type = pr_type_from_id (dbval_type);
9712  if (type == NULL)
9713  {
9714  type = tp_Type_null; /* handle strange arguments with NULL */
9715  }
9716  type->data_writeval (buf, value);
9717 }
9718 
9719 /*
9720  * MISCELLANEOUS TYPE-RELATED HELPER FUNCTIONS
9721  */
9722 
9723 /*
9724  * pr_valstring - Take the value and formats it using the sptrfunc member of
9725  * the pr_type vector for the appropriate type.
9726  * return: a freshly db_private_realloc()'ed string with a printed rep of "val" in it
9727  * val(in): some DB_VALUE
9728  * Note:
9729  * The caller is responsible for eventually freeing the memory using db_private_free()
9730  *
9731  * This is really just a debugging helper; it probably doesn't do enough
9732  * serious formatting for external use. Use it to get printed DB_VALUE
9733  * representations into error messages and the like.
9734  */
9735 char *
9736 pr_valstring (const DB_VALUE * val)
9737 {
9738  const size_t BUFFER_SIZE = 1024;
9740 
9741  if (val == NULL || DB_IS_NULL (val))
9742  {
9743  /* space with terminating NULL */
9744  sb ("(null)");
9745  }
9746  else
9747  {
9748  db_sprint_value (val, sb);
9749  }
9750 
9751  return sb.release_ptr (); //caller should use db_private_free() to deallocate it
9752 }
9753 
9754 /*
9755  * pr_complete_enum_value - Sets both index and string of a enum value in case
9756  * one of them is missing.
9757  * return: NO_ERROR or error code.
9758  * value(in/out): enumeration value.
9759  * domain(in): enumeration domain against which the value is checked.
9760  */
9761 int
9762 pr_complete_enum_value (DB_VALUE * value, struct tp_domain *domain)
9763 {
9764  unsigned short short_val;
9765  const char *str_val;
9766  int enum_count, str_val_size, idx;
9767  DB_ENUM_ELEMENT *db_elem = 0;
9768 
9769  if (value == NULL || domain == NULL || DB_IS_NULL (value))
9770  {
9771  return NO_ERROR;
9772  }
9773 
9774  if (value->domain.general_info.type != DB_TYPE_ENUMERATION || domain->type->id != DB_TYPE_ENUMERATION)
9775  {
9776  return ER_FAILED;
9777  }
9778 
9779  short_val = db_get_enum_short (value);
9780  str_val = db_get_enum_string (value);
9781  str_val_size = db_get_enum_string_size (value);
9782  enum_count = DOM_GET_ENUM_ELEMS_COUNT (domain);
9783  if (short_val > enum_count)
9784  {
9785  return ER_FAILED;
9786  }
9787 
9788  if (short_val > 0)
9789  {
9790  db_elem = &DOM_GET_ENUM_ELEM (domain, short_val);
9791  if (str_val != NULL && DB_GET_ENUM_ELEM_STRING_SIZE (db_elem) == str_val_size
9792  && !memcmp (str_val, DB_GET_ENUM_ELEM_STRING (db_elem), str_val_size))
9793  {
9794  db_make_enumeration (value, short_val, str_val, str_val_size, DB_GET_ENUM_ELEM_CODESET (db_elem),
9795  db_get_enum_collation (value));
9796  return NO_ERROR;
9797  }
9798  pr_clear_value (value);
9799 
9800  str_val_size = DB_GET_ENUM_ELEM_STRING_SIZE (db_elem);
9801  char *str_val_tmp = (char *) db_private_alloc (NULL, str_val_size + 1);
9802  if (str_val_tmp == NULL)
9803  {
9804  return ER_OUT_OF_VIRTUAL_MEMORY;
9805  }
9806  memcpy (str_val_tmp, DB_GET_ENUM_ELEM_STRING (db_elem), str_val_size);
9807  str_val_tmp[str_val_size] = 0;
9808  str_val = str_val_tmp;
9809 
9810  db_make_enumeration (value, short_val, str_val, str_val_size, DB_GET_ENUM_ELEM_CODESET (db_elem),
9811  db_get_enum_collation (value));
9812  value->need_clear = true;
9813 
9814  return NO_ERROR;
9815  }
9816  else if (str_val == NULL)
9817  {
9818  /* empty string enum value with index 0 */
9819  return NO_ERROR;
9820  }
9821 
9822  for (idx = 0; idx < enum_count; idx++)
9823  {
9824  db_elem = &DOM_GET_ENUM_ELEM (domain, idx + 1);
9825  if (DB_GET_ENUM_ELEM_STRING_SIZE (db_elem) == str_val_size
9826  && !memcmp (DB_GET_ENUM_ELEM_STRING (db_elem), str_val, str_val_size))
9827  {
9828  db_make_enumeration (value, DB_GET_ENUM_ELEM_SHORT (db_elem), str_val, str_val_size,
9829  DB_GET_ENUM_ELEM_CODESET (db_elem), db_get_enum_collation (value));
9830  break;
9831  }
9832  }
9833 
9834  return NO_ERROR;
9835 }
9836 
9837 /*
9838  * TYPE RESULTSET
9839  */
9840 
9841 static void
9842 mr_initmem_resultset (void *mem, TP_DOMAIN * domain)
9843 {
9844  *(int *) mem = 0;
9845 }
9846 
9847 static int
9848 mr_setmem_resultset (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
9849 {
9850  if (value != NULL)
9851  {
9852  *(int *) mem = db_get_resultset (value);
9853  }
9854  else
9855  {
9856  mr_initmem_resultset (mem, domain);
9857  }
9858 
9859  return NO_ERROR;
9860 }
9861 
9862 static int
9863 mr_getmem_resultset (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
9864 {
9865  return db_make_resultset (value, *(int *) mem);
9866 }
9867 
9868 static void
9869 mr_data_writemem_resultset (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
9870 {
9871  or_put_int (buf, *(int *) mem);
9872 }
9873 
9874 static void
9875 mr_data_readmem_resultset (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
9876 {
9877  int rc = NO_ERROR;
9878 
9879  if (mem == NULL)
9880  {
9881  or_advance (buf, tp_ResultSet.disksize);
9882  }
9883  else
9884  {
9885  *(int *) mem = or_get_int (buf, &rc);
9886  }
9887 }
9888 
9889 static void
9890 mr_initval_resultset (DB_VALUE * value, int precision, int scale)
9891 {
9892  db_value_domain_init (value, DB_TYPE_RESULTSET, precision, scale);
9893  db_make_resultset (value, 0);
9894 }
9895 
9896 static int
9897 mr_setval_resultset (DB_VALUE * dest, const DB_VALUE * src, bool copy)
9898 {
9899  if (src && !DB_IS_NULL (src))
9900  {
9901  return db_make_resultset (dest, db_get_resultset (src));
9902  }
9903  else
9904  {
9906  }
9907 }
9908 
9909 static int
9911 {
9912  return or_put_int (buf, db_get_resultset (value));
9913 }
9914 
9915 static int
9916 mr_data_readval_resultset (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
9917  int copy_buf_len)
9918 {
9919  int temp_int, rc = NO_ERROR;
9920 
9921  if (value == NULL)
9922  {
9923  rc = or_advance (buf, tp_ResultSet.disksize);
9924  }
9925  else
9926  {
9927  temp_int = or_get_int (buf, &rc);
9928  db_make_resultset (value, temp_int);
9929  value->need_clear = false;
9930  }
9931  return rc;
9932 }
9933 
9935 mr_data_cmpdisk_resultset (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
9936  int *start_colp)
9937 {
9938  int i1, i2;
9939 
9940  assert (domain != NULL);
9941 
9942  /* is not index type */
9943  assert (!domain->is_desc && !tp_valid_indextype (TP_DOMAIN_TYPE (domain)));
9944 
9945  i1 = OR_GET_INT (mem1);
9946  i2 = OR_GET_INT (mem2);
9947 
9948  return MR_CMP (i1, i2);
9949 }
9950 
9952 mr_cmpval_resultset (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
9953  int collation)
9954 {
9955  int i1, i2;
9956 
9957  i1 = db_get_resultset (value1);
9958  i2 = db_get_resultset (value2);
9959 
9960  return MR_CMP (i1, i2);
9961 }
9962 
9963 
9964 /*
9965  * TYPE STRING
9966  */
9967 
9968 static void
9969 mr_initmem_string (void *mem, TP_DOMAIN * domain)
9970 {
9971  *(char **) mem = NULL;
9972 }
9973 
9974 
9975 /*
9976  * The main difference between "memory" strings and "value" strings is that
9977  * the length tag is stored as an in-line prefix in the memory block allocated
9978  * to hold the string characters.
9979  */
9980 static int
9981 mr_setmem_string (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
9982 {
9983  int error = NO_ERROR;
9984  const char *src;
9985  char *cur, *new_, **mem;
9986  int src_precision, src_length, new_length;
9987 
9988  /* get the current memory contents */
9989  mem = (char **) memptr;
9990  cur = *mem;
9991 
9992  if (value == NULL || (src = db_get_string (value)) == NULL)
9993  {
9994  /* remove the current value */
9995  if (cur != NULL)
9996  {
9998  mr_initmem_string (memptr, domain);
9999  }
10000  }
10001  else
10002  {
10003  /*
10004  * Get information from the value. Ignore precision for the time being
10005  * since we really only care about the byte size of the value for varchar.
10006  * Whether or not the value "fits" should have been checked by now.
10007  */
10008  src_precision = DB_GET_STRING_PRECISION (value);
10009  src_length = db_get_string_size (value); /* size in bytes */
10010 
10011  if (src_length < 0)
10012  {
10013  src_length = strlen (src);
10014  }
10015 
10016  /* Currently we NULL terminate the workspace string. Could try to do the single byte size hack like we have in
10017  * the disk representation. */
10018  new_length = src_length + sizeof (int) + 1;
10019  new_ = (char *) db_private_alloc (NULL, new_length);
10020  if (new_ == NULL)
10021  {
10022  assert (er_errid () != NO_ERROR);
10023  error = er_errid ();
10024  }
10025  else
10026  {
10027  if (cur != NULL)
10028  {
10030  }
10031 
10032  /* pack in the length prefix */
10033  *(int *) new_ = src_length;
10034  cur = new_ + sizeof (int);
10035  /* store the string */
10036  memcpy (cur, src, src_length);
10037  /* NULL terminate the stored string for safety */
10038  cur[src_length] = '\0';
10039  *mem = new_;
10040  }
10041  }
10042 
10043  return error;
10044 }
10045 
10046 static int
10047 mr_getmem_string (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
10048 {
10049  int error = NO_ERROR;
10050  int mem_length;
10051  char **mem, *cur, *new_;
10052 
10053  /* get to the current value */
10054  mem = (char **) memptr;
10055  cur = *mem;
10056 
10057  if (cur == NULL)
10058  {
10059  db_value_domain_init (value, DB_TYPE_VARCHAR, domain->precision, 0);
10060  value->need_clear = false;
10061  }
10062  else
10063  {
10064  /* extract the length prefix and the pointer to the actual string data */
10065  mem_length = *(int *) cur;
10066  cur += sizeof (int);
10067 
10069  {
10070  assert (false);
10071  return ER_FAILED;
10072  }
10073 
10074  if (!copy)
10075  {
10076  db_make_varchar (value, domain->precision, cur, mem_length, TP_DOMAIN_CODESET (domain),
10077  TP_DOMAIN_COLLATION (domain));
10078  value->need_clear = false;
10079  }
10080  else
10081  {
10082  /* return it with a NULL terminator */
10083  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
10084  if (new_ == NULL)
10085  {
10086  assert (er_errid () != NO_ERROR);
10087  error = er_errid ();
10088  }
10089  else
10090  {
10091  memcpy (new_, cur, mem_length);
10092  new_[mem_length] = '\0';
10093  db_make_varchar (value, domain->precision, new_, mem_length, TP_DOMAIN_CODESET (domain),
10094  TP_DOMAIN_COLLATION (domain));
10095  value->need_clear = true;
10096  }
10097  }
10098  }
10099  return error;
10100 }
10101 
10102 
10103 /*
10104  * For the disk representation, we may be adding pad bytes to round up to a
10105  * word boundary.
10106  *
10107  * We are currently adding a NULL terminator to the disk representation
10108  * for some code on the server that still manufactures pointers directly into
10109  * the disk buffer and assumes it is a NULL terminated string. This terminator
10110  * can be removed after the server has been updated. The logic for maintaining
10111  * the terminator is actually in the or_put_varchar, family of functions.
10112  */
10113 static int
10114 mr_data_lengthmem_string (void *memptr, TP_DOMAIN * domain, int disk)
10115 {
10116  char **mem, *cur;
10117  int len;
10118 
10119  len = 0;
10120  if (!disk)
10121  {
10122  len = tp_String.size;
10123  }
10124  else if (memptr != NULL)
10125  {
10126  mem = (char **) memptr;
10127  cur = *mem;
10128  if (cur != NULL)
10129  {
10130  len = *(int *) cur;
10132  {
10133  /* Skip the length of the string */
10134  len = pr_get_compression_length ((cur + sizeof (int)), len) + PRIM_TEMPORARY_DISK_SIZE;
10136  }
10137  else
10138  {
10139  len = or_packed_varchar_length (len);
10140  }
10141  }
10142  }
10143 
10144  return len;
10145 }
10146 
10147 static int
10148 mr_index_lengthmem_string (void *memptr, TP_DOMAIN * domain)
10149 {
10150  int charlen;
10151  OR_BUF buf;
10152  int rc = NO_ERROR, compressed_length = 0, decompressed_length = 0, length = 0;
10153 
10154  /* generally, index key-value is short enough */
10155  charlen = OR_GET_BYTE (memptr);
10157  {
10158  return or_varchar_length (charlen);
10159  }
10160 
10162 
10163  or_init (&buf, (char *) memptr, -1);
10164 
10165  rc = or_get_varchar_compression_lengths (&buf, &compressed_length, &decompressed_length);
10166 
10167  if (compressed_length > 0)
10168  {
10169  charlen = compressed_length;
10170  }
10171  else
10172  {
10173  charlen = decompressed_length;
10174  }
10175  /* Temporary disk size in case the length of the current buffer is less than 255.
10176  * Therefore the or_varchar_length will always add the 8 bytes consisting the compressed_length
10177  * and decompressed_length stored in buffer.
10178  */
10179 
10180  charlen += PRIM_TEMPORARY_DISK_SIZE;
10181 
10182  length = or_varchar_length (charlen);
10183 
10184  return length - PRIM_TEMPORARY_DISK_SIZE;
10185 }
10186 
10187 static void
10188 mr_data_writemem_string (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
10189 {
10190  char **mem, *cur;
10191  int len;
10192 
10193  mem = (char **) memptr;
10194  cur = *mem;
10195  if (cur != NULL)
10196  {
10197  len = *(int *) cur;
10198  cur += sizeof (int);
10199  or_packed_put_varchar (buf, cur, len);
10200  }
10201 }
10202 
10203 
10204 /*
10205  * The amount of memory requested is currently calculated based on the
10206  * stored size prefix. If we ever go to a system where we avoid storing the
10207  * size, then we could use the size argument passed in to this function but
10208  * that may also include any padding byte that added to bring us up to a word
10209  * boundary.
10210  * Might want some way to determine which bytes at the end of a string are
10211  * padding.
10212  */
10213 static void
10214 mr_data_readmem_string (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
10215 {
10216  char **mem, *cur, *new_;
10217  int len;
10218  int mem_length, pad;
10219  char *start;
10220  int rc = NO_ERROR;
10221 
10222  /*
10223  * we must have an explicit size here as it can't be determined from the
10224  * domain
10225  */
10226  if (size < 0)
10227  {
10228  return;
10229  }
10230 
10231  if (memptr == NULL)
10232  {
10233  if (size)
10234  {
10235  or_advance (buf, size);
10236  }
10237  }
10238  else
10239  {
10240  mem = (char **) memptr;
10241  cur = *mem;
10242  /* should we be checking for existing strings ? */
10243 #if 0
10244  if (cur != NULL)
10246 #endif
10247 
10248  new_ = NULL;
10249  if (size)
10250  {
10251  int compressed_size;
10252  start = buf->ptr;
10253 
10254  /* KLUDGE, we have some knowledge of how the thing is stored here in order have some control over the
10255  * conversion between the packed length prefix and the full word memory length prefix. Might want to put this
10256  * in another specialized or_ function. */
10257 
10258  /* Get just the length prefix. */
10259  rc = or_get_varchar_compression_lengths (buf, &compressed_size, &len);
10260  if (rc != NO_ERROR)
10261  {
10262  or_abort (buf);
10263  return;
10264  }
10265 
10266  /*
10267  * Allocate storage for this string, including our own full word size
10268  * prefix and a NULL terminator.
10269  */
10270  mem_length = len + sizeof (int) + 1;
10271 
10272  new_ = (char *) db_private_alloc (NULL, mem_length);
10273  if (new_ == NULL)
10274  {
10275  or_abort (buf);
10276  }
10277  else
10278  {
10279  /* store the length in our memory prefix */
10280  *(int *) new_ = len;
10281  cur = new_ + sizeof (int);
10282 
10283  /* decompress buffer (this also writes nul terminator) */
10284  rc = pr_get_compressed_data_from_buffer (buf, cur, compressed_size, len);
10285  if (rc != NO_ERROR)
10286  {
10287  db_private_free (NULL, new_);
10288  or_abort (buf);
10289  return;
10290  }
10291  /* align like or_get_varchar */
10292  or_get_align32 (buf);
10293  }
10294 
10295  /* If we were given a size, check to see if for some reason this is larger than the already word aligned
10296  * string that we have now extracted. This shouldn't be the case but since we've got a length, we may as
10297  * well obey it. */
10298  pad = size - (int) (buf->ptr - start);
10299  if (pad > 0)
10300  {
10301  or_advance (buf, pad);
10302  }
10303  }
10304  *mem = new_;
10305  }
10306 }
10307 
10308 static void
10309 mr_freemem_string (void *memptr)
10310 {
10311  char *cur;
10312 
10313  if (memptr != NULL)
10314  {
10315  cur = *(char **) memptr;
10316  if (cur != NULL)
10318  }
10319 }
10320 
10321 static void
10322 mr_initval_string (DB_VALUE * value, int precision, int scale)
10323 {
10324  db_make_varchar (value, precision, NULL, 0, LANG_SYS_CODESET, LANG_SYS_COLLATION);
10325  value->need_clear = false;
10326 }
10327 
10328 static int
10329 mr_setval_string (DB_VALUE * dest, const DB_VALUE * src, bool copy)
10330 {
10331  int error = NO_ERROR;
10332  int src_precision, src_length;
10333  const char *src_str;
10334  char *new_, *new_compressed_buf;
10335 
10336  assert (!db_value_is_corrupted (src));
10337  if (src == NULL || DB_IS_NULL (src))
10338  {
10340  }
10341  else if ((src_str = db_get_string (src)) == NULL)
10342  {
10343  error = db_value_domain_init (dest, DB_TYPE_VARCHAR, db_value_precision (src), 0);
10344  if (src->data.ch.info.is_max_string)
10345  {
10346  dest->data.ch.info.is_max_string = true;
10347  dest->domain.general_info.is_null = 0;
10349  dest->data.ch.medium.compressed_buf = NULL;
10350  dest->data.ch.medium.codeset = db_get_string_codeset (src);
10352  dest->data.ch.info.compressed_need_clear = false;
10353  }
10354  }
10355  else
10356  {
10357  /* Get information from the value. */
10358  src_precision = db_value_precision (src);
10359  src_length = db_get_string_size (src);
10360  if (src_length < 0)
10361  {
10362  src_length = strlen (src_str);
10363  }
10364 
10365  assert (src->data.ch.info.is_max_string == false);
10366 
10367  /* should we be paying attention to this? it is extremely dangerous */
10368  if (!copy)
10369  {
10370  error = db_make_varchar (dest, src_precision, src_str, src_length, db_get_string_codeset (src),
10371  db_get_string_collation (src));
10373  dest->data.ch.info.compressed_need_clear = false;
10374  }
10375  else
10376  {
10377  new_ = (char *) db_private_alloc (NULL, src_length + 1);
10378  if (new_ == NULL)
10379  {
10380  db_value_domain_init (dest, DB_TYPE_VARCHAR, src_precision, 0);
10381  assert (er_errid () != NO_ERROR);
10382  error = er_errid ();
10383  }
10384  else
10385  {
10386  memcpy (new_, src_str, src_length);
10387  new_[src_length] = '\0';
10388  db_make_varchar (dest, src_precision, new_, src_length, db_get_string_codeset (src),
10389  db_get_string_collation (src));
10390  dest->need_clear = true;
10391  }
10392 
10393  if (src->data.ch.medium.compressed_buf == NULL)
10394  {
10395  dest->data.ch.medium.compressed_buf = NULL;
10396  dest->data.ch.info.compressed_need_clear = false;
10397  }
10398  else
10399  {
10400  new_compressed_buf = (char *) db_private_alloc (NULL, src->data.ch.medium.compressed_size + 1);
10401  if (new_compressed_buf == NULL)
10402  {
10403  db_value_domain_init (dest, DB_TYPE_VARCHAR, src_precision, 0);
10404  assert (er_errid () != NO_ERROR);
10405  error = er_errid ();
10406  }
10407  else
10408  {
10409  memcpy (new_compressed_buf, src->data.ch.medium.compressed_buf, src->data.ch.medium.compressed_size);
10410  new_compressed_buf[src->data.ch.medium.compressed_size] = '\0';
10411  dest->data.ch.medium.compressed_buf = new_compressed_buf;
10412  dest->data.ch.info.compressed_need_clear = true;
10413  }
10414  }
10415  }
10416 
10418  }
10419 
10420  return error;
10421 }
10422 
10423 static int
10425 {
10426  return mr_lengthval_string_internal (value, 1, CHAR_ALIGNMENT);
10427 }
10428 
10429 static int
10431 {
10432  return mr_writeval_string_internal (buf, value, CHAR_ALIGNMENT);
10433 }
10434 
10435 static int
10436 mr_index_readval_string (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
10437  int copy_buf_len)
10438 {
10439  return mr_readval_string_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
10440 }
10441 
10442 static int
10444 {
10445  return mr_lengthval_string_internal (value, disk, INT_ALIGNMENT);
10446 }
10447 
10448 static int
10450 {
10451  return mr_writeval_string_internal (buf, value, INT_ALIGNMENT);
10452 }
10453 
10454 static int
10455 mr_data_readval_string (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
10456  int copy_buf_len)
10457 {
10458  return mr_readval_string_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
10459 }
10460 
10461 /*
10462  * Ignoring precision as byte size is really the only important thing for
10463  * varchar.
10464  */
10465 static int
10467 {
10468  int len;
10469  bool is_temporary_data = false;
10470  const char *str;
10471  int rc = NO_ERROR;
10472  int compressed_size = 0;
10473 
10474  if (DB_IS_NULL (value))
10475  {
10476  return 0;
10477  }
10478  str = value->data.ch.medium.buf;
10479  len = value->data.ch.medium.size;
10480  if (!str)
10481  {
10482  return 0;
10483  }
10484  if (len < 0)
10485  {
10486  len = strlen (str);
10487  }
10488 
10489  if (disk == 0)
10490  {
10491  return len;
10492  }
10493  else
10494  {
10495  /* Test and try compression. */
10496  if (!DB_TRIED_COMPRESSION (value))
10497  {
10498  /* It means that the value has never passed through a compression process. */
10499  rc = pr_do_db_value_string_compression (value);
10500  }
10501  /* We are now sure that the value has been through the process of compression */
10502  compressed_size = db_get_compressed_size (value);
10503 
10504  /* If the compression was successful, then we use the compression size value */
10505  if (compressed_size > 0)
10506  {
10507  len = compressed_size + PRIM_TEMPORARY_DISK_SIZE;
10508  is_temporary_data = true;
10509  }
10510  else
10511  {
10512  /* Compression failed so we are using the uncompressed size */
10513  len = value->data.ch.medium.size;
10514  }
10515 
10516  if (len >= OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION && is_temporary_data == false)
10517  {
10518  /* The compression failed but the size of the string calls for the new encoding. */
10519  len += PRIM_TEMPORARY_DISK_SIZE;
10520  is_temporary_data = true;
10521  }
10522 
10523  if (align == INT_ALIGNMENT)
10524  {
10525  len = or_packed_varchar_length (len);
10526  }
10527  else
10528  {
10529  len = or_varchar_length (len);
10530  }
10531 
10532  if (is_temporary_data == true)
10533  {
10534  return len - PRIM_TEMPORARY_DISK_SIZE;
10535  }
10536  return len;
10537  }
10538 }
10539 
10540 
10541 /*
10542  * Ignoring precision as byte size is really the only important thing for
10543  * varchar.
10544  */
10545 static int
10547 {
10548  int src_length, compressed_size;
10549  const char *str, *compressed_string;
10550  int rc = NO_ERROR;
10551  const char *string;
10552  int size;
10553 
10554  if (value != NULL && (str = db_get_string (value)) != NULL)
10555  {
10556  src_length = db_get_string_size (value); /* size in bytes */
10557  if (src_length < 0)
10558  {
10559  src_length = strlen (str);
10560  }
10561 
10562  /* Test for possible compression. */
10563  if (!DB_TRIED_COMPRESSION (value))
10564  {
10565  /* It means that the value has never passed through a compression process. */
10566  rc = pr_do_db_value_string_compression (value);
10567  }
10568 
10569  if (rc != NO_ERROR)
10570  {
10571  return rc;
10572  }
10573 
10574  compressed_size = db_get_compressed_size (value);
10575  compressed_string = DB_GET_COMPRESSED_STRING (value);
10576 
10577  if (compressed_size == DB_UNCOMPRESSABLE && src_length < OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
10578  {
10579  rc = pr_write_uncompressed_string_to_buffer (buf, str, src_length, align);
10580  }
10581  else
10582  {
10583  /* String has been prompted to compression before. */
10584 
10585  if (compressed_string == NULL)
10586  {
10587  /* The value passed through a compression process but it failed due to its size. */
10588  assert (compressed_size == DB_UNCOMPRESSABLE);
10589  string = value->data.ch.medium.buf;
10590  }
10591  else
10592  {
10593  /* Compression successful. */
10594  assert (compressed_size > 0);
10595  string = compressed_string;
10596  }
10597  if (compressed_size == DB_UNCOMPRESSABLE)
10598  {
10599  size = 0;
10600  }
10601  else
10602  {
10603  size = compressed_size;
10604  }
10605  rc = pr_write_compressed_string_to_buffer (buf, string, size, src_length, align);
10606  }
10607  }
10608  return rc;
10609 }
10610 
10611 static int
10612 mr_readval_string_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
10613  int copy_buf_len, int align)
10614 {
10615  int pad, precision;
10616  char *new_ = NULL, *start = NULL;
10617  int str_length;
10618  int rc = NO_ERROR;
10619  int compressed_size = 0, expected_decompressed_size = 0;
10620  char *decompressed_string = NULL, *string = NULL, *compressed_string = NULL;
10621  int decompressed_size = 0;
10622  bool compressed_need_clear = false;
10623 
10624  if (value == NULL)
10625  {
10626  if (size == -1)
10627  {
10628  rc = or_skip_varchar (buf, align);
10629  }
10630  else
10631  {
10632  if (size)
10633  {
10634  rc = or_advance (buf, size);
10635  }
10636  }
10637  }
10638  else
10639  {
10640  if (domain != NULL)
10641  {
10642  precision = domain->precision;
10643  }
10644  else
10645  {
10646  precision = DB_MAX_VARCHAR_PRECISION;
10647  }
10648 
10649  if (size == 0)
10650  {
10651  /* its NULL */
10652  db_value_domain_init (value, DB_TYPE_VARCHAR, precision, 0);
10653  }
10654  else if (!copy)
10655  {
10657  {
10658  assert (false);
10659  return ER_FAILED;
10660  }
10661  /* Get the compressed size and uncompressed size from the buffer, and point the buf->ptr
10662  * towards the data stored in the buffer */
10663  rc = or_get_varchar_compression_lengths (buf, &compressed_size, &expected_decompressed_size);
10664  if (rc != NO_ERROR)
10665  {
10666  return rc;
10667  }
10668 
10669  if (compressed_size > 0)
10670  {
10671  str_length = compressed_size;
10672 
10673  string = (char *) db_private_alloc (NULL, expected_decompressed_size + 1);
10674  if (string == NULL)
10675  {
10677  expected_decompressed_size * sizeof (char));
10679  goto cleanup;
10680  }
10681 
10682  start = buf->ptr;
10683 
10684  rc = pr_get_compressed_data_from_buffer (buf, string, compressed_size, expected_decompressed_size);
10685  if (rc != NO_ERROR)
10686  {
10687  goto cleanup;
10688  }
10689  string[expected_decompressed_size] = '\0';
10690  db_make_varchar (value, precision, string, expected_decompressed_size, TP_DOMAIN_CODESET (domain),
10691  TP_DOMAIN_COLLATION (domain));
10692  value->need_clear = true;
10693 
10694  compressed_string = (char *) db_private_alloc (NULL, compressed_size + 1);
10695  if (compressed_string == NULL)
10696  {
10698  (compressed_size + 1) * sizeof (char));
10700  goto cleanup;
10701  }
10702 
10703  memcpy (compressed_string, start, compressed_size);
10704  compressed_string[compressed_size] = '\0';
10705 
10706  db_set_compressed_string (value, compressed_string, compressed_size, true);
10707  }
10708  else
10709  {
10710  assert (compressed_size == 0);
10711 
10712  str_length = expected_decompressed_size;
10713  db_make_varchar (value, precision, buf->ptr, expected_decompressed_size, TP_DOMAIN_CODESET (domain),
10714  TP_DOMAIN_COLLATION (domain));
10715  value->need_clear = false;
10717  }
10718 
10719  or_skip_varchar_remainder (buf, str_length, align);
10720  }
10721  else /* if (!copy) */
10722  {
10723  assert (size != 0);
10724 
10725  if (size == -1)
10726  {
10727  /* Standard packed varchar with a size prefix */
10728  ; /* do nothing */
10729  }
10730  else
10731  { /* size != -1 */
10732  /* Standard packed varchar within an area of fixed size, usually this means we're looking at the disk
10733  * representation of an attribute. Just like the -1 case except we advance past the additional
10734  * padding. */
10735  start = buf->ptr;
10736  } /* size != -1 */
10737 
10738  /* Get the length of the string, be it compressed or uncompressed. */
10739  rc = or_get_varchar_compression_lengths (buf, &compressed_size, &expected_decompressed_size);
10740  if (rc != NO_ERROR)
10741  {
10742  return ER_FAILED;
10743  }
10744  if (compressed_size <= 0)
10745  {
10746  assert (compressed_size == 0);
10747  str_length = expected_decompressed_size;
10748  }
10749  else
10750  {
10751  str_length = compressed_size;
10752  }
10753 
10754  if (copy_buf && copy_buf_len >= str_length + 1)
10755  {
10756  /* read buf image into the copy_buf */
10757  new_ = copy_buf;
10758  }
10759  else
10760  {
10761  /*
10762  * Allocate storage for the string including the kludge
10763  * NULL terminator
10764  */
10765  new_ = (char *) db_private_alloc (NULL, str_length + 1);
10766  }
10767 
10768  if (new_ == NULL)
10769  {
10770  /* need to be able to return errors ! */
10771  if (domain)
10772  {
10774  }
10775  or_abort (buf);
10776  return ER_FAILED;
10777  }
10778  else
10779  {
10780  if (align == INT_ALIGNMENT)
10781  {
10782  /* read the kludge NULL terminator */
10783  rc = or_get_data (buf, new_, str_length + 1);
10784 
10785  /* round up to a word boundary */
10786  if (rc == NO_ERROR)
10787  {
10788  rc = or_get_align32 (buf);
10789  }
10790  }
10791  else
10792  {
10793  rc = or_get_data (buf, new_, str_length);
10794  }
10795 
10796  if (rc != NO_ERROR)
10797  {
10798  if (new_ != copy_buf)
10799  {
10801  }
10802  return ER_FAILED;
10803  }
10804 
10805  /* Handle decompression if there was any */
10806  if (compressed_size > 0)
10807  {
10808  /* String was compressed */
10809  assert (expected_decompressed_size > 0);
10810 
10811  decompressed_size = 0;
10812 
10813  /* Handle decompression */
10814  decompressed_string = (char *) db_private_alloc (NULL, expected_decompressed_size + 1);
10815  if (decompressed_string == NULL)
10816  {
10818  (size_t) expected_decompressed_size * sizeof (char));
10820  goto cleanup;
10821  }
10822 
10823  /* decompressing the string */
10824  decompressed_size =
10825  LZ4_decompress_safe (new_, decompressed_string, compressed_size, expected_decompressed_size);
10826  if (decompressed_size < 0)
10827  {
10830  goto cleanup;
10831  }
10832  assert (decompressed_size == expected_decompressed_size);
10833 
10834  compressed_string = (char *) db_private_alloc (NULL, compressed_size + 1);
10835  if (compressed_string == NULL)
10836  {
10838  (size_t) (compressed_size + 1) * sizeof (char));
10840  goto cleanup;
10841  }
10842 
10843  memcpy (compressed_string, new_, compressed_size);
10844  compressed_string[compressed_size] = '\0';
10845  compressed_need_clear = true;
10846 
10847  if (new_ != copy_buf)
10848  {
10850  }
10851 
10852  new_ = decompressed_string;
10853  str_length = expected_decompressed_size;
10854  }
10855 
10856  new_[str_length] = '\0'; /* append the kludge NULL terminator */
10858  {
10859  rc = ER_FAILED;
10860  goto cleanup;
10861  }
10862 
10863  db_make_varchar (value, precision, new_, str_length, TP_DOMAIN_CODESET (domain),
10864  TP_DOMAIN_COLLATION (domain));
10865  value->need_clear = (new_ != copy_buf) ? true : false;
10866 
10867  if (compressed_string == NULL)
10868  {
10869  compressed_size = DB_UNCOMPRESSABLE;
10870  compressed_need_clear = false;
10871  }
10872 
10873  db_set_compressed_string (value, compressed_string, compressed_size, compressed_need_clear);
10874 
10875  if (size == -1)
10876  {
10877  /* Standard packed varchar with a size prefix */
10878  ; /* do nothing */
10879  }
10880  else
10881  { /* size != -1 */
10882  /* Standard packed varchar within an area of fixed size, usually this means we're looking at the
10883  * disk representation of an attribute. Just like the -1 case except we advance past the
10884  * additional padding. */
10885  pad = size - (int) (buf->ptr - start);
10886  if (pad > 0)
10887  {
10888  rc = or_advance (buf, pad);
10889  }
10890  } /* size != -1 */
10891  } /* else */
10892  }
10893  }
10894 
10895 cleanup:
10896  if (new_ != NULL && new_ != copy_buf && rc != NO_ERROR)
10897  {
10899  }
10900 
10901  if (decompressed_string != NULL && rc != NO_ERROR)
10902  {
10903  db_private_free_and_init (NULL, decompressed_string);
10904  }
10905 
10906  if (rc != NO_ERROR && compressed_string != NULL)
10907  {
10908  db_private_free_and_init (NULL, compressed_string);
10909  }
10910 
10911  return rc;
10912 }
10913 
10915 mr_index_cmpdisk_string (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
10916 {
10917  assert (domain != NULL);
10918 
10919  return mr_data_cmpdisk_string (mem1, mem2, domain, do_coercion, total_order, start_colp);
10920 }
10921 
10923 mr_data_cmpdisk_string (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
10924 {
10926  char *str1, *str2;
10927  int str_length1, str1_compressed_length = 0, str1_decompressed_length = 0;
10928  int str_length2, str2_compressed_length = 0, str2_decompressed_length = 0;
10929  OR_BUF buf1, buf2;
10930  int rc = NO_ERROR;
10931  char *string1 = NULL, *string2 = NULL;
10932  bool alloced_string1 = false, alloced_string2 = false;
10933  int strc;
10934 
10935  bool ti = true;
10936  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
10937 
10938  assert (domain != NULL);
10939 
10940  str1 = (char *) mem1;
10941  str2 = (char *) mem2;
10942 
10943  /* generally, data is short enough */
10944  str_length1 = OR_GET_BYTE (str1);
10945  str_length2 = OR_GET_BYTE (str2);
10946  if (!ignore_trailing_space)
10947  {
10948  ti = false;
10949  }
10950 
10952  {
10953  str1 += OR_BYTE_SIZE;
10954  str2 += OR_BYTE_SIZE;
10955  strc =
10956  QSTR_COMPARE (domain->collation_id, (unsigned char *) str1, str_length1, (unsigned char *) str2, str_length2,
10957  ti);
10958  c = MR_CMP_RETURN_CODE (strc);
10959  return c;
10960  }
10961 
10963  || str_length2 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION);
10964 
10965  /* String 1 */
10966  or_init (&buf1, str1, 0);
10967  if (str_length1 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
10968  {
10969  rc = or_get_varchar_compression_lengths (&buf1, &str1_compressed_length, &str1_decompressed_length);
10970  if (rc != NO_ERROR)
10971  {
10972  goto cleanup;
10973  }
10974 
10975  string1 = (char *) db_private_alloc (NULL, str1_decompressed_length + 1);
10976  if (string1 == NULL)
10977  {
10978  /* Error report */
10979  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, str1_decompressed_length);
10980  goto cleanup;
10981  }
10982 
10983  alloced_string1 = true;
10984 
10985  rc = pr_get_compressed_data_from_buffer (&buf1, string1, str1_compressed_length, str1_decompressed_length);
10986  if (rc != NO_ERROR)
10987  {
10988  goto cleanup;
10989  }
10990 
10991  str_length1 = str1_decompressed_length;
10992  string1[str_length1] = '\0';
10993  }
10994  else
10995  {
10996  /* Skip the size byte */
10997  string1 = buf1.ptr + OR_BYTE_SIZE;
10998  }
10999 
11000  if (rc != NO_ERROR)
11001  {
11002  ASSERT_ERROR ();
11003  goto cleanup;
11004  }
11005 
11006  /* String 2 */
11007 
11008  or_init (&buf2, str2, 0);
11009 
11010  if (str_length2 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
11011  {
11012  rc = or_get_varchar_compression_lengths (&buf2, &str2_compressed_length, &str2_decompressed_length);
11013  if (rc != NO_ERROR)
11014  {
11015  goto cleanup;
11016  }
11017 
11018  string2 = (char *) db_private_alloc (NULL, str2_decompressed_length + 1);
11019  if (string2 == NULL)
11020  {
11021  /* Error report */
11022  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, str2_decompressed_length);
11023  goto cleanup;
11024  }
11025 
11026  alloced_string2 = true;
11027 
11028  rc = pr_get_compressed_data_from_buffer (&buf2, string2, str2_compressed_length, str2_decompressed_length);
11029  if (rc != NO_ERROR)
11030  {
11031  goto cleanup;
11032  }
11033 
11034  str_length2 = str2_decompressed_length;
11035  string2[str_length2] = '\0';
11036  }
11037  else
11038  {
11039  /* Skip the size byte */
11040  string2 = buf2.ptr + OR_BYTE_SIZE;
11041  }
11042 
11043  if (rc != NO_ERROR)
11044  {
11045  ASSERT_ERROR ();
11046  goto cleanup;
11047  }
11048 
11049  /* Compare the strings */
11050  strc =
11051  QSTR_COMPARE (domain->collation_id, (unsigned char *) string1, str_length1, (unsigned char *) string2, str_length2,
11052  ti);
11053  c = MR_CMP_RETURN_CODE (strc);
11054 
11055  /* Clean up the strings */
11056  if (string1 != NULL && alloced_string1 == true)
11057  {
11058  db_private_free_and_init (NULL, string1);
11059  }
11060 
11061  if (string2 != NULL && alloced_string2 == true)
11062  {
11063  db_private_free_and_init (NULL, string2);
11064  }
11065 
11066  return c;
11067 
11068 cleanup:
11069  if (string1 != NULL && alloced_string1 == true)
11070  {
11071  db_private_free_and_init (NULL, string1);
11072  }
11073 
11074  if (string2 != NULL && alloced_string2 == true)
11075  {
11076  db_private_free_and_init (NULL, string2);
11077  }
11078 
11079  return DB_UNK;
11080 }
11081 
11083 mr_cmpval_string (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
11084  int collation)
11085 {
11087  int size1, size2;
11088  int strc;
11089 
11090  bool ti = true;
11091  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
11092 
11093  DB_TYPE type1 = (DB_TYPE) value1->domain.char_info.type;
11094  DB_TYPE type2 = (DB_TYPE) value2->domain.char_info.type;
11095 
11096  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
11097  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
11098 
11099  /*
11100  * Check if the is_max_string flag set for each DB_VALUE.
11101  * If "value1" has the flag set, return 1, meaning that "value2" is Less Than "value1".
11102  * If "value2" has the flag set, return -1, meaning that "value1" is Greater Than "value2".
11103  */
11104 
11105  if (value1->data.ch.info.is_max_string != 0)
11106  {
11107  if (value2->data.ch.info.is_max_string != 0)
11108  {
11109  /* Both strings are max_string. Therefore equal. Even though this should not happen. */
11110  assert (false);
11111  return DB_EQ;
11112  }
11113  return DB_GT;
11114  }
11115  else
11116  {
11117  if (value2->data.ch.info.is_max_string != 0)
11118  {
11119  return DB_LT;
11120  }
11121  }
11122 
11123  if (string1 == NULL || string2 == NULL || db_get_string_codeset (value1) != db_get_string_codeset (value2))
11124  {
11125  return DB_UNK;
11126  }
11127 
11128  size1 = (int) db_get_string_size (value1);
11129  size2 = (int) db_get_string_size (value2);
11130 
11131  if (size1 < 0)
11132  {
11133  size1 = strlen ((char *) string1);
11134  }
11135 
11136  if (size2 < 0)
11137  {
11138  size2 = strlen ((char *) string2);
11139  }
11140 
11141  if (collation == -1)
11142  {
11143  assert (false);
11144  return DB_UNK;
11145  }
11146 
11147  if (!ignore_trailing_space)
11148  {
11149  int i;
11150 
11151  if (type1 == DB_TYPE_CHAR || type1 == DB_TYPE_NCHAR)
11152  {
11153  for (i = size1; i > 1; i--)
11154  {
11155  if (string1[i - 1] != 0x20)
11156  {
11157  break;
11158  }
11159  }
11160  size1 = i;
11161  }
11162 
11163  if (type2 == DB_TYPE_CHAR || type2 == DB_TYPE_NCHAR)
11164  {
11165  for (i = size2; i > 1; i--)
11166  {
11167  if (string2[i - 1] != 0x20)
11168  {
11169  break;
11170  }
11171  }
11172  size2 = i;
11173  }
11174 
11175  ti = false;
11176  }
11177 
11178  strc = QSTR_COMPARE (collation, string1, size1, string2, size2, ti);
11179  c = MR_CMP_RETURN_CODE (strc);
11180 
11181  return c;
11182 }
11183 
11184 #if defined (ENABLE_UNUSED_FUNCTION)
11185 static int
11186 mr_cmpval_string2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order, int *start_colp)
11187 {
11188  int c;
11189  int len1, len2, string_size;
11190 
11191  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
11192  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
11193 
11194  if (string1 == NULL || string2 == NULL)
11195  {
11196  return DB_UNK;
11197  }
11198 
11199  string_size = (int) db_get_string_size (value1);
11200  len1 = MIN (string_size, length);
11201  string_size = (int) db_get_string_size (value2);
11202  len2 = MIN (string_size, length);
11203 
11204  c = QSTR_COMPARE (string1, len1, string2, len2);
11205  c = MR_CMP_RETURN_CODE (c);
11206 
11207  return c;
11208 }
11209 #endif
11210 
11212  "character varying", DB_TYPE_STRING, 1, sizeof (const char *), 0, 1,
11232 };
11233 
11235 
11236 /*
11237  * TYPE CHAR
11238  */
11239 
11240 static void
11241 mr_initmem_char (void *memptr, TP_DOMAIN * domain)
11242 {
11243 #if !defined(NDEBUG)
11244  int mem_length;
11245 
11246  assert (!IS_FLOATING_PRECISION (domain->precision));
11247 
11248  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11249  memset (memptr, 0, mem_length);
11250 #endif
11251 }
11252 
11253 
11254 /*
11255  * Note! Due to the "within tolerance" comparison of domains used for
11256  * assignment validation, we may get values in here whose precision is
11257  * less than the precision of the actual attribute. This prevents
11258  * having to copy a string just to coerce a value into a larger precision.
11259  * Note that the precision of the source value may also come in as -1 here
11260  * which is used to mean a "floating" precision that is assumed to be
11261  * compatible with the destination domain as long as the associated value
11262  * is within tolerance. This case is generally only seen for string
11263  * literals that have been produced by the parser. These literals will
11264  * not contain blank padding and strlen() or db_get_string_size() can be
11265  * used to determine the number of significant characters.
11266  *
11267  */
11268 static int
11269 mr_setmem_char (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
11270 {
11271  int error = NO_ERROR;
11272  char *mem;
11273  const char *src;
11274  int src_precision, src_length, mem_length, pad;
11275 
11276  assert (!IS_FLOATING_PRECISION (domain->precision));
11277 
11278  if (value == NULL)
11279  {
11280  return NO_ERROR;
11281  }
11282 
11283  /* Get information from the value */
11284  src = db_get_string (value);
11285  src_precision = DB_GET_STRING_PRECISION (value);
11286  src_length = db_get_string_size (value); /* size in bytes */
11287 
11288  if (src == NULL)
11289  {
11290  return NO_ERROR;
11291  }
11292 
11293  /* Check for special NTS flag. This may not be necessary any more. */
11294  if (src_length < 0)
11295  {
11296  src_length = strlen (src);
11297  }
11298 
11299 
11300  /* The only thing we really care about at this point, is the byte length of the string. The precision could be
11301  * checked here but it really isn't necessary for this operation. Calculate the maximum number of bytes we have
11302  * available here. The multiplier is dependent on codeset */
11303  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11304 
11305  if (mem_length < src_length)
11306  {
11307  /*
11308  * should never get here, this is supposed to be caught during domain
11309  * validation, need a better error message.
11310  */
11311  error = ER_OBJ_DOMAIN_CONFLICT;
11312  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, "");
11313  }
11314  else
11315  {
11316  /* copy the value into memory */
11317  mem = (char *) memptr;
11318  memcpy (mem, src, src_length);
11319 
11320  /*
11321  * Check for space padding, if this were a national string, we would
11322  * need to be padding with the appropriate space character !
11323  */
11324  pad = mem_length - src_length;
11325  if (pad)
11326  {
11327  int i;
11328 
11329  for (i = src_length; i < mem_length; i++)
11330  {
11331  mem[i] = ' ';
11332  }
11333  }
11334  }
11335  return error;
11336 }
11337 
11338 
11339 static int
11340 mr_getmem_char (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
11341 {
11342  int mem_length;
11343  char *new_;
11344 
11345  assert (!IS_FLOATING_PRECISION (domain->precision));
11347  {
11348  assert (false);
11349  return ER_FAILED;
11350  }
11351 
11352  intl_char_size ((unsigned char *) mem, domain->precision, TP_DOMAIN_CODESET (domain), &mem_length);
11353  if (mem_length == 0)
11354  {
11355  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11356  }
11357 
11358  if (!copy)
11359  {
11360  new_ = (char *) mem;
11361  }
11362  else
11363  {
11364  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
11365  if (new_ == NULL)
11366  {
11367  assert (er_errid () != NO_ERROR);
11368  return er_errid ();
11369  }
11370  memcpy (new_, (char *) mem, mem_length);
11371  /* make sure that all outgoing strings are NULL terminated */
11372  new_[mem_length] = '\0';
11373  }
11374 
11375  db_make_char (value, domain->precision, new_, mem_length, TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain));
11376  if (copy)
11377  {
11378  value->need_clear = true;
11379  }
11380 
11381  return NO_ERROR;
11382 }
11383 
11384 static int
11385 mr_data_lengthmem_char (void *memptr, TP_DOMAIN * domain, int disk)
11386 {
11387  int mem_length;
11388 
11389  assert (!IS_FLOATING_PRECISION (domain->precision));
11390 
11391  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11392 
11393  return mem_length;
11394 }
11395 
11396 static int
11397 mr_index_lengthmem_char (void *memptr, TP_DOMAIN * domain)
11398 {
11399  int mem_length;
11400 
11401  assert (!(IS_FLOATING_PRECISION (domain->precision) && memptr == NULL));
11402 
11403  if (IS_FLOATING_PRECISION (domain->precision))
11404  {
11405  memcpy (&mem_length, memptr, OR_INT_SIZE);
11406  mem_length += OR_INT_SIZE;
11407  }
11408  else
11409  {
11410  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11411  }
11412 
11413  return mem_length;
11414 }
11415 
11416 static void
11417 mr_data_writemem_char (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
11418 {
11419  int mem_length;
11420 
11421  assert (!IS_FLOATING_PRECISION (domain->precision));
11422 
11423  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11424 
11425  /*
11426  * We simply dump the memory image to disk, it will already have been padded.
11427  * If this were a national character string, at this point, we'd have to
11428  * decide now to perform a character set conversion.
11429  */
11430  or_put_data (buf, (char *) mem, mem_length);
11431 }
11432 
11433 static void
11434 mr_data_readmem_char (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
11435 {
11436  int mem_length, padding;
11437 
11438  assert (!IS_FLOATING_PRECISION (domain->precision));
11439 
11440  if (mem == NULL)
11441  {
11442  /*
11443  * If we passed in a size, then use it. Otherwise, determine the
11444  * size from the domain.
11445  */
11446  if (size > 0)
11447  {
11448  or_advance (buf, size);
11449  }
11450  else
11451  {
11452  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11453  or_advance (buf, mem_length);
11454  }
11455  }
11456  else
11457  {
11458  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11459 
11460  if (size != -1 && mem_length > size)
11461  {
11463  or_abort (buf);
11464  }
11465  or_get_data (buf, (char *) mem, mem_length);
11466 
11467  /*
11468  * We should only see padding if the string is contained within a packed
11469  * value that had extra padding to ensure alignment. If we see these,
11470  * just pop them out of the buffer. This shouldn't ever happen for the
11471  * "getmem" function, only for the "getval" function.
11472  */
11473  if (size != -1)
11474  {
11475  padding = size - mem_length;
11476  if (padding > 0)
11477  {
11478  or_advance (buf, padding);
11479  }
11480  }
11481  }
11482 }
11483 
11484 static void
11485 mr_freemem_char (void *memptr)
11486 {
11487 }
11488 
11489 static void
11490 mr_initval_char (DB_VALUE * value, int precision, int scale)
11491 {
11492  DB_DOMAIN_INIT_CHAR (value, precision);
11493 }
11494 
11495 static int
11496 mr_setval_char (DB_VALUE * dest, const DB_VALUE * src, bool copy)
11497 {
11498  int error = NO_ERROR;
11499  int src_precision, src_length;
11500  char *new_;
11501  const char *src_string;
11502 
11503  assert (!db_value_is_corrupted (src));
11504  if (DB_IS_NULL (src))
11505  {
11507  }
11508  else
11509  {
11510  src_precision = DB_GET_STRING_PRECISION (src);
11511  if (src_precision == 0)
11512  {
11513  src_precision = TP_FLOATING_PRECISION_VALUE;
11514  }
11515  DB_DOMAIN_INIT_CHAR (dest, src_precision);
11516  /* Get information from the value */
11517  src_string = db_get_string (src);
11518  src_length = db_get_string_size (src); /* size in bytes */
11519 
11520  /* shouldn't see a NULL string at this point, treat as NULL */
11521  if (src_string != NULL)
11522  {
11523  if (!copy)
11524  {
11525  db_make_char (dest, src_precision, src_string, src_length, db_get_string_codeset (src),
11526  db_get_string_collation (src));
11527  }
11528  else
11529  {
11530  /* Check for NTS marker, may not need to do this any more */
11531  if (src_length < 0)
11532  {
11533  src_length = strlen (src_string);
11534  }
11535 
11536  /* make sure the copy gets a NULL terminator */
11537  new_ = (char *) db_private_alloc (NULL, src_length + 1);
11538  if (new_ == NULL)
11539  {
11540  assert (er_errid () != NO_ERROR);
11541  error = er_errid ();
11542  }
11543  else
11544  {
11545  memcpy (new_, src_string, src_length);
11546  new_[src_length] = '\0';
11547  db_make_char (dest, src_precision, new_, src_length, db_get_string_codeset (src),
11548  db_get_string_collation (src));
11549  dest->need_clear = true;
11550  }
11551  }
11552  }
11553  }
11554 
11555  return error;
11556 }
11557 
11558 static int
11560 {
11561  return mr_data_lengthval_char (value, 1);
11562 }
11563 
11564 /*
11565  */
11566 static int
11568 {
11569  int packed_length, src_precision;
11570 
11571  const char *src = db_get_string (value);
11572  if (src == NULL)
11573  {
11574  return 0;
11575  }
11576 
11577  src_precision = db_value_precision (value);
11578  if (!IS_FLOATING_PRECISION (src_precision))
11579  {
11580  packed_length = STR_SIZE (src_precision, db_get_string_codeset (value));
11581  }
11582  else
11583  {
11584  /*
11585  * Precision is "floating", calculate the effective precision based on the
11586  * string length.
11587  * Should be rounding this up so it is a proper multiple of the charset
11588  * width ?
11589  */
11590  packed_length = db_get_string_size (value);
11591  if (packed_length < 0)
11592  {
11593  packed_length = strlen (src);
11594  }
11595 
11596  /* add in storage for a size prefix on the packed value. */
11597  packed_length += OR_INT_SIZE;
11598  }
11599 
11600  /*
11601  * NOTE: We do NOT perform padding here, if this is used in the context
11602  * of a packed value, the or_put_value() family of functions must handle
11603  * their own padding, this is because "lengthval" and "writeval" can be
11604  * used to place values into the disk representation of instances and
11605  * there can be no padding in there.
11606  */
11607 
11608  return packed_length;
11609 }
11610 
11611 
11612 static int
11614 {
11615  return mr_writeval_char_internal (buf, value, CHAR_ALIGNMENT);
11616 }
11617 
11618 /*
11619  * See commentary in mr_lengthval_char.
11620  */
11621 static int
11623 {
11624  return mr_writeval_char_internal (buf, value, INT_ALIGNMENT);
11625 }
11626 
11627 static int
11629 {
11630  int src_precision, src_length, packed_length, pad;
11631  const char *src;
11632  int rc = NO_ERROR;
11633 
11634  src = db_get_string (value);
11635  if (src == NULL)
11636  {
11637  return rc;
11638  }
11639 
11640  src_precision = db_value_precision (value);
11641 
11642  if (!IS_FLOATING_PRECISION (src_precision))
11643  {
11644  src_length = db_get_string_size (value); /* size in bytes */
11645 
11646  if (src_length < 0)
11647  {
11648  src_length = strlen (src);
11649  }
11650 
11651  packed_length = STR_SIZE (src_precision, db_get_string_codeset (value));
11652 
11653  if (packed_length < src_length)
11654  {
11655  /* should have caught this by now, truncate silently */
11656  rc = or_put_data (buf, src, packed_length);
11657  }
11658  else
11659  {
11660  rc = or_put_data (buf, src, src_length);
11661  /*
11662  * Check for space padding, if this were a national string, we
11663  * would need to be padding with the appropriate space character !
11664  */
11665  pad = packed_length - src_length;
11666  if (pad)
11667  {
11668  int i;
11669  for (i = src_length; i < packed_length; i++)
11670  {
11671  rc = or_put_byte (buf, (int) ' ');
11672  }
11673  }
11674  }
11675  if (rc != NO_ERROR)
11676  {
11677  return rc;
11678  }
11679  }
11680  else
11681  {
11682  /*
11683  * This is a "floating" precision value. Pack what we can based on the
11684  * string size. Note that for this to work, this can only be packed as
11685  * part of a domain tagged value and we must include a length prefix
11686  * after the domain.
11687  */
11688  packed_length = db_get_string_size (value);
11689  if (packed_length < 0)
11690  {
11691  packed_length = strlen (src);
11692  }
11693 
11694  /* store the size prefix */
11695  if (align == INT_ALIGNMENT)
11696  {
11697  rc = or_put_int (buf, packed_length);
11698  }
11699  else
11700  {
11701  rc = or_put_data (buf, (char *) (&packed_length), OR_INT_SIZE);
11702  }
11703  if (rc == NO_ERROR)
11704  {
11705  /* store the data */
11706  rc = or_put_data (buf, src, packed_length);
11707  /* there is no blank padding in this case */
11708  }
11709  }
11710  return rc;
11711 }
11712 
11713 static int
11714 mr_index_readval_char (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
11715  int copy_buf_len)
11716 {
11717  return mr_readval_char_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
11718 }
11719 
11720 static int
11721 mr_data_readval_char (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
11722  int copy_buf_len)
11723 {
11724  return mr_readval_char_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
11725 }
11726 
11727 static int
11728 mr_readval_char_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
11729  int copy_buf_len, int align)
11730 {
11731  int mem_length, padding;
11732  int str_length, precision;
11733  char *new_;
11734  int rc = NO_ERROR;
11735  precision = domain->precision;
11737  {
11738  assert (false);
11739  return ER_FAILED;
11740  }
11741 
11742  if (IS_FLOATING_PRECISION (domain->precision))
11743  {
11744  if (align == INT_ALIGNMENT)
11745  {
11746  mem_length = or_get_int (buf, &rc);
11747  }
11748  else
11749  {
11750  rc = or_get_data (buf, (char *) (&mem_length), OR_INT_SIZE);
11751  }
11752  if (rc != NO_ERROR)
11753  {
11754  return rc;
11755  }
11756 
11757  if (value == NULL)
11758  {
11759  rc = or_advance (buf, mem_length);
11760  }
11761  else if (!copy)
11762  {
11763  db_make_char (value, TP_FLOATING_PRECISION_VALUE, buf->ptr, mem_length, TP_DOMAIN_CODESET (domain),
11764  TP_DOMAIN_COLLATION (domain));
11765  value->need_clear = false;
11766  rc = or_advance (buf, mem_length);
11767  }
11768  else
11769  {
11770  if (copy_buf && copy_buf_len >= mem_length + 1)
11771  {
11772  /* read buf image into the copy_buf */
11773  new_ = copy_buf;
11774  }
11775  else
11776  {
11777  /* Allocate storage for the string including the kludge NULL terminator */
11778  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
11779  }
11780 
11781  if (new_ == NULL)
11782  {
11783  /* need to be able to return errors ! */
11785  or_abort (buf);
11786 
11787  return ER_FAILED;
11788  }
11789  else
11790  {
11791  rc = or_get_data (buf, new_, mem_length);
11792  if (rc != NO_ERROR)
11793  {
11794  if (new_ != copy_buf)
11795  {
11797  }
11798  return rc;
11799  }
11800  new_[mem_length] = '\0'; /* append the kludge NULL terminator */
11801  db_make_char (value, TP_FLOATING_PRECISION_VALUE, new_, mem_length, TP_DOMAIN_CODESET (domain),
11802  TP_DOMAIN_COLLATION (domain));
11803  value->need_clear = (new_ != copy_buf) ? true : false;
11804  }
11805  }
11806  }
11807  else
11808  {
11809  /*
11810  * Normal fixed width char(n) whose size can be determined by looking at
11811  * the domain.
11812  */
11813  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11814 
11815  if (disk_size != -1 && mem_length > disk_size)
11816  {
11817  /*
11818  * If we're low here, we could just read what we have and make a
11819  * smaller value. Still the domain should match at this point.
11820  */
11822  or_abort (buf);
11823  return ER_FAILED;
11824  }
11825 
11826  if (value == NULL)
11827  {
11828  rc = or_advance (buf, mem_length);
11829  }
11830  else if (disk_size == 0)
11831  {
11832  db_value_domain_init (value, DB_TYPE_CHAR, precision, 0);
11833  }
11834  else if (!copy)
11835  {
11836  intl_char_size ((unsigned char *) buf->ptr, domain->precision, TP_DOMAIN_CODESET (domain), &str_length);
11837  if (str_length == 0)
11838  {
11839  str_length = mem_length;
11840  }
11841  db_make_char (value, precision, buf->ptr, str_length, TP_DOMAIN_CODESET (domain),
11842  TP_DOMAIN_COLLATION (domain));
11843  value->need_clear = false;
11844  rc = or_advance (buf, mem_length);
11845  }
11846  else
11847  {
11848  if (copy_buf && copy_buf_len >= mem_length + 1)
11849  {
11850  /* read buf image into the copy_buf */
11851  new_ = copy_buf;
11852  }
11853  else
11854  {
11855  /*
11856  * Allocate storage for the string including the kludge NULL
11857  * terminator
11858  */
11859  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
11860  }
11861  if (new_ == NULL)
11862  {
11863  /* need to be able to return errors ! */
11864  db_value_domain_init (value, TP_DOMAIN_TYPE (domain), domain->precision, 0);
11865  or_abort (buf);
11866 
11867  return ER_FAILED;
11868  }
11869  else
11870  {
11871  int actual_size = 0;
11872  rc = or_get_data (buf, new_, mem_length);
11873  if (rc != NO_ERROR)
11874  {
11875  if (new_ != copy_buf)
11876  {
11878  }
11879  return rc;
11880  }
11881  intl_char_size ((unsigned char *) new_, domain->precision, TP_DOMAIN_CODESET (domain), &actual_size);
11882  if (actual_size == 0)
11883  {
11884  actual_size = mem_length;
11885  }
11886  new_[actual_size] = '\0'; /* append the kludge NULL terminator */
11887  db_make_char (value, domain->precision, new_, actual_size, TP_DOMAIN_CODESET (domain),
11888  TP_DOMAIN_COLLATION (domain));
11889  value->need_clear = (new_ != copy_buf) ? true : false;
11890  }
11891  }
11892 
11893  if (rc == NO_ERROR)
11894  {
11895  /*
11896  * We should only see padding if the string is contained within a
11897  * packed value that had extra padding to ensure alignment. If we
11898  * see these, just pop them out of the buffer.
11899  */
11900  if (disk_size != -1)
11901  {
11902  padding = disk_size - mem_length;
11903  if (padding > 0)
11904  {
11905  rc = or_advance (buf, padding);
11906  }
11907  }
11908  }
11909  }
11910  return rc;
11911 }
11912 
11914 mr_index_cmpdisk_char (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
11915 {
11916  assert (domain != NULL);
11917 
11918  return mr_cmpdisk_char_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, CHAR_ALIGNMENT);
11919 }
11920 
11922 mr_data_cmpdisk_char (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
11923 {
11924  assert (domain != NULL);
11925 
11926  return mr_cmpdisk_char_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, INT_ALIGNMENT);
11927 }
11928 
11930 mr_cmpdisk_char_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp,
11931  int align)
11932 {
11934  int mem_length1, mem_length2, strc;
11935 
11936  bool ti = true;
11937  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
11938 
11939  if (IS_FLOATING_PRECISION (domain->precision))
11940  {
11941  if (align == INT_ALIGNMENT)
11942  {
11943  mem_length1 = OR_GET_INT (mem1);
11944  mem_length2 = OR_GET_INT (mem2);
11945  }
11946  else
11947  {
11948  memcpy (&mem_length1, mem1, OR_INT_SIZE);
11949  memcpy (&mem_length2, mem2, OR_INT_SIZE);
11950  }
11951  mem1 = (char *) mem1 + OR_INT_SIZE;
11952  mem2 = (char *) mem2 + OR_INT_SIZE;
11953  }
11954  else
11955  {
11956  /*
11957  * Normal fixed width char(n) whose size can be determined by looking at
11958  * the domain.
11959  * Needs NCHAR work here to separate the dependencies on disk_size and
11960  * mem_size.
11961  */
11962  mem_length1 = mem_length2 = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
11963  }
11964 
11965  if (!ignore_trailing_space)
11966  {
11967  ti = (domain->type->id == DB_TYPE_CHAR || domain->type->id == DB_TYPE_NCHAR);
11968  }
11969 
11970  strc = QSTR_CHAR_COMPARE (domain->collation_id, (unsigned char *) mem1, mem_length1, (unsigned char *) mem2,
11971  mem_length2, ti);
11972  c = MR_CMP_RETURN_CODE (strc);
11973 
11974  return c;
11975 }
11976 
11978 mr_cmpval_char (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
11979 {
11981  int strc, size1, size2;
11982 
11983  bool ti = true;
11984  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
11985 
11986  DB_TYPE type1 = (DB_TYPE) value1->domain.char_info.type;
11987  DB_TYPE type2 = (DB_TYPE) value2->domain.char_info.type;
11988 
11989  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
11990  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
11991 
11992  /*
11993  * Check if the is_max_string flag set for each DB_VALUE.
11994  * If "value1" has the flag set, return 1, meaning that "value2" is Less Than "value1".
11995  * If "value2" has the flag set, return -1, meaning that "value1" is Greater Than "value2".
11996  */
11997 
11998  if (value1->data.ch.info.is_max_string != 0)
11999  {
12000  if (value2->data.ch.info.is_max_string != 0)
12001  {
12002  /* Both strings are max_string. Therefore equal. Even though this should not happen. */
12003  assert (false);
12004  return DB_EQ;
12005  }
12006  return DB_GT;
12007  }
12008  else
12009  {
12010  if (value2->data.ch.info.is_max_string != 0)
12011  {
12012  return DB_LT;
12013  }
12014  }
12015 
12016  if (string1 == NULL || string2 == NULL || db_get_string_codeset (value1) != db_get_string_codeset (value2))
12017  {
12018  return DB_UNK;
12019  }
12020 
12021  if (collation == -1)
12022  {
12023  assert (false);
12024  return DB_UNK;
12025  }
12026 
12027  size1 = db_get_string_size (value1);
12028  size2 = db_get_string_size (value2);
12029 
12030  /*
12031  * do_coercion = 2:
12032  * from btree compare key
12033  * we need to process the ignore trailing space
12034  */
12035  if (do_coercion == 2)
12036  {
12037  ti = true;
12038  }
12039  /*
12040  * do_coercion = 3:
12041  * from eliminate_duplicated_keys and scan_key_compre
12042  * we need to process enforcing no-ignore-trailing space.
12043  */
12044  else if (do_coercion == 3)
12045  {
12046  ti = false;
12047  }
12048  else if (!ignore_trailing_space &&
12049  (type1 == DB_TYPE_STRING || type1 == DB_TYPE_VARNCHAR || type2 == DB_TYPE_STRING
12050  || type2 == DB_TYPE_VARNCHAR))
12051  {
12052  int i;
12053 
12054  if (type1 == DB_TYPE_CHAR || type1 == DB_TYPE_NCHAR)
12055  {
12056  for (i = size1; i > 1; i--)
12057  {
12058  if (string1[i - 1] != 0x20)
12059  {
12060  break;
12061  }
12062  }
12063  size1 = i;
12064  }
12065 
12066  if (type2 == DB_TYPE_CHAR || type2 == DB_TYPE_NCHAR)
12067  {
12068  for (i = size2; i > 1; i--)
12069  {
12070  if (string2[i - 1] != 0x20)
12071  {
12072  break;
12073  }
12074  }
12075  size2 = i;
12076  }
12077 
12078  ti = false;
12079  }
12080 
12081  strc = QSTR_CHAR_COMPARE (collation, string1, size1, string2, size2, ti);
12082  c = MR_CMP_RETURN_CODE (strc);
12083 
12084  return c;
12085 }
12086 
12087 #if defined (ENABLE_UNUSED_FUNCTION)
12088 static int
12089 mr_cmpval_char2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order, int *start_colp)
12090 {
12091  int c;
12092  int len1, len2, string_size;
12093 
12094  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
12095  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
12096 
12097  if (string1 == NULL || string2 == NULL)
12098  {
12099  return DB_UNK;
12100  }
12101 
12102  string_size = (int) db_get_string_size (value1);
12103  len1 = MIN (string_size, length);
12104  string_size = (int) db_get_string_size (value2);
12105  len2 = MIN (string_size, length);
12106 
12107  c = QSTR_CHAR_COMPARE (string1, len1, string2, len2);
12108  c = MR_CMP_RETURN_CODE (c);
12109 
12110  return c;
12111 }
12112 #endif
12113 
12115  "character", DB_TYPE_CHAR, 0, 0, 0, 1,
12135 };
12136 
12138 
12139 /*
12140  * TYPE NCHAR
12141  */
12142 
12143 static void
12144 mr_initmem_nchar (void *memptr, TP_DOMAIN * domain)
12145 {
12146 #if !defined(NDEBUG)
12147  int mem_length;
12148 
12149  assert (!IS_FLOATING_PRECISION (domain->precision));
12150 
12151  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12152  memset (memptr, 0, mem_length);
12153 #endif
12154 }
12155 
12156 
12157 /*
12158  * Due to the "within tolerance" comparison of domains used for
12159  * assignment validation, we may get values in here whose precision is
12160  * less than the precision of the actual attribute. This prevents
12161  * having to copy a string just to coerce a value into a larger precision.
12162  * Note that the precision of the source value may also come in as -1 here
12163  * which is used to mean a "floating" precision that is assumed to be
12164  * compatible with the destination domain as long as the associated value
12165  * is within tolerance. This case is generally only seen for string
12166  * literals that have been produced by the parser. These literals will
12167  * not contain blank padding and strlen() or db_get_string_size() can be
12168  * used to determine the number of significant characters.
12169  */
12170 static int
12171 mr_setmem_nchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
12172 {
12173  int error = NO_ERROR;
12174  char *mem;
12175  const char *src;
12176  int src_precision, src_length, mem_length, pad;
12177 
12178  if (value == NULL)
12179  {
12180  return NO_ERROR;
12181  }
12182 
12183  /* Get information from the value */
12184  src = db_get_string (value);
12185  src_precision = db_value_precision (value);
12186  src_length = db_get_string_size (value); /* size in bytes */
12187 
12188  if (src == NULL)
12189  {
12190  return NO_ERROR;
12191  }
12192 
12193  /* Check for special NTS flag. This may not be necessary any more. */
12194  if (src_length < 0)
12195  {
12196  src_length = strlen (src);
12197  }
12198 
12199  /*
12200  * The only thing we really care about at this point, is the byte
12201  * length of the string. The precision could be checked here but it
12202  * really isn't necessary for this operation.
12203  * Calculate the maximum number of bytes we have available here.
12204  */
12205  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12206 
12207  if (mem_length < src_length)
12208  {
12209  /*
12210  * should never get here, this is supposed to be caught during domain
12211  * validation, need a better error message.
12212  */
12213  error = ER_OBJ_DOMAIN_CONFLICT;
12214  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, "");
12215  }
12216  else
12217  {
12218  /* copy the value into memory */
12219  mem = (char *) memptr;
12220  memcpy (mem, src, src_length);
12221 
12222  /*
12223  * Check for space padding, if this were a national string, we would need
12224  * to be padding with the appropriate space character !
12225  */
12226  pad = mem_length - src_length;
12227  if (pad)
12228  {
12229  int i;
12230 
12231  for (i = src_length; i < mem_length; i++)
12232  {
12233  mem[i] = ' ';
12234  }
12235  }
12236  }
12237 
12238  return error;
12239 }
12240 
12241 /*
12242  * We always ensure that the string returned here is NULL terminated
12243  * if the copy flag is on. This technically shouldn't be necessary but there
12244  * is a lot of code scattered about (especially applications) that assumes
12245  * NULL termination.
12246  */
12247 static int
12248 mr_getmem_nchar (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
12249 {
12250  int mem_length;
12251  char *new_;
12252 
12254  {
12255  assert (false);
12256  return ER_FAILED;
12257  }
12258  intl_char_size ((unsigned char *) mem, domain->precision, TP_DOMAIN_CODESET (domain), &mem_length);
12259  if (mem_length == 0)
12260  {
12261  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12262  }
12263 
12264  if (!copy)
12265  {
12266  new_ = (char *) mem;
12267  }
12268  else
12269  {
12270  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
12271  if (new_ == NULL)
12272  {
12273  assert (er_errid () != NO_ERROR);
12274  return er_errid ();
12275  }
12276  memcpy (new_, (char *) mem, mem_length);
12277  /* make sure that all outgoing strings are NULL terminated */
12278  new_[mem_length] = '\0';
12279  }
12280 
12282  {
12283  assert (false);
12284  return ER_FAILED;
12285  }
12286  db_make_nchar (value, domain->precision, new_, mem_length, TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain));
12287  if (copy)
12288  {
12289  value->need_clear = true;
12290  }
12291 
12292  return NO_ERROR;
12293 }
12294 
12295 static int
12296 mr_data_lengthmem_nchar (void *memptr, TP_DOMAIN * domain, int disk)
12297 {
12298  assert (!IS_FLOATING_PRECISION (domain->precision));
12299 
12300  return STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12301 }
12302 
12303 static int
12304 mr_index_lengthmem_nchar (void *memptr, TP_DOMAIN * domain)
12305 {
12306  int mem_length;
12307 
12308  assert (!(IS_FLOATING_PRECISION (domain->precision) && memptr == NULL));
12309 
12310  if (!IS_FLOATING_PRECISION (domain->precision))
12311  {
12312  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12313  }
12314  else
12315  {
12316  memcpy (&mem_length, memptr, OR_INT_SIZE);
12317  mem_length += OR_INT_SIZE;
12318  }
12319 
12320  return mem_length;
12321 }
12322 
12323 static void
12324 mr_data_writemem_nchar (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
12325 {
12326  int mem_length;
12327 
12328  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12329 
12330  /*
12331  * We simply dump the memory image to disk, it will already have been padded.
12332  * If this were a national character string, at this point, we'd have to
12333  * decide now to perform a character set conversion.
12334  */
12335  or_put_data (buf, (char *) mem, mem_length);
12336 }
12337 
12338 static void
12339 mr_data_readmem_nchar (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
12340 {
12341  int mem_length, padding;
12342 
12343  if (mem == NULL)
12344  {
12345  /*
12346  * If we passed in a size, then use it. Otherwise, determine the
12347  * size from the domain.
12348  */
12349  if (size > 0)
12350  {
12351  or_advance (buf, size);
12352  }
12353  else
12354  {
12355  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12356  or_advance (buf, mem_length);
12357  }
12358  }
12359  else
12360  {
12361  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12362 
12363  if (size != -1 && mem_length > size)
12364  {
12366  or_abort (buf);
12367  }
12368  or_get_data (buf, (char *) mem, mem_length);
12369 
12370  /*
12371  * We should only see padding if the string is contained within a packed
12372  * value that had extra padding to ensure alignment. If we see these,
12373  * just pop them out of the buffer. This shouldn't ever happen for
12374  * the "getmem" function, only for the "getval" function.
12375  */
12376  if (size != -1)
12377  {
12378  padding = size - mem_length;
12379  if (padding > 0)
12380  {
12381  or_advance (buf, padding);
12382  }
12383  }
12384  }
12385 }
12386 
12387 static void
12388 mr_freemem_nchar (void *memptr)
12389 {
12390 }
12391 
12392 static void
12393 mr_initval_nchar (DB_VALUE * value, int precision, int scale)
12394 {
12395  db_value_domain_init (value, DB_TYPE_NCHAR, precision, scale);
12396 }
12397 
12398 static int
12399 mr_setval_nchar (DB_VALUE * dest, const DB_VALUE * src, bool copy)
12400 {
12401  int error = NO_ERROR;
12402  int src_precision, src_length;
12403  char *new_;
12404  const char *src_string;
12405 
12406  assert (!db_value_is_corrupted (src));
12407  if (src == NULL || DB_IS_NULL (src))
12408  {
12410  }
12411  else
12412  {
12413  /* Get information from the value */
12414  src_string = db_get_string (src);
12415  src_precision = db_value_precision (src);
12416  src_length = db_get_string_size (src); /* size in bytes */
12417 
12418  db_value_domain_init (dest, DB_TYPE_NCHAR, src_precision, 0);
12419 
12420  /* shouldn't see a NULL string at this point, treat as NULL */
12421  if (src_string != NULL)
12422  {
12423  if (!copy)
12424  {
12425  db_make_nchar (dest, src_precision, src_string, src_length, db_get_string_codeset (src),
12426  db_get_string_collation (src));
12427  }
12428  else
12429  {
12430  /* Check for NTS marker, may not need to do this any more */
12431  if (src_length < 0)
12432  {
12433  src_length = strlen (src_string);
12434  }
12435 
12436  /* make sure the copy gets a NULL terminator */
12437  new_ = (char *) db_private_alloc (NULL, src_length + 1);
12438  if (new_ == NULL)
12439  {
12440  assert (er_errid () != NO_ERROR);
12441  error = er_errid ();
12442  }
12443  else
12444  {
12445  memcpy (new_, src_string, src_length);
12446  new_[src_length] = '\0';
12447  db_make_nchar (dest, src_precision, new_, src_length, db_get_string_codeset (src),
12448  db_get_string_collation (src));
12449  dest->need_clear = true;
12450  }
12451  }
12452  }
12453  }
12454  return error;
12455 }
12456 
12457 
12458 static int
12460 {
12461  return mr_data_lengthval_nchar (value, 1);
12462 }
12463 
12464 static int
12466 {
12467  int packed_length, src_precision;
12468  INTL_CODESET src_codeset = (INTL_CODESET) db_get_string_codeset (value);
12469 
12470  const char *src = db_get_string (value);
12471  if (src == NULL)
12472  {
12473  return 0;
12474  }
12475 
12476  src_precision = db_value_precision (value);
12477  if (!IS_FLOATING_PRECISION (src_precision))
12478  {
12479  /* Would have to check for charset conversion here ! */
12480  packed_length = STR_SIZE (src_precision, src_codeset);
12481  }
12482  else
12483  {
12484  /* Precision is "floating", calculate the effective precision based on the string length. Should be rounding this
12485  * up so it is a proper multiple of the charset width ? */
12486  packed_length = db_get_string_size (value);
12487  if (packed_length < 0)
12488  {
12489  packed_length = strlen (src);
12490  }
12491 
12492 #if !defined (SERVER_MODE)
12493  /*
12494  * If this is a client side string, and the disk representation length
12495  * is requested, Need to return the length of a converted string.
12496  *
12497  * Note: This is only done to support the 'floating precision' style of
12498  * fixed strings. In this case, the string is treated similarly to a
12499  * variable length string.
12500  */
12501  if (!db_on_server && packed_length > 0 && disk && DO_CONVERSION_TO_SRVR_STR (src_codeset))
12502  {
12503  int unconverted;
12504  int char_count = db_get_string_length (value);
12505  char *converted_string = (char *) db_private_alloc (NULL, STR_SIZE (char_count, src_codeset));
12506 
12507  intl_convert_charset ((unsigned char *) src, char_count, src_codeset, (unsigned char *) converted_string,
12508  lang_charset (), &unconverted);
12509 
12510  if (converted_string)
12511  {
12512  intl_char_size ((unsigned char *) converted_string, (char_count - unconverted), src_codeset,
12513  &packed_length);
12514  db_private_free_and_init (NULL, converted_string);
12515  }
12516  }
12517 #endif /* !SERVER_MODE */
12518 
12519  /* add in storage for a size prefix on the packed value. */
12520  packed_length += OR_INT_SIZE;
12521  }
12522 
12523  /*
12524  * NOTE: We do NOT perform padding here, if this is used in the context
12525  * of a packed value, the or_put_value() family of functions must handle
12526  * their own padding, this is because "lengthval" and "writeval" can be
12527  * used to place values into the disk representation of instances and
12528  * there can be no padding in there.
12529  */
12530 
12531  return packed_length;
12532 }
12533 
12534 
12535 static int
12537 {
12538  return mr_writeval_nchar_internal (buf, value, CHAR_ALIGNMENT);
12539 }
12540 
12541 /*
12542  * See commentary in mr_lengthval_nchar.
12543  */
12544 static int
12546 {
12547  return mr_writeval_nchar_internal (buf, value, INT_ALIGNMENT);
12548 }
12549 
12550 static int
12552 {
12553  int src_precision, src_size, packed_size, pad;
12554  const char *src;
12555  INTL_CODESET src_codeset;
12556  int pad_charsize;
12557  char pad_char[2];
12558  char *converted_string = NULL;
12559  int rc = NO_ERROR;
12560 
12561  src = db_get_string (value);
12562  if (src == NULL)
12563  {
12564  return rc;
12565  }
12566 
12567  src_precision = db_value_precision (value);
12568  src_size = db_get_string_size (value); /* size in bytes */
12569  src_codeset = (INTL_CODESET) db_get_string_codeset (value);
12570 
12571  if (src_size < 0)
12572  {
12573  src_size = strlen (src);
12574  }
12575 
12576 #if !defined (SERVER_MODE)
12577  if (!db_on_server && src_size > 0 && DO_CONVERSION_TO_SRVR_STR (src_codeset))
12578  {
12579  int unconverted;
12580  int char_count = db_get_string_length (value);
12581 
12582  converted_string = (char *) db_private_alloc (NULL, STR_SIZE (char_count, src_codeset));
12583  (void) intl_convert_charset ((unsigned char *) src, char_count, src_codeset, (unsigned char *) converted_string,
12584  lang_charset (), &unconverted);
12585  /* Reset the 'src' of the string */
12586  src = converted_string;
12587  src_precision = src_precision - unconverted;
12588  intl_char_size ((unsigned char *) converted_string, (char_count - unconverted), src_codeset, &src_size);
12589  src_codeset = lang_charset ();
12590  }
12591  intl_pad_char (src_codeset, (unsigned char *) pad_char, &pad_charsize);
12592 #else
12593  /*
12594  * (void) lang_srvr_space_char(pad_char, &pad_charsize);
12595  *
12596  * Until this is resolved, set the pad character to be an ASCII space.
12597  */
12598  pad_charsize = 1;
12599  pad_char[0] = ' ';
12600  pad_char[1] = ' ';
12601 #endif
12602 
12603  if (!IS_FLOATING_PRECISION (src_precision))
12604  {
12605  packed_size = STR_SIZE (src_precision, src_codeset);
12606 
12607  if (packed_size < src_size)
12608  {
12609  /* should have caught this by now, truncate silently */
12610  rc = or_put_data (buf, src, packed_size);
12611  }
12612  else
12613  {
12614  if ((rc = or_put_data (buf, src, src_size)) == NO_ERROR)
12615  {
12616  /*
12617  * Check for space padding, if this were a national string, we
12618  * would need to be padding with the appropriate space character!
12619  */
12620  pad = packed_size - src_size;
12621  if (pad)
12622  {
12623  int i;
12624  for (i = src_size; i < packed_size; i += pad_charsize)
12625  {
12626  rc = or_put_byte (buf, pad_char[0]);
12627  if (i + 1 < packed_size && pad_charsize == 2)
12628  {
12629  rc = or_put_byte (buf, pad_char[1]);
12630  }
12631  }
12632  }
12633  }
12634  }
12635  if (rc != NO_ERROR)
12636  {
12637  goto error;
12638  }
12639  }
12640  else
12641  {
12642  /*
12643  * This is a "floating" precision value. Pack what we can based on the
12644  * string size. Note that for this to work, this can only be packed as
12645  * part of a domain tagged value and we must include a size prefix after
12646  * the domain.
12647  */
12648 
12649  /* store the size prefix */
12650  if (align == INT_ALIGNMENT)
12651  {
12652  rc = or_put_int (buf, src_size);
12653  }
12654  else
12655  {
12656  rc = or_put_data (buf, (char *) (&src_size), OR_INT_SIZE);
12657  }
12658 
12659  if (rc == NO_ERROR)
12660  {
12661  /* store the data */
12662  rc = or_put_data (buf, src, src_size);
12663  /* there is no blank padding in this case */
12664  }
12665  }
12666 
12667 error:
12668  if (converted_string)
12669  {
12670  db_private_free_and_init (NULL, converted_string);
12671  }
12672 
12673  return rc;
12674 }
12675 
12676 static int
12677 mr_index_readval_nchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
12678  int copy_buf_len)
12679 {
12680  return mr_readval_nchar_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
12681 }
12682 
12683 static int
12684 mr_data_readval_nchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
12685  int copy_buf_len)
12686 {
12687  return mr_readval_nchar_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
12688 }
12689 
12690 static int
12691 mr_readval_nchar_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
12692  int copy_buf_len, int align)
12693 {
12694  int mem_length, padding;
12695  char *new_;
12696  int rc = NO_ERROR;
12697 
12699  {
12700  assert (false);
12701  return ER_FAILED;
12702  }
12703 
12704  if (IS_FLOATING_PRECISION (domain->precision))
12705  {
12706  if (align == INT_ALIGNMENT)
12707  {
12708  mem_length = or_get_int (buf, &rc);
12709  }
12710  else
12711  {
12712  rc = or_get_data (buf, (char *) (&mem_length), OR_INT_SIZE);
12713  }
12714  if (rc != NO_ERROR)
12715  {
12716  return ER_FAILED;
12717  }
12718 
12719  if (value == NULL)
12720  {
12721  rc = or_advance (buf, mem_length);
12722  }
12723  else if (!copy)
12724  {
12725  db_make_nchar (value, TP_FLOATING_PRECISION_VALUE, buf->ptr, mem_length, TP_DOMAIN_CODESET (domain),
12726  TP_DOMAIN_COLLATION (domain));
12727  value->need_clear = false;
12728  rc = or_advance (buf, mem_length);
12729  }
12730  else
12731  {
12732  if (copy_buf && copy_buf_len >= mem_length + 1)
12733  {
12734  /* read buf image into the copy_buf */
12735  new_ = copy_buf;
12736  }
12737  else
12738  {
12739  /*
12740  * Allocate storage for the string including the kludge NULL
12741  * terminator
12742  */
12743  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
12744  }
12745 
12746  if (new_ == NULL)
12747  {
12748  /* need to be able to return errors ! */
12750  or_abort (buf);
12751 
12752  return ER_FAILED;
12753  }
12754  else
12755  {
12756  rc = or_get_data (buf, new_, mem_length);
12757  if (rc != NO_ERROR)
12758  {
12759  if (new_ != copy_buf)
12760  {
12762  }
12763  return rc;
12764  }
12765  new_[mem_length] = '\0'; /* append the kludge NULL terminator */
12766  db_make_nchar (value, TP_FLOATING_PRECISION_VALUE, new_, mem_length, TP_DOMAIN_CODESET (domain),
12767  TP_DOMAIN_COLLATION (domain));
12768  value->need_clear = (new_ != copy_buf) ? true : false;
12769  }
12770  }
12771  }
12772  else
12773  {
12774  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12775 
12776  if (disk_size != -1 && mem_length > disk_size)
12777  {
12778  /*
12779  * If we're low here, we could just read what we have and make a
12780  * smaller value. Still the domain should match at this point.
12781  */
12783  or_abort (buf);
12784 
12785  return ER_FAILED;
12786  }
12787 
12788  if (value == NULL)
12789  {
12790  rc = or_advance (buf, mem_length);
12791  }
12792  else if (!copy)
12793  {
12794  int str_length;
12795 
12796  intl_char_size ((unsigned char *) buf->ptr, domain->precision, TP_DOMAIN_CODESET (domain), &str_length);
12797  if (str_length == 0)
12798  {
12799  str_length = mem_length;
12800  }
12801  db_make_nchar (value, domain->precision, buf->ptr, str_length, TP_DOMAIN_CODESET (domain),
12802  TP_DOMAIN_COLLATION (domain));
12803  value->need_clear = false;
12804  rc = or_advance (buf, mem_length);
12805  }
12806  else
12807  {
12808  if (copy_buf && copy_buf_len >= mem_length + 1)
12809  {
12810  /* read buf image into the copy_buf */
12811  new_ = copy_buf;
12812  }
12813  else
12814  {
12815  /*
12816  * Allocate storage for the string including the kludge NULL
12817  * terminator
12818  */
12819  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
12820  }
12821 
12822  if (new_ == NULL)
12823  {
12824  /* need to be able to return errors ! */
12825  db_value_domain_init (value, TP_DOMAIN_TYPE (domain), domain->precision, 0);
12826  or_abort (buf);
12827 
12828  return ER_FAILED;
12829  }
12830  else
12831  {
12832  int actual_size = 0;
12833 
12834  rc = or_get_data (buf, new_, mem_length);
12835  if (rc != NO_ERROR)
12836  {
12837  if (new_ != copy_buf)
12838  {
12840  }
12841 
12842  return rc;
12843  }
12844  intl_char_size ((unsigned char *) new_, domain->precision, TP_DOMAIN_CODESET (domain), &actual_size);
12845  if (actual_size == 0)
12846  {
12847  actual_size = mem_length;
12848  }
12849  new_[actual_size] = '\0'; /* append the kludge NULL terminator */
12850  db_make_nchar (value, domain->precision, new_, actual_size, TP_DOMAIN_CODESET (domain),
12851  TP_DOMAIN_COLLATION (domain));
12852  value->need_clear = (new_ != copy_buf) ? true : false;
12853  }
12854  }
12855 
12856  if (rc == NO_ERROR)
12857  {
12858  /* We should only see padding if the string is contained within a packed value that had extra padding to
12859  * ensure alignment. If we see these, just pop them out of the buffer. */
12860  if (disk_size != -1)
12861  {
12862  padding = disk_size - mem_length;
12863  if (padding > 0)
12864  {
12865  rc = or_advance (buf, padding);
12866  }
12867  }
12868  }
12869  }
12870 
12871  /* Check if conversion needs to be done */
12872 #if !defined (SERVER_MODE)
12873  if (value && !db_on_server && DO_CONVERSION_TO_SQLTEXT (TP_DOMAIN_CODESET (domain)) && !DB_IS_NULL (value))
12874  {
12875  int unconverted;
12876  int char_count;
12877  const char *temp_string = db_get_nchar (value, &char_count);
12878 
12879  if (char_count > 0)
12880  {
12881  new_ = (char *) db_private_alloc (NULL, STR_SIZE (char_count, TP_DOMAIN_CODESET (domain)));
12882  (void) intl_convert_charset ((unsigned char *) temp_string, char_count, TP_DOMAIN_CODESET (domain),
12883  (unsigned char *) new_, LANG_SYS_CODESET, &unconverted);
12884  db_value_clear (value);
12885  db_make_nchar (value, domain->precision, new_, STR_SIZE (char_count, TP_DOMAIN_CODESET (domain)),
12886  TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain));
12887  value->need_clear = true;
12888  }
12889  }
12890 #endif /* !SERVER_MODE */
12891 
12892  return rc;
12893 }
12894 
12896 mr_index_cmpdisk_nchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
12897 {
12898  assert (domain != NULL);
12899 
12900  return mr_cmpdisk_nchar_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, CHAR_ALIGNMENT);
12901 }
12902 
12904 mr_data_cmpdisk_nchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
12905 {
12906  assert (domain != NULL);
12907 
12908  return mr_cmpdisk_nchar_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, INT_ALIGNMENT);
12909 }
12910 
12912 mr_cmpdisk_nchar_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
12913  int *start_colp, int align)
12914 {
12916  int mem_length1, mem_length2, strc;
12917 
12918  if (IS_FLOATING_PRECISION (domain->precision))
12919  {
12920  /*
12921  * This is only allowed if we're unpacking a "floating" domain CHAR(n) in
12922  * which case there will be a byte size prefix.
12923  */
12924  if (align == INT_ALIGNMENT)
12925  {
12926  mem_length1 = OR_GET_INT (mem1);
12927  mem_length2 = OR_GET_INT (mem2);
12928  }
12929  else
12930  {
12931  memcpy (&mem_length1, mem1, OR_INT_SIZE);
12932  memcpy (&mem_length2, mem2, OR_INT_SIZE);
12933  }
12934  mem1 = (char *) mem1 + OR_INT_SIZE;
12935  mem2 = (char *) mem2 + OR_INT_SIZE;
12936  }
12937  else
12938  {
12939  mem_length1 = mem_length2 = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
12940  }
12941 
12942  strc = QSTR_NCHAR_COMPARE (domain->collation_id, (unsigned char *) mem1, mem_length1, (unsigned char *) mem2,
12943  mem_length2, TP_DOMAIN_CODESET (domain), true);
12944  c = MR_CMP_RETURN_CODE (strc);
12945 
12946  return c;
12947 }
12948 
12950 mr_cmpval_nchar (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
12951 {
12953  int strc, size1, size2;
12954 
12955  bool ti = true;
12956  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
12957 
12958  DB_TYPE type1 = (DB_TYPE) value1->domain.char_info.type;
12959  DB_TYPE type2 = (DB_TYPE) value2->domain.char_info.type;
12960 
12961  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
12962  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
12963 
12964  if (string1 == NULL || string2 == NULL || db_get_string_codeset (value1) != db_get_string_codeset (value2))
12965  {
12966  return DB_UNK;
12967  }
12968 
12969  if (collation == -1)
12970  {
12971  assert (false);
12972  return DB_UNK;
12973  }
12974 
12975  size1 = db_get_string_size (value1);
12976  size2 = db_get_string_size (value2);
12977 
12978  /*
12979  * do_coercion = 2:
12980  * from btree compare key
12981  * we need to process the ignore trailing space
12982  */
12983  if (do_coercion == 2)
12984  {
12985  ti = true;
12986  }
12987  /*
12988  * do_coercion = 3:
12989  * from eliminate_duplicated_keys and scan_key_compre
12990  * we need to process enforcing no-ignore-trailing space.
12991  */
12992  else if (do_coercion == 3)
12993  {
12994  ti = false;
12995  }
12996  else if (!ignore_trailing_space &&
12997  (type1 == DB_TYPE_STRING || type1 == DB_TYPE_VARNCHAR || type2 == DB_TYPE_STRING
12998  || type2 == DB_TYPE_VARNCHAR))
12999  {
13000  int i;
13001 
13002  if (type1 == DB_TYPE_CHAR || type1 == DB_TYPE_NCHAR)
13003  {
13004  for (i = size1; i > 1; i--)
13005  {
13006  if (string1[i - 1] != 0x20)
13007  {
13008  break;
13009  }
13010  }
13011  size1 = i;
13012  }
13013 
13014  if (type2 == DB_TYPE_CHAR || type2 == DB_TYPE_NCHAR)
13015  {
13016  for (i = size2; i > 1; i--)
13017  {
13018  if (string2[i - 1] != 0x20)
13019  {
13020  break;
13021  }
13022  }
13023  size2 = i;
13024  }
13025 
13026  ti = false;
13027  }
13028 
13029  strc = QSTR_NCHAR_COMPARE (collation, string1, size1, string2, size2, db_get_string_codeset (value2), ti);
13030  c = MR_CMP_RETURN_CODE (strc);
13031 
13032  return c;
13033 }
13034 
13035 #if defined (ENABLE_UNUSED_FUNCTION)
13036 static int
13037 mr_cmpval_nchar2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order, int *start_colp)
13038 {
13039  int c;
13040  int len1, len2, string_size;
13041 
13042  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
13043  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
13044 
13045  if (string1 == NULL || string2 == NULL)
13046  {
13047  return DB_UNK;
13048  }
13049 
13050  string_size = (int) db_get_string_size (value1);
13051  len1 = MIN (string_size, length);
13052  string_size = (int) db_get_string_size (value2);
13053  len2 = MIN (string_size, length);
13054 
13055  c = nchar_compare (string1, len1, string2, len2, db_get_string_codeset (value2));
13056  c = MR_CMP_RETURN_CODE (c);
13057 
13058  return c;
13059 }
13060 #endif
13061 
13062 
13064  "national character", DB_TYPE_NCHAR, 0, 0, 0, 1,
13084 };
13085 
13087 
13088 /*
13089  * TYPE VARNCHAR
13090  */
13091 
13092 static void
13093 mr_initmem_varnchar (void *mem, TP_DOMAIN * domain)
13094 {
13095  *(char **) mem = NULL;
13096 }
13097 
13098 
13099 /*
13100  * The main difference between "memory" strings and "value" strings is that
13101  * the length tag is stored as an in-line prefix in the memory block allocated
13102  * to hold the string characters.
13103  */
13104 static int
13105 mr_setmem_varnchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
13106 {
13107  int error = NO_ERROR;
13108  const char *src;
13109  char *cur, *new_, **mem;
13110  int src_precision, src_length, new_length;
13111 
13112  /* get the current memory contents */
13113  mem = (char **) memptr;
13114  cur = *mem;
13115 
13116  if (value == NULL || (src = db_get_string (value)) == NULL)
13117  {
13118  /* remove the current value */
13119  if (cur != NULL)
13120  {
13122  mr_initmem_varnchar (memptr, domain);
13123  }
13124  }
13125  else
13126  {
13127  /*
13128  * Get information from the value. Ignore precision for the time being
13129  * since we really only care about the byte size of the value for
13130  * varnchar.
13131  * Whether or not the value "fits" should have been checked by now.
13132  */
13133  src_precision = db_value_precision (value);
13134  src_length = db_get_string_size (value); /* size in bytes */
13135  if (src_length < 0)
13136  {
13137  src_length = strlen (src);
13138  }
13139 
13140  /*
13141  * Currently we NULL terminate the workspace string.
13142  * Could try to do the single byte size hack like we have in the
13143  * disk representation.
13144  */
13145  new_length = src_length + sizeof (int) + 1;
13146  new_ = (char *) db_private_alloc (NULL, new_length);
13147  if (new_ == NULL)
13148  {
13149  assert (er_errid () != NO_ERROR);
13150  error = er_errid ();
13151  }
13152  else
13153  {
13154  if (cur != NULL)
13155  {
13157  }
13158 
13159  /* pack in the length prefix */
13160  *(int *) new_ = src_length;
13161  cur = new_ + sizeof (int);
13162  /* store the string */
13163  memcpy (cur, src, src_length);
13164  /* NULL terminate the stored string for safety */
13165  cur[src_length] = '\0';
13166  *mem = new_;
13167  }
13168  }
13169 
13170  return error;
13171 }
13172 
13173 static int
13174 mr_getmem_varnchar (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
13175 {
13176  int error = NO_ERROR;
13177  int mem_length;
13178  char **mem, *cur, *new_;
13179 
13180  /* get to the current value */
13181  mem = (char **) memptr;
13182  cur = *mem;
13183 
13184  if (cur == NULL)
13185  {
13186  db_value_domain_init (value, DB_TYPE_VARNCHAR, domain->precision, 0);
13187  value->need_clear = false;
13188  }
13189  else
13190  {
13191  /* extract the length prefix and the pointer to the actual string data */
13192  mem_length = *(int *) cur;
13193  cur += sizeof (int);
13194 
13196  {
13197  assert (false);
13198  return ER_FAILED;
13199  }
13200 
13201  if (!copy)
13202  {
13203  db_make_varnchar (value, domain->precision, cur, mem_length, TP_DOMAIN_CODESET (domain),
13204  TP_DOMAIN_COLLATION (domain));
13205  value->need_clear = false;
13206  }
13207  else
13208  {
13209  /* return it with a NULL terminator */
13210  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
13211  if (new_ == NULL)
13212  {
13213  assert (er_errid () != NO_ERROR);
13214  error = er_errid ();
13215  }
13216  else
13217  {
13218  memcpy (new_, cur, mem_length);
13219  new_[mem_length] = '\0';
13220  db_make_varnchar (value, domain->precision, new_, mem_length, TP_DOMAIN_CODESET (domain),
13221  TP_DOMAIN_COLLATION (domain));
13222  value->need_clear = true;
13223  }
13224  }
13225  }
13226  return error;
13227 }
13228 
13229 
13230 /*
13231  * For the disk representation, we may be adding pad bytes
13232  * to round up to a word boundary.
13233  *
13234  * NOTE: We are currently adding a NULL terminator to the disk representation
13235  * for some code on the server that still manufactures pointers directly into
13236  * the disk buffer and assumes it is a NULL terminated string. This terminator
13237  * can be removed after the server has been updated. The logic for maintaining
13238  * the terminator is actually in the or_put_varchar, family of functions.
13239  */
13240 static int
13241 mr_data_lengthmem_varnchar (void *memptr, TP_DOMAIN * domain, int disk)
13242 {
13243  char **mem, *cur;
13244  int len;
13245 
13246  len = 0;
13247  if (!disk)
13248  {
13249  len = tp_VarNChar.size;
13250  }
13251  else if (memptr != NULL)
13252  {
13253  mem = (char **) memptr;
13254  cur = *mem;
13255  if (cur != NULL)
13256  {
13257  len = *(int *) cur;
13259  {
13260  /* Skip the length of the string */
13261  len = pr_get_compression_length ((cur + sizeof (int)), len) + PRIM_TEMPORARY_DISK_SIZE;
13263  }
13264  else
13265  {
13266  len = or_packed_varchar_length (len);
13267  }
13268  }
13269  }
13270 
13271  return len;
13272 }
13273 
13274 static int
13275 mr_index_lengthmem_varnchar (void *memptr, TP_DOMAIN * domain)
13276 {
13277  return mr_index_lengthmem_string (memptr, domain);
13278 }
13279 
13280 static void
13281 mr_data_writemem_varnchar (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
13282 {
13283  char **mem, *cur;
13284  int len;
13285 
13286  mem = (char **) memptr;
13287  cur = *mem;
13288  if (cur != NULL)
13289  {
13290  len = *(int *) cur;
13291  cur += sizeof (int);
13292  or_packed_put_varchar (buf, cur, len);
13293  }
13294 }
13295 
13296 
13297 /*
13298  * The amount of memory requested is currently calculated based on the
13299  * stored size prefix. If we ever go to a system where we avoid storing
13300  * the size, then we could use the size argument passed in to this function
13301  * but that may also include any padding byte that added to bring us up to
13302  * a word boundary. Might want some way to determine which bytes at the
13303  * end of a string are padding.
13304  */
13305 static void
13306 mr_data_readmem_varnchar (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
13307 {
13308  return mr_data_readmem_string (buf, memptr, domain, size);
13309 }
13310 
13311 static void
13312 mr_freemem_varnchar (void *memptr)
13313 {
13314  char *cur;
13315 
13316  if (memptr != NULL)
13317  {
13318  cur = *(char **) memptr;
13319  if (cur != NULL)
13320  {
13322  }
13323  }
13324 }
13325 
13326 static void
13327 mr_initval_varnchar (DB_VALUE * value, int precision, int scale)
13328 {
13329  db_make_varnchar (value, precision, NULL, 0, LANG_SYS_CODESET, LANG_SYS_COLLATION);
13330  value->need_clear = false;
13331 }
13332 
13333 static int
13334 mr_setval_varnchar (DB_VALUE * dest, const DB_VALUE * src, bool copy)
13335 {
13336  int error = NO_ERROR;
13337  int src_precision, src_length;
13338  char *new_;
13339  const char *src_str;
13340 
13341  assert (!db_value_is_corrupted (src));
13342  if (src == NULL || DB_IS_NULL (src))
13343  {
13345  }
13346  else if ((src_str = db_get_string (src)) == NULL)
13347  {
13348  error = db_value_domain_init (dest, DB_TYPE_VARNCHAR, db_value_precision (src), 0);
13349  }
13350  else
13351  {
13352  /* Get information from the value. */
13353  src_precision = db_value_precision (src);
13354  src_length = db_get_string_size (src);
13355  if (src_length < 0)
13356  {
13357  src_length = strlen (src_str);
13358  }
13359 
13360  /* should we be paying attention to this? it is extremely dangerous */
13361  if (!copy)
13362  {
13363  error = db_make_varnchar (dest, src_precision, src_str, src_length, db_get_string_codeset (src),
13364  db_get_string_collation (src));
13365  }
13366  else
13367  {
13368  new_ = (char *) db_private_alloc (NULL, src_length + 1);
13369  if (new_ == NULL)
13370  {
13371  db_value_domain_init (dest, DB_TYPE_VARNCHAR, src_precision, 0);
13372  assert (er_errid () != NO_ERROR);
13373  error = er_errid ();
13374  }
13375  else
13376  {
13377  memcpy (new_, src_str, src_length);
13378  new_[src_length] = '\0';
13379  db_make_varnchar (dest, src_precision, new_, src_length, db_get_string_codeset (src),
13380  db_get_string_collation (src));
13381  dest->need_clear = true;
13382  }
13383 
13384  if (src->data.ch.medium.compressed_buf == NULL)
13385  {
13386  dest->data.ch.medium.compressed_buf = NULL;
13387  dest->data.ch.info.compressed_need_clear = false;
13388  }
13389  else
13390  {
13391  char *new_compressed_buf = (char *) db_private_alloc (NULL, src->data.ch.medium.compressed_size + 1);
13392  if (new_compressed_buf == NULL)
13393  {
13394  db_value_domain_init (dest, DB_TYPE_VARNCHAR, src_precision, 0);
13395  assert (er_errid () != NO_ERROR);
13396  error = er_errid ();
13397  }
13398  else
13399  {
13400  memcpy (new_compressed_buf, src->data.ch.medium.compressed_buf, src->data.ch.medium.compressed_size);
13401  new_compressed_buf[src->data.ch.medium.compressed_size] = '\0';
13402  dest->data.ch.medium.compressed_buf = new_compressed_buf;
13403  dest->data.ch.info.compressed_need_clear = true;
13404  }
13405  }
13406 
13408  }
13409  }
13410 
13411  return error;
13412 }
13413 
13414 static int
13416 {
13418 }
13419 
13420 static int
13422 {
13423  return mr_writeval_varnchar_internal (buf, value, CHAR_ALIGNMENT);
13424 }
13425 
13426 static int
13427 mr_index_readval_varnchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
13428  int copy_buf_len)
13429 {
13430  return mr_readval_varnchar_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
13431 }
13432 
13433 static int
13435 {
13436  return mr_lengthval_varnchar_internal (value, disk, INT_ALIGNMENT);
13437 }
13438 
13439 static int
13441 {
13442  return mr_writeval_varnchar_internal (buf, value, INT_ALIGNMENT);
13443 }
13444 
13445 static int
13446 mr_data_readval_varnchar (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
13447  int copy_buf_len)
13448 {
13449  return mr_readval_varnchar_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
13450 }
13451 
13452 /*
13453  * Ignoring precision as byte size is really the only important thing for
13454  * varnchar.
13455  */
13456 static int
13458 {
13459  int src_size, len, rc = NO_ERROR;
13460  const char *str;
13461  bool is_temporary_data = false;
13462  int compressed_size = 0;
13463 
13464 #if !defined (SERVER_MODE)
13465  INTL_CODESET src_codeset;
13466 #endif
13467 
13468  len = 0;
13469  if (value != NULL && (str = db_get_string (value)) != NULL)
13470  {
13471  src_size = db_get_string_size (value); /* size in bytes */
13472  if (src_size < 0)
13473  {
13474  src_size = strlen (str);
13475  }
13476 
13477  /* Test and try compression. */
13478  if (!DB_TRIED_COMPRESSION (value))
13479  {
13480  /* It means that the value has never passed through a compression process. */
13481  rc = pr_do_db_value_string_compression (value);
13482  }
13483  /* We are now sure that the value has been through the process of compression */
13484  compressed_size = db_get_compressed_size (value);
13485  /* If the compression was successful, then we use the compression size value */
13486  if (compressed_size > 0)
13487  {
13488  /* Compression successful so we use the compressed_size from the value. */
13489  len = compressed_size + PRIM_TEMPORARY_DISK_SIZE;
13490  is_temporary_data = true;
13491  }
13492  else
13493  {
13494  /* Compression failed so we use the uncompressed size of the value. */
13495  len = src_size;
13496  }
13497 
13498  if (len >= OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION && is_temporary_data == false)
13499  {
13500  /* The compression failed but the size of the string calls for the new encoding. */
13501  len += PRIM_TEMPORARY_DISK_SIZE;
13502  is_temporary_data = true;
13503  }
13504 
13505 #if !defined (SERVER_MODE)
13506  src_codeset = (INTL_CODESET) db_get_string_codeset (value);
13507 
13508  /*
13509  * If this is a client side string, and the disk representation length
13510  * is requested, Need to return the length of a converted string.
13511  */
13512  if (!db_on_server && src_size > 0 && disk && DO_CONVERSION_TO_SRVR_STR (src_codeset))
13513  {
13514  int unconverted;
13515  int char_count = db_get_string_length (value);
13516  char *converted_string = (char *) db_private_alloc (NULL, STR_SIZE (char_count, src_codeset));
13517 
13518  intl_convert_charset ((unsigned char *) str, char_count, src_codeset, (unsigned char *) converted_string,
13519  lang_charset (), &unconverted);
13520 
13521  if (converted_string)
13522  {
13523  intl_char_size ((unsigned char *) converted_string, (char_count - unconverted), src_codeset, &len);
13524  db_private_free_and_init (NULL, converted_string);
13525  }
13526  }
13527 #endif
13528  if (align == INT_ALIGNMENT)
13529  {
13530  len = or_packed_varchar_length (len);
13531  }
13532  else
13533  {
13534  len = or_varchar_length (len);
13535  }
13536  }
13537 
13538  if (is_temporary_data == true)
13539  {
13540  len -= PRIM_TEMPORARY_DISK_SIZE;
13541  }
13542 
13543  return len;
13544 }
13545 
13546 static int
13548 {
13549  int src_size, size, compressed_size;
13550  INTL_CODESET src_codeset;
13551  const char *str, *string;
13552  char *compressed_string;
13553  int rc = NO_ERROR;
13554 
13555  if (value != NULL && (str = db_get_string (value)) != NULL)
13556  {
13557  src_size = db_get_string_size (value); /* size in bytes */
13558  if (src_size < 0)
13559  {
13560  src_size = strlen (str);
13561  }
13562 
13563  src_codeset = (INTL_CODESET) db_get_string_codeset (value);
13564 #if !defined (SERVER_MODE)
13565  if (!db_on_server && src_size > 0 && DO_CONVERSION_TO_SRVR_STR (src_codeset))
13566  {
13567  int unconverted;
13568  int char_count = db_get_string_length (value);
13569  char *converted_string = (char *) db_private_alloc (NULL, STR_SIZE (char_count, src_codeset));
13570 
13571  (void) intl_convert_charset (REINTERPRET_CAST (const unsigned char *, str), char_count, src_codeset,
13572  (unsigned char *) converted_string, lang_charset (), &unconverted);
13573 
13574  if (converted_string)
13575  {
13576  intl_char_size ((unsigned char *) converted_string, (char_count - unconverted), src_codeset, &src_size);
13577  if (align == INT_ALIGNMENT)
13578  {
13579  or_packed_put_varchar (buf, converted_string, src_size);
13580  }
13581  else
13582  {
13583  or_put_varchar (buf, converted_string, src_size);
13584  }
13585  db_private_free_and_init (NULL, converted_string);
13586  return rc;
13587  }
13588  }
13589 #endif /* !SERVER_MODE */
13590 
13591  if (!DB_TRIED_COMPRESSION (value))
13592  {
13593  /* Check for previous compression. */
13594  rc = pr_do_db_value_string_compression (value);
13595  }
13596 
13597  if (rc != NO_ERROR)
13598  {
13599  return rc;
13600  }
13601 
13602  compressed_size = db_get_compressed_size (value);
13603  compressed_string = DB_GET_COMPRESSED_STRING (value);
13604 
13605  if (compressed_size == DB_UNCOMPRESSABLE && src_size < OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
13606  {
13607  rc = pr_write_uncompressed_string_to_buffer (buf, str, src_size, align);
13608  }
13609  else
13610  {
13611  /* String has been prompted to compression before. */
13612  assert (compressed_size != DB_NOT_YET_COMPRESSED);
13613  if (compressed_string == NULL)
13614  {
13615  assert (compressed_size == DB_UNCOMPRESSABLE);
13616  string = value->data.ch.medium.buf;
13617  }
13618  else
13619  {
13620  assert (compressed_size > 0);
13621  string = compressed_string;
13622  }
13623  if (compressed_size == DB_UNCOMPRESSABLE)
13624  {
13625  size = 0;
13626  }
13627  else
13628  {
13629  size = compressed_size;
13630  }
13631  rc = pr_write_compressed_string_to_buffer (buf, string, size, src_size, align);
13632  }
13633  }
13634 
13635  return rc;
13636 }
13637 
13638 static int
13639 mr_readval_varnchar_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
13640  int copy_buf_len, int align)
13641 {
13642  int pad, precision;
13643 #if !defined (SERVER_MODE)
13644  INTL_CODESET codeset;
13645 #endif
13646  char *new_ = NULL, *start = NULL, *string = NULL, *compressed_string = NULL;
13647  int str_length, expected_decompressed_size = 0, compressed_size = 0;
13648  char *decompressed_string = NULL;
13649  int rc = NO_ERROR;
13650  bool compressed_need_clear = false;
13651 
13652  if (value == NULL)
13653  {
13654  if (size == -1)
13655  {
13656  rc = or_skip_varchar (buf, align);
13657  }
13658  else
13659  {
13660  if (size)
13661  {
13662  rc = or_advance (buf, size);
13663  }
13664  }
13665  }
13666  else
13667  {
13668  if (domain != NULL)
13669  {
13670  precision = domain->precision;
13671 #if !defined (SERVER_MODE)
13672  codeset = TP_DOMAIN_CODESET (domain);
13673 #endif
13674  }
13675  else
13676  {
13677  precision = DB_MAX_VARNCHAR_PRECISION;
13678 #if !defined (SERVER_MODE)
13679  codeset = LANG_SYS_CODESET;
13680 #endif
13681  }
13682 
13683  if (size == 0)
13684  {
13685  /* its NULL */
13686  db_value_domain_init (value, DB_TYPE_VARNCHAR, precision, 0);
13687  }
13688  /* Branch according to convention based on size */
13689  else if (!copy)
13690  {
13692  {
13693  assert (false);
13694  return ER_FAILED;
13695  }
13696 
13697  /* Get the decompressed and compressed size of the string stored in buffer.
13698  * If compressed_size is set to -1, then the string is not compressed at all.
13699  * If compressed_size is set to 0, the string was attempted to be compressed, however it failed.
13700  */
13701  rc = or_get_varchar_compression_lengths (buf, &compressed_size, &expected_decompressed_size);
13702  if (rc != NO_ERROR)
13703  {
13704  return rc;
13705  }
13706 
13707  if (compressed_size > 0)
13708  {
13709  str_length = compressed_size;
13710  string = (char *) db_private_alloc (NULL, expected_decompressed_size + 1);
13711  if (string == NULL)
13712  {
13714  expected_decompressed_size * sizeof (char));
13716  return rc;
13717  }
13718 
13719  start = buf->ptr;
13720 
13721  /* Getting data from the buffer. */
13722  rc = pr_get_compressed_data_from_buffer (buf, string, compressed_size, expected_decompressed_size);
13723 
13724  if (rc != NO_ERROR)
13725  {
13726  goto cleanup;
13727  }
13728  string[expected_decompressed_size] = '\0';
13729  db_make_varnchar (value, precision, string, expected_decompressed_size, TP_DOMAIN_CODESET (domain),
13730  TP_DOMAIN_COLLATION (domain));
13731  value->need_clear = true;
13732 
13733  compressed_string = (char *) db_private_alloc (NULL, compressed_size + 1);
13734  if (compressed_string == NULL)
13735  {
13737  (compressed_size + 1) * sizeof (char));
13739  goto cleanup;
13740  }
13741 
13742  memcpy (compressed_string, start, compressed_size);
13743  compressed_string[compressed_size] = '\0';
13744  compressed_need_clear = true;
13745  }
13746  else
13747  {
13748  /* If there is no decompression, then buf->ptr points to the data stored in buffer. */
13749  str_length = expected_decompressed_size;
13750  db_make_varnchar (value, precision, buf->ptr, expected_decompressed_size, TP_DOMAIN_CODESET (domain),
13751  TP_DOMAIN_COLLATION (domain));
13752  value->need_clear = false;
13753  compressed_size = DB_UNCOMPRESSABLE;
13754  }
13755 
13756  db_set_compressed_string (value, compressed_string, compressed_size, compressed_need_clear);
13757 
13758  or_skip_varchar_remainder (buf, str_length, align);
13759  }
13760  else
13761  {
13762  /* copy == true */
13763  assert (size != 0);
13764 
13765  if (size == -1)
13766  {
13767  /* Standard packed varnchar with a size prefix */
13768  ; /* do nothing */
13769  }
13770  else
13771  { /* size != -1 */
13772  /* Standard packed varnchar within an area of fixed size, usually this means we're looking at the
13773  * disk representation of an attribute. Just like the -1 case except we advance past the additional
13774  * padding. */
13775  start = buf->ptr;
13776  } /* size != -1 */
13777 
13778  rc = or_get_varchar_compression_lengths (buf, &compressed_size, &expected_decompressed_size);
13779  if (rc != NO_ERROR)
13780  {
13781  return ER_FAILED;
13782  }
13783 
13784  if (compressed_size <= 0)
13785  {
13786  assert (compressed_size == 0);
13787  str_length = expected_decompressed_size;
13788  }
13789  else
13790  {
13791  str_length = compressed_size;
13792  }
13793 
13794  if (copy_buf && copy_buf_len >= str_length + 1)
13795  {
13796  /* read buf image into the copy_buf */
13797  new_ = copy_buf;
13798  }
13799  else
13800  {
13801  /*
13802  * Allocate storage for the string including the kludge
13803  * NULL terminator
13804  */
13805  new_ = (char *) db_private_alloc (NULL, str_length + 1);
13806  }
13807 
13808  if (new_ == NULL)
13809  {
13810  /* need to be able to return errors ! */
13811  if (domain)
13812  {
13814  }
13815  or_abort (buf);
13816  return ER_FAILED;
13817  }
13818  else
13819  {
13820  if (align == INT_ALIGNMENT)
13821  {
13822  /* read the kludge NULL terminator */
13823  rc = or_get_data (buf, new_, str_length + 1);
13824  if (rc == NO_ERROR)
13825  {
13826  /* round up to a word boundary */
13827  rc = or_get_align32 (buf);
13828  }
13829  }
13830  else
13831  {
13832  rc = or_get_data (buf, new_, str_length);
13833  }
13834 
13835  if (rc != NO_ERROR)
13836  {
13837  if (new_ != copy_buf)
13838  {
13840  }
13841  return ER_FAILED;
13842  }
13843 
13844  if (compressed_size > 0)
13845  {
13846  /* String was compressed */
13847  int decompressed_size = 0;
13848 
13849  assert (expected_decompressed_size > 0);
13850 
13851  /* Handle decompression */
13852  decompressed_string = (char *) db_private_alloc (NULL, expected_decompressed_size + 1);
13853 
13854  if (decompressed_string == NULL)
13855  {
13857  (size_t) expected_decompressed_size * sizeof (char));
13859  goto cleanup;
13860  }
13861 
13862  /* decompressing the string */
13863  decompressed_size =
13864  LZ4_decompress_safe (new_, decompressed_string, compressed_size, expected_decompressed_size);
13865  if (decompressed_size < 0)
13866  {
13869  goto cleanup;
13870  }
13871 
13872  assert (decompressed_size == expected_decompressed_size);
13873 
13874  /* The compressed string stored in buf is now decompressed in decompressed_string
13875  * and is needed now to be copied over new_. */
13876 
13877  compressed_string = (char *) db_private_alloc (NULL, compressed_size + 1);
13878  if (compressed_string == NULL)
13879  {
13881  (size_t) (compressed_size + 1) * sizeof (char));
13883  goto cleanup;
13884  }
13885 
13886  memcpy (compressed_string, new_, compressed_size);
13887  compressed_string[compressed_size] = '\0';
13888  compressed_need_clear = true;
13889 
13890  if (new_ != copy_buf)
13891  {
13893  }
13894 
13895  new_ = decompressed_string;
13896  str_length = expected_decompressed_size;
13897  }
13898 
13900  {
13901  rc = ER_FAILED;
13902  goto cleanup;
13903  }
13904 
13905  new_[str_length] = '\0';
13906  db_make_varnchar (value, precision, new_, str_length, TP_DOMAIN_CODESET (domain),
13907  TP_DOMAIN_COLLATION (domain));
13908  value->need_clear = (new_ != copy_buf) ? true : false;
13909 
13910  if (compressed_string == NULL)
13911  {
13912  compressed_size = DB_UNCOMPRESSABLE;
13913  compressed_need_clear = false;
13914  }
13915 
13916  db_set_compressed_string (value, compressed_string, compressed_size, compressed_need_clear);
13917 
13918  if (size == -1)
13919  {
13920  /* Standard packed varnchar with a size prefix */
13921  ; /* do nothing */
13922  }
13923  else
13924  { /* size != -1 */
13925  /* Standard packed varnchar within an area of fixed size, usually this means we're looking at the
13926  * disk representation of an attribute. Just like the -1 case except we advance past the
13927  * additional padding. */
13928  pad = size - (int) (buf->ptr - start);
13929  if (pad > 0)
13930  {
13931  rc = or_advance (buf, pad);
13932  }
13933  } /* size != -1 */
13934  } /* else if (new_ == NULL) */
13935  }
13936 
13937  /* Check if conversion needs to be done */
13938 #if !defined (SERVER_MODE)
13939  if (!db_on_server && DO_CONVERSION_TO_SQLTEXT (codeset) && !DB_IS_NULL (value))
13940  {
13941  int unconverted;
13942  int char_count;
13943  const char *temp_string = db_get_nchar (value, &char_count);
13944 
13945  if (char_count > 0)
13946  {
13947  new_ = (char *) db_private_alloc (NULL, STR_SIZE (char_count, codeset));
13948  (void) intl_convert_charset ((unsigned char *) temp_string, char_count, codeset, (unsigned char *) new_,
13949  LANG_SYS_CODESET, &unconverted);
13950  db_value_clear (value);
13952  {
13953  rc = ER_FAILED;
13954  goto cleanup;
13955  }
13956  db_make_varnchar (value, precision, new_, STR_SIZE (char_count, codeset), codeset,
13957  TP_DOMAIN_COLLATION (domain));
13958  value->need_clear = true;
13959  }
13960  }
13961 #endif /* !SERVER_MODE */
13962  }
13963 
13964 cleanup:
13965  if (decompressed_string != NULL && rc != NO_ERROR)
13966  {
13967  db_private_free_and_init (NULL, decompressed_string);
13968  }
13969 
13970  if (new_ != NULL && new_ != copy_buf && rc != NO_ERROR)
13971  {
13973  }
13974 
13975  if (rc != NO_ERROR && compressed_string != NULL)
13976  {
13977  db_private_free_and_init (NULL, compressed_string);
13978  }
13979  return rc;
13980 }
13981 
13983 mr_index_cmpdisk_varnchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
13984  int *start_colp)
13985 {
13986  assert (domain != NULL);
13987 
13988  return mr_data_cmpdisk_varnchar (mem1, mem2, domain, do_coercion, total_order, start_colp);
13989 }
13990 
13992 mr_data_cmpdisk_varnchar (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
13993 {
13995  char *str1, *str2;
13996  int str_length1, str1_compressed_length = 0, str1_decompressed_length = 0;
13997  int str_length2, str2_compressed_length = 0, str2_decompressed_length = 0;
13998  OR_BUF buf1, buf2;
13999  char *string1 = NULL, *string2 = NULL;
14000  bool alloced_string1 = false, alloced_string2 = false;
14001  int rc = NO_ERROR;
14002  int strc;
14003 
14004  assert (domain != NULL);
14005 
14006  str1 = (char *) mem1;
14007  str2 = (char *) mem2;
14008 
14009  /* generally, data is short enough */
14010  str_length1 = OR_GET_BYTE (str1);
14011  str_length2 = OR_GET_BYTE (str2);
14013  {
14014  str1 += OR_BYTE_SIZE;
14015  str2 += OR_BYTE_SIZE;
14016  strc = QSTR_NCHAR_COMPARE (domain->collation_id, (unsigned char *) str1, str_length1, (unsigned char *) str2,
14017  str_length2, TP_DOMAIN_CODESET (domain), false);
14018  c = MR_CMP_RETURN_CODE (strc);
14019  return c;
14020  }
14021 
14023  || str_length2 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION);
14024 
14025  /* String 1 */
14026  or_init (&buf1, str1, 0);
14027  if (str_length1 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
14028  {
14029  rc = or_get_varchar_compression_lengths (&buf1, &str1_compressed_length, &str1_decompressed_length);
14030  if (rc != NO_ERROR)
14031  {
14032  goto cleanup;
14033  }
14034 
14035  string1 = (char *) db_private_alloc (NULL, str1_decompressed_length + 1);
14036  if (string1 == NULL)
14037  {
14038  /* Error report */
14039  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, str1_decompressed_length);
14040  goto cleanup;
14041  }
14042  alloced_string1 = true;
14043 
14044  rc = pr_get_compressed_data_from_buffer (&buf1, string1, str1_compressed_length, str1_decompressed_length);
14045  if (rc != NO_ERROR)
14046  {
14047  goto cleanup;
14048  }
14049 
14050  str_length1 = str1_decompressed_length;
14051  string1[str_length1] = '\0';
14052  }
14053  else
14054  {
14055  /* Skip the size byte */
14056  string1 = buf1.ptr + OR_BYTE_SIZE;
14057  }
14058 
14059  if (rc != NO_ERROR)
14060  {
14061  ASSERT_ERROR ();
14062  goto cleanup;
14063  }
14064 
14065  /* String 2 */
14066  or_init (&buf2, str2, 0);
14067  if (str_length2 == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
14068  {
14069  rc = or_get_varchar_compression_lengths (&buf2, &str2_compressed_length, &str2_decompressed_length);
14070  if (rc != NO_ERROR)
14071  {
14072  goto cleanup;
14073  }
14074 
14075  string2 = (char *) db_private_alloc (NULL, str2_decompressed_length + 1);
14076  if (string2 == NULL)
14077  {
14078  /* Error report */
14079  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, str2_decompressed_length);
14080  goto cleanup;
14081  }
14082 
14083  alloced_string2 = true;
14084 
14085  rc = pr_get_compressed_data_from_buffer (&buf2, string2, str2_compressed_length, str2_decompressed_length);
14086  if (rc != NO_ERROR)
14087  {
14088  goto cleanup;
14089  }
14090 
14091  str_length2 = str2_decompressed_length;
14092  string2[str_length2] = '\0';
14093  }
14094  else
14095  {
14096  /* Skip the size byte */
14097  string2 = buf2.ptr + OR_BYTE_SIZE;
14098  }
14099 
14100  if (rc != NO_ERROR)
14101  {
14102  ASSERT_ERROR ();
14103  goto cleanup;
14104  }
14105 
14106  /* Compare the strings */
14107  strc = QSTR_NCHAR_COMPARE (domain->collation_id, (unsigned char *) string1, str_length1, (unsigned char *) string2,
14108  str_length2, TP_DOMAIN_CODESET (domain), false);
14109  c = MR_CMP_RETURN_CODE (strc);
14110  /* Clean up the strings */
14111  if (string1 != NULL && alloced_string1 == true)
14112  {
14113  db_private_free_and_init (NULL, string1);
14114  }
14115 
14116  if (string2 != NULL && alloced_string2 == true)
14117  {
14118  db_private_free_and_init (NULL, string2);
14119  }
14120 
14121  return c;
14122 
14123 cleanup:
14124  if (string1 != NULL && alloced_string1 == true)
14125  {
14126  db_private_free_and_init (NULL, string1);
14127  }
14128 
14129  if (string2 != NULL && alloced_string2 == true)
14130  {
14131  db_private_free_and_init (NULL, string2);
14132  }
14133 
14134  return DB_UNK;
14135 }
14136 
14138 mr_cmpval_varnchar (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
14139  int collation)
14140 {
14142  int strc, size1, size2;
14143 
14144  bool ti = true;
14145  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
14146 
14147  DB_TYPE type1 = (DB_TYPE) value1->domain.char_info.type;
14148  DB_TYPE type2 = (DB_TYPE) value2->domain.char_info.type;
14149 
14150  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
14151  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
14152 
14153  if (string1 == NULL || string2 == NULL || db_get_string_codeset (value1) != db_get_string_codeset (value2))
14154  {
14155  return DB_UNK;
14156  }
14157 
14158  if (collation == -1)
14159  {
14160  assert (false);
14161  return DB_UNK;
14162  }
14163 
14164  size1 = (int) db_get_string_size (value1);
14165  size2 = (int) db_get_string_size (value2);
14166 
14167  if (size1 < 0)
14168  {
14169  size1 = strlen ((char *) string1);
14170  }
14171 
14172  if (size2 < 0)
14173  {
14174  size2 = strlen ((char *) string2);
14175  }
14176 
14177  if (!ignore_trailing_space)
14178  {
14179  int i;
14180 
14181  if (type1 == DB_TYPE_CHAR || type1 == DB_TYPE_NCHAR)
14182  {
14183  for (i = size1; i > 1; i--)
14184  {
14185  if (string1[i - 1] != 0x20)
14186  {
14187  break;
14188  }
14189  }
14190  size1 = i;
14191  }
14192 
14193  if (type2 == DB_TYPE_CHAR || type2 == DB_TYPE_NCHAR)
14194  {
14195  for (i = size2; i > 1; i--)
14196  {
14197  if (string2[i - 1] != 0x20)
14198  {
14199  break;
14200  }
14201  }
14202  size2 = i;
14203  }
14204 
14205  ti = false;
14206  }
14207 
14208  strc = QSTR_NCHAR_COMPARE (collation, string1, size1, string2, size2, db_get_string_codeset (value2), ti);
14209  c = MR_CMP_RETURN_CODE (strc);
14210 
14211  return c;
14212 }
14213 
14214 #if defined (ENABLE_UNUSED_FUNCTION)
14215 static int
14216 mr_cmpval_varnchar2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order,
14217  int *start_colp)
14218 {
14219  int c;
14220  int len1, len2, string_size;
14221 
14222  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
14223  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
14224 
14225  if (string1 == NULL || string2 == NULL)
14226  {
14227  return DB_UNK;
14228  }
14229 
14230  string_size = (int) db_get_string_size (value1);
14231  len1 = MIN (string_size, length);
14232  string_size = (int) db_get_string_size (value2);
14233  len2 = MIN (string_size, length);
14234 
14235  c = varnchar_compare (string1, len1, string2, len2, db_get_string_codeset (value2));
14236  c = MR_CMP_RETURN_CODE (c);
14237 
14238  return c;
14239 }
14240 #endif
14241 
14243  "national character varying", DB_TYPE_VARNCHAR, 1, sizeof (const char *), 0, 1,
14263 };
14264 
14266 
14267 /*
14268  * TYPE BIT
14269  */
14270 
14271 static void
14272 mr_initmem_bit (void *memptr, TP_DOMAIN * domain)
14273 {
14274 #if !defined(NDEBUG)
14275  int mem_length;
14276 
14277  assert (!IS_FLOATING_PRECISION (domain->precision));
14279 
14280  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14281  memset (memptr, 0, mem_length);
14282 #endif
14283 }
14284 
14285 
14286 /*
14287  * Due to the "within tolerance" comparison of domains used for
14288  * assignment validation, we may get values in here whose precision is
14289  * less than the precision of the actual attribute. This prevents
14290  * having to copy a string just to coerce a value into a larger precision.
14291  * Note that the precision of the source value may also come in as -1 here
14292  * which is used to mean a "floating" precision that is assumed to be
14293  * compatible with the destination domain as long as the associated value
14294  * is within tolerance. This case is generally only seen for string
14295  * literals that have been produced by the parser. These literals will
14296  * not contain blank padding and strlen() or db_get_string_size() can be
14297  * used to determine the number of significant characters.
14298  */
14299 static int
14300 mr_setmem_bit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
14301 {
14302  int error = NO_ERROR;
14303  char *mem;
14304  const char *src;
14305  int src_precision, src_length, mem_length, pad;
14306 
14307  if (value == NULL)
14308  {
14309  return NO_ERROR;
14310  }
14311 
14312  /* Get information from the value */
14313  src = db_get_string (value);
14314  src_precision = db_value_precision (value);
14315  src_length = db_get_string_size (value); /* size in bytes */
14316 
14317  if (src == NULL)
14318  {
14319  return NO_ERROR;
14320  }
14321 
14322  /*
14323  * The only thing we really care about at this point, is the byte
14324  * length of the string. The precision could be checked here but it
14325  * really isn't necessary for this operation.
14326  * Calculate the maximum number of bytes we have available here.
14327  */
14329  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14330 
14331  if (mem_length < src_length)
14332  {
14333  /*
14334  * should never get here, this is supposed to be caught during domain
14335  * validation, need a better error message.
14336  */
14337  error = ER_OBJ_DOMAIN_CONFLICT;
14338  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 1, "");
14339  }
14340  else
14341  {
14342  /* copy the value into memory */
14343  mem = (char *) memptr;
14344  memcpy (mem, src, src_length);
14345 
14346  /* Check for padding */
14347  pad = mem_length - src_length;
14348  if (pad)
14349  {
14350  int i;
14351 
14352  for (i = src_length; i < mem_length; i++)
14353  {
14354  mem[i] = '\0';
14355  }
14356  }
14357  }
14358 
14359  return error;
14360 }
14361 
14362 static int
14363 mr_getmem_bit (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
14364 {
14365  int mem_length;
14366  char *new_;
14367 
14369  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14370 
14371  if (!copy)
14372  {
14373  new_ = (char *) mem;
14374  }
14375  else
14376  {
14377  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
14378  if (new_ == NULL)
14379  {
14380  assert (er_errid () != NO_ERROR);
14381  return er_errid ();
14382  }
14383  memcpy (new_, (char *) mem, mem_length);
14384  }
14385 
14386  db_make_bit (value, domain->precision, new_, domain->precision);
14387  if (copy)
14388  {
14389  value->need_clear = true;
14390  }
14391 
14392  return NO_ERROR;
14393 }
14394 
14395 static int
14396 mr_data_lengthmem_bit (void *memptr, TP_DOMAIN * domain, int disk)
14397 {
14398  assert (!IS_FLOATING_PRECISION (domain->precision));
14400 
14401  /* There is no difference between the disk & memory sizes. */
14402  return STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14403 }
14404 
14405 static void
14406 mr_data_writemem_bit (OR_BUF * buf, void *mem, TP_DOMAIN * domain)
14407 {
14408  int mem_length;
14409 
14411  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14412 
14413  /*
14414  * We simply dump the memory image to disk, it will already have been padded.
14415  * If this were a national character string, at this point, we'd have to
14416  * decide now to perform a character set conversion.
14417  */
14418  or_put_data (buf, (char *) mem, mem_length);
14419 }
14420 
14421 static void
14422 mr_data_readmem_bit (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
14423 {
14424  int mem_length, padding;
14425 
14426  if (mem == NULL)
14427  {
14428  /* If we passed in a size, then use it. Otherwise, determine the size from the domain. */
14429  if (size > 0)
14430  {
14431  or_advance (buf, size);
14432  }
14433  else
14434  {
14436  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14437  or_advance (buf, mem_length);
14438  }
14439  }
14440  else
14441  {
14443  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14444  if (size != -1 && mem_length > size)
14445  {
14447  or_abort (buf);
14448  }
14449  or_get_data (buf, (char *) mem, mem_length);
14450 
14451  /*
14452  * We should only see padding if the string is contained within a packed
14453  * value that had extra padding to ensure alignment. If we see these,
14454  * just pop them out of the buffer. This shouldn't ever happen for the
14455  * "getmem" function, only for the "getval" function.
14456  */
14457  if (size != -1)
14458  {
14459  padding = size - mem_length;
14460  if (padding > 0)
14461  {
14462  or_advance (buf, padding);
14463  }
14464  }
14465  }
14466 }
14467 
14468 static void
14469 mr_freemem_bit (void *memptr)
14470 {
14471 }
14472 
14473 static void
14474 mr_initval_bit (DB_VALUE * value, int precision, int scale)
14475 {
14476  db_value_domain_init (value, DB_TYPE_BIT, precision, scale);
14477 }
14478 
14479 static int
14480 mr_setval_bit (DB_VALUE * dest, const DB_VALUE * src, bool copy)
14481 {
14482  int error = NO_ERROR;
14483  int src_precision, src_length, src_number_of_bits = 0;
14484  char *new_ = NULL;
14485  const char *src_string = NULL;
14486 
14487  assert (!db_value_is_corrupted (src));
14488  if (src == NULL || DB_IS_NULL (src))
14489  {
14491  }
14492  else
14493  {
14494  /* Get information from the value */
14495  src_string = db_get_bit (src, &src_number_of_bits);
14496  src_precision = db_value_precision (src);
14497  src_length = db_get_string_size (src); /* size in bytes */
14498 
14499  db_value_domain_init (dest, DB_TYPE_BIT, src_precision, 0);
14500 
14501  /* shouldn't see a NULL string at this point, treat as NULL */
14502  if (src_string != NULL)
14503  {
14504  if (!copy)
14505  {
14506  db_make_bit (dest, src_precision, src_string, src_number_of_bits);
14507  }
14508  else
14509  {
14510 
14511  /* make sure the copy gets a NULL terminator */
14512  new_ = (char *) db_private_alloc (NULL, src_length + 1);
14513  if (new_ == NULL)
14514  {
14515  assert (er_errid () != NO_ERROR);
14516  error = er_errid ();
14517  }
14518  else
14519  {
14520  memcpy (new_, src_string, src_length);
14521  db_make_bit (dest, src_precision, new_, src_number_of_bits);
14522  dest->need_clear = true;
14523  }
14524  }
14525  }
14526  }
14527  return error;
14528 }
14529 
14530 static int
14531 mr_index_lengthmem_bit (void *memptr, TP_DOMAIN * domain)
14532 {
14533  int mem_length;
14534 
14535  assert (!IS_FLOATING_PRECISION (domain->precision) || memptr != NULL);
14537 
14538  if (!IS_FLOATING_PRECISION (domain->precision))
14539  {
14540  mem_length = domain->precision;
14541 
14542  return STR_SIZE (mem_length, TP_DOMAIN_CODESET (domain));
14543  }
14544  else
14545  {
14546  memcpy (&mem_length, memptr, OR_INT_SIZE);
14547 
14548  return STR_SIZE (mem_length, TP_DOMAIN_CODESET (domain)) + OR_INT_SIZE;
14549  }
14550 
14551 }
14552 
14553 static int
14555 {
14556  return mr_data_lengthval_bit (value, 1);
14557 }
14558 
14559 static int
14560 mr_data_lengthval_bit (DB_VALUE * value, int disk)
14561 {
14562  int packed_length, src_precision;
14563 
14564  const char *src = db_get_string (value);
14565  if (src == NULL)
14566  {
14567  return 0;
14568  }
14569 
14570  src_precision = db_value_precision (value);
14571  if (!IS_FLOATING_PRECISION (src_precision))
14572  {
14574  packed_length = STR_SIZE (src_precision, db_get_string_codeset (value));
14575  }
14576  else
14577  {
14578  /*
14579  * Precision is "floating", calculate the effective precision based on the
14580  * string length.
14581  */
14582  packed_length = db_get_string_size (value);
14583 
14584  /* add in storage for a size prefix on the packed value. */
14585  packed_length += OR_INT_SIZE;
14586  }
14587 
14588  /*
14589  * NOTE: We do NOT perform padding here, if this is used in the context
14590  * of a packed value, the or_put_value() family of functions must handle
14591  * their own padding, this is because "lengthval" and "writeval" can be
14592  * used to place values into the disk representation of instances and
14593  * there can be no padding in there.
14594  */
14595 
14596  return packed_length;
14597 }
14598 
14599 
14600 static int
14602 {
14603  return mr_writeval_bit_internal (buf, value, CHAR_ALIGNMENT);
14604 }
14605 
14606 /*
14607  * See commentary in mr_data_lengthval_bit.
14608  */
14609 static int
14611 {
14612  return mr_writeval_bit_internal (buf, value, INT_ALIGNMENT);
14613 }
14614 
14615 static int
14617 {
14618  int src_precision, src_length, packed_length, pad;
14619  const char *src;
14620  int rc = NO_ERROR;
14621 
14622  src = db_get_string (value);
14623  if (src == NULL)
14624  {
14625  return rc;
14626  }
14627 
14628  src_precision = db_value_precision (value);
14629  src_length = db_get_string_size (value); /* size in bytes */
14630 
14631  if (!IS_FLOATING_PRECISION (src_precision))
14632  {
14634  packed_length = STR_SIZE (src_precision, db_get_string_codeset (value));
14635 
14636  if (packed_length < src_length)
14637  {
14638  /* should have caught this by now, truncate silently */
14639  or_put_data (buf, src, packed_length);
14640  }
14641  else
14642  {
14643  rc = or_put_data (buf, src, src_length);
14644  if (rc == NO_ERROR)
14645  {
14646  /* Check for padding */
14647  pad = packed_length - src_length;
14648  if (pad)
14649  {
14650  int i;
14651 
14652  for (i = src_length; i < packed_length; i++)
14653  {
14654  rc = or_put_byte (buf, (int) '\0');
14655  }
14656  }
14657  }
14658  }
14659  }
14660  else
14661  {
14662  /*
14663  * This is a "floating" precision value. Pack what we can based on the
14664  * string size. Note that for this to work, this can only be packed
14665  * as part of a domain tagged value and we must include a length
14666  * prefix after the domain.
14667  */
14668  packed_length = db_get_string_length (value);
14669 
14670  /* store the size prefix */
14671  if (align == INT_ALIGNMENT)
14672  {
14673  rc = or_put_int (buf, packed_length);
14674  }
14675  else
14676  {
14677  rc = or_put_data (buf, (char *) (&packed_length), OR_INT_SIZE);
14678  }
14679 
14680  if (rc == NO_ERROR)
14681  {
14682  /* store the data */
14683  rc = or_put_data (buf, src, BITS_TO_BYTES (packed_length));
14684  /* there is no blank padding in this case */
14685  }
14686  }
14687 
14688  return rc;
14689 }
14690 
14691 static int
14692 mr_index_readval_bit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
14693  int copy_buf_len)
14694 {
14695  return mr_readval_bit_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
14696 }
14697 
14698 static int
14699 mr_data_readval_bit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
14700  int copy_buf_len)
14701 {
14702  return mr_readval_bit_internal (buf, value, domain, disk_size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
14703 }
14704 
14705 static int
14706 mr_readval_bit_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int disk_size, bool copy, char *copy_buf,
14707  int copy_buf_len, int align)
14708 {
14709  int mem_length, padding;
14710  int bit_length;
14711  char *new_;
14712  int rc = NO_ERROR;
14713 
14714  if (IS_FLOATING_PRECISION (domain->precision))
14715  {
14716  if (align == INT_ALIGNMENT)
14717  {
14718  bit_length = or_get_int (buf, &rc);
14719  }
14720  else
14721  {
14722  rc = or_get_data (buf, (char *) (&bit_length), OR_INT_SIZE);
14723  }
14724  if (rc != NO_ERROR)
14725  {
14726  return ER_FAILED;
14727  }
14728 
14729  mem_length = BITS_TO_BYTES (bit_length);
14730  if (value == NULL)
14731  {
14732  rc = or_advance (buf, mem_length);
14733  }
14734  else if (!copy)
14735  {
14736  db_make_bit (value, TP_FLOATING_PRECISION_VALUE, buf->ptr, bit_length);
14737  value->need_clear = false;
14738  rc = or_advance (buf, mem_length);
14739  }
14740  else
14741  {
14742  if (copy_buf && copy_buf_len >= mem_length + 1)
14743  {
14744  /* read buf image into the copy_buf */
14745  new_ = copy_buf;
14746  }
14747  else
14748  {
14749  /*
14750  * Allocate storage for the string including the kludge NULL
14751  * terminator
14752  */
14753  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
14754  }
14755 
14756  if (new_ == NULL)
14757  {
14758  /* need to be able to return errors ! */
14760  or_abort (buf);
14761 
14762  return ER_FAILED;
14763  }
14764  else
14765  {
14766  rc = or_get_data (buf, new_, mem_length);
14767  if (rc != NO_ERROR)
14768  {
14769  if (new_ != copy_buf)
14770  {
14772  }
14773 
14774  return rc;
14775  }
14776  new_[mem_length] = '\0'; /* append the kludge NULL terminator */
14777  db_make_bit (value, TP_FLOATING_PRECISION_VALUE, new_, bit_length);
14778  value->need_clear = (new_ != copy_buf) ? true : false;
14779  }
14780  }
14781  }
14782  else
14783  {
14785  mem_length = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14786 
14787  if (disk_size != -1 && mem_length > disk_size)
14788  {
14789  /*
14790  * If we're low here, we could just read what we have and make a
14791  * smaller value. Still the domain should match at this point.
14792  */
14794  or_abort (buf);
14795 
14796  return ER_FAILED;
14797  }
14798 
14799  if (value == NULL)
14800  {
14801  rc = or_advance (buf, mem_length);
14802  }
14803  else if (!copy)
14804  {
14805  db_make_bit (value, domain->precision, buf->ptr, domain->precision);
14806  value->need_clear = false;
14807  rc = or_advance (buf, mem_length);
14808  }
14809  else
14810  {
14811  if (copy_buf && copy_buf_len >= mem_length + 1)
14812  {
14813  /* read buf image into the copy_buf */
14814  new_ = copy_buf;
14815  }
14816  else
14817  {
14818  /*
14819  * Allocate storage for the string including the kludge NULL
14820  * terminator
14821  */
14822  new_ = (char *) db_private_alloc (NULL, mem_length + 1);
14823  }
14824 
14825  if (new_ == NULL)
14826  {
14827  /* need to be able to return errors ! */
14828  db_value_domain_init (value, TP_DOMAIN_TYPE (domain), domain->precision, 0);
14829  or_abort (buf);
14830 
14831  return ER_FAILED;
14832  }
14833  else
14834  {
14835  rc = or_get_data (buf, new_, mem_length);
14836  if (rc != NO_ERROR)
14837  {
14838  if (new_ != copy_buf)
14839  {
14841  }
14842 
14843  return rc;
14844  }
14845  new_[mem_length] = '\0'; /* append the kludge NULL terminator */
14846  db_make_bit (value, domain->precision, new_, domain->precision);
14847  value->need_clear = (new_ != copy_buf) ? true : false;
14848  }
14849  }
14850  if (rc == NO_ERROR)
14851  {
14852  /*
14853  * We should only see padding if the string is contained within a
14854  * packed value that had extra padding to ensure alignment. If we see
14855  * these, just pop them out of the buffer.
14856  */
14857  if (disk_size != -1)
14858  {
14859  padding = disk_size - mem_length;
14860  if (padding > 0)
14861  {
14862  rc = or_advance (buf, padding);
14863  }
14864  }
14865  }
14866  }
14867 
14868  return rc;
14869 }
14870 
14872 mr_index_cmpdisk_bit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
14873 {
14874  assert (domain != NULL);
14875 
14876  return mr_cmpdisk_bit_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, CHAR_ALIGNMENT);
14877 }
14878 
14880 mr_data_cmpdisk_bit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
14881 {
14882  assert (domain != NULL);
14883 
14884  return mr_cmpdisk_bit_internal (mem1, mem2, domain, do_coercion, total_order, start_colp, INT_ALIGNMENT);
14885 }
14886 
14888 mr_cmpdisk_bit_internal (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp,
14889  int align)
14890 {
14892  int bit_length1, mem_length1, bit_length2, mem_length2, bitc;
14893 
14894  if (IS_FLOATING_PRECISION (domain->precision))
14895  {
14896  if (align == INT_ALIGNMENT)
14897  {
14898  bit_length1 = OR_GET_INT (mem1);
14899  bit_length2 = OR_GET_INT (mem2);
14900  }
14901  else
14902  {
14903  memcpy (&bit_length1, mem1, OR_INT_SIZE);
14904  memcpy (&bit_length2, mem2, OR_INT_SIZE);
14905  }
14906  mem1 = (char *) mem1 + OR_INT_SIZE;
14907  mem_length1 = BITS_TO_BYTES (bit_length1);
14908  mem2 = (char *) mem2 + OR_INT_SIZE;
14909  mem_length2 = BITS_TO_BYTES (bit_length2);
14910  }
14911  else
14912  {
14914  mem_length1 = mem_length2 = STR_SIZE (domain->precision, TP_DOMAIN_CODESET (domain));
14915  }
14916 
14917  bitc = bit_compare ((unsigned char *) mem1, mem_length1, (unsigned char *) mem2, mem_length2);
14918  c = MR_CMP_RETURN_CODE (bitc);
14919 
14920  return c;
14921 }
14922 
14924 mr_cmpval_bit (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
14925 {
14927  int bitc;
14928 
14929  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
14930  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
14931 
14932  if (string1 == NULL || string2 == NULL)
14933  {
14934  return DB_UNK;
14935  }
14936 
14937  bitc = bit_compare (string1, (int) db_get_string_size (value1), string2, (int) db_get_string_size (value2));
14938  c = MR_CMP_RETURN_CODE (bitc);
14939 
14940  return c;
14941 }
14942 
14944 mr_cmpval_bit2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order, int *start_colp)
14945 {
14947  int len1, len2, string_size;
14948  int bitc;
14949 
14950  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
14951  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
14952 
14953  if (string1 == NULL || string2 == NULL)
14954  {
14955  return DB_UNK;
14956  }
14957 
14958  string_size = (int) db_get_string_size (value1);
14959  len1 = MIN (string_size, length);
14960  string_size = (int) db_get_string_size (value2);
14961  len2 = MIN (string_size, length);
14962 
14963  bitc = bit_compare (string1, len1, string2, len2);
14964  c = MR_CMP_RETURN_CODE (bitc);
14965 
14966  return c;
14967 }
14968 
14969 
14971  "bit", DB_TYPE_BIT, 0, 0, 0, 1,
14974  mr_setmem_bit,
14975  mr_getmem_bit,
14976  mr_setval_bit,
14991 };
14992 
14994 
14995 /*
14996  * TYPE VARBIT
14997  */
14998 
14999 static void
15000 mr_initmem_varbit (void *mem, TP_DOMAIN * domain)
15001 {
15002  *(char **) mem = NULL;
15003 }
15004 
15005 
15006 /*
15007  * The main difference between "memory" strings and "value" strings is that
15008  * the length tag is stored as an in-line prefix in the memory block allocated
15009  * to hold the string characters.
15010  */
15011 static int
15012 mr_setmem_varbit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
15013 {
15014  int error = NO_ERROR;
15015  const char *src;
15016  char *cur, *new_, **mem;
15017  int src_precision, src_length, src_length_bits, new_length;
15018 
15019  /* get the current memory contents */
15020  mem = (char **) memptr;
15021  cur = *mem;
15022 
15023  if (value == NULL || (src = db_get_string (value)) == NULL)
15024  {
15025  /* remove the current value */
15026  if (cur != NULL)
15027  {
15029  mr_initmem_varbit (memptr, domain);
15030  }
15031  }
15032  else
15033  {
15034  /*
15035  * Get information from the value. Ignore precision for the time being
15036  * since we really only care about the byte size of the value for varbit.
15037  * Whether or not the value "fits" should have been checked by now.
15038  */
15039  src_precision = db_value_precision (value);
15040  src_length = db_get_string_size (value); /* size in bytes */
15041  src_length_bits = db_get_string_length (value); /* size in bits */
15042 
15043  new_length = src_length + sizeof (int);
15044  new_ = (char *) db_private_alloc (NULL, new_length);
15045  if (new_ == NULL)
15046  {
15047  assert (er_errid () != NO_ERROR);
15048  error = er_errid ();
15049  }
15050  else
15051  {
15052  if (cur != NULL)
15053  {
15055  }
15056 
15057  /* pack in the length prefix */
15058  *(int *) new_ = src_length_bits;
15059  cur = new_ + sizeof (int);
15060  /* store the string */
15061  memcpy (cur, src, src_length);
15062  *mem = new_;
15063  }
15064  }
15065 
15066  return error;
15067 }
15068 
15069 static int
15070 mr_getmem_varbit (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
15071 {
15072  int error = NO_ERROR;
15073  int mem_bit_length;
15074  char **mem, *cur, *new_;
15075 
15076  /* get to the current value */
15077  mem = (char **) memptr;
15078  cur = *mem;
15079 
15080  if (cur == NULL)
15081  {
15082  db_value_domain_init (value, DB_TYPE_VARBIT, domain->precision, 0);
15083  value->need_clear = false;
15084  }
15085  else
15086  {
15087  /* extract the length prefix and the pointer to the actual string data */
15088  mem_bit_length = *(int *) cur;
15089  cur += sizeof (int);
15090 
15091  if (!copy)
15092  {
15093  db_make_varbit (value, domain->precision, cur, mem_bit_length);
15094  value->need_clear = false;
15095  }
15096  else
15097  {
15098  /* return it */
15099  new_ = (char *) db_private_alloc (NULL, BITS_TO_BYTES (mem_bit_length) + 1);
15100  if (new_ == NULL)
15101  {
15102  assert (er_errid () != NO_ERROR);
15103  error = er_errid ();
15104  }
15105  else
15106  {
15107  memcpy (new_, cur, BITS_TO_BYTES (mem_bit_length));
15108  db_make_varbit (value, domain->precision, new_, mem_bit_length);
15109  value->need_clear = true;
15110  }
15111  }
15112  }
15113 
15114  return error;
15115 }
15116 
15117 
15118 /*
15119  * For the disk representation, we may be adding pad bytes
15120  * to round up to a word boundary.
15121  */
15122 static int
15123 mr_data_lengthmem_varbit (void *memptr, TP_DOMAIN * domain, int disk)
15124 {
15125  char **mem, *cur;
15126  int len;
15127 
15128  len = 0;
15129  if (!disk)
15130  {
15131  len = tp_VarBit.size;
15132  }
15133  else if (memptr != NULL)
15134  {
15135  mem = (char **) memptr;
15136  cur = *mem;
15137  if (cur != NULL)
15138  {
15139  len = *(int *) cur;
15140  len = or_packed_varbit_length (len);
15141  }
15142  }
15143 
15144  return len;
15145 }
15146 
15147 static int
15148 mr_index_lengthmem_varbit (void *memptr, TP_DOMAIN * domain)
15149 {
15150  OR_BUF buf;
15151  int bitlen;
15152  int rc = NO_ERROR;
15153 
15154  or_init (&buf, (char *) memptr, -1);
15155 
15156  bitlen = or_get_varbit_length (&buf, &rc);
15157 
15158  return or_varbit_length (bitlen);
15159 }
15160 
15161 static void
15162 mr_data_writemem_varbit (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
15163 {
15164  char **mem, *cur;
15165  int bitlen;
15166 
15167  mem = (char **) memptr;
15168  cur = *mem;
15169  if (cur != NULL)
15170  {
15171  bitlen = *(int *) cur;
15172  cur += sizeof (int);
15173  or_packed_put_varbit (buf, cur, bitlen);
15174  }
15175 }
15176 
15177 
15178 /*
15179  * The amount of memory requested is currently calculated based on the
15180  * stored size prefix. If we ever go to a system where we avoid storing the
15181  * size, then we could use the size argument passed in to this function but
15182  * that may also include any padding byte that added to bring us up to a word
15183  * boundary. Might want some way to determine which bytes at the end of a
15184  * string are padding.
15185  */
15186 static void
15187 mr_data_readmem_varbit (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
15188 {
15189  char **mem, *cur, *new_;
15190  int bit_len;
15191  int mem_length, pad;
15192  char *start;
15193  int rc = NO_ERROR;
15194 
15195  /* Must have an explicit size here - can't be determined from the domain */
15196  if (size < 0)
15197  {
15198  return;
15199  }
15200 
15201  if (memptr == NULL)
15202  {
15203  if (size)
15204  {
15205  or_advance (buf, size);
15206  }
15207  }
15208  else
15209  {
15210  mem = (char **) memptr;
15211  cur = *mem;
15212  /* should we be checking for existing strings ? */
15213 #if 0
15214  if (cur != NULL)
15216 #endif
15217 
15218  new_ = NULL;
15219  if (size)
15220  {
15221  start = buf->ptr;
15222 
15223  /* KLUDGE, we have some knowledge of how the thing is stored here in order have some control over the
15224  * conversion between the packed length prefix and the full word memory length prefix. Might want to put this
15225  * in another specialized or_ function. */
15226 
15227  /* Get just the length prefix. */
15228  bit_len = or_get_varbit_length (buf, &rc);
15229 
15230  /*
15231  * Allocate storage for this string, including our own full word size
15232  * prefix.
15233  */
15234  mem_length = BITS_TO_BYTES (bit_len) + sizeof (int);
15235 
15236  new_ = (char *) db_private_alloc (NULL, mem_length);
15237  if (new_ == NULL)
15238  {
15239  or_abort (buf);
15240  }
15241  else
15242  {
15243  /* store the length in our memory prefix */
15244  *(int *) new_ = bit_len;
15245  cur = new_ + sizeof (int);
15246 
15247  /* read the string */
15248  or_get_data (buf, cur, BITS_TO_BYTES (bit_len));
15249  /* align like or_get_varchar */
15250  or_get_align32 (buf);
15251  }
15252 
15253  /*
15254  * If we were given a size, check to see if for some reason this is
15255  * larger than the already word aligned string that we have now
15256  * extracted. This shouldn't be the case but since we've got a
15257  * length, we may as well obey it.
15258  */
15259  pad = size - (int) (buf->ptr - start);
15260  if (pad > 0)
15261  {
15262  or_advance (buf, pad);
15263  }
15264  }
15265  *mem = new_;
15266  }
15267 }
15268 
15269 static void
15270 mr_freemem_varbit (void *memptr)
15271 {
15272  char *cur;
15273 
15274  if (memptr != NULL)
15275  {
15276  cur = *(char **) memptr;
15277  if (cur != NULL)
15278  {
15280  }
15281  }
15282 }
15283 
15284 static void
15285 mr_initval_varbit (DB_VALUE * value, int precision, int scale)
15286 {
15287  db_make_varbit (value, precision, NULL, 0);
15288  value->need_clear = false;
15289 }
15290 
15291 static int
15292 mr_setval_varbit (DB_VALUE * dest, const DB_VALUE * src, bool copy)
15293 {
15294  int error = NO_ERROR;
15295  int src_precision, src_length, src_bit_length;
15296  char *new_;
15297  const char *src_str;
15298 
15299  assert (!db_value_is_corrupted (src));
15300  if (src == NULL || DB_IS_NULL (src))
15301  {
15303  }
15304  else if ((src_str = db_get_string (src)) == NULL)
15305  {
15306  error = db_value_domain_init (dest, DB_TYPE_VARBIT, db_value_precision (src), 0);
15307  }
15308  else
15309  {
15310  /* Get information from the value. */
15311  src_precision = db_value_precision (src);
15312  src_length = db_get_string_size (src);
15313  src_bit_length = db_get_string_length (src);
15314 
15315  /* should we be paying attention to this? it is extremely dangerous */
15316  if (!copy)
15317  {
15318  error = db_make_varbit (dest, src_precision, src_str, src_bit_length);
15319  }
15320  else
15321  {
15322  new_ = (char *) db_private_alloc (NULL, src_length + 1);
15323  if (new_ == NULL)
15324  {
15325  db_value_domain_init (dest, DB_TYPE_VARBIT, src_precision, 0);
15326  assert (er_errid () != NO_ERROR);
15327  error = er_errid ();
15328  }
15329  else
15330  {
15331  memcpy (new_, src_str, src_length);
15332  db_make_varbit (dest, src_precision, new_, src_bit_length);
15333  dest->need_clear = true;
15334  }
15335  }
15336  }
15337 
15338  return error;
15339 }
15340 
15341 static int
15343 {
15344  return mr_lengthval_varbit_internal (value, 1, CHAR_ALIGNMENT);
15345 }
15346 
15347 static int
15349 {
15350  return mr_writeval_varbit_internal (buf, value, CHAR_ALIGNMENT);
15351 }
15352 
15353 static int
15354 mr_index_readval_varbit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
15355  int copy_buf_len)
15356 {
15357  return mr_readval_varbit_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, CHAR_ALIGNMENT);
15358 }
15359 
15360 static int
15362 {
15363  return mr_lengthval_varbit_internal (value, disk, INT_ALIGNMENT);
15364 }
15365 
15366 static int
15368 {
15369  return mr_writeval_varbit_internal (buf, value, INT_ALIGNMENT);
15370 }
15371 
15372 static int
15373 mr_data_readval_varbit (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
15374  int copy_buf_len)
15375 {
15376  return mr_readval_varbit_internal (buf, value, domain, size, copy, copy_buf, copy_buf_len, INT_ALIGNMENT);
15377 }
15378 
15379 static int
15381 {
15382  int bit_length, len;
15383 
15384  len = 0;
15385  if (value != NULL && db_get_string (value) != NULL)
15386  {
15387  bit_length = db_get_string_length (value); /* size in bits */
15388 
15389  if (align == INT_ALIGNMENT)
15390  {
15391  len = or_packed_varbit_length (bit_length);
15392  }
15393  else
15394  {
15395  len = or_varbit_length (bit_length);
15396  }
15397  }
15398 
15399  return len;
15400 }
15401 
15402 static int
15404 {
15405  int src_bit_length;
15406  const char *str;
15407  int rc = NO_ERROR;
15408 
15409  if (value != NULL && (str = db_get_string (value)) != NULL)
15410  {
15411  src_bit_length = db_get_string_length (value); /* size in bits */
15412 
15413  if (align == INT_ALIGNMENT)
15414  {
15415  rc = or_packed_put_varbit (buf, str, src_bit_length);
15416  }
15417  else
15418  {
15419  rc = or_put_varbit (buf, str, src_bit_length);
15420  }
15421  }
15422 
15423  return rc;
15424 }
15425 
15426 /*
15427  * Size can come in as negative here to create a value with a pointer
15428  * directly to disk.
15429  *
15430  * Note that we have a potential conflict with this as -1 is a valid size
15431  * to use here when the string has been packed with a domain/length prefix
15432  * and we can determine the size from there. In current practice, this
15433  * isn't a problem because due to word alignment, we'll never get a
15434  * negative size here that is greater than -4.
15435  */
15436 static int
15437 mr_readval_varbit_internal (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
15438  int copy_buf_len, int align)
15439 {
15440  int pad, precision;
15441  int str_bit_length, str_length;
15442  char *new_, *start = NULL;
15443  int rc = NO_ERROR;
15444 
15445  if (value == NULL)
15446  {
15447  if (size == -1)
15448  {
15449  rc = or_skip_varbit (buf, align);
15450  }
15451  else
15452  {
15453  if (size)
15454  rc = or_advance (buf, size);
15455  }
15456  }
15457  else
15458  {
15459  if (domain != NULL)
15460  {
15461  precision = domain->precision;
15462  }
15463  else
15464  {
15465  precision = DB_MAX_VARBIT_PRECISION;
15466  }
15467 
15468  if (!copy)
15469  {
15470  str_bit_length = or_get_varbit_length (buf, &rc);
15471  if (rc == NO_ERROR)
15472  {
15473  db_make_varbit (value, precision, buf->ptr, str_bit_length);
15474  value->need_clear = false;
15475  rc = or_skip_varbit_remainder (buf, str_bit_length, align);
15476  }
15477  }
15478  else
15479  {
15480  if (size == 0)
15481  {
15482  /* its NULL */
15483  db_value_domain_init (value, DB_TYPE_VARBIT, precision, 0);
15484  }
15485  else
15486  { /* size != 0 */
15487  if (size == -1)
15488  {
15489  /* Standard packed varbit with a size prefix */
15490  ; /* do nothing */
15491  }
15492  else
15493  { /* size != -1 */
15494  /* Standard packed varbit within an area of fixed size, usually this means we're looking at the disk
15495  * representation of an attribute. Just like the -1 case except we advance past the additional
15496  * padding. */
15497  start = buf->ptr;
15498  } /* size != -1 */
15499 
15500  str_bit_length = or_get_varbit_length (buf, &rc);
15501  if (rc != NO_ERROR)
15502  {
15503  return ER_FAILED;
15504  }
15505  /* get the string byte length */
15506  str_length = BITS_TO_BYTES (str_bit_length);
15507 
15508  if (copy_buf && copy_buf_len >= str_length + 1)
15509  {
15510  /* read buf image into the copy_buf */
15511  new_ = copy_buf;
15512  }
15513  else
15514  {
15515  /*
15516  * Allocate storage for the string including the kludge NULL
15517  * terminator
15518  */
15519  new_ = (char *) db_private_alloc (NULL, str_length + 1);
15520  }
15521 
15522  if (new_ == NULL)
15523  {
15524  /* need to be able to return errors ! */
15525  if (domain)
15526  {
15528  }
15529  or_abort (buf);
15530  return ER_FAILED;
15531  }
15532  else
15533  {
15534  /* do not read the kludge NULL terminator */
15535  rc = or_get_data (buf, new_, str_length);
15536  if (rc == NO_ERROR && align == INT_ALIGNMENT)
15537  {
15538  /* round up to a word boundary */
15539  rc = or_get_align32 (buf);
15540  }
15541 
15542  if (rc != NO_ERROR)
15543  {
15544  if (new_ != copy_buf)
15545  {
15547  }
15548  return ER_FAILED;
15549  }
15550 
15551  new_[str_length] = '\0'; /* append the kludge NULL terminator */
15552  db_make_varbit (value, precision, new_, str_bit_length);
15553  value->need_clear = (new_ != copy_buf) ? true : false;
15554 
15555  if (size == -1)
15556  {
15557  /* Standard packed varbit with a size prefix */
15558  ; /* do nothing */
15559  }
15560  else
15561  { /* size != -1 */
15562  /* Standard packed varbit within an area of fixed size, usually this means we're looking at the
15563  * disk representation of an attribute. Just like the -1 case except we advance past the
15564  * additional padding. */
15565  pad = size - (int) (buf->ptr - start);
15566  if (pad > 0)
15567  {
15568  rc = or_advance (buf, pad);
15569  }
15570  } /* size != -1 */
15571  } /* else */
15572  } /* size != 0 */
15573  }
15574 
15575  }
15576  return rc;
15577 }
15578 
15580 mr_index_cmpdisk_varbit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
15581 {
15582  assert (domain != NULL);
15583 
15584  return mr_data_cmpdisk_varbit (mem1, mem2, domain, do_coercion, total_order, start_colp);
15585 }
15586 
15588 mr_data_cmpdisk_varbit (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
15589 {
15591  int bit_length1, bit_length2;
15592  int mem_length1, mem_length2, bitc;
15593  OR_BUF buf1, buf2;
15594  int error = NO_ERROR;
15595 
15596  assert (domain != NULL);
15597 
15598  or_init (&buf1, (char *) mem1, 0);
15599  bit_length1 = or_get_varbit_length (&buf1, &error);
15600  mem_length1 = BITS_TO_BYTES (bit_length1);
15601  assert (error == NO_ERROR);
15602 
15603  or_init (&buf2, (char *) mem2, 0);
15604  bit_length2 = or_get_varbit_length (&buf2, &error);
15605  mem_length2 = BITS_TO_BYTES (bit_length2);
15606  assert (error == NO_ERROR);
15607 
15608  bitc = varbit_compare ((unsigned char *) buf1.ptr, mem_length1, (unsigned char *) buf2.ptr, mem_length2);
15609  c = MR_CMP_RETURN_CODE (bitc);
15610 
15611  return c;
15612 }
15613 
15615 mr_cmpval_varbit (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
15616  int collation)
15617 {
15619  int bitc;
15620 
15621  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
15622  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
15623 
15624  if (string1 == NULL || string2 == NULL)
15625  {
15626  return DB_UNK;
15627  }
15628 
15629  bitc = varbit_compare (string1, (int) db_get_string_size (value1), string2, (int) db_get_string_size (value2));
15630  c = MR_CMP_RETURN_CODE (bitc);
15631 
15632  return c;
15633 }
15634 
15636 mr_cmpval_varbit2 (DB_VALUE * value1, DB_VALUE * value2, int length, int do_coercion, int total_order, int *start_colp)
15637 {
15639  int len1, len2, string_size;
15640  int bitc;
15641 
15642  const unsigned char *string1 = REINTERPRET_CAST (const unsigned char *, db_get_string (value1));
15643  const unsigned char *string2 = REINTERPRET_CAST (const unsigned char *, db_get_string (value2));
15644 
15645  if (string1 == NULL || string2 == NULL)
15646  {
15647  return DB_UNK;
15648  }
15649 
15650  string_size = (int) db_get_string_size (value1);
15651  len1 = MIN (string_size, length);
15652  string_size = (int) db_get_string_size (value2);
15653  len2 = MIN (string_size, length);
15654 
15655  bitc = varbit_compare (string1, len1, string2, len2);
15656  c = MR_CMP_RETURN_CODE (bitc);
15657 
15658  return c;
15659 }
15660 
15661 
15663  "bit varying", DB_TYPE_VARBIT, 1, sizeof (const char *), 0, 1,
15683 };
15684 
15686 
15687 
15688 static void
15689 mr_initmem_enumeration (void *mem, TP_DOMAIN * domain)
15690 {
15691  *(unsigned short *) mem = 0;
15692 }
15693 
15694 static void
15695 mr_initval_enumeration (DB_VALUE * value, int precision, int scale)
15696 {
15697  db_value_domain_init (value, DB_TYPE_ENUMERATION, precision, scale);
15699 }
15700 
15701 static int
15702 mr_setmem_enumeration (void *mem, TP_DOMAIN * domain, DB_VALUE * value)
15703 {
15704  if (value == NULL)
15705  {
15706  mr_initmem_enumeration (mem, domain);
15707  }
15708  else
15709  {
15710  *(unsigned short *) mem = db_get_enum_short (value);
15711  }
15712 
15713  return NO_ERROR;
15714 }
15715 
15716 static int
15717 mr_getmem_enumeration (void *mem, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
15718 {
15719  unsigned short short_val = 0;
15720 
15721  short_val = *(short *) mem;
15722 
15723  return mr_setval_enumeration_internal (value, domain, short_val, 0, copy, NULL, 0);
15724 }
15725 
15726 static int
15727 mr_setval_enumeration (DB_VALUE * dest, const DB_VALUE * src, bool copy)
15728 {
15729  const char *str = NULL;
15730  bool need_clear = false;
15731 
15732  if (src == NULL || DB_IS_NULL (src))
15733  {
15735  }
15736 
15737  if (db_get_enum_string (src) != NULL)
15738  {
15739  if (copy)
15740  {
15741  char *str_tmp = (char *) db_private_alloc (NULL, db_get_enum_string_size (src) + 1);
15742  if (str_tmp == NULL)
15743  {
15744  assert (er_errid () != NO_ERROR);
15745  return er_errid ();
15746  }
15747  memcpy (str_tmp, db_get_enum_string (src), db_get_enum_string_size (src));
15748  str_tmp[db_get_enum_string_size (src)] = 0;
15749  need_clear = true;
15750  str = str_tmp;
15751  }
15752  else
15753  {
15754  str = db_get_enum_string (src);
15755  }
15756  }
15757 
15758  /* get proper codeset from src */
15760  db_get_enum_collation (src));
15761  dest->need_clear = need_clear;
15762 
15763  return NO_ERROR;
15764 }
15765 
15766 static void
15767 mr_data_writemem_enumeration (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
15768 {
15769  unsigned short *mem = (unsigned short *) memptr;
15770 
15771  or_put_short (buf, *mem);
15772 }
15773 
15774 static void
15775 mr_data_readmem_enumeration (OR_BUF * buf, void *mem, TP_DOMAIN * domain, int size)
15776 {
15777  int rc = NO_ERROR;
15778  if (mem == NULL)
15779  {
15780  or_advance (buf, tp_Enumeration.disksize);
15781  }
15782  else
15783  {
15784  *(unsigned short *) mem = (unsigned short) or_get_short (buf, &rc);
15785  }
15786 }
15787 
15788 /*
15789  * mr_setval_enumeration_internal () - make an enumeration value based on
15790  * index and domain.
15791  * return: NO_ERROR or error code.
15792  * value(in/out):
15793  * domain(in):
15794  * index(in): index of enumeration string
15795  * size(in):
15796  * copy(in):
15797  * copy_buf(in):
15798  * copy_buf_len(in):
15799  */
15800 static int
15801 mr_setval_enumeration_internal (DB_VALUE * value, TP_DOMAIN * domain, unsigned short index, int size, bool copy,
15802  char *copy_buf, int copy_buf_len)
15803 {
15804  bool need_clear = false;
15805  int str_size;
15806  const char *str = NULL;
15807  DB_ENUM_ELEMENT *db_elem = NULL;
15808 
15809  if (domain == NULL || DOM_GET_ENUM_ELEMS_COUNT (domain) == 0 || index == 0 || index == DB_ENUM_OVERFLOW_VAL)
15810  {
15811  db_make_enumeration (value, index, NULL, 0, TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain));
15812  value->need_clear = false;
15813  return NO_ERROR;
15814  }
15815 
15816  if (index > DOM_GET_ENUM_ELEMS_COUNT (domain) && DOM_GET_ENUM_ELEMS_COUNT (domain) > 0)
15817  {
15818  assert (false);
15819  return ER_FAILED;
15820  }
15821 
15822  db_elem = &DOM_GET_ENUM_ELEM (domain, index);
15823  str_size = DB_GET_ENUM_ELEM_STRING_SIZE (db_elem);
15824  if (!copy)
15825  {
15826  str = DB_GET_ENUM_ELEM_STRING (db_elem);
15827  }
15828  else
15829  {
15830  char *str_tmp = NULL;
15831  if (copy_buf && copy_buf_len >= str_size + 1)
15832  {
15833  /* read buf image into the copy_buf */
15834  str_tmp = copy_buf;
15835  need_clear = false;
15836  }
15837  else
15838  {
15839  str_tmp = (char *) db_private_alloc (NULL, str_size + 1);
15840  if (str_tmp == NULL)
15841  {
15842  return ER_FAILED;
15843  }
15844  need_clear = true;
15845  }
15846 
15847  memcpy (str_tmp, DB_GET_ENUM_ELEM_STRING (db_elem), str_size);
15848  str_tmp[str_size] = 0;
15849 
15850  str = str_tmp;
15851  }
15852 
15853  db_make_enumeration (value, index, str, str_size, TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain));
15854  value->need_clear = need_clear;
15855 
15856  return NO_ERROR;
15857 }
15858 
15859 static int
15860 mr_data_readval_enumeration (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
15861  int copy_buf_len)
15862 {
15863  int rc = NO_ERROR;
15864  unsigned short s;
15865 
15866  if (value == NULL)
15867  {
15868  rc = or_advance (buf, tp_Enumeration.disksize);
15869  return rc;
15870  }
15871 
15872  s = (unsigned short) or_get_short (buf, &rc);
15873  if (rc != NO_ERROR)
15874  {
15875  return rc;
15876  }
15877 
15878  return mr_setval_enumeration_internal (value, domain, s, size, copy, copy_buf, copy_buf_len);
15879 }
15880 
15881 static int
15883 {
15884  return or_put_short (buf, db_get_enum_short (value));
15885 }
15886 
15887 static int
15889 {
15890  unsigned short s = db_get_enum_short (value);
15891 
15892  return or_put_data (buf, (char *) (&s), tp_Enumeration.disksize);
15893 }
15894 
15895 static int
15896 mr_index_readval_enumeration (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
15897  int copy_buf_len)
15898 {
15899  int rc = NO_ERROR;
15900  unsigned short s;
15901 
15902  if (value == NULL)
15903  {
15904  rc = or_advance (buf, tp_Enumeration.disksize);
15905  return rc;
15906  }
15907 
15908  rc = or_get_data (buf, (char *) (&s), tp_Enumeration.disksize);
15909  if (rc != NO_ERROR)
15910  {
15911  return rc;
15912  }
15913 
15914  return mr_setval_enumeration_internal (value, domain, s, size, copy, copy_buf, copy_buf_len);
15915 }
15916 
15918 mr_index_cmpdisk_enumeration (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
15919  int *start_colp)
15920 {
15921  unsigned short s1, s2;
15922 
15923  assert (domain != NULL);
15924 
15925  COPYMEM (unsigned short, &s1, mem1);
15926  COPYMEM (unsigned short, &s2, mem2);
15927 
15928  return MR_CMP (s1, s2);
15929 }
15930 
15932 mr_data_cmpdisk_enumeration (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order,
15933  int *start_colp)
15934 {
15935  unsigned short s1, s2;
15936 
15937  assert (domain != NULL);
15938 
15939  s1 = (unsigned short) OR_GET_SHORT (mem1);
15940  s2 = (unsigned short) OR_GET_SHORT (mem2);
15941 
15942  return MR_CMP (s1, s2);
15943 }
15944 
15946 mr_cmpval_enumeration (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp,
15947  int collation)
15948 {
15949  unsigned short s1, s2;
15950 
15951  s1 = db_get_enum_short (value1);
15952  s2 = db_get_enum_short (value2);
15953 
15954  return MR_CMP (s1, s2);
15955 }
15956 
15957 /*
15958  * pr_get_compressed_data_from_buffer () - Uncompresses a data stored in buffer.
15959  *
15960  * return() : NO_ERROR or error code.
15961  * buf(in) : The buffer from which is needed decompression.
15962  * data(out) : The result of the decompression. !!! Needs to be alloc'ed !!!
15963  * compressed_size(in) : The compressed data size.
15964  * expected_decompressed_sizes(in) : The expected uncompressed data size.
15965  */
15966 int
15967 pr_get_compressed_data_from_buffer (struct or_buf *buf, char *data, int compressed_size, int expected_decompressed_size)
15968 {
15969  int rc = NO_ERROR;
15970 
15971  /* Check if the string needs decompression */
15972  if (compressed_size > 0)
15973  {
15974  int decompressed_size = 0;
15975  /* Handle decompression */
15976 
15977  /* decompressing the string */
15978  decompressed_size = LZ4_decompress_safe (buf->ptr, data, compressed_size, expected_decompressed_size);
15979  if (decompressed_size < 0)
15980  {
15983  }
15984 
15985  assert (decompressed_size == expected_decompressed_size);
15986 
15987  data[decompressed_size] = '\0';
15988  }
15989  else
15990  {
15991  /* String is not compressed and buf->ptr is pointing towards an array of chars of length equal to
15992  * decompressed_size */
15993 
15994  rc = or_get_data (buf, data, expected_decompressed_size);
15995  data[expected_decompressed_size] = '\0';
15996  }
15997 
15998  return rc;
15999 }
16000 
16001 /*
16002  * pr_get_compression_length() - Simulate a compression to find its length to be stored on the disk.
16003  *
16004  * return() : The length of the compression, based on the new encoding of varchar.
16005  * If the compression fails, then it returns charlen.
16006  * string(in) : The string to be compressed.
16007  * str_length(in) : The length of the string to be compressed.
16008  */
16009 int
16010 pr_get_compression_length (const char *string, int str_length)
16011 {
16012  char *compressed_string = NULL;
16013  int compressed_length = 0;
16014  int rc = NO_ERROR;
16015  int length = 0, compress_buffer_size;
16016 
16018  if (!pr_Enable_string_compression || str_length > LZ4_MAX_INPUT_SIZE) /* compression is not set */
16019  {
16020  return str_length;
16021  }
16022 
16023  /* Alloc memory for the compressed string */
16024  compress_buffer_size = LZ4_compressBound (str_length);
16025  compressed_string = (char *) malloc (compress_buffer_size);
16026  if (compressed_string == NULL)
16027  {
16028  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) compress_buffer_size);
16029  return str_length;
16030  }
16031 
16032  /* Compress the string */
16033  compressed_length = LZ4_compress_default (string, compressed_string, str_length, compress_buffer_size);
16034  if (compressed_length <= 0)
16035  {
16036  /* We should not be having any kind of errors here. Because if this compression fails, there is not warranty
16037  * that the compression from putting data into buffer will fail as well. This needs to be checked but for now
16038  * we leave it as it is.
16039  */
16043  goto cleanup;
16044  }
16045  assert (compressed_length <= compress_buffer_size);
16046 
16047  if (compressed_length < str_length - 8)
16048  {
16049  /* Compression successful */
16050  length = compressed_length;
16051  }
16052  else
16053  {
16054  /* Compression failed */
16055  length = str_length;
16056  }
16057 
16058 cleanup:
16059 
16060  if (compressed_string != NULL)
16061  {
16062  free_and_init (compressed_string);
16063  }
16064 
16065  return length;
16066 }
16067 
16068 /*
16069  * pr_get_size_and_write_string_to_buffer ()
16070  * : Writes a VARCHAR or VARNCHAR to buffer and gets the correct size on the disk.
16071  *
16072  * buf(out) : Buffer to be written to.
16073  * val_p(in) : Memory area to be written to.
16074  * value(in) : DB_VALUE to be written.
16075  * val_size(out) : Disk size of the DB_VALUE.
16076  * align(in) :
16077  *
16078  * Note:
16079  * We use this to avoid double compression when it is required to have the size of the DB_VALUE, previous
16080  * to the write of the DB_VALUE in the buffer.
16081  */
16082 int
16083 pr_get_size_and_write_string_to_buffer (struct or_buf *buf, char *val_p, DB_VALUE * value, int *val_size, int align)
16084 {
16085  const char *string = NULL, *str = NULL;
16086  char *compressed_string = NULL;
16087  int rc = NO_ERROR, str_length = 0, length = 0;
16088  int compression_length = 0, compress_buffer_size;
16089  bool compressed = false;
16090  int save_error_abort = 0;
16091 
16092  /* Checks to be sure that we have the correct input */
16095 
16096  save_error_abort = buf->error_abort;
16097  buf->error_abort = 0;
16098 
16099  string = db_get_string (value);
16100  str_length = db_get_string_size (value);
16101  *val_size = 0;
16102 
16103  if (!pr_Enable_string_compression || db_get_string_size (value) > LZ4_MAX_INPUT_SIZE) /* compression is not set */
16104  {
16105  length = str_length;
16106  compression_length = 0;
16107  str = string;
16108  goto after_compression;
16109  }
16110 
16111  /* Step 1 : Compress, if possible, the dbvalue */
16112  /* Alloc memory for the compressed string */
16113  compress_buffer_size = LZ4_compressBound (str_length);
16114  compressed_string = (char *) malloc (compress_buffer_size);
16115  if (compressed_string == NULL)
16116  {
16117  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, compress_buffer_size);
16119  goto cleanup;
16120  }
16121 
16122  compression_length = LZ4_compress_default (string, compressed_string, str_length, compress_buffer_size);
16123  if (compression_length <= 0)
16124  {
16125  /* We should not be having any kind of errors here. Because if this compression fails, there is not warranty
16126  * that the compression from putting data into buffer will fail as well. This needs to be checked but for now
16127  * we leave it as it is.
16128  */
16133  goto cleanup;
16134  }
16135  assert (compression_length <= compress_buffer_size);
16136 
16137  if (compression_length < str_length - 8)
16138  {
16139  /* Compression successful */
16140  length = (int) compression_length;
16141  compressed = true;
16142  str = compressed_string;
16143  }
16144  else
16145  {
16146  /* Compression failed */
16147  length = str_length;
16148  compression_length = 0;
16149  str = string;
16150  }
16151 after_compression:
16152  /*
16153  * Step 2 : Compute the disk size of the dbvalue.
16154  * We are sure that the initial string length is greater than 255, which means that the new encoding applies.
16155  */
16156 
16157  switch (DB_VALUE_DOMAIN_TYPE (value))
16158  {
16159  case DB_TYPE_VARCHAR:
16160  case DB_TYPE_VARNCHAR:
16162  break;
16163 
16164  default:
16165  /* It should not happen */
16166  assert (false);
16167  rc = ER_FAILED;
16168  goto cleanup;
16169  }
16170 
16171  /* Step 3 : Insert the disk representation of the dbvalue in the buffer */
16172 
16173  switch (DB_VALUE_DOMAIN_TYPE (value))
16174  {
16175  case DB_TYPE_VARNCHAR:
16176  case DB_TYPE_STRING:
16177  rc = pr_write_compressed_string_to_buffer (buf, str, (int) compression_length, str_length, align);
16178  break;
16179 
16180  default:
16181  /* It should not happen. */
16182  assert (false);
16183  rc = ER_FAILED;
16184  goto cleanup;
16185  }
16186 
16187 cleanup:
16188 
16189  buf->error_abort = save_error_abort;
16190 
16191  if (compressed_string != NULL)
16192  {
16193  free_and_init (compressed_string);
16194  }
16195 
16196  if (rc == ER_TF_BUFFER_OVERFLOW)
16197  {
16198  return or_overflow (buf);
16199  }
16200 
16201  return rc;
16202 }
16203 
16204 /* pr_write_compressed_string_to_buffer() : Similar function to the previous implementation of
16205  * or_put_varchar_internal.
16206  *
16207  * buf(in/out) : Buffer to be written the string.
16208  * compressed_string(in) : The string to be written.
16209  * compressed_length(in) : Compressed length of the string. If it is 0, then no
16210  * compression happened.
16211  * decompressed_length(in) : Decompressed length of the string.
16212  * align(in) :
16213  */
16214 
16215 static int
16216 pr_write_compressed_string_to_buffer (OR_BUF * buf, const char *compressed_string, int compressed_length,
16217  int decompressed_length, int align)
16218 {
16219  int storage_length = 0;
16220  int rc = NO_ERROR;
16221 
16222  assert (decompressed_length >= OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION
16223  && (compressed_length <= 0 || decompressed_length <= LZ4_MAX_INPUT_SIZE));
16224 
16225  /* store the size prefix */
16226  rc = or_put_byte (buf, 0xFF);
16227  if (rc != NO_ERROR)
16228  {
16229  return rc;
16230  }
16231 
16232  /* Store the compressed size */
16233  OR_PUT_INT (&storage_length, compressed_length);
16234  rc = or_put_data (buf, (char *) &storage_length, OR_INT_SIZE);
16235  if (rc != NO_ERROR)
16236  {
16237  return rc;
16238  }
16239 
16240  /* Store the decompressed size */
16241  OR_PUT_INT (&storage_length, decompressed_length);
16242  rc = or_put_data (buf, (char *) &storage_length, OR_INT_SIZE);
16243  if (rc != NO_ERROR)
16244  {
16245  return rc;
16246  }
16247 
16248  /* Get the string disk size */
16249  if (compressed_length > 0)
16250  {
16251  storage_length = compressed_length;
16252  }
16253  else
16254  {
16255  storage_length = decompressed_length;
16256  }
16257 
16258  /* store the string bytes */
16259  rc = or_put_data (buf, compressed_string, storage_length);
16260  if (rc != NO_ERROR)
16261  {
16262  return rc;
16263  }
16264 
16265  if (align == INT_ALIGNMENT)
16266  {
16267  /* kludge, temporary NULL terminator */
16268  rc = or_put_byte (buf, 0);
16269  if (rc != NO_ERROR)
16270  {
16271  return rc;
16272  }
16273 
16274  /* round up to a word boundary */
16275  rc = or_put_align32 (buf);
16276  }
16277 
16278  return rc;
16279 }
16280 
16281 /*
16282  * pr_write_uncompressed_string_to_buffer() :- Writes a string with a size less than
16283  * OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION to buffer.
16284  *
16285  * return :- NO_ERROR or error code.
16286  * buf(in/out) :- Buffer to be written to.
16287  * string(in) :- String to be written.
16288  * size(in) :- Size of the string.
16289  * align() :-
16290  */
16291 
16292 static int
16293 pr_write_uncompressed_string_to_buffer (OR_BUF * buf, const char *string, int size, int align)
16294 {
16295  int rc = NO_ERROR;
16296 
16298 
16299  /* Store the size prefix */
16300  rc = or_put_byte (buf, size);
16301  if (rc != NO_ERROR)
16302  {
16303  return rc;
16304  }
16305 
16306  /* store the string bytes */
16307  rc = or_put_data (buf, string, size);
16308  if (rc != NO_ERROR)
16309  {
16310  return rc;
16311  }
16312 
16313  if (align == INT_ALIGNMENT)
16314  {
16315  /* kludge, temporary NULL terminator */
16316  rc = or_put_byte (buf, 0);
16317  if (rc != NO_ERROR)
16318  {
16319  return rc;
16320  }
16321 
16322  /* round up to a word boundary */
16323  rc = or_put_align32 (buf);
16324  }
16325 
16326  return rc;
16327 }
16328 
16329 /*
16330  * pr_data_compress_string() :- Does compression for a string.
16331  *
16332  * return :- NO_ERROR or error code.
16333  * string(in) :- String to be compressed.
16334  * str_length(in) :- The size of the string.
16335  * compressed_string(out) :- The compressed string. Needs to be alloced!!!!!
16336  * compress_buffer_size(in) :- The compressed string buffer size.
16337  * compressed_length(out) :- The compressed string length.
16338  *
16339  */
16340 int
16341 pr_data_compress_string (const char *string, int str_length, char *compressed_string, int compress_buffer_size,
16342  int *compressed_length)
16343 {
16344  int compressed_length_local = 0;
16345 
16346  assert (string != NULL && compressed_string != NULL && compressed_length != NULL && str_length >= 0
16347  && compress_buffer_size >= 0);
16348 
16349  if (!OR_IS_STRING_LENGTH_COMPRESSABLE (str_length))
16350  {
16351  *compressed_length = 0;
16352  return NO_ERROR;
16353  }
16354 
16355  if (!pr_Enable_string_compression) /* compression is not set */
16356  {
16357  *compressed_length = -1;
16358  return NO_ERROR;
16359  }
16360 
16361  /* Compress the string */
16362  compressed_length_local = LZ4_compress_default (string, compressed_string, str_length, compress_buffer_size);
16363  if (compressed_length_local <= 0)
16364  {
16368  return ER_IO_LZ4_COMPRESS_FAIL;
16369  }
16370  assert (compressed_length_local <= compress_buffer_size);
16371 
16372  if (compressed_length_local >= str_length - 8)
16373  {
16374  /* Compression successful but its length exceeds the original length of the string. */
16375  /* We will also be freeing the compressed_string since we will not need it anymore. */
16376  *compressed_length = -1;
16377  }
16378  else
16379  {
16380  /* Compression successful */
16381  *compressed_length = compressed_length_local;
16382  }
16383 
16384  return NO_ERROR;
16385 }
16386 
16387 /*
16388  * pr_clear_compressed_string() :- Clears the compressed string that might have been stored in a DB_VALUE.
16389  * This needs to succeed only for VARCHAR and VARNCHAR types.
16390  *
16391  * return () :- NO_ERROR or error code.
16392  * value(in/out) :- The DB_VALUE that needs the clearing.
16393  */
16394 
16395 int
16397 {
16398  char *data = NULL;
16399  DB_TYPE db_type;
16400 
16401  if (value == NULL || DB_IS_NULL (value))
16402  {
16403  return NO_ERROR; /* do nothing */
16404  }
16405 
16406  db_type = DB_VALUE_DOMAIN_TYPE (value);
16407 
16408  /* Make sure we clear only for VARCHAR and VARNCHAR types. */
16409  if (db_type != DB_TYPE_VARCHAR && db_type != DB_TYPE_VARNCHAR)
16410  {
16411  return NO_ERROR; /* do nothing */
16412  }
16413 
16414  if (value->data.ch.info.compressed_need_clear == false)
16415  {
16416  return NO_ERROR;
16417  }
16418 
16419  if (value->data.ch.medium.compressed_size <= 0)
16420  {
16421  return NO_ERROR; /* do nothing */
16422  }
16423 
16424  data = value->data.ch.medium.compressed_buf;
16425  if (data != NULL)
16426  {
16428  }
16429 
16430  db_set_compressed_string (value, NULL, 0, false);
16431 
16432  return NO_ERROR;
16433 }
16434 
16435 /*
16436  * pr_do_db_value_string_compression() :- Test a DB_VALUE for VARCHAR and VARNCHAR types and do string compression
16437  * :- for such types.
16438  *
16439  * return() :- NO_ERROR or error code.
16440  * value(in/out) :- The DB_VALUE to be tested.
16441  */
16442 
16443 int
16445 {
16446  DB_TYPE db_type;
16447  const char *string;
16448  char *compressed_string;
16449  int rc = NO_ERROR;
16450  int src_size = 0, compressed_size, compressed_length;
16451 
16452  if (value == NULL || DB_IS_NULL (value))
16453  {
16454  return rc; /* do nothing */
16455  }
16456 
16457  db_type = DB_VALUE_DOMAIN_TYPE (value);
16458 
16459  /* Make sure we clear only for VARCHAR and VARNCHAR types. */
16460  if (db_type != DB_TYPE_VARCHAR && db_type != DB_TYPE_VARNCHAR)
16461  {
16462  return rc; /* do nothing */
16463  }
16464 
16465  /* Make sure the value has not been through a compression before */
16466  if (value->data.ch.medium.compressed_size != 0)
16467  {
16468  return rc;
16469  }
16470 
16471  string = db_get_string (value);
16472  src_size = db_get_string_size (value);
16473 
16475  {
16476  /* Either compression was disabled or the source size is less than the compression threshold. */
16477  value->data.ch.medium.compressed_buf = NULL;
16478  value->data.ch.medium.compressed_size = -1;
16479  return rc;
16480  }
16481 
16482  /* Alloc memory for compression */
16483  compressed_size = LZ4_compressBound (src_size);
16484  compressed_string = (char *) db_private_alloc (NULL, compressed_size);
16485  if (compressed_string == NULL)
16486  {
16489  return rc;
16490  }
16491 
16492  rc = pr_data_compress_string (string, src_size, compressed_string, compressed_size, &compressed_length);
16493  if (rc != NO_ERROR)
16494  {
16495  ASSERT_ERROR ();
16496  goto error;
16497  }
16498 
16499  if (compressed_length > 0)
16500  {
16501  /* Compression successful */
16502  db_set_compressed_string (value, compressed_string, compressed_length, true);
16503  return rc;
16504  }
16505  else
16506  {
16507  /* Compression failed */
16508  db_set_compressed_string (value, NULL, -1, false);
16509  goto error;
16510  }
16511 
16512 error:
16513  if (compressed_string != NULL)
16514  {
16515  db_private_free_and_init (NULL, compressed_string);
16516  }
16517 
16518  return rc;
16519 }
16520 
16522  "json", DB_TYPE_JSON, 1, sizeof (DB_JSON), 0, 1,
16534  NULL, /* index_lengthmem */
16535  NULL, /* index_lengthval */
16536  NULL, /* index_writeval */
16537  NULL, /* index_readval */
16538  NULL, /* index_cmpdisk */
16542 };
16543 
16545 
16546 static void
16547 mr_initmem_json (void *mem, TP_DOMAIN * domain)
16548 {
16549  DB_JSON *json = (DB_JSON *) mem;
16550 
16551  if (json != NULL)
16552  {
16553  json->document = NULL;
16554  json->schema_raw = NULL;
16555  }
16556  else
16557  {
16558  assert (false);
16559  }
16560 }
16561 
16562 static int
16563 mr_setmem_json (void *memptr, TP_DOMAIN * domain, DB_VALUE * value)
16564 {
16565  int error = NO_ERROR;
16566  DB_JSON *json;
16567  JSON_DOC *doc;
16568 
16569  json = (DB_JSON *) memptr;
16570  if (json != NULL)
16571  {
16572  mr_freemem_json (memptr);
16573  }
16574  else
16575  {
16576  assert (false);
16577  }
16578 
16579  if (value == NULL)
16580  {
16581  return NO_ERROR;
16582  }
16583  doc = db_get_json_document (value);
16584  if (doc != NULL)
16585  {
16586  error = db_get_deep_copy_of_json (&value->data.json, json);
16587  if (error != NO_ERROR)
16588  {
16589  ASSERT_ERROR ();
16590  return error;
16591  }
16592  }
16593 
16594  return error;
16595 }
16596 
16597 static int
16598 mr_getmem_json (void *memptr, TP_DOMAIN * domain, DB_VALUE * value, bool copy)
16599 {
16600  int error = NO_ERROR;
16601  const char *json_schema = NULL;
16602  DB_JSON *json, json_copy;
16603  JSON_DOC *new_doc = NULL;
16604 
16605  json = (DB_JSON *) memptr;
16606 
16607  if (json == NULL)
16608  {
16609  db_make_null (value);
16610  db_value_domain_init (value, DB_TYPE_JSON, domain->precision, 0);
16611  value->need_clear = false;
16612  return NO_ERROR;
16613  }
16614 
16615  if (!copy)
16616  {
16617  json_schema = json->schema_raw;
16618  new_doc = json->document;
16619  }
16620  else
16621  {
16622  error = db_init_db_json_pointers (&json_copy);
16623  if (error != NO_ERROR)
16624  {
16625  return error;
16626  }
16627  error = db_get_deep_copy_of_json (json, &json_copy);
16628  if (error != NO_ERROR)
16629  {
16630  return error;
16631  }
16632  json_schema = json_copy.schema_raw;
16633  new_doc = json_copy.document;
16634  }
16635 
16636  db_make_json (value, new_doc, copy);
16637  db_get_json_schema (value) = json_schema;
16638 
16639  return error;
16640 }
16641 
16642 static int
16643 mr_data_lengthmem_json (void *memptr, TP_DOMAIN * domain, int disk)
16644 {
16645  int len = 0;
16646  DB_JSON *json;
16647 
16648  if (!disk)
16649  {
16650  len = tp_Json.size;
16651  }
16652  else
16653  {
16654  if (memptr != NULL)
16655  {
16656  json = (DB_JSON *) memptr;
16657  if (json->document == NULL)
16658  {
16659  return 0;
16660  }
16661 
16662  return (int) db_json_serialize_length (*json->document);
16663  }
16664  }
16665 
16666  return len;
16667 }
16668 
16669 static void
16670 mr_data_writemem_json (OR_BUF * buf, void *memptr, TP_DOMAIN * domain)
16671 {
16672  DB_JSON *json;
16673  int rc = NO_ERROR;
16674 
16675  json = (DB_JSON *) memptr;
16676  if (json == NULL || json->document == NULL)
16677  {
16678  return;
16679  }
16680 
16681  rc = db_json_serialize (*json->document, *buf);
16682  if (rc != NO_ERROR)
16683  {
16684  ASSERT_ERROR ();
16685  }
16686 }
16687 
16688 static void
16689 mr_data_readmem_json (OR_BUF * buf, void *memptr, TP_DOMAIN * domain, int size)
16690 {
16691  DB_JSON *json;
16692  int rc = NO_ERROR;
16693 
16694  json = (DB_JSON *) memptr;
16695  if (json == NULL)
16696  {
16697  if (size != 0)
16698  {
16699  if (or_advance (buf, size) != NO_ERROR)
16700  {
16701  assert (false);
16702  }
16703  }
16704  return;
16705  }
16706 
16707  if (size < 0)
16708  {
16709  assert (false);
16710  return;
16711  }
16712 
16713  if (size == 0)
16714  {
16715  mr_initmem_json (memptr, domain);
16716  return;
16717  }
16718 
16719  rc = db_json_deserialize (buf, json->document);
16720  if (rc != NO_ERROR)
16721  {
16722  ASSERT_ERROR ();
16723  db_json_delete_doc (json->document);
16724  }
16725 }
16726 
16727 static void
16728 mr_freemem_json (void *memptr)
16729 {
16730  DB_JSON *cur;
16731 
16732  cur = (DB_JSON *) memptr;
16733 
16734  if (cur != NULL)
16735  {
16736  if (cur->schema_raw != NULL)
16737  {
16738  db_private_free (NULL, const_cast < char *>(cur->schema_raw));
16739  cur->schema_raw = NULL;
16740  }
16741  if (cur->document != NULL)
16742  {
16744  cur->document = NULL;
16745  }
16746  }
16747 }
16748 
16749 static void
16750 mr_initval_json (DB_VALUE * value, int precision, int scale)
16751 {
16752  db_value_domain_init (value, DB_TYPE_JSON, precision, scale);
16753  value->need_clear = false;
16754 }
16755 
16756 static int
16757 mr_setval_json (DB_VALUE * dest, const DB_VALUE * src, bool copy)
16758 {
16759  int error = NO_ERROR;
16760 
16761  if (src == NULL || DB_IS_NULL (src))
16762  {
16764  if (error != NO_ERROR)
16765  {
16766  ASSERT_ERROR ();
16767  return error;
16768  }
16769  }
16770  else
16771  {
16773  dest->domain.general_info.is_null = 0;
16774 
16775  if (copy)
16776  {
16779  dest->need_clear = true;
16780  }
16781  else
16782  {
16783  dest->data.json.document = src->data.json.document;
16784  dest->data.json.schema_raw = src->data.json.schema_raw;
16785  dest->need_clear = false;
16786  }
16787  }
16788 
16789  return error;
16790 }
16791 
16792 static int
16794 {
16795  if (!disk)
16796  {
16797  return tp_Json.size;
16798  }
16799 
16800  if (value->data.json.document != NULL)
16801  {
16802  return (int) db_json_serialize_length (*value->data.json.document);
16803  }
16804  else
16805  {
16806  return 0;
16807  }
16808 }
16809 
16810 static int
16812 {
16813  int rc = NO_ERROR;
16814 
16815  if (value->data.json.document == NULL || DB_IS_NULL (value))
16816  {
16817  assert (false);
16818  return ER_FAILED;
16819  }
16820 
16821  if (buf->error_abort)
16822  {
16823  int estimated_length = mr_data_lengthval_json (value, true);
16824 
16825  if ((ptrdiff_t) estimated_length > ((ptrdiff_t) (buf->endptr - buf->ptr)))
16826  {
16827  /* this will make string_data_writeval jump because
16828  * of buffer overflow, leaking memory in the process,
16829  * we need to take care of it here
16830  */
16831  (void) or_overflow (buf);
16832  }
16833  }
16834 
16835  JSON_DOC *json_doc = db_get_json_document (value);
16836  rc = db_json_serialize (*json_doc, *buf);
16837  if (rc != NO_ERROR)
16838  {
16839  ASSERT_ERROR ();
16840  }
16841 
16842  return rc;
16843 }
16844 
16845 static int
16846 mr_data_readval_json (OR_BUF * buf, DB_VALUE * value, TP_DOMAIN * domain, int size, bool copy, char *copy_buf,
16847  int copy_buf_len)
16848 {
16849  JSON_DOC *doc = NULL;
16850  char *json_raw = NULL;
16851  int rc = NO_ERROR;
16852 
16853  db_make_null (value);
16854 
16855  if (size == 0)
16856  {
16857  /* early out, means json is NULL */
16858  return NO_ERROR;
16859  }
16860 
16861  rc = db_json_deserialize (buf, doc);
16862  if (rc != NO_ERROR)
16863  {
16864  ASSERT_ERROR ();
16865  return rc;
16866  }
16867 
16868  db_make_json (value, doc, true);
16869 
16870  return NO_ERROR;
16871 }
16872 
16874 mr_data_cmpdisk_json (void *mem1, void *mem2, TP_DOMAIN * domain, int do_coercion, int total_order, int *start_colp)
16875 {
16876  char *first, *second;
16877  OR_BUF first_buf, second_buf;
16878  DB_VALUE json1, json2;
16879  JSON_DOC *doc1 = NULL, *doc2 = NULL;
16880  int rc = NO_ERROR;
16881 
16883 
16884  first = (char *) mem1;
16885  second = (char *) mem2;
16886 
16887  or_init (&first_buf, first, 0);
16888  or_init (&second_buf, second, 0);
16889 
16890  rc = db_json_deserialize (&first_buf, doc1);
16891  if (rc != NO_ERROR)
16892  {
16893  ASSERT_ERROR ();
16894  return res;
16895  }
16896 
16897  rc = db_json_deserialize (&second_buf, doc2);
16898  if (rc != NO_ERROR)
16899  {
16900  ASSERT_ERROR ();
16901  return res;
16902  }
16903 
16904  db_make_json (&json1, doc1, true);
16905  db_make_json (&json2, doc2, true);
16906 
16907  res = mr_cmpval_json (&json1, &json2, do_coercion, total_order, 0, 0);
16908  pr_clear_value (&json1);
16909  pr_clear_value (&json2);
16910 
16911  return res;
16912 }
16913 
16914 /* when total_order is true,
16915  * we force to string uncomparable types.
16916  * this is because "order by" uses total_order=true
16917  * and we don't want to fail. The standard says that
16918  * only scalar and nulls are comparable.
16919  *
16920  * we only return DB_UNK when either one is null and
16921  * total_order is false
16922  */
16924 mr_cmpval_json (DB_VALUE * value1, DB_VALUE * value2, int do_coercion, int total_order, int *start_colp, int collation)
16925 {
16926  JSON_DOC *doc1 = NULL, *doc2 = NULL;
16927  DB_JSON_TYPE type1 = DB_JSON_UNKNOWN;
16928  DB_JSON_TYPE type2 = DB_JSON_UNKNOWN;
16929  DB_VALUE scalar_value1, scalar_value2;
16930  DB_VALUE_COMPARE_RESULT cmp_result;
16931  bool is_value1_null = true, is_value2_null = true;
16932  int error_code;
16933 
16934  doc1 = db_get_json_document (value1);
16935  doc2 = db_get_json_document (value2);
16936 
16937  is_value1_null = DB_IS_NULL (value1) || ((type1 = db_json_get_type (doc1)) == DB_JSON_NULL);
16938  is_value2_null = DB_IS_NULL (value2) || ((type2 = db_json_get_type (doc2)) == DB_JSON_NULL);
16939 
16940  if (is_value1_null || is_value2_null)
16941  {
16942  if (!total_order)
16943  {
16944  return DB_UNK;
16945  }
16946 
16947  if (is_value1_null && is_value2_null)
16948  {
16949  return DB_EQ;
16950  }
16951 
16952  return is_value1_null ? DB_LT : DB_GT;
16953  }
16954 
16955  /* db_json_get_type shouldn't return DB_JSON_UNKNOWN, this represents a bug */
16956  assert (type1 != DB_JSON_UNKNOWN && type2 != DB_JSON_UNKNOWN);
16957 
16958  db_make_null (&scalar_value1);
16959  db_make_null (&scalar_value2);
16960 
16962  {
16963  /* force string comp */
16964  char *str1 = NULL, *str2 = NULL;
16965 
16966  str1 = db_json_get_json_body_from_document (*doc1);
16967  str2 = db_json_get_json_body_from_document (*doc2);
16968 
16969  db_make_string (&scalar_value1, str1);
16970  db_make_string (&scalar_value2, str2);
16971 
16972  scalar_value1.need_clear = true;
16973  scalar_value2.need_clear = true;
16974  }
16975  else
16976  {
16977  /* This is not according to standard, in SQL/JSON standard
16978  * different types should not be compared, but rather throw
16979  * an error. We chose to also compare different scalar types
16980  * even when total_order is false.
16981  */
16982  error_code = db_convert_json_into_scalar (value1, &scalar_value1);
16983  if (error_code != NO_ERROR)
16984  {
16985  /* this shouldn't happen */
16986  assert (false);
16987  pr_clear_value (&scalar_value1);
16988  return DB_UNK;
16989  }
16990 
16991  error_code = db_convert_json_into_scalar (value2, &scalar_value2);
16992  if (error_code != NO_ERROR)
16993  {
16994  /* this shouldn't happen */
16995  assert (false);
16996  pr_clear_value (&scalar_value1);
16997  pr_clear_value (&scalar_value2);
16998  return DB_UNK;
16999  }
17000  }
17001 
17002  cmp_result = tp_value_compare_with_error (&scalar_value1, &scalar_value2, do_coercion, total_order, NULL);
17003 
17004  pr_clear_value (&scalar_value1);
17005  pr_clear_value (&scalar_value2);
17006  return cmp_result;
17007 }
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_string(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initval_time(DB_VALUE *value, int precision, int scale)
static int pr_midxkey_get_element_internal(const DB_MIDXKEY *midxkey, int index, DB_VALUE *value, bool copy, int *prev_indexp, char **prev_ptrp)
char * or_unpack_set(char *ptr, setobj **set, struct tp_domain *domain)
PR_TYPE tp_Multiset
static int mr_setmem_set(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
static void mr_initval_midxkey(DB_VALUE *value, int precision, int scale)
#define OR_GET_DATE(ptr, value)
MIN_MAX_COLUMN_INFO min_max_val
Definition: dbtype_def.h:867
DB_C_FLOAT db_get_float(const DB_VALUE *value)
DB_DOMAIN * disk_domain
Definition: db_set.h:45
initmem_function_type f_initmem
#define ER_IO_LZ4_DECOMPRESS_FAIL
Definition: error_code.h:1119
struct db_domain_info::char_info char_info
DB_VALUE_COMPARE_RESULT set_compare_order(DB_COLLECTION *set1, DB_COLLECTION *set2, int do_coercion, int total_order)
Definition: set_object.c:3359
static void mr_initval_bigint(DB_VALUE *value, int precision, int scale)
index_readval_function_type f_index_readval
PR_TYPE * tp_Type_nchar
static int mr_setmem_ptr(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
struct db_datetime DB_DATETIME
Definition: dbtype_def.h:773
struct db_value DB_VALUE
Definition: dbtype_def.h:1079
static void mr_data_writemem_enumeration(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
int bit_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
#define DB_GET_STRING_PRECISION(v)
Definition: dbtype.h:139
static int mr_getmem_datetimeltz(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static void mr_initmem_bigint(void *mem, TP_DOMAIN *domain)
int db_make_json(DB_VALUE *value, JSON_DOC *json_document, bool need_clear)
#define OR_TIME_SIZE
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
static int mr_index_writeval_varbit(OR_BUF *buf, DB_VALUE *value)
static int mr_setval_multiset(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define OR_MULTI_ENABLE_BOUND_BIT(bitptr, element)
#define WS_IS_DELETED(mop)
Definition: work_space.h:284
static int mr_data_lengthmem_set(void *memptr, TP_DOMAIN *domain, int disk)
PR_TYPE * tp_Type_midxkey
#define NO_ERROR
Definition: error_code.h:46
PR_TYPE tp_Bigint
PR_TYPE tp_Datetime
static int mr_index_readval_numeric(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_writeval_nchar_internal(OR_BUF *buf, DB_VALUE *value, int align)
DB_VALUE_COMPARE_RESULT(* data_cmpdisk_function_type)(void *memptr1, void *memptr2, tp_domain *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE tp_Utime
static void mr_initmem_null(void *mem, TP_DOMAIN *domain)
static int mr_index_writeval_bit(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_bit(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_data_lengthmem_varbit(void *memptr, TP_DOMAIN *domain, int disk)
#define DB_GET_ENUM_ELEM_STRING(elem)
Definition: dbtype.h:103
static DB_VALUE_COMPARE_RESULT mr_cmpval_float(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int pr_data_compress_string(const char *string, int str_length, char *compressed_string, int compress_buffer_size, int *compressed_length)
static void mr_data_writemem_json(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
#define OR_MULTI_ATT_IS_BOUND(bitptr, element)
int pr_Enable_string_compression
static int mr_data_writeval_null(OR_BUF *buf, DB_VALUE *value)
static void mr_freemem_set(void *memptr)
DB_COLLECTION * db_get_set(const DB_VALUE *value)
int db_value_scale(const DB_VALUE *value)
static int mr_setval_enumeration_internal(DB_VALUE *value, TP_DOMAIN *domain, unsigned short index, int size, bool copy, char *copy_buf, int copy_buf_len)
char buf[DB_SMALL_CHAR_BUF_SIZE]
Definition: dbtype_def.h:991
static int mr_data_readval_oid(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define LANG_SYS_COLLATION
static int mr_setval_vobj(DB_VALUE *dest, const DB_VALUE *src, bool copy)
PR_TYPE tp_Monetary
static void mr_initval_money(DB_VALUE *value, int precision, int scale)
int pr_data_writeval_disk_size(DB_VALUE *value)
static void mr_data_writemem_char(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
char * release_ptr()
static void mr_initmem_sub(void *mem, TP_DOMAIN *domain)
int pr_do_db_value_string_compression(DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_cmpval_short(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_getmem_varbit(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int or_get_varbit_length(OR_BUF *buf, int *intval)
static int mr_data_readval_varnchar(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
unsigned char codeset
Definition: dbtype_def.h:980
static int mr_setmem_short(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
DB_MIDXKEY * db_get_midxkey(const DB_VALUE *value)
static int mr_data_readval_string(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_index_readval_nchar(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_elo(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
STATIC_INLINE int or_get_varchar_compression_lengths(OR_BUF *buf, int *compressed_size, int *decompressed_size) __attribute__((ALWAYS_INLINE))
static int mr_getmem_error(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
PR_TYPE * tp_Type_id_map[]
static void mr_initval_varbit(DB_VALUE *value, int precision, int scale)
float or_get_float(OR_BUF *buf, int *error)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_datetimetz(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static DB_VALUE_COMPARE_RESULT mr_cmpval_sequence(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static void mr_freemem_bit(void *memptr)
static int mr_data_writeval_time(OR_BUF *buf, DB_VALUE *value)
static int mr_setval_nchar(DB_VALUE *dest, const DB_VALUE *src, bool copy)
DB_VALUE_COMPARE_RESULT tp_value_compare(const DB_VALUE *value1, const DB_VALUE *value2, int allow_coercion, int total_order)
static int mr_data_lengthval_json(DB_VALUE *value, int disk)
int or_put_float(OR_BUF *buf, float num)
static int mr_readval_bit_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len, int align)
static int mr_index_lengthval_numeric(DB_VALUE *value)
static int mr_data_lengthmem_ptr(void *memptr, TP_DOMAIN *domain, int disk)
#define ASSERT_ERROR()
int index_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_MULTI_ATT_IS_UNBOUND(bitptr, element)
static int mr_getmem_enumeration(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static DB_VALUE_COMPARE_RESULT mr_cmpval_bigint(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
DB_VALUE * pr_make_value(void)
#define ER_IO_LZ4_COMPRESS_FAIL
Definition: error_code.h:1118
OID * tf_need_permanent_oid(or_buf *buf, DB_OBJECT *obj)
Definition: transform_cl.c:513
int or_put_oid(OR_BUF *buf, const OID *oid)
void or_abort(OR_BUF *buf)
const char * fileio_get_zip_level_string(FILEIO_ZIP_LEVEL zip_level)
Definition: file_io.c:10774
static DB_VALUE_COMPARE_RESULT mr_cmpval_numeric(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_setmem_char(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
static void mr_data_readmem_date(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static int mr_data_writeval_variable(OR_BUF *buf, DB_VALUE *value)
int disk_size
Definition: db_set.h:48
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
int data_writeval(struct or_buf *buf, const DB_VALUE *value) const
static void mr_data_readmem_datetime(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
unsigned int db_on_server
const char * schema_raw
Definition: dbtype_def.h:1039
static void mr_freemem_char(void *memptr)
static int mr_index_readval_varnchar(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
DB_OBJECT * db_real_instance(DB_OBJECT *obj)
Definition: db_virt.c:247
void area_destroy(AREA *area)
Definition: area_alloc.c:247
static int mr_data_readval_datetimetz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_initval_multiset(DB_VALUE *value, int precision, int scale)
static void mr_initval_timestamptz(DB_VALUE *value, int precision, int scale)
static void mr_data_writemem_oid(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_varbit(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int or_packed_varchar_length(int charlen)
DB_CONST_C_BIT db_get_bit(const DB_VALUE *value, int *length)
static DB_VALUE_COMPARE_RESULT mr_cmpval_nchar(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
#define TP_IS_SET_TYPE(typenum)
static DB_VALUE_COMPARE_RESULT mr_cmpval_varbit(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
#define ER_TF_BUFFER_OVERFLOW
Definition: error_code.h:388
DB_CONST_C_NCHAR db_get_nchar(const DB_VALUE *value, int *length)
JSON_DOC * db_get_json_document(const DB_VALUE *value)
static int mr_getmem_time(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int get_index_size_of_value(const DB_VALUE *value) const
void set_free(DB_COLLECTION *set)
Definition: set_object.c:2560
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_nchar(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
const char * fileio_get_zip_method_string(FILEIO_ZIP_METHOD zip_method)
Definition: file_io.c:10747
PR_TYPE tp_Clob
static void mr_initval_varnchar(DB_VALUE *value, int precision, int scale)
static int mr_writeval_varnchar_internal(OR_BUF *buf, DB_VALUE *value, int align)
static void mr_data_writemem_utime(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
PR_TYPE * tp_Type_substructure
data_cmpdisk_function_type get_data_cmpdisk_function() const
static int mr_index_writeval_short(OR_BUF *buf, DB_VALUE *value)
static int mr_writeval_bit_internal(OR_BUF *buf, DB_VALUE *value, int align)
static int mr_getmem_set(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
int db_get_int(const DB_VALUE *value)
static int mr_index_readval_string(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
size_t align(size_t v)
Definition: align.h:19
static int mr_index_readval_oid(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
DB_TIMESTAMP timestamp
Definition: dbtype_def.h:766
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_enumeration(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE tp_Numeric
int or_put_time(OR_BUF *buf, DB_TIME *timeval)
DB_TYPE
Definition: dbtype_def.h:670
static DB_VALUE_COMPARE_RESULT mr_cmpval_resultset(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
DB_C_DOUBLE db_get_double(const DB_VALUE *value)
#define ER_FAILED
Definition: error_code.h:47
static void mr_initmem_nchar(void *memptr, TP_DOMAIN *domain)
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)
double or_get_double(OR_BUF *buf, int *error)
static void mr_data_writemem_object(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
int or_get_datetimetz(OR_BUF *buf, DB_DATETIMETZ *datetimetz)
static void mr_freemem_varbit(void *memptr)
freemem_function_type f_freemem
static void mr_initmem_double(void *mem, TP_DOMAIN *domain)
int pr_get_compressed_data_from_buffer(struct or_buf *buf, char *data, int compressed_size, int expected_decompressed_size)
static void mr_initval_null(DB_VALUE *value, int precision, int scale)
#define DB_GET_COMPRESSED_STRING(v)
Definition: dbtype.h:89
int db_get_string_collation(const DB_VALUE *value)
int pr_midxkey_unique_prefix(const DB_VALUE *db_midxkey1, const DB_VALUE *db_midxkey2, DB_VALUE *db_result)
DB_COLLECTION * set_copy(DB_COLLECTION *set)
Definition: set_object.c:2473
static DB_VALUE_COMPARE_RESULT mr_cmpval_object(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static DB_VALUE_COMPARE_RESULT mr_cmpval_vobj(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
struct db_monetary DB_MONETARY
Definition: dbtype_def.h:828
int pr_midxkey_common_prefix(DB_VALUE *key1, DB_VALUE *key2)
static int mr_index_writeval_numeric(OR_BUF *buf, DB_VALUE *value)
struct tp_domain * setdomain
Definition: object_domain.h:82
static void mr_data_writemem_float(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
char * db_json_get_json_body_from_document(const JSON_DOC &doc)
Definition: db_json.cpp:1370
DB_ELO_TYPE type
Definition: dbtype_def.h:950
static int getmem_elo_with_type(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy, DB_TYPE type)
static DB_VALUE_COMPARE_RESULT mr_cmpval_varbit2(DB_VALUE *value1, DB_VALUE *value2, int length, int do_coercion, int total_order, int *start_colp)
cmpval_function_type get_cmpval_function() const
#define ER_SM_CORRUPTED
Definition: error_code.h:335
static void mr_data_writemem_varbit(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
static int mr_data_readval_blob(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_short(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int pr_area_init(void)
#define OR_BUF_INIT(buf, data, size)
data_writemem_function_type f_data_writemem
static int mr_data_writeval_datetimetz(OR_BUF *buf, DB_VALUE *value)
int or_put_datetimetz(OR_BUF *buf, DB_DATETIMETZ *datetimetz)
static int mr_setval_ptr(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static void mr_initmem_ptr(void *memptr, TP_DOMAIN *domain)
DB_VALUE_COMPARE_RESULT tp_value_compare_with_error(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion, int total_order, bool *can_compare)
#define OR_IS_STRING_LENGTH_COMPRESSABLE(str_length)
index_cmpdisk_function_type f_index_cmpdisk
static DB_VALUE_COMPARE_RESULT mr_cmpval_varnchar(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int db_make_numeric(DB_VALUE *value, const DB_C_NUMERIC num, const int precision, const int scale)
int db_get_enum_codeset(const DB_VALUE *value)
static int mr_setval_int(DB_VALUE *dest, const DB_VALUE *src, bool copy)
struct setobj * set
Definition: db_set.h:43
static int mr_index_lengthmem_string(void *memptr, TP_DOMAIN *domain)
int or_get_oid(OR_BUF *buf, OID *oid)
int db_get_enum_string_size(const DB_VALUE *value)
int pr_is_variable_type(DB_TYPE id)
#define STR_SIZE(prec, codeset)
MOP pointer
Definition: work_space.h:162
static int mr_data_readval_datetimeltz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define assert_release(e)
Definition: error_manager.h:96
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_char(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int or_put_varbit(OR_BUF *buf, const char *string, int bitlen)
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
static DB_VALUE_COMPARE_RESULT mr_cmpval_time(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
#define MR_CMP(d1, d2)
static int mr_getmem_varnchar(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int varbit_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2)
int db_make_pointer(DB_VALUE *value, DB_C_POINTER ptr)
DB_C_NUMERIC db_get_numeric(const DB_VALUE *value)
PR_TYPE * tp_Type_variable
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_string(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_data_lengthval_elo(DB_VALUE *value, int disk)
DB_COLLECTION * setobj_get_reference(COL *set)
Definition: set_object.c:6247
PR_TYPE tp_Datetimeltz
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_bit(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int or_skip_varchar_remainder(OR_BUF *buf, int charlen, int align)
JSON_DOC * db_json_get_copy_of_doc(const JSON_DOC *doc)
Definition: db_json.cpp:1627
static void mr_data_readmem_utime(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static int mr_data_readval_timestamptz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
int pr_midxkey_init_boundbits(char *bufptr, int n_atts)
static int mr_data_readval_set(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
int numeric_db_value_compare(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
static int mr_setval_double(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_index_readval_double(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_setval_date(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_data_writeval_short(OR_BUF *buf, DB_VALUE *value)
static void mr_initmem_oid(void *memptr, TP_DOMAIN *domain)
bool db_json_doc_is_uncomparable(const JSON_DOC *doc)
Definition: db_json.cpp:3147
static DB_VALUE_COMPARE_RESULT mr_cmpdisk_char_internal(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp, int align)
static int mr_data_readval_bit(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_data_writemem_date(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
#define WS_ISVID(mop)
Definition: work_space.h:288
static int mr_getmem_bigint(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static void mr_initval_error(DB_VALUE *value, int precision, int scale)
static int mr_index_writeval_time(OR_BUF *buf, DB_VALUE *value)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
#define BUFFER_SIZE
Definition: broker.c:106
DB_DATETIMETZ * db_get_datetimetz(const DB_VALUE *value)
int db_make_datetimeltz(DB_VALUE *value, const DB_DATETIME *datetime)
static void mr_null_oid(OID *oid)
DB_VALUE_COMPARE_RESULT(* cmpval_function_type)(DB_VALUE *value, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_data_writeval_string(OR_BUF *buf, DB_VALUE *value)
PR_TYPE * tp_Type_clob
static int mr_index_writeval_float(OR_BUF *buf, DB_VALUE *value)
int db_make_sequence(DB_VALUE *value, DB_C_SET *set)
static int mr_data_writeval_nchar(OR_BUF *buf, DB_VALUE *value)
void vid_get_keys(MOP mop, DB_VALUE *value)
int or_varchar_length(int charlen)
static DB_VALUE_COMPARE_RESULT mr_cmpval_enumeration(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int vid_object_to_vobj(const DB_OBJECT *obj, DB_VALUE *vobj)
static int mr_data_lengthval_object(DB_VALUE *value, int disk)
#define OR_GET_BYTE(ptr)
static void mr_initval_datetime(DB_VALUE *value, int precision, int scale)
void set_cmpval_function(cmpval_function_type cmpval_arg)
static int mr_data_readval_double(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
PR_TYPE tp_Integer
static int mr_index_readval_datetime(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_lengthval_string_internal(DB_VALUE *value, int disk, int align)
int er_errid(void)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_time(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initval_date(DB_VALUE *value, int precision, int scale)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_float(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_writemem_double(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
int or_skip_varbit(OR_BUF *buf, int align)
static void mr_initval_resultset(DB_VALUE *value, int precision, int scale)
static int mr_data_lengthval_numeric(DB_VALUE *value, int disk)
static void mr_freemem_nchar(void *memptr)
DB_VALUE_COMPARE_RESULT set_seq_compare(DB_COLLECTION *set1, DB_COLLECTION *set2, int do_coercion, int total_order)
Definition: set_object.c:3464
#define OR_MULTI_BOUND_BIT_BYTES(count)
static void mr_initmem_json(void *mem, TP_DOMAIN *domain)
static void mr_data_readmem_sub(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
const block_allocator PRIVATE_BLOCK_ALLOCATOR
static int mr_data_lengthval_set(DB_VALUE *value, int disk)
static int mr_getmem_object(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_data_lengthmem_midxkey(void *memptr, TP_DOMAIN *domain, int disk)
static int mr_getmem_datetimetz(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
const char * name
static int mr_index_readval_char(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
PR_TYPE tp_Oid
static int mr_setval_datetimeltz(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define DB_VALUE_PRECISION(value)
Definition: dbtype.h:73
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_varnchar(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_data_readval_nchar(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_index_writeval_bigint(OR_BUF *buf, DB_VALUE *value)
static int mr_getmem_char(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
#define OR_OID_SLOTID
static int mr_index_lengthval_char(DB_VALUE *value)
static int mr_index_lengthval_midxkey(DB_VALUE *value)
#define OR_GET_UTIME(ptr, value)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_object(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initval_clob(DB_VALUE *value, int precision, int scale)
int or_put_date(OR_BUF *buf, DB_DATE *date)
int or_get_monetary(OR_BUF *buf, DB_MONETARY *monetary)
PR_TYPE tp_Time
static void mr_freemem_elo(void *memptr)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_sequence(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE * tp_Type_varbit
static int mr_index_readval_float(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
PR_TYPE tp_Char
#define OR_DATETIME_TIME
static int mr_data_writeval_varnchar(OR_BUF *buf, DB_VALUE *value)
PR_TYPE * tp_Type_object
static void mr_data_readmem_enumeration(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
#define DB_DOMAIN_INIT_CHAR(value, precision)
static void mr_data_writemem_string(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_float(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_data_writeval_error(OR_BUF *buf, DB_VALUE *value)
static int mr_data_lengthval_error(DB_VALUE *value, int disk)
int db_make_elo(DB_VALUE *value, DB_TYPE type, const DB_ELO *elo)
static int mr_getmem_sub(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_timestamptz(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_data_readval_vobj(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
AREA * area_create(const char *name, size_t element_size, size_t alloc_count)
Definition: area_alloc.c:146
#define OR_MONETARY_SIZE
static int mr_setval_float(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_setval_error(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_data_lengthmem_error(void *memptr, TP_DOMAIN *domain, int disk)
data_readval_function_type f_data_readval
static int mr_index_readval_bit(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_readval_date(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_readval_json(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
PR_TYPE * tp_Type_bigint
PR_TYPE tp_Pointer
#define DB_VALUE_SCALE(value)
Definition: dbtype.h:74
DB_ELO * db_get_elo(const DB_VALUE *value)
static void mr_data_writemem_timestamptz(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
PR_TYPE * tp_Type_Datetimetz
static int mr_getmem_null(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
struct db_object * owner
Definition: db_set.h:41
static int mr_data_readval_error(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_data_readmem_int(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static int mr_data_readval_ptr(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_index_lengthmem_midxkey(void *memptr, TP_DOMAIN *domain)
#define db_make_utime
Definition: dbtype.h:48
PR_TYPE * tp_Type_varnchar
static int mr_index_writeval_object(OR_BUF *buf, DB_VALUE *value)
int or_put_utime(OR_BUF *buf, DB_UTIME *timeval)
static int mr_data_readval_utime(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_writeval_midxkey(OR_BUF *buf, DB_VALUE *value)
int db_init_db_json_pointers(DB_JSON *val)
Definition: db_macro.c:2042
static int mr_readval_string_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len, int align)
static int mr_data_readval_midxkey(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_setval_bigint(DB_VALUE *dest, const DB_VALUE *src, bool copy)
PR_TYPE tp_Blob
#define REINTERPRET_CAST(dest_type, expr)
Definition: porting.h:1080
#define CHAR_ALIGNMENT
Definition: memory_alloc.h:59
DB_TIMESTAMPTZ * db_get_timestamptz(const DB_VALUE *value)
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
#define OR_DATETIME_SIZE
static int mr_data_writeval_object(OR_BUF *buf, DB_VALUE *value)
PR_TYPE * tp_Type_pointer
void set_data_cmpdisk_function(data_cmpdisk_function_type data_cmpdisk_arg)
int pr_free_ext_value(DB_VALUE *value)
MIN_MAX_COLUMN_TYPE type
Definition: dbtype_def.h:857
static void mr_initval_json(DB_VALUE *value, int precision, int scale)
static void peekmem_elo(OR_BUF *buf, DB_ELO *elo)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_error(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_index_readval_bigint(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_getmem_blob(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_index_writeval_datetime(OR_BUF *buf, DB_VALUE *value)
static int mr_setmem_time(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
DB_MONETARY * db_get_monetary(const DB_VALUE *value)
DB_RESULTSET db_get_resultset(const DB_VALUE *value)
bool pr_is_set_type(DB_TYPE type)
DB_DATA data
Definition: dbtype_def.h:1083
INTL_CODESET lang_charset(void)
static int mr_data_readval_enumeration(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_index_readval_varbit(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_readval_timestampltz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_setval_datetime(DB_VALUE *dest, const DB_VALUE *src, bool copy)
DB_JSON json
Definition: dbtype_def.h:1073
int or_get_utime(OR_BUF *buf, DB_UTIME *timeval)
int pr_index_writeval_disk_size(DB_VALUE *value)
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
static int mr_data_writeval_enumeration(OR_BUF *buf, DB_VALUE *value)
PR_TYPE * pr_type_from_id(DB_TYPE id)
PR_TYPE tp_Timestampltz
#define DB_MAX_VARBIT_PRECISION
Definition: dbtype_def.h:552
int or_put_timestamptz(OR_BUF *buf, DB_TIMESTAMPTZ *ts_tz)
static int mr_getmem_timestamptz(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_index_writeval_nchar(OR_BUF *buf, DB_VALUE *value)
int ref_count
Definition: db_set.h:47
static int mr_data_lengthmem_bit(void *memptr, TP_DOMAIN *domain, int disk)
int pr_free_value(DB_VALUE *value)
PR_TYPE tp_Sequence
#define ER_MR_NULL_DOMAIN
Definition: error_code.h:1168
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
Definition: db_set.h:35
static int mr_index_writeval_date(OR_BUF *buf, DB_VALUE *value)
static void mr_data_writemem_bigint(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
std::size_t db_json_serialize_length(const JSON_DOC &doc)
Definition: db_json.cpp:3946
enum db_elo_type DB_ELO_TYPE
Definition: dbtype_def.h:943
PR_TYPE tp_Vobj
int pr_mem_size(const PR_TYPE *type)
static int mr_setmem_oid(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
int db_value_put_encoded_time(DB_VALUE *value, const DB_TIME *time)
Definition: db_macro.c:1357
int db_make_enumeration(DB_VALUE *value, unsigned short index, DB_CONST_C_CHAR str, int size, unsigned char codeset, const int collation_id)
static int mr_setmem_elo(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
#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)
int pr_midxkey_add_elements(DB_VALUE *keyval, DB_VALUE *dbvals, int num_dbvals, struct tp_domain *dbvals_domain_list)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_sub(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_datetime(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define assert(x)
static int mr_data_lengthmem_string(void *memptr, TP_DOMAIN *domain, int disk)
static int mr_index_lengthval_object(DB_VALUE *value)
PR_TYPE * tp_Type_numeric
static int mr_data_readval_variable(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static DB_VALUE_COMPARE_RESULT mr_cmpval_money(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int set_get_setobj(DB_COLLECTION *ref, COL **setptr, int for_write)
Definition: set_object.c:2175
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
getmem_function_type f_getmem
PR_TYPE * tp_Type_null
#define DB_NEED_CLEAR(v)
Definition: dbtype.h:83
static int mr_data_readval_datetime(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_readval_bigint(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define MR_OID_SIZE
int or_packed_string_length(const char *string, int *strlen)
static void mr_initmem_resultset(void *mem, TP_DOMAIN *domain)
void pr_clear_value_vector(std::vector< DB_VALUE > &value_vector)
#define OR_ENABLE_BOUND_BIT(bitptr, element)
data_cmpdisk_function_type f_data_cmpdisk
static int mr_setmem_numeric(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_index_readval_object(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_data_readmem_short(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
setval_function_type f_setval
int db_make_set(DB_VALUE *value, DB_C_SET *set)
static int mr_setval_bit(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_getmem_float(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
char * db_private_strdup(THREAD_ENTRY *thrd, const char *s)
Definition: memory_alloc.c:675
int db_make_multiset(DB_VALUE *value, DB_C_SET *set)
static int mr_setval_timestampltz(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static void mr_data_readmem_timestamptz(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
void intl_pad_char(const INTL_CODESET codeset, unsigned char *pad_char, int *pad_size)
static int mr_data_readval_null(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static DB_VALUE_COMPARE_RESULT mr_cmpval_int(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static void mr_initmem_date(void *mem, TP_DOMAIN *domain)
struct db_char::@52 info
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_header)
int or_get_time(OR_BUF *buf, DB_TIME *timeval)
int or_get_short(OR_BUF *buf, int *error)
int ws_pin(MOP mop, int pin)
Definition: work_space.c:2989
static void mr_data_writemem_sub(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
DB_IDENTIFIER OID
Definition: dbtype_def.h:967
static void mr_initmem_varnchar(void *mem, TP_DOMAIN *domain)
static int mr_setval_json(DB_VALUE *dest, const DB_VALUE *src, bool copy)
int pr_get_size_and_write_string_to_buffer(struct or_buf *buf, char *val_p, DB_VALUE *value, int *val_size, int align)
#define OR_MULTI_CLEAR_BOUND_BIT(bitptr, element)
static void mr_initmem_char(void *memptr, TP_DOMAIN *domain)
#define ER_MR_TEMP_OID_WITHOUT_MOP
Definition: error_code.h:246
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
#define DB_ENUM_OVERFLOW_VAL
Definition: dbtype_def.h:645
static int mr_data_writeval_elo(OR_BUF *buf, DB_VALUE *value)
int pr_get_compression_length(const char *string, int str_length)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_char(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define OID_ISTEMP(oidp)
Definition: oid.h:80
int or_disk_set_size(OR_BUF *buf, struct tp_domain *domain, DB_TYPE *set_type)
static int mr_data_writeval_numeric(OR_BUF *buf, DB_VALUE *value)
static int mr_writeval_string_internal(OR_BUF *buf, DB_VALUE *value, int align)
static int mr_index_writeval_enumeration(OR_BUF *buf, DB_VALUE *value)
enum special_column_type MIN_MAX_COLUMN_TYPE
Definition: dbtype_def.h:850
PR_TYPE tp_Null
static int mr_data_writeval_set(OR_BUF *buf, DB_VALUE *value)
static int mr_setmem_varbit(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_data_readval_char(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len)
unsigned is_desc
static int mr_index_readval_int(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define OR_OID_PAGEID
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_money(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define OR_GET_OID(ptr, oid)
int compressed_size
Definition: dbtype_def.h:1001
static int setval_elo_with_type(DB_VALUE *dest, const DB_VALUE *src, bool copy, DB_TYPE type)
JSON_DOC * document
Definition: dbtype_def.h:1040
DB_DATETIME datetime
Definition: dbtype_def.h:783
PR_TYPE * tp_Type_char
static int mr_data_readval_short(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_getmem_money(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
need_clear_type need_clear
Definition: db_set.h:49
int or_put_int(OR_BUF *buf, int num)
static void mr_initval_datetimetz(DB_VALUE *value, int precision, int scale)
DB_BIGINT or_get_bigint(OR_BUF *buf, int *error)
#define OR_GET_DATETIME(ptr, datetime)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
static int mr_setmem_object(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_data_lengthval_sub(DB_VALUE *value, int disk)
static void mr_initmem_numeric(void *memptr, TP_DOMAIN *domain)
PR_TYPE tp_NChar
int or_put_string_aligned(OR_BUF *buf, char *string)
int or_get_datetime(OR_BUF *buf, DB_DATETIME *datetime)
static void mr_initval_utime(DB_VALUE *value, int precision, int scale)
static int mr_lengthval_varnchar_internal(DB_VALUE *value, int disk, int align)
char * compressed_buf
Definition: dbtype_def.h:1002
#define IS_FLOATING_PRECISION(prec)
static void mr_initval_int(DB_VALUE *value, int precision, int scale)
#define DOM_GET_ENUM_ELEM(dom, idx)
Definition: object_domain.h:44
int db_convert_json_into_scalar(const DB_VALUE *src, DB_VALUE *dest)
Definition: db_macro.c:4981
#define DB_UNCOMPRESSABLE
Definition: dbtype_def.h:624
static int mr_data_writeval_money(OR_BUF *buf, DB_VALUE *value)
static int mr_getmem_nchar(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static DB_VALUE_COMPARE_RESULT mr_cmpval_oid(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
PR_TYPE tp_Short
#define TP_DOMAIN_COLLATION(dom)
static int mr_index_readval_utime(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define QSTR_CHAR_COMPARE(id, string1, size1, string2, size2, ti)
Definition: string_opfunc.h:60
int or_varbit_length(int bitlen)
int or_put_bigint(OR_BUF *buf, DB_BIGINT num)
int or_put_byte(OR_BUF *buf, int num)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_vobj(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define DOM_GET_ENUM_ELEMS_COUNT(dom)
Definition: object_domain.h:42
static int mr_data_readval_money(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
int pr_midxkey_get_element_offset(const DB_MIDXKEY *midxkey, int index)
static int mr_index_lengthmem_char(void *memptr, TP_DOMAIN *domain)
static int mr_index_lengthmem_nchar(void *memptr, TP_DOMAIN *domain)
static int mr_getmem_datetime(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_index_readval_short(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
data_lengthval_function_type f_data_lengthval
static int mr_setmem_nchar(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
int or_overflow(OR_BUF *buf)
static void mr_initval_timestampltz(DB_VALUE *value, int precision, int scale)
int or_put_short(OR_BUF *buf, int num)
static void mr_data_readmem_json(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
PR_TYPE * tp_Type_enumeration
#define OR_OID_VOLID
#define db_get_json_schema(v)
Definition: dbtype.h:148
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_oid(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static DB_VALUE_COMPARE_RESULT mr_cmpval_datetimetz(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
void db_json_delete_doc(JSON_DOC *&doc)
Definition: db_json.cpp:2355
static int mr_setval_varnchar(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_numeric(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE * tp_Type_float
PR_TYPE * tp_Type_utime
DB_OBJECT * db_get_object(const DB_VALUE *value)
static int mr_data_writeval_double(OR_BUF *buf, DB_VALUE *value)
static void mr_freemem_string(void *memptr)
static void mr_initval_object(DB_VALUE *value, int precision, int scale)
int db_make_timestamptz(DB_VALUE *value, const DB_C_TIMESTAMPTZ *ts_tz_val)
static int mr_setval_varbit(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static void mr_initval_short(DB_VALUE *value, int precision, int scale)
static int mr_index_lengthval_string(DB_VALUE *value)
PR_TYPE tp_Float
int pr_midxkey_add_prefix(DB_VALUE *result, DB_VALUE *prefix, DB_VALUE *postfix, int n_prefix)
#define TP_DOMAIN_TYPE(dom)
PR_TYPE * tp_Type_datetimeltz
static DB_VALUE_COMPARE_RESULT mr_cmpval_date(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
#define DO_CONVERSION_TO_SRVR_STR(codeset)
static void cleanup(int signo)
Definition: broker.c:717
static void mr_data_readmem_error(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static int mr_index_readval_date(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static DB_VALUE_COMPARE_RESULT pr_midxkey_compare_element(char *mem1, char *mem2, TP_DOMAIN *dom1, TP_DOMAIN *dom2, int do_coercion, int total_order)
static void mr_initmem_datetime(void *memptr, TP_DOMAIN *domain)
DB_VALUE * pr_copy_value(DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_cmpval_string(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int DB_RESULTSET
Definition: dbtype_def.h:1017
static void mr_data_readmem_varnchar(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static int mr_data_readval_numeric(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_data_readmem_null(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
PR_TYPE * tp_Type_json
#define NULL
Definition: freelistheap.h:34
unsigned short db_get_enum_short(const DB_VALUE *value)
int tp_valid_indextype(DB_TYPE type)
data_lengthmem_function_type f_data_lengthmem
unsigned char * DB_C_NUMERIC
Definition: dbtype_def.h:1214
static void mr_initmem_timestamptz(void *mem, TP_DOMAIN *domain)
#define COPYMEM(type, dst, src)
Definition: porting.h:723
PR_TYPE tp_Set
static int mr_data_readval_float(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
struct pr_type * type
Definition: object_domain.h:76
static int mr_getmem_date(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
DB_CHAR ch
Definition: dbtype_def.h:1070
static int mr_data_writeval_sub(OR_BUF *buf, DB_VALUE *value)
static int mr_index_writeval_timestamptz(OR_BUF *buf, DB_VALUE *value)
static int mr_data_lengthmem_sub(void *mem, TP_DOMAIN *domain, int disk)
static DB_VALUE_COMPARE_RESULT mr_cmpval_char(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
unsigned char size
Definition: dbtype_def.h:990
PR_TYPE tp_VarBit
const char * pr_type_name(DB_TYPE id)
DB_CURRENCY type
Definition: dbtype_def.h:832
static void mr_initmem_bit(void *memptr, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_varnchar(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define OR_BIGINT_SIZE
static int mr_getmem_resultset(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_data_readval_time(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_readval_clob(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_setval_variable(DB_VALUE *dest, const DB_VALUE *src, bool copy)
bool db_value_is_corrupted(const DB_VALUE *value)
Definition: db_macro.c:5094
static int mr_data_readval_resultset(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
PR_TYPE * tp_Type_string
struct db_timestamptz DB_TIMESTAMPTZ
Definition: dbtype_def.h:763
static void mr_initval_sub(DB_VALUE *value, int precision, int scale)
PR_TYPE * tp_Type_oid
#define OR_GET_BIGINT(ptr, val)
void setobj_free(COL *col)
Definition: set_object.c:4338
static int mr_getmem_utime(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int pr_midxkey_get_vals_size(TP_DOMAIN *domains, DB_VALUE *dbvals, int total)
DB_VALUE * pr_make_ext_value(void)
#define OR_GET_FLOAT(ptr, value)
static void mr_initval_float(DB_VALUE *value, int precision, int scale)
#define DO_CONVERSION_TO_SQLTEXT(codeset)
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int db_value_put_encoded_date(DB_VALUE *value, const DB_DATE *date)
Definition: db_macro.c:1383
void PRIM_SET_NULL(DB_VALUE *value)
static int mr_setmem_int(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_readval_char_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len, int align)
static int mr_index_readval_timestamptz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_setmem_money(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
unsigned char is_max_string
Definition: dbtype_def.h:981
static int mr_data_writeval_json(OR_BUF *buf, DB_VALUE *value)
static int mr_index_readval_timestampltz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
DB_OBJECT * op
Definition: dbtype_def.h:1055
PR_TYPE * tp_Type_Timestamptz
#define db_private_free(thrd, ptr)
Definition: memory_alloc.h:229
PR_TYPE tp_Substructure
static int mr_data_lengthval_string(DB_VALUE *value, int disk)
void or_init(OR_BUF *buf, char *data, int length)
int or_get_timestamptz(OR_BUF *buf, DB_TIMESTAMPTZ *ts_tz)
PR_TYPE tp_Variable
pr_type()=delete
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
static void mr_initmem_datetimetz(void *memptr, TP_DOMAIN *domain)
int intl_char_size(const unsigned char *src, int length_in_chars, INTL_CODESET src_codeset, int *byte_count)
#define CONST_CAST(dest_type, expr)
Definition: porting.h:1060
static void mr_data_readmem_elo(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
PR_TYPE * tp_Type_datetime
const OID oid_Null_oid
Definition: oid.c:68
static void mr_data_writemem_time(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
PR_TYPE * tp_Type_elo
static int pr_write_uncompressed_string_to_buffer(OR_BUF *buf, const char *string, int size, int align)
int db_json_serialize(const JSON_DOC &doc, or_buf &buffer)
Definition: db_json.cpp:3931
int pr_midxkey_get_element_nocopy(const DB_MIDXKEY *midxkey, int index, DB_VALUE *value, int *prev_indexp, char **prev_ptrp)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_datetimetz(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
need_clear_type need_clear
Definition: dbtype_def.h:1084
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_int(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initmem_time(void *mem, TP_DOMAIN *domain)
static int mr_index_lengthmem_numeric(void *mem, TP_DOMAIN *domain)
int nchar_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2, INTL_CODESET codeset)
static int mr_setval_time(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_data_writeval_ptr(OR_BUF *buf, DB_VALUE *value)
PR_TYPE * tp_Type_short
static int mr_index_readval_money(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
int pr_clear_value(DB_VALUE *value)
#define PR_INHIBIT_OID_PROMOTION_DEFAULT
DB_BIGINT db_get_bigint(const DB_VALUE *value)
void db_set_compressed_string(DB_VALUE *value, char *compressed_string, int compressed_size, bool compressed_need_clear)
DB_JSON_TYPE db_json_get_type(const JSON_DOC *doc)
Definition: db_json.cpp:2519
static void mr_initmem_money(void *memptr, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_cmpval_elo(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int db_get_deep_copy_of_json(const DB_JSON *src, DB_JSON *dst)
Definition: db_macro.c:2022
static DB_VALUE_COMPARE_RESULT mr_cmpdisk_bit_internal(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp, int align)
static void mr_data_readmem_set(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static int mr_setmem_resultset(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static void mr_initmem_set(void *memptr, TP_DOMAIN *domain)
setobj * or_get_set(OR_BUF *buf, struct tp_domain *domain)
static int mr_setmem_error(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
int db_is_updatable_object(DB_OBJECT *obj)
Definition: db_virt.c:342
static int mr_data_readval_object(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
PR_TYPE * tp_Type_blob
int varnchar_compare(const unsigned char *string1, int size1, const unsigned char *string2, int size2, INTL_CODESET codeset)
static void mr_data_readmem_resultset(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
int db_make_datetimetz(DB_VALUE *value, const DB_DATETIMETZ *datetimetz)
static void mr_data_writemem_set(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
static int mr_getmem_oid(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
PR_TYPE tp_Midxkey
struct db_domain_info::general_info general_info
int64_t DB_BIGINT
Definition: dbtype_def.h:751
#define d1
PR_TYPE * tp_Type_sequence
static AREA * Value_area
static int mr_index_readval_time(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
PR_TYPE * tp_Type_integer
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_nchar(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
index_lengthmem_function_type f_index_lengthmem
static int mr_data_writeval_utime(OR_BUF *buf, DB_VALUE *value)
#define CAST_BUFLEN
Definition: porting.h:471
int or_packed_set_length(setobj *set, int include_domain)
static void mr_data_writemem_nchar(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
int ncolumns
Definition: dbtype_def.h:864
int db_json_deserialize(OR_BUF *buf, JSON_DOC *&doc)
Definition: db_json.cpp:4266
DB_CONST_C_CHAR db_get_enum_string(const DB_VALUE *value)
static int mr_data_lengthval_varnchar(DB_VALUE *value, int disk)
PR_TYPE * tp_Type_bit
#define OR_GET_TIME(ptr, value)
int or_put_varchar(OR_BUF *buf, char *string, int charlen)
static void error(const char *msg)
Definition: gencat.c:331
static DB_VALUE_COMPARE_RESULT mr_cmpval_midxkey(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_setmem_json(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_readval_varbit_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len, int align)
static void mr_data_readmem_oid(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
int db_make_float(DB_VALUE *value, const DB_C_FLOAT num)
static DB_VALUE_COMPARE_RESULT mr_cmpval_datetime(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
int or_put_datetime(OR_BUF *buf, DB_DATETIME *datetimeval)
static void mr_initval_set(DB_VALUE *value, int precision, int scale)
static int mr_setval_set(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_index_readval_datetimetz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int rc
Definition: serial.c:50
int or_skip_varbit_remainder(OR_BUF *buf, int bitlen, int align)
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
static int mr_index_lengthval_varbit(DB_VALUE *value)
PR_TYPE tp_Bit
#define PRIM_TEMPORARY_DISK_SIZE
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_money(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_writemem_ptr(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
#define DB_GET_ENUM_ELEM_STRING_SIZE(elem)
Definition: dbtype.h:105
int pr_Inhibit_oid_promotion
int get_mem_size_of_value(const DB_VALUE *value) const
static int mr_data_readval_sub(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_index_writeval_midxkey(OR_BUF *buf, DB_VALUE *value)
int db_make_midxkey(DB_VALUE *value, DB_MIDXKEY *midxkey)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_time(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_short(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_writemem_varnchar(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
int or_put_monetary(OR_BUF *buf, DB_MONETARY *monetary)
static void mr_initmem_utime(void *mem, TP_DOMAIN *domain)
static int readval_elo_with_type(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len, DB_TYPE type)
PR_TYPE * pr_find_type(const char *name)
static void mr_freemem_varnchar(void *memptr)
DB_VALUE_COMPARE_RESULT setvobj_compare(COL *set1, COL *set2, int do_coercion, int total_order)
Definition: set_object.c:1874
index_lengthval_function_type f_index_lengthval
int get_index_size_of_mem(const void *memptr, const tp_domain *domain) const
unsigned char compressed_need_clear
Definition: dbtype_def.h:982
#define ARG_FILE_LINE
Definition: error_manager.h:44
PR_TYPE tp_String
static void mr_data_readmem_money(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static int mr_setval_string(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static void clean_up(void)
Definition: esql_cli.c:2789
#define OR_BYTE_SIZE
void db_sprint_value(const db_value *value, string_buffer &sb)
static int mr_setval_clob(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_getmem_bit(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_setval_enumeration(DB_VALUE *dest, const DB_VALUE *src, bool copy)
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
static void mr_initmem_elo(void *memptr, TP_DOMAIN *domain)
static void mr_initval_oid(DB_VALUE *value, int precision, int scale)
OID * db_get_oid(const DB_VALUE *value)
static int mr_setval_elo(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define OR_UTIME_SIZE
#define OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION
static int mr_data_readval_elo(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_initmem_string(void *mem, TP_DOMAIN *domain)
#define WS_OID(mop)
Definition: work_space.h:293
unsigned int DB_TIME
Definition: dbtype_def.h:754
static int mr_index_writeval_string(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_cmpval_bit2(DB_VALUE *value1, DB_VALUE *value2, int length, int do_coercion, int total_order, int *start_colp)
index_writeval_function_type f_index_writeval
static int mr_setval_set_internal(DB_VALUE *dest, const DB_VALUE *src, bool copy, DB_TYPE set_type)
static void mr_initmem_float(void *mem, TP_DOMAIN *domain)
int db_make_varbit(DB_VALUE *value, const int max_bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
static void mr_initval_datetimeltz(DB_VALUE *value, int precision, int scale)
int pr_is_string_type(DB_TYPE type)
unsigned int DB_DATE
Definition: dbtype_def.h:771
static int mr_data_lengthmem_varnchar(void *memptr, TP_DOMAIN *domain, int disk)
#define OR_GET_INT(ptr)
data_readmem_function_type f_data_readmem
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_json(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initval_blob(DB_VALUE *value, int precision, int scale)
static int mr_index_writeval_utime(OR_BUF *buf, DB_VALUE *value)
int pr_is_prefix_key_type(DB_TYPE type)
int db_make_error(DB_VALUE *value, const int errcode)
static int mr_index_readval_midxkey(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static void mr_freemem_json(void *memptr)
static int mr_setval_null(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_index_lengthmem_bit(void *memptr, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_datetime(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_oid(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE tp_Double
static void mr_data_readmem_char(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
char * locator
Definition: dbtype_def.h:948
PR_TYPE tp_Date
#define free_and_init(ptr)
Definition: memory_alloc.h:147
static int mr_index_lengthval_varnchar(DB_VALUE *value)
#define strlen(s1)
Definition: intl_support.c:43
static int pr_write_compressed_string_to_buffer(OR_BUF *buf, const char *compressed_string, int compressed_length, int decompressed_length, int alignment)
setmem_function_type f_setmem
int db_make_timestampltz(DB_VALUE *value, const DB_C_TIMESTAMP ts_val)
static DB_VALUE_COMPARE_RESULT mr_cmpval_variable(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
DB_DATE * db_get_date(const DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_date(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initval_vobj(DB_VALUE *value, int precision, int scale)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_ptr(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int oid_compare(const void *a, const void *b)
Definition: oid.c:243
int or_packed_varbit_length(int bitlen)
void elo_free_structure(DB_ELO *elo)
Definition: elo.c:186
static void mr_data_readmem_bigint(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
int pr_midxkey_remove_prefix(DB_VALUE *key, int prefix)
static int mr_data_lengthval_midxkey(DB_VALUE *value, int disk)
static int mr_setval_money(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_data_writeval_bigint(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_enumeration(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
DB_VALUE_COMPARE_RESULT setobj_compare_order(COL *set1, COL *set2, int do_coercion, int total_order)
Definition: set_object.c:5228
static int mr_setmem_enumeration(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
int db_value_precision(const DB_VALUE *value)
struct db_json DB_JSON
Definition: dbtype_def.h:1036
DB_DOMAIN * domain
Definition: dbtype_def.h:865
PR_TYPE tp_Json
static int mr_data_lengthval_char(DB_VALUE *value, int disk)
int setobj_release(COL *set)
Definition: set_object.c:6289
initval_function_type f_initval
#define QSTR_NCHAR_COMPARE(id, string1, size1, string2, size2, codeset, ti)
Definition: string_opfunc.h:63
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_variable(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_writemem_bit(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
#define OR_MOVE_DOUBLE(src, dst)
Definition: byte_order.h:89
#define DB_NOT_YET_COMPRESSED
Definition: dbtype_def.h:627
unsigned int date
Definition: dbtype_def.h:776
static void mr_data_writemem_datetime(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
int or_put_align32(OR_BUF *buf)
#define QSTR_IS_VARIABLE_LENGTH(s)
Definition: string_opfunc.h:54
static int mr_writeval_varbit_internal(OR_BUF *buf, DB_VALUE *value, int align)
DB_COLLECTION * set_make_reference(void)
Definition: set_object.c:1936
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
static int mr_setmem_bit(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
char * disk_set
Definition: db_set.h:44
static int mr_data_writeval_timestamptz(OR_BUF *buf, DB_VALUE *value)
int or_packed_put_varbit(OR_BUF *buf, const char *string, int bitlen)
static int mr_data_lengthmem_nchar(void *memptr, TP_DOMAIN *domain, int disk)
static int mr_setval_utime(DB_VALUE *dest, const DB_VALUE *src, bool copy)
PR_TYPE tp_Timestamptz
PR_TYPE tp_Object
static DB_VALUE_COMPARE_RESULT mr_cmpdisk_nchar_internal(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp, int align)
void * area_alloc(AREA *area)
Definition: area_alloc.c:360
static int mr_getmem_multiset(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_data_lengthmem_elo(void *memptr, TP_DOMAIN *domain, int disk)
static void mr_data_writemem_int(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
bool prm_get_bool_value(PARAM_ID prm_id)
#define OR_TIMESTAMPTZ_SIZE
#define INT_ALIGNMENT
Definition: memory_alloc.h:61
int db_get_compressed_size(DB_VALUE *value)
static int mr_getmem_elo(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
#define QSTR_IS_ANY_CHAR_OR_BIT(s)
Definition: string_opfunc.h:47
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_bigint(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_setval_oid(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_getmem_clob(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int or_get_align32(OR_BUF *buf)
static int mr_data_lengthmem_char(void *memptr, TP_DOMAIN *domain, int disk)
int intl_mbs_casecmp(const char *mbs1, const char *mbs2)
Definition: intl_support.c:358
#define OR_PUT_INT(ptr, val)
int64_t size
Definition: dbtype_def.h:947
DB_TIMESTAMP * db_get_timestamp(const DB_VALUE *value)
int pr_clear_compressed_string(DB_VALUE *value)
PR_TYPE tp_Datetimetz
int db_get_string_size(const DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_midxkey(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
DB_C_SHORT db_get_short(const DB_VALUE *value)
static int mr_getmem_timestampltz(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
#define MR_CMP_RETURN_CODE(c)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_utime(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_index_writeval_datetimetz(OR_BUF *buf, DB_VALUE *value)
int or_get_date(OR_BUF *buf, DB_DATE *date)
PR_TYPE * tp_Type_resultset
#define OR_GET_DOUBLE(ptr, value)
static int mr_getmem_double(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_setval_numeric(DB_VALUE *dest, const DB_VALUE *src, bool copy)
PR_TYPE * tp_Type_monetary
int pr_value_mem_size(const DB_VALUE *value)
PR_TYPE tp_VarNChar
static int mr_index_readval_datetimeltz(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_writeval_char(OR_BUF *buf, DB_VALUE *value)
static int mr_index_readval_enumeration(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
int area_free(AREA *area, void *ptr)
Definition: area_alloc.c:514
PR_TYPE tp_Elo
#define OR_DATETIMETZ_SIZE
static void mr_initval_enumeration(DB_VALUE *value, int precision, int scale)
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
int or_packed_put_varchar(OR_BUF *buf, char *string, int charlen)
int or_put_data(OR_BUF *buf, const char *data, int length)
static void mr_data_writemem_error(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
#define TP_FLOATING_PRECISION_VALUE
static DB_VALUE_COMPARE_RESULT mr_cmpval_sub(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static DB_VALUE_COMPARE_RESULT mr_cmpval_utime(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static DB_VALUE_COMPARE_RESULT mr_cmpval_error(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_setmem_float(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static void mr_initval_variable(DB_VALUE *value, int precision, int scale)
static void mr_initmem_varbit(void *mem, TP_DOMAIN *domain)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
static int mr_setval_midxkey(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define DB_CURRENCY_DEFAULT
Definition: dbtype.h:46
static void mr_data_writemem_money(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
int db_get_enum_collation(const DB_VALUE *value)
int i
Definition: dynamic_load.c:954
#define MR_NUMERIC_SIZE(precision)
static void mr_initmem_enumeration(void *mem, TP_DOMAIN *domain)
int db_make_resultset(DB_VALUE *value, const DB_RESULTSET handle)
static int mr_setmem_datetime(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_data_lengthval_bit(DB_VALUE *value, int disk)
static int mr_index_lengthmem_varnchar(void *memptr, TP_DOMAIN *domain)
int db_make_null(DB_VALUE *value)
static int mr_setmem_null(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
char * pr_valstring(const DB_VALUE *val)
static int mr_setval_sub(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static void mr_data_readmem_numeric(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static int mr_getmem_json(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_getmem_ptr(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
DB_TYPE id
PR_TYPE * tp_Type_multiset
static int mr_data_readval_varbit(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
static void mr_initval_ptr(DB_VALUE *value, int precision, int scale)
#define ER_OBJ_DOMAIN_CONFLICT
Definition: error_code.h:285
struct tp_domain * next
Definition: object_domain.h:74
static void mr_initval_char(DB_VALUE *value, int precision, int scale)
static int mr_writeval_char_internal(OR_BUF *buf, DB_VALUE *value, int align)
unsigned is_temp
Definition: work_space.h:149
DB_COLLECTION * set
Definition: dbtype_def.h:1063
PR_TYPE * tp_Type_time
static int mr_index_writeval_double(OR_BUF *buf, DB_VALUE *value)
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
static int mr_index_writeval_varnchar(OR_BUF *buf, DB_VALUE *value)
int or_get_data(OR_BUF *buf, char *data, int length)
static int mr_getmem_numeric(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_data_writeval_oid(OR_BUF *buf, DB_VALUE *value)
static int mr_index_writeval_money(OR_BUF *buf, DB_VALUE *value)
static int mr_setval_object(DB_VALUE *dest, const DB_VALUE *src, bool copy)
PR_TYPE * tp_Type_date
int db_get_error(const DB_VALUE *value)
TP_DOMAIN tp_Sequence_domain
DB_DATETIME * db_get_datetime(const DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_set(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define OR_GET_MONETARY(ptr, value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_bigint(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
data_writeval_function_type f_data_writeval
#define DB_MAX_VARNCHAR_PRECISION
Definition: dbtype_def.h:546
static DB_VALUE_COMPARE_RESULT mr_cmpval_set(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static void mr_data_writemem_short(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
static int mr_data_lengthval_varbit(DB_VALUE *value, int disk)
static int mr_setval_timestamptz(DB_VALUE *dest, const DB_VALUE *src, bool copy)
DB_TYPE set_get_type(DB_COLLECTION *set)
Definition: set_object.c:3566
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_double(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_initmem_short(void *mem, TP_DOMAIN *domain)
static int mr_readval_nchar_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int disk_size, bool copy, char *copy_buf, int copy_buf_len, int align)
static void mr_initval_string(DB_VALUE *value, int precision, int scale)
DB_MIDXKEY midxkey
Definition: dbtype_def.h:1065
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_date(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int setval(DB_VALUE *dest, const DB_VALUE *src, bool copy) const
int db_make_int(DB_VALUE *value, const int num)
int or_put_double(OR_BUF *buf, double num)
int db_get_string_length(const DB_VALUE *value)
static int mr_index_lengthval_nchar(DB_VALUE *value)
static void mr_initval_numeric(DB_VALUE *value, int precision, int scale)
void pr_area_final(void)
static int mr_readval_varnchar_internal(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len, int align)
static void mr_initval_elo(DB_VALUE *value, int precision, int scale)
PR_TYPE tp_Error
static int mr_data_lengthval_nchar(DB_VALUE *value, int disk)
static void mr_data_writemem_resultset(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
void pr_data_writeval(struct or_buf *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_resultset(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int intl_convert_charset(const unsigned char *src, int length_in_chars, INTL_CODESET src_codeset, unsigned char *dest, INTL_CODESET dest_codeset, int *unconverted)
Definition: intl_support.c:953
int db_make_oid(DB_VALUE *value, const OID *oid)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_null(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_index_lengthmem_varbit(void *memptr, TP_DOMAIN *domain)
static int mr_setmem_varnchar(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
cmpval_function_type f_cmpval
int db_make_char(DB_VALUE *value, const int char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
static void mr_initval_sequence(DB_VALUE *value, int precision, int scale)
static void mr_data_readmem_nchar(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
#define BITS_TO_BYTES(bit_cnt)
#define OID_ISNULL(oidp)
Definition: oid.h:81
static void mr_initmem_int(void *mem, TP_DOMAIN *domain)
char * meta_data
Definition: dbtype_def.h:949
PR_TYPE * tp_Type_set
DB_TIMESTAMP DB_UTIME
Definition: dbtype_def.h:761
static int mr_data_writeval_date(OR_BUF *buf, DB_VALUE *value)
static int mr_setval_sequence(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define LANG_SYS_CODESET
#define TP_DOMAIN_CODESET(dom)
static DB_VALUE_COMPARE_RESULT mr_cmpval_ptr(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_data_lengthval_ptr(DB_VALUE *value, int disk)
static int mr_setval_datetimetz(DB_VALUE *dest, const DB_VALUE *src, bool copy)
int or_get_int(OR_BUF *buf, int *error)
static int mr_getmem_sequence(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int collation_id
Definition: object_domain.h:92
static int mr_setval_resultset(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_numeric(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
PR_TYPE * tp_Type_error
DB_TIME * db_get_time(const DB_VALUE *value)
static int mr_setmem_string(void *memptr, TP_DOMAIN *domain, DB_VALUE *value)
int elo_copy_structure(const DB_ELO *elo, DB_ELO *dest)
Definition: elo.c:142
static void mr_data_readmem_time(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
PR_TYPE tp_Enumeration
static void mr_initval_bit(DB_VALUE *value, int precision, int scale)
static int mr_getmem_int(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static void mr_data_readmem_double(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
#define DB_GET_ENUM_ELEM_CODESET(elem)
Definition: dbtype.h:108
static int mr_data_writeval_resultset(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_object(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
DB_VALUE_COMPARE_RESULT
Definition: dbtype_def.h:199
static DB_VALUE_COMPARE_RESULT mr_cmpval_double(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_index_writeval_oid(OR_BUF *buf, DB_VALUE *value)
static void mr_initval_double(DB_VALUE *value, int precision, int scale)
static DB_VALUE_COMPARE_RESULT mr_cmpval_bit(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
DB_C_POINTER db_get_pointer(const DB_VALUE *value)
static int mr_index_writeval_int(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_int(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
#define OR_NUMERIC_SIZE(precision)
DB_VALUE_COMPARE_RESULT vobj_compare(DB_COLLECTION *set1, DB_COLLECTION *set2, int do_coercion, int total_order)
Definition: set_object.c:3517
double amount
Definition: dbtype_def.h:831
#define DB_TRIED_COMPRESSION(value)
Definition: dbtype.h:79
PR_TYPE * tp_Type_vobj
static int mr_data_writeval_int(OR_BUF *buf, DB_VALUE *value)
static int mr_setmem_datetimetz(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static void mr_initmem_error(void *memptr, TP_DOMAIN *domain)
static int mr_data_lengthval_variable(DB_VALUE *value, int disk)
static void mr_data_readmem_string(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_timestamptz(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_readmem_varbit(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
void or_put_set(OR_BUF *buf, setobj *set, int include_domain)
int db_make_bit(DB_VALUE *value, const int bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
PR_TYPE * tp_Type_double
static int mr_data_writeval_datetime(OR_BUF *buf, DB_VALUE *value)
char * buf
Definition: dbtype_def.h:866
PR_TYPE tp_ResultSet
int db_get_string_codeset(const DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_cmpval_timestamptz(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static void mr_initmem_object(void *mem, TP_DOMAIN *domain)
static int mr_setval_short(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_data_writeval_float(OR_BUF *buf, DB_VALUE *value)
static int mr_index_writeval_char(OR_BUF *buf, DB_VALUE *value)
static int mr_data_writeval_varbit(OR_BUF *buf, DB_VALUE *value)
static int mr_setmem_double(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
#define OR_DATE_SIZE
static void mr_data_writemem_datetimetz(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
static DB_VALUE_COMPARE_RESULT mr_index_cmpdisk_midxkey(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
static int mr_setval_blob(DB_VALUE *dest, const DB_VALUE *src, bool copy)
static int mr_setval_char(DB_VALUE *dest, const DB_VALUE *src, bool copy)
#define OR_DATETIME_DATE
int or_advance(OR_BUF *buf, int offset)
static void mr_initval_nchar(DB_VALUE *value, int precision, int scale)
struct db_datetimetz DB_DATETIMETZ
Definition: dbtype_def.h:780
static void mr_data_readmem_bit(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
static void mr_data_writemem_elo(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
struct db_char::@54 medium
unsigned int time
Definition: dbtype_def.h:777
static int mr_getmem_string(void *memptr, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
static int mr_lengthval_varbit_internal(DB_VALUE *value, int disk, int align)
static int mr_data_readval_int(OR_BUF *buf, DB_VALUE *value, TP_DOMAIN *domain, int size, bool copy, char *copy_buf, int copy_buf_len)
static int mr_data_lengthmem_numeric(void *mem, TP_DOMAIN *domain, int disk)
#define QSTR_COMPARE(id, string1, size1, string2, size2, ti)
Definition: string_opfunc.h:66
#define OR_GET_SHORT(ptr)
DB_VALUE_COMPARE_RESULT pr_midxkey_compare(DB_MIDXKEY *mul1, DB_MIDXKEY *mul2, int do_coercion, int total_order, int num_index_term, int *start_colp, int *result_size1, int *result_size2, int *diff_column, bool *dom_is_desc, bool *next_dom_is_desc)
static void mr_data_readmem_float(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)
int pr_complete_enum_value(DB_VALUE *value, struct tp_domain *domain)
static void mr_data_writemem_numeric(OR_BUF *buf, void *mem, TP_DOMAIN *domain)
int db_make_nchar(DB_VALUE *value, const int nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
static int mr_index_lengthval_bit(DB_VALUE *value)
static int mr_setmem_date(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
int get_disk_size_of_value(const DB_VALUE *value) const
#define VALUE_AREA_COUNT
static int mr_data_writeval_bit(OR_BUF *buf, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_cmpval_json(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
#define DB_GET_ENUM_ELEM_SHORT(elem)
Definition: dbtype.h:99
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
static int mr_setmem_utime(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
#define TP_DOMAIN_COLLATION_FLAG(dom)
static DB_VALUE_COMPARE_RESULT mr_cmpval_null(DB_VALUE *value1, DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation)
static int mr_setmem_bigint(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_varbit(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static int mr_getmem_short(void *mem, TP_DOMAIN *domain, DB_VALUE *value, bool copy)
int or_skip_varchar(OR_BUF *buf, int align)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_double(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
int db_value_alter_type(DB_VALUE *value, const DB_TYPE type)
Definition: db_macro.c:1225
static int mr_data_lengthmem_json(void *memptr, TP_DOMAIN *domain, int disk)
static int mr_setmem_timestamptz(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static int mr_setmem_sub(void *mem, TP_DOMAIN *domain, DB_VALUE *value)
static DB_VALUE_COMPARE_RESULT mr_data_cmpdisk_utime(void *mem1, void *mem2, TP_DOMAIN *domain, int do_coercion, int total_order, int *start_colp)
static void mr_data_writemem_null(OR_BUF *buf, void *memptr, TP_DOMAIN *domain)
int pr_midxkey_element_disk_size(char *mem, DB_DOMAIN *domain)
static void mr_data_readmem_ptr(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static void mr_data_readmem_object(OR_BUF *buf, void *memptr, TP_DOMAIN *domain, int size)
static void mr_data_readmem_datetimetz(OR_BUF *buf, void *mem, TP_DOMAIN *domain, int size)