1 /***************************************************************************** 2 3 Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2018, 2020, MariaDB Corporation. 5 6 This program is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free Software 8 Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along with 15 this program; if not, write to the Free Software Foundation, Inc., 16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA 17 18 *****************************************************************************/ 19 20 /**************************************************//** 21 @file include/lock0prdt.h 22 The predicate lock system 23 24 Created 9/7/2013 Jimmy Yang 25 *******************************************************/ 26 #ifndef lock0prdt_h 27 #define lock0prdt_h 28 29 #include "lock0lock.h" 30 31 /* Predicate lock data */ 32 typedef struct lock_prdt { 33 void* data; /* Predicate data */ 34 uint16 op; /* Predicate operator */ 35 } lock_prdt_t; 36 37 /*********************************************************************//** 38 Acquire a predicate lock on a block 39 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 40 dberr_t 41 lock_prdt_lock( 42 /*===========*/ 43 buf_block_t* block, /*!< in/out: buffer block of rec */ 44 lock_prdt_t* prdt, /*!< in: Predicate for the lock */ 45 dict_index_t* index, /*!< in: secondary index */ 46 enum lock_mode mode, /*!< in: mode of the lock which 47 the read cursor should set on 48 records: LOCK_S or LOCK_X; the 49 latter is possible in 50 SELECT FOR UPDATE */ 51 unsigned type_mode, 52 /*!< in: LOCK_PREDICATE or LOCK_PRDT_PAGE */ 53 que_thr_t* thr); /*!< in: query thread 54 (can be NULL if BTR_NO_LOCKING_FLAG) */ 55 56 /*********************************************************************//** 57 Acquire a "Page" lock on a block 58 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 59 dberr_t 60 lock_place_prdt_page_lock( 61 const page_id_t page_id, /*!< in: page identifier */ 62 dict_index_t* index, /*!< in: secondary index */ 63 que_thr_t* thr); /*!< in: query thread */ 64 65 /*********************************************************************//** 66 Initiate a Predicate lock from a MBR */ 67 void 68 lock_init_prdt_from_mbr( 69 /*====================*/ 70 lock_prdt_t* prdt, /*!< in/out: predicate to initialized */ 71 rtr_mbr_t* mbr, /*!< in: Minimum Bounding Rectangle */ 72 ulint mode, /*!< in: Search mode */ 73 mem_heap_t* heap); /*!< in: heap for allocating memory */ 74 75 /*********************************************************************//** 76 Get predicate lock's minimum bounding box 77 @return the minimum bounding box*/ 78 lock_prdt_t* 79 lock_get_prdt_from_lock( 80 /*====================*/ 81 const lock_t* lock); /*!< in: the lock */ 82 83 /*********************************************************************//** 84 Checks if a predicate lock request for a new lock has to wait for 85 request lock2. 86 @return true if new lock has to wait for lock2 to be removed */ 87 bool 88 lock_prdt_has_to_wait( 89 /*==================*/ 90 const trx_t* trx, /*!< in: trx of new lock */ 91 unsigned type_mode,/*!< in: precise mode of the new lock 92 to set: LOCK_S or LOCK_X, possibly 93 ORed to LOCK_PREDICATE or LOCK_PRDT_PAGE, 94 LOCK_INSERT_INTENTION */ 95 lock_prdt_t* prdt, /*!< in: lock predicate to check */ 96 const lock_t* lock2); /*!< in: another record lock; NOTE that 97 it is assumed that this has a lock bit 98 set on the same record as in the new 99 lock we are setting */ 100 101 /**************************************************************//** 102 Update predicate lock when page splits */ 103 void 104 lock_prdt_update_split( 105 /*===================*/ 106 buf_block_t* new_block, /*!< in/out: the new half page */ 107 lock_prdt_t* prdt, /*!< in: MBR on the old page */ 108 lock_prdt_t* new_prdt, /*!< in: MBR on the new page */ 109 const page_id_t page_id); /*!< in: page number */ 110 111 /**************************************************************//** 112 Ajust locks from an ancester page of Rtree on the appropriate level . */ 113 void 114 lock_prdt_update_parent( 115 /*====================*/ 116 buf_block_t* left_block, /*!< in/out: page to be split */ 117 buf_block_t* right_block, /*!< in/out: the new half page */ 118 lock_prdt_t* left_prdt, /*!< in: MBR on the old page */ 119 lock_prdt_t* right_prdt, /*!< in: MBR on the new page */ 120 const page_id_t page_id); /*!< in: parent page */ 121 122 /*********************************************************************//** 123 Checks if locks of other transactions prevent an immediate insert of 124 a predicate record. 125 @return DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK */ 126 dberr_t 127 lock_prdt_insert_check_and_lock( 128 /*============================*/ 129 ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is 130 set, does nothing */ 131 const rec_t* rec, /*!< in: record after which to insert */ 132 buf_block_t* block, /*!< in/out: buffer block of rec */ 133 dict_index_t* index, /*!< in: index */ 134 que_thr_t* thr, /*!< in: query thread */ 135 mtr_t* mtr, /*!< in/out: mini-transaction */ 136 lock_prdt_t* prdt); /*!< in: Minimum Bound Rectangle */ 137 138 /*********************************************************************//** 139 Append a predicate to the lock */ 140 void 141 lock_prdt_set_prdt( 142 /*===============*/ 143 lock_t* lock, /*!< in: lock */ 144 const lock_prdt_t* prdt); /*!< in: Predicate */ 145 146 #if 0 147 148 /*********************************************************************//** 149 Checks if a predicate lock request for a new lock has to wait for 150 request lock2. 151 @return true if new lock has to wait for lock2 to be removed */ 152 UNIV_INLINE 153 bool 154 lock_prdt_has_to_wait( 155 /*==================*/ 156 const trx_t* trx, /*!< in: trx of new lock */ 157 unsigned type_mode,/*!< in: precise mode of the new lock 158 to set: LOCK_S or LOCK_X, possibly 159 ORed to LOCK_PREDICATE or LOCK_PRDT_PAGE, 160 LOCK_INSERT_INTENTION */ 161 lock_prdt_t* prdt, /*!< in: lock predicate to check */ 162 const lock_t* lock2); /*!< in: another record lock; NOTE that 163 it is assumed that this has a lock bit 164 set on the same record as in the new 165 lock we are setting */ 166 167 /*********************************************************************//** 168 Get predicate lock's minimum bounding box 169 @return the minimum bounding box*/ 170 UNIV_INLINE 171 rtr_mbr_t* 172 prdt_get_mbr_from_prdt( 173 /*===================*/ 174 const lock_prdt_t* prdt); /*!< in: the lock predicate */ 175 176 177 #endif 178 /*************************************************************//** 179 Moves the locks of a record to another record and resets the lock bits of 180 the donating record. */ 181 void 182 lock_prdt_rec_move( 183 /*===============*/ 184 const buf_block_t* receiver, /*!< in: buffer block containing 185 the receiving record */ 186 const buf_block_t* donator); /*!< in: buffer block containing 187 the donating record */ 188 189 /** Check whether there are R-tree Page lock on a page 190 @param[in] trx trx to test the lock 191 @param[in] page_id page identifier 192 @return true if there is none */ 193 bool lock_test_prdt_page_lock(const trx_t *trx, const page_id_t page_id); 194 195 /** Removes predicate lock objects set on an index page which is discarded. 196 @param[in] block page to be discarded 197 @param[in] lock_hash lock hash */ 198 void 199 lock_prdt_page_free_from_discard( 200 /*=============================*/ 201 const buf_block_t* block, 202 hash_table_t* lock_hash); 203 204 #endif 205