mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 19:23:02 +01:00
1. Frontported fix for CORE-1944: Monitoring tables contain wrong data
2. Added new methods to Clumplet classes - date, time and floating point support. 3. Avoid endianess #ifdef's in Clumplet classes.
This commit is contained in:
parent
b8be425321
commit
99f17b4d00
@ -484,18 +484,10 @@ const UCHAR* ClumpletReader::getBytes() const
|
|||||||
return getBuffer() + cur_offset + getClumpletSize(true, true, false);
|
return getBuffer() + cur_offset + getClumpletSize(true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLONG ClumpletReader::getInt() const
|
SINT64 ClumpletReader::fromVaxInteger(const UCHAR* ptr, size_t length)
|
||||||
{
|
{
|
||||||
const UCHAR* ptr = getBytes();
|
|
||||||
size_t length = getClumpLength();
|
|
||||||
|
|
||||||
if (length > 4) {
|
|
||||||
invalid_structure("length of integer exceeds 4 bytes");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This code is taken from gds__vax_integer
|
// This code is taken from gds__vax_integer
|
||||||
SLONG value = 0;
|
SINT64 value = 0;
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
--length;
|
--length;
|
||||||
@ -506,9 +498,60 @@ SLONG ClumpletReader::getInt() const
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SLONG ClumpletReader::getInt() const
|
||||||
|
{
|
||||||
|
size_t length = getClumpLength();
|
||||||
|
|
||||||
|
if (length > 4) {
|
||||||
|
invalid_structure("length of integer exceeds 4 bytes");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromVaxInteger(getBytes(), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ClumpletReader::getDouble() const
|
||||||
|
{
|
||||||
|
|
||||||
|
if (getClumpLength() != sizeof(double)) {
|
||||||
|
invalid_structure("length of double must be equal 8 bytes");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on XDR code
|
||||||
|
union {
|
||||||
|
double temp_double;
|
||||||
|
SLONG temp_long[2];
|
||||||
|
} temp;
|
||||||
|
|
||||||
|
fb_assert(sizeof(double) == sizeof(temp));
|
||||||
|
|
||||||
|
const UCHAR* ptr = getBytes();
|
||||||
|
temp.temp_long[FB_LONG_DOUBLE_FIRST] = fromVaxInteger(ptr, sizeof(SLONG));
|
||||||
|
temp.temp_long[FB_LONG_DOUBLE_SECOND] = fromVaxInteger(ptr + sizeof(SLONG), sizeof(SLONG));
|
||||||
|
|
||||||
|
return temp.temp_double;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISC_TIMESTAMP ClumpletReader::getTimeStamp() const
|
||||||
|
{
|
||||||
|
ISC_TIMESTAMP value;
|
||||||
|
|
||||||
|
if (getClumpLength() != sizeof(ISC_TIMESTAMP)) {
|
||||||
|
invalid_structure("length of ISC_TIMESTAMP must be equal 8 bytes");
|
||||||
|
value.timestamp_date = 0;
|
||||||
|
value.timestamp_time = 0;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UCHAR* ptr = getBytes();
|
||||||
|
value.timestamp_date = fromVaxInteger(ptr, sizeof(SLONG));
|
||||||
|
value.timestamp_time = fromVaxInteger(ptr + sizeof(SLONG), sizeof(SLONG));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
SINT64 ClumpletReader::getBigInt() const
|
SINT64 ClumpletReader::getBigInt() const
|
||||||
{
|
{
|
||||||
const UCHAR* ptr = getBytes();
|
|
||||||
size_t length = getClumpLength();
|
size_t length = getClumpLength();
|
||||||
|
|
||||||
if (length > 8) {
|
if (length > 8) {
|
||||||
@ -516,16 +559,7 @@ SINT64 ClumpletReader::getBigInt() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This code is taken from isc_portable_integer
|
return fromVaxInteger(getBytes(), length);
|
||||||
SINT64 value = 0;
|
|
||||||
int shift = 0;
|
|
||||||
while (length > 0) {
|
|
||||||
--length;
|
|
||||||
value += ((SINT64) *ptr++) << shift;
|
|
||||||
shift += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string& ClumpletReader::getString(string& str) const
|
string& ClumpletReader::getString(string& str) const
|
||||||
|
@ -68,6 +68,10 @@ public:
|
|||||||
string& getString(string& str) const;
|
string& getString(string& str) const;
|
||||||
PathName& getPath(PathName& str) const;
|
PathName& getPath(PathName& str) const;
|
||||||
const UCHAR* getBytes() const;
|
const UCHAR* getBytes() const;
|
||||||
|
double getDouble() const;
|
||||||
|
ISC_TIMESTAMP getTimeStamp() const;
|
||||||
|
ISC_TIME getTime() const { return getInt(); }
|
||||||
|
ISC_DATE getDate() const { return getInt(); }
|
||||||
|
|
||||||
// Return the tag for buffer (usually structure version)
|
// Return the tag for buffer (usually structure version)
|
||||||
UCHAR getBufferTag() const;
|
UCHAR getBufferTag() const;
|
||||||
@ -129,6 +133,8 @@ private:
|
|||||||
|
|
||||||
const UCHAR* static_buffer;
|
const UCHAR* static_buffer;
|
||||||
const UCHAR* static_buffer_end;
|
const UCHAR* static_buffer_end;
|
||||||
|
|
||||||
|
static SINT64 ClumpletReader::fromVaxInteger(const UCHAR* ptr, size_t length);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
@ -121,38 +121,53 @@ void ClumpletWriter::size_overflow()
|
|||||||
fatal_exception::raise("Clumplet buffer size limit reached");
|
fatal_exception::raise("Clumplet buffer size limit reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClumpletWriter::toVaxInteger(UCHAR* ptr, size_t length, SINT64 value)
|
||||||
|
{
|
||||||
|
int shift = 0;
|
||||||
|
while (length--) {
|
||||||
|
*ptr++ = (UCHAR)(value >> shift);
|
||||||
|
shift += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClumpletWriter::insertInt(UCHAR tag, SLONG value)
|
void ClumpletWriter::insertInt(UCHAR tag, SLONG value)
|
||||||
{
|
{
|
||||||
#if defined(WORDS_BIGENDIAN)
|
|
||||||
UCHAR bytes[4];
|
UCHAR bytes[4];
|
||||||
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
|
|
||||||
bytes[0] = ptr[3];
|
toVaxInteger(bytes, sizeof(bytes), value);
|
||||||
bytes[1] = ptr[2];
|
|
||||||
bytes[2] = ptr[1];
|
|
||||||
bytes[3] = ptr[0];
|
|
||||||
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
||||||
#else
|
|
||||||
insertBytesLengthCheck(tag, reinterpret_cast<UCHAR*>(&value), sizeof(value));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClumpletWriter::insertBigInt(UCHAR tag, SINT64 value)
|
void ClumpletWriter::insertBigInt(UCHAR tag, SINT64 value)
|
||||||
{
|
{
|
||||||
#if defined(WORDS_BIGENDIAN)
|
|
||||||
UCHAR bytes[8];
|
UCHAR bytes[8];
|
||||||
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
|
|
||||||
bytes[0] = ptr[7];
|
toVaxInteger(bytes, sizeof(bytes), value);
|
||||||
bytes[1] = ptr[6];
|
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
||||||
bytes[2] = ptr[5];
|
}
|
||||||
bytes[3] = ptr[4];
|
|
||||||
bytes[4] = ptr[3];
|
void ClumpletWriter::insertDouble(UCHAR tag, double value)
|
||||||
bytes[5] = ptr[2];
|
{
|
||||||
bytes[6] = ptr[1];
|
union {
|
||||||
bytes[7] = ptr[0];
|
double temp_double;
|
||||||
|
SLONG temp_long[2];
|
||||||
|
} temp;
|
||||||
|
|
||||||
|
fb_assert(sizeof(double) == sizeof(temp));
|
||||||
|
|
||||||
|
temp.temp_double = value;
|
||||||
|
UCHAR bytes[8];
|
||||||
|
toVaxInteger(bytes, sizeof(SLONG), temp.temp_long[FB_LONG_DOUBLE_FIRST]);
|
||||||
|
toVaxInteger(bytes + sizeof(SLONG), sizeof(SLONG), temp.temp_long[FB_LONG_DOUBLE_SECOND]);
|
||||||
|
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClumpletWriter::insertTimeStamp(UCHAR tag, ISC_TIMESTAMP value)
|
||||||
|
{
|
||||||
|
UCHAR bytes[8];
|
||||||
|
toVaxInteger(bytes, sizeof(SLONG), value.timestamp_date);
|
||||||
|
toVaxInteger(bytes + sizeof(SLONG), sizeof(SLONG), value.timestamp_time);
|
||||||
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
insertBytesLengthCheck(tag, bytes, sizeof(bytes));
|
||||||
#else
|
|
||||||
insertBytesLengthCheck(tag, reinterpret_cast<UCHAR*>(&value), sizeof(value));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClumpletWriter::insertString(UCHAR tag, const string& str)
|
void ClumpletWriter::insertString(UCHAR tag, const string& str)
|
||||||
@ -266,35 +281,17 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const UCHAR* bytes, size_
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
USHORT value = static_cast<USHORT>(length);
|
|
||||||
fb_assert(sizeof(USHORT) == 2);
|
|
||||||
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
|
|
||||||
#if defined(WORDS_BIGENDIAN)
|
|
||||||
UCHAR b[2];
|
UCHAR b[2];
|
||||||
b[0] = ptr[1];
|
toVaxInteger(b, sizeof(b), length);
|
||||||
b[1] = ptr[0];
|
|
||||||
dynamic_buffer.insert(cur_offset, b, sizeof(b));
|
dynamic_buffer.insert(cur_offset, b, sizeof(b));
|
||||||
#else
|
|
||||||
dynamic_buffer.insert(cur_offset, ptr, sizeof(value));
|
|
||||||
#endif
|
|
||||||
cur_offset += 2;
|
cur_offset += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
ULONG value = static_cast<ULONG>(length);
|
|
||||||
fb_assert(sizeof(ULONG) == 4);
|
|
||||||
const UCHAR* ptr = reinterpret_cast<UCHAR*>(&value);
|
|
||||||
#if defined(WORDS_BIGENDIAN)
|
|
||||||
UCHAR b[4];
|
UCHAR b[4];
|
||||||
b[0] = ptr[3];
|
toVaxInteger(b, sizeof(b), length);
|
||||||
b[1] = ptr[2];
|
|
||||||
b[2] = ptr[1];
|
|
||||||
b[3] = ptr[0];
|
|
||||||
dynamic_buffer.insert(cur_offset, b, sizeof(b));
|
dynamic_buffer.insert(cur_offset, b, sizeof(b));
|
||||||
#else
|
|
||||||
dynamic_buffer.insert(cur_offset, ptr, sizeof(value));
|
|
||||||
#endif
|
|
||||||
cur_offset += 4;
|
cur_offset += 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -63,6 +63,10 @@ public:
|
|||||||
void insertString(UCHAR tag, const char* str, size_t length);
|
void insertString(UCHAR tag, const char* str, size_t length);
|
||||||
void insertByte(UCHAR tag, const UCHAR byte);
|
void insertByte(UCHAR tag, const UCHAR byte);
|
||||||
void insertTag(UCHAR tag);
|
void insertTag(UCHAR tag);
|
||||||
|
void insertDouble(UCHAR tag, double value);
|
||||||
|
void insertTimeStamp(UCHAR tag, ISC_TIMESTAMP value);
|
||||||
|
void insertTime(UCHAR tag, ISC_TIME value) { insertInt(tag, value); }
|
||||||
|
void insertDate(UCHAR tag, ISC_DATE value) { insertInt(tag, value); }
|
||||||
void insertEndMarker(UCHAR tag);
|
void insertEndMarker(UCHAR tag);
|
||||||
|
|
||||||
// Delete currently selected clumplet from buffer
|
// Delete currently selected clumplet from buffer
|
||||||
@ -87,6 +91,7 @@ private:
|
|||||||
HalfStaticArray<UCHAR, 128> dynamic_buffer;
|
HalfStaticArray<UCHAR, 128> dynamic_buffer;
|
||||||
|
|
||||||
void initNewBuffer(UCHAR tag);
|
void initNewBuffer(UCHAR tag);
|
||||||
|
static void toVaxInteger(UCHAR* ptr, size_t length, SINT64 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
@ -472,8 +472,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
reader = dumpData(tdbb, false);
|
reader = dumpData(tdbb, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader->rewind();
|
|
||||||
|
|
||||||
// Parse the dump
|
// Parse the dump
|
||||||
RecordBuffer* buffer = NULL;
|
RecordBuffer* buffer = NULL;
|
||||||
Record* record = NULL;
|
Record* record = NULL;
|
||||||
@ -481,7 +479,7 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
int rid = 0;
|
int rid = 0;
|
||||||
bool fields_processed = false, allowed = false, our_dbb = false;
|
bool fields_processed = false, allowed = false, our_dbb = false;
|
||||||
|
|
||||||
while (!reader->isEof())
|
for (reader->rewind(); !reader->isEof(); reader->moveNext())
|
||||||
{
|
{
|
||||||
if (reader->getClumpTag() == TAG_DBB)
|
if (reader->getClumpTag() == TAG_DBB)
|
||||||
{
|
{
|
||||||
@ -491,8 +489,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
|
|
||||||
our_dbb = !memcmp(&guid, &dbb->dbb_guid, sizeof(FB_GUID));
|
our_dbb = !memcmp(&guid, &dbb->dbb_guid, sizeof(FB_GUID));
|
||||||
|
|
||||||
reader->moveNext();
|
|
||||||
|
|
||||||
if (fields_processed)
|
if (fields_processed)
|
||||||
{
|
{
|
||||||
buffer->store(record);
|
buffer->store(record);
|
||||||
@ -502,7 +498,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
else if (reader->getClumpTag() == TAG_RECORD)
|
else if (reader->getClumpTag() == TAG_RECORD)
|
||||||
{
|
{
|
||||||
rid = reader->getInt();
|
rid = reader->getInt();
|
||||||
reader->moveNext();
|
|
||||||
|
|
||||||
if (fields_processed)
|
if (fields_processed)
|
||||||
{
|
{
|
||||||
@ -560,8 +555,6 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
|
|
||||||
const char* source = checkNull(rid, fid, (char*) reader->getBytes(), length);
|
const char* source = checkNull(rid, fid, (char*) reader->getBytes(), length);
|
||||||
|
|
||||||
reader->moveNext();
|
|
||||||
|
|
||||||
if (rid == rel_mon_database) // special case for MON$DATABASE
|
if (rid == rel_mon_database) // special case for MON$DATABASE
|
||||||
{
|
{
|
||||||
if (fid == f_mon_db_name)
|
if (fid == f_mon_db_name)
|
||||||
@ -571,13 +564,13 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
|
|
||||||
if (record && allowed && our_dbb)
|
if (record && allowed && our_dbb)
|
||||||
{
|
{
|
||||||
putField(record, fid, source, length);
|
putField(record, fid, reader, source == NULL);
|
||||||
fields_processed = true;
|
fields_processed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (record && allowed) // generic logic that covers all other relations
|
else if (record && allowed) // generic logic that covers all other relations
|
||||||
{
|
{
|
||||||
putField(record, fid, source, length);
|
putField(record, fid, reader, source == NULL);
|
||||||
fields_processed = true;
|
fields_processed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -644,26 +637,26 @@ void DatabaseSnapshot::clearRecord(Record* record)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::putField(Record* record, int id, const void* source, size_t length)
|
void DatabaseSnapshot::putField(Record* record, int id, const Firebird::ClumpletReader* reader, bool makeNull)
|
||||||
{
|
{
|
||||||
fb_assert(record);
|
fb_assert(record);
|
||||||
|
|
||||||
const Format* const format = record->rec_format;
|
const Format* const format = record->rec_format;
|
||||||
fb_assert(format && id < format->fmt_count);
|
fb_assert(format && id < format->fmt_count);
|
||||||
|
|
||||||
const dsc desc = format->fmt_desc[id];
|
if (makeNull)
|
||||||
UCHAR* const address = record->rec_data + (IPTR) desc.dsc_address;
|
|
||||||
|
|
||||||
if (!source)
|
|
||||||
{
|
{
|
||||||
SET_NULL(record, id);
|
SET_NULL(record, id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == sizeof(SINT64) && desc.dsc_dtype == dtype_long)
|
const dsc desc = format->fmt_desc[id];
|
||||||
|
UCHAR* const address = record->rec_data + (IPTR) desc.dsc_address;
|
||||||
|
|
||||||
|
if (reader->getClumpLength() == sizeof(SINT64) && desc.dsc_dtype == dtype_long)
|
||||||
{
|
{
|
||||||
// special case: translate 64-bit global ID into 32-bit local ID
|
// special case: translate 64-bit global ID into 32-bit local ID
|
||||||
const SINT64 global_id = *(SINT64*) source;
|
const SINT64 global_id = reader->getBigInt();
|
||||||
SLONG local_id = 0;
|
SLONG local_id = 0;
|
||||||
if (!idMap.get(global_id, local_id))
|
if (!idMap.get(global_id, local_id))
|
||||||
{
|
{
|
||||||
@ -678,18 +671,18 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
|
|||||||
switch (desc.dsc_dtype) {
|
switch (desc.dsc_dtype) {
|
||||||
case dtype_text:
|
case dtype_text:
|
||||||
{
|
{
|
||||||
const char* const string = (char*) source;
|
const char* const string = (char*) reader->getBytes();
|
||||||
const size_t max_length = desc.dsc_length;
|
const size_t max_length = desc.dsc_length;
|
||||||
length = MIN(length, max_length);
|
const size_t length = MIN(reader->getClumpLength(), max_length);
|
||||||
memcpy(address, string, length);
|
memcpy(address, string, length);
|
||||||
memset(address + length, ' ', max_length - length);
|
memset(address + length, ' ', max_length - length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case dtype_varying:
|
case dtype_varying:
|
||||||
{
|
{
|
||||||
const char* const string = (char*) source;
|
const char* const string = (char*) reader->getBytes();
|
||||||
const size_t max_length = desc.dsc_length - sizeof(USHORT);
|
const size_t max_length = desc.dsc_length - sizeof(USHORT);
|
||||||
length = MIN(length, max_length);
|
const size_t length = MIN(reader->getClumpLength(), max_length);
|
||||||
vary* varying = (vary*) address;
|
vary* varying = (vary*) address;
|
||||||
varying->vary_length = length;
|
varying->vary_length = length;
|
||||||
memcpy(varying->vary_string, string, length);
|
memcpy(varying->vary_string, string, length);
|
||||||
@ -697,30 +690,30 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case dtype_short:
|
case dtype_short:
|
||||||
*(SSHORT*) address = *(SSHORT*) source;
|
*(SSHORT*) address = reader->getBigInt();
|
||||||
break;
|
break;
|
||||||
case dtype_long:
|
case dtype_long:
|
||||||
*(SLONG*) address = *(SLONG*) source;
|
*(SLONG*) address = reader->getBigInt();
|
||||||
break;
|
break;
|
||||||
case dtype_int64:
|
case dtype_int64:
|
||||||
*(SINT64*) address = *(SINT64*) source;
|
*(SINT64*) address = reader->getBigInt();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtype_real:
|
case dtype_real:
|
||||||
*(float*) address = *(float*) source;
|
*(float*) address = reader->getDouble();
|
||||||
break;
|
break;
|
||||||
case dtype_double:
|
case dtype_double:
|
||||||
*(double*) address = *(double*) source;
|
*(double*) address = reader->getDouble();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtype_sql_date:
|
case dtype_sql_date:
|
||||||
*(ISC_DATE*) address = *(ISC_DATE*) source;
|
*(ISC_DATE*) address = reader->getDate();
|
||||||
break;
|
break;
|
||||||
case dtype_sql_time:
|
case dtype_sql_time:
|
||||||
*(ISC_TIME*) address = *(ISC_TIME*) source;
|
*(ISC_TIME*) address = reader->getTime();
|
||||||
break;
|
break;
|
||||||
case dtype_timestamp:
|
case dtype_timestamp:
|
||||||
*(ISC_TIMESTAMP*) address = *(ISC_TIMESTAMP*) source;
|
*(ISC_TIMESTAMP*) address = reader->getTimeStamp();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtype_blob:
|
case dtype_blob:
|
||||||
@ -755,9 +748,9 @@ void DatabaseSnapshot::putField(Record* record, int id, const void* source, size
|
|||||||
blb* blob = BLB_create2(tdbb, tdbb->getTransaction(), &blob_id,
|
blb* blob = BLB_create2(tdbb, tdbb->getTransaction(), &blob_id,
|
||||||
bpb.getCount(), bpb.begin());
|
bpb.getCount(), bpb.begin());
|
||||||
|
|
||||||
length = MIN(length, MAX_USHORT);
|
const size_t length = MIN(reader->getClumpLength(), MAX_USHORT);
|
||||||
|
|
||||||
BLB_put_segment(tdbb, blob, (const UCHAR*) source, length);
|
BLB_put_segment(tdbb, blob, reader->getBytes(), length);
|
||||||
BLB_close(tdbb, blob);
|
BLB_close(tdbb, blob);
|
||||||
|
|
||||||
*(bid*) address = blob_id;
|
*(bid*) address = blob_id;
|
||||||
@ -996,9 +989,7 @@ void DatabaseSnapshot::putDatabase(const Database* database,
|
|||||||
temp = (database->dbb_flags & DBB_no_reserve) ? 0 : 1;
|
temp = (database->dbb_flags & DBB_no_reserve) ? 0 : 1;
|
||||||
writer.insertInt(f_mon_db_res_space, temp);
|
writer.insertInt(f_mon_db_res_space, temp);
|
||||||
// creation date
|
// creation date
|
||||||
writer.insertBytes(f_mon_db_created,
|
writer.insertTimeStamp(f_mon_db_created, database->dbb_creation_date.value());
|
||||||
(UCHAR*) &database->dbb_creation_date.value(),
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
// database size
|
// database size
|
||||||
writer.insertBigInt(f_mon_db_pages, PageSpace::actAlloc(database));
|
writer.insertBigInt(f_mon_db_pages, PageSpace::actAlloc(database));
|
||||||
|
|
||||||
@ -1078,9 +1069,7 @@ void DatabaseSnapshot::putAttachment(const Attachment* attachment,
|
|||||||
// charset
|
// charset
|
||||||
writer.insertInt(f_mon_att_charset_id, attachment->att_charset);
|
writer.insertInt(f_mon_att_charset_id, attachment->att_charset);
|
||||||
// timestamp
|
// timestamp
|
||||||
writer.insertBytes(f_mon_att_timestamp,
|
writer.insertTimeStamp(f_mon_att_timestamp, attachment->att_timestamp.value());
|
||||||
(UCHAR*) &attachment->att_timestamp.value(),
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
// garbage collection flag
|
// garbage collection flag
|
||||||
temp = (attachment->att_flags & ATT_no_cleanup) ? 0 : 1;
|
temp = (attachment->att_flags & ATT_no_cleanup) ? 0 : 1;
|
||||||
writer.insertInt(f_mon_att_gc, temp);
|
writer.insertInt(f_mon_att_gc, temp);
|
||||||
@ -1110,9 +1099,7 @@ void DatabaseSnapshot::putTransaction(const jrd_tra* transaction,
|
|||||||
temp = transaction->tra_requests ? mon_state_active : mon_state_idle;
|
temp = transaction->tra_requests ? mon_state_active : mon_state_idle;
|
||||||
writer.insertInt(f_mon_tra_state, temp);
|
writer.insertInt(f_mon_tra_state, temp);
|
||||||
// timestamp
|
// timestamp
|
||||||
writer.insertBytes(f_mon_tra_timestamp,
|
writer.insertTimeStamp(f_mon_tra_timestamp, transaction->tra_timestamp.value());
|
||||||
(UCHAR*) &transaction->tra_timestamp.value(),
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
// top transaction
|
// top transaction
|
||||||
writer.insertInt(f_mon_tra_top, transaction->tra_top);
|
writer.insertInt(f_mon_tra_top, transaction->tra_top);
|
||||||
// oldest transaction
|
// oldest transaction
|
||||||
@ -1173,17 +1160,13 @@ void DatabaseSnapshot::putRequest(const jrd_req* request,
|
|||||||
const int tra_id = request->req_transaction ?
|
const int tra_id = request->req_transaction ?
|
||||||
request->req_transaction->tra_number : 0;
|
request->req_transaction->tra_number : 0;
|
||||||
writer.insertInt(f_mon_stmt_tra_id, tra_id);
|
writer.insertInt(f_mon_stmt_tra_id, tra_id);
|
||||||
writer.insertBytes(f_mon_stmt_timestamp,
|
writer.insertTimeStamp(f_mon_stmt_timestamp, request->req_timestamp.value());
|
||||||
(UCHAR*) &request->req_timestamp.value(),
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writer.insertInt(f_mon_stmt_state, mon_state_idle);
|
writer.insertInt(f_mon_stmt_state, mon_state_idle);
|
||||||
writer.insertInt(f_mon_stmt_tra_id, 0);
|
writer.insertInt(f_mon_stmt_tra_id, 0);
|
||||||
ISC_TIMESTAMP empty = {0, 0};
|
ISC_TIMESTAMP empty = {0, 0};
|
||||||
writer.insertBytes(f_mon_stmt_timestamp,
|
writer.insertTimeStamp(f_mon_stmt_timestamp, empty);
|
||||||
(UCHAR*) &empty,
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
}
|
}
|
||||||
// sql text
|
// sql text
|
||||||
writer.insertString(f_mon_stmt_sql_text, request->req_sql_text);
|
writer.insertString(f_mon_stmt_sql_text, request->req_sql_text);
|
||||||
@ -1238,9 +1221,7 @@ void DatabaseSnapshot::putCall(const jrd_req* request,
|
|||||||
writer.insertInt(f_mon_call_type, 0);
|
writer.insertInt(f_mon_call_type, 0);
|
||||||
}
|
}
|
||||||
// timestamp
|
// timestamp
|
||||||
writer.insertBytes(f_mon_call_timestamp,
|
writer.insertTimeStamp(f_mon_call_timestamp, request->req_timestamp.value());
|
||||||
(const UCHAR*) &request->req_timestamp.value(),
|
|
||||||
sizeof(ISC_TIMESTAMP));
|
|
||||||
// source line/column
|
// source line/column
|
||||||
writer.insertInt(f_mon_call_src_line, request->req_src_line);
|
writer.insertInt(f_mon_call_src_line, request->req_src_line);
|
||||||
writer.insertInt(f_mon_call_src_column, request->req_src_column);
|
writer.insertInt(f_mon_call_src_column, request->req_src_column);
|
||||||
|
@ -115,7 +115,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int);
|
RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int);
|
||||||
void clearRecord(Record*);
|
void clearRecord(Record*);
|
||||||
void putField(Record*, int, const void*, size_t);
|
void putField(Record*, int, const Firebird::ClumpletReader*, bool);
|
||||||
|
|
||||||
static Firebird::ClumpletReader* dumpData(thread_db*, bool);
|
static Firebird::ClumpletReader* dumpData(thread_db*, bool);
|
||||||
static const char* checkNull(int, int, const char*, size_t);
|
static const char* checkNull(int, int, const char*, size_t);
|
||||||
|
@ -805,6 +805,43 @@ void GDS_breakpoint(int);
|
|||||||
#define CONST64(a) (a##LL)
|
#define CONST64(a) (a##LL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// 30 Dec 2002. Nickolay Samofatov
|
||||||
|
// This needs to be checked for all supported platforms
|
||||||
|
// The simpliest way to check it is to issue from correct client:
|
||||||
|
// declare external function abs2 double precision
|
||||||
|
// returns double precision by value
|
||||||
|
// entry_point 'IB_UDF_abs' module_name 'ib_udf';
|
||||||
|
// select abs2(2.0 / 3.0) from rdb$database;
|
||||||
|
// It will return big strange value in case of invalid define
|
||||||
|
|
||||||
|
// ASF: Currently, all little-endian are FB_SWAP_DOUBLE and big-endian aren't.
|
||||||
|
// AP: Define it for your hardware correctly in case your CPU do not follow mentioned rule.
|
||||||
|
// The follwoing lines are kept for reference only.
|
||||||
|
//#if defined(i386) || defined(I386) || defined(_M_IX86) || defined(AMD64) || defined(ARM) || defined(MIPSEL) || defined(DARWIN64) || defined(IA64)
|
||||||
|
//#define FB_SWAP_DOUBLE 1
|
||||||
|
//#elif defined(sparc) || defined(PowerPC) || defined(PPC) || defined(__ppc__) || defined(HPUX) || defined(MIPS) || defined(__ppc64__)
|
||||||
|
//#define FB_SWAP_DOUBLE 0
|
||||||
|
//#else
|
||||||
|
//#error "Define FB_SWAP_DOUBLE for your platform correctly !"
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifndef FB_SWAP_DOUBLE
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
#define FB_SWAP_DOUBLE 0
|
||||||
|
#else
|
||||||
|
#define FB_SWAP_DOUBLE 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Commonly used indices to access parts of double in correct order.
|
||||||
|
#if FB_SWAP_DOUBLE
|
||||||
|
#define FB_LONG_DOUBLE_FIRST 1
|
||||||
|
#define FB_LONG_DOUBLE_SECOND 0
|
||||||
|
#else
|
||||||
|
#define FB_LONG_DOUBLE_FIRST 0
|
||||||
|
#define FB_LONG_DOUBLE_SECOND 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* switch name and state table. This structure should be used in all
|
/* switch name and state table. This structure should be used in all
|
||||||
* command line tools to facilitate parsing options.*/
|
* command line tools to facilitate parsing options.*/
|
||||||
|
@ -33,43 +33,6 @@
|
|||||||
#include "../remote/xdr_proto.h"
|
#include "../remote/xdr_proto.h"
|
||||||
#include "../jrd/gds_proto.h"
|
#include "../jrd/gds_proto.h"
|
||||||
|
|
||||||
// 30 Dec 2002. Nickolay Samofatov
|
|
||||||
// This needs to be checked for all supported platforms
|
|
||||||
// The simpliest way to check it is to issue from correct client:
|
|
||||||
// declare external function abs2 double precision
|
|
||||||
// returns double precision by value
|
|
||||||
// entry_point 'IB_UDF_abs' module_name 'ib_udf';
|
|
||||||
// select abs2(2.0 / 3.0) from rdb$database;
|
|
||||||
// It will return big strange value in case of invalid define
|
|
||||||
|
|
||||||
/*
|
|
||||||
// ASF: Currently, all little-endian are FB_SWAP_DOUBLE and big-endian aren't.
|
|
||||||
// AP: Left this lines as a reference in case some CPU in the future do not follow mentioned rule.
|
|
||||||
#if defined(i386) || defined(I386) || defined(_M_IX86) || defined(AMD64) || defined(ARM) || defined(MIPSEL) || defined(DARWIN64) || defined(IA64)
|
|
||||||
#define FB_SWAP_DOUBLE 1
|
|
||||||
#elif defined(sparc) || defined(PowerPC) || defined(PPC) || defined(__ppc__) || defined(HPUX) || defined(MIPS) || defined(__ppc64__)
|
|
||||||
#define FB_SWAP_DOUBLE 0
|
|
||||||
#else
|
|
||||||
#error "Define FB_SWAP_DOUBLE for your platform correctly !"
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FB_SWAP_DOUBLE
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
#define FB_SWAP_DOUBLE 0
|
|
||||||
#else
|
|
||||||
#define FB_SWAP_DOUBLE 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FB_SWAP_DOUBLE
|
|
||||||
#define FB_LONG_DOUBLE_FIRST 1
|
|
||||||
#define FB_LONG_DOUBLE_SECOND 0
|
|
||||||
#else
|
|
||||||
#define FB_LONG_DOUBLE_FIRST 0
|
|
||||||
#define FB_LONG_DOUBLE_SECOND 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BURP
|
#ifdef BURP
|
||||||
#include "../burp/misc_proto.h" /* Was "../burp/misc_pro.h" -Jeevan */
|
#include "../burp/misc_proto.h" /* Was "../burp/misc_pro.h" -Jeevan */
|
||||||
inline UCHAR* XDR_ALLOC(ULONG size) {
|
inline UCHAR* XDR_ALLOC(ULONG size) {
|
||||||
|
Loading…
Reference in New Issue
Block a user