mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 00:03:03 +01:00
Backported fix for CORE-5428: Rare segfault when preparing request working with a table with triggers
This commit is contained in:
parent
1d27cdbabd
commit
0ca6c0dc2f
@ -87,12 +87,12 @@ static void makeValidation(thread_db* tdbb, CompilerScratch* csb, StreamType str
|
||||
static StmtNode* pass1ExpandView(thread_db* tdbb, CompilerScratch* csb, StreamType orgStream,
|
||||
StreamType newStream, bool remap);
|
||||
static RelationSourceNode* pass1Update(thread_db* tdbb, CompilerScratch* csb, jrd_rel* relation,
|
||||
const trig_vec* trigger, StreamType stream, StreamType updateStream, SecurityClass::flags_t priv,
|
||||
const TrigVector* trigger, StreamType stream, StreamType updateStream, SecurityClass::flags_t priv,
|
||||
jrd_rel* view, StreamType viewStream, StreamType viewUpdateStream);
|
||||
static void pass1Validations(thread_db* tdbb, CompilerScratch* csb, Array<ValidateInfo>& validations);
|
||||
static void postTriggerAccess(CompilerScratch* csb, jrd_rel* ownerRelation,
|
||||
ExternalAccess::exa_act operation, jrd_rel* view);
|
||||
static void preModifyEraseTriggers(thread_db* tdbb, trig_vec** trigs,
|
||||
static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs,
|
||||
StmtNode::WhichTrigger whichTrig, record_param* rpb, record_param* rec, TriggerAction op);
|
||||
static void validateExpressions(thread_db* tdbb, const Array<ValidateInfo>& validations);
|
||||
|
||||
@ -2224,8 +2224,8 @@ void EraseNode::pass1Erase(thread_db* tdbb, CompilerScratch* csb, EraseNode* nod
|
||||
if (parent)
|
||||
priv |= SCL_select;
|
||||
|
||||
const trig_vec* trigger = relation->rel_pre_erase ?
|
||||
relation->rel_pre_erase : relation->rel_post_erase;
|
||||
RefPtr<const TrigVector> trigger(relation->rel_pre_erase ?
|
||||
relation->rel_pre_erase : relation->rel_post_erase);
|
||||
|
||||
// If we have a view with triggers, let's expand it.
|
||||
|
||||
@ -5928,8 +5928,8 @@ void ModifyNode::pass1Modify(thread_db* tdbb, CompilerScratch* csb, ModifyNode*
|
||||
if (parent)
|
||||
priv |= SCL_select;
|
||||
|
||||
const trig_vec* trigger = (relation->rel_pre_modify) ?
|
||||
relation->rel_pre_modify : relation->rel_post_modify;
|
||||
RefPtr<const TrigVector> trigger(relation->rel_pre_modify ?
|
||||
relation->rel_pre_modify : relation->rel_post_modify);
|
||||
|
||||
// If we have a view with triggers, let's expand it.
|
||||
|
||||
@ -6693,8 +6693,8 @@ bool StoreNode::pass1Store(thread_db* tdbb, CompilerScratch* csb, StoreNode* nod
|
||||
|
||||
postTriggerAccess(csb, relation, ExternalAccess::exa_insert, view);
|
||||
|
||||
const trig_vec* trigger = relation->rel_pre_store ?
|
||||
relation->rel_pre_store : relation->rel_post_store;
|
||||
RefPtr<const TrigVector> trigger(relation->rel_pre_store ?
|
||||
relation->rel_pre_store : relation->rel_post_store);
|
||||
|
||||
// Check out insert. If this is an insert thru a view, verify the view by checking for read
|
||||
// access on the base table. If field-level select privileges are implemented, this needs
|
||||
@ -9092,7 +9092,7 @@ static StmtNode* pass1ExpandView(thread_db* tdbb, CompilerScratch* csb, StreamTy
|
||||
// If it's a view update, make sure the view is updatable, and return the view source for redirection.
|
||||
// If it's a simple relation, return NULL.
|
||||
static RelationSourceNode* pass1Update(thread_db* tdbb, CompilerScratch* csb, jrd_rel* relation,
|
||||
const trig_vec* trigger, StreamType stream, StreamType updateStream, SecurityClass::flags_t priv,
|
||||
const TrigVector* trigger, StreamType stream, StreamType updateStream, SecurityClass::flags_t priv,
|
||||
jrd_rel* view, StreamType viewStream, StreamType viewUpdateStream)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
@ -9219,7 +9219,7 @@ static void postTriggerAccess(CompilerScratch* csb, jrd_rel* ownerRelation,
|
||||
}
|
||||
|
||||
// Perform operation's pre-triggers, storing active rpb in chain.
|
||||
static void preModifyEraseTriggers(thread_db* tdbb, trig_vec** trigs,
|
||||
static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs,
|
||||
StmtNode::WhichTrigger whichTrig, record_param* rpb, record_param* rec, TriggerAction op)
|
||||
{
|
||||
if (!tdbb->getTransaction()->tra_rpblist)
|
||||
|
@ -758,3 +758,4 @@ JAttachment* Attachment::getInterface() throw()
|
||||
{
|
||||
return att_stable->getInterface();
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace Jrd
|
||||
class jrd_rel;
|
||||
class jrd_prc;
|
||||
class Trigger;
|
||||
typedef Firebird::ObjectsArray<Trigger> trig_vec;
|
||||
class TrigVector;
|
||||
class Function;
|
||||
class JrdStatement;
|
||||
class Validation;
|
||||
@ -292,8 +292,8 @@ public:
|
||||
|
||||
vec<jrd_rel*>* att_relations; // relation vector
|
||||
Firebird::Array<jrd_prc*> att_procedures; // scanned procedures
|
||||
trig_vec* att_triggers[DB_TRIGGER_MAX];
|
||||
trig_vec* att_ddl_triggers;
|
||||
TrigVector* att_triggers[DB_TRIGGER_MAX];
|
||||
TrigVector* att_ddl_triggers;
|
||||
Firebird::Array<Function*> att_functions; // User defined functions
|
||||
|
||||
Firebird::Array<JrdStatement*> att_internal; // internal statements
|
||||
@ -556,7 +556,6 @@ private:
|
||||
void destroy(Attachment* attachment);
|
||||
};
|
||||
|
||||
|
||||
} // namespace Jrd
|
||||
|
||||
#endif // JRD_ATTACHMENT_H
|
||||
|
@ -588,7 +588,7 @@ void JrdStatement::release(thread_db* tdbb)
|
||||
|
||||
// Check that we have enough rights to access all resources this list of triggers touches.
|
||||
void JrdStatement::verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation,
|
||||
trig_vec* triggers, jrd_rel* view)
|
||||
TrigVector* triggers, jrd_rel* view)
|
||||
{
|
||||
if (!triggers)
|
||||
return;
|
||||
@ -640,7 +640,7 @@ void JrdStatement::verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation,
|
||||
|
||||
// Invoke buildExternalAccess for triggers in vector
|
||||
inline void JrdStatement::triggersExternalAccess(thread_db* tdbb, ExternalAccessList& list,
|
||||
trig_vec* tvec)
|
||||
TrigVector* tvec)
|
||||
{
|
||||
if (!tvec)
|
||||
return;
|
||||
@ -687,7 +687,7 @@ void JrdStatement::buildExternalAccess(thread_db* tdbb, ExternalAccessList& list
|
||||
if (!relation)
|
||||
continue;
|
||||
|
||||
trig_vec *vec1, *vec2;
|
||||
RefPtr<TrigVector> vec1, vec2;
|
||||
|
||||
switch (item->exa_action)
|
||||
{
|
||||
|
@ -57,9 +57,9 @@ public:
|
||||
void release(thread_db* tdbb);
|
||||
|
||||
private:
|
||||
static void verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation, trig_vec* triggers,
|
||||
static void verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation, TrigVector* triggers,
|
||||
jrd_rel* view);
|
||||
static void triggersExternalAccess(thread_db* tdbb, ExternalAccessList& list, trig_vec* tvec);
|
||||
static void triggersExternalAccess(thread_db* tdbb, ExternalAccessList& list, TrigVector* tvec);
|
||||
|
||||
void buildExternalAccess(thread_db* tdbb, ExternalAccessList& list);
|
||||
|
||||
|
@ -273,7 +273,7 @@ void jrd_rel::RelPagesSnapshot::clear()
|
||||
|
||||
bool jrd_rel::hasTriggers() const
|
||||
{
|
||||
typedef const trig_vec* ctv;
|
||||
typedef const TrigVector* ctv;
|
||||
ctv trigs[6] = // non-const array, don't want optimization tricks by the compiler.
|
||||
{
|
||||
rel_pre_erase,
|
||||
|
@ -257,12 +257,12 @@ public:
|
||||
Lock* rel_gc_lock; // garbage collection lock
|
||||
IndexLock* rel_index_locks; // index existence locks
|
||||
IndexBlock* rel_index_blocks; // index blocks for caching index info
|
||||
trig_vec* rel_pre_erase; // Pre-operation erase trigger
|
||||
trig_vec* rel_post_erase; // Post-operation erase trigger
|
||||
trig_vec* rel_pre_modify; // Pre-operation modify trigger
|
||||
trig_vec* rel_post_modify; // Post-operation modify trigger
|
||||
trig_vec* rel_pre_store; // Pre-operation store trigger
|
||||
trig_vec* rel_post_store; // Post-operation store trigger
|
||||
TrigVector* rel_pre_erase; // Pre-operation erase trigger
|
||||
TrigVector* rel_post_erase; // Post-operation erase trigger
|
||||
TrigVector* rel_pre_modify; // Pre-operation modify trigger
|
||||
TrigVector* rel_post_modify; // Post-operation modify trigger
|
||||
TrigVector* rel_pre_store; // Pre-operation store trigger
|
||||
TrigVector* rel_post_store; // Post-operation store trigger
|
||||
prim rel_primary_dpnds; // foreign dependencies on this relation's primary key
|
||||
frgn rel_foreign_refs; // foreign references to other relations' primary keys
|
||||
|
||||
|
@ -498,13 +498,13 @@ static bool formatsAreEqual(const Format*, const Format*);
|
||||
static bool find_depend_in_dfw(thread_db*, TEXT*, USHORT, USHORT, jrd_tra*);
|
||||
static void get_array_desc(thread_db*, const TEXT*, Ods::InternalArrayDesc*);
|
||||
static void get_trigger_dependencies(DeferredWork*, bool, jrd_tra*);
|
||||
static void load_trigs(thread_db*, jrd_rel*, trig_vec**);
|
||||
static void load_trigs(thread_db*, jrd_rel*, TrigVector**);
|
||||
static Format* make_format(thread_db*, jrd_rel*, USHORT *, TemporaryField*);
|
||||
static void put_summary_blob(thread_db* tdbb, blb*, enum rsr_t, bid*, jrd_tra*);
|
||||
static void put_summary_record(thread_db* tdbb, blb*, enum rsr_t, const UCHAR*, USHORT);
|
||||
static void setup_array(thread_db*, blb*, const TEXT*, USHORT, TemporaryField*);
|
||||
static blb* setup_triggers(thread_db*, jrd_rel*, bool, trig_vec**, blb*);
|
||||
static void setup_trigger_details(thread_db*, jrd_rel*, blb*, trig_vec**, const TEXT*, bool);
|
||||
static blb* setup_triggers(thread_db*, jrd_rel*, bool, TrigVector**, blb*);
|
||||
static void setup_trigger_details(thread_db*, jrd_rel*, blb*, TrigVector**, const TEXT*, bool);
|
||||
static bool validate_text_type (thread_db*, const TemporaryField*);
|
||||
|
||||
static void check_partners(thread_db*, const USHORT);
|
||||
@ -5329,7 +5329,7 @@ static void get_trigger_dependencies(DeferredWork* work, bool compile, jrd_tra*
|
||||
}
|
||||
|
||||
|
||||
static void load_trigs(thread_db* tdbb, jrd_rel* relation, trig_vec** triggers)
|
||||
static void load_trigs(thread_db* tdbb, jrd_rel* relation, TrigVector** triggers)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -5343,7 +5343,7 @@ static void load_trigs(thread_db* tdbb, jrd_rel* relation, trig_vec** triggers)
|
||||
* place ie the relation block.
|
||||
*
|
||||
**************************************/
|
||||
trig_vec* tmp_vector;
|
||||
TrigVector* tmp_vector;
|
||||
|
||||
tmp_vector = relation->rel_pre_store;
|
||||
relation->rel_pre_store = triggers[TRIGGER_PRE_STORE];
|
||||
@ -5574,7 +5574,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_
|
||||
int physical_fields = 0;
|
||||
bool external_flag = false;
|
||||
bool computed_field;
|
||||
trig_vec* triggers[TRIGGER_MAX];
|
||||
TrigVector* triggers[TRIGGER_MAX];
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
@ -6042,7 +6042,7 @@ static bool modify_trigger(thread_db* tdbb, SSHORT phase, DeferredWork* work, jr
|
||||
relation->rel_flags &= ~REL_scanned;
|
||||
MET_scan_relation(tdbb, relation);
|
||||
|
||||
trig_vec* triggers[TRIGGER_MAX];
|
||||
TrigVector* triggers[TRIGGER_MAX];
|
||||
|
||||
for (int i = 0; i < TRIGGER_MAX; ++i)
|
||||
triggers[i] = NULL;
|
||||
@ -6276,7 +6276,7 @@ static void setup_array(thread_db* tdbb, blb* blob, const TEXT* field_name, USHO
|
||||
|
||||
|
||||
static blb* setup_triggers(thread_db* tdbb, jrd_rel* relation, bool null_view,
|
||||
trig_vec** triggers, blb* blob)
|
||||
TrigVector** triggers, blb* blob)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -6374,7 +6374,7 @@ static blb* setup_triggers(thread_db* tdbb, jrd_rel* relation, bool null_view,
|
||||
static void setup_trigger_details(thread_db* tdbb,
|
||||
jrd_rel* relation,
|
||||
blb* blob,
|
||||
trig_vec** triggers,
|
||||
TrigVector** triggers,
|
||||
const TEXT* trigger_name,
|
||||
bool null_view)
|
||||
{
|
||||
|
@ -544,10 +544,10 @@ void EXE_execute_ddl_triggers(thread_db* tdbb, jrd_tra* transaction, bool preTri
|
||||
|
||||
try
|
||||
{
|
||||
trig_vec triggers;
|
||||
trig_vec* triggersPtr = &triggers;
|
||||
TrigVector triggers;
|
||||
TrigVector* triggersPtr = &triggers;
|
||||
|
||||
for (trig_vec::iterator i = attachment->att_ddl_triggers->begin();
|
||||
for (TrigVector::iterator i = attachment->att_ddl_triggers->begin();
|
||||
i != attachment->att_ddl_triggers->end();
|
||||
++i)
|
||||
{
|
||||
@ -988,7 +988,7 @@ static void execute_looper(thread_db* tdbb,
|
||||
|
||||
|
||||
void EXE_execute_triggers(thread_db* tdbb,
|
||||
trig_vec** triggers,
|
||||
TrigVector** triggers,
|
||||
record_param* old_rpb,
|
||||
record_param* new_rpb,
|
||||
TriggerAction trigger_action, StmtNode::WhichTrigger which_trig)
|
||||
@ -1012,7 +1012,7 @@ void EXE_execute_triggers(thread_db* tdbb,
|
||||
jrd_req* const request = tdbb->getRequest();
|
||||
jrd_tra* const transaction = request ? request->req_transaction : tdbb->getTransaction();
|
||||
|
||||
trig_vec* vector = *triggers;
|
||||
TrigVector* vector = *triggers;
|
||||
Record* const old_rec = old_rpb ? old_rpb->rpb_record : NULL;
|
||||
Record* const new_rec = new_rpb ? new_rpb->rpb_record : NULL;
|
||||
|
||||
@ -1038,7 +1038,7 @@ void EXE_execute_triggers(thread_db* tdbb,
|
||||
|
||||
try
|
||||
{
|
||||
for (trig_vec::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
|
||||
for (TrigVector::iterator ptr = vector->begin(); ptr != vector->end(); ++ptr)
|
||||
{
|
||||
ptr->compile(tdbb);
|
||||
|
||||
|
@ -43,7 +43,7 @@ void EXE_execute_ddl_triggers(Jrd::thread_db* tdbb, Jrd::jrd_tra* transaction,
|
||||
const Jrd::StmtNode* EXE_looper(Jrd::thread_db* tdbb, Jrd::jrd_req* request,
|
||||
const Jrd::StmtNode* in_node);
|
||||
|
||||
void EXE_execute_triggers(Jrd::thread_db*, Jrd::trig_vec**, Jrd::record_param*, Jrd::record_param*,
|
||||
void EXE_execute_triggers(Jrd::thread_db*, Jrd::TrigVector**, Jrd::record_param*, Jrd::record_param*,
|
||||
enum TriggerAction, Jrd::StmtNode::WhichTrigger);
|
||||
|
||||
void EXE_receive(Jrd::thread_db*, Jrd::jrd_req*, USHORT, ULONG, UCHAR*, bool = false);
|
||||
|
@ -1869,7 +1869,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
|
||||
// load DDL triggers
|
||||
MET_load_ddl_triggers(tdbb);
|
||||
|
||||
const trig_vec* trig_connect = attachment->att_triggers[DB_TRIGGER_CONNECT];
|
||||
const TrigVector* trig_connect = attachment->att_triggers[DB_TRIGGER_CONNECT];
|
||||
if (trig_connect && !trig_connect->isEmpty())
|
||||
{
|
||||
// Start a transaction to execute ON CONNECT triggers.
|
||||
@ -6902,7 +6902,7 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
||||
{
|
||||
try
|
||||
{
|
||||
const trig_vec* const trig_disconnect =
|
||||
const TrigVector* const trig_disconnect =
|
||||
attachment->att_triggers[DB_TRIGGER_DISCONNECT];
|
||||
|
||||
if (!forcedPurge &&
|
||||
@ -8077,3 +8077,29 @@ void JRD_cancel_operation(thread_db* /*tdbb*/, Jrd::Attachment* attachment, int
|
||||
fb_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TrigVector::release() const
|
||||
{
|
||||
release(JRD_get_thread_data());
|
||||
}
|
||||
|
||||
|
||||
void TrigVector::release(thread_db* tdbb) const
|
||||
{
|
||||
if (--useCount == 0)
|
||||
{
|
||||
const const_iterator e = end();
|
||||
for (const_iterator t = begin(); t != e; ++t)
|
||||
{
|
||||
JrdStatement* stmt = t->statement;
|
||||
if (stmt)
|
||||
stmt->release(tdbb);
|
||||
|
||||
delete t->extTrigger;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +135,6 @@ class PreparedStatement;
|
||||
class TraceManager;
|
||||
class MessageNode;
|
||||
|
||||
// The database block, the topmost block in the metadata
|
||||
// cache for a database
|
||||
|
||||
// Relation trigger definition
|
||||
|
||||
@ -172,6 +170,39 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// Array of triggers (suppose separate arrays for triggers of different types)
|
||||
|
||||
class TrigVector : public Firebird::ObjectsArray<Trigger>
|
||||
{
|
||||
public:
|
||||
explicit TrigVector(Firebird::MemoryPool& pool)
|
||||
: Firebird::ObjectsArray<Trigger>(pool),
|
||||
useCount(0)
|
||||
{ }
|
||||
|
||||
TrigVector()
|
||||
: Firebird::ObjectsArray<Trigger>(),
|
||||
useCount(0)
|
||||
{ }
|
||||
|
||||
void addRef() const
|
||||
{
|
||||
++useCount;
|
||||
}
|
||||
|
||||
void release() const;
|
||||
void release(thread_db* tdbb) const;
|
||||
|
||||
~TrigVector()
|
||||
{
|
||||
fb_assert(useCount.value() == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable Firebird::AtomicCounter useCount;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Flags to indicate normal internal requests vs. dyn internal requests
|
||||
//
|
||||
|
@ -114,7 +114,7 @@ static int blocking_ast_relation(void*);
|
||||
static int partners_ast_relation(void*);
|
||||
static int rescan_ast_relation(void*);
|
||||
static ULONG get_rel_flags_from_FLAGS(USHORT);
|
||||
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, trig_vec**, const TEXT*, FB_UINT64, bool,
|
||||
static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, bool,
|
||||
USHORT, const MetaName&, const string&, const bid*);
|
||||
static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*);
|
||||
static void lookup_view_contexts(thread_db*, jrd_rel*);
|
||||
@ -122,7 +122,7 @@ static void make_relation_scope_name(const TEXT*, const USHORT, string& str);
|
||||
static ValueExprNode* parse_field_default_blr(thread_db* tdbb, bid* blob_id);
|
||||
static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const MetaName name);
|
||||
static bool resolve_charset_and_collation(thread_db*, USHORT*, const UCHAR*, const UCHAR*);
|
||||
static void save_trigger_data(thread_db*, trig_vec**, jrd_rel*, JrdStatement*, blb*, blb*,
|
||||
static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, JrdStatement*, blb*, blb*,
|
||||
const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&,
|
||||
const bid*);
|
||||
static void scan_partners(thread_db*, jrd_rel*);
|
||||
@ -132,7 +132,7 @@ static bool verify_TRG_ignore_perm(thread_db*, const MetaName&);
|
||||
|
||||
|
||||
// Decompile all triggers from vector
|
||||
static void release_cached_triggers(thread_db* tdbb, trig_vec* vector)
|
||||
static void release_cached_triggers(thread_db* tdbb, TrigVector* vector)
|
||||
{
|
||||
if (!vector)
|
||||
return;
|
||||
@ -179,7 +179,7 @@ static void inc_int_use_count(JrdStatement* statement)
|
||||
|
||||
|
||||
// Increment int_use_count for all procedures used by triggers
|
||||
static void post_used_procedures(trig_vec* vector)
|
||||
static void post_used_procedures(TrigVector* vector)
|
||||
{
|
||||
if (!vector)
|
||||
return;
|
||||
@ -1851,7 +1851,8 @@ void MET_load_db_triggers(thread_db* tdbb, int type)
|
||||
}
|
||||
|
||||
attachment->att_triggers[type] = FB_NEW_POOL(*attachment->att_pool)
|
||||
trig_vec(*attachment->att_pool);
|
||||
TrigVector(*attachment->att_pool);
|
||||
attachment->att_triggers[type]->addRef();
|
||||
|
||||
AutoRequest trigger_request;
|
||||
int encoded_type = type | TRIGGER_TYPE_DB;
|
||||
@ -1884,7 +1885,7 @@ void MET_load_ddl_triggers(thread_db* tdbb)
|
||||
}
|
||||
|
||||
attachment->att_ddl_triggers = FB_NEW_POOL(*attachment->att_pool)
|
||||
trig_vec(*attachment->att_pool);
|
||||
TrigVector(*attachment->att_pool);
|
||||
|
||||
AutoRequest trigger_request;
|
||||
|
||||
@ -1907,7 +1908,7 @@ void MET_load_ddl_triggers(thread_db* tdbb)
|
||||
void MET_load_trigger(thread_db* tdbb,
|
||||
jrd_rel* relation,
|
||||
const MetaName& trigger_name,
|
||||
trig_vec** triggers)
|
||||
TrigVector** triggers)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -3117,7 +3118,7 @@ void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation)
|
||||
const USHORT trig_flags = TRG.RDB$FLAGS;
|
||||
const TEXT* name = TRG.RDB$TRIGGER_NAME;
|
||||
|
||||
trig_vec** ptr;
|
||||
TrigVector** ptr;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -3753,7 +3754,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
trig_vec* triggers[TRIGGER_MAX];
|
||||
TrigVector* triggers[TRIGGER_MAX];
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
Jrd::ContextPoolHolder context(tdbb, attachment->att_pool);
|
||||
@ -4050,7 +4051,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
|
||||
// We have just loaded the triggers onto the local vector triggers.
|
||||
// Its now time to place them at their rightful place ie the relation block.
|
||||
|
||||
trig_vec* tmp_vector;
|
||||
TrigVector* tmp_vector;
|
||||
|
||||
tmp_vector = relation->rel_pre_store;
|
||||
relation->rel_pre_store = triggers[TRIGGER_PRE_STORE];
|
||||
@ -4443,7 +4444,7 @@ ULONG MET_get_rel_flags_from_TYPE(USHORT type)
|
||||
|
||||
|
||||
static void get_trigger(thread_db* tdbb, jrd_rel* relation,
|
||||
bid* blob_id, bid* debug_blob_id, trig_vec** ptr,
|
||||
bid* blob_id, bid* debug_blob_id, TrigVector** ptr,
|
||||
const TEXT* name, FB_UINT64 type,
|
||||
bool sys_trigger, USHORT flags,
|
||||
const MetaName& engine, const string& entryPoint,
|
||||
@ -4642,7 +4643,7 @@ static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, c
|
||||
}
|
||||
|
||||
|
||||
void MET_release_trigger(thread_db* tdbb, trig_vec** vector_ptr, const MetaName& name)
|
||||
void MET_release_trigger(thread_db* tdbb, TrigVector** vector_ptr, const MetaName& name)
|
||||
{
|
||||
/***********************************************
|
||||
*
|
||||
@ -4659,7 +4660,7 @@ void MET_release_trigger(thread_db* tdbb, trig_vec** vector_ptr, const MetaName&
|
||||
if (!*vector_ptr)
|
||||
return;
|
||||
|
||||
trig_vec& vector = **vector_ptr;
|
||||
TrigVector& vector = **vector_ptr;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
@ -4681,7 +4682,7 @@ void MET_release_trigger(thread_db* tdbb, trig_vec** vector_ptr, const MetaName&
|
||||
}
|
||||
|
||||
|
||||
void MET_release_triggers( thread_db* tdbb, trig_vec** vector_ptr)
|
||||
void MET_release_triggers( thread_db* tdbb, TrigVector** vector_ptr)
|
||||
{
|
||||
/***********************************************
|
||||
*
|
||||
@ -4695,7 +4696,7 @@ void MET_release_triggers( thread_db* tdbb, trig_vec** vector_ptr)
|
||||
* else do the work.
|
||||
*
|
||||
**************************************/
|
||||
trig_vec* vector = *vector_ptr;
|
||||
TrigVector* vector = *vector_ptr;
|
||||
|
||||
if (!vector)
|
||||
return;
|
||||
@ -4711,16 +4712,7 @@ void MET_release_triggers( thread_db* tdbb, trig_vec** vector_ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
for (FB_SIZE_T i = 0; i < vector->getCount(); i++)
|
||||
{
|
||||
JrdStatement* stmt = (*vector)[i].statement;
|
||||
if (stmt)
|
||||
stmt->release(tdbb);
|
||||
|
||||
delete (*vector)[i].extTrigger;
|
||||
}
|
||||
|
||||
delete vector;
|
||||
vector->release(tdbb);
|
||||
}
|
||||
|
||||
|
||||
@ -4837,7 +4829,7 @@ static bool resolve_charset_and_collation(thread_db* tdbb,
|
||||
}
|
||||
|
||||
|
||||
static void save_trigger_data(thread_db* tdbb, trig_vec** ptr, jrd_rel* relation,
|
||||
static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relation,
|
||||
JrdStatement* statement, blb* blrBlob, blb* debugInfoBlob,
|
||||
const TEXT* name, FB_UINT64 type,
|
||||
bool sys_trigger, USHORT flags,
|
||||
@ -4855,12 +4847,13 @@ static void save_trigger_data(thread_db* tdbb, trig_vec** ptr, jrd_rel* relation
|
||||
*
|
||||
**************************************/
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
trig_vec* vector = *ptr;
|
||||
TrigVector* vector = *ptr;
|
||||
|
||||
if (!vector)
|
||||
{
|
||||
MemoryPool* pool = relation ? relation->rel_pool : attachment->att_pool;
|
||||
vector = FB_NEW_POOL(*pool) trig_vec(*pool);
|
||||
vector = FB_NEW_POOL(*pool) TrigVector(*pool);
|
||||
vector->addRef();
|
||||
*ptr = vector;
|
||||
}
|
||||
|
||||
@ -4905,11 +4898,11 @@ static void save_trigger_data(thread_db* tdbb, trig_vec** ptr, jrd_rel* relation
|
||||
}
|
||||
|
||||
|
||||
const Trigger* findTrigger(trig_vec* triggers, const MetaName& trig_name)
|
||||
const Trigger* findTrigger(TrigVector* triggers, const MetaName& trig_name)
|
||||
{
|
||||
if (triggers)
|
||||
{
|
||||
for (trig_vec::iterator t = triggers->begin(); t != triggers->end(); ++t)
|
||||
for (TrigVector::iterator t = triggers->begin(); t != triggers->end(); ++t)
|
||||
{
|
||||
if (t->name.compare(trig_name) == 0)
|
||||
return &(*t);
|
||||
|
@ -94,7 +94,7 @@ void MET_get_shadow_files(Jrd::thread_db*, bool);
|
||||
void MET_load_db_triggers(Jrd::thread_db*, int);
|
||||
void MET_load_ddl_triggers(Jrd::thread_db* tdbb);
|
||||
bool MET_load_exception(Jrd::thread_db*, Jrd::ExceptionItem&);
|
||||
void MET_load_trigger(Jrd::thread_db*, Jrd::jrd_rel*, const Firebird::MetaName&, Jrd::trig_vec**);
|
||||
void MET_load_trigger(Jrd::thread_db*, Jrd::jrd_rel*, const Firebird::MetaName&, Jrd::TrigVector**);
|
||||
void MET_lookup_cnstrt_for_index(Jrd::thread_db*, Firebird::MetaName& constraint, const Firebird::MetaName& index_name);
|
||||
void MET_lookup_cnstrt_for_trigger(Jrd::thread_db*, Firebird::MetaName&, Firebird::MetaName&, const Firebird::MetaName&);
|
||||
void MET_lookup_exception(Jrd::thread_db*, SLONG, /* OUT */ Firebird::MetaName&, /* OUT */ Firebird::string*);
|
||||
@ -120,8 +120,8 @@ void MET_prepare(Jrd::thread_db*, Jrd::jrd_tra*, USHORT, const UCHAR*);
|
||||
Jrd::jrd_prc* MET_procedure(Jrd::thread_db*, USHORT, bool, USHORT);
|
||||
Jrd::jrd_rel* MET_relation(Jrd::thread_db*, USHORT);
|
||||
void MET_release_existence(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_release_trigger(Jrd::thread_db*, Jrd::trig_vec**, const Firebird::MetaName&);
|
||||
void MET_release_triggers(Jrd::thread_db*, Jrd::trig_vec**);
|
||||
void MET_release_trigger(Jrd::thread_db*, Jrd::TrigVector**, const Firebird::MetaName&);
|
||||
void MET_release_triggers(Jrd::thread_db*, Jrd::TrigVector**);
|
||||
#ifdef DEV_BUILD
|
||||
void MET_verify_cache(Jrd::thread_db*);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user