~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/row0sel.h

  • Committer: Monty Taylor
  • Date: 2009-03-08 23:45:12 UTC
  • mto: (923.2.1 mordred)
  • mto: This revision was merged to the branch mainline in revision 921.
  • Revision ID: mordred@inaugust.com-20090308234512-tqkygxtu1iaig23s
Removed C99 isnan() usage, which allows us to remove the util/math.{cc,h} workarounds. Yay for standards!

Show diffs side-by-side

added added

removed removed

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