1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/pars0sym.h
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
*******************************************************/
#ifndef pars0sym_h
#define pars0sym_h
#include "que0types.h"
#include "pars0types.h"
#include "row0types.h"
/******************************************************************//**
Creates a symbol table for a single stored procedure or query.
@return own: symbol table */
sym_tab_t*
sym_tab_create(
/*===========*/
mem_heap_t* heap); /*!< in: memory heap where to create */
/******************************************************************//**
Frees the memory allocated dynamically AFTER parsing phase for variables
etc. in the symbol table. Does not free the mem heap where the table was
originally created. Frees also SQL explicit cursor definitions. */
void
sym_tab_free_private(
/*=================*/
sym_tab_t* sym_tab); /*!< in, own: symbol table */
/******************************************************************//**
Adds an integer literal to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_int_lit(
/*================*/
sym_tab_t* sym_tab, /*!< in: symbol table */
ulint val); /*!< in: integer value */
/******************************************************************//**
Adds an string literal to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_str_lit(
/*================*/
sym_tab_t* sym_tab, /*!< in: symbol table */
const byte* str, /*!< in: string with no quotes around
it */
ulint len); /*!< in: string length */
/******************************************************************//**
Add a bound literal to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_bound_lit(
/*==================*/
sym_tab_t* sym_tab, /*!< in: symbol table */
const char* name, /*!< in: name of bound literal */
ulint* lit_type); /*!< out: type of literal (PARS_*_LIT) */
/**********************************************************************
Rebind literal to a node in the symbol table. */
sym_node_t*
sym_tab_rebind_lit(
/*===============*/
/* out: symbol table node */
sym_node_t* node, /* in: node that is bound to literal*/
const void* address, /* in: pointer to data */
ulint length); /* in: length of data */
/******************************************************************//**
Adds an SQL null literal to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_null_lit(
/*=================*/
sym_tab_t* sym_tab); /*!< in: symbol table */
/******************************************************************//**
Adds an identifier to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_id(
/*===========*/
sym_tab_t* sym_tab, /*!< in: symbol table */
byte* name, /*!< in: identifier name */
ulint len); /*!< in: identifier length */
/******************************************************************//**
Add a bound identifier to a symbol table.
@return symbol table node */
sym_node_t*
sym_tab_add_bound_id(
/*===========*/
sym_tab_t* sym_tab, /*!< in: symbol table */
const char* name); /*!< in: name of bound id */
/** Index of sym_node_t::field_nos corresponding to the clustered index */
#define SYM_CLUST_FIELD_NO 0
/** Index of sym_node_t::field_nos corresponding to a secondary index */
#define SYM_SEC_FIELD_NO 1
/** Types of a symbol table node */
enum sym_tab_entry {
SYM_UNSET, /*!< Unset entry. */
SYM_VAR = 91, /*!< declared parameter or local
variable of a procedure */
SYM_IMPLICIT_VAR, /*!< storage for a intermediate result
of a calculation */
SYM_LIT, /*!< literal */
SYM_TABLE_REF_COUNTED, /*!< database table name, ref counted. Must
be closed explicitly. */
SYM_TABLE, /*!< database table name */
SYM_COLUMN, /*!< database table name */
SYM_CURSOR, /*!< named cursor */
SYM_PROCEDURE_NAME, /*!< stored procedure name */
SYM_INDEX, /*!< database index name */
SYM_FUNCTION /*!< user function name */
};
/** Symbol table node */
struct sym_node_t{
que_common_t common; /*!< node type:
QUE_NODE_SYMBOL */
/* NOTE: if the data field in 'common.val' is not NULL and the symbol
table node is not for a temporary column, the memory for the value has
been allocated from dynamic memory and it should be freed when the
symbol table is discarded */
/* 'alias' and 'indirection' are almost the same, but not quite.
'alias' always points to the primary instance of the variable, while
'indirection' does the same only if we should use the primary
instance's values for the node's data. This is usually the case, but
when initializing a cursor (e.g., "DECLARE CURSOR c IS SELECT * FROM
t WHERE id = x;"), we copy the values from the primary instance to
the cursor's instance so that they are fixed for the duration of the
cursor, and set 'indirection' to NULL. If we did not, the value of
'x' could change between fetches and things would break horribly.
TODO: It would be cleaner to make 'indirection' a boolean field and
always use 'alias' to refer to the primary node. */
sym_node_t* indirection; /*!< pointer to
another symbol table
node which contains
the value for this
node, NULL otherwise */
sym_node_t* alias; /*!< pointer to
another symbol table
node for which this
node is an alias,
NULL otherwise */
UT_LIST_NODE_T(sym_node_t) col_var_list; /*!< list of table
columns or a list of
input variables for an
explicit cursor */
ibool copy_val; /*!< TRUE if a column
and its value should
be copied to dynamic
memory when fetched */
ulint field_nos[2]; /*!< if a column, in
the position
SYM_CLUST_FIELD_NO is
the field number in the
clustered index; in
the position
SYM_SEC_FIELD_NO
the field number in the
non-clustered index to
use first; if not found
from the index, then
ULINT_UNDEFINED */
ibool resolved; /*!< TRUE if the
meaning of a variable
or a column has been
resolved; for literals
this is always TRUE */
enum sym_tab_entry token_type; /*!< type of the
parsed token */
const char* name; /*!< name of an id */
ulint name_len; /*!< id name length */
dict_table_t* table; /*!< table definition
if a table id or a
column id */
ulint col_no; /*!< column number if a
column */
sel_buf_t* prefetch_buf; /*!< NULL, or a buffer
for cached column
values for prefetched
rows */
sel_node_t* cursor_def; /*!< cursor definition
select node if a
named cursor */
ulint param_type; /*!< PARS_INPUT,
PARS_OUTPUT, or
PARS_NOT_PARAM if not a
procedure parameter */
sym_tab_t* sym_table; /*!< back pointer to
the symbol table */
UT_LIST_NODE_T(sym_node_t) sym_list; /*!< list of symbol
nodes */
sym_node_t* like_node; /* LIKE operator node*/
};
/** Symbol table */
struct sym_tab_t{
que_t* query_graph;
/*!< query graph generated by the
parser */
const char* sql_string;
/*!< SQL string to parse */
size_t string_len;
/*!< SQL string length */
size_t next_char_pos;
/*!< position of the next character in
sql_string to give to the lexical
analyzer */
pars_info_t* info; /*!< extra information, or NULL */
sym_node_list_t sym_list;
/*!< list of symbol nodes in the symbol
table */
UT_LIST_BASE_NODE_T(func_node_t)
func_node_list;
/*!< list of function nodes in the
parsed query graph */
mem_heap_t* heap; /*!< memory heap from which we can
allocate space */
};
#endif
|