File object_representation.h¶
File List > base > object_representation.h
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* object_representation.h - Definitions related to the representation of
* objects on disk and in memory.
* his file is shared by both the client and server.
*/
#ifndef _OBJECT_REPRESENTATION_H_
#define _OBJECT_REPRESENTATION_H_
#ident "$Id$"
#include <setjmp.h>
#include <time.h>
#include <float.h>
#include <limits.h>
#include <assert.h>
#if !defined(WINDOWS)
#include <netinet/in.h>
#endif /* !WINDOWS */
#include "byte_order.h"
#include "db_set.h"
#include "error_manager.h"
#include "memory_alloc.h"
#include "oid.h"
#include "object_representation_constants.h"
#include "porting_inline.hpp"
#include "storage_common.h"
#include "lock_table.h" // LOCK, lock_conv
// forward declarations
struct log_lsa;
struct setobj;
#define OR_VALUE_ALIGNED_SIZE(value) \
(or_db_value_size (value) + MAX_ALIGNMENT)
/* OVERFLOW CHECK MACROS */
#define OR_CHECK_ASSIGN_OVERFLOW(dest, src) \
(((src) > 0 && (dest) < 0) || ((src) < 0 && (dest) > 0))
#define OR_CHECK_ADD_OVERFLOW(a, b, c) \
(((a) > 0 && (b) > 0 && (c) < 0) \
|| ((a) < 0 && (b) < 0 && (c) >= 0))
#define OR_CHECK_UNS_ADD_OVERFLOW(a, b, c) \
(c) < (a) || (c) < (b)
#define OR_CHECK_SUB_UNDERFLOW(a, b, c) \
(((a) < (b) && (c) > 0) \
|| ((a) > (b) && (c) < 0))
#define OR_CHECK_UNS_SUB_UNDERFLOW(a, b, c) \
(b) > (a)
#define OR_CHECK_MULT_OVERFLOW(a, b, c) \
(((b) == 0) ? ((c) != 0) : ((c) / (b) != (a)))
#define OR_CHECK_SHORT_DIV_OVERFLOW(a, b) \
((a) == DB_INT16_MIN && (b) == -1)
#define OR_CHECK_INT_DIV_OVERFLOW(a, b) \
((a) == DB_INT32_MIN && (b) == -1)
#define OR_CHECK_BIGINT_DIV_OVERFLOW(a, b) \
((a) == DB_BIGINT_MIN && (b) == -1)
#define OR_CHECK_SHORT_OVERFLOW(i) ((i) > DB_INT16_MAX || (i) < DB_INT16_MIN)
#define OR_CHECK_INT_OVERFLOW(i) ((i) > DB_INT32_MAX || (i) < DB_INT32_MIN)
#define OR_CHECK_BIGINT_OVERFLOW(i) ((i) > DB_BIGINT_MAX || (i) < DB_BIGINT_MIN)
#define OR_CHECK_USHRT_OVERFLOW(i) ((i) > (int) DB_UINT16_MAX || (i) < 0)
#define OR_CHECK_UINT_OVERFLOW(i) ((i) > DB_UINT32_MAX || (i) < 0)
#define OR_CHECK_FLOAT_OVERFLOW(i) ((i) > FLT_MAX || (-(i)) > FLT_MAX)
#define OR_CHECK_DOUBLE_OVERFLOW(i) ((i) > DBL_MAX || (-(i)) > DBL_MAX)
/* simple macro to calculate minimum bytes to contain given bits */
#define BITS_TO_BYTES(bit_cnt) (((bit_cnt) + 7) / 8)
/* PACK/UNPACK MACROS */
/* NUMERIC */
#define OR_PUT_BYTE(ptr, val) \
(*((unsigned char *) (ptr)) = (unsigned char) (val))
#define OR_GET_BYTE(ptr) \
(*(unsigned char *) ((char *) (ptr)))
#define OR_PUT_SHORT(ptr, val) \
(*(short *) ((char *) (ptr)) = htons ((short) (val)))
#define OR_GET_SHORT(ptr) \
((short) ntohs (*(short *) ((char *) (ptr))))
#define OR_PUT_INT(ptr, val) \
(*(int *) ((char *) (ptr)) = htonl ((int) (val)))
#define OR_GET_INT(ptr) \
((int) ntohl (*(int *) ((char *) (ptr))))
#define OR_PUT_INT64(ptr, val) \
do { \
INT64 packed_value; \
packed_value = ((INT64) swap64 (*(INT64*) val)); \
memcpy (ptr, &packed_value, OR_INT64_SIZE); \
} while (0)
#define OR_GET_INT64(ptr, val) \
do { \
INT64 packed_value; \
memcpy (&packed_value, ptr, OR_INT64_SIZE); \
*((INT64*) (val)) = ((INT64) swap64 (packed_value)); \
} while (0)
#define OR_PUT_BIGINT(ptr, val) do { \
assert (OR_BIGINT_SIZE == OR_INT64_SIZE); \
INT64* pval = (INT64*) (val); \
OR_PUT_INT64 (ptr, pval); \
} while (0)
#define OR_GET_BIGINT(ptr, val) do { \
assert (OR_BIGINT_SIZE == OR_INT64_SIZE); \
INT64* pval = (INT64*) (val); \
OR_GET_INT64 (ptr, pval); \
} while (0)
STATIC_INLINE void
OR_PUT_FLOAT (char *ptr, float val)
{
UINT32 ui = htonf (val);
memcpy (ptr, &ui, sizeof (ui));
}
#define OR_GET_FLOAT(ptr, value) \
(*(value) = ntohf (*(UINT32 *) (ptr)))
STATIC_INLINE void
OR_PUT_DOUBLE (char *ptr, double val)
{
UINT64 ui = htond (val);
memcpy (ptr, &ui, sizeof (ui));
}
#define OR_GET_DOUBLE(ptr, value) \
(*(value) = ntohd (*(UINT64 *) (ptr)))
#if __WORDSIZE == 32
#define OR_PUT_PTR(ptr, val) OR_PUT_INT ((ptr), (val))
#define OR_GET_PTR(ptr) OR_GET_INT ((ptr))
#else /* __WORDSIZE == 32 */
#define OR_PUT_PTR(ptr, val) (*(UINTPTR *) ((char *) (ptr)) = swap64 ((UINTPTR) val))
#define OR_GET_PTR(ptr) ((UINTPTR) swap64 (*(UINTPTR *) ((char *) (ptr))))
#endif /* __WORDSIZE == 64 */
/* EXTENDED TYPE */
#define OR_PUT_TIME(ptr, value) \
OR_PUT_INT (ptr, *((DB_TIME *) (value)))
#define OR_GET_TIME(ptr, value) \
*((DB_TIME *) (value)) = OR_GET_INT (ptr)
#define OR_PUT_UTIME(ptr, value) \
OR_PUT_INT (ptr, *((DB_UTIME *) (value)))
#define OR_GET_UTIME(ptr, value) \
*((DB_UTIME *) (value)) = OR_GET_INT (ptr)
#define OR_PUT_TIMESTAMPTZ(ptr, ts_tz) \
do { \
OR_PUT_INT (((char *) ptr), (ts_tz)->timestamp); \
OR_PUT_INT (((char *) ptr) + OR_TIMESTAMPTZ_TZID, (ts_tz)->tz_id); \
} while (0)
#define OR_GET_TIMESTAMPTZ(ptr, ts_tz) \
do { \
(ts_tz)->timestamp = OR_GET_INT ((char *) (ptr)); \
(ts_tz)->tz_id = OR_GET_INT (((char *) (ptr)) + OR_TIMESTAMPTZ_TZID); \
} while (0)
#define OR_PUT_DATE(ptr, value) \
OR_PUT_INT (ptr, *((DB_DATE *) (value)))
#define OR_GET_DATE(ptr, value) \
*((DB_DATE *) (value)) = OR_GET_INT (ptr)
#define OR_PUT_DATETIME(ptr, datetime) \
do { \
OR_PUT_INT (((char *)ptr) + OR_DATETIME_DATE, (datetime)->date); \
OR_PUT_INT (((char *)ptr) + OR_DATETIME_TIME, (datetime)->time); \
} while (0)
#define OR_GET_DATETIME(ptr, datetime) \
do { \
(datetime)->date = OR_GET_INT (((char *) (ptr)) + OR_DATETIME_DATE); \
(datetime)->time = OR_GET_INT (((char *) (ptr)) + OR_DATETIME_TIME); \
} while (0)
#define OR_PUT_DATETIMETZ(ptr, datetimetz) \
do { \
OR_PUT_DATETIME (((char *) ptr), \
&((DB_DATETIMETZ *) datetimetz)->datetime); \
OR_PUT_INT (((char *) ptr) + OR_DATETIMETZ_TZID, (datetimetz)->tz_id); \
} while (0)
#define OR_GET_DATETIMETZ(ptr, datetimetz) \
do { \
OR_GET_DATETIME ((char *) ptr, \
&((DB_DATETIMETZ *) datetimetz)->datetime); \
(datetimetz)->tz_id = OR_GET_INT (((char *) (ptr)) + OR_DATETIMETZ_TZID); \
} while (0)
#define OR_PUT_MONETARY(ptr, value) \
do { \
char pack_value[OR_DOUBLE_SIZE]; \
OR_PUT_INT (((char *) (ptr)) + OR_MONETARY_TYPE, (int) (value)->type); \
OR_PUT_DOUBLE (pack_value, (value)->amount); \
memcpy (((char *) (ptr)) + OR_MONETARY_AMOUNT, pack_value, OR_DOUBLE_SIZE); \
} while (0)
#define OR_GET_MONETARY(ptr, value) \
do { \
UINT64 pack_value; \
(value)->type = (DB_CURRENCY) OR_GET_INT (((char *) (ptr)) + OR_MONETARY_TYPE); \
memcpy ((char *) (&pack_value), ((char *) (ptr)) + OR_MONETARY_AMOUNT, OR_DOUBLE_SIZE); \
OR_GET_DOUBLE (&pack_value, &(value)->amount); \
} while (0)
#define OR_MOVE_MONETARY(src, dst) \
do { \
OR_MOVE_DOUBLE (src, dst); \
((DB_MONETARY *) dst)->type = ((DB_MONETARY *) src)->type; \
} while (0)
#define OR_GET_CURRENCY_TYPE(ptr) \
(DB_CURRENCY) OR_GET_INT (((char *) (ptr)) + OR_MONETARY_TYPE)
#define OR_PUT_SHA1(ptr, value) \
do { \
int i = 0; \
for (; i < 5; i++) \
{ \
OR_PUT_INT (ptr + i * OR_INT_SIZE, ((SHA1Hash *) (value))->h[i]); \
} \
} while (0)
#define OR_GET_SHA1(ptr, value) \
do { \
int i = 0; \
for (; i < 5; i++) \
{ \
((SHA1Hash *) (value))->h[i] = (INT32) OR_GET_INT (ptr + i * OR_INT_SIZE); \
} \
} while (0)
#define OR_GET_STRING(ptr) \
((char *) ((char *) (ptr)))
/* DISK IDENTIFIERS */
#define OR_GET_OID(ptr, oid) \
do { \
(oid)->pageid = OR_GET_INT (((char *) (ptr)) + OR_OID_PAGEID); \
(oid)->slotid = OR_GET_SHORT (((char *) (ptr)) + OR_OID_SLOTID); \
(oid)->volid = OR_GET_SHORT (((char *) (ptr)) + OR_OID_VOLID); \
} while (0)
#define OR_PUT_OID(ptr, oid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_OID_PAGEID, (oid)->pageid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_OID_SLOTID, (oid)->slotid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_OID_VOLID, (oid)->volid); \
} while (0)
#define OR_GET_VPID(ptr, vpid) \
do { \
(vpid)->pageid = OR_GET_INT (((char *) (ptr)) + OR_VPID_PAGEID); \
(vpid)->volid = OR_GET_SHORT (((char *) (ptr)) + OR_VPID_VOLID); \
} while (0)
#define OR_PUT_VPID(ptr, vpid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_VPID_PAGEID, (vpid)->pageid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_VPID_VOLID, (vpid)->volid); \
} while (0)
#define OR_PUT_VPID_ALIGNED(ptr, vpid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_VPID_PAGEID, (vpid)->pageid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_VPID_VOLID, (vpid)->volid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_VPID_SIZE, 0); \
} while (0)
#define OR_PUT_NULL_OID(ptr) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_OID_PAGEID, NULL_PAGEID); \
OR_PUT_SHORT (((char *) (ptr)) + OR_OID_SLOTID, 0); \
OR_PUT_SHORT (((char *) (ptr)) + OR_OID_VOLID, 0); \
} while (0)
#define OR_GET_HFID(ptr, hfid) \
do { \
(hfid)->hpgid = OR_GET_INT (((char *) (ptr)) + OR_HFID_PAGEID); \
(hfid)->vfid.fileid = OR_GET_INT (((char *) (ptr)) + OR_HFID_VFID_FILEID); \
(hfid)->vfid.volid = OR_GET_INT (((char *) (ptr)) + OR_HFID_VFID_VOLID); \
} while (0)
#define OR_PUT_HFID(ptr, hfid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_PAGEID, (hfid)->hpgid); \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_VFID_FILEID, (hfid)->vfid.fileid); \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_VFID_VOLID, (hfid)->vfid.volid); \
} while (0)
#define OR_PUT_NULL_HFID(ptr) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_PAGEID, -1); \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_VFID_FILEID, -1); \
OR_PUT_INT (((char *) (ptr)) + OR_HFID_VFID_VOLID, -1); \
} while (0)
#define OR_GET_BTID(ptr, btid) \
do { \
(btid)->root_pageid = OR_GET_INT (((char *) (ptr)) + OR_BTID_PAGEID); \
(btid)->vfid.fileid = OR_GET_INT (((char *) (ptr)) + OR_BTID_VFID_FILEID); \
(btid)->vfid.volid = OR_GET_SHORT (((char *) (ptr)) + OR_BTID_VFID_VOLID); \
} while (0)
#define OR_PUT_BTID(ptr, btid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_BTID_PAGEID, (btid)->root_pageid); \
OR_PUT_INT (((char *) (ptr)) + OR_BTID_VFID_FILEID, (btid)->vfid.fileid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_BTID_VFID_VOLID, (btid)->vfid.volid); \
} while (0)
#define OR_PUT_NULL_BTID(ptr) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_BTID_PAGEID, NULL_PAGEID); \
OR_PUT_INT (((char *) (ptr)) + OR_BTID_VFID_FILEID, NULL_FILEID); \
OR_PUT_SHORT (((char *) (ptr)) + OR_BTID_VFID_VOLID, NULL_VOLID); \
} while (0)
#define OR_GET_EHID(ptr, ehid) \
do { \
(ehid)->vfid.volid = OR_GET_INT (((char *) (ptr)) + OR_EHID_VOLID); \
(ehid)->vfid.fileid = OR_GET_INT (((char *) (ptr)) + OR_EHID_FILEID); \
(ehid)->pageid = OR_GET_INT (((char *) (ptr)) + OR_EHID_PAGEID); \
} while (0)
#define OR_PUT_EHID(ptr, ehid) \
do { \
OR_PUT_INT (((char *) (ptr)) + OR_EHID_VOLID, (ehid)->vfid.volid); \
OR_PUT_INT (((char *) (ptr)) + OR_EHID_FILEID, (ehid)->vfid.fileid); \
OR_PUT_INT (((char *) (ptr)) + OR_EHID_PAGEID, (ehid)->pageid); \
} while (0)
#define OR_GET_LOG_LSA(ptr, lsa) \
do { \
INT64 value; \
OR_GET_INT64 (((char *) (ptr)) + OR_LOG_LSA_PAGEID, &value); \
(lsa)->pageid = value; \
(lsa)->offset = OR_GET_SHORT (((char *) (ptr)) + OR_LOG_LSA_OFFSET); \
} while (0)
#define OR_PUT_LOG_LSA(ptr, lsa) \
do { \
INT64 pageid = (lsa)->pageid; \
OR_PUT_INT64 (((char *) (ptr)) + OR_LOG_LSA_PAGEID, &pageid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_LOG_LSA_OFFSET, (lsa)->offset); \
} while (0)
#define OR_PUT_NULL_LOG_LSA(ptr) \
do { \
INT64 pageid = -1; \
OR_PUT_INT64 (((char *) (ptr)) + OR_LOG_LSA_PAGEID, &pageid); \
OR_PUT_SHORT (((char *) (ptr)) + OR_LOG_LSA_OFFSET, -1); \
} while (0)
/* VARIABLE OFFSET ACCESSORS */
#define OR_PUT_BIG_VAR_OFFSET(ptr, val) \
OR_PUT_INT ((ptr), (val))
#define OR_GET_BIG_VAR_OFFSET(ptr) \
OR_GET_INT ((ptr))
#define OR_PUT_OFFSET(ptr, val) \
OR_PUT_BIG_VAR_OFFSET ((ptr), (val))
#define OR_GET_OFFSET(ptr) \
OR_GET_BIG_VAR_OFFSET ((ptr))
#define OR_PUT_OFFSET_INTERNAL(ptr, val, offset_size) \
do { \
if ((offset_size) == OR_BYTE_SIZE) \
{ \
OR_PUT_BYTE ((ptr), (val)); \
} \
else if ((offset_size) == OR_SHORT_SIZE) \
{ \
OR_PUT_SHORT ((ptr), (val)); \
} \
else \
{ \
assert ((offset_size) == OR_INT_SIZE); \
OR_PUT_INT ((ptr), (val)); \
} \
} while (0)
#define OR_GET_OFFSET_INTERNAL(ptr, offset_size) \
((offset_size) == OR_BYTE_SIZE) \
? OR_GET_BYTE ((ptr)) \
: (((offset_size) == OR_SHORT_SIZE) \
? OR_GET_SHORT ((ptr)) : OR_GET_INT ((ptr)))
/*
* VARIABLE OFFSET TABLE ACCESSORS
* The variable offset table is present in the headers of objects and sets.
*/
#define OR_VAR_TABLE_SIZE(vars) \
(OR_VAR_TABLE_SIZE_INTERNAL (vars, BIG_VAR_OFFSET_SIZE))
#define OR_VAR_TABLE_SIZE_INTERNAL(vars, offset_size) \
(((vars) == 0) ? 0 : DB_ALIGN ((offset_size * ((vars) + 1)), INT_ALIGNMENT))
#define OR_VAR_TABLE_ELEMENT_PTR(table, index, offset_size) \
((offset_size == OR_BYTE_SIZE) \
? (&((char *) (table))[(index)]) \
: ((offset_size == OR_SHORT_SIZE) \
? ((char *) (&((short *) (table))[(index)])) \
: ((char *) (&((int *) (table))[(index)]))))
#define OR_VAR_TABLE_ELEMENT_OFFSET_INTERNAL(table, index, offset_size) \
((offset_size == OR_BYTE_SIZE) \
? (OR_GET_BYTE (OR_VAR_TABLE_ELEMENT_PTR (table, index, offset_size))) \
: ((offset_size == OR_SHORT_SIZE) \
? (OR_GET_SHORT (OR_VAR_TABLE_ELEMENT_PTR (table, index, offset_size))) \
: (OR_GET_INT (OR_VAR_TABLE_ELEMENT_PTR (table, index, offset_size)))))
#define OR_VAR_TABLE_ELEMENT_LENGTH_INTERNAL(table, index, offset_size) \
(OR_VAR_TABLE_ELEMENT_OFFSET_INTERNAL (table, (index) + 1, offset_size) \
- OR_VAR_TABLE_ELEMENT_OFFSET_INTERNAL (table, (index), offset_size))
/* ATTRIBUTE LOCATION */
#define OR_FIXED_ATTRIBUTES_OFFSET(ptr, nvars) \
(OR_FIXED_ATTRIBUTES_OFFSET_INTERNAL (ptr, nvars, BIG_VAR_OFFSET_SIZE))
#define OR_FIXED_ATTRIBUTES_OFFSET_INTERNAL(ptr, nvars, offset_size) \
(OR_HEADER_SIZE (ptr) + OR_VAR_TABLE_SIZE_INTERNAL (nvars, offset_size))
/* OBJECT HEADER LAYOUT */
/* header fixed-size in non-MVCC only, in MVCC the header has variable size */
#define OR_HEADER_SIZE(ptr) (or_header_size ((char *) (ptr)))
/* representation offset in MVCC and non-MVCC. In MVCC the representation
* contains flags that allow to compute header size and CHN offset.
*/
#define OR_REP_OFFSET 0
#define OR_MVCC_REP_SIZE 4
#define OR_MVCC_FLAG_OFFSET OR_REP_OFFSET
#define OR_MVCC_FLAG_SIZE OR_MVCC_REP_SIZE
#define OR_CHN_OFFSET (OR_REP_OFFSET + OR_MVCC_REP_SIZE)
#define OR_CHN_SIZE 4
#define OR_MVCC_INSERT_ID_OFFSET (OR_CHN_OFFSET + OR_CHN_SIZE)
#define OR_MVCC_INSERT_ID_SIZE 8
#define OR_MVCC_DELETE_ID_OFFSET(mvcc_flags) \
(OR_MVCC_INSERT_ID_OFFSET + (((mvcc_flags) & OR_MVCC_FLAG_VALID_INSID) ? OR_MVCC_INSERT_ID_SIZE : 0))
#define OR_MVCC_DELETE_ID_SIZE 8
#define OR_MVCC_PREV_VERSION_LSA_OFFSET(mvcc_flags) \
(OR_MVCC_DELETE_ID_OFFSET(mvcc_flags) + (((mvcc_flags) & OR_MVCC_FLAG_VALID_DELID) ? OR_MVCC_DELETE_ID_SIZE : 0))
#define OR_MVCC_PREV_VERSION_LSA_SIZE 8
/* MVCC */
#define OR_MVCCID_SIZE OR_BIGINT_SIZE
#define OR_PUT_MVCCID OR_PUT_BIGINT
#define OR_GET_MVCCID OR_GET_BIGINT
/* In case MVCC is enabled and chn is needed it will be saved instead of
* delete MVCC id.
*/
/* high bit of the repid word is reserved for the bound bit flag,
need to keep representations from going negative ! */
#define OR_BOUND_BIT_FLAG 0x80000000
#define BIG_VAR_OFFSET_SIZE OR_INT_SIZE /* 4byte */
#define SHORT_VAR_OFFSET_SIZE OR_SHORT_SIZE /* 2byte */
/* OBJECT HEADER ACCESS MACROS */
#define OR_GET_REPID(ptr) \
((OR_GET_INT ((ptr) + OR_REP_OFFSET)) & ~OR_BOUND_BIT_FLAG & ~OR_OFFSET_SIZE_FLAG)
#define OR_GET_BOUND_BIT_FLAG(ptr) \
((OR_GET_INT ((ptr) + OR_REP_OFFSET)) & OR_BOUND_BIT_FLAG)
#define OR_GET_OFFSET_SIZE(ptr) \
((((OR_GET_INT (((char *) (ptr)) + OR_REP_OFFSET)) & OR_OFFSET_SIZE_FLAG) == OR_OFFSET_SIZE_1BYTE) \
? OR_BYTE_SIZE \
: ((((OR_GET_INT (((char *) (ptr)) + OR_REP_OFFSET)) & OR_OFFSET_SIZE_FLAG) == OR_OFFSET_SIZE_2BYTE) \
? OR_SHORT_SIZE : OR_INT_SIZE))
#define OR_SET_VAR_OFFSET_SIZE(val, offset_size) \
(((offset_size) == OR_BYTE_SIZE) \
? ((val) |= OR_OFFSET_SIZE_1BYTE) \
: (((offset_size) == OR_SHORT_SIZE) \
? ((val) |= OR_OFFSET_SIZE_2BYTE) \
: ((val) |= OR_OFFSET_SIZE_4BYTE)))
/* MVCC OBJECT HEADER ACCESS MACROS */
#define OR_GET_MVCC_INSERT_ID(ptr, mvcc_flags, valp) \
((((mvcc_flags) & OR_MVCC_FLAG_VALID_INSID) == 0) \
? MVCCID_ALL_VISIBLE \
: (OR_GET_BIGINT (((char *) (ptr)) + OR_MVCC_INSERT_ID_OFFSET, (valp))))
#define OR_GET_MVCC_DELETE_ID(ptr, mvcc_flags, valp) \
((((mvcc_flags) & OR_MVCC_FLAG_VALID_DELID) == 0) \
? MVCCID_NULL \
: (OR_GET_BIGINT (((char *) (ptr)) + OR_MVCC_DELETE_ID_OFFSET(mvcc_flags), (valp))))
#define OR_GET_MVCC_REPID(ptr) \
((OR_GET_INT(((char *) (ptr)) + OR_REP_OFFSET)) \
& OR_MVCC_REPID_MASK)
#define OR_GET_MVCC_CHN(ptr) (OR_GET_INT ((char *) (ptr) + OR_CHN_OFFSET))
#define OR_GET_MVCC_FLAG(ptr) \
(((OR_GET_INT (((char *) (ptr)) + OR_REP_OFFSET)) \
>> OR_MVCC_FLAG_SHIFT_BITS) & OR_MVCC_FLAG_MASK)
#define OR_GET_MVCC_REPID_AND_FLAG(ptr) \
(OR_GET_INT (((char *) (ptr)) + OR_REP_OFFSET))
/* VARIABLE OFFSET TABLE ACCESSORS */
#define OR_GET_OBJECT_VAR_TABLE(obj) \
((short *) (((char *) (obj)) + OR_HEADER_SIZE ((char *) (obj))))
#define OR_VAR_ELEMENT_PTR(obj, index) \
(OR_VAR_TABLE_ELEMENT_PTR (OR_GET_OBJECT_VAR_TABLE (obj), index, OR_GET_OFFSET_SIZE (obj)))
#define OR_VAR_OFFSET(obj, index) \
(OR_HEADER_SIZE (obj) \
+ OR_VAR_TABLE_ELEMENT_OFFSET_INTERNAL (OR_GET_OBJECT_VAR_TABLE (obj), \
index, OR_GET_OFFSET_SIZE (obj)))
#define OR_VAR_IS_NULL(obj, index) \
((OR_VAR_TABLE_ELEMENT_LENGTH_INTERNAL (OR_GET_OBJECT_VAR_TABLE (obj), \
index, OR_GET_OFFSET_SIZE (obj))) ? 0 : 1)
#define OR_VAR_LENGTH(length, obj, index, n_variables) \
do { \
int _this_offset, _next_offset, _temp_offset, _nth_var; \
_this_offset = OR_VAR_OFFSET(obj, index); \
_next_offset = OR_VAR_OFFSET(obj, index + 1); \
if ((length = _next_offset - _this_offset) != 0) \
{ \
_next_offset = 0; \
for (_nth_var = 0; _nth_var <= n_variables; _nth_var++) \
{ \
_temp_offset = OR_VAR_OFFSET(obj, _nth_var); \
if (_temp_offset > _this_offset ) \
{ \
if (_next_offset == 0) \
{ \
_next_offset = _temp_offset; \
} \
else if (_temp_offset < _next_offset) \
{ \
_next_offset = _temp_offset; \
} \
} \
} \
length = _next_offset - _this_offset; \
} \
} while (0)
/*
* BOUND BIT ACCESSORS.
* Note that these are assuming 4 byte integers to avoid a divide operation.
*/
#define OR_BOUND_BIT_WORDS(count) (((count) + 31) >> 5)
#define OR_BOUND_BIT_BYTES(count) ((((count) + 31) >> 5) * 4)
#define OR_BOUND_BIT_MASK(element) (1 << ((int) (element) & 7))
#define OR_GET_BOUND_BIT_BYTE(bitptr, element) \
((char *) (bitptr) + ((int) (element) >> 3))
#define OR_GET_BOUND_BIT(bitptr, element) \
((*OR_GET_BOUND_BIT_BYTE ((bitptr), (element))) & OR_BOUND_BIT_MASK ((element)))
#define OR_GET_BOUND_BITS(obj, nvars, fsize) \
(char *) (((char *) (obj)) \
+ OR_HEADER_SIZE ((char *) (obj)) \
+ OR_VAR_TABLE_SIZE_INTERNAL ((nvars), OR_GET_OFFSET_SIZE (obj)) + (fsize))
/* These are the most useful ones if we're only testing a single attribute */
#define OR_FIXED_ATT_IS_BOUND(obj, nvars, fsize, position) \
(!OR_GET_BOUND_BIT_FLAG (obj) || OR_GET_BOUND_BIT (OR_GET_BOUND_BITS (obj, nvars, fsize), position))
#define OR_FIXED_ATT_IS_UNBOUND(obj, nvars, fsize, position) \
(OR_GET_BOUND_BIT_FLAG (obj) && !OR_GET_BOUND_BIT (OR_GET_BOUND_BITS (obj, nvars, fsize), position))
#define OR_ENABLE_BOUND_BIT(bitptr, element) \
*OR_GET_BOUND_BIT_BYTE (bitptr, element) = *OR_GET_BOUND_BIT_BYTE (bitptr, element) | OR_BOUND_BIT_MASK (element)
#define OR_CLEAR_BOUND_BIT(bitptr, element) \
*OR_GET_BOUND_BIT_BYTE (bitptr, element) = *OR_GET_BOUND_BIT_BYTE (bitptr, element) & ~OR_BOUND_BIT_MASK (element)
/* SET HEADER */
#define OR_SET_HEADER_SIZE 8
#define OR_SET_SIZE_OFFSET 4
/* optional header extension if the full domain is present */
#define OR_SET_DOMAIN_SIZE_OFFSET 8
/* Set header fields.
These constants are used to construct and decompose the set header word. */
#define OR_SET_TYPE_MASK 0xFF
#define OR_SET_ETYPE_MASK 0xFF00
#define OR_SET_ETYPE_SHIFT 8
#define OR_SET_BOUND_BIT 0x10000
#define OR_SET_VARIABLE_BIT 0x20000
#define OR_SET_DOMAIN_BIT 0x40000
#define OR_SET_TAG_BIT 0x80000
#define OR_SET_COMMON_SUB_BIT 0x100000
#define OR_SET_TYPE(setptr) \
(DB_TYPE) ((OR_GET_INT ((char *) (setptr))) & OR_SET_TYPE_MASK)
#define OR_SET_ELEMENT_TYPE(setptr) \
(DB_TYPE) ((OR_GET_INT ((char *) (setptr)) & OR_SET_ETYPE_MASK) >> OR_SET_ETYPE_SHIFT)
#define OR_SET_HAS_BOUND_BITS(setptr) \
(OR_GET_INT ((char *) (setptr)) & OR_SET_BOUND_BIT)
#define OR_SET_HAS_OFFSET_TABLE(setptr) \
(OR_GET_INT ((char *) (setptr)) & OR_SET_VARIABLE_BIT)
#define OR_SET_HAS_DOMAIN(setptr) \
(OR_GET_INT ((char *) (setptr)) & OR_SET_DOMAIN_BIT)
#define OR_SET_HAS_ELEMENT_TAGS(setptr) \
(OR_GET_INT ((char *) (setptr)) & OR_SET_TAG_BIT)
#define OR_SET_ELEMENT_COUNT(setptr) \
((OR_GET_INT ((char *) (setptr) + OR_SET_SIZE_OFFSET)))
#define OR_SET_DOMAIN_SIZE(setptr) \
((OR_GET_INT ((char *) (setptr) + OR_SET_DOMAIN_SIZE_OFFSET)))
/*
* SET VARIABLE OFFSET TABLE ACCESSORS.
* Should make sure that the set actually has one before using.
*/
#define OR_GET_SET_VAR_TABLE(setptr) \
((int *) ((char *) (setptr) + OR_SET_HEADER_SIZE))
#define OR_SET_ELEMENT_OFFSET(setptr, element) \
(OR_VAR_TABLE_ELEMENT_OFFSET_INTERNAL (OR_GET_SET_VAR_TABLE (setptr), element, BIG_VAR_OFFSET_SIZE))
/*
* SET BOUND BIT ACCESSORS
*
* Should make sure that the set actually has these before using.
* Its essentially the same as OR_GET_SET_VAR_TABLE since these will
* be in the same position and can't both appear at the same time.
*/
#define OR_GET_SET_BOUND_BITS(setptr) \
(int *) ((char *) (setptr) + OR_SET_HEADER_SIZE)
/*
* OR_SUB_HEADER_SIZE
*
* Used to tag each substructure. Same as the object header currently.
* class oid, repid, flags
*/
#define OR_SUB_HEADER_SIZE OR_OID_SIZE + OR_INT_SIZE + OR_INT_SIZE
/*
* OR_SUB_DOMAIN_AND_HEADER_SIZE
*
* Hack for the class transformer, since we always currently know what the
* substructure lists contain, this allows us to skip over the packed domain
* quickly. Must match the stuff packed by or_put_sub_domain_and_header().
*/
#define OR_SUB_DOMAIN_SIZE OR_INT_SIZE
/* VARIABLE HEADER */
#define OR_VARIABLE_HEADER_SIZE 4
#define OR_GET_VARIABLE_TYPE(ptr) (OR_GET_INT ((int *) (ptr)))
/* class */
enum
{
ORC_REP_DIR_OFFSET = 8,
ORC_HFID_FILEID_OFFSET = 16,
ORC_HFID_VOLID_OFFSET = 20,
ORC_HFID_PAGEID_OFFSET = 24,
ORC_FIXED_COUNT_OFFSET = 28,
ORC_VARIABLE_COUNT_OFFSET = 32,
ORC_FIXED_LENGTH_OFFSET = 36,
ORC_ATT_COUNT_OFFSET = 40,
ORC_SHARED_COUNT_OFFSET = 48,
ORC_CLASS_ATTR_COUNT_OFFSET = 60,
ORC_CLASS_FLAGS = 64,
ORC_CLASS_TYPE = 68,
ORC_CLASS_TDE_ALGORITHM = 84
};
enum
{
ORC_NAME_INDEX = 0,
ORC_LOADER_COMMANDS_INDEX = 1,
ORC_REPRESENTATIONS_INDEX = 2,
ORC_SUBCLASSES_INDEX = 3,
ORC_SUPERCLASSES_INDEX = 4,
ORC_ATTRIBUTES_INDEX = 5,
ORC_SHARED_ATTRS_INDEX = 6,
ORC_CLASS_ATTRS_INDEX = 7,
ORC_METHODS_INDEX = 8,
ORC_CLASS_METHODS_INDEX = 9,
ORC_METHOD_FILES_INDEX = 10,
ORC_RESOLUTIONS_INDEX = 11,
ORC_QUERY_SPEC_INDEX = 12,
ORC_TRIGGERS_INDEX = 13,
ORC_PROPERTIES_INDEX = 14,
ORC_COMMENT_INDEX = 15,
ORC_PARTITION_INDEX = 16,
/* add a new one above */
ORC_LAST_INDEX,
ORC_CLASS_VAR_ATT_COUNT = ORC_LAST_INDEX
};
/* attribute */
enum
{
ORC_ATT_ID_OFFSET = 0,
ORC_ATT_TYPE_OFFSET = 4,
ORC_ATT_DEF_ORDER_OFFSET = 12,
ORC_ATT_CLASS_OFFSET = 16,
ORC_ATT_FLAG_OFFSET = 24,
ORC_ATT_INDEX_OFFSET = 28
};
enum
{
ORC_ATT_NAME_INDEX = 0,
ORC_ATT_CURRENT_VALUE_INDEX = 1,
ORC_ATT_ORIGINAL_VALUE_INDEX = 2,
ORC_ATT_DOMAIN_INDEX = 3,
ORC_ATT_TRIGGER_INDEX = 4,
ORC_ATT_PROPERTIES_INDEX = 5,
ORC_ATT_COMMENT_INDEX = 6,
/* add a new one above */
ORC_ATT_LAST_INDEX,
ORC_ATT_VAR_ATT_COUNT = ORC_ATT_LAST_INDEX
};
/* representation */
enum
{
ORC_REP_ID_OFFSET = 0,
ORC_REP_FIXED_COUNT_OFFSET = 4,
ORC_REP_VARIABLE_COUNT_OFFSET = 8
};
enum
{
ORC_REP_ATTRIBUTES_INDEX = 0,
ORC_REP_PROPERTIES_INDEX = 1,
/* add a new one above */
ORC_REP_LAST_INDEX,
ORC_REP_VAR_ATT_COUNT = ORC_REP_LAST_INDEX
};
/* rep_attribute */
enum
{
ORC_REPATT_ID_OFFSET = 0,
ORC_REPATT_TYPE_OFFSET = 4
};
enum
{
ORC_REPATT_DOMAIN_INDEX = 0,
/* add a new one above */
ORC_REPATT_LAST_INDEX,
ORC_REPATT_VAR_ATT_COUNT = ORC_REPATT_LAST_INDEX
};
/* domain */
enum
{
ORC_DOMAIN_TYPE_OFFSET = 0,
ORC_DOMAIN_PRECISION_OFFSET = 4,
ORC_DOMAIN_SCALE_OFFSET = 8,
ORC_DOMAIN_CODESET_OFFSET = 12,
ORC_DOMAIN_COLLATION_ID_OFFSET = 16,
ORC_DOMAIN_CLASS_OFFSET = 20
};
enum
{
ORC_DOMAIN_SETDOMAIN_INDEX = 0,
ORC_DOMAIN_ENUMERATION_INDEX = 1,
ORC_DOMAIN_SCHEMA_JSON_OFFSET = 2,
/* add a new one above */
ORC_DOMAIN_LAST_INDEX,
ORC_DOMAIN_VAR_ATT_COUNT = ORC_DOMAIN_LAST_INDEX
};
/* method */
enum
{
ORC_METHOD_NAME_INDEX = 0,
ORC_METHOD_SIGNATURE_INDEX = 1,
ORC_METHOD_PROPERTIES_INDEX = 2,
/* add a new one above */
ORC_METHOD_LAST_INDEX,
ORC_METHOD_VAR_ATT_COUNT = ORC_METHOD_LAST_INDEX
};
/* method argument */
enum
{
ORC_METHARG_DOMAIN_INDEX = 0,
/* add a new one above */
ORC_METHARG_LAST_INDEX,
ORC_METHARG_VAR_ATT_COUNT = ORC_METHARG_LAST_INDEX
};
/* method signature */
enum
{
ORC_METHSIG_FUNCTION_NAME_INDEX = 0,
ORC_METHSIG_SQL_DEF_INDEX = 1,
ORC_METHSIG_RETURN_VALUE_INDEX = 2,
ORC_METHSIG_ARGUMENTS_INDEX = 3,
/* add a new one above */
ORC_METHSIG_LAST_INDEX,
ORC_METHSIG_VAR_ATT_COUNT = ORC_METHSIG_LAST_INDEX
};
/* method file */
enum
{
ORC_METHFILE_NAME_INDEX = 0,
ORC_METHFILE_PROPERTIES_INDEX = 1,
/* add a new one above */
ORC_METHFILE_LAST_INDEX,
ORC_METHFILE_VAR_ATT_COUNT = ORC_METHFILE_LAST_INDEX
};
/* query spec */
enum
{
ORC_QUERY_SPEC_SPEC_INDEX = 0,
/* add a new one above */
ORC_QUERY_LAST_INDEX,
ORC_QUERY_SPEC_VAR_ATT_COUNT = ORC_QUERY_LAST_INDEX
};
/* resolution */
enum
{
ORC_RES_NAME_INDEX = 0,
ORC_RES_ALIAS_INDEX = 1,
/* add a new one above */
ORC_RES_LAST_INDEX,
ORC_RES_VAR_ATT_COUNT = ORC_RES_LAST_INDEX
};
/* partition */
enum
{
ORC_PARTITION_NAME_INDEX = 0,
ORC_PARTITION_EXPR_INDEX = 1,
ORC_PARTITION_VALUES_INDEX = 2,
ORC_PARTITION_COMMENT_INDEX = 3,
/* add a new one above */
ORC_PARTITION_LAST_INDEX,
ORC_PARTITION_VAR_ATT_COUNT = ORC_PARTITION_LAST_INDEX
};
/* MEMORY REPRESENTATION STRUCTURES */
#define OR_BINARY_MAX_LENGTH 65535
#define OR_BINARY_LENGTH_MASK 0xFFFF
#define OR_BINARY_PAD_SHIFT 16
typedef struct db_binary DB_BINARY;
struct db_binary
{
unsigned char *data;
unsigned int length;
};
/*
* DB_REFERENCE
* This is a common structure header used by DB_SET and DB_ELO.
* It encapsulates ownership information that must be maintained
* by these two types. General routines can be written to maintain
* ownership information for both types.
*
*/
typedef struct db_reference DB_REFERENCE;
struct db_reference
{
struct db_object *handle;
struct db_object *owner;
int attribute;
};
/*
* SETOBJ
* This is the primitive set object header.
*/
typedef struct setobj SETOBJ;
typedef struct db_set SETREF;
#if defined (__cplusplus)
class JSON_VALIDATOR;
#endif
/*
* OR_VARINFO
* Memory representation for a variable offset table. This is build
* from a disk offset table, either in an object header or in a
* set header.
*/
typedef struct or_varinfo OR_VARINFO;
struct or_varinfo
{
int offset;
int length;
};
#if __WORDSIZE == 32
#define OR_ALIGNED_BUF(size) \
union \
{ \
double dummy; \
char buf[(size) + MAX_ALIGNMENT]; \
}
#define OR_ALIGNED_BUF_START(abuf) (PTR_ALIGN (abuf.buf, MAX_ALIGNMENT))
#define OR_ALIGNED_BUF_SIZE(abuf) (sizeof (abuf.buf) - MAX_ALIGNMENT)
#else /* __WORDSIZE == 32 */
#define OR_ALIGNED_BUF(size) \
union \
{ \
double dummy; \
char buf[(size)]; \
}
#define OR_ALIGNED_BUF_START(abuf) (abuf.buf)
#define OR_ALIGNED_BUF_SIZE(abuf) (sizeof (abuf.buf))
#endif
#define OR_INFINITE_POINTER ((void *) (~((UINTPTR) 0UL)))
typedef struct or_buf OR_BUF;
struct or_buf
{
char *buffer;
char *ptr;
char *endptr;
struct or_fixup *fixups;
};
/* Need to translate types of DB_TYPE_OBJECT into DB_TYPE_OID in server-side */
#define OR_PACK_DOMAIN_OBJECT_TO_OID(p, d, o, n) \
or_pack_domain ((p), \
TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT ? &tp_Oid_domain : (d), \
(o), (n))
#define ASSERT_ALIGN(ptr, alignment) (assert (PTR_ALIGN (ptr, alignment) == ptr))
#if defined __cplusplus
extern "C"
{
#endif
extern int db_string_put_cs_and_collation (DB_VALUE * value, const int codeset, const int collation_id);
extern int db_enum_put_cs_and_collation (DB_VALUE * value, const int codeset, const int collation_id);
extern int valcnv_convert_value_to_string (DB_VALUE * value);
#if defined __cplusplus
}
#endif
extern int or_rep_id (RECDES * record);
extern int or_set_rep_id (RECDES * record, int repid);
extern int or_chn (RECDES * record);
extern int or_replace_chn (RECDES * record, int chn);
extern int or_mvcc_get_repid_and_flags (OR_BUF * buf, int *error);
extern int or_mvcc_set_repid_and_flags (OR_BUF * buf, int mvcc_flag, int repid, int bound_bit,
int variable_offset_size);
extern char *or_class_name (RECDES * record);
/* Pointer based decoding functions */
extern int or_set_element_offset (char *setptr, int element);
#if defined(ENABLE_UNUSED_FUNCTION)
extern int or_get_bound_bit (char *bound_bits, int element);
extern void or_put_bound_bit (char *bound_bits, int element, int bound);
#endif
/* Data packing functions */
extern char *or_pack_int (char *ptr, int number);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_pack_bigint (char *ptr, DB_BIGINT number);
#endif
extern char *or_pack_int64 (char *ptr, INT64 number);
extern char *or_pack_float (char *ptr, float number);
extern char *or_pack_double (char *ptr, double number);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_pack_time (char *ptr, DB_TIME time);
extern char *or_pack_date (char *ptr, DB_DATE date);
extern char *or_pack_monetary (char *ptr, DB_MONETARY * money);
extern char *or_pack_utime (char *ptr, DB_UTIME utime);
#endif
extern char *or_pack_short (char *ptr, short number);
extern char *or_pack_string_with_null_padding (char *ptr, const char *stream, size_t len);
extern char *or_pack_stream (char *ptr, const char *stream, size_t len);
extern char *or_pack_string (char *ptr, const char *string);
extern char *or_pack_string_with_length (char *ptr, const char *string, int length);
extern char *or_pack_errcode (char *ptr, int error);
extern char *or_pack_oid (char *ptr, const OID * oid);
extern char *or_pack_oid_array (char *ptr, int n, const OID * oids);
extern char *or_pack_hfid (const char *ptr, const HFID * hfid);
extern char *or_pack_btid (char *buf, const BTID * btid);
extern char *or_pack_ehid (char *buf, EHID * btid);
extern char *or_pack_recdes (char *buf, RECDES * recdes);
extern char *or_pack_log_lsa (const char *ptr, const struct log_lsa *lsa);
extern char *or_unpack_log_lsa (char *ptr, struct log_lsa *lsa);
extern char *or_unpack_set (char *ptr, setobj ** set, struct tp_domain *domain);
extern char *or_unpack_setref (char *ptr, DB_SET ** ref);
extern char *or_pack_listid (char *ptr, void *listid);
extern char *or_pack_lock (char *ptr, LOCK lock);
extern char *or_pack_set_header (char *buf, DB_TYPE stype, DB_TYPE etype, int bound_bits, int size);
extern char *or_pack_set_node (char *ptr, void *set_node);
extern char *or_pack_int_array (char *buffer, int count, const int *int_array);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_pack_elo (char *ptr, void *elo);
extern char *or_pack_string_array (char *buffer, int count, const char **string_array);
extern char *or_pack_db_value_array (char *buffer, int count, DB_VALUE * val);
#endif
/* should be using the or_pack_value family instead ! */
extern char *or_pack_db_value (char *buffer, DB_VALUE * var);
extern char *or_unpack_db_value (char *buffer, DB_VALUE * val);
extern int or_db_value_size (DB_VALUE * var);
/* Data unpacking functions */
extern char *or_unpack_int (char *ptr, int *number);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_unpack_bigint (char *ptr, DB_BIGINT * number);
#endif
extern char *or_unpack_int64 (char *ptr, INT64 * number);
extern char *or_unpack_int_array (char *ptr, int n, int **number_array);
extern char *or_unpack_longint (char *ptr, int *number);
extern char *or_unpack_short (char *ptr, short *number);
extern char *or_unpack_float (char *ptr, float *number);
extern char *or_unpack_double (char *ptr, double *number);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_unpack_time (char *ptr, DB_TIME * time);
extern char *or_unpack_date (char *ptr, DB_DATE * date);
extern char *or_unpack_monetary (char *ptr, DB_MONETARY * money);
extern char *or_unpack_utime (char *ptr, DB_UTIME * utime);
#endif
extern char *or_unpack_stream (char *ptr, char *stream, size_t len);
extern char *or_unpack_string (char *ptr, char **string);
extern char *or_unpack_string_alloc (char *ptr, char **string);
extern char *or_unpack_string_nocopy (char *ptr, char **string);
extern char *or_unpack_errcode (char *ptr, int *error);
extern char *or_unpack_oid (char *ptr, OID * oid);
extern char *or_unpack_oid_array (char *ptr, int n, OID ** oids);
extern char *or_unpack_hfid (char *ptr, HFID * hfid);
extern char *or_unpack_hfid_array (char *ptr, int n, HFID ** hfids);
extern char *or_unpack_btid (char *buf, BTID * btid);
extern char *or_unpack_ehid (char *buf, EHID * btid);
extern char *or_unpack_recdes (char *buf, RECDES ** recdes);
extern char *or_unpack_listid (char *ptr, void *listid_ptr);
extern char *or_unpack_unbound_listid (char *ptr, void **listid_ptr);
extern char *or_unpack_lock (char *ptr, LOCK * lock);
extern char *or_unpack_set_header (char *buf, DB_TYPE * stype, DB_TYPE * etype, int *bound_bits, int *size);
extern char *or_unpack_method_sig_list (char *ptr, void **method_sig_list_ptr);
extern char *or_unpack_set_node (char *ptr, void *set_node_ptr);
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_unpack_string_array (char *buffer, char ***string_array, int *cnt);
extern char *or_unpack_db_value_array (char *buffer, DB_VALUE ** val, int *count);
extern char *or_unpack_elo (char *ptr, void **elo_ptr);
#endif
extern char *or_pack_ptr (char *ptr, UINTPTR ptrval);
extern char *or_unpack_ptr (char *ptr, UINTPTR * ptrval);
extern char *or_pack_key_val_range (char *ptr, const void *key_val_range_ptr);
extern char *or_unpack_key_val_range (char *ptr, void *key_val_range_ptr);
extern char *or_pack_bool_array (char *ptr, const bool * bools, int size);
extern char *or_unpack_bool_array (char *ptr, bool ** bools);
extern int or_packed_bool_array_length (const bool * bools, int size);
/* pack/unpack support functions */
extern int or_packed_stream_length (size_t len);
extern int or_packed_string_length (const char *string, int *strlen);
#if defined(ENABLE_UNUSED_FUNCTION)
extern int or_align_length (int length);
#endif /* ENABLE_UNUSED_FUNCTION */
extern int or_packed_varbit_length (int bitlen);
/*
* to avoid circular dependencies, don't require the definition of QFILE_LIST_ID in
* this file (it references DB_TYPE)
*/
extern int or_listid_length (void *listid);
extern int or_set_node_length (void *set_node_ptr);
#if defined(ENABLE_UNUSED_FUNCTION)
extern int or_elo_length (void *elo_ptr);
extern int or_packed_string_array_length (int count, const char **string_array);
extern int or_packed_db_value_array_length (int count, DB_VALUE * val);
#endif
extern void or_encode (char *buffer, const char *source, int size);
extern void or_decode (const char *buffer, char *dest, int size);
STATIC_INLINE void or_init (OR_BUF * buf, char *data, int length) __attribute__ ((ALWAYS_INLINE));
/* Pack/unpack support functions */
STATIC_INLINE int or_advance (OR_BUF * buf, int offset) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_seek (OR_BUF * buf, int psn) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_pad (OR_BUF * buf, int length) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_align32 (OR_BUF * buf) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_align (OR_BUF * buf, int alignment) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_align (OR_BUF * buf, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_align32 (OR_BUF * buf) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_align64 (OR_BUF * buf) __attribute__ ((ALWAYS_INLINE));
/*
* NUMERIC DATA TRANSFORMS
* This set of functions handles the transformation of the
* numeric types byte, short, integer, float, and double.
*
*/
STATIC_INLINE int or_put_byte (OR_BUF * buf, int num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_short (OR_BUF * buf, int num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_int (OR_BUF * buf, int num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_bigint (OR_BUF * buf, DB_BIGINT num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_float (OR_BUF * buf, float num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_double (OR_BUF * buf, double num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_byte (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_short (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_int (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE DB_BIGINT or_get_bigint (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE float or_get_float (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE double or_get_double (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
/*
* EXTENDED TYPE TRANSLATORS
* This set of functions reads and writes the extended types time,
* utime, date, and monetary.
*/
STATIC_INLINE int or_put_time (OR_BUF * buf, DB_TIME * timeval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_utime (OR_BUF * buf, DB_UTIME * timeval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_timestamptz (OR_BUF * buf, DB_TIMESTAMPTZ * ts_tz) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_date (OR_BUF * buf, DB_DATE * date) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_datetime (OR_BUF * buf, DB_DATETIME * datetimeval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_datetimetz (OR_BUF * buf, DB_DATETIMETZ * datetimetz) __attribute__ ((ALWAYS_INLINE));
extern int or_put_monetary (OR_BUF * buf, DB_MONETARY * monetary);
STATIC_INLINE int or_get_time (OR_BUF * buf, DB_TIME * timeval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_utime (OR_BUF * buf, DB_UTIME * timeval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_timestamptz (OR_BUF * buf, DB_TIMESTAMPTZ * ts_tz) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_date (OR_BUF * buf, DB_DATE * date) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_datetime (OR_BUF * buf, DB_DATETIME * datetime) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_datetimetz (OR_BUF * buf, DB_DATETIMETZ * datetimetz) __attribute__ ((ALWAYS_INLINE));
extern int or_get_monetary (OR_BUF * buf, DB_MONETARY * monetary);
#if defined(ENABLE_UNUSED_FUNCTION)
extern int or_put_binary (OR_BUF * buf, DB_BINARY * binary);
#endif
STATIC_INLINE int or_put_data (OR_BUF * buf, const char *data, int length) __attribute__ ((ALWAYS_INLINE));
extern int or_put_varbit (OR_BUF * buf, const char *string, int bitlen);
extern int or_put_varchar (OR_BUF * buf, char *string, int charlen);
STATIC_INLINE int or_put_string_aligned (OR_BUF * buf, char *string) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_string_aligned_with_length (OR_BUF * buf, const char *str) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_data (OR_BUF * buf, char *data, int length) __attribute__ ((ALWAYS_INLINE));
#if defined(ENABLE_UNUSED_FUNCTION)
extern char *or_get_varbit (OR_BUF * buf, int *length_ptr);
extern char *or_get_varchar (OR_BUF * buf, int *length_ptr);
#endif
STATIC_INLINE int or_get_varbit_length (OR_BUF * buf, int *intval) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_varchar_length (OR_BUF * buf, int *intval) __attribute__ ((ALWAYS_INLINE));
/* Get the compressed and the decompressed lengths of a string stored in buffer */
STATIC_INLINE int or_get_varchar_compression_lengths (OR_BUF * buf, int *compressed_size, int *decompressed_size)
__attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_string_size_byte (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_varbit_length (int bitlen) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_varchar_length (int charlen) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_varbit_length_internal (int bitlen, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_varchar_length_internal (int charlen, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_skip_varbit (OR_BUF * buf, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_skip_varchar (OR_BUF * buf, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_skip_varbit_remainder (OR_BUF * buf, int bitlen, int align) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_skip_varchar_remainder (OR_BUF * buf, int charlen, int align) __attribute__ ((ALWAYS_INLINE));
#if defined(ENABLE_UNUSED_FUNCTION)
extern int or_length_binary (DB_BINARY * binary);
extern int or_length_string (char *string);
#endif
/*
* DISK IDENTIFIER TRANSLATORS
* Translators for the disk identifiers OID, HFID, BTID, EHID.
*/
STATIC_INLINE int or_put_oid (OR_BUF * buf, const OID * oid) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_mvccid (OR_BUF * buf, MVCCID mvccid) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_oid (OR_BUF * buf, OID * oid) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_mvccid (OR_BUF * buf, MVCCID * mvccid) __attribute__ ((ALWAYS_INLINE));
/* VARIABLE OFFSET TABLE ACCESSORS */
STATIC_INLINE int or_put_big_var_offset (OR_BUF * buf, int num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_offset (OR_BUF * buf, int num) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_put_offset_internal (OR_BUF * buf, int num, int offset_size) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_big_var_offset (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_offset (OR_BUF * buf, int *error) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_get_offset_internal (OR_BUF * buf, int *error, int offset_size) __attribute__ ((ALWAYS_INLINE));
/* Data unpacking functions */
extern int or_packed_put_varbit (OR_BUF * buf, const char *string, int bitlen);
extern int or_packed_put_varchar (OR_BUF * buf, char *string, int charlen);
extern int or_packed_varchar_length (int charlen);
extern int or_packed_recdesc_length (int length);
extern char *or_unpack_var_table (char *ptr, int nvars, OR_VARINFO * vars);
extern OR_VARINFO *or_get_var_table (OR_BUF * buf, int nvars, char *(*allocator) (int));
extern OR_VARINFO *or_get_var_table_internal (OR_BUF * buf, int nvars, char *(*allocator) (int), int offset_size);
/* DOMAIN functions */
extern int or_packed_domain_size (struct tp_domain *domain, int include_classoids);
extern char *or_pack_domain (char *ptr, struct tp_domain *domain, int include_classoids, int is_null);
extern char *or_unpack_domain (char *ptr, struct tp_domain **domain_ptr, int *is_null);
extern int or_put_domain (OR_BUF * buf, struct tp_domain *domain, int include_classoids, int is_null);
extern struct tp_domain *or_get_domain (OR_BUF * buf, struct tp_domain *dom, int *is_null);
extern int or_put_sub_domain (OR_BUF * buf);
/* SET functions */
extern void or_packed_set_info (DB_TYPE set_type, struct tp_domain *domain, int include_domain, int *bound_bits,
int *offset_table, int *element_tags, int *element_size);
extern int or_put_set_header (OR_BUF * buf, DB_TYPE set_type, int size, int domain, int bound_bits, int offset_table,
int element_tags, int common_sub_header);
extern 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);
extern int or_skip_set_header (OR_BUF * buf);
extern int or_packed_set_length (setobj * set, int include_domain);
extern void or_put_set (OR_BUF * buf, setobj * set, int include_domain);
extern setobj *or_get_set (OR_BUF * buf, struct tp_domain *domain);
extern int or_disk_set_size (OR_BUF * buf, struct tp_domain *domain, DB_TYPE * set_type);
/* DB_VALUE functions */
extern int or_packed_value_size (const DB_VALUE * value, int collapse_null, int include_domain,
int include_domain_classoids);
extern int or_put_value (OR_BUF * buf, DB_VALUE * value, int collapse_null, int include_domain,
int include_domain_classoids);
extern int or_get_value (OR_BUF * buf, DB_VALUE * value, struct tp_domain *domain, int expected, bool copy);
extern char *or_pack_value (char *buf, DB_VALUE * value);
extern char *or_pack_mem_value (char *ptr, DB_VALUE * value, int *packed_len_except_alignment);
extern char *or_unpack_value (const char *buf, DB_VALUE * value);
extern char *or_unpack_mem_value (char *buf, DB_VALUE * value);
extern int or_packed_enumeration_size (const DB_ENUMERATION * e);
extern int or_put_enumeration (OR_BUF * buf, const DB_ENUMERATION * e);
extern int or_get_enumeration (OR_BUF * buf, DB_ENUMERATION * e);
extern int or_header_size (char *ptr);
extern char *or_pack_mvccid (char *ptr, const MVCCID mvccid);
extern char *or_unpack_mvccid (char *ptr, MVCCID * mvccid);
extern char *or_pack_sha1 (char *ptr, const SHA1Hash * sha1);
extern char *or_unpack_sha1 (char *ptr, SHA1Hash * sha1);
extern int or_packed_spacedb_size (const SPACEDB_ALL * all, const SPACEDB_ONEVOL * vols, const SPACEDB_FILES * files);
extern char *or_pack_spacedb (char *ptr, const SPACEDB_ALL * all, const SPACEDB_ONEVOL * vols,
const SPACEDB_FILES * files);
extern char *or_unpack_spacedb (char *ptr, SPACEDB_ALL * all, SPACEDB_ONEVOL ** vols, SPACEDB_FILES * files);
/* class object */
extern int classobj_decompose_property_oid (const char *buffer, int *volid, int *fileid, int *pageid);
extern void classobj_initialize_default_expr (DB_DEFAULT_EXPR * default_expr);
extern int classobj_get_prop (DB_SEQ * properties, const char *name, DB_VALUE * pvalue);
#if defined (__cplusplus)
extern int or_get_json_validator (OR_BUF * buf, REFPTR (JSON_VALIDATOR, validator));
extern int or_put_json_validator (OR_BUF * buf, JSON_VALIDATOR * validator);
extern int or_get_json_schema (OR_BUF * buf, REFPTR (char, schema));
extern int or_put_json_schema (OR_BUF * buf, const char *schema);
#endif
/* Because of the STRING encoding, this one could not be changed for over 255, just lower. */
#define OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION 255
#define OR_IS_STRING_LENGTH_COMPRESSABLE(str_length) \
((str_length) >= OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION && (str_length) <= LZ4_MAX_INPUT_SIZE)
/*
* MIDXKEY HEADER ACCESSORS
*/
STATIC_INLINE int or_multi_nullmap_size (const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_offset_table_size (const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_header_size (const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_clear_header (char *nullmap_ptr, const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_set_not_null (char *nullmap_ptr, const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_set_null (char *nullmap_ptr, const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE bool or_multi_is_not_null (char *nullmap_ptr, const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE bool or_multi_is_null (char *nullmap_ptr, const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE char *or_multi_get_offset_table (char *nullmap_ptr, const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE char *or_multi_get_element_offset_ptr (char *nullmap_ptr, const int n_elements, const int index)
__attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_get_element_offset_internal (char *nullmap_ptr, const int n_elements, const int index)
__attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_get_element_offset (char *nullmap_ptr, const int n_elements, const int index)
__attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_get_next_element_offset (char *nullmap_ptr, const int n_elements, const int index)
__attribute__ ((ALWAYS_INLINE));
STATIC_INLINE int or_multi_get_size_offset (char *nullmap_ptr, const int n_elements) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_put_element_offset_internal (char *nullmap_ptr, const int n_elements, const int offset,
const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_put_element_offset (char *nullmap_ptr, const int n_elements, const int offset,
const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_put_next_element_offset (char *nullmap_ptr, const int n_elements, const int offset,
const int index) __attribute__ ((ALWAYS_INLINE));
STATIC_INLINE void or_multi_put_size_offset (char *nullmap_ptr, const int n_elements, const int offset)
__attribute__ ((ALWAYS_INLINE));
/*
* or_init - initialize the field of an OR_BUF
* return: void
* buf(in/out): or buffer to initialize
* data(in): buffer data
* length(in): buffer data length
*/
STATIC_INLINE void
or_init (OR_BUF * buf, char *data, int length)
{
buf->buffer = data;
buf->ptr = data;
/* TODO: LP64 check DB_INT32_MAX */
if (length <= 0 || length == DB_INT32_MAX)
{
buf->endptr = (char *) OR_INFINITE_POINTER;
}
else
{
buf->endptr = data + length;
}
buf->fixups = NULL;
}
/*
* OR_BUF PACK/UNPACK FUNCTIONS
*/
/*
* or_seek - This sets the translation pointer directly to a certain byte in
* the buffer.
* return: ERROR_SUCCESS or error code
* buf(in/out): or buffer
* psn(in): position within buffer
*/
STATIC_INLINE int
or_seek (OR_BUF * buf, int psn)
{
assert (buf->buffer + psn <= buf->endptr);
buf->ptr = buf->buffer + psn;
return NO_ERROR;
}
/*
* or_advance - This advances the translation pointer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* offset(in): number of bytes to skip
*/
STATIC_INLINE int
or_advance (OR_BUF * buf, int offset)
{
assert (buf->ptr + offset <= buf->endptr);
buf->ptr += offset;
return NO_ERROR;
}
/*
* or_pad - This advances the translation pointer and adds bytes of zero.
* return: NO_ERROR or error code
* buf(in/out): or buffer
* length(in): number of bytes to pad
*
* Note:
* This advances the translation pointer and adds bytes of zero.
* This is used add padding bytes to ensure proper alignment of
* some data types.
*/
STATIC_INLINE int
or_pad (OR_BUF * buf, int length)
{
assert (buf->ptr + length <= buf->endptr);
(void) memset (buf->ptr, 0, length);
buf->ptr += length;
return NO_ERROR;
}
/*
* or_put_align32 - pad zero bytes round up to 4 byte bound
* return: NO_ERROR or error code
* buf(in/out): or buffer
*/
STATIC_INLINE int
or_put_align32 (OR_BUF * buf)
{
unsigned int bits;
int rc = NO_ERROR;
bits = (UINTPTR) buf->ptr & 3;
if (bits)
{
assert (buf->ptr + 4 - bits <= buf->endptr);
rc = or_pad (buf, 4 - bits);
}
return rc;
}
/*
* or_align () - Align current buffer pointer to given alignment.
*
* return : Error code.
* buf (in/out) : Buffer.
* alignment (in) : Desired alignment.
*/
STATIC_INLINE int
or_align (OR_BUF * buf, int alignment)
{
char *new_ptr = PTR_ALIGN (buf->ptr, alignment);
assert (new_ptr <= buf->endptr);
buf->ptr = new_ptr;
return NO_ERROR;
}
/*
* or_get_align - adnvance or buf pointer to next alignment position
* return: NO_ERROR or error code
* buf(in/out): or buffer
* align(in):
*/
STATIC_INLINE int
or_get_align (OR_BUF * buf, int align)
{
char *ptr;
ptr = PTR_ALIGN (buf->ptr, align);
assert (ptr <= buf->endptr);
buf->ptr = ptr;
return NO_ERROR;
}
/*
* or_get_align32 - adnvance or buf pointer to next 4 byte alignment position
* return: NO_ERROR or error code
* buf(in/out): or buffer
*/
STATIC_INLINE int
or_get_align32 (OR_BUF * buf)
{
unsigned int bits;
int rc = NO_ERROR;
bits = (UINTPTR) (buf->ptr) & 3;
if (bits)
{
rc = or_advance (buf, 4 - bits);
}
return rc;
}
/*
* or_get_align64 - adnvance or buf pointer to next 8 byte alignment position
* return: NO_ERROR or error code
* buf(in/out): or buffer
*/
STATIC_INLINE int
or_get_align64 (OR_BUF * buf)
{
unsigned int bits;
int rc = NO_ERROR;
bits = (UINTPTR) (buf->ptr) & 7;
if (bits)
{
rc = or_advance (buf, 8 - bits);
}
return rc;
}
/*
* NUMERIC DATA TRANSFORMS
* This set of functions handles the transformation of the
* numeric types byte, short, integer, float, and double.
*
*/
/*
* or_put_byte - put a byte to or buffer
* return: NO_ERROR or error code
* buf(out/out): or buffer
* num(in): byte value
*/
STATIC_INLINE int
or_put_byte (OR_BUF * buf, int num)
{
assert (buf->ptr + OR_BYTE_SIZE <= buf->endptr);
OR_PUT_BYTE (buf->ptr, num);
buf->ptr += OR_BYTE_SIZE;
return NO_ERROR;
}
/*
* or_get_byte - read a byte value from or buffer
* return: byte value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE int
or_get_byte (OR_BUF * buf, int *error)
{
int value = 0;
assert (buf->ptr + OR_BYTE_SIZE <= buf->endptr);
value = OR_GET_BYTE (buf->ptr);
buf->ptr += OR_BYTE_SIZE;
*error = NO_ERROR;
return value;
}
/*
* or_put_short - put a short value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* num(in): short value to put
*/
STATIC_INLINE int
or_put_short (OR_BUF * buf, int num)
{
ASSERT_ALIGN (buf->ptr, SHORT_ALIGNMENT);
assert (buf->ptr + OR_SHORT_SIZE <= buf->endptr);
OR_PUT_SHORT (buf->ptr, num);
buf->ptr += OR_SHORT_SIZE;
return NO_ERROR;
}
/*
* or_get_short - read a short value from or buffer
* return: short value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE int
or_get_short (OR_BUF * buf, int *error)
{
int value = 0;
ASSERT_ALIGN (buf->ptr, SHORT_ALIGNMENT);
assert (buf->ptr + OR_SHORT_SIZE <= buf->endptr);
value = OR_GET_SHORT (buf->ptr);
buf->ptr += OR_SHORT_SIZE;
*error = NO_ERROR;
return value;
}
/*
* or_put_int - put int value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* num(in): int value to put
*/
STATIC_INLINE int
or_put_int (OR_BUF * buf, int num)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_INT_SIZE <= buf->endptr);
OR_PUT_INT (buf->ptr, num);
buf->ptr += OR_INT_SIZE;
return NO_ERROR;
}
/*
* or_get_int - get int value from or buffer
* return: int value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE int
or_get_int (OR_BUF * buf, int *error)
{
int value = 0;
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_INT_SIZE <= buf->endptr);
value = OR_GET_INT (buf->ptr);
buf->ptr += OR_INT_SIZE;
*error = NO_ERROR;
return value;
}
/*
* or_put_bigint - put bigint value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* num(in): bigint value to put
*/
STATIC_INLINE int
or_put_bigint (OR_BUF * buf, DB_BIGINT num)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_BIGINT_SIZE <= buf->endptr);
OR_PUT_BIGINT (buf->ptr, &num);
buf->ptr += OR_BIGINT_SIZE;
return NO_ERROR;
}
/*
* or_get_bigint - get bigint value from or buffer
* return: bigint value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE DB_BIGINT
or_get_bigint (OR_BUF * buf, int *error)
{
DB_BIGINT value = 0;
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_BIGINT_SIZE <= buf->endptr);
OR_GET_BIGINT (buf->ptr, &value);
buf->ptr += OR_BIGINT_SIZE;
*error = NO_ERROR;
return value;
}
/*
* or_put_float - put a float value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* fnum(in): float value to put
*/
STATIC_INLINE int
or_put_float (OR_BUF * buf, float fnum)
{
ASSERT_ALIGN (buf->ptr, FLOAT_ALIGNMENT);
assert (buf->ptr + OR_FLOAT_SIZE <= buf->endptr);
OR_PUT_FLOAT (buf->ptr, fnum);
buf->ptr += OR_FLOAT_SIZE;
return NO_ERROR;
}
/*
* or_get_float - read a float value from or buffer
* return: float value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE float
or_get_float (OR_BUF * buf, int *error)
{
float value = 0.0;
ASSERT_ALIGN (buf->ptr, FLOAT_ALIGNMENT);
assert (buf->ptr + OR_FLOAT_SIZE <= buf->endptr);
OR_GET_FLOAT (buf->ptr, &value);
buf->ptr += OR_FLOAT_SIZE;
*error = NO_ERROR;
return value;
}
/*
* or_put_double - put a double value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* dnum(in): double value to put
*/
STATIC_INLINE int
or_put_double (OR_BUF * buf, double dnum)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DOUBLE_SIZE <= buf->endptr);
OR_PUT_DOUBLE (buf->ptr, dnum);
buf->ptr += OR_DOUBLE_SIZE;
return NO_ERROR;
}
/*
* or_get_double - read a double value from or buffer
* return: double value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*/
STATIC_INLINE double
or_get_double (OR_BUF * buf, int *error)
{
double value = 0.0;
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DOUBLE_SIZE <= buf->endptr);
OR_GET_DOUBLE (buf->ptr, &value);
buf->ptr += OR_DOUBLE_SIZE;
*error = NO_ERROR;
return value;
}
/*
* EXTENDED TYPE TRANSLATORS
* This set of functions reads and writes the extended types time,
* utime, date, and monetary.
*/
/*
* or_put_time - write a DB_TIME to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* timeval(in): time value to write
*/
STATIC_INLINE int
or_put_time (OR_BUF * buf, DB_TIME * timeval)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_TIME_SIZE <= buf->endptr);
OR_PUT_TIME (buf->ptr, timeval);
buf->ptr += OR_TIME_SIZE;
return NO_ERROR;
}
/*
* or_get_time - read a DB_TIME from or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* timeval(out): pointer to DB_TIME value
*/
STATIC_INLINE int
or_get_time (OR_BUF * buf, DB_TIME * timeval)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_TIME_SIZE <= buf->endptr);
OR_GET_TIME (buf->ptr, timeval);
buf->ptr += OR_TIME_SIZE;
return NO_ERROR;
}
/*
* or_put_utime - write a timestamp value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* timeval(in): pointer to timestamp value
*/
STATIC_INLINE int
or_put_utime (OR_BUF * buf, DB_UTIME * timeval)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_UTIME_SIZE <= buf->endptr);
OR_PUT_UTIME (buf->ptr, timeval);
buf->ptr += OR_UTIME_SIZE;
return NO_ERROR;
}
/*
* or_get_utime - read a timestamp value from or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* timeval(out): pointer to timestamp value
*/
STATIC_INLINE int
or_get_utime (OR_BUF * buf, DB_UTIME * timeval)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_UTIME_SIZE <= buf->endptr);
OR_GET_UTIME (buf->ptr, timeval);
buf->ptr += OR_UTIME_SIZE;
return NO_ERROR;
}
/*
* or_put_timestamptz - write a timestamp with tz value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* ts_tz(in): pointer to DB_TIMESTAMPTZ value
*/
STATIC_INLINE int
or_put_timestamptz (OR_BUF * buf, DB_TIMESTAMPTZ * ts_tz)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_TIMESTAMPTZ_SIZE <= buf->endptr);
OR_PUT_TIMESTAMPTZ (buf->ptr, ts_tz);
buf->ptr += OR_TIMESTAMPTZ_SIZE;
return NO_ERROR;
}
/*
* or_get_timestamptz - read a timestamp with tz value from or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* ts_tz(out): pointer to DB_TIMESTAMPTZ value
*/
STATIC_INLINE int
or_get_timestamptz (OR_BUF * buf, DB_TIMESTAMPTZ * ts_tz)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_TIMESTAMPTZ_SIZE <= buf->endptr);
OR_GET_TIMESTAMPTZ (buf->ptr, ts_tz);
buf->ptr += OR_TIMESTAMPTZ_SIZE;
return NO_ERROR;
}
/*
* or_put_date - write a DB_DATE value to or_buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* date(in): pointer to DB_DATE value
*/
STATIC_INLINE int
or_put_date (OR_BUF * buf, DB_DATE * date)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATE_SIZE <= buf->endptr);
OR_PUT_DATE (buf->ptr, date);
buf->ptr += OR_DATE_SIZE;
return NO_ERROR;
}
/*
* or_get_date - read a DB_DATE value from or_buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* date(out): pointer to DB_DATE value
*/
STATIC_INLINE int
or_get_date (OR_BUF * buf, DB_DATE * date)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATE_SIZE <= buf->endptr);
OR_GET_DATE (buf->ptr, date);
buf->ptr += OR_DATE_SIZE;
return NO_ERROR;
}
/*
* or_put_datetime - write a datetime value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* datetimeval(in): pointer to datetime value
*/
STATIC_INLINE int
or_put_datetime (OR_BUF * buf, DB_DATETIME * datetimeval)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATETIME_SIZE <= buf->endptr);
OR_PUT_DATETIME (buf->ptr, datetimeval);
buf->ptr += OR_DATETIME_SIZE;
return NO_ERROR;
}
/*
* or_get_datetime - read a DB_DATETIME value from or_buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* date(out): pointer to DB_DATETIME value
*/
STATIC_INLINE int
or_get_datetime (OR_BUF * buf, DB_DATETIME * datetime)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATETIME_SIZE <= buf->endptr);
OR_GET_DATETIME (buf->ptr, datetime);
buf->ptr += OR_DATETIME_SIZE;
return NO_ERROR;
}
/*
* or_put_datetimetz - write a datetime with tz value to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* datetimetz(in): pointer to DB_DATETIMETZ value
*/
STATIC_INLINE int
or_put_datetimetz (OR_BUF * buf, DB_DATETIMETZ * datetimetz)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATETIMETZ_SIZE <= buf->endptr);
OR_PUT_DATETIMETZ (buf->ptr, datetimetz);
buf->ptr += OR_DATETIMETZ_SIZE;
return NO_ERROR;
}
/*
* or_get_datetimetz - read a datetime with tz value from or_buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* datetimetz(out): pointer to DB_DATETIMETZ value
*/
STATIC_INLINE int
or_get_datetimetz (OR_BUF * buf, DB_DATETIMETZ * datetimetz)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_DATETIMETZ_SIZE <= buf->endptr);
OR_GET_DATETIMETZ (buf->ptr, datetimetz);
buf->ptr += OR_DATETIMETZ_SIZE;
return NO_ERROR;
}
/*
* or_put_data - write an array of bytes to or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* data(in): pointer to data
* length(in): length in bytes
*/
STATIC_INLINE int
or_put_data (OR_BUF * buf, const char *data, int length)
{
assert (buf->ptr + length <= buf->endptr);
(void) memcpy (buf->ptr, data, length);
buf->ptr += length;
return NO_ERROR;
}
/*
* or_get_data - read an array of bytes from or buffer for given length
* return: NO_ERROR or error code
* buf(in/out): or buffer
* data(in): pointer to buffer to read data into
* length(in): length of read data
*/
STATIC_INLINE int
or_get_data (OR_BUF * buf, char *data, int length)
{
assert (buf->ptr + length <= buf->endptr);
(void) memcpy (data, buf->ptr, length);
buf->ptr += length;
return NO_ERROR;
}
/*
* or_get_varbit_length - get varbit length from or buffer
* return: length of varbit or 0 if error
* buf(in/out): or buffer
* rc(out): NO_ERROR or error code
*/
STATIC_INLINE int
or_get_varbit_length (OR_BUF * buf, int *rc)
{
int net_bitlen = 0, bitlen = 0;
/* unpack the size prefix */
bitlen = or_get_byte (buf, rc);
if (*rc != NO_ERROR)
{
return bitlen;
}
if (bitlen == 0xFF)
{
*rc = or_get_data (buf, (char *) &net_bitlen, OR_INT_SIZE);
bitlen = OR_GET_INT (&net_bitlen);
}
return bitlen;
}
/*
* or_get_varchar_length - get varchar length from or buffer
* return: length of varchar or 0 if error.
* buf(in/out): or buffer
* rc(out): status code
*/
STATIC_INLINE int
or_get_varchar_length (OR_BUF * buf, int *rc)
{
int charlen, compressed_length = 0, decompressed_length = 0;
*rc = or_get_varchar_compression_lengths (buf, &compressed_length, &decompressed_length);
if (compressed_length > 0)
{
charlen = compressed_length;
}
else
{
charlen = decompressed_length;
}
return charlen;
}
/* or_get_varchar_compression_lengths() - Function to get the compressed length and the uncompressed length of
* a compressed string.
*
* return : NO_ERROR or error_code.
* buf(in) : The buffer where the string is stored.
* compressed_size(out) : The compressed size of the string. Set to 0 if the string was not compressed.
* decompressed_size(out) : The uncompressed size of the string.
*/
STATIC_INLINE int
or_get_varchar_compression_lengths (OR_BUF * buf, int *compressed_size, int *decompressed_size)
{
int compressed_length = 0, decompressed_length = 0, rc = NO_ERROR, net_charlen = 0;
int size_prefix = 0;
/* Check if the string is compressed */
size_prefix = or_get_string_size_byte (buf, &rc);
if (rc != NO_ERROR)
{
assert (size_prefix == 0);
return rc;
}
if (size_prefix == OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
{
/* String was compressed */
/* Get the compressed size */
rc = or_get_data (buf, (char *) &net_charlen, OR_INT_SIZE);
compressed_length = OR_GET_INT ((char *) &net_charlen);
if (rc != NO_ERROR)
{
return rc;
}
*compressed_size = compressed_length;
net_charlen = 0;
/* Get the decompressed size */
rc = or_get_data (buf, (char *) &net_charlen, OR_INT_SIZE);
decompressed_length = OR_GET_INT ((char *) &net_charlen);
if (rc != NO_ERROR)
{
return rc;
}
*decompressed_size = decompressed_length;
}
else
{
/* String was not compressed so we set compressed_size to 0 to know that no compression happened. */
*compressed_size = 0;
*decompressed_size = size_prefix;
}
return rc;
}
/*
* or_put_string - write string to or buf
* return: NO_ERROR or error code
* buf(in/out): or buffer
* str(in): string to write
*
* Note:
* Does byte padding on strings to bring them up to 4 byte boundary.
*
* There is no or_get_string since this is the same as or_get_data.
* Since the workspace allocator (and most other Unix allocators) will
* keep track of the size of allocated blocks (and they will be
* in word multiples anyway), we can just include the disk padding
* bytes with the string when it is brought in from disk even though
* the total length may be more than that returned by strlen.
*/
STATIC_INLINE int
or_put_string_aligned (OR_BUF * buf, char *str)
{
int len, bits, pad;
int rc = NO_ERROR;
if (str == NULL)
{
return rc;
}
len = strlen (str) + 1;
rc = or_put_data (buf, str, len);
if (rc == NO_ERROR)
{
/* PAD */
bits = len & 3;
if (bits)
{
pad = 4 - bits;
rc = or_pad (buf, pad);
}
}
return rc;
}
/*
* this function also adds
* the length of the string to the buffer
*/
STATIC_INLINE int
or_put_string_aligned_with_length (OR_BUF * buf, const char *str)
{
int len;
int rc = NO_ERROR;
if (str == NULL)
{
return rc;
}
len = (int) strlen (str) + 1;
rc = or_put_int (buf, len);
if (rc != NO_ERROR)
{
return rc;
}
rc = or_put_data (buf, str, len);
if (rc == NO_ERROR)
{
or_align (buf, OR_INT_SIZE);
}
return rc;
}
/*
* or_get_string_size_byte - read string size byte value from or buffer
* return: byte value read
* buf(in/out): or buffer
* error(out): NO_ERROR or error code
*
* NOTE that it is really same as or_get_byte function. It is duplicated to inline the function for performance.
*/
STATIC_INLINE int
or_get_string_size_byte (OR_BUF * buf, int *error)
{
int size_prefix;
assert (buf->ptr + OR_BYTE_SIZE <= buf->endptr);
size_prefix = OR_GET_BYTE (buf->ptr);
buf->ptr += OR_BYTE_SIZE;
*error = NO_ERROR;
return size_prefix;
}
/*
* or_packed_varbit_length - returns packed varbit length of or buffer encoding
* return: varbit encoding length
* bitlen(in): varbit length
*/
STATIC_INLINE int
or_varbit_length (int bitlen)
{
return or_varbit_length_internal (bitlen, CHAR_ALIGNMENT);
}
/*
* or_varchar_length - returns length of place holder that can contain
* package varchar length.
* return: length of place holder that can contain packed varchar length
* charlen(in): varchar length
*/
STATIC_INLINE int
or_varchar_length (int charlen)
{
return or_varchar_length_internal (charlen, CHAR_ALIGNMENT);
}
STATIC_INLINE int
or_varbit_length_internal (int bitlen, int align)
{
int len;
/* calculate size of length prefix */
if (bitlen < 0xFF)
{
len = 1;
}
else
{
len = 1 + OR_INT_SIZE;
}
/* add in the string length in bytes */
len += ((bitlen + 7) / 8);
if (align == INT_ALIGNMENT)
{
/* round up to a word boundary */
len = DB_ALIGN (len, INT_ALIGNMENT);
}
return len;
}
STATIC_INLINE int
or_varchar_length_internal (int charlen, int align)
{
int len;
if (charlen < OR_MINIMUM_STRING_LENGTH_FOR_COMPRESSION)
{
len = OR_BYTE_SIZE + charlen;
}
else
{
/*
* Regarding the new encoding for VARCHAR, the strings stored in buffers have this representation:
* OR_BYTE_SIZE : First byte in encoding. If it's 0xFF, the string's length is greater than 255.
* : Otherwise, the first byte states the length of the string.
* 1st OR_INT_SIZE : string's compressed length
* 2nd OR_INT_SIZE : string's decompressed length
* charlen : string's disk length
*/
len = OR_BYTE_SIZE + OR_INT_SIZE + OR_INT_SIZE + charlen;
}
if (align == INT_ALIGNMENT)
{
/* size of NULL terminator */
len += OR_BYTE_SIZE;
len = DB_ALIGN (len, INT_ALIGNMENT);
}
return len;
}
/*
* or_skip_varbit - skip varbit in or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* align(in):
*/
STATIC_INLINE int
or_skip_varbit (OR_BUF * buf, int align)
{
int bitlen;
int rc = NO_ERROR;
bitlen = or_get_varbit_length (buf, &rc);
if (rc == NO_ERROR)
{
return (or_skip_varbit_remainder (buf, bitlen, align));
}
return rc;
}
/*
* or_skip_varchar - skip varchar field (length + data) from or buffer
* return: NO_ERROR or error code.
* buf(in/out): or buffer
* align(in):
*/
STATIC_INLINE int
or_skip_varchar (OR_BUF * buf, int align)
{
int charlen, rc = NO_ERROR;
charlen = or_get_varchar_length (buf, &rc);
if (rc == NO_ERROR)
{
return (or_skip_varchar_remainder (buf, charlen, align));
}
return rc;
}
/*
* or_skip_varbit_remainder - skip varbit field of given length in or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* bitlen(in): bitlen to skip
* align(in):
*/
STATIC_INLINE int
or_skip_varbit_remainder (OR_BUF * buf, int bitlen, int align)
{
int rc = NO_ERROR;
rc = or_advance (buf, BITS_TO_BYTES (bitlen));
if (rc == NO_ERROR && align == INT_ALIGNMENT)
{
rc = or_get_align32 (buf);
}
return rc;
}
/*
* or_skip_varchar_remainder - skip varchar field of given length
* return: NO_ERROR if successful, error code otherwise
* buf(in/out): or buffer
* charlen(in): length of varchar field to skip
* align(in):
*/
STATIC_INLINE int
or_skip_varchar_remainder (OR_BUF * buf, int charlen, int align)
{
int rc = NO_ERROR;
if (align == INT_ALIGNMENT)
{
rc = or_advance (buf, charlen + 1);
if (rc == NO_ERROR)
{
rc = or_get_align32 (buf);
}
}
else
{
rc = or_advance (buf, charlen);
}
return rc;
}
/*
* DISK IDENTIFIER TRANSLATORS
* Translators for the disk identifiers OID, HFID, BTID, EHID.
*/
/*
* or_put_oid - write content of an OID structure from or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* oid(in): pointer to OID
*/
STATIC_INLINE int
or_put_oid (OR_BUF * buf, const OID * oid)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_OID_SIZE <= buf->endptr);
if (oid == NULL)
{
OR_PUT_NULL_OID (buf->ptr);
}
else
{
/* Cannot allow any temp oid's to be written */
if (OID_ISTEMP (oid))
{
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_GENERIC_ERROR, 0);
assert (false);
}
OR_PUT_OID (buf->ptr, oid);
}
buf->ptr += OR_OID_SIZE;
return NO_ERROR;
}
/*
* or_get_oid - read content of an OID structure from or buffer
* return: NO_ERROR or error code
* buf(in/out): or buffer
* oid(out): pointer to OID
*/
STATIC_INLINE int
or_get_oid (OR_BUF * buf, OID * oid)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_OID_SIZE <= buf->endptr);
OR_GET_OID (buf->ptr, oid);
buf->ptr += OR_OID_SIZE;
return NO_ERROR;
}
/*
* or_put_mvccid () - Put an MVCCID to OR Buffer.
*
* return : Error code.
* buf (in) : OR Buffer
* mvccid (in) : MVCCID
*/
STATIC_INLINE int
or_put_mvccid (OR_BUF * buf, MVCCID mvccid)
{
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
assert (buf->ptr + OR_MVCCID_SIZE <= buf->endptr);
OR_PUT_MVCCID (buf->ptr, &mvccid);
buf->ptr += OR_MVCCID_SIZE;
return NO_ERROR;
}
/*
* or_get_mvccid () - Get an MVCCID from OR Buffer.
*
* return : MVCCID
* buf (in/out) : OR Buffer.
* error (out) : Error code.
*/
STATIC_INLINE int
or_get_mvccid (OR_BUF * buf, MVCCID * mvccid)
{
assert (mvccid != NULL);
ASSERT_ALIGN (buf->ptr, INT_ALIGNMENT);
*mvccid = MVCCID_NULL;
assert (buf->ptr + OR_MVCCID_SIZE <= buf->endptr);
OR_GET_MVCCID (buf->ptr, mvccid);
buf->ptr += OR_MVCCID_SIZE;
return NO_ERROR;
}
/* VARIABLE OFFSET TABLE ACCESSORS */
STATIC_INLINE int
or_put_big_var_offset (OR_BUF * buf, int num)
{
return or_put_int (buf, num);
}
STATIC_INLINE int
or_get_big_var_offset (OR_BUF * buf, int *error)
{
return or_get_int (buf, error);
}
STATIC_INLINE int
or_put_offset (OR_BUF * buf, int num)
{
return or_put_big_var_offset (buf, num);
}
STATIC_INLINE int
or_get_offset (OR_BUF * buf, int *error)
{
return or_get_big_var_offset (buf, error);
}
STATIC_INLINE int
or_put_offset_internal (OR_BUF * buf, int num, int offset_size)
{
if (offset_size == OR_BYTE_SIZE)
{
return or_put_byte (buf, num);
}
else if (offset_size == OR_SHORT_SIZE)
{
return or_put_short (buf, num);
}
else
{
assert (offset_size == OR_INT_SIZE);
return or_put_int (buf, num);
}
}
STATIC_INLINE int
or_get_offset_internal (OR_BUF * buf, int *error, int offset_size)
{
if (offset_size == OR_BYTE_SIZE)
{
return or_get_byte (buf, error);
}
else if (offset_size == OR_SHORT_SIZE)
{
return or_get_short (buf, error);
}
else
{
assert (offset_size == OR_INT_SIZE);
return or_get_int (buf, error);
}
}
/*
* MIDXKEY HEADER ACCESSORS
*/
STATIC_INLINE int
or_multi_nullmap_size (const int n_elements)
{
int nullmap_size;
assert (n_elements > 0);
nullmap_size = ((n_elements + 7) >> 3);
assert (nullmap_size > 0);
return nullmap_size;
}
STATIC_INLINE int
or_multi_offset_table_size (const int n_elements)
{
assert (n_elements > 0);
return n_elements + 1;
}
STATIC_INLINE int
or_multi_header_size (const int n_elements)
{
return or_multi_nullmap_size (n_elements) + or_multi_offset_table_size (n_elements);
}
STATIC_INLINE void
or_multi_clear_header (char *nullmap_ptr, const int n_elements)
{
assert (nullmap_ptr != NULL);
memset (nullmap_ptr, 0x00, or_multi_header_size (n_elements));
}
STATIC_INLINE void
or_multi_set_not_null (char *nullmap_ptr, const int index)
{
assert (nullmap_ptr != NULL);
assert (index >= 0);
(*(nullmap_ptr + (index >> 3))) |= (1 << (index & 7));
}
STATIC_INLINE void
or_multi_set_null (char *nullmap_ptr, const int index)
{
assert (nullmap_ptr != NULL);
assert (index >= 0);
(*(nullmap_ptr + (index >> 3))) &= (~(1 << (index & 7)));
}
STATIC_INLINE bool
or_multi_is_not_null (char *nullmap_ptr, const int index)
{
assert (nullmap_ptr != NULL);
assert (index >= 0);
if ((*(nullmap_ptr + (index >> 3))) & (1 << (index & 7)))
{
return true;
}
return false;
}
STATIC_INLINE bool
or_multi_is_null (char *nullmap_ptr, const int index)
{
return !or_multi_is_not_null (nullmap_ptr, index);
}
STATIC_INLINE char *
or_multi_get_offset_table (char *nullmap_ptr, const int n_elements)
{
assert (nullmap_ptr != NULL);
return nullmap_ptr + or_multi_nullmap_size (n_elements);
}
STATIC_INLINE char *
or_multi_get_element_offset_ptr (char *nullmap_ptr, const int n_elements, const int index)
{
return or_multi_get_offset_table (nullmap_ptr, n_elements) + index;
}
STATIC_INLINE int
or_multi_get_element_offset_internal (char *nullmap_ptr, const int n_elements, const int index)
{
int offset;
offset = OR_GET_BYTE (or_multi_get_element_offset_ptr (nullmap_ptr, n_elements, index));
assert (offset >= or_multi_header_size (n_elements));
assert (offset <= OR_MULTI_MAX_OFFSET);
return offset;
}
STATIC_INLINE int
or_multi_get_element_offset (char *nullmap_ptr, const int n_elements, const int index)
{
int offset;
offset = or_multi_get_element_offset_internal (nullmap_ptr, n_elements, index);
if (offset < OR_MULTI_MAX_OFFSET)
{
return offset;
}
return -1;
}
STATIC_INLINE int
or_multi_get_next_element_offset (char *nullmap_ptr, const int n_elements, const int index)
{
return or_multi_get_element_offset (nullmap_ptr, n_elements, index + 1);
}
STATIC_INLINE int
or_multi_get_size_offset (char *nullmap_ptr, const int n_elements)
{
int offset;
offset = or_multi_get_element_offset_internal (nullmap_ptr, n_elements, n_elements);
if (offset < OR_MULTI_MAX_OFFSET)
{
return offset;
}
return -1;
}
STATIC_INLINE void
or_multi_put_element_offset_internal (char *nullmap_ptr, const int n_elements, const int offset, const int index)
{
assert (nullmap_ptr != NULL);
assert (n_elements > 0);
assert (offset >= or_multi_header_size (n_elements));
assert (offset <= OR_MULTI_MAX_OFFSET);
assert (index >= 0);
OR_PUT_BYTE (or_multi_get_element_offset_ptr (nullmap_ptr, n_elements, index), offset);
}
STATIC_INLINE void
or_multi_put_element_offset (char *nullmap_ptr, const int n_elements, const int offset, const int index)
{
if (offset < OR_MULTI_MAX_OFFSET)
{
or_multi_put_element_offset_internal (nullmap_ptr, n_elements, offset, index);
}
else
{
or_multi_put_element_offset_internal (nullmap_ptr, n_elements, OR_MULTI_MAX_OFFSET, index);
}
}
STATIC_INLINE void
or_multi_put_next_element_offset (char *nullmap_ptr, const int n_elements, const int offset, const int index)
{
or_multi_put_element_offset (nullmap_ptr, n_elements, offset, index + 1);
}
STATIC_INLINE void
or_multi_put_size_offset (char *nullmap_ptr, const int n_elements, const int offset)
{
if (offset < OR_MULTI_MAX_OFFSET)
{
or_multi_put_element_offset_internal (nullmap_ptr, n_elements, offset, n_elements);
}
else
{
or_multi_put_element_offset_internal (nullmap_ptr, n_elements, OR_MULTI_MAX_OFFSET, n_elements);
}
}
#endif /* _OBJECT_REPRESENTATION_H_ */