mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
Refactor.
This commit is contained in:
parent
3442e1e5f2
commit
871c073279
@ -51,6 +51,11 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned getLength() const
|
||||
{
|
||||
return (unsigned) (end - start);
|
||||
}
|
||||
|
||||
const UCHAR* getPos() const
|
||||
{
|
||||
fb_assert(pos);
|
||||
|
@ -1295,7 +1295,7 @@ DmlNode* DeclareSubFuncNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerSc
|
||||
node->blrLength = reader.getLong();
|
||||
node->blrStart = reader.getPos();
|
||||
|
||||
MET_par_messages(tdbb, reader.getPos(), node->blrLength, subFunc, subCsb);
|
||||
subFunc->parseMessages(tdbb, subCsb, BlrReader(reader.getPos(), node->blrLength));
|
||||
|
||||
USHORT count = subFunc->getInputFormat() ? subFunc->getInputFormat()->fmt_count : 0;
|
||||
if (subFunc->getInputFields().getCount() * 2 != count)
|
||||
@ -1545,7 +1545,7 @@ DmlNode* DeclareSubProcNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerSc
|
||||
node->blrLength = reader.getLong();
|
||||
node->blrStart = reader.getPos();
|
||||
|
||||
MET_par_messages(tdbb, reader.getPos(), node->blrLength, subProc, subCsb);
|
||||
subProc->parseMessages(tdbb, subCsb, BlrReader(reader.getPos(), node->blrLength));
|
||||
|
||||
USHORT count = subProc->getInputFormat() ? subProc->getInputFormat()->fmt_count : 0;
|
||||
if (subProc->getInputFields().getCount() * 2 != count)
|
||||
|
@ -408,7 +408,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
|
||||
try
|
||||
{
|
||||
MET_parse_routine_blr(tdbb, function, &X.RDB$FUNCTION_BLR, csb);
|
||||
function->parseBlr(tdbb, csb, &X.RDB$FUNCTION_BLR);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
|
@ -1,29 +1,30 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Adriano dos Santos Fernandes
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* Copyright (c) 2013 Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
* and all contributors signed below.
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Adriano dos Santos Fernandes
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../jrd/Routine.h"
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/exe.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../jrd/par_proto.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -97,5 +98,107 @@ Format* Routine::createFormat(MemoryPool& pool, IMessageMetadata* params, bool a
|
||||
return format;
|
||||
}
|
||||
|
||||
// Parse routine BLR.
|
||||
void Routine::parseBlr(thread_db* tdbb, CompilerScratch* csb, bid* blob_id)
|
||||
{
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
UCharBuffer tmp;
|
||||
|
||||
if (blob_id)
|
||||
{
|
||||
blb* blob = blb::open(tdbb, attachment->getSysTransaction(), blob_id);
|
||||
ULONG length = blob->blb_length + 10;
|
||||
UCHAR* temp = tmp.getBuffer(length);
|
||||
length = blob->BLB_get_data(tdbb, temp, length);
|
||||
tmp.resize(length);
|
||||
}
|
||||
|
||||
parseMessages(tdbb, csb, BlrReader(tmp.begin(), (unsigned) tmp.getCount()));
|
||||
|
||||
JrdStatement* statement = getStatement();
|
||||
PAR_blr(tdbb, NULL, tmp.begin(), (ULONG) tmp.getCount(), NULL, &csb, &statement, false, 0);
|
||||
setStatement(statement);
|
||||
|
||||
if (!blob_id)
|
||||
setImplemented(false);
|
||||
}
|
||||
|
||||
// Parse the messages of a blr request. For specified message, allocate a format (Format) block.
|
||||
void Routine::parseMessages(thread_db* tdbb, CompilerScratch* csb, BlrReader blrReader)
|
||||
{
|
||||
if (blrReader.getLength() < 2)
|
||||
status_exception::raise(Arg::Gds(isc_metadata_corrupt));
|
||||
|
||||
csb->csb_blr_reader = blrReader;
|
||||
|
||||
const SSHORT version = csb->csb_blr_reader.getByte();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case blr_version4:
|
||||
case blr_version5:
|
||||
//case blr_version6:
|
||||
break;
|
||||
|
||||
default:
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_metadata_corrupt) <<
|
||||
Arg::Gds(isc_wroblrver2) << Arg::Num(blr_version4) << Arg::Num(blr_version5/*6*/) <<
|
||||
Arg::Num(version));
|
||||
}
|
||||
|
||||
if (csb->csb_blr_reader.getByte() != blr_begin)
|
||||
status_exception::raise(Arg::Gds(isc_metadata_corrupt));
|
||||
|
||||
while (csb->csb_blr_reader.getByte() == blr_message)
|
||||
{
|
||||
const USHORT msgNumber = csb->csb_blr_reader.getByte();
|
||||
USHORT count = csb->csb_blr_reader.getWord();
|
||||
Format* format = Format::newFormat(*tdbb->getDefaultPool(), count);
|
||||
|
||||
USHORT padField;
|
||||
const bool shouldPad = csb->csb_message_pad.get(msgNumber, padField);
|
||||
|
||||
USHORT maxAlignment = 0;
|
||||
ULONG offset = 0;
|
||||
USHORT i = 0;
|
||||
|
||||
for (Format::fmt_desc_iterator desc = format->fmt_desc.begin(); i < count; ++i, ++desc)
|
||||
{
|
||||
const USHORT align = PAR_desc(tdbb, csb, &*desc);
|
||||
if (align)
|
||||
offset = FB_ALIGN(offset, align);
|
||||
|
||||
desc->dsc_address = (UCHAR*)(IPTR) offset;
|
||||
offset += desc->dsc_length;
|
||||
|
||||
maxAlignment = MAX(maxAlignment, align);
|
||||
|
||||
if (maxAlignment && shouldPad && i + 1 == padField)
|
||||
offset = FB_ALIGN(offset, maxAlignment);
|
||||
}
|
||||
|
||||
if (offset > MAX_MESSAGE_SIZE)
|
||||
status_exception::raise(Arg::Gds(isc_imp_exc) << Arg::Gds(isc_blktoobig));
|
||||
|
||||
format->fmt_length = offset;
|
||||
|
||||
switch (msgNumber)
|
||||
{
|
||||
case 0:
|
||||
setInputFormat(format);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
setOutputFormat(format);
|
||||
break;
|
||||
|
||||
default:
|
||||
delete format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Jrd
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/BlrReader.h"
|
||||
#include "../common/classes/MetaName.h"
|
||||
#include "../common/classes/QualifiedName.h"
|
||||
#include "../common/classes/NestConst.h"
|
||||
@ -30,6 +31,8 @@
|
||||
|
||||
namespace Jrd
|
||||
{
|
||||
class thread_db;
|
||||
class CompilerScratch;
|
||||
class JrdStatement;
|
||||
class Format;
|
||||
class Parameter;
|
||||
@ -106,6 +109,9 @@ namespace Jrd
|
||||
const Firebird::Array<NestConst<Parameter> >& getOutputFields() const { return outputFields; }
|
||||
Firebird::Array<NestConst<Parameter> >& getOutputFields() { return outputFields; }
|
||||
|
||||
void parseBlr(thread_db* tdbb, CompilerScratch* csb, bid* blob_id);
|
||||
void parseMessages(thread_db* tdbb, CompilerScratch* csb, Firebird::BlrReader blrReader);
|
||||
|
||||
public:
|
||||
virtual int getObjectType() const = 0;
|
||||
virtual SLONG getSclType() const = 0;
|
||||
|
@ -5595,7 +5595,7 @@ static bool modify_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
|
||||
try
|
||||
{
|
||||
MET_parse_routine_blr(tdbb, function, &FUN.RDB$FUNCTION_BLR, csb);
|
||||
function->parseBlr(tdbb, csb, &FUN.RDB$FUNCTION_BLR);
|
||||
valid_blr = true;
|
||||
}
|
||||
catch (const Firebird::Exception&)
|
||||
|
107
src/jrd/met.epp
107
src/jrd/met.epp
@ -3074,8 +3074,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
|
||||
try
|
||||
{
|
||||
MET_parse_routine_blr(tdbb, procedure,
|
||||
(P.RDB$PROCEDURE_BLR.NULL ? NULL : &P.RDB$PROCEDURE_BLR), csb);
|
||||
procedure->parseBlr(tdbb, csb, &P.RDB$PROCEDURE_BLR);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
@ -4343,110 +4342,6 @@ static void parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const Meta
|
||||
}
|
||||
|
||||
|
||||
// Parse routine BLR.
|
||||
void MET_parse_routine_blr(thread_db* tdbb, Routine* routine, bid* blob_id, CompilerScratch* csb)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
UCharBuffer tmp;
|
||||
|
||||
if (blob_id)
|
||||
{
|
||||
blb* blob = blb::open(tdbb, attachment->getSysTransaction(), blob_id);
|
||||
ULONG length = blob->blb_length + 10;
|
||||
UCHAR* temp = tmp.getBuffer(length);
|
||||
length = blob->BLB_get_data(tdbb, temp, length);
|
||||
tmp.resize(length);
|
||||
}
|
||||
|
||||
MET_par_messages(tdbb, tmp.begin(), (ULONG) tmp.getCount(), routine, csb);
|
||||
|
||||
JrdStatement* statement = routine->getStatement();
|
||||
PAR_blr(tdbb, NULL, tmp.begin(), (ULONG) tmp.getCount(), NULL, &csb, &statement, false, 0);
|
||||
routine->setStatement(statement);
|
||||
|
||||
if (!blob_id)
|
||||
routine->setImplemented(false);
|
||||
}
|
||||
|
||||
|
||||
// Parse the messages of a blr request. For specified message, allocate a format (Format) block.
|
||||
void MET_par_messages(thread_db* tdbb, const UCHAR* const blr, ULONG blrLength,
|
||||
Routine* routine, CompilerScratch* csb)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
if (blrLength < 2)
|
||||
ERR_post(Arg::Gds(isc_metadata_corrupt));
|
||||
blrLength -= 2;
|
||||
|
||||
csb->csb_blr_reader = BlrReader(blr, blrLength);
|
||||
|
||||
const SSHORT version = csb->csb_blr_reader.getByte();
|
||||
switch (version)
|
||||
{
|
||||
case blr_version4:
|
||||
case blr_version5:
|
||||
//case blr_version6:
|
||||
break;
|
||||
default:
|
||||
ERR_post(Arg::Gds(isc_metadata_corrupt) <<
|
||||
Arg::Gds(isc_wroblrver2) << Arg::Num(blr_version4) << Arg::Num(blr_version5/*6*/) <<
|
||||
Arg::Num(version));
|
||||
}
|
||||
|
||||
if (csb->csb_blr_reader.getByte() != blr_begin)
|
||||
ERR_post(Arg::Gds(isc_metadata_corrupt));
|
||||
|
||||
while (csb->csb_blr_reader.getByte() == blr_message)
|
||||
{
|
||||
const USHORT msgNumber = csb->csb_blr_reader.getByte();
|
||||
USHORT count = csb->csb_blr_reader.getWord();
|
||||
Format* format = Format::newFormat(*tdbb->getDefaultPool(), count);
|
||||
|
||||
USHORT padField;
|
||||
const bool shouldPad = csb->csb_message_pad.get(msgNumber, padField);
|
||||
|
||||
USHORT maxAlignment = 0;
|
||||
ULONG offset = 0;
|
||||
USHORT i = 0;
|
||||
|
||||
for (Format::fmt_desc_iterator desc = format->fmt_desc.begin(); i < count; ++i, ++desc)
|
||||
{
|
||||
const USHORT align = PAR_desc(tdbb, csb, &*desc);
|
||||
if (align)
|
||||
offset = FB_ALIGN(offset, align);
|
||||
|
||||
desc->dsc_address = (UCHAR*)(IPTR) offset;
|
||||
offset += desc->dsc_length;
|
||||
|
||||
maxAlignment = MAX(maxAlignment, align);
|
||||
|
||||
if (maxAlignment && shouldPad && i + 1 == padField)
|
||||
offset = FB_ALIGN(offset, maxAlignment);
|
||||
}
|
||||
|
||||
if (offset > MAX_MESSAGE_SIZE)
|
||||
ERR_post(Arg::Gds(isc_imp_exc) << Arg::Gds(isc_blktoobig));
|
||||
|
||||
format->fmt_length = offset;
|
||||
|
||||
switch (msgNumber)
|
||||
{
|
||||
case 0:
|
||||
routine->setInputFormat(format);
|
||||
break;
|
||||
case 1:
|
||||
routine->setOutputFormat(format);
|
||||
break;
|
||||
default:
|
||||
delete format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MET_release_trigger(thread_db* tdbb, trig_vec** vector_ptr, const MetaName& name)
|
||||
{
|
||||
/***********************************************
|
||||
|
@ -101,11 +101,8 @@ Jrd::jrd_prc* MET_lookup_procedure(Jrd::thread_db*, const Firebird::QualifiedNam
|
||||
Jrd::jrd_prc* MET_lookup_procedure_id(Jrd::thread_db*, SSHORT, bool, bool, USHORT);
|
||||
Jrd::jrd_rel* MET_lookup_relation(Jrd::thread_db*, const Firebird::MetaName&);
|
||||
Jrd::jrd_rel* MET_lookup_relation_id(Jrd::thread_db*, SLONG, bool);
|
||||
void MET_par_messages(Jrd::thread_db*, const UCHAR* const, ULONG,
|
||||
Jrd::Routine* routine, Jrd::CompilerScratch*);
|
||||
Jrd::DmlNode* MET_parse_blob(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::bid*, Jrd::CompilerScratch**,
|
||||
Jrd::JrdStatement**, bool, bool);
|
||||
void MET_parse_routine_blr(Jrd::thread_db*, Jrd::Routine*, Jrd::bid*, Jrd::CompilerScratch*);
|
||||
void MET_parse_sys_trigger(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_post_existence(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_prepare(Jrd::thread_db*, Jrd::jrd_tra*, USHORT, const UCHAR*);
|
||||
|
Loading…
Reference in New Issue
Block a user