8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:03:03 +01:00

Inject UserBlob into QLI (not in all places).

This commit is contained in:
robocop 2007-04-06 10:10:10 +00:00
parent c5ea420493
commit 345b422633
8 changed files with 233 additions and 135 deletions

View File

@ -24,8 +24,10 @@
#include "UserBlob.h" #include "UserBlob.h"
#include "../jrd/ibase.h" #include "../jrd/ibase.h"
#include "../jrd/common.h" #include "../jrd/common.h"
#include "../jrd/gds_proto.h"
static const USHORT SEGMENT_LIMIT = 65535; static const USHORT SEGMENT_LIMIT = 65535;
//static SLONG fb_vax_integer(const UCHAR* ptr, int length);
bool UserBlob::open(FB_API_HANDLE& db, FB_API_HANDLE& trans, ISC_QUAD& blobid) bool UserBlob::open(FB_API_HANDLE& db, FB_API_HANDLE& trans, ISC_QUAD& blobid)
@ -236,3 +238,91 @@ bool UserBlob::getInfo(size_t items_size, const UCHAR* blr_items,
out_len, reinterpret_cast<char*>(blob_info)); out_len, reinterpret_cast<char*>(blob_info));
} }
bool fb_blob_size( const UserBlob& b,
SLONG* size,
SLONG* seg_count,
SLONG* max_seg)
{
/**************************************
*
* f b _ b l o b _ s i z e
*
**************************************
*
* Functional description
* Get the size, number of segments, and max
* segment length of a blob. Return true
* if it happens to succeed.
*
**************************************/
static const UCHAR blob_items[] =
{
isc_info_blob_max_segment,
isc_info_blob_num_segments,
isc_info_blob_total_length
};
UCHAR buffer[64];
if (!b.getInfo(sizeof(blob_items), blob_items, sizeof(buffer), buffer))
return false;
const UCHAR* p = buffer;
const UCHAR* const end = buffer + sizeof(buffer);
for (UCHAR item = *p++; item != isc_info_end && p < end; item = *p++)
{
const USHORT l = gds__vax_integer(p, 2);
p += 2;
const SLONG n = gds__vax_integer(p, l);
p += l;
switch (item)
{
case isc_info_blob_max_segment:
if (max_seg)
*max_seg = n;
break;
case isc_info_blob_num_segments:
if (seg_count)
*seg_count = n;
break;
case isc_info_blob_total_length:
if (size)
*size = n;
break;
default:
return false;
}
}
return true;
}
/* If someone sees the need to not depend on gds.cpp...
static SLONG fb_vax_integer(const UCHAR* ptr, int length)
{
// **************************************
// *
// * f b _ v a x _ i n t e g e r
// *
// **************************************
// *
// * Functional description
// * Pick up (and convert) a VAX style integer of length 1, 2, or 4 bytes.
// *
// **************************************
SLONG value = 0;
int shift = 0;
while (--length >= 0) {
value += ((SLONG) *ptr++) << shift;
shift += 8;
}
return value;
}
*/

View File

@ -46,6 +46,7 @@ public:
bool putData(size_t len, const void* buffer, size_t& real_len); bool putData(size_t len, const void* buffer, size_t& real_len);
bool isOpen() const; bool isOpen() const;
ISC_STATUS getCode() const; ISC_STATUS getCode() const;
// FB_API_HANDLE& getHandle();
bool getInfo(size_t items_size, const UCHAR* blr_items, size_t info_size, UCHAR* blob_info) const; bool getInfo(size_t items_size, const UCHAR* blr_items, size_t info_size, UCHAR* blob_info) const;
static bool blobIsNull(const ISC_QUAD& blobid); static bool blobIsNull(const ISC_QUAD& blobid);
private: private:
@ -84,10 +85,22 @@ inline ISC_STATUS UserBlob::getCode() const
return m_status[1]; return m_status[1];
} }
//inline FB_API_HANDLE& UserBlob::getHandle()
//{
// return m_blob;
//}
inline bool UserBlob::blobIsNull(const ISC_QUAD& blobid) inline bool UserBlob::blobIsNull(const ISC_QUAD& blobid)
{ {
return blobid.gds_quad_high == 0 && blobid.gds_quad_low == 0; return blobid.gds_quad_high == 0 && blobid.gds_quad_low == 0;
} }
bool fb_blob_size( const UserBlob& b,
SLONG* size,
SLONG* seg_count,
SLONG* max_seg);
#endif // FB_USER_BLOB_H #endif // FB_USER_BLOB_H

View File

@ -536,10 +536,5 @@ EXTERN qli_req* QLI_requests; // Requests in statement
#include "../qli/all_proto.h" #include "../qli/all_proto.h"
inline bool isNullBlob(const ISC_QUAD* id)
{
return !id->gds_quad_high && !id->gds_quad_low;
}
#endif // QLI_DTR_H #endif // QLI_DTR_H

View File

@ -37,6 +37,7 @@
#include "../qli/picst_proto.h" #include "../qli/picst_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/utl_proto.h" #include "../jrd/utl_proto.h"
#include "../common/classes/UserBlob.h"
static SLONG execute_any(qli_nod*); static SLONG execute_any(qli_nod*);
@ -677,7 +678,7 @@ static DSC *execute_edit( qli_nod* node)
const TEXT* field_name = (TEXT *) node->nod_arg[e_edt_name]; const TEXT* field_name = (TEXT *) node->nod_arg[e_edt_name];
BLOB_edit(id, dbb->dbb_handle, dbb->dbb_transaction, field_name); BLOB_edit(id, dbb->dbb_handle, dbb->dbb_transaction, field_name);
node->nod_desc.dsc_missing = isNullBlob(id) ? DSC_missing : 0; node->nod_desc.dsc_missing = UserBlob::blobIsNull(*id) ? DSC_missing : 0;
return &node->nod_desc; return &node->nod_desc;
} }

View File

@ -38,6 +38,7 @@
#include "../qli/repor_proto.h" #include "../qli/repor_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/utl_proto.h" #include "../jrd/utl_proto.h"
#include "../common/classes/UserBlob.h"
using MsgFormat::SafeArg; using MsgFormat::SafeArg;
@ -664,17 +665,15 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
return false; return false;
} }
// We've got a blob copy on our hands. // We've got a blob copy on our hands.
if (!from_desc) { if (!from_desc) {
*to_desc->dsc_address = 0; *to_desc->dsc_address = 0;
return true; return true;
} }
FB_API_HANDLE to_blob = 0;
FB_API_HANDLE from_blob = 0;
// Format blob parameter block for the existing blob // Format blob parameter block for the existing blob
UCHAR bpb[20]; UCHAR bpb[20];
UCHAR* p = bpb; UCHAR* p = bpb;
@ -690,23 +689,25 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
const USHORT bpb_length = p - bpb; const USHORT bpb_length = p - bpb;
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
if (isc_create_blob(status_vector, &to_dbb->dbb_handle, UserBlob to_blob(status_vector);
&to_dbb->dbb_transaction, &to_blob, UserBlob from_blob(status_vector);
(ISC_QUAD*) to_desc->dsc_address))
if (!to_blob.create(to_dbb->dbb_handle, to_dbb->dbb_transaction,
*(ISC_QUAD*) to_desc->dsc_address))
{ {
ERRQ_database_error(to_dbb, status_vector); ERRQ_database_error(to_dbb, status_vector);
} }
if (isc_open_blob2(status_vector, &from_dbb->dbb_handle, if (!from_blob.open(from_dbb->dbb_handle, from_dbb->dbb_transaction,
&from_dbb->dbb_transaction, &from_blob, *(ISC_QUAD*) from_desc->dsc_address, bpb_length,
(ISC_QUAD*) from_desc->dsc_address, bpb_length,
bpb)) bpb))
{ {
ERRQ_database_error(from_dbb, status_vector); ERRQ_database_error(from_dbb, status_vector);
} }
SLONG size, segment_count, max_segment; SLONG size, segment_count, max_segment;
gds__blob_size(&from_blob, &size, &segment_count, &max_segment); if (!fb_blob_size(from_blob, &size, &segment_count, &max_segment))
ERRQ_database_error(from_dbb, status_vector);
UCHAR fixed_buffer[4096]; UCHAR fixed_buffer[4096];
UCHAR* buffer; UCHAR* buffer;
@ -725,12 +726,10 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
#endif #endif
} }
USHORT length; size_t length;
while (!isc_get_segment(status_vector, &from_blob, &length, buffer_length, while (from_blob.getSegment(buffer_length, buffer, length) && !from_blob.getCode())
(char*) buffer))
{ {
if (isc_put_segment(status_vector, &to_blob, length, if (!to_blob.putSegment(length, buffer))
reinterpret_cast<const char*>(buffer)))
{ {
ERRQ_database_error(to_dbb, status_vector); ERRQ_database_error(to_dbb, status_vector);
} }
@ -739,10 +738,10 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
if (buffer != fixed_buffer) if (buffer != fixed_buffer)
gds__free(buffer); gds__free(buffer);
if (isc_close_blob(status_vector, &from_blob)) if (!from_blob.close())
ERRQ_database_error(from_dbb, status_vector); ERRQ_database_error(from_dbb, status_vector);
if (isc_close_blob(status_vector, &to_blob)) if (!to_blob.close())
ERRQ_database_error(to_dbb, status_vector); ERRQ_database_error(to_dbb, status_vector);
return true; return true;

View File

@ -42,6 +42,7 @@
#include "../jrd/utl_proto.h" #include "../jrd/utl_proto.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../common/classes/UserBlob.h"
using MsgFormat::SafeArg; using MsgFormat::SafeArg;
@ -55,7 +56,7 @@ DATABASE DB1 = FILENAME "yachts.lnk";
static void add_field(qli_rel*, qli_fld*, USHORT); static void add_field(qli_rel*, qli_fld*, USHORT);
static void add_sql_field(qli_rel*, qli_fld*, USHORT, qli_rlb*); static void add_sql_field(qli_rel*, qli_fld*, USHORT, qli_rlb*);
static void blob_copy(qli_rlb*, qli_rel*, ISC_QUAD*); static void blob_copy(qli_rlb*, qli_rel*, ISC_QUAD&);
static void change_field(qli_rel*, qli_fld*); static void change_field(qli_rel*, qli_fld*);
static bool check_global_field(DBB, qli_fld*, const TEXT*); static bool check_global_field(DBB, qli_fld*, const TEXT*);
static bool check_relation(qli_rel*); static bool check_relation(qli_rel*);
@ -67,14 +68,14 @@ static ISC_STATUS detach(ISC_STATUS *, DBB);
static void execute_dynamic_ddl(DBB, qli_rlb*); static void execute_dynamic_ddl(DBB, qli_rlb*);
static int field_length(USHORT, USHORT); static int field_length(USHORT, USHORT);
static void get_database_type(DBB); static void get_database_type(DBB);
static TEXT *get_query_header(DBB, ISC_QUAD*); static TEXT *get_query_header(DBB, ISC_QUAD&);
static void install(dbb*); static void install(dbb*);
static qli_syntax* make_node(NOD_T, USHORT); static qli_syntax* make_node(NOD_T, USHORT);
static TEXT *make_string(TEXT*, SSHORT); static TEXT *make_string(TEXT*, SSHORT);
static qli_symbol* make_symbol(TEXT *, SSHORT); static qli_symbol* make_symbol(TEXT *, SSHORT);
static qli_const* missing_value(ISC_QUAD*, qli_symbol*); static qli_const* missing_value(ISC_QUAD&, qli_symbol*);
static qli_syntax* parse_blr(UCHAR **, qli_symbol*); static qli_syntax* parse_blr(UCHAR **, qli_symbol*);
static qli_syntax* parse_blr_blob(ISC_QUAD*, qli_symbol*); static qli_syntax* parse_blr_blob(ISC_QUAD&, qli_symbol*);
static void purge_relation(qli_rel*); static void purge_relation(qli_rel*);
static void put_dyn_string(qli_rlb*, const TEXT*); static void put_dyn_string(qli_rlb*, const TEXT*);
static void rollback_update(DBB); static void rollback_update(DBB);
@ -801,13 +802,13 @@ void MET_fields( qli_rel* relation)
} }
ISC_QUAD* blob = & RFR.RDB$QUERY_HEADER; ISC_QUAD* blob = & RFR.RDB$QUERY_HEADER;
if (isNullBlob(blob)) if (UserBlob::blobIsNull(*blob))
blob = & RFL.RDB$QUERY_HEADER; blob = & RFL.RDB$QUERY_HEADER;
if (!isNullBlob(blob)) if (!UserBlob::blobIsNull(*blob))
field->fld_query_header = get_query_header(database, blob); field->fld_query_header = get_query_header(database, *blob);
blob = & RFL.RDB$COMPUTED_BLR; blob = & RFL.RDB$COMPUTED_BLR;
if (!isNullBlob(blob)) if (!UserBlob::blobIsNull(*blob))
field->fld_flags |= FLD_computed; field->fld_flags |= FLD_computed;
field->fld_dtype = MET_get_datatype(RFL.RDB$FIELD_TYPE); field->fld_dtype = MET_get_datatype(RFL.RDB$FIELD_TYPE);
@ -820,14 +821,14 @@ void MET_fields( qli_rel* relation)
if (!RFL.RDB$MISSING_VALUE.NULL) if (!RFL.RDB$MISSING_VALUE.NULL)
field->fld_missing = field->fld_missing =
missing_value(&RFL.RDB$MISSING_VALUE, field->fld_name); missing_value(RFL.RDB$MISSING_VALUE, field->fld_name);
if (!(field->fld_edit_string = if (!(field->fld_edit_string =
make_string(RFR.RDB$EDIT_STRING, sizeof(RFR.RDB$EDIT_STRING)))) make_string(RFR.RDB$EDIT_STRING, sizeof(RFR.RDB$EDIT_STRING))))
field->fld_edit_string = field->fld_edit_string =
make_string(RFL.RDB$EDIT_STRING, sizeof(RFL.RDB$EDIT_STRING)); make_string(RFL.RDB$EDIT_STRING, sizeof(RFL.RDB$EDIT_STRING));
field->fld_validation = field->fld_validation =
parse_blr_blob(&RFL.RDB$VALIDATION_BLR, field->fld_name); parse_blr_blob(RFL.RDB$VALIDATION_BLR, field->fld_name);
if (MET_dimensions(database, RFL.RDB$FIELD_NAME) > 0) if (MET_dimensions(database, RFL.RDB$FIELD_NAME) > 0)
field->fld_flags |= FLD_array; field->fld_flags |= FLD_array;
END_FOR END_FOR
@ -1824,7 +1825,7 @@ static void add_sql_field( qli_rel* relation, qli_fld* field, USHORT position,
} }
static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD* source_blob_id) static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD& source_blob_id)
{ {
/************************************** /**************************************
* *
@ -1842,17 +1843,20 @@ static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD* source_blob_id)
DBB source_dbb = DBB source_dbb =
(source->rel_database) ? source->rel_database : QLI_databases; (source->rel_database) ? source->rel_database : QLI_databases;
DB = source_dbb->dbb_handle; DB = source_dbb->dbb_handle;
FB_API_HANDLE source_blob = 0; UserBlob source_blob(status_vector);
if (isc_open_blob(status_vector, &DB, &source_dbb->dbb_meta_trans, if (!source_blob.open(DB, source_dbb->dbb_meta_trans, source_blob_id))
&source_blob, source_blob_id))
{ {
rollback_update(source_dbb); rollback_update(source_dbb);
ERRQ_database_error(source_dbb, status_vector); ERRQ_database_error(source_dbb, status_vector);
} }
SLONG size, segment_count, max_segment; SLONG size, segment_count, max_segment;
gds__blob_size(&source_blob, (SLONG*) &size, &segment_count, &max_segment); if (!fb_blob_size(source_blob, &size, &segment_count, &max_segment))
{
rollback_update(source_dbb);
ERRQ_database_error(source_dbb, status_vector);
}
TEXT fixed_buffer[4096]; TEXT fixed_buffer[4096];
TEXT* buffer; TEXT* buffer;
@ -1868,9 +1872,8 @@ static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD* source_blob_id)
STUFF_WORD((USHORT) size); STUFF_WORD((USHORT) size);
USHORT length; size_t length;
while (!isc_get_segment(status_vector, &source_blob, &length, while (source_blob.getSegment(buffer_length, buffer, length) && !source_blob.getCode())
buffer_length, buffer))
{ {
while (rlb->rlb_limit - rlb->rlb_data < length) while (rlb->rlb_limit - rlb->rlb_data < length)
rlb = GEN_rlb_extend(rlb); rlb = GEN_rlb_extend(rlb);
@ -1889,7 +1892,7 @@ static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD* source_blob_id)
if (buffer != fixed_buffer) if (buffer != fixed_buffer)
gds__free(buffer); gds__free(buffer);
if (isc_close_blob(status_vector, &source_blob)) { if (!source_blob.close()) {
rollback_update(source_dbb); rollback_update(source_dbb);
ERRQ_database_error(source_dbb, status_vector); ERRQ_database_error(source_dbb, status_vector);
} }
@ -2021,8 +2024,8 @@ static bool check_global_field(DBB database,
} }
if (!field->fld_query_header) if (!field->fld_query_header)
{ {
ISC_QUAD* blob = &X.RDB$QUERY_HEADER; ISC_QUAD& blob = X.RDB$QUERY_HEADER;
if (!isNullBlob(blob)) if (!UserBlob::blobIsNull(blob))
{ {
field->fld_query_header = field->fld_query_header =
get_query_header(database, blob); get_query_header(database, blob);
@ -2139,7 +2142,7 @@ static void clone_fields( qli_rel* target, qli_rel* source)
if (!F.RDB$VALIDATION_BLR.NULL) { if (!F.RDB$VALIDATION_BLR.NULL) {
STUFF(isc_dyn_fld_validation_blr); STUFF(isc_dyn_fld_validation_blr);
blob_copy(rlb, source, &F.RDB$VALIDATION_BLR); blob_copy(rlb, source, F.RDB$VALIDATION_BLR);
} }
} }
else else
@ -2177,17 +2180,17 @@ static void clone_fields( qli_rel* target, qli_rel* source)
if (!Y.RDB$QUERY_HEADER.NULL) { if (!Y.RDB$QUERY_HEADER.NULL) {
STUFF(isc_dyn_fld_query_header); STUFF(isc_dyn_fld_query_header);
blob_copy(rlb, source, &Y.RDB$QUERY_HEADER); blob_copy(rlb, source, Y.RDB$QUERY_HEADER);
} }
if (!Y.RDB$DESCRIPTION.NULL) { if (!Y.RDB$DESCRIPTION.NULL) {
STUFF(isc_dyn_description); STUFF(isc_dyn_description);
blob_copy(rlb, source, &Y.RDB$DESCRIPTION); blob_copy(rlb, source, Y.RDB$DESCRIPTION);
} }
if (!Y.RDB$DEFAULT_VALUE.NULL) { if (!Y.RDB$DEFAULT_VALUE.NULL) {
STUFF(isc_dyn_fld_default_value); STUFF(isc_dyn_fld_default_value);
blob_copy(rlb, source, &Y.RDB$DEFAULT_VALUE); blob_copy(rlb, source, Y.RDB$DEFAULT_VALUE);
} }
if ((source->rel_database->dbb_capabilities & DBB_cap_rfr_sys_flag) && if ((source->rel_database->dbb_capabilities & DBB_cap_rfr_sys_flag) &&
@ -2211,9 +2214,9 @@ static void clone_fields( qli_rel* target, qli_rel* source)
if (!F.RDB$COMPUTED_BLR.NULL) if (!F.RDB$COMPUTED_BLR.NULL)
{ {
STUFF(isc_dyn_fld_computed_blr); STUFF(isc_dyn_fld_computed_blr);
blob_copy(rlb, source, &F.RDB$COMPUTED_BLR); blob_copy(rlb, source, F.RDB$COMPUTED_BLR);
STUFF(isc_dyn_fld_computed_source); STUFF(isc_dyn_fld_computed_source);
blob_copy(rlb, source, &F.RDB$COMPUTED_SOURCE); blob_copy(rlb, source, F.RDB$COMPUTED_SOURCE);
STUFF(isc_dyn_fld_type); STUFF(isc_dyn_fld_type);
STUFF_WORD(2); STUFF_WORD(2);
@ -2391,32 +2394,32 @@ static void clone_global_fields( qli_rel* target, qli_rel* source)
if (!Y.RDB$MISSING_VALUE.NULL) { if (!Y.RDB$MISSING_VALUE.NULL) {
STUFF(isc_dyn_fld_missing_value); STUFF(isc_dyn_fld_missing_value);
blob_copy(rlb, source, &Y.RDB$MISSING_VALUE); blob_copy(rlb, source, Y.RDB$MISSING_VALUE);
} }
if (!Y.RDB$DEFAULT_VALUE.NULL) { if (!Y.RDB$DEFAULT_VALUE.NULL) {
STUFF(isc_dyn_fld_default_value); STUFF(isc_dyn_fld_default_value);
blob_copy(rlb, source, &Y.RDB$DEFAULT_VALUE); blob_copy(rlb, source, Y.RDB$DEFAULT_VALUE);
} }
if (!Y.RDB$QUERY_HEADER.NULL) { if (!Y.RDB$QUERY_HEADER.NULL) {
STUFF(isc_dyn_fld_query_header); STUFF(isc_dyn_fld_query_header);
blob_copy(rlb, source, &Y.RDB$QUERY_HEADER); blob_copy(rlb, source, Y.RDB$QUERY_HEADER);
} }
if (!Y.RDB$DESCRIPTION.NULL) { if (!Y.RDB$DESCRIPTION.NULL) {
STUFF(isc_dyn_description); STUFF(isc_dyn_description);
blob_copy(rlb, source, &Y.RDB$DESCRIPTION); blob_copy(rlb, source, Y.RDB$DESCRIPTION);
} }
if (!Y.RDB$VALIDATION_BLR.NULL) { if (!Y.RDB$VALIDATION_BLR.NULL) {
STUFF(isc_dyn_fld_validation_blr); STUFF(isc_dyn_fld_validation_blr);
blob_copy(rlb, source, &Y.RDB$VALIDATION_BLR); blob_copy(rlb, source, Y.RDB$VALIDATION_BLR);
} }
if (!Y.RDB$VALIDATION_SOURCE.NULL) { if (!Y.RDB$VALIDATION_SOURCE.NULL) {
STUFF(isc_dyn_fld_validation_source); STUFF(isc_dyn_fld_validation_source);
blob_copy(rlb, source, &Y.RDB$VALIDATION_SOURCE); blob_copy(rlb, source, Y.RDB$VALIDATION_SOURCE);
} }
if ((target->rel_database->dbb_capabilities & DBB_cap_dimensions) && if ((target->rel_database->dbb_capabilities & DBB_cap_dimensions) &&
@ -2721,7 +2724,7 @@ static void get_database_type( DBB new_dbb)
} }
static TEXT *get_query_header( DBB database, ISC_QUAD* blob_id) static TEXT *get_query_header( DBB database, ISC_QUAD& blob_id)
{ {
/************************************** /**************************************
* *
@ -2735,10 +2738,9 @@ static TEXT *get_query_header( DBB database, ISC_QUAD* blob_id)
**************************************/ **************************************/
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
TEXT header[1024], buffer[1024]; TEXT header[1024], buffer[1024];
FB_API_HANDLE blob = 0; UserBlob blob(status_vector);
if (isc_open_blob(status_vector, &database->dbb_handle, if (!blob.open(database->dbb_handle, gds_trans, blob_id))
&gds_trans, &blob, blob_id))
{ {
ERRQ_database_error(database, status_vector); ERRQ_database_error(database, status_vector);
} }
@ -2748,10 +2750,8 @@ static TEXT *get_query_header( DBB database, ISC_QUAD* blob_id)
// CVC: No bounds check here: it's assumed that 1024 is enough, but "p" // CVC: No bounds check here: it's assumed that 1024 is enough, but "p"
// might overflow "header" eventually. // might overflow "header" eventually.
for (;;) { for (;;) {
USHORT length; size_t length;
ISC_STATUS status = isc_get_segment(status_vector, &blob, &length, if (!blob.getSegment(sizeof(buffer), buffer, length))
sizeof(buffer), buffer);
if (status && status != isc_segment)
break; break;
if (length && buffer[length - 1] == '\n') if (length && buffer[length - 1] == '\n')
--length; --length;
@ -2769,7 +2769,7 @@ static TEXT *get_query_header( DBB database, ISC_QUAD* blob_id)
} }
} }
if (isc_close_blob(status_vector, &blob)) if (!blob.close())
ERRQ_database_error(database, gds_status); ERRQ_database_error(database, gds_status);
*p = 0; *p = 0;
@ -3002,7 +3002,7 @@ static qli_symbol* make_symbol( TEXT* string, SSHORT length)
} }
static qli_const* missing_value( ISC_QUAD* blob_id, qli_symbol* symbol) static qli_const* missing_value( ISC_QUAD& blob_id, qli_symbol* symbol)
{ {
/************************************** /**************************************
* *
@ -3286,7 +3286,7 @@ static qli_syntax* parse_blr( UCHAR ** ptr, qli_symbol* symbol)
} }
static qli_syntax* parse_blr_blob(ISC_QUAD* blob_id, qli_symbol* symbol) static qli_syntax* parse_blr_blob(ISC_QUAD& blob_id, qli_symbol* symbol)
{ {
/************************************** /**************************************
* *
@ -3300,28 +3300,29 @@ static qli_syntax* parse_blr_blob(ISC_QUAD* blob_id, qli_symbol* symbol)
**************************************/ **************************************/
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
if (isNullBlob(blob_id)) if (UserBlob::blobIsNull(blob_id))
return NULL; return NULL;
FB_API_HANDLE handle = 0; UserBlob handle(status_vector);
if (isc_open_blob(status_vector, &DB, &gds_trans, &handle, blob_id)) if (!handle.open(DB, gds_trans, blob_id))
return NULL; return NULL;
UCHAR buffer[1024]; UCHAR buffer[1024];
UCHAR* ptr = buffer; UCHAR* ptr = buffer;
for (;;) { for (;;) {
USHORT length = buffer + sizeof(buffer) - ptr; size_t length = buffer + sizeof(buffer) - ptr;
if (!length) if (!length)
break; break;
if (isc_get_segment(status_vector, &handle, &length, length, // The old code considered getting a portion of a segment a bug.
(char*) ptr)) // Anyway, 1024 is not much to contain the BLR stream, even for validation.
if (!handle.getSegment(length, ptr, length) || handle.getCode())
break; break;
ptr += length; ptr += length;
} }
if (isc_close_blob(status_vector, &handle)) if (!handle.close())
return NULL; return NULL;
if (ptr == buffer) if (ptr == buffer)
@ -3467,8 +3468,10 @@ static void set_capabilities( DBB database)
} }
if (req) if (req)
{
if (isc_release_request(gds_status, &req)) if (isc_release_request(gds_status, &req))
ERRQ_database_error(database, gds_status); ERRQ_database_error(database, gds_status);
}
} }

View File

@ -156,7 +156,8 @@ void PRO_copy_procedure(
DB1 = new_database->dbb_handle; DB1 = new_database->dbb_handle;
// create blob parameter block since procedure is a text blob // create blob parameter block since procedure is a text blob
// But nothing was done! The bpb is empty.
UCHAR bpb[20]; UCHAR bpb[20];
UCHAR* p = bpb; UCHAR* p = bpb;

View File

@ -39,19 +39,20 @@
#include "../qli/show_proto.h" #include "../qli/show_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../common/classes/UserBlob.h"
using MsgFormat::SafeArg; using MsgFormat::SafeArg;
static void array_dimensions(DBB, const TEXT*); static void array_dimensions(DBB, const TEXT*);
static void display_acl(DBB, ISC_QUAD*); static void display_acl(DBB, ISC_QUAD&);
static void display_blob(DBB, ISC_QUAD*, const TEXT*, USHORT, const UCHAR*, bool); static void display_blob(DBB, ISC_QUAD&, const TEXT*, USHORT, const UCHAR*, bool);
static void display_blr(DBB, ISC_QUAD*); static void display_blr(DBB, ISC_QUAD&);
static void display_text(DBB, ISC_QUAD*, const TEXT*, bool); static void display_text(DBB, ISC_QUAD&, const TEXT*, bool);
static void display_procedure(DBB, const UCHAR*, FB_API_HANDLE); static void display_procedure(DBB, const UCHAR*, FB_API_HANDLE);
static USHORT get_window_size(int); static USHORT get_window_size(int);
static void show_blob_info(ISC_QUAD*, ISC_QUAD*, USHORT, USHORT, DBB, const TEXT*); static void show_blob_info(ISC_QUAD&, ISC_QUAD&, USHORT, USHORT, DBB, const TEXT*);
static void show_blr(DBB, USHORT, ISC_QUAD*, USHORT, ISC_QUAD*); static void show_blr(DBB, USHORT, ISC_QUAD&, USHORT, ISC_QUAD&);
static void show_datatype(DBB, USHORT, USHORT, SSHORT, SSHORT, USHORT, static void show_datatype(DBB, USHORT, USHORT, SSHORT, SSHORT, USHORT,
USHORT); USHORT);
static void show_dbb(DBB); static void show_dbb(DBB);
@ -75,7 +76,7 @@ static int show_gbl_field_detail(DBB, const TEXT*);
static void show_gbl_fields(DBB); static void show_gbl_fields(DBB);
static int show_gbl_fields_detail(DBB); static int show_gbl_fields_detail(DBB);
static int show_indices_detail(qli_rel*); static int show_indices_detail(qli_rel*);
static void show_matching(void); static void show_matching();
static void show_names(const TEXT*, USHORT, TEXT*); static void show_names(const TEXT*, USHORT, TEXT*);
static void show_proc(QPR); static void show_proc(QPR);
static void show_procs(DBB); static void show_procs(DBB);
@ -90,7 +91,7 @@ static void show_text_blob(DBB, const TEXT*, USHORT, ISC_QUAD*, USHORT,
ISC_QUAD*, bool); ISC_QUAD*, bool);
static void show_trig(qli_rel*); static void show_trig(qli_rel*);
static int show_trigger_detail(DBB, const TEXT*); static int show_trigger_detail(DBB, const TEXT*);
static void show_trigger_header(TEXT*, USHORT, USHORT, USHORT, ISC_QUAD*, static void show_trigger_header(TEXT*, USHORT, USHORT, USHORT, ISC_QUAD&,
DBB, const TEXT*); DBB, const TEXT*);
static void show_trigger_messages(DBB, const TEXT*); static void show_trigger_messages(DBB, const TEXT*);
static void show_trigger_status(TEXT*, USHORT, USHORT, USHORT); static void show_trigger_status(TEXT*, USHORT, USHORT, USHORT);
@ -460,7 +461,7 @@ static void array_dimensions( DBB database, const TEXT * field_name)
} }
static void display_acl( DBB dbb, ISC_QUAD* blob_id) static void display_acl( DBB dbb, ISC_QUAD& blob_id)
{ {
/************************************** /**************************************
* *
@ -479,7 +480,7 @@ static void display_acl( DBB dbb, ISC_QUAD* blob_id)
static void display_blob( static void display_blob(
DBB dbb, DBB dbb,
ISC_QUAD* blob_id, ISC_QUAD& blob_id,
const TEXT* prefix, const TEXT* prefix,
USHORT bpb_length, USHORT bpb_length,
const UCHAR* bpb, const UCHAR* bpb,
@ -497,11 +498,9 @@ static void display_blob(
**************************************/ **************************************/
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
FB_API_HANDLE blob = 0; UserBlob blob(status_vector);
if (isc_open_blob2(status_vector, &dbb->dbb_handle, &dbb->dbb_meta_trans, if (!blob.open(dbb->dbb_handle, dbb->dbb_meta_trans, blob_id, bpb_length, bpb))
&blob, blob_id, bpb_length,
bpb))
{ {
ERRQ_database_error(dbb, status_vector); ERRQ_database_error(dbb, status_vector);
} }
@ -509,10 +508,8 @@ static void display_blob(
buf_type buffer; buf_type buffer;
const USHORT buffer_length = sizeof(buffer) - 1; const USHORT buffer_length = sizeof(buffer) - 1;
for (;;) { for (;;) {
USHORT length; size_t length;
const ISC_STATUS status = isc_get_segment(status_vector, &blob, if (!blob.getSegment(buffer_length, buffer, length))
&length, buffer_length, buffer);
if (status && status != isc_segment)
break; break;
buffer[length--] = 0; buffer[length--] = 0;
if (strip_line) { if (strip_line) {
@ -531,11 +528,11 @@ static void display_blob(
printf("%s%s\n", prefix, buffer); printf("%s%s\n", prefix, buffer);
} }
isc_close_blob(status_vector, &blob); blob.close();
} }
static void display_blr( DBB dbb, ISC_QUAD* blob_id) static void display_blr( DBB dbb, ISC_QUAD& blob_id)
{ {
/************************************** /**************************************
* *
@ -552,7 +549,7 @@ static void display_blr( DBB dbb, ISC_QUAD* blob_id)
} }
static void display_text( DBB dbb, ISC_QUAD* blob_id, const TEXT* prefix, bool strip) static void display_text( DBB dbb, ISC_QUAD& blob_id, const TEXT* prefix, bool strip)
{ {
/************************************** /**************************************
* *
@ -618,8 +615,8 @@ static USHORT get_window_size( int max_width)
static void show_blob_info( static void show_blob_info(
ISC_QUAD* blob_blr, ISC_QUAD& blob_blr,
ISC_QUAD* blob_src, ISC_QUAD& blob_src,
USHORT msg_blr, USHORT msg_blr,
USHORT msg_src, DBB database, USHORT msg_src, DBB database,
const TEXT* relation_name) const TEXT* relation_name)
@ -635,13 +632,13 @@ static void show_blob_info(
* *
*****************************************************/ *****************************************************/
if (isNullBlob(blob_src)) { if (UserBlob::blobIsNull(blob_src)) {
ERRQ_msg_put(msg_blr); ERRQ_msg_put(msg_blr);
display_blr(database, blob_blr); display_blr(database, blob_blr);
} }
else { else {
ERRQ_msg_put(msg_src, relation_name); ERRQ_msg_put(msg_src, relation_name);
show_text_blob(database, "\t", 0, blob_src, 0, NULL, true); show_text_blob(database, "\t", 0, &blob_src, 0, NULL, true);
} }
} }
@ -650,7 +647,7 @@ static void show_blob_info(
static void show_blr( static void show_blr(
DBB database, DBB database,
USHORT source_msg, USHORT source_msg,
ISC_QUAD* source, USHORT blr_msg, ISC_QUAD* blr) ISC_QUAD& source, USHORT blr_msg, ISC_QUAD& blr)
{ {
/************************************** /**************************************
* *
@ -664,9 +661,9 @@ static void show_blr(
* *
**************************************/ **************************************/
if (!isNullBlob(source)) if (!UserBlob::blobIsNull(source))
show_text_blob(database, "\t", source_msg, source, 0, NULL, false); show_text_blob(database, "\t", source_msg, &source, 0, NULL, false);
else if (!isNullBlob(blr)) { else if (!UserBlob::blobIsNull(blr)) {
if (blr_msg) if (blr_msg)
ERRQ_msg_put(blr_msg); ERRQ_msg_put(blr_msg);
display_blr(database, blr); display_blr(database, blr);
@ -1011,10 +1008,10 @@ static int show_field_detail(
if (dimensions && !idx_node) if (dimensions && !idx_node)
array_dimensions(database, F.RDB$FIELD_NAME); array_dimensions(database, F.RDB$FIELD_NAME);
printf("\n"); printf("\n");
show_blr(database, 341, &F.RDB$COMPUTED_SOURCE, 341, show_blr(database, 341, F.RDB$COMPUTED_SOURCE, 341,
&F.RDB$COMPUTED_BLR); F.RDB$COMPUTED_BLR);
show_blr(database, 342, &F.RDB$VALIDATION_SOURCE, 342, show_blr(database, 342, F.RDB$VALIDATION_SOURCE, 342,
&F.RDB$VALIDATION_BLR); F.RDB$VALIDATION_BLR);
show_string(270, RFR.RDB$SECURITY_CLASS, 0, NULL); show_string(270, RFR.RDB$SECURITY_CLASS, 0, NULL);
show_string(271, RFR.RDB$QUERY_NAME, 271, F.RDB$QUERY_NAME); show_string(271, RFR.RDB$QUERY_NAME, 271, F.RDB$QUERY_NAME);
show_string(273, RFR.RDB$EDIT_STRING, 273, F.RDB$EDIT_STRING); show_string(273, RFR.RDB$EDIT_STRING, 273, F.RDB$EDIT_STRING);
@ -1609,10 +1606,10 @@ static int show_insecure_fields(
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH, F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH,
MET_dimensions(database, F.RDB$FIELD_NAME)); MET_dimensions(database, F.RDB$FIELD_NAME));
printf("\n"); printf("\n");
show_blr(database, 341, &F.RDB$COMPUTED_SOURCE, 341, show_blr(database, 341, F.RDB$COMPUTED_SOURCE, 341,
&F.RDB$COMPUTED_BLR); F.RDB$COMPUTED_BLR);
show_blr(database, 342, &F.RDB$VALIDATION_SOURCE, 342, show_blr(database, 342, F.RDB$VALIDATION_SOURCE, 342,
&F.RDB$VALIDATION_BLR); F.RDB$VALIDATION_BLR);
show_string(343, RFR.RDB$QUERY_NAME, 343, F.RDB$QUERY_NAME); show_string(343, RFR.RDB$QUERY_NAME, 343, F.RDB$QUERY_NAME);
show_string(346, RFR.RDB$EDIT_STRING, 346, F.RDB$EDIT_STRING); show_string(346, RFR.RDB$EDIT_STRING, 346, F.RDB$EDIT_STRING);
show_text_blob(database, "\t", 345, &RFR.RDB$QUERY_HEADER, 345, show_text_blob(database, "\t", 345, &RFR.RDB$QUERY_HEADER, 345,
@ -1735,10 +1732,10 @@ static int show_gbl_field_detail( DBB database, const TEXT* field_name)
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH, F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH,
MET_dimensions(database, F.RDB$FIELD_NAME)); MET_dimensions(database, F.RDB$FIELD_NAME));
printf("\n"); printf("\n");
show_blr(database, 279, &F.RDB$COMPUTED_SOURCE, 341, show_blr(database, 279, F.RDB$COMPUTED_SOURCE, 341,
&F.RDB$COMPUTED_BLR); F.RDB$COMPUTED_BLR);
show_blr(database, 280, &F.RDB$VALIDATION_SOURCE, 342, show_blr(database, 280, F.RDB$VALIDATION_SOURCE, 342,
&F.RDB$VALIDATION_BLR); F.RDB$VALIDATION_BLR);
show_string(281, F.RDB$QUERY_NAME, 0, NULL); show_string(281, F.RDB$QUERY_NAME, 0, NULL);
show_string(282, F.RDB$EDIT_STRING, 0, NULL); show_string(282, F.RDB$EDIT_STRING, 0, NULL);
show_text_blob(database, "\t", 283, &F.RDB$QUERY_HEADER, 0, NULL, false); show_text_blob(database, "\t", 283, &F.RDB$QUERY_HEADER, 0, NULL, false);
@ -1891,7 +1888,7 @@ static int show_indices_detail( qli_rel* relation)
else if (!X.RDB$EXPRESSION_BLR.NULL) else if (!X.RDB$EXPRESSION_BLR.NULL)
{ {
ERRQ_msg_put (485); ERRQ_msg_put (485);
display_blr(database, &X.RDB$EXPRESSION_BLR); display_blr(database, X.RDB$EXPRESSION_BLR);
} }
END_FOR; END_FOR;
@ -1921,7 +1918,7 @@ static int show_indices_detail( qli_rel* relation)
} }
static void show_matching(void) static void show_matching()
{ {
/************************************** /**************************************
* *
@ -1933,11 +1930,10 @@ static void show_matching(void)
* Just print the QLI matching language string. * Just print the QLI matching language string.
* *
**************************************/ **************************************/
buf_type buffer;
if (QLI_abort) if (QLI_abort)
return; return;
if (QLI_matching_language) { if (QLI_matching_language) {
buf_type buffer;
strncpy(buffer, (char*) QLI_matching_language->con_data, strncpy(buffer, (char*) QLI_matching_language->con_data,
QLI_matching_language->con_desc.dsc_length); QLI_matching_language->con_desc.dsc_length);
buffer[QLI_matching_language->con_desc.dsc_length] = 0; buffer[QLI_matching_language->con_desc.dsc_length] = 0;
@ -2213,7 +2209,7 @@ static USHORT show_security_class_detail( DBB database, const TEXT * name)
S IN RDB$SECURITY_CLASSES WITH S.RDB$SECURITY_CLASS = name S IN RDB$SECURITY_CLASSES WITH S.RDB$SECURITY_CLASS = name
if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) { if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) {
printf("\t%s:\n", S.RDB$SECURITY_CLASS); printf("\t%s:\n", S.RDB$SECURITY_CLASS);
display_acl(database, &S.RDB$ACL); display_acl(database, S.RDB$ACL);
} }
count++; count++;
END_FOR; END_FOR;
@ -2249,7 +2245,7 @@ static USHORT show_security_classes_detail( DBB database)
if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) { if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) {
printf("\t%s:\n", S.RDB$SECURITY_CLASS); printf("\t%s:\n", S.RDB$SECURITY_CLASS);
display_acl(database, &S.RDB$ACL); display_acl(database, S.RDB$ACL);
} }
count++; count++;
END_FOR; END_FOR;
@ -2317,9 +2313,9 @@ static void show_sys_trigs( DBB database)
// Msg379 System Triggers // Msg379 System Triggers
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE, show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
X.RDB$TRIGGER_SEQUENCE, X.RDB$TRIGGER_SEQUENCE,
X.RDB$TRIGGER_INACTIVE, &X.RDB$DESCRIPTION, X.RDB$TRIGGER_INACTIVE, X.RDB$DESCRIPTION,
database, X.RDB$RELATION_NAME); database, X.RDB$RELATION_NAME);
show_blob_info(&X.RDB$TRIGGER_BLR, &X.RDB$TRIGGER_SOURCE, show_blob_info(X.RDB$TRIGGER_BLR, X.RDB$TRIGGER_SOURCE,
377, // Msg377 Source for the trigger is not available. Trigger BLR: 377, // Msg377 Source for the trigger is not available. Trigger BLR:
376, // Msg376 Source for the trigger 376, // Msg376 Source for the trigger
database, X.RDB$RELATION_NAME); database, X.RDB$RELATION_NAME);
@ -2353,18 +2349,18 @@ static void show_text_blob(
* *
**************************************/ **************************************/
if (blob2 && isNullBlob(blob1)) { if (blob2 && UserBlob::blobIsNull(*blob1)) {
blob1 = blob2; blob1 = blob2;
msg1 = msg2; msg1 = msg2;
} }
if (isNullBlob(blob1)) if (UserBlob::blobIsNull(*blob1))
return; return;
if (msg1) if (msg1)
ERRQ_msg_put(msg1); ERRQ_msg_put(msg1);
display_text(database, blob1, column, strip); display_text(database, *blob1, column, strip);
} }
@ -2427,9 +2423,9 @@ static int show_trigger_detail( DBB database, const TEXT* relation_name)
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE, show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
X.RDB$TRIGGER_SEQUENCE, X.RDB$TRIGGER_SEQUENCE,
X.RDB$TRIGGER_INACTIVE, X.RDB$TRIGGER_INACTIVE,
&X.RDB$DESCRIPTION, database, X.RDB$DESCRIPTION, database,
relation_name); relation_name);
show_blob_info(&X.RDB$TRIGGER_BLR, &X.RDB$TRIGGER_SOURCE, show_blob_info(X.RDB$TRIGGER_BLR, X.RDB$TRIGGER_SOURCE,
377, // Msg377 Source for the trigger is not available. Trigger BLR: 377, // Msg377 Source for the trigger is not available. Trigger BLR:
376, // Msg376 Source for the trigger 376, // Msg376 Source for the trigger
database, relation_name); database, relation_name);
@ -2460,7 +2456,7 @@ static void show_trigger_header(
USHORT type, USHORT type,
USHORT sequence, USHORT sequence,
USHORT inactive, USHORT inactive,
ISC_QUAD* description, ISC_QUAD& description,
DBB database, DBB database,
const TEXT* relation_name) // unused param const TEXT* relation_name) // unused param
{ {
@ -2477,7 +2473,7 @@ static void show_trigger_header(
*****************************************************/ *****************************************************/
show_trigger_status(name, type, inactive, sequence); show_trigger_status(name, type, inactive, sequence);
show_text_blob(database, "\t ", 375, description, 0, NULL, true); show_text_blob(database, "\t ", 375, &description, 0, NULL, true);
} }
@ -2628,9 +2624,9 @@ static int show_triggers_detail( DBB database)
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE, show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
X.RDB$TRIGGER_SEQUENCE, X.RDB$TRIGGER_SEQUENCE,
X.RDB$TRIGGER_INACTIVE, X.RDB$TRIGGER_INACTIVE,
&X.RDB$DESCRIPTION, database, X.RDB$DESCRIPTION, database,
X.RDB$RELATION_NAME); X.RDB$RELATION_NAME);
show_blob_info(&X.RDB$TRIGGER_BLR, &X.RDB$TRIGGER_SOURCE, show_blob_info(X.RDB$TRIGGER_BLR, X.RDB$TRIGGER_SOURCE,
377, // Msg377 Source for the trigger is not available. Trigger BLR: 377, // Msg377 Source for the trigger is not available. Trigger BLR:
376, // Msg376 Source for the trigger 376, // Msg376 Source for the trigger
database, X.RDB$RELATION_NAME); database, X.RDB$RELATION_NAME);
@ -2765,7 +2761,7 @@ static void show_view( qli_rel* relation)
if (X.RDB$VIEW_SOURCE.NULL) { if (X.RDB$VIEW_SOURCE.NULL) {
ERRQ_msg_put(312, relation->rel_symbol->sym_string); ERRQ_msg_put(312, relation->rel_symbol->sym_string);
// Msg312 View source for relation %s is not available. View BLR: // Msg312 View source for relation %s is not available. View BLR:
display_blr(database, &X.RDB$VIEW_BLR); display_blr(database, X.RDB$VIEW_BLR);
} }
else { else {
ERRQ_msg_put(313, relation->rel_symbol->sym_string); ERRQ_msg_put(313, relation->rel_symbol->sym_string);