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