/** Global variable used to denote the '*' in SELECT * FROM.. */
ulint pars_star_denoter = 12345678;
/********************************************************************
Get user function with the given name.*/
UNIV_INLINE
pars_user_func_t*
pars_info_lookup_user_func( /*=======================*/ /* out: user func, or NULL if not
found */
pars_info_t* info, /* in: info struct */ constchar* name) /* in: function name to find*/
{ if (info && info->funcs) {
ulint i;
ib_vector_t* vec = info->funcs;
for (i = 0; i < ib_vector_size(vec); i++) {
pars_user_func_t* puf;
if (strcmp(puf->name, name) == 0) { return(puf);
}
}
}
return(NULL);
}
/********************************************************************
Get bound identifier with the given name.*/
UNIV_INLINE
pars_bound_id_t*
pars_info_lookup_bound_id( /*======================*/ /* out: bound literal, or NULL if
not found */
pars_info_t* info, /* in: info struct */ constchar* name) /* in: bound literal name to find */
{ if (info && info->bound_ids) {
ulint i;
ib_vector_t* vec = info->bound_ids;
for (i = 0; i < ib_vector_size(vec); i++) {
pars_bound_id_t* bid;
if (strcmp(bid->name, name) == 0) { return(bid);
}
}
}
return(NULL);
}
/********************************************************************
Get bound literal with the given name.*/
UNIV_INLINE
pars_bound_lit_t*
pars_info_lookup_bound_lit( /*=======================*/ /* out: bound literal, or NULL if
not found */
pars_info_t* info, /* in: info struct */ constchar* name) /* in: bound literal name to find */
{ if (info && info->bound_lits) {
ulint i;
ib_vector_t* vec = info->bound_lits;
for (i = 0; i < ib_vector_size(vec); i++) {
pars_bound_lit_t* pbl;
if (strcmp(pbl->name, name) == 0) { return(pbl);
}
}
}
return(NULL);
}
/*********************************************************************//**
Determines the class of a function code.
@return function class: PARS_FUNC_ARITH, ... */ static
ulint
pars_func_get_class( /*================*/ int func) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
{ switch (func) { case'+': case'-': case'*': case'/': return(PARS_FUNC_ARITH);
case'=': case'<': case'>': case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN: return(PARS_FUNC_CMP);
case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN: return(PARS_FUNC_LOGICAL);
case PARS_COUNT_TOKEN: return(PARS_FUNC_AGGREGATE);
case PARS_TO_BINARY_TOKEN: case PARS_SUBSTR_TOKEN: case PARS_CONCAT_TOKEN: case PARS_LENGTH_TOKEN: case PARS_INSTR_TOKEN: case PARS_NOTFOUND_TOKEN: return(PARS_FUNC_PREDEFINED);
default: return(PARS_FUNC_OTHER);
}
}
/*********************************************************************//**
Parses an operatoror predefined function expression.
@return own: function node in a query tree */ static
func_node_t*
pars_func_low( /*==========*/ int func, /*!< in: function token code */
que_node_t* arg) /*!< in: first argument in the argument list */
{
func_node_t* node;
/*********************************************************************//**
Parses a function expression.
@return own: function node in a query tree */
func_node_t*
pars_func( /*======*/
que_node_t* res_word,/*!< in: function name reserved word */
que_node_t* arg) /*!< in: first argument in the argument list */
{ return(pars_func_low(((pars_res_word_t*) res_word)->code, arg));
}
/************************************************************************* RebindaLIKEsearchstring.NOTE:Weignoreany'%'charactersembedded
within the search string.*/ int
pars_like_rebind( /*=============*/ /* out, own: function node in a query tree */
sym_node_t* node, /* in: The search string node.*/ const byte* ptr, /* in: literal to (re) bind */
ulint ptr_len)/* in: length of literal to (re) bind*/
{
dtype_t* dtype;
dfield_t* dfield;
ib_like_t op_check;
sym_node_t* like_node;
sym_node_t* str_node = NULL;
ib_like_t op = IB_LIKE_EXACT; int func = PARS_LIKE_TOKEN_EXACT;
/* Is this a STRING% ? */ if (ptr[ptr_len - 1] == '%') {
op = IB_LIKE_PREFIX;
}
/* Is this a '%STRING' or %STRING% ?*/
ut_ad(*ptr != '%');
if (node->like_node == NULL) { /* Add the LIKE operator info node to the node list. Thiswillbeusedduringthecomparisonphasetodetermine
how to match.*/
like_node = sym_tab_add_int_lit(node->sym_table, op);
que_node_list_add_last(NULL, like_node);
node->like_node = like_node;
str_node = sym_tab_add_str_lit(node->sym_table, ptr, ptr_len);
que_node_list_add_last(like_node, str_node);
} else {
like_node = node->like_node;
/* Change the value of the string in the existing
string node of like node */
str_node = static_cast<sym_node_t*>(
que_node_list_get_last(like_node));
/* Must find the string node */
ut_a(str_node);
ut_a(str_node != like_node);
ut_a(str_node->token_type == SYM_LIT);
/* Adjust the length of the search value so the '%' is not visible.Thencreateandaddasearchstringnodetothe searchvaluenode.Searchingfor%SUFFIXand%SUBSTR%requires afulltablescanandsowesetthesearchvalueto''.
For PREFIX% we simply remove the trailing '%'.*/
/*************************************************************************
Parses a LIKE operator expression. */ static int
pars_like_op( /*=========*/ /* out, own: function node in a query tree */
que_node_t* arg) /* in: LIKE comparison string.*/
{ char* ptr;
ulint ptr_len; int func = PARS_LIKE_TOKEN_EXACT;
dfield_t* dfield = que_node_get_val(arg);
dtype_t* dtype = dfield_get_type(dfield);
return(func);
} /*********************************************************************//**
Parses an operator expression.
@return own: function node in a query tree */
func_node_t*
pars_op( /*====*/ int func, /*!< in: operator token code */
que_node_t* arg1, /*!< in: first argument */
que_node_t* arg2) /*!< in: second argument or NULL for an unary
operator */
{
que_node_list_add_last(NULL, arg1);
if (arg2) {
que_node_list_add_last(arg1, arg2);
}
/* We need to parse the string and determine whether it's a
PREFIX, SUFFIX or SUBSTRING comparison */ if (func == PARS_LIKE_TOKEN) {
/*********************************************************************//**
Parses an ORDER BY clause. Order by a single column only is supported.
@return own: order-by node in a query tree */
order_node_t*
pars_order_by( /*==========*/
sym_node_t* column, /*!< in: column name */
pars_res_word_t* asc) /*!< in: &pars_asc_token or pars_desc_token */
{
order_node_t* node;
/*********************************************************************//**
Determine if a data type is a built-in string data type of the InnoDB
SQL parser.
@returnTRUEif string data type */ static
ibool
pars_is_string_type( /*================*/
ulint mtype) /*!< in: main data type */
{ switch (mtype) { case DATA_VARCHAR: case DATA_CHAR: case DATA_FIXBINARY: case DATA_BINARY: return(TRUE);
}
return(FALSE);
}
/*********************************************************************//**
Resolves the data type of a function in an expression. The argument data
types must already be resolved. */ static void
pars_resolve_func_data_type( /*========================*/
func_node_t* node) /*!< in: function node */
{
que_node_t* arg;
ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
arg = node->args;
switch (node->func) { case'+': case'-': case'*': case'/': /* Inherit the data type from the first argument (which must
not be the SQL null literal whose type is DATA_ERROR) */
case PARS_COUNT_TOKEN:
ut_a(arg);
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4); break;
case PARS_TO_BINARY_TOKEN: if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
DATA_ENGLISH, 0);
} else {
dtype_set(que_node_get_data_type(node), DATA_BINARY, 0, 0);
} break;
case PARS_LENGTH_TOKEN: case PARS_INSTR_TOKEN:
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4); break;
case PARS_SUBSTR_TOKEN: case PARS_CONCAT_TOKEN:
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
DATA_ENGLISH, 0); break;
case'>': case'<': case'=': case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN: case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN: case PARS_NOTFOUND_TOKEN:
/* We currently have no iboolean type: use integer type */
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4); break;
case PARS_LIKE_TOKEN_EXACT: case PARS_LIKE_TOKEN_PREFIX: case PARS_LIKE_TOKEN_SUFFIX: case PARS_LIKE_TOKEN_SUBSTR:
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
DATA_ENGLISH, 0); break;
default:
ut_error;
}
}
/*********************************************************************//**
Resolves the meaning of variables in an expression and the data types of
functions. It is an error if some identifier cannot be resolved here. */ static void
pars_resolve_exp_variables_and_types( /*=================================*/
sel_node_t* select_node, /*!< in: select node or NULL; if thisisnotNULLthenthevariable symnodesareaddedtothe
copy_variables list of select_node */
que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
sym_node_t* sym_node;
sym_node_t* node;
ut_a(exp_node);
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
func_node = static_cast<func_node_t*>(exp_node);
arg = func_node->args;
while (arg) {
pars_resolve_exp_variables_and_types(select_node, arg);
/*********************************************************************//**
Resolves the meaning of variables in an expression list. It is an error if
some identifier cannot be resolved here. Resolves also the data types of
functions. */ static void
pars_resolve_exp_list_variables_and_types( /*======================================*/
sel_node_t* select_node, /*!< in: select node or NULL */
que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{ while (exp_node) {
pars_resolve_exp_variables_and_types(select_node, exp_node);
exp_node = que_node_get_next(exp_node);
}
}
/*********************************************************************//**
Resolves the columns in an expression. */ static void
pars_resolve_exp_columns( /*=====================*/
sym_node_t* table_node, /*!< in: first node in a table list */
que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
sym_node_t* sym_node;
dict_table_t* table;
sym_node_t* t_node;
ulint n_cols;
ulint i;
ut_a(exp_node);
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
func_node = static_cast<func_node_t*>(exp_node);
arg = func_node->args;
while (arg) {
pars_resolve_exp_columns(table_node, arg);
/*********************************************************************//**
Resolves the meaning of columns in an expression list. */ static void
pars_resolve_exp_list_columns( /*==========================*/
sym_node_t* table_node, /*!< in: first node in a table list */
que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{ while (exp_node) {
pars_resolve_exp_columns(table_node, exp_node);
exp_node = que_node_get_next(exp_node);
}
}
/*********************************************************************//**
Retrieves the table definition for a table name id. */ static void
pars_retrieve_table_def( /*====================*/
sym_node_t* sym_node) /*!< in: table node */
{
ut_a(sym_node);
ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
/* Open the table only if it is not already opened. */ if (sym_node->token_type != SYM_TABLE_REF_COUNTED) {
/*********************************************************************//**
Retrieves the table definitions for a list of table name ids.
@return number of tables */ static
ulint
pars_retrieve_table_list_defs( /*==========================*/
sym_node_t* sym_node) /*!< in: first table node in list */
{
ulint count = 0;
while (sym_node) {
pars_retrieve_table_def(sym_node);
/*********************************************************************//**
Adds all columns to the select list if the query is SELECT * FROM ... */ static void
pars_select_all_columns( /*====================*/
sel_node_t* select_node) /*!< in: select node already containing
the table list */
{
sym_node_t* col_node;
sym_node_t* table_node;
dict_table_t* table;
ulint i;
select_node->select_list = NULL;
table_node = select_node->table_list;
while (table_node) {
table = table_node->table;
for (i = 0; i < dict_table_get_n_user_cols(table); i++) { const Lex_ident_column col_name = dict_table_get_col_name(
table, i);
/*********************************************************************//**
Parses a select list; creates a query graph node for the whole SELECT
statement.
@return own: select node in a query tree */
sel_node_t*
pars_select_list( /*=============*/
que_node_t* select_list, /*!< in: select list */
sym_node_t* into_list) /*!< in: variables list or NULL */
{
sel_node_t* node;
/*********************************************************************//**
Checks if the query is an aggregate query, in which case the selct list must
contain only aggregate function items. */ static void
pars_check_aggregate( /*=================*/
sel_node_t* select_node) /*!< in: select node already containing
the select list */
{
que_node_t* exp_node;
func_node_t* func_node;
ulint n_nodes = 0;
ulint n_aggregate_nodes = 0;
exp_node = select_node->select_list;
while (exp_node) {
n_nodes++;
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
func_node = static_cast<func_node_t*>(exp_node);
if (func_node->fclass == PARS_FUNC_AGGREGATE) {
n_aggregate_nodes++;
}
}
exp_node = que_node_get_next(exp_node);
}
if (n_aggregate_nodes > 0) {
ut_a(n_nodes == n_aggregate_nodes);
/*********************************************************************//**
Parses a function declaration.
@return sym_node */
que_node_t*
pars_function_declaration( /*======================*/
sym_node_t* sym_node) /*!< in: function id node in the symbol
table */
{
sym_node->resolved = TRUE;
sym_node->token_type = SYM_FUNCTION;
/* Check that the function exists. */
ut_a(pars_info_lookup_user_func(
pars_sym_tab_global->info, sym_node->name));
return(sym_node);
}
/*********************************************************************//**
Parses a deleteor update statement start.
@return own: update node in a query tree */
upd_node_t*
pars_update_statement_start( /*========================*/
ibool is_delete, /*!< in: TRUE if delete */
sym_node_t* table_sym, /*!< in: table name node */
col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
if delete */
{
upd_node_t* node;
/*********************************************************************//**
Set the type of a dfield. */ static void
pars_set_dfield_type( /*=================*/
dfield_t* dfield, /*!< in: dfield */
pars_res_word_t* type, /*!< in: pointer to a type
token */
ulint len, /*!< in: length, or 0 */ bool is_not_null) /*!< in: whether the column is
NOT NULL. */
{
ulint flags = 0;
/*********************************************************************//**
Parses a variable declaration.
@return own: symbol table node of type SYM_VAR */
sym_node_t*
pars_variable_declaration( /*======================*/
sym_node_t* node, /*!< in: symbol table node allocated for the
id of the variable */
pars_res_word_t* type) /*!< in: pointer to a type token */
{
node->resolved = TRUE;
node->token_type = SYM_VAR;
/*********************************************************************//**
Sets the parent field in a query node list. */ static void
pars_set_parent_in_list( /*====================*/
que_node_t* node_list, /*!< in: first node in a list */
que_node_t* parent) /*!< in: parent value to set in all
nodes of the list */
{
que_common_t* common;
common = static_cast<que_common_t*>(node_list);
while (common) {
common->parent = parent;
common = static_cast<que_common_t*>(que_node_get_next(common));
}
}
/*********************************************************************//**
Parses a column definition at a table creation.
@return column sym table node */
sym_node_t*
pars_column_def( /*============*/
sym_node_t* sym_node, /*!< in: column node in the
symbol table */
pars_res_word_t* type, /*!< in: data type */
sym_node_t* len, /*!< in: length of column, or
NULL */ void* is_not_null) /*!< in: if not NULL, column
is of type NOT NULL. */
{
ulint len2;
/*********************************************************************//**
Parses an index creation operation.
@return index create subgraph */
ind_node_t*
pars_create_index( /*==============*/
pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
sym_node_t* index_sym, /*!< in: index name node in the symbol
table */
sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
sym_node_t* column_list) /*!< in: list of column names */
{
dict_index_t* index;
sym_node_t* column;
ind_node_t* node;
ulint n_fields;
ulint ind_type;
n_fields = que_node_list_get_len(column_list);
ind_type = 0;
if (unique_def) {
ind_type = ind_type | DICT_UNIQUE;
}
if (clustered_def) {
ind_type = ind_type | DICT_CLUSTERED;
}
index = dict_mem_index_create(NULL, index_sym->name,
ind_type, n_fields);
column = column_list;
while (column) {
dict_mem_index_add_field(index, column->name, 0);
/*************************************************************//**
Retrieves characters to the lexical analyzer. */ int
pars_get_lex_chars( /*===============*/ char* buf, /*!< in/out: buffer where to copy */
size_t max_size) /*!< in: maximum number of characters which fit
in the buffer */
{
size_t len = pars_sym_tab_global->string_len
- pars_sym_tab_global->next_char_pos; if (len == 0) { return(0);
}
except that the buffer is dynamically allocated from the info struct's
heap. */ void
pars_info_add_int4_literal( /*=======================*/
pars_info_t* info, /*!< in: info struct */ constchar* name, /*!< in: name */
ulint val) /*!< in: value */
{
byte* buf = static_cast<byte*>(mem_heap_alloc(info->heap, 4));
except that the buffer is dynamically allocated from the info struct's
heap. */ void
pars_info_add_ull_literal( /*======================*/
pars_info_t* info, /*!< in: info struct */ constchar* name, /*!< in: name */
ib_uint64_t val) /*!< in: value */
{
byte* buf = static_cast<byte*>(mem_heap_alloc(info->heap, 8));
/****************************************************************//** If the literal value already exists then it rebinds otherwise it
creates a new entry. */ void
pars_info_bind_ull_literal( /*=======================*/
pars_info_t* info, /*!< in: info struct */ constchar* name, /*!< in: name */ const ib_uint64_t* val) /*!< in: value */
{
pars_bound_lit_t* pbl;
/* Create a "new" element */
bid = static_cast<pars_bound_id_t*>(
ib_vector_push(info->bound_ids, NULL));
bid->name = name;
}
bid->id = id;
}
/********************************************************************
Get bound identifier with the given name.*/
pars_bound_id_t*
pars_info_get_bound_id( /*===================*/ /* out: bound id, or NULL if not
found */
pars_info_t* info, /* in: info struct */ constchar* name) /* in: bound id name to find */
{ return(pars_info_lookup_bound_id(info, name));
}
/****************************************************************//**
Get bound literal with the given name.
@return bound literal, or NULL ifnot found */
pars_bound_lit_t*
pars_info_get_bound_lit( /*====================*/
pars_info_t* info, /*!< in: info struct */ constchar* name) /*!< in: bound literal name to find */
{ return(pars_info_lookup_bound_lit(info, name));
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.30 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.