00001 /****************************************************** 00002 Update of a row 00003 00004 (c) 1996 Innobase Oy 00005 00006 Created 12/27/1996 Heikki Tuuri 00007 *******************************************************/ 00008 00009 #ifndef row0upd_h 00010 #define row0upd_h 00011 00012 #include "univ.i" 00013 #include "data0data.h" 00014 #include "btr0types.h" 00015 #include "btr0pcur.h" 00016 #include "dict0types.h" 00017 #include "trx0types.h" 00018 #include "que0types.h" 00019 #include "row0types.h" 00020 #include "pars0types.h" 00021 00022 /************************************************************************* 00023 Creates an update vector object. */ 00024 UNIV_INLINE 00025 upd_t* 00026 upd_create( 00027 /*=======*/ 00028 /* out, own: update vector object */ 00029 ulint n, /* in: number of fields */ 00030 mem_heap_t* heap); /* in: heap from which memory allocated */ 00031 /************************************************************************* 00032 Returns the number of fields in the update vector == number of columns 00033 to be updated by an update vector. */ 00034 UNIV_INLINE 00035 ulint 00036 upd_get_n_fields( 00037 /*=============*/ 00038 /* out: number of fields */ 00039 upd_t* update); /* in: update vector */ 00040 /************************************************************************* 00041 Returns the nth field of an update vector. */ 00042 UNIV_INLINE 00043 upd_field_t* 00044 upd_get_nth_field( 00045 /*==============*/ 00046 /* out: update vector field */ 00047 upd_t* update, /* in: update vector */ 00048 ulint n); /* in: field position in update vector */ 00049 /************************************************************************* 00050 Sets an index field number to be updated by an update vector field. */ 00051 UNIV_INLINE 00052 void 00053 upd_field_set_field_no( 00054 /*===================*/ 00055 upd_field_t* upd_field, /* in: update vector field */ 00056 ulint field_no, /* in: field number in a clustered 00057 index */ 00058 dict_index_t* index, /* in: index */ 00059 trx_t* trx); /* in: transaction */ 00060 /************************************************************************* 00061 Writes into the redo log the values of trx id and roll ptr and enough info 00062 to determine their positions within a clustered index record. */ 00063 00064 byte* 00065 row_upd_write_sys_vals_to_log( 00066 /*==========================*/ 00067 /* out: new pointer to mlog */ 00068 dict_index_t* index, /* in: clustered index */ 00069 trx_t* trx, /* in: transaction */ 00070 dulint roll_ptr,/* in: roll ptr of the undo log record */ 00071 byte* log_ptr,/* pointer to a buffer of size > 20 opened 00072 in mlog */ 00073 mtr_t* mtr); /* in: mtr */ 00074 /************************************************************************* 00075 Updates the trx id and roll ptr field in a clustered index record when 00076 a row is updated or marked deleted. */ 00077 UNIV_INLINE 00078 void 00079 row_upd_rec_sys_fields( 00080 /*===================*/ 00081 rec_t* rec, /* in: record */ 00082 dict_index_t* index, /* in: clustered index */ 00083 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 00084 trx_t* trx, /* in: transaction */ 00085 dulint roll_ptr);/* in: roll ptr of the undo log record */ 00086 /************************************************************************* 00087 Sets the trx id or roll ptr field of a clustered index entry. */ 00088 00089 void 00090 row_upd_index_entry_sys_field( 00091 /*==========================*/ 00092 dtuple_t* entry, /* in: index entry, where the memory buffers 00093 for sys fields are already allocated: 00094 the function just copies the new values to 00095 them */ 00096 dict_index_t* index, /* in: clustered index */ 00097 ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */ 00098 dulint val); /* in: value to write */ 00099 /************************************************************************* 00100 Creates an update node for a query graph. */ 00101 00102 upd_node_t* 00103 upd_node_create( 00104 /*============*/ 00105 /* out, own: update node */ 00106 mem_heap_t* heap); /* in: mem heap where created */ 00107 /*************************************************************** 00108 Writes to the redo log the new values of the fields occurring in the index. */ 00109 00110 void 00111 row_upd_index_write_log( 00112 /*====================*/ 00113 upd_t* update, /* in: update vector */ 00114 byte* log_ptr,/* in: pointer to mlog buffer: must contain at least 00115 MLOG_BUF_MARGIN bytes of free space; the buffer is 00116 closed within this function */ 00117 mtr_t* mtr); /* in: mtr into whose log to write */ 00118 /*************************************************************** 00119 Returns TRUE if row update changes size of some field in index or if some 00120 field to be updated is stored externally in rec or update. */ 00121 00122 ibool 00123 row_upd_changes_field_size_or_external( 00124 /*===================================*/ 00125 /* out: TRUE if the update changes the size of 00126 some field in index or the field is external 00127 in rec or update */ 00128 dict_index_t* index, /* in: index */ 00129 const ulint* offsets,/* in: rec_get_offsets(rec, index) */ 00130 upd_t* update);/* in: update vector */ 00131 /*************************************************************** 00132 Replaces the new column values stored in the update vector to the record 00133 given. No field size changes are allowed. This function is used only for 00134 a clustered index */ 00135 00136 void 00137 row_upd_rec_in_place( 00138 /*=================*/ 00139 rec_t* rec, /* in/out: record where replaced */ 00140 const ulint* offsets,/* in: array returned by rec_get_offsets() */ 00141 upd_t* update);/* in: update vector */ 00142 /******************************************************************* 00143 Builds an update vector from those fields which in a secondary index entry 00144 differ from a record that has the equal ordering fields. NOTE: we compare 00145 the fields as binary strings! */ 00146 00147 upd_t* 00148 row_upd_build_sec_rec_difference_binary( 00149 /*====================================*/ 00150 /* out, own: update vector of differing 00151 fields */ 00152 dict_index_t* index, /* in: index */ 00153 dtuple_t* entry, /* in: entry to insert */ 00154 rec_t* rec, /* in: secondary index record */ 00155 trx_t* trx, /* in: transaction */ 00156 mem_heap_t* heap); /* in: memory heap from which allocated */ 00157 /******************************************************************* 00158 Builds an update vector from those fields, excluding the roll ptr and 00159 trx id fields, which in an index entry differ from a record that has 00160 the equal ordering fields. NOTE: we compare the fields as binary strings! */ 00161 00162 upd_t* 00163 row_upd_build_difference_binary( 00164 /*============================*/ 00165 /* out, own: update vector of differing 00166 fields, excluding roll ptr and trx id */ 00167 dict_index_t* index, /* in: clustered index */ 00168 dtuple_t* entry, /* in: entry to insert */ 00169 ulint* ext_vec,/* in: array containing field numbers of 00170 externally stored fields in entry, or NULL */ 00171 ulint n_ext_vec,/* in: number of fields in ext_vec */ 00172 rec_t* rec, /* in: clustered index record */ 00173 trx_t* trx, /* in: transaction */ 00174 mem_heap_t* heap); /* in: memory heap from which allocated */ 00175 /*************************************************************** 00176 Replaces the new column values stored in the update vector to the index entry 00177 given. */ 00178 00179 void 00180 row_upd_index_replace_new_col_vals_index_pos( 00181 /*=========================================*/ 00182 dtuple_t* entry, /* in/out: index entry where replaced */ 00183 dict_index_t* index, /* in: index; NOTE that this may also be a 00184 non-clustered index */ 00185 upd_t* update, /* in: an update vector built for the index so 00186 that the field number in an upd_field is the 00187 index position */ 00188 ibool order_only, 00189 /* in: if TRUE, limit the replacement to 00190 ordering fields of index; note that this 00191 does not work for non-clustered indexes. */ 00192 mem_heap_t* heap); /* in: memory heap to which we allocate and 00193 copy the new values, set this as NULL if you 00194 do not want allocation */ 00195 /*************************************************************** 00196 Replaces the new column values stored in the update vector to the index entry 00197 given. */ 00198 00199 void 00200 row_upd_index_replace_new_col_vals( 00201 /*===============================*/ 00202 dtuple_t* entry, /* in/out: index entry where replaced */ 00203 dict_index_t* index, /* in: index; NOTE that this may also be a 00204 non-clustered index */ 00205 upd_t* update, /* in: an update vector built for the 00206 CLUSTERED index so that the field number in 00207 an upd_field is the clustered index position */ 00208 mem_heap_t* heap); /* in: memory heap to which we allocate and 00209 copy the new values, set this as NULL if you 00210 do not want allocation */ 00211 /*************************************************************** 00212 Checks if an update vector changes an ordering field of an index record. 00213 This function is fast if the update vector is short or the number of ordering 00214 fields in the index is small. Otherwise, this can be quadratic. 00215 NOTE: we compare the fields as binary strings! */ 00216 00217 ibool 00218 row_upd_changes_ord_field_binary( 00219 /*=============================*/ 00220 /* out: TRUE if update vector changes 00221 an ordering field in the index record; 00222 NOTE: the fields are compared as binary 00223 strings */ 00224 dtuple_t* row, /* in: old value of row, or NULL if the 00225 row and the data values in update are not 00226 known when this function is called, e.g., at 00227 compile time */ 00228 dict_index_t* index, /* in: index of the record */ 00229 upd_t* update);/* in: update vector for the row; NOTE: the 00230 field numbers in this MUST be clustered index 00231 positions! */ 00232 /*************************************************************** 00233 Checks if an update vector changes an ordering field of an index record. 00234 This function is fast if the update vector is short or the number of ordering 00235 fields in the index is small. Otherwise, this can be quadratic. 00236 NOTE: we compare the fields as binary strings! */ 00237 00238 ibool 00239 row_upd_changes_some_index_ord_field_binary( 00240 /*========================================*/ 00241 /* out: TRUE if update vector may change 00242 an ordering field in an index record */ 00243 dict_table_t* table, /* in: table */ 00244 upd_t* update);/* in: update vector for the row */ 00245 /*************************************************************** 00246 Updates a row in a table. This is a high-level function used 00247 in SQL execution graphs. */ 00248 00249 que_thr_t* 00250 row_upd_step( 00251 /*=========*/ 00252 /* out: query thread to run next or NULL */ 00253 que_thr_t* thr); /* in: query thread */ 00254 /************************************************************************* 00255 Performs an in-place update for the current clustered index record in 00256 select. */ 00257 00258 void 00259 row_upd_in_place_in_select( 00260 /*=======================*/ 00261 sel_node_t* sel_node, /* in: select node */ 00262 que_thr_t* thr, /* in: query thread */ 00263 mtr_t* mtr); /* in: mtr */ 00264 /************************************************************************* 00265 Parses the log data of system field values. */ 00266 00267 byte* 00268 row_upd_parse_sys_vals( 00269 /*===================*/ 00270 /* out: log data end or NULL */ 00271 byte* ptr, /* in: buffer */ 00272 byte* end_ptr,/* in: buffer end */ 00273 ulint* pos, /* out: TRX_ID position in record */ 00274 dulint* trx_id, /* out: trx id */ 00275 dulint* roll_ptr);/* out: roll ptr */ 00276 /************************************************************************* 00277 Updates the trx id and roll ptr field in a clustered index record in database 00278 recovery. */ 00279 00280 void 00281 row_upd_rec_sys_fields_in_recovery( 00282 /*===============================*/ 00283 rec_t* rec, /* in: record */ 00284 const ulint* offsets,/* in: array returned by rec_get_offsets() */ 00285 ulint pos, /* in: TRX_ID position in rec */ 00286 dulint trx_id, /* in: transaction id */ 00287 dulint roll_ptr);/* in: roll ptr of the undo log record */ 00288 /************************************************************************* 00289 Parses the log data written by row_upd_index_write_log. */ 00290 00291 byte* 00292 row_upd_index_parse( 00293 /*================*/ 00294 /* out: log data end or NULL */ 00295 byte* ptr, /* in: buffer */ 00296 byte* end_ptr,/* in: buffer end */ 00297 mem_heap_t* heap, /* in: memory heap where update vector is 00298 built */ 00299 upd_t** update_out);/* out: update vector */ 00300 00301 00302 /* Update vector field */ 00303 struct upd_field_struct{ 00304 ulint field_no; /* field number in an index, usually 00305 the clustered index, but in updating 00306 a secondary index record in btr0cur.c 00307 this is the position in the secondary 00308 index */ 00309 que_node_t* exp; /* expression for calculating a new 00310 value: it refers to column values and 00311 constants in the symbol table of the 00312 query graph */ 00313 dfield_t new_val; /* new value for the column */ 00314 ibool extern_storage; /* this is set to TRUE if dfield 00315 actually contains a reference to 00316 an externally stored field */ 00317 }; 00318 00319 /* Update vector structure */ 00320 struct upd_struct{ 00321 ulint info_bits; /* new value of info bits to record; 00322 default is 0 */ 00323 ulint n_fields; /* number of update fields */ 00324 upd_field_t* fields; /* array of update fields */ 00325 }; 00326 00327 /* Update node structure which also implements the delete operation 00328 of a row */ 00329 00330 struct upd_node_struct{ 00331 que_common_t common; /* node type: QUE_NODE_UPDATE */ 00332 ibool is_delete;/* TRUE if delete, FALSE if update */ 00333 ibool searched_update; 00334 /* TRUE if searched update, FALSE if 00335 positioned */ 00336 ibool select_will_do_update; 00337 /* TRUE if a searched update where ordering 00338 fields will not be updated, and the size of 00339 the fields will not change: in this case the 00340 select node will take care of the update */ 00341 ibool in_mysql_interface; 00342 /* TRUE if the update node was created 00343 for the MySQL interface */ 00344 dict_foreign_t* foreign;/* NULL or pointer to a foreign key 00345 constraint if this update node is used in 00346 doing an ON DELETE or ON UPDATE operation */ 00347 upd_node_t* cascade_node;/* NULL or an update node template which 00348 is used to implement ON DELETE/UPDATE CASCADE 00349 or ... SET NULL for foreign keys */ 00350 mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade 00351 node is created */ 00352 sel_node_t* select; /* query graph subtree implementing a base 00353 table cursor: the rows returned will be 00354 updated */ 00355 btr_pcur_t* pcur; /* persistent cursor placed on the clustered 00356 index record which should be updated or 00357 deleted; the cursor is stored in the graph 00358 of 'select' field above, except in the case 00359 of the MySQL interface */ 00360 dict_table_t* table; /* table where updated */ 00361 upd_t* update; /* update vector for the row */ 00362 ulint update_n_fields; 00363 /* when this struct is used to implement 00364 a cascade operation for foreign keys, we store 00365 here the size of the buffer allocated for use 00366 as the update vector */ 00367 sym_node_list_t columns;/* symbol table nodes for the columns 00368 to retrieve from the table */ 00369 ibool has_clust_rec_x_lock; 00370 /* TRUE if the select which retrieves the 00371 records to update already sets an x-lock on 00372 the clustered record; note that it must always 00373 set at least an s-lock */ 00374 ulint cmpl_info;/* information extracted during query 00375 compilation; speeds up execution: 00376 UPD_NODE_NO_ORD_CHANGE and 00377 UPD_NODE_NO_SIZE_CHANGE, ORed */ 00378 /*----------------------*/ 00379 /* Local storage for this graph node */ 00380 ulint state; /* node execution state */ 00381 dict_index_t* index; /* NULL, or the next index whose record should 00382 be updated */ 00383 dtuple_t* row; /* NULL, or a copy (also fields copied to 00384 heap) of the row to update; this must be reset 00385 to NULL after a successful update */ 00386 ulint* ext_vec;/* array describing which fields are stored 00387 externally in the clustered index record of 00388 row */ 00389 ulint n_ext_vec;/* number of fields in ext_vec */ 00390 mem_heap_t* heap; /* memory heap used as auxiliary storage; 00391 this must be emptied after a successful 00392 update */ 00393 /*----------------------*/ 00394 sym_node_t* table_sym;/* table node in symbol table */ 00395 que_node_t* col_assign_list; 00396 /* column assignment list */ 00397 ulint magic_n; 00398 }; 00399 00400 #define UPD_NODE_MAGIC_N 1579975 00401 00402 /* Node execution states */ 00403 #define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from 00404 a node above and if the field 00405 has_clust_rec_x_lock is FALSE, we 00406 should set an intention x-lock on 00407 the table */ 00408 #define UPD_NODE_UPDATE_CLUSTERED 2 /* clustered index record should be 00409 updated */ 00410 #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be 00411 inserted, old record is already delete 00412 marked */ 00413 #define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered 00414 index record was changed, or this is 00415 a delete operation: should update 00416 all the secondary index records */ 00417 #define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be 00418 looked at and updated if an ordering 00419 field changed */ 00420 00421 /* Compilation info flags: these must fit within 3 bits; see trx0rec.h */ 00422 #define UPD_NODE_NO_ORD_CHANGE 1 /* no secondary index record will be 00423 changed in the update and no ordering 00424 field of the clustered index */ 00425 #define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be 00426 changed in the update */ 00427 00428 #ifndef UNIV_NONINL 00429 #include "row0upd.ic" 00430 #endif 00431 00432 #endif
1.4.7

