~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/******************************************************
2
Select
3
4
(c) 1997 Innobase Oy
5
6
Created 12/19/1997 Heikki Tuuri
7
*******************************************************/
8
9
#ifndef row0sel_h
10
#define row0sel_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
#include "que0types.h"
19
#include "pars0sym.h"
20
#include "btr0pcur.h"
21
#include "read0read.h"
22
#include "row0mysql.h"
23
24
/*************************************************************************
25
Creates a select node struct. */
26
27
sel_node_t*
28
sel_node_create(
29
/*============*/
30
				/* out, own: select node struct */
31
	mem_heap_t*	heap);	/* in: memory heap where created */
32
/*************************************************************************
33
Frees the memory private to a select node when a query graph is freed,
34
does not free the heap where the node was originally created. */
35
36
void
37
sel_node_free_private(
38
/*==================*/
39
	sel_node_t*	node);	/* in: select node struct */
40
/*************************************************************************
41
Frees a prefetch buffer for a column, including the dynamically allocated
42
memory for data stored there. */
43
44
void
45
sel_col_prefetch_buf_free(
46
/*======================*/
47
	sel_buf_t*	prefetch_buf);	/* in, own: prefetch buffer */
48
/*************************************************************************
49
Gets the plan node for the nth table in a join. */
50
UNIV_INLINE
51
plan_t*
52
sel_node_get_nth_plan(
53
/*==================*/
54
	sel_node_t*	node,
55
	ulint		i);
56
/**************************************************************************
57
Performs a select step. This is a high-level function used in SQL execution
58
graphs. */
59
60
que_thr_t*
61
row_sel_step(
62
/*=========*/
63
				/* out: query thread to run next or NULL */
64
	que_thr_t*	thr);	/* in: query thread */
65
/**************************************************************************
66
Performs an execution step of an open or close cursor statement node. */
67
UNIV_INLINE
68
que_thr_t*
69
open_step(
70
/*======*/
71
				/* out: query thread to run next or NULL */
72
	que_thr_t*	thr);	/* in: query thread */
73
/**************************************************************************
74
Performs a fetch for a cursor. */
75
76
que_thr_t*
77
fetch_step(
78
/*=======*/
79
				/* out: query thread to run next or NULL */
80
	que_thr_t*	thr);	/* in: query thread */
81
/********************************************************************
82
Sample callback function for fetch that prints each row.*/
83
84
void*
85
row_fetch_print(
86
/*============*/
87
				/* out: always returns non-NULL */
88
	void*	row,		/* in:  sel_node_t* */
89
	void*	user_arg);	/* in:  not used */
90
/********************************************************************
91
Callback function for fetch that stores an unsigned 4 byte integer to the
92
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
93
= 4. */
94
95
void*
96
row_fetch_store_uint4(
97
/*==================*/
98
				/* out: always returns NULL */
99
	void*	row,		/* in:  sel_node_t* */
100
	void*	user_arg);	/* in:  data pointer */
101
/***************************************************************
102
Prints a row in a select result. */
103
104
que_thr_t*
105
row_printf_step(
106
/*============*/
107
				/* out: query thread to run next or NULL */
108
	que_thr_t*	thr);	/* in: query thread */
109
/********************************************************************
110
Converts a key value stored in MySQL format to an Innobase dtuple. The last
111
field of the key value may be just a prefix of a fixed length field: hence
112
the parameter key_len. But currently we do not allow search keys where the
113
last field is only a prefix of the full key field len and print a warning if
114
such appears. */
115
116
void
117
row_sel_convert_mysql_key_to_innobase(
118
/*==================================*/
119
	dtuple_t*	tuple,		/* in: tuple where to build;
120
					NOTE: we assume that the type info
121
					in the tuple is already according
122
					to index! */
123
	byte*		buf,		/* in: buffer to use in field
124
					conversions */
125
	ulint		buf_len,	/* in: buffer length */
126
	dict_index_t*	index,		/* in: index of the key value */
127
	byte*		key_ptr,	/* in: MySQL key value */
128
	ulint		key_len,	/* in: MySQL key value length */
129
	trx_t*		trx);		/* in: transaction */
130
/************************************************************************
131
Searches for rows in the database. This is used in the interface to
132
MySQL. This function opens a cursor, and also implements fetch next
133
and fetch prev. NOTE that if we do a search with a full key value
134
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
135
position and fetch next or fetch prev must not be tried to the cursor! */
136
137
ulint
138
row_search_for_mysql(
139
/*=================*/
140
					/* out: DB_SUCCESS,
141
					DB_RECORD_NOT_FOUND,
142
					DB_END_OF_INDEX, DB_DEADLOCK,
143
					DB_LOCK_TABLE_FULL,
144
					or DB_TOO_BIG_RECORD */
145
	byte*		buf,		/* in/out: buffer for the fetched
146
					row in the MySQL format */
147
	ulint		mode,		/* in: search mode PAGE_CUR_L, ... */
148
	row_prebuilt_t*	prebuilt,	/* in: prebuilt struct for the
149
					table handle; this contains the info
150
					of search_tuple, index; if search
151
					tuple contains 0 fields then we
152
					position the cursor at the start or
153
					the end of the index, depending on
154
					'mode' */
155
	ulint		match_mode,	/* in: 0 or ROW_SEL_EXACT or
156
					ROW_SEL_EXACT_PREFIX */
157
	ulint		direction);	/* in: 0 or ROW_SEL_NEXT or
158
					ROW_SEL_PREV; NOTE: if this is != 0,
159
					then prebuilt must have a pcur
160
					with stored position! In opening of a
161
					cursor 'direction' should be 0. */
162
/***********************************************************************
163
Checks if MySQL at the moment is allowed for this table to retrieve a
164
consistent read result, or store it to the query cache. */
165
166
ibool
167
row_search_check_if_query_cache_permitted(
168
/*======================================*/
169
					/* out: TRUE if storing or retrieving
170
					from the query cache is permitted */
171
	trx_t*		trx,		/* in: transaction object */
172
	const char*	norm_name);	/* in: concatenation of database name,
173
					'/' char, table name */
174
/***********************************************************************
175
Read the max AUTOINC value from an index. */
176
177
ulint
178
row_search_max_autoinc(
179
/*===================*/
180
					/* out: DB_SUCCESS if all OK else
181
					error code */
182
	dict_index_t*	index,		/* in: index to search */
183
	const char*	col_name,	/* in: autoinc column name */
184
	ib_longlong*	value);		/* out: AUTOINC value read */
185
186
/* A structure for caching column values for prefetched rows */
187
struct sel_buf_struct{
188
	byte*		data;	/* data, or NULL; if not NULL, this field
189
				has allocated memory which must be explicitly
190
				freed; can be != NULL even when len is
191
				UNIV_SQL_NULL */
192
	ulint		len;	/* data length or UNIV_SQL_NULL */
193
	ulint		val_buf_size;
194
				/* size of memory buffer allocated for data:
195
				this can be more than len; this is defined
196
				when data != NULL */
197
};
198
199
struct plan_struct{
200
	dict_table_t*	table;		/* table struct in the dictionary
201
					cache */
202
	dict_index_t*	index;		/* table index used in the search */
203
	btr_pcur_t	pcur;		/* persistent cursor used to search
204
					the index */
205
	ibool		asc;		/* TRUE if cursor traveling upwards */
206
	ibool		pcur_is_open;	/* TRUE if pcur has been positioned
207
					and we can try to fetch new rows */
208
	ibool		cursor_at_end;	/* TRUE if the cursor is open but
209
					we know that there are no more
210
					qualifying rows left to retrieve from
211
					the index tree; NOTE though, that
212
					there may still be unprocessed rows in
213
					the prefetch stack; always FALSE when
214
					pcur_is_open is FALSE */
215
	ibool		stored_cursor_rec_processed;
216
					/* TRUE if the pcur position has been
217
					stored and the record it is positioned
218
					on has already been processed */
219
	que_node_t**	tuple_exps;	/* array of expressions which are used
220
					to calculate the field values in the
221
					search tuple: there is one expression
222
					for each field in the search tuple */
223
	dtuple_t*	tuple;		/* search tuple */
224
	ulint		mode;		/* search mode: PAGE_CUR_G, ... */
225
	ulint		n_exact_match;	/* number of first fields in the search
226
					tuple which must be exactly matched */
227
	ibool		unique_search;	/* TRUE if we are searching an
228
					index record with a unique key */
229
	ulint		n_rows_fetched;	/* number of rows fetched using pcur
230
					after it was opened */
231
	ulint		n_rows_prefetched;/* number of prefetched rows cached
232
					for fetch: fetching several rows in
233
					the same mtr saves CPU time */
234
	ulint		first_prefetched;/* index of the first cached row in
235
					select buffer arrays for each column */
236
	ibool		no_prefetch;	/* no prefetch for this table */
237
	sym_node_list_t	columns;	/* symbol table nodes for the columns
238
					to retrieve from the table */
239
	UT_LIST_BASE_NODE_T(func_node_t)
240
			end_conds;	/* conditions which determine the
241
					fetch limit of the index segment we
242
					have to look at: when one of these
243
					fails, the result set has been
244
					exhausted for the cursor in this
245
					index; these conditions are normalized
246
					so that in a comparison the column
247
					for this table is the first argument */
248
	UT_LIST_BASE_NODE_T(func_node_t)
249
			other_conds;	/* the rest of search conditions we can
250
					test at this table in a join */
251
	ibool		must_get_clust;	/* TRUE if index is a non-clustered
252
					index and we must also fetch the
253
					clustered index record; this is the
254
					case if the non-clustered record does
255
					not contain all the needed columns, or
256
					if this is a single-table explicit
257
					cursor, or a searched update or
258
					delete */
259
	ulint*		clust_map;	/* map telling how clust_ref is built
260
					from the fields of a non-clustered
261
					record */
262
	dtuple_t*	clust_ref;	/* the reference to the clustered
263
					index entry is built here if index is
264
					a non-clustered index */
265
	btr_pcur_t	clust_pcur;	/* if index is non-clustered, we use
266
					this pcur to search the clustered
267
					index */
268
	mem_heap_t*	old_vers_heap;	/* memory heap used in building an old
269
					version of a row, or NULL */
270
};
271
272
struct sel_node_struct{
273
	que_common_t	common;		/* node type: QUE_NODE_SELECT */
274
	ulint		state;		/* node state */
275
	que_node_t*	select_list;	/* select list */
276
	sym_node_t*	into_list;	/* variables list or NULL */
277
	sym_node_t*	table_list;	/* table list */
278
	ibool		asc;		/* TRUE if the rows should be fetched
279
					in an ascending order */
280
	ibool		set_x_locks;	/* TRUE if the cursor is for update or
281
					delete, which means that a row x-lock
282
					should be placed on the cursor row */
283
	ibool		select_will_do_update;
284
					/* TRUE if the select is for a searched
285
					update which can be performed in-place:
286
					in this case the select will take care
287
					of the update */
288
	ulint		latch_mode;	/* BTR_SEARCH_LEAF, or BTR_MODIFY_LEAF
289
					if select_will_do_update is TRUE */
290
	ulint		row_lock_mode;	/* LOCK_X or LOCK_S */
291
	ulint		n_tables;	/* number of tables */
292
	ulint		fetch_table;	/* number of the next table to access
293
					in the join */
294
	plan_t*		plans;		/* array of n_tables many plan nodes
295
					containing the search plan and the
296
					search data structures */
297
	que_node_t*	search_cond;	/* search condition */
298
	read_view_t*	read_view;	/* if the query is a non-locking
299
					consistent read, its read view is
300
					placed here, otherwise NULL */
301
	ibool		consistent_read;/* TRUE if the select is a consistent,
302
					non-locking read */
303
	order_node_t*	order_by;	/* order by column definition, or
304
					NULL */
305
	ibool		is_aggregate;	/* TRUE if the select list consists of
306
					aggregate functions */
307
	ibool		aggregate_already_fetched;
308
					/* TRUE if the aggregate row has
309
					already been fetched for the current
310
					cursor */
311
	ibool		can_get_updated;/* this is TRUE if the select
312
					is in a single-table explicit
313
					cursor which can get updated
314
					within the stored procedure,
315
					or in a searched update or
316
					delete; NOTE that to determine
317
					of an explicit cursor if it
318
					can get updated, the parser
319
					checks from a stored procedure
320
					if it contains positioned
321
					update or delete statements */
322
	sym_node_t*	explicit_cursor;/* not NULL if an explicit cursor */
323
	UT_LIST_BASE_NODE_T(sym_node_t)
324
			copy_variables; /* variables whose values we have to
325
					copy when an explicit cursor is opened,
326
					so that they do not change between
327
					fetches */
328
};
329
330
/* Select node states */
331
#define	SEL_NODE_CLOSED		0	/* it is a declared cursor which is not
332
					currently open */
333
#define SEL_NODE_OPEN		1	/* intention locks not yet set on
334
					tables */
335
#define SEL_NODE_FETCH		2	/* intention locks have been set */
336
#define SEL_NODE_NO_MORE_ROWS	3	/* cursor has reached the result set
337
					end */
338
339
/* Fetch statement node */
340
struct fetch_node_struct{
341
	que_common_t	common;		/* type: QUE_NODE_FETCH */
342
	sel_node_t*	cursor_def;	/* cursor definition */
343
	sym_node_t*	into_list;	/* variables to set */
344
345
	pars_user_func_t*
346
			func;		/* User callback function or NULL.
347
					The first argument to the function
348
					is a sel_node_t*, containing the
349
					results of the SELECT operation for
350
					one row. If the function returns
351
					NULL, it is not interested in
352
					further rows and the cursor is
353
					modified so (cursor % NOTFOUND) is
354
					true. If it returns not-NULL,
355
					continue normally. See
356
					row_fetch_print() for an example
357
					(and a useful debugging tool). */
358
};
359
360
/* Open or close cursor statement node */
361
struct open_node_struct{
362
	que_common_t	common;		/* type: QUE_NODE_OPEN */
363
	ulint		op_type;	/* ROW_SEL_OPEN_CURSOR or
364
					ROW_SEL_CLOSE_CURSOR */
365
	sel_node_t*	cursor_def;	/* cursor definition */
366
};
367
368
/* Row printf statement node */
369
struct row_printf_node_struct{
370
	que_common_t	common;		/* type: QUE_NODE_ROW_PRINTF */
371
	sel_node_t*	sel_node;	/* select */
372
};
373
374
#define ROW_SEL_OPEN_CURSOR	0
375
#define ROW_SEL_CLOSE_CURSOR	1
376
377
/* Flags for the MySQL interface */
378
#define ROW_SEL_NEXT		1
379
#define ROW_SEL_PREV		2
380
381
#define ROW_SEL_EXACT		1	/* search using a complete key value */
382
#define ROW_SEL_EXACT_PREFIX	2	/* search using a key prefix which
383
					must match to rows: the prefix may
384
					contain an incomplete field (the
385
					last field in prefix may be just
386
					a prefix of a fixed length column) */
387
388
#ifndef UNIV_NONINL
389
#include "row0sel.ic"
390
#endif
391
392
#endif