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