"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/blb.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

blb.cpp  (Firebird-3.0.2.32703-0.tar.bz2):blb.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 55 skipping to change at line 55
#include "../jrd/exe.h" #include "../jrd/exe.h"
#include "../jrd/req.h" #include "../jrd/req.h"
#include "../jrd/blb.h" #include "../jrd/blb.h"
#include "../jrd/ods.h" #include "../jrd/ods.h"
#include "../jrd/lls.h" #include "../jrd/lls.h"
#include "gen/iberror.h" #include "gen/iberror.h"
#include "../jrd/blob_filter.h" #include "../jrd/blob_filter.h"
#include "../common/sdl.h" #include "../common/sdl.h"
#include "../jrd/intl.h" #include "../jrd/intl.h"
#include "../jrd/cch.h" #include "../jrd/cch.h"
#include "../dsql/ExprNodes.h"
#include "../common/gdsassert.h" #include "../common/gdsassert.h"
#include "../jrd/blb_proto.h" #include "../jrd/blb_proto.h"
#include "../jrd/blf_proto.h" #include "../jrd/blf_proto.h"
#include "../jrd/cch_proto.h" #include "../jrd/cch_proto.h"
#include "../jrd/dpm_proto.h" #include "../jrd/dpm_proto.h"
#include "../jrd/err_proto.h" #include "../jrd/err_proto.h"
#include "../jrd/evl_proto.h" #include "../jrd/evl_proto.h"
#include "../jrd/filte_proto.h" #include "../jrd/filte_proto.h"
#include "../yvalve/gds_proto.h" #include "../yvalve/gds_proto.h"
#include "../jrd/intl_proto.h" #include "../jrd/intl_proto.h"
skipping to change at line 90 skipping to change at line 89
static ArrayField* alloc_array(jrd_tra*, Ods::InternalArrayDesc*); static ArrayField* alloc_array(jrd_tra*, Ods::InternalArrayDesc*);
//static blb* allocate_blob(thread_db*, jrd_tra*); //static blb* allocate_blob(thread_db*, jrd_tra*);
static ISC_STATUS blob_filter(USHORT, BlobControl*); static ISC_STATUS blob_filter(USHORT, BlobControl*);
//static blb* copy_blob(thread_db*, const bid*, bid*, USHORT, const UCHAR*, USHO RT); //static blb* copy_blob(thread_db*, const bid*, bid*, USHORT, const UCHAR*, USHO RT);
//static void delete_blob(thread_db*, blb*, ULONG); //static void delete_blob(thread_db*, blb*, ULONG);
//static void delete_blob_id(thread_db*, const bid*, ULONG, jrd_rel*); //static void delete_blob_id(thread_db*, const bid*, ULONG, jrd_rel*);
static ArrayField* find_array(jrd_tra*, const bid*); static ArrayField* find_array(jrd_tra*, const bid*);
static BlobFilter* find_filter(thread_db*, SSHORT, SSHORT); static BlobFilter* find_filter(thread_db*, SSHORT, SSHORT);
//static blob_page* get_next_page(thread_db*, blb*, WIN *); //static blob_page* get_next_page(thread_db*, blb*, WIN *);
//static void insert_page(thread_db*, blb*); //static void insert_page(thread_db*, blb*);
static void move_from_string(Jrd::thread_db*, const dsc*, dsc*, const ValueExprN ode*); static void move_from_string(Jrd::thread_db*, const dsc*, dsc*, const record_par am* rpb, USHORT fieldId);
static void move_to_string(Jrd::thread_db*, dsc*, dsc*); static void move_to_string(Jrd::thread_db*, dsc*, dsc*);
static void slice_callback(array_slice*, ULONG, dsc*); static void slice_callback(array_slice*, ULONG, dsc*);
static blb* store_array(thread_db*, jrd_tra*, bid*); static blb* store_array(thread_db*, jrd_tra*, bid*);
void blb::BLB_cancel(thread_db* tdbb) void blb::BLB_cancel(thread_db* tdbb)
{ {
/************************************** /**************************************
* *
* b l b : : c a n c e l * b l b : : c a n c e l
* *
skipping to change at line 936 skipping to change at line 935
blb_flags |= BLB_seek; blb_flags |= BLB_seek;
blb_flags &= ~BLB_eof; blb_flags &= ~BLB_eof;
return offset; return offset;
} }
// This function can't take from_desc as const because it may call store_array, // This function can't take from_desc as const because it may call store_array,
// which in turn calls blb::create2 that writes in the blob id. Although the // which in turn calls blb::create2 that writes in the blob id. Although the
// compiler allows to modify from_desc->dsc_address' contents when from_desc is // compiler allows to modify from_desc->dsc_address' contents when from_desc is
// constant, this is misleading so I didn't make the source descriptor constant. // constant, this is misleading so I didn't make the source descriptor constant.
void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod e* field) void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param * rpb, USHORT fieldId)
{ {
/************************************** /**************************************
* *
* b l b : : m o v e * b l b : : m o v e
* *
************************************** **************************************
* *
* Functional description * Functional description
* Perform an assignment to a blob field or a blob descriptor. * Perform an assignment to a blob field or a blob descriptor.
* When assigning to a field, unless the blob is null, * When assigning to a field, unless the blob is null,
skipping to change at line 967 skipping to change at line 966
if (from_desc->dsc_dtype != dtype_array && from_desc->dsc_dtype ! = dtype_quad) if (from_desc->dsc_dtype != dtype_array && from_desc->dsc_dtype ! = dtype_quad)
{ {
ERR_post(Arg::Gds(isc_array_convert_error)); ERR_post(Arg::Gds(isc_array_convert_error));
} }
} }
else if (DTYPE_IS_BLOB_OR_QUAD(to_desc->dsc_dtype)) else if (DTYPE_IS_BLOB_OR_QUAD(to_desc->dsc_dtype))
{ {
if (!DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype)) if (!DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype))
{ {
// anything that can be copied into a string can be copie d into a blob // anything that can be copied into a string can be copie d into a blob
move_from_string(tdbb, from_desc, to_desc, field); move_from_string(tdbb, from_desc, to_desc, rpb, fieldId);
return; return;
} }
} }
else if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype)) else if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype))
{ {
move_to_string(tdbb, from_desc, to_desc); move_to_string(tdbb, from_desc, to_desc);
return; return;
} }
else else
fb_assert(false); fb_assert(false);
bool simpleMove = true;
// If the target node is a field, we need more work to do. // If the target node is a field, we need more work to do.
const FieldNode* fieldNode = NULL; // We should not materialize the blob if the destination field
// stream (nod_union, for example) doesn't have a relation.
if (field) const bool simpleMove = !rpb || (rpb->rpb_relation == NULL);
{
if ((fieldNode = ExprNode::as<FieldNode>(field)))
{
// We should not materialize the blob if the destination
field
// stream (nod_union, for example) doesn't have a relatio
n.
simpleMove = tdbb->getRequest()->req_rpb[fieldNode->field
Stream].rpb_relation == NULL;
}
else if (!(ExprNode::is<ParameterNode>(field) || ExprNode::is<Var
iableNode>(field)))
BUGCHECK(199); // msg 199 expected field node
}
// Use local copy of source blob id to not change contents of from_desc i n // Use local copy of source blob id to not change contents of from_desc i n
// a case when it points to materialized temporary blob (see below for // a case when it points to materialized temporary blob (see below for
// assignment to *source). // assignment to *source).
bid srcBlobID = *(bid*)from_desc->dsc_address; bid srcBlobID = *(bid*)from_desc->dsc_address;
bid* source = &srcBlobID; bid* source = &srcBlobID;
bid* destination = (bid*) to_desc->dsc_address; bid* destination = (bid*) to_desc->dsc_address;
// If nothing changed, do nothing. If it isn't broken, don't fix it. // If nothing changed, do nothing. If it isn't broken, don't fix it.
if (*source == *destination) if (*source == *destination)
skipping to change at line 1051 skipping to change at line 1038
copy_blob(tdbb, source, destination, bpb.getCount(), bpb. begin(), pageSpace); copy_blob(tdbb, source, destination, bpb.getCount(), bpb. begin(), pageSpace);
} }
else else
*destination = *source; *destination = *source;
return; return;
} }
jrd_req* request = tdbb->getRequest(); jrd_req* request = tdbb->getRequest();
const USHORT id = fieldNode->fieldId;
record_param* rpb = &request->req_rpb[fieldNode->fieldStream];
jrd_rel* relation = rpb->rpb_relation; jrd_rel* relation = rpb->rpb_relation;
if (relation->isVirtual()) { if (relation->isVirtual()) {
ERR_post(Arg::Gds(isc_read_only)); ERR_post(Arg::Gds(isc_read_only));
} }
RelationPages* relPages = relation->getPages(tdbb); RelationPages* relPages = relation->getPages(tdbb);
Record* record = rpb->rpb_record; Record* record = rpb->rpb_record;
// If either the source value is null or the blob id itself is null // If either the source value is null or the blob id itself is null
// (all zeros), then the blob is null. // (all zeros), then the blob is null.
if ((request->req_flags & req_null) || source->isEmpty()) if ((request->req_flags & req_null) || source->isEmpty())
{ {
record->setNull(id); record->setNull(fieldId);
destination->clear(); destination->clear();
return; return;
} }
record->clearNull(id); record->clearNull(fieldId);
jrd_tra* transaction = request->req_transaction; jrd_tra* transaction = request->req_transaction;
transaction = transaction->getOuter(); transaction = transaction->getOuter();
// If the target is a view, this must be from a view update trigger. // If the target is a view, this must be from a view update trigger.
// Just pass the blob id thru. // Just pass the blob id thru.
if (relation->rel_view_rse) if (relation->rel_view_rse)
{ {
// But if the sub_type or charset is different, create a new blob . // But if the sub_type or charset is different, create a new blob .
if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype) && if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype) &&
skipping to change at line 2474 skipping to change at line 2459
CCH_precedence(tdbb, &window, page_number); CCH_precedence(tdbb, &window, page_number);
CCH_MARK(tdbb, &window); CCH_MARK(tdbb, &window);
l = blb_sequence % blb_pointers; l = blb_sequence % blb_pointers;
page->blp_page[l] = page_number.getPageNum(); page->blp_page[l] = page_number.getPageNum();
page->blp_length = (l + 1) << SHIFTLONG; page->blp_length = (l + 1) << SHIFTLONG;
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
} }
static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc , static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc ,
const ValueExprNode* field) const record_param* rpb, USHORT fieldId)
{ {
/************************************** /**************************************
* *
* m o v e _ f r o m _ s t r i n g * m o v e _ f r o m _ s t r i n g
* *
************************************** **************************************
* *
* Functional description * Functional description
* Perform an assignment to a blob field. It's capable of handling * Perform an assignment to a blob field. It's capable of handling
* strings (and anything that could be converted to strings) by * strings (and anything that could be converted to strings) by
skipping to change at line 2528 skipping to change at line 2513
blob_desc.dsc_scale = to_desc->dsc_scale; // blob charset blob_desc.dsc_scale = to_desc->dsc_scale; // blob charset
blob_desc.dsc_flags = (blob_desc.dsc_flags & 0xFF) | (to_desc->dsc_flags & 0xFF00); // blob collation blob_desc.dsc_flags = (blob_desc.dsc_flags & 0xFF) | (to_desc->dsc_flags & 0xFF00); // blob collation
blob_desc.dsc_sub_type = to_desc->dsc_sub_type; blob_desc.dsc_sub_type = to_desc->dsc_sub_type;
blob_desc.dsc_dtype = dtype_blob; blob_desc.dsc_dtype = dtype_blob;
blob_desc.dsc_length = sizeof(ISC_QUAD); blob_desc.dsc_length = sizeof(ISC_QUAD);
blob_desc.dsc_address = reinterpret_cast<UCHAR*>(&temp_bid); blob_desc.dsc_address = reinterpret_cast<UCHAR*>(&temp_bid);
blob->BLB_put_segment(tdbb, fromstr, length); blob->BLB_put_segment(tdbb, fromstr, length);
blob->BLB_close(tdbb); blob->BLB_close(tdbb);
ULONG blob_temp_id = blob->getTempId(); ULONG blob_temp_id = blob->getTempId();
blb::move(tdbb, &blob_desc, to_desc, field); blb::move(tdbb, &blob_desc, to_desc, rpb, fieldId);
// 14-June-2004. Nickolay Samofatov // 14-June-2004. Nickolay Samofatov
// The code below saves a lot of memory when bunches of records are // The code below saves a lot of memory when bunches of records are
// converted to blobs from strings. If blb::move is materialized blob we // converted to blobs from strings. If blb::move is materialized blob we
// can discard it without consequences since we know there are no other // can discard it without consequences since we know there are no other
// descriptors using temporary ID of blob we just created. If blob is // descriptors using temporary ID of blob we just created. If blob is
// still temporary we cannot free it as it may now be used inside // still temporary we cannot free it as it may now be used inside
// trigger for updatable view. In theory we could make this decision // trigger for updatable view. In theory we could make this decision
// solely via checking that destination field belongs to updatable // solely via checking that destination field belongs to updatable
// view, but direct check that blob is fully materialized should be // view, but direct check that blob is fully materialized should be
 End of changes. 11 change blocks. 
29 lines changed or deleted 10 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)