mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 19:23:03 +01:00
Inject UserBlob into QLI (not in all places).
This commit is contained in:
parent
c5ea420493
commit
345b422633
@ -24,8 +24,10 @@
|
||||
#include "UserBlob.h"
|
||||
#include "../jrd/ibase.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
|
||||
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)
|
||||
@ -236,3 +238,91 @@ bool UserBlob::getInfo(size_t items_size, const UCHAR* blr_items,
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
bool putData(size_t len, const void* buffer, size_t& real_len);
|
||||
bool isOpen() 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;
|
||||
static bool blobIsNull(const ISC_QUAD& blobid);
|
||||
private:
|
||||
@ -84,10 +85,22 @@ inline ISC_STATUS UserBlob::getCode() const
|
||||
return m_status[1];
|
||||
}
|
||||
|
||||
//inline FB_API_HANDLE& UserBlob::getHandle()
|
||||
//{
|
||||
// return m_blob;
|
||||
//}
|
||||
|
||||
inline bool UserBlob::blobIsNull(const ISC_QUAD& blobid)
|
||||
{
|
||||
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
|
||||
|
||||
|
@ -536,10 +536,5 @@ EXTERN qli_req* QLI_requests; // Requests in statement
|
||||
|
||||
#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
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "../qli/picst_proto.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/utl_proto.h"
|
||||
#include "../common/classes/UserBlob.h"
|
||||
|
||||
|
||||
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];
|
||||
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;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "../qli/repor_proto.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/utl_proto.h"
|
||||
#include "../common/classes/UserBlob.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
|
||||
@ -664,17 +665,15 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
|
||||
return false;
|
||||
}
|
||||
|
||||
// We've got a blob copy on our hands.
|
||||
// We've got a blob copy on our hands.
|
||||
|
||||
if (!from_desc) {
|
||||
*to_desc->dsc_address = 0;
|
||||
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* p = bpb;
|
||||
@ -690,23 +689,25 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
|
||||
const USHORT bpb_length = p - bpb;
|
||||
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
if (isc_create_blob(status_vector, &to_dbb->dbb_handle,
|
||||
&to_dbb->dbb_transaction, &to_blob,
|
||||
(ISC_QUAD*) to_desc->dsc_address))
|
||||
UserBlob to_blob(status_vector);
|
||||
UserBlob from_blob(status_vector);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (isc_open_blob2(status_vector, &from_dbb->dbb_handle,
|
||||
&from_dbb->dbb_transaction, &from_blob,
|
||||
(ISC_QUAD*) from_desc->dsc_address, bpb_length,
|
||||
if (!from_blob.open(from_dbb->dbb_handle, from_dbb->dbb_transaction,
|
||||
*(ISC_QUAD*) from_desc->dsc_address, bpb_length,
|
||||
bpb))
|
||||
{
|
||||
ERRQ_database_error(from_dbb, status_vector);
|
||||
}
|
||||
|
||||
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* buffer;
|
||||
@ -725,12 +726,10 @@ static bool copy_blob( qli_nod* value, qli_par* parameter)
|
||||
#endif
|
||||
}
|
||||
|
||||
USHORT length;
|
||||
while (!isc_get_segment(status_vector, &from_blob, &length, buffer_length,
|
||||
(char*) buffer))
|
||||
size_t length;
|
||||
while (from_blob.getSegment(buffer_length, buffer, length) && !from_blob.getCode())
|
||||
{
|
||||
if (isc_put_segment(status_vector, &to_blob, length,
|
||||
reinterpret_cast<const char*>(buffer)))
|
||||
if (!to_blob.putSegment(length, buffer))
|
||||
{
|
||||
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)
|
||||
gds__free(buffer);
|
||||
|
||||
if (isc_close_blob(status_vector, &from_blob))
|
||||
if (!from_blob.close())
|
||||
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);
|
||||
|
||||
return true;
|
||||
|
105
src/qli/meta.epp
105
src/qli/meta.epp
@ -42,6 +42,7 @@
|
||||
#include "../jrd/utl_proto.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/classes/UserBlob.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
|
||||
@ -55,7 +56,7 @@ DATABASE DB1 = FILENAME "yachts.lnk";
|
||||
|
||||
static void add_field(qli_rel*, qli_fld*, USHORT);
|
||||
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 bool check_global_field(DBB, qli_fld*, const TEXT*);
|
||||
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 int field_length(USHORT, USHORT);
|
||||
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 qli_syntax* make_node(NOD_T, USHORT);
|
||||
static TEXT *make_string(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_blob(ISC_QUAD*, qli_symbol*);
|
||||
static qli_syntax* parse_blr_blob(ISC_QUAD&, qli_symbol*);
|
||||
static void purge_relation(qli_rel*);
|
||||
static void put_dyn_string(qli_rlb*, const TEXT*);
|
||||
static void rollback_update(DBB);
|
||||
@ -801,13 +802,13 @@ void MET_fields( qli_rel* relation)
|
||||
}
|
||||
|
||||
ISC_QUAD* blob = & RFR.RDB$QUERY_HEADER;
|
||||
if (isNullBlob(blob))
|
||||
if (UserBlob::blobIsNull(*blob))
|
||||
blob = & RFL.RDB$QUERY_HEADER;
|
||||
if (!isNullBlob(blob))
|
||||
field->fld_query_header = get_query_header(database, blob);
|
||||
if (!UserBlob::blobIsNull(*blob))
|
||||
field->fld_query_header = get_query_header(database, *blob);
|
||||
|
||||
blob = & RFL.RDB$COMPUTED_BLR;
|
||||
if (!isNullBlob(blob))
|
||||
if (!UserBlob::blobIsNull(*blob))
|
||||
field->fld_flags |= FLD_computed;
|
||||
|
||||
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)
|
||||
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 =
|
||||
make_string(RFR.RDB$EDIT_STRING, sizeof(RFR.RDB$EDIT_STRING))))
|
||||
field->fld_edit_string =
|
||||
make_string(RFL.RDB$EDIT_STRING, sizeof(RFL.RDB$EDIT_STRING));
|
||||
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)
|
||||
field->fld_flags |= FLD_array;
|
||||
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 =
|
||||
(source->rel_database) ? source->rel_database : QLI_databases;
|
||||
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,
|
||||
&source_blob, source_blob_id))
|
||||
if (!source_blob.open(DB, source_dbb->dbb_meta_trans, source_blob_id))
|
||||
{
|
||||
rollback_update(source_dbb);
|
||||
ERRQ_database_error(source_dbb, status_vector);
|
||||
}
|
||||
|
||||
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* buffer;
|
||||
@ -1868,9 +1872,8 @@ static void blob_copy( qli_rlb* rlb, qli_rel* source, ISC_QUAD* source_blob_id)
|
||||
|
||||
STUFF_WORD((USHORT) size);
|
||||
|
||||
USHORT length;
|
||||
while (!isc_get_segment(status_vector, &source_blob, &length,
|
||||
buffer_length, buffer))
|
||||
size_t length;
|
||||
while (source_blob.getSegment(buffer_length, buffer, length) && !source_blob.getCode())
|
||||
{
|
||||
while (rlb->rlb_limit - rlb->rlb_data < length)
|
||||
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)
|
||||
gds__free(buffer);
|
||||
|
||||
if (isc_close_blob(status_vector, &source_blob)) {
|
||||
if (!source_blob.close()) {
|
||||
rollback_update(source_dbb);
|
||||
ERRQ_database_error(source_dbb, status_vector);
|
||||
}
|
||||
@ -2021,8 +2024,8 @@ static bool check_global_field(DBB database,
|
||||
}
|
||||
if (!field->fld_query_header)
|
||||
{
|
||||
ISC_QUAD* blob = &X.RDB$QUERY_HEADER;
|
||||
if (!isNullBlob(blob))
|
||||
ISC_QUAD& blob = X.RDB$QUERY_HEADER;
|
||||
if (!UserBlob::blobIsNull(blob))
|
||||
{
|
||||
field->fld_query_header =
|
||||
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) {
|
||||
STUFF(isc_dyn_fld_validation_blr);
|
||||
blob_copy(rlb, source, &F.RDB$VALIDATION_BLR);
|
||||
blob_copy(rlb, source, F.RDB$VALIDATION_BLR);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2177,17 +2180,17 @@ static void clone_fields( qli_rel* target, qli_rel* source)
|
||||
|
||||
if (!Y.RDB$QUERY_HEADER.NULL) {
|
||||
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) {
|
||||
STUFF(isc_dyn_description);
|
||||
blob_copy(rlb, source, &Y.RDB$DESCRIPTION);
|
||||
blob_copy(rlb, source, Y.RDB$DESCRIPTION);
|
||||
}
|
||||
|
||||
if (!Y.RDB$DEFAULT_VALUE.NULL) {
|
||||
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) &&
|
||||
@ -2211,9 +2214,9 @@ static void clone_fields( qli_rel* target, qli_rel* source)
|
||||
if (!F.RDB$COMPUTED_BLR.NULL)
|
||||
{
|
||||
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);
|
||||
blob_copy(rlb, source, &F.RDB$COMPUTED_SOURCE);
|
||||
blob_copy(rlb, source, F.RDB$COMPUTED_SOURCE);
|
||||
|
||||
STUFF(isc_dyn_fld_type);
|
||||
STUFF_WORD(2);
|
||||
@ -2391,32 +2394,32 @@ static void clone_global_fields( qli_rel* target, qli_rel* source)
|
||||
|
||||
if (!Y.RDB$MISSING_VALUE.NULL) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
STUFF(isc_dyn_description);
|
||||
blob_copy(rlb, source, &Y.RDB$DESCRIPTION);
|
||||
blob_copy(rlb, source, Y.RDB$DESCRIPTION);
|
||||
}
|
||||
|
||||
if (!Y.RDB$VALIDATION_BLR.NULL) {
|
||||
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) {
|
||||
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) &&
|
||||
@ -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;
|
||||
TEXT header[1024], buffer[1024];
|
||||
FB_API_HANDLE blob = 0;
|
||||
UserBlob blob(status_vector);
|
||||
|
||||
if (isc_open_blob(status_vector, &database->dbb_handle,
|
||||
&gds_trans, &blob, blob_id))
|
||||
if (!blob.open(database->dbb_handle, gds_trans, blob_id))
|
||||
{
|
||||
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"
|
||||
// might overflow "header" eventually.
|
||||
for (;;) {
|
||||
USHORT length;
|
||||
ISC_STATUS status = isc_get_segment(status_vector, &blob, &length,
|
||||
sizeof(buffer), buffer);
|
||||
if (status && status != isc_segment)
|
||||
size_t length;
|
||||
if (!blob.getSegment(sizeof(buffer), buffer, length))
|
||||
break;
|
||||
if (length && buffer[length - 1] == '\n')
|
||||
--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);
|
||||
|
||||
*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;
|
||||
|
||||
if (isNullBlob(blob_id))
|
||||
if (UserBlob::blobIsNull(blob_id))
|
||||
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;
|
||||
|
||||
UCHAR buffer[1024];
|
||||
UCHAR* ptr = buffer;
|
||||
|
||||
for (;;) {
|
||||
USHORT length = buffer + sizeof(buffer) - ptr;
|
||||
size_t length = buffer + sizeof(buffer) - ptr;
|
||||
if (!length)
|
||||
break;
|
||||
if (isc_get_segment(status_vector, &handle, &length, length,
|
||||
(char*) ptr))
|
||||
// The old code considered getting a portion of a segment a bug.
|
||||
// Anyway, 1024 is not much to contain the BLR stream, even for validation.
|
||||
if (!handle.getSegment(length, ptr, length) || handle.getCode())
|
||||
break;
|
||||
ptr += length;
|
||||
}
|
||||
|
||||
if (isc_close_blob(status_vector, &handle))
|
||||
if (!handle.close())
|
||||
return NULL;
|
||||
|
||||
if (ptr == buffer)
|
||||
@ -3467,8 +3468,10 @@ static void set_capabilities( DBB database)
|
||||
}
|
||||
|
||||
if (req)
|
||||
{
|
||||
if (isc_release_request(gds_status, &req))
|
||||
ERRQ_database_error(database, gds_status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,8 @@ void PRO_copy_procedure(
|
||||
|
||||
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* p = bpb;
|
||||
|
114
src/qli/show.epp
114
src/qli/show.epp
@ -39,19 +39,20 @@
|
||||
#include "../qli/show_proto.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/classes/UserBlob.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
|
||||
|
||||
static void array_dimensions(DBB, const TEXT*);
|
||||
static void display_acl(DBB, ISC_QUAD*);
|
||||
static void display_blob(DBB, ISC_QUAD*, const TEXT*, USHORT, const UCHAR*, bool);
|
||||
static void display_blr(DBB, ISC_QUAD*);
|
||||
static void display_text(DBB, ISC_QUAD*, const TEXT*, bool);
|
||||
static void display_acl(DBB, ISC_QUAD&);
|
||||
static void display_blob(DBB, ISC_QUAD&, const TEXT*, USHORT, const UCHAR*, bool);
|
||||
static void display_blr(DBB, ISC_QUAD&);
|
||||
static void display_text(DBB, ISC_QUAD&, const TEXT*, bool);
|
||||
static void display_procedure(DBB, const UCHAR*, FB_API_HANDLE);
|
||||
static USHORT get_window_size(int);
|
||||
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_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_datatype(DBB, USHORT, USHORT, SSHORT, SSHORT, USHORT,
|
||||
USHORT);
|
||||
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 int show_gbl_fields_detail(DBB);
|
||||
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_proc(QPR);
|
||||
static void show_procs(DBB);
|
||||
@ -90,7 +91,7 @@ static void show_text_blob(DBB, const TEXT*, USHORT, ISC_QUAD*, USHORT,
|
||||
ISC_QUAD*, bool);
|
||||
static void show_trig(qli_rel*);
|
||||
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*);
|
||||
static void show_trigger_messages(DBB, const TEXT*);
|
||||
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(
|
||||
DBB dbb,
|
||||
ISC_QUAD* blob_id,
|
||||
ISC_QUAD& blob_id,
|
||||
const TEXT* prefix,
|
||||
USHORT bpb_length,
|
||||
const UCHAR* bpb,
|
||||
@ -497,11 +498,9 @@ static void display_blob(
|
||||
**************************************/
|
||||
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,
|
||||
&blob, blob_id, bpb_length,
|
||||
bpb))
|
||||
if (!blob.open(dbb->dbb_handle, dbb->dbb_meta_trans, blob_id, bpb_length, bpb))
|
||||
{
|
||||
ERRQ_database_error(dbb, status_vector);
|
||||
}
|
||||
@ -509,10 +508,8 @@ static void display_blob(
|
||||
buf_type buffer;
|
||||
const USHORT buffer_length = sizeof(buffer) - 1;
|
||||
for (;;) {
|
||||
USHORT length;
|
||||
const ISC_STATUS status = isc_get_segment(status_vector, &blob,
|
||||
&length, buffer_length, buffer);
|
||||
if (status && status != isc_segment)
|
||||
size_t length;
|
||||
if (!blob.getSegment(buffer_length, buffer, length))
|
||||
break;
|
||||
buffer[length--] = 0;
|
||||
if (strip_line) {
|
||||
@ -531,11 +528,11 @@ static void display_blob(
|
||||
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(
|
||||
ISC_QUAD* blob_blr,
|
||||
ISC_QUAD* blob_src,
|
||||
ISC_QUAD& blob_blr,
|
||||
ISC_QUAD& blob_src,
|
||||
USHORT msg_blr,
|
||||
USHORT msg_src, DBB database,
|
||||
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);
|
||||
display_blr(database, blob_blr);
|
||||
}
|
||||
else {
|
||||
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(
|
||||
DBB database,
|
||||
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))
|
||||
show_text_blob(database, "\t", source_msg, source, 0, NULL, false);
|
||||
else if (!isNullBlob(blr)) {
|
||||
if (!UserBlob::blobIsNull(source))
|
||||
show_text_blob(database, "\t", source_msg, &source, 0, NULL, false);
|
||||
else if (!UserBlob::blobIsNull(blr)) {
|
||||
if (blr_msg)
|
||||
ERRQ_msg_put(blr_msg);
|
||||
display_blr(database, blr);
|
||||
@ -1011,10 +1008,10 @@ static int show_field_detail(
|
||||
if (dimensions && !idx_node)
|
||||
array_dimensions(database, F.RDB$FIELD_NAME);
|
||||
printf("\n");
|
||||
show_blr(database, 341, &F.RDB$COMPUTED_SOURCE, 341,
|
||||
&F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 342, &F.RDB$VALIDATION_SOURCE, 342,
|
||||
&F.RDB$VALIDATION_BLR);
|
||||
show_blr(database, 341, F.RDB$COMPUTED_SOURCE, 341,
|
||||
F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 342, F.RDB$VALIDATION_SOURCE, 342,
|
||||
F.RDB$VALIDATION_BLR);
|
||||
show_string(270, RFR.RDB$SECURITY_CLASS, 0, NULL);
|
||||
show_string(271, RFR.RDB$QUERY_NAME, 271, F.RDB$QUERY_NAME);
|
||||
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,
|
||||
MET_dimensions(database, F.RDB$FIELD_NAME));
|
||||
printf("\n");
|
||||
show_blr(database, 341, &F.RDB$COMPUTED_SOURCE, 341,
|
||||
&F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 342, &F.RDB$VALIDATION_SOURCE, 342,
|
||||
&F.RDB$VALIDATION_BLR);
|
||||
show_blr(database, 341, F.RDB$COMPUTED_SOURCE, 341,
|
||||
F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 342, F.RDB$VALIDATION_SOURCE, 342,
|
||||
F.RDB$VALIDATION_BLR);
|
||||
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_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,
|
||||
MET_dimensions(database, F.RDB$FIELD_NAME));
|
||||
printf("\n");
|
||||
show_blr(database, 279, &F.RDB$COMPUTED_SOURCE, 341,
|
||||
&F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 280, &F.RDB$VALIDATION_SOURCE, 342,
|
||||
&F.RDB$VALIDATION_BLR);
|
||||
show_blr(database, 279, F.RDB$COMPUTED_SOURCE, 341,
|
||||
F.RDB$COMPUTED_BLR);
|
||||
show_blr(database, 280, F.RDB$VALIDATION_SOURCE, 342,
|
||||
F.RDB$VALIDATION_BLR);
|
||||
show_string(281, F.RDB$QUERY_NAME, 0, NULL);
|
||||
show_string(282, F.RDB$EDIT_STRING, 0, NULL);
|
||||
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)
|
||||
{
|
||||
ERRQ_msg_put (485);
|
||||
display_blr(database, &X.RDB$EXPRESSION_BLR);
|
||||
display_blr(database, X.RDB$EXPRESSION_BLR);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
**************************************/
|
||||
buf_type buffer;
|
||||
|
||||
if (QLI_abort)
|
||||
return;
|
||||
if (QLI_matching_language) {
|
||||
buf_type buffer;
|
||||
strncpy(buffer, (char*) QLI_matching_language->con_data,
|
||||
QLI_matching_language->con_desc.dsc_length);
|
||||
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
|
||||
if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) {
|
||||
printf("\t%s:\n", S.RDB$SECURITY_CLASS);
|
||||
display_acl(database, &S.RDB$ACL);
|
||||
display_acl(database, S.RDB$ACL);
|
||||
}
|
||||
count++;
|
||||
END_FOR;
|
||||
@ -2249,7 +2245,7 @@ static USHORT show_security_classes_detail( DBB database)
|
||||
|
||||
if (fb_utils::exact_name(S.RDB$SECURITY_CLASS)[0]) {
|
||||
printf("\t%s:\n", S.RDB$SECURITY_CLASS);
|
||||
display_acl(database, &S.RDB$ACL);
|
||||
display_acl(database, S.RDB$ACL);
|
||||
}
|
||||
count++;
|
||||
END_FOR;
|
||||
@ -2317,9 +2313,9 @@ static void show_sys_trigs( DBB database)
|
||||
// Msg379 System Triggers
|
||||
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
|
||||
X.RDB$TRIGGER_SEQUENCE,
|
||||
X.RDB$TRIGGER_INACTIVE, &X.RDB$DESCRIPTION,
|
||||
X.RDB$TRIGGER_INACTIVE, X.RDB$DESCRIPTION,
|
||||
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:
|
||||
376, // Msg376 Source for the trigger
|
||||
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;
|
||||
msg1 = msg2;
|
||||
}
|
||||
|
||||
if (isNullBlob(blob1))
|
||||
if (UserBlob::blobIsNull(*blob1))
|
||||
return;
|
||||
|
||||
if (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,
|
||||
X.RDB$TRIGGER_SEQUENCE,
|
||||
X.RDB$TRIGGER_INACTIVE,
|
||||
&X.RDB$DESCRIPTION, database,
|
||||
X.RDB$DESCRIPTION, database,
|
||||
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:
|
||||
376, // Msg376 Source for the trigger
|
||||
database, relation_name);
|
||||
@ -2460,7 +2456,7 @@ static void show_trigger_header(
|
||||
USHORT type,
|
||||
USHORT sequence,
|
||||
USHORT inactive,
|
||||
ISC_QUAD* description,
|
||||
ISC_QUAD& description,
|
||||
DBB database,
|
||||
const TEXT* relation_name) // unused param
|
||||
{
|
||||
@ -2477,7 +2473,7 @@ static void show_trigger_header(
|
||||
*****************************************************/
|
||||
|
||||
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,
|
||||
X.RDB$TRIGGER_SEQUENCE,
|
||||
X.RDB$TRIGGER_INACTIVE,
|
||||
&X.RDB$DESCRIPTION, database,
|
||||
X.RDB$DESCRIPTION, 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:
|
||||
376, // Msg376 Source for the trigger
|
||||
database, X.RDB$RELATION_NAME);
|
||||
@ -2765,7 +2761,7 @@ static void show_view( qli_rel* relation)
|
||||
if (X.RDB$VIEW_SOURCE.NULL) {
|
||||
ERRQ_msg_put(312, relation->rel_symbol->sym_string);
|
||||
// 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 {
|
||||
ERRQ_msg_put(313, relation->rel_symbol->sym_string);
|
||||
|
Loading…
Reference in New Issue
Block a user