1
by brian
clean slate |
1 |
/******************************************************
|
2 |
Insert into a table
|
|
3 |
||
4 |
(c) 1996 Innobase Oy
|
|
5 |
||
6 |
Created 4/20/1996 Heikki Tuuri
|
|
7 |
*******************************************************/
|
|
8 |
||
9 |
#ifndef row0ins_h
|
|
10 |
#define row0ins_h
|
|
11 |
||
12 |
#include "univ.i" |
|
13 |
#include "data0data.h" |
|
14 |
#include "que0types.h" |
|
15 |
#include "dict0types.h" |
|
16 |
#include "trx0types.h" |
|
17 |
#include "row0types.h" |
|
18 |
||
19 |
/*******************************************************************
|
|
20 |
Checks if foreign key constraint fails for an index entry. Sets shared locks
|
|
21 |
which lock either the success or the failure of the constraint. NOTE that
|
|
22 |
the caller must have a shared latch on dict_foreign_key_check_lock. */
|
|
23 |
||
24 |
ulint
|
|
25 |
row_ins_check_foreign_constraint( |
|
26 |
/*=============================*/
|
|
27 |
/* out: DB_SUCCESS, DB_LOCK_WAIT,
|
|
28 |
DB_NO_REFERENCED_ROW,
|
|
29 |
or DB_ROW_IS_REFERENCED */
|
|
30 |
ibool check_ref,/* in: TRUE If we want to check that |
|
31 |
the referenced table is ok, FALSE if we
|
|
32 |
want to to check the foreign key table */
|
|
33 |
dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the |
|
34 |
tables mentioned in it must be in the
|
|
35 |
dictionary cache if they exist at all */
|
|
36 |
dict_table_t* table, /* in: if check_ref is TRUE, then the foreign |
|
37 |
table, else the referenced table */
|
|
38 |
dtuple_t* entry, /* in: index entry for index */ |
|
39 |
que_thr_t* thr); /* in: query thread */ |
|
40 |
/*************************************************************************
|
|
41 |
Creates an insert node struct. */
|
|
42 |
||
43 |
ins_node_t* |
|
44 |
ins_node_create( |
|
45 |
/*============*/
|
|
46 |
/* out, own: insert node struct */
|
|
47 |
ulint ins_type, /* in: INS_VALUES, ... */ |
|
48 |
dict_table_t* table, /* in: table where to insert */ |
|
49 |
mem_heap_t* heap); /* in: mem heap where created */ |
|
50 |
/*************************************************************************
|
|
51 |
Sets a new row to insert for an INS_DIRECT node. This function is only used
|
|
52 |
if we have constructed the row separately, which is a rare case; this
|
|
53 |
function is quite slow. */
|
|
54 |
||
55 |
void
|
|
56 |
ins_node_set_new_row( |
|
57 |
/*=================*/
|
|
58 |
ins_node_t* node, /* in: insert node */ |
|
59 |
dtuple_t* row); /* in: new row (or first row) for the node */ |
|
60 |
/*******************************************************************
|
|
61 |
Tries to insert an index entry to an index. If the index is clustered
|
|
62 |
and a record with the same unique key is found, the other record is
|
|
63 |
necessarily marked deleted by a committed transaction, or a unique key
|
|
64 |
violation error occurs. The delete marked record is then updated to an
|
|
65 |
existing record, and we must write an undo log record on the delete
|
|
66 |
marked record. If the index is secondary, and a record with exactly the
|
|
67 |
same fields is found, the other record is necessarily marked deleted.
|
|
68 |
It is then unmarked. Otherwise, the entry is just inserted to the index. */
|
|
69 |
||
70 |
ulint
|
|
71 |
row_ins_index_entry_low( |
|
72 |
/*====================*/
|
|
73 |
/* out: DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL
|
|
74 |
if pessimistic retry needed, or error code */
|
|
75 |
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, |
|
76 |
depending on whether we wish optimistic or
|
|
77 |
pessimistic descent down the index tree */
|
|
78 |
dict_index_t* index, /* in: index */ |
|
79 |
dtuple_t* entry, /* in: index entry to insert */ |
|
80 |
ulint* ext_vec,/* in: array containing field numbers of |
|
81 |
externally stored fields in entry, or NULL */
|
|
82 |
ulint n_ext_vec,/* in: number of fields in ext_vec */ |
|
83 |
que_thr_t* thr); /* in: query thread */ |
|
84 |
/*******************************************************************
|
|
85 |
Inserts an index entry to index. Tries first optimistic, then pessimistic
|
|
86 |
descent down the tree. If the entry matches enough to a delete marked record,
|
|
87 |
performs the insert by updating or delete unmarking the delete marked
|
|
88 |
record. */
|
|
89 |
||
90 |
ulint
|
|
91 |
row_ins_index_entry( |
|
92 |
/*================*/
|
|
93 |
/* out: DB_SUCCESS, DB_LOCK_WAIT,
|
|
94 |
DB_DUPLICATE_KEY, or some other error code */
|
|
95 |
dict_index_t* index, /* in: index */ |
|
96 |
dtuple_t* entry, /* in: index entry to insert */ |
|
97 |
ulint* ext_vec,/* in: array containing field numbers of |
|
98 |
externally stored fields in entry, or NULL */
|
|
99 |
ulint n_ext_vec,/* in: number of fields in ext_vec */ |
|
100 |
que_thr_t* thr); /* in: query thread */ |
|
101 |
/***************************************************************
|
|
102 |
Inserts a row to a table. */
|
|
103 |
||
104 |
ulint
|
|
105 |
row_ins( |
|
106 |
/*====*/
|
|
107 |
/* out: DB_SUCCESS if operation successfully
|
|
108 |
completed, else error code or DB_LOCK_WAIT */
|
|
109 |
ins_node_t* node, /* in: row insert node */ |
|
110 |
que_thr_t* thr); /* in: query thread */ |
|
111 |
/***************************************************************
|
|
112 |
Inserts a row to a table. This is a high-level function used in
|
|
113 |
SQL execution graphs. */
|
|
114 |
||
115 |
que_thr_t* |
|
116 |
row_ins_step( |
|
117 |
/*=========*/
|
|
118 |
/* out: query thread to run next or NULL */
|
|
119 |
que_thr_t* thr); /* in: query thread */ |
|
120 |
||
121 |
/* Insert node structure */
|
|
122 |
||
123 |
struct ins_node_struct{ |
|
124 |
que_common_t common; /* node type: QUE_NODE_INSERT */ |
|
125 |
ulint ins_type;/* INS_VALUES, INS_SEARCHED, or INS_DIRECT */ |
|
126 |
dtuple_t* row; /* row to insert */ |
|
127 |
dict_table_t* table; /* table where to insert */ |
|
128 |
sel_node_t* select; /* select in searched insert */ |
|
129 |
que_node_t* values_list;/* list of expressions to evaluate and |
|
130 |
insert in an INS_VALUES insert */
|
|
131 |
ulint state; /* node execution state */ |
|
132 |
dict_index_t* index; /* NULL, or the next index where the index |
|
133 |
entry should be inserted */
|
|
134 |
dtuple_t* entry; /* NULL, or entry to insert in the index; |
|
135 |
after a successful insert of the entry,
|
|
136 |
this should be reset to NULL */
|
|
137 |
UT_LIST_BASE_NODE_T(dtuple_t) |
|
138 |
entry_list;/* list of entries, one for each index */ |
|
139 |
byte* row_id_buf;/* buffer for the row id sys field in row */ |
|
140 |
dulint trx_id; /* trx id or the last trx which executed the |
|
141 |
node */
|
|
142 |
byte* trx_id_buf;/* buffer for the trx id sys field in row */ |
|
143 |
mem_heap_t* entry_sys_heap; |
|
144 |
/* memory heap used as auxiliary storage;
|
|
145 |
entry_list and sys fields are stored here;
|
|
146 |
if this is NULL, entry list should be created
|
|
147 |
and buffers for sys fields in row allocated */
|
|
148 |
ulint magic_n; |
|
149 |
};
|
|
150 |
||
151 |
#define INS_NODE_MAGIC_N 15849075
|
|
152 |
||
153 |
/* Insert node types */
|
|
154 |
#define INS_SEARCHED 0 /* INSERT INTO ... SELECT ... */ |
|
155 |
#define INS_VALUES 1 /* INSERT INTO ... VALUES ... */ |
|
156 |
#define INS_DIRECT 2 /* this is for internal use in dict0crea: |
|
157 |
insert the row directly */
|
|
158 |
||
159 |
/* Node execution states */
|
|
160 |
#define INS_NODE_SET_IX_LOCK 1 /* we should set an IX lock on table */ |
|
161 |
#define INS_NODE_ALLOC_ROW_ID 2 /* row id should be allocated */ |
|
162 |
#define INS_NODE_INSERT_ENTRIES 3 /* index entries should be built and |
|
163 |
inserted */
|
|
164 |
||
165 |
#ifndef UNIV_NONINL
|
|
166 |
#include "row0ins.ic" |
|
167 |
#endif
|
|
168 |
||
169 |
#endif
|