1/*****************************************************************************
2
3Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, 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/row0ins.h
22Insert into a table
23
24Created 4/20/1996 Heikki Tuuri
25*******************************************************/
26
27#ifndef row0ins_h
28#define row0ins_h
29
30#include "univ.i"
31#include "data0data.h"
32#include "que0types.h"
33#include "dict0types.h"
34#include "trx0types.h"
35#include "row0types.h"
36
37/***************************************************************//**
38Checks if foreign key constraint fails for an index entry. Sets shared locks
39which lock either the success or the failure of the constraint. NOTE that
40the caller must have a shared latch on dict_foreign_key_check_lock.
41@return DB_SUCCESS, DB_LOCK_WAIT, DB_NO_REFERENCED_ROW, or
42DB_ROW_IS_REFERENCED */
43dberr_t
44row_ins_check_foreign_constraint(
45/*=============================*/
46 ibool check_ref,/*!< in: TRUE If we want to check that
47 the referenced table is ok, FALSE if we
48 want to check the foreign key table */
49 dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
50 tables mentioned in it must be in the
51 dictionary cache if they exist at all */
52 dict_table_t* table, /*!< in: if check_ref is TRUE, then the foreign
53 table, else the referenced table */
54 dtuple_t* entry, /*!< in: index entry for index */
55 que_thr_t* thr) /*!< in: query thread */
56 MY_ATTRIBUTE((nonnull, warn_unused_result));
57/*********************************************************************//**
58Creates an insert node struct.
59@return own: insert node struct */
60ins_node_t*
61ins_node_create(
62/*============*/
63 ulint ins_type, /*!< in: INS_VALUES, ... */
64 dict_table_t* table, /*!< in: table where to insert */
65 mem_heap_t* heap); /*!< in: mem heap where created */
66/*********************************************************************//**
67Sets a new row to insert for an INS_DIRECT node. This function is only used
68if we have constructed the row separately, which is a rare case; this
69function is quite slow. */
70void
71ins_node_set_new_row(
72/*=================*/
73 ins_node_t* node, /*!< in: insert node */
74 dtuple_t* row); /*!< in: new row (or first row) for the node */
75/***************************************************************//**
76Tries to insert an entry into a clustered index, ignoring foreign key
77constraints. If a record with the same unique key is found, the other
78record is necessarily marked deleted by a committed transaction, or a
79unique key violation error occurs. The delete marked record is then
80updated to an existing record, and we must write an undo log record on
81the delete marked record.
82@retval DB_SUCCESS on success
83@retval DB_LOCK_WAIT on lock wait when !(flags & BTR_NO_LOCKING_FLAG)
84@retval DB_FAIL if retry with BTR_MODIFY_TREE is needed
85@return error code */
86dberr_t
87row_ins_clust_index_entry_low(
88/*==========================*/
89 ulint flags, /*!< in: undo logging and locking flags */
90 ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
91 depending on whether we wish optimistic or
92 pessimistic descent down the index tree */
93 dict_index_t* index, /*!< in: clustered index */
94 ulint n_uniq, /*!< in: 0 or index->n_uniq */
95 dtuple_t* entry, /*!< in/out: index entry to insert */
96 ulint n_ext, /*!< in: number of externally stored columns */
97 que_thr_t* thr, /*!< in: query thread or NULL */
98 bool dup_chk_only)
99 /*!< in: if true, just do duplicate check
100 and return. don't execute actual insert. */
101 MY_ATTRIBUTE((warn_unused_result));
102
103/***************************************************************//**
104Tries to insert an entry into a secondary index. If a record with exactly the
105same fields is found, the other record is necessarily marked deleted.
106It is then unmarked. Otherwise, the entry is just inserted to the index.
107@retval DB_SUCCESS on success
108@retval DB_LOCK_WAIT on lock wait when !(flags & BTR_NO_LOCKING_FLAG)
109@retval DB_FAIL if retry with BTR_MODIFY_TREE is needed
110@return error code */
111dberr_t
112row_ins_sec_index_entry_low(
113/*========================*/
114 ulint flags, /*!< in: undo logging and locking flags */
115 ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
116 depending on whether we wish optimistic or
117 pessimistic descent down the index tree */
118 dict_index_t* index, /*!< in: secondary index */
119 mem_heap_t* offsets_heap,
120 /*!< in/out: memory heap that can be emptied */
121 mem_heap_t* heap, /*!< in/out: memory heap */
122 dtuple_t* entry, /*!< in/out: index entry to insert */
123 trx_id_t trx_id, /*!< in: PAGE_MAX_TRX_ID during
124 row_log_table_apply(), or 0 */
125 que_thr_t* thr, /*!< in: query thread */
126 bool dup_chk_only)
127 /*!< in: if true, just do duplicate check
128 and return. don't execute actual insert. */
129 MY_ATTRIBUTE((warn_unused_result));
130/** Sets the values of the dtuple fields in entry from the values of appropriate
131columns in row.
132@param[in] index index handler
133@param[out] entry index entry to make
134@param[in] row row */
135dberr_t
136row_ins_index_entry_set_vals(
137 const dict_index_t* index,
138 dtuple_t* entry,
139 const dtuple_t* row);
140
141/***************************************************************//**
142Inserts an entry into a clustered index. Tries first optimistic,
143then pessimistic descent down the tree. If the entry matches enough
144to a delete marked record, performs the insert by updating or delete
145unmarking the delete marked record.
146@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
147dberr_t
148row_ins_clust_index_entry(
149/*======================*/
150 dict_index_t* index, /*!< in: clustered index */
151 dtuple_t* entry, /*!< in/out: index entry to insert */
152 que_thr_t* thr, /*!< in: query thread */
153 ulint n_ext, /*!< in: number of externally stored columns */
154 bool dup_chk_only)
155 /*!< in: if true, just do duplicate check
156 and return. don't execute actual insert. */
157 MY_ATTRIBUTE((warn_unused_result));
158/***************************************************************//**
159Inserts an entry into a secondary index. Tries first optimistic,
160then pessimistic descent down the tree. If the entry matches enough
161to a delete marked record, performs the insert by updating or delete
162unmarking the delete marked record.
163@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
164dberr_t
165row_ins_sec_index_entry(
166/*====================*/
167 dict_index_t* index, /*!< in: secondary index */
168 dtuple_t* entry, /*!< in/out: index entry to insert */
169 que_thr_t* thr, /*!< in: query thread */
170 bool dup_chk_only)
171 /*!< in: if true, just do duplicate check
172 and return. don't execute actual insert. */
173 MY_ATTRIBUTE((warn_unused_result));
174/***********************************************************//**
175Inserts a row to a table. This is a high-level function used in
176SQL execution graphs.
177@return query thread to run next or NULL */
178que_thr_t*
179row_ins_step(
180/*=========*/
181 que_thr_t* thr); /*!< in: query thread */
182
183/* Insert node structure */
184
185struct ins_node_t{
186 que_common_t common; /*!< node type: QUE_NODE_INSERT */
187 ulint ins_type;/* INS_VALUES, INS_SEARCHED, or INS_DIRECT */
188 dtuple_t* row; /*!< row to insert */
189 dict_table_t* table; /*!< table where to insert */
190 sel_node_t* select; /*!< select in searched insert */
191 que_node_t* values_list;/* list of expressions to evaluate and
192 insert in an INS_VALUES insert */
193 ulint state; /*!< node execution state */
194 dict_index_t* index; /*!< NULL, or the next index where the index
195 entry should be inserted */
196 dtuple_t* entry; /*!< NULL, or entry to insert in the index;
197 after a successful insert of the entry,
198 this should be reset to NULL */
199 UT_LIST_BASE_NODE_T(dtuple_t)
200 entry_list;/* list of entries, one for each index */
201 /** buffer for the system columns */
202 byte sys_buf[DATA_ROW_ID_LEN
203 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
204 trx_id_t trx_id; /*!< trx id or the last trx which executed the
205 node */
206 byte vers_start_buf[8]; /* Buffers for System Versioning */
207 byte vers_end_buf[8]; /* system fields. */
208 mem_heap_t* entry_sys_heap;
209 /* memory heap used as auxiliary storage;
210 entry_list and sys fields are stored here;
211 if this is NULL, entry list should be created
212 and buffers for sys fields in row allocated */
213 dict_index_t* duplicate;
214 /* This is the first index that reported
215 DB_DUPLICATE_KEY. Used in the case of REPLACE
216 or INSERT ... ON DUPLICATE UPDATE. */
217 ulint magic_n;
218};
219
220#define INS_NODE_MAGIC_N 15849075
221
222/* Insert node types */
223#define INS_SEARCHED 0 /* INSERT INTO ... SELECT ... */
224#define INS_VALUES 1 /* INSERT INTO ... VALUES ... */
225#define INS_DIRECT 2 /* this is for internal use in dict0crea:
226 insert the row directly */
227
228/* Node execution states */
229#define INS_NODE_SET_IX_LOCK 1 /* we should set an IX lock on table */
230#define INS_NODE_ALLOC_ROW_ID 2 /* row id should be allocated */
231#define INS_NODE_INSERT_ENTRIES 3 /* index entries should be built and
232 inserted */
233#endif
234