1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/row0ins.h
29 Insert into a table
30 
31 Created 4/20/1996 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef row0ins_h
35 #define row0ins_h
36 
37 #include "univ.i"
38 #include "data0data.h"
39 #include "que0types.h"
40 #include "dict0types.h"
41 #include "trx0types.h"
42 #include "row0types.h"
43 
44 /***************************************************************//**
45 Checks if foreign key constraint fails for an index entry. Sets shared locks
46 which lock either the success or the failure of the constraint. NOTE that
47 the caller must have a shared latch on dict_foreign_key_check_lock.
48 @return DB_SUCCESS, DB_LOCK_WAIT, DB_NO_REFERENCED_ROW, or
49 DB_ROW_IS_REFERENCED */
50 UNIV_INTERN
51 dberr_t
52 row_ins_check_foreign_constraint(
53 /*=============================*/
54 	ibool		check_ref,/*!< in: TRUE If we want to check that
55 				the referenced table is ok, FALSE if we
56 				want to check the foreign key table */
57 	dict_foreign_t*	foreign,/*!< in: foreign constraint; NOTE that the
58 				tables mentioned in it must be in the
59 				dictionary cache if they exist at all */
60 	dict_table_t*	table,	/*!< in: if check_ref is TRUE, then the foreign
61 				table, else the referenced table */
62 	dtuple_t*	entry,	/*!< in: index entry for index */
63 	que_thr_t*	thr)	/*!< in: query thread */
64 	MY_ATTRIBUTE((nonnull, warn_unused_result));
65 /*********************************************************************//**
66 Creates an insert node struct.
67 @return	own: insert node struct */
68 UNIV_INTERN
69 ins_node_t*
70 ins_node_create(
71 /*============*/
72 	ulint		ins_type,	/*!< in: INS_VALUES, ... */
73 	dict_table_t*	table,		/*!< in: table where to insert */
74 	mem_heap_t*	heap);		/*!< in: mem heap where created */
75 /*********************************************************************//**
76 Sets a new row to insert for an INS_DIRECT node. This function is only used
77 if we have constructed the row separately, which is a rare case; this
78 function is quite slow. */
79 UNIV_INTERN
80 void
81 ins_node_set_new_row(
82 /*=================*/
83 	ins_node_t*	node,	/*!< in: insert node */
84 	dtuple_t*	row);	/*!< in: new row (or first row) for the node */
85 /***************************************************************//**
86 Tries to insert an entry into a clustered index, ignoring foreign key
87 constraints. If a record with the same unique key is found, the other
88 record is necessarily marked deleted by a committed transaction, or a
89 unique key violation error occurs. The delete marked record is then
90 updated to an existing record, and we must write an undo log record on
91 the delete marked record.
92 @retval DB_SUCCESS on success
93 @retval DB_LOCK_WAIT on lock wait when !(flags & BTR_NO_LOCKING_FLAG)
94 @retval DB_FAIL if retry with BTR_MODIFY_TREE is needed
95 @return error code */
96 UNIV_INTERN
97 dberr_t
98 row_ins_clust_index_entry_low(
99 /*==========================*/
100 	ulint		flags,	/*!< in: undo logging and locking flags */
101 	ulint		mode,	/*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
102 				depending on whether we wish optimistic or
103 				pessimistic descent down the index tree */
104 	dict_index_t*	index,	/*!< in: clustered index */
105 	ulint		n_uniq,	/*!< in: 0 or index->n_uniq */
106 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
107 	ulint		n_ext,	/*!< in: number of externally stored columns */
108 	que_thr_t*	thr)	/*!< in: query thread or NULL */
109 	MY_ATTRIBUTE((nonnull, warn_unused_result));
110 /***************************************************************//**
111 Tries to insert an entry into a secondary index. If a record with exactly the
112 same fields is found, the other record is necessarily marked deleted.
113 It is then unmarked. Otherwise, the entry is just inserted to the index.
114 @retval DB_SUCCESS on success
115 @retval DB_LOCK_WAIT on lock wait when !(flags & BTR_NO_LOCKING_FLAG)
116 @retval DB_FAIL if retry with BTR_MODIFY_TREE is needed
117 @return error code */
118 UNIV_INTERN
119 dberr_t
120 row_ins_sec_index_entry_low(
121 /*========================*/
122 	ulint		flags,	/*!< in: undo logging and locking flags */
123 	ulint		mode,	/*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
124 				depending on whether we wish optimistic or
125 				pessimistic descent down the index tree */
126 	dict_index_t*	index,	/*!< in: secondary index */
127 	mem_heap_t*	offsets_heap,
128 				/*!< in/out: memory heap that can be emptied */
129 	mem_heap_t*	heap,	/*!< in/out: memory heap */
130 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
131 	trx_id_t	trx_id,	/*!< in: PAGE_MAX_TRX_ID during
132 				row_log_table_apply(), or 0 */
133 	que_thr_t*	thr)	/*!< in: query thread */
134 	MY_ATTRIBUTE((nonnull, warn_unused_result));
135 /***************************************************************//**
136 Tries to insert the externally stored fields (off-page columns)
137 of a clustered index entry.
138 @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
139 UNIV_INTERN
140 dberr_t
141 row_ins_index_entry_big_rec_func(
142 /*=============================*/
143 	const dtuple_t*		entry,	/*!< in/out: index entry to insert */
144 	const big_rec_t*	big_rec,/*!< in: externally stored fields */
145 	ulint*			offsets,/*!< in/out: rec offsets */
146 	mem_heap_t**		heap,	/*!< in/out: memory heap */
147 	dict_index_t*		index,	/*!< in: index */
148 	const char*		file,	/*!< in: file name of caller */
149 #ifndef DBUG_OFF
150 	const void*		thd,	/*!< in: connection, or NULL */
151 #endif /* DBUG_OFF */
152 	ulint			line)	/*!< in: line number of caller */
153 	MY_ATTRIBUTE((nonnull(1,2,3,4,5,6), warn_unused_result));
154 #ifdef DBUG_OFF
155 # define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd,file,line) \
156 	row_ins_index_entry_big_rec_func(e,big,ofs,heap,index,file,line)
157 #else /* DBUG_OFF */
158 # define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd,file,line) \
159 	row_ins_index_entry_big_rec_func(e,big,ofs,heap,index,file,thd,line)
160 #endif /* DBUG_OFF */
161 /***************************************************************//**
162 Inserts an entry into a clustered index. Tries first optimistic,
163 then pessimistic descent down the tree. If the entry matches enough
164 to a delete marked record, performs the insert by updating or delete
165 unmarking the delete marked record.
166 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
167 UNIV_INTERN
168 dberr_t
169 row_ins_clust_index_entry(
170 /*======================*/
171 	dict_index_t*	index,	/*!< in: clustered index */
172 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
173 	que_thr_t*	thr,	/*!< in: query thread */
174 	ulint		n_ext)	/*!< in: number of externally stored columns */
175 	MY_ATTRIBUTE((nonnull, warn_unused_result));
176 /***************************************************************//**
177 Inserts an entry into a secondary index. Tries first optimistic,
178 then pessimistic descent down the tree. If the entry matches enough
179 to a delete marked record, performs the insert by updating or delete
180 unmarking the delete marked record.
181 @return	DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
182 UNIV_INTERN
183 dberr_t
184 row_ins_sec_index_entry(
185 /*====================*/
186 	dict_index_t*	index,	/*!< in: secondary index */
187 	dtuple_t*	entry,	/*!< in/out: index entry to insert */
188 	que_thr_t*	thr)	/*!< in: query thread */
189 	MY_ATTRIBUTE((nonnull, warn_unused_result));
190 /***********************************************************//**
191 Inserts a row to a table. This is a high-level function used in
192 SQL execution graphs.
193 @return	query thread to run next or NULL */
194 UNIV_INTERN
195 que_thr_t*
196 row_ins_step(
197 /*=========*/
198 	que_thr_t*	thr);	/*!< in: query thread */
199 
200 /* Insert node structure */
201 
202 struct ins_node_t{
203 	que_common_t	common;	/*!< node type: QUE_NODE_INSERT */
204 	ulint		ins_type;/* INS_VALUES, INS_SEARCHED, or INS_DIRECT */
205 	dtuple_t*	row;	/*!< row to insert */
206 	dict_table_t*	table;	/*!< table where to insert */
207 	sel_node_t*	select;	/*!< select in searched insert */
208 	que_node_t*	values_list;/* list of expressions to evaluate and
209 				insert in an INS_VALUES insert */
210 	ulint		state;	/*!< node execution state */
211 	dict_index_t*	index;	/*!< NULL, or the next index where the index
212 				entry should be inserted */
213 	dtuple_t*	entry;	/*!< NULL, or entry to insert in the index;
214 				after a successful insert of the entry,
215 				this should be reset to NULL */
216 	UT_LIST_BASE_NODE_T(dtuple_t)
217 			entry_list;/* list of entries, one for each index */
218 	byte*		row_id_buf;/* buffer for the row id sys field in row */
219 	trx_id_t	trx_id;	/*!< trx id or the last trx which executed the
220 				node */
221 	byte*		trx_id_buf;/* buffer for the trx id sys field in row */
222 	mem_heap_t*	entry_sys_heap;
223 				/* memory heap used as auxiliary storage;
224 				entry_list and sys fields are stored here;
225 				if this is NULL, entry list should be created
226 				and buffers for sys fields in row allocated */
227 	ulint		magic_n;
228 };
229 
230 #define	INS_NODE_MAGIC_N	15849075
231 
232 /* Insert node types */
233 #define INS_SEARCHED	0	/* INSERT INTO ... SELECT ... */
234 #define INS_VALUES	1	/* INSERT INTO ... VALUES ... */
235 #define INS_DIRECT	2	/* this is for internal use in dict0crea:
236 				insert the row directly */
237 
238 /* Node execution states */
239 #define	INS_NODE_SET_IX_LOCK	1	/* we should set an IX lock on table */
240 #define INS_NODE_ALLOC_ROW_ID	2	/* row id should be allocated */
241 #define	INS_NODE_INSERT_ENTRIES 3	/* index entries should be built and
242 					inserted */
243 
244 #ifndef UNIV_NONINL
245 #include "row0ins.ic"
246 #endif
247 
248 #endif
249