/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NDB_TRIGGER_DEFINITIONS_H #define NDB_TRIGGER_DEFINITIONS_H #include #include "ndb_limits.h" #include #include #define ILLEGAL_TRIGGER_ID ((Uint32)(~0)) struct TriggerType { enum Value { //CONSTRAINT = 0, SECONDARY_INDEX = DictTabInfo::HashIndexTrigger, FK_PARENT = DictTabInfo::FKParentTrigger, FK_CHILD = DictTabInfo::FKChildTrigger, //SCHEMA_UPGRADE = 3, //API_TRIGGER = 4, //SQL_TRIGGER = 5, SUBSCRIPTION = DictTabInfo::SubscriptionTrigger, READ_ONLY_CONSTRAINT = DictTabInfo::ReadOnlyConstraint, ORDERED_INDEX = DictTabInfo::IndexTrigger, SUBSCRIPTION_BEFORE = 9, // Only used by TUP/SUMA, should be REMOVED!! REORG_TRIGGER = DictTabInfo::ReorgTrigger }; }; struct TriggerActionTime { enum Value { TA_BEFORE = 0, /* Immediate, before operation */ TA_AFTER = 1, /* Immediate, after operation */ TA_DEFERRED = 2, /* Before commit */ TA_DETACHED = 3, /* After commit in a separate transaction, NYI */ TA_CUSTOM = 4 /* Hardcoded per TriggerType */ }; }; struct TriggerEvent { /** TableEvent must match 1 << TriggerEvent */ enum Value { TE_INSERT = 0, TE_DELETE = 1, TE_UPDATE = 2, TE_CUSTOM = 3 /* Hardcoded per TriggerType */ }; }; struct TriggerInfo { TriggerType::Value triggerType; TriggerActionTime::Value triggerActionTime; TriggerEvent::Value triggerEvent; bool monitorReplicas; bool monitorAllAttributes; bool reportAllMonitoredAttributes; // static methods // get/set bits in Uint32 static TriggerType::Value getTriggerType(const Uint32& info) { const Uint32 val = BitmaskImpl::getField(1, &info, 0, 8); return (TriggerType::Value)val; } static void setTriggerType(Uint32& info, TriggerType::Value val) { BitmaskImpl::setField(1, &info, 0, 8, (Uint32)val); } static TriggerActionTime::Value getTriggerActionTime(const Uint32& info) { const Uint32 val = BitmaskImpl::getField(1, &info, 8, 8); return (TriggerActionTime::Value)val; } static void setTriggerActionTime(Uint32& info, TriggerActionTime::Value val) { BitmaskImpl::setField(1, &info, 8, 8, (Uint32)val); } static TriggerEvent::Value getTriggerEvent(const Uint32& info) { const Uint32 val = BitmaskImpl::getField(1, &info, 16, 8); return (TriggerEvent::Value)val; } static void setTriggerEvent(Uint32& info, TriggerEvent::Value val) { BitmaskImpl::setField(1, &info, 16, 8, (Uint32)val); } static bool getMonitorReplicas(const Uint32& info) { return BitmaskImpl::getField(1, &info, 24, 1); } static void setMonitorReplicas(Uint32& info, bool val) { BitmaskImpl::setField(1, &info, 24, 1, val); } static bool getMonitorAllAttributes(const Uint32& info) { return BitmaskImpl::getField(1, &info, 25, 1); } static void setMonitorAllAttributes(Uint32& info, bool val) { BitmaskImpl::setField(1, &info, 25, 1, val); } static bool getReportAllMonitoredAttributes(const Uint32& info) { return BitmaskImpl::getField(1, &info, 26, 1); } static void setReportAllMonitoredAttributes(Uint32& info, bool val) { BitmaskImpl::setField(1, &info, 26, 1, val); } // convert between Uint32 and struct static void packTriggerInfo(Uint32& val, const TriggerInfo& str) { val = 0; setTriggerType(val, str.triggerType); setTriggerActionTime(val, str.triggerActionTime); setTriggerEvent(val, str.triggerEvent); setMonitorReplicas(val, str.monitorReplicas); setMonitorAllAttributes(val, str.monitorAllAttributes); setReportAllMonitoredAttributes(val, str.reportAllMonitoredAttributes); } static void unpackTriggerInfo(const Uint32& val, TriggerInfo& str) { str.triggerType = getTriggerType(val); str.triggerActionTime = getTriggerActionTime(val); str.triggerEvent = getTriggerEvent(val); str.monitorReplicas = getMonitorReplicas(val); str.monitorAllAttributes = getMonitorAllAttributes(val); str.reportAllMonitoredAttributes = getReportAllMonitoredAttributes(val); } // for debug print static const char* triggerTypeName(Uint32 val) { switch (val) { case TriggerType::SECONDARY_INDEX: return "SECONDARY_INDEX"; case TriggerType::SUBSCRIPTION: return "SUBSCRIPTION"; case TriggerType::READ_ONLY_CONSTRAINT: return "READ_ONLY_CONSTRAINT"; case TriggerType::ORDERED_INDEX: return "ORDERED_INDEX"; case TriggerType::SUBSCRIPTION_BEFORE: return "SUBSCRIPTION_BEFORE"; } return "UNKNOWN"; } static const char* triggerActionTimeName(Uint32 val) { switch (val) { case TriggerActionTime::TA_BEFORE: return "TA_BEFORE"; case TriggerActionTime::TA_AFTER: return "TA_AFTER"; case TriggerActionTime::TA_DEFERRED: return "TA_DEFERRED"; case TriggerActionTime::TA_DETACHED: return "TA_DETACHED"; case TriggerActionTime::TA_CUSTOM: return "TA_CUSTOM"; } return "UNKNOWN"; } static const char* triggerEventName(Uint32 val) { switch (val) { case TriggerEvent::TE_INSERT: return "TE_INSERT"; case TriggerEvent::TE_DELETE: return "TE_DELETE"; case TriggerEvent::TE_UPDATE: return "TE_UPDATE"; case TriggerEvent::TE_CUSTOM: return "TE_CUSTOM"; } return "UNKNOWN"; } }; struct NoOfFiredTriggers { STATIC_CONST( DeferredUKBit = (Uint32(1) << 31) ); STATIC_CONST( DeferredFKBit = (Uint32(1) << 30) ); STATIC_CONST( DeferredBits = (DeferredUKBit | DeferredFKBit)); static Uint32 getFiredCount(Uint32 v) { return v & ~(Uint32(DeferredBits)); } static Uint32 getDeferredUKBit(Uint32 v) { return (v & Uint32(DeferredUKBit)) != 0; } static void setDeferredUKBit(Uint32 & v) { v |= Uint32(DeferredUKBit); } static Uint32 getDeferredFKBit(Uint32 v) { return (v & Uint32(DeferredFKBit)) != 0; } static void setDeferredFKBit(Uint32 & v) { v |= Uint32(DeferredFKBit); } static bool getDeferredAllSet(Uint32 v) { return (v & Uint32(DeferredBits)) == DeferredBits; } }; struct TriggerPreCommitPass { /** * When using deferred triggers... * - UK are split into 2 passes... * - FK needs to be evaluated *after* UK has been processed * as it (can) use UK * * When having cascadeing FK's they can provoke UK updates * in such cases...the passes are * N * (PASS_MAX + 1) + PASS */ enum { UK_PASS_0 = 0, UK_PASS_1 = 1, FK_PASS_0 = 7, // leave some room...(unsure if it's needed) TPCP_PASS_MAX = 15 }; }; #endif