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