1 /* 2 Copyright (c) 2003, 2021, Oracle and/or its affiliates. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #ifndef NDB_TRIGGER_DEFINITIONS_H 26 #define NDB_TRIGGER_DEFINITIONS_H 27 28 #include <ndb_global.h> 29 #include "ndb_limits.h" 30 #include <Bitmask.hpp> 31 #include <signaldata/DictTabInfo.hpp> 32 33 #define ILLEGAL_TRIGGER_ID ((Uint32)(~0)) 34 35 struct TriggerType { 36 enum Value { 37 //CONSTRAINT = 0, 38 SECONDARY_INDEX = DictTabInfo::HashIndexTrigger, 39 FK_PARENT = DictTabInfo::FKParentTrigger, 40 FK_CHILD = DictTabInfo::FKChildTrigger, 41 //SCHEMA_UPGRADE = 3, 42 //API_TRIGGER = 4, 43 //SQL_TRIGGER = 5, 44 SUBSCRIPTION = DictTabInfo::SubscriptionTrigger, 45 READ_ONLY_CONSTRAINT = DictTabInfo::ReadOnlyConstraint, 46 ORDERED_INDEX = DictTabInfo::IndexTrigger, 47 48 SUBSCRIPTION_BEFORE = 9, // Only used by TUP/SUMA, should be REMOVED!! 49 REORG_TRIGGER = DictTabInfo::ReorgTrigger 50 }; 51 }; 52 53 struct TriggerActionTime { 54 enum Value { 55 TA_BEFORE = 0, /* Immediate, before operation */ 56 TA_AFTER = 1, /* Immediate, after operation */ 57 TA_DEFERRED = 2, /* Before commit */ 58 TA_DETACHED = 3, /* After commit in a separate transaction, NYI */ 59 TA_CUSTOM = 4 /* Hardcoded per TriggerType */ 60 }; 61 }; 62 63 struct TriggerEvent { 64 /** TableEvent must match 1 << TriggerEvent */ 65 enum Value { 66 TE_INSERT = 0, 67 TE_DELETE = 1, 68 TE_UPDATE = 2, 69 TE_CUSTOM = 3 /* Hardcoded per TriggerType */ 70 }; 71 }; 72 73 struct TriggerInfo { 74 TriggerType::Value triggerType; 75 TriggerActionTime::Value triggerActionTime; 76 TriggerEvent::Value triggerEvent; 77 bool monitorReplicas; 78 bool monitorAllAttributes; 79 bool reportAllMonitoredAttributes; 80 81 // static methods 82 83 // get/set bits in Uint32 84 static TriggerType::Value getTriggerTypeTriggerInfo85 getTriggerType(const Uint32& info) { 86 const Uint32 val = BitmaskImpl::getField(1, &info, 0, 8); 87 return (TriggerType::Value)val; 88 } 89 static void setTriggerTypeTriggerInfo90 setTriggerType(Uint32& info, TriggerType::Value val) { 91 BitmaskImpl::setField(1, &info, 0, 8, (Uint32)val); 92 } 93 static TriggerActionTime::Value getTriggerActionTimeTriggerInfo94 getTriggerActionTime(const Uint32& info) { 95 const Uint32 val = BitmaskImpl::getField(1, &info, 8, 8); 96 return (TriggerActionTime::Value)val; 97 } 98 static void setTriggerActionTimeTriggerInfo99 setTriggerActionTime(Uint32& info, TriggerActionTime::Value val) { 100 BitmaskImpl::setField(1, &info, 8, 8, (Uint32)val); 101 } 102 static TriggerEvent::Value getTriggerEventTriggerInfo103 getTriggerEvent(const Uint32& info) { 104 const Uint32 val = BitmaskImpl::getField(1, &info, 16, 8); 105 return (TriggerEvent::Value)val; 106 } 107 static void setTriggerEventTriggerInfo108 setTriggerEvent(Uint32& info, TriggerEvent::Value val) { 109 BitmaskImpl::setField(1, &info, 16, 8, (Uint32)val); 110 } 111 static bool getMonitorReplicasTriggerInfo112 getMonitorReplicas(const Uint32& info) { 113 return BitmaskImpl::getField(1, &info, 24, 1); 114 } 115 static void setMonitorReplicasTriggerInfo116 setMonitorReplicas(Uint32& info, bool val) { 117 BitmaskImpl::setField(1, &info, 24, 1, val); 118 } 119 static bool getMonitorAllAttributesTriggerInfo120 getMonitorAllAttributes(const Uint32& info) { 121 return BitmaskImpl::getField(1, &info, 25, 1); 122 } 123 static void setMonitorAllAttributesTriggerInfo124 setMonitorAllAttributes(Uint32& info, bool val) { 125 BitmaskImpl::setField(1, &info, 25, 1, val); 126 } 127 static bool getReportAllMonitoredAttributesTriggerInfo128 getReportAllMonitoredAttributes(const Uint32& info) { 129 return BitmaskImpl::getField(1, &info, 26, 1); 130 } 131 static void setReportAllMonitoredAttributesTriggerInfo132 setReportAllMonitoredAttributes(Uint32& info, bool val) { 133 BitmaskImpl::setField(1, &info, 26, 1, val); 134 } 135 136 // convert between Uint32 and struct 137 static void packTriggerInfoTriggerInfo138 packTriggerInfo(Uint32& val, const TriggerInfo& str) { 139 val = 0; 140 setTriggerType(val, str.triggerType); 141 setTriggerActionTime(val, str.triggerActionTime); 142 setTriggerEvent(val, str.triggerEvent); 143 setMonitorReplicas(val, str.monitorReplicas); 144 setMonitorAllAttributes(val, str.monitorAllAttributes); 145 setReportAllMonitoredAttributes(val, str.reportAllMonitoredAttributes); 146 } 147 static void unpackTriggerInfoTriggerInfo148 unpackTriggerInfo(const Uint32& val, TriggerInfo& str) { 149 str.triggerType = getTriggerType(val); 150 str.triggerActionTime = getTriggerActionTime(val); 151 str.triggerEvent = getTriggerEvent(val); 152 str.monitorReplicas = getMonitorReplicas(val); 153 str.monitorAllAttributes = getMonitorAllAttributes(val); 154 str.reportAllMonitoredAttributes = getReportAllMonitoredAttributes(val); 155 } 156 157 // for debug print 158 static const char* triggerTypeNameTriggerInfo159 triggerTypeName(Uint32 val) { 160 switch (val) { 161 case TriggerType::SECONDARY_INDEX: 162 return "SECONDARY_INDEX"; 163 case TriggerType::SUBSCRIPTION: 164 return "SUBSCRIPTION"; 165 case TriggerType::READ_ONLY_CONSTRAINT: 166 return "READ_ONLY_CONSTRAINT"; 167 case TriggerType::ORDERED_INDEX: 168 return "ORDERED_INDEX"; 169 case TriggerType::SUBSCRIPTION_BEFORE: 170 return "SUBSCRIPTION_BEFORE"; 171 } 172 return "UNKNOWN"; 173 } 174 static const char* triggerActionTimeNameTriggerInfo175 triggerActionTimeName(Uint32 val) { 176 switch (val) { 177 case TriggerActionTime::TA_BEFORE: 178 return "TA_BEFORE"; 179 case TriggerActionTime::TA_AFTER: 180 return "TA_AFTER"; 181 case TriggerActionTime::TA_DEFERRED: 182 return "TA_DEFERRED"; 183 case TriggerActionTime::TA_DETACHED: 184 return "TA_DETACHED"; 185 case TriggerActionTime::TA_CUSTOM: 186 return "TA_CUSTOM"; 187 } 188 return "UNKNOWN"; 189 } 190 static const char* triggerEventNameTriggerInfo191 triggerEventName(Uint32 val) { 192 switch (val) { 193 case TriggerEvent::TE_INSERT: 194 return "TE_INSERT"; 195 case TriggerEvent::TE_DELETE: 196 return "TE_DELETE"; 197 case TriggerEvent::TE_UPDATE: 198 return "TE_UPDATE"; 199 case TriggerEvent::TE_CUSTOM: 200 return "TE_CUSTOM"; 201 } 202 return "UNKNOWN"; 203 } 204 }; 205 206 struct NoOfFiredTriggers 207 { 208 STATIC_CONST( DeferredUKBit = (Uint32(1) << 31) ); 209 STATIC_CONST( DeferredFKBit = (Uint32(1) << 30) ); 210 STATIC_CONST( DeferredBits = (DeferredUKBit | DeferredFKBit)); 211 getFiredCountNoOfFiredTriggers212 static Uint32 getFiredCount(Uint32 v) { 213 return v & ~(Uint32(DeferredBits)); 214 } getDeferredUKBitNoOfFiredTriggers215 static Uint32 getDeferredUKBit(Uint32 v) { 216 return (v & Uint32(DeferredUKBit)) != 0; 217 } setDeferredUKBitNoOfFiredTriggers218 static void setDeferredUKBit(Uint32 & v) { 219 v |= Uint32(DeferredUKBit); 220 } getDeferredFKBitNoOfFiredTriggers221 static Uint32 getDeferredFKBit(Uint32 v) { 222 return (v & Uint32(DeferredFKBit)) != 0; 223 } setDeferredFKBitNoOfFiredTriggers224 static void setDeferredFKBit(Uint32 & v) { 225 v |= Uint32(DeferredFKBit); 226 } 227 getDeferredAllSetNoOfFiredTriggers228 static bool getDeferredAllSet(Uint32 v) { 229 return (v & Uint32(DeferredBits)) == DeferredBits; 230 } 231 }; 232 233 struct TriggerPreCommitPass 234 { 235 /** 236 * When using deferred triggers... 237 * - UK are split into 2 passes... 238 * - FK needs to be evaluated *after* UK has been processed 239 * as it (can) use UK 240 * 241 * When having cascadeing FK's they can provoke UK updates 242 * in such cases...the passes are 243 * N * (PASS_MAX + 1) + PASS 244 */ 245 enum 246 { 247 UK_PASS_0 = 0, 248 UK_PASS_1 = 1, 249 FK_PASS_0 = 7, // leave some room...(unsure if it's needed) 250 TPCP_PASS_MAX = 15 251 }; 252 }; 253 254 #endif 255