summaryrefslogtreecommitdiff
path: root/storage/innobase/pars/pars0sym.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/pars/pars0sym.c')
-rw-r--r--storage/innobase/pars/pars0sym.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/storage/innobase/pars/pars0sym.c b/storage/innobase/pars/pars0sym.c
new file mode 100644
index 00000000000..8ade5579e47
--- /dev/null
+++ b/storage/innobase/pars/pars0sym.c
@@ -0,0 +1,237 @@
+/******************************************************
+SQL parser symbol table
+
+(c) 1997 Innobase Oy
+
+Created 12/15/1997 Heikki Tuuri
+*******************************************************/
+
+#include "pars0sym.h"
+
+#ifdef UNIV_NONINL
+#include "pars0sym.ic"
+#endif
+
+#include "mem0mem.h"
+#include "data0type.h"
+#include "data0data.h"
+#include "pars0pars.h"
+#include "que0que.h"
+#include "eval0eval.h"
+#include "row0sel.h"
+
+/**********************************************************************
+Creates a symbol table for a single stored procedure or query. */
+
+sym_tab_t*
+sym_tab_create(
+/*===========*/
+ /* out, own: symbol table */
+ mem_heap_t* heap) /* in: memory heap where to create */
+{
+ sym_tab_t* sym_tab;
+
+ sym_tab = mem_heap_alloc(heap, sizeof(sym_tab_t));
+
+ UT_LIST_INIT(sym_tab->sym_list);
+ UT_LIST_INIT(sym_tab->func_node_list);
+
+ sym_tab->heap = heap;
+
+ return(sym_tab);
+}
+
+/**********************************************************************
+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 */
+{
+ sym_node_t* sym;
+ func_node_t* func;
+
+ sym = UT_LIST_GET_FIRST(sym_tab->sym_list);
+
+ while (sym) {
+ eval_node_free_val_buf(sym);
+
+ if (sym->prefetch_buf) {
+ sel_col_prefetch_buf_free(sym->prefetch_buf);
+ }
+
+ if (sym->cursor_def) {
+ que_graph_free_recursive(sym->cursor_def);
+ }
+
+ sym = UT_LIST_GET_NEXT(sym_list, sym);
+ }
+
+ func = UT_LIST_GET_FIRST(sym_tab->func_node_list);
+
+ while (func) {
+ eval_node_free_val_buf(func);
+
+ func = UT_LIST_GET_NEXT(func_node_list, func);
+ }
+}
+
+/**********************************************************************
+Adds an integer literal to a symbol table. */
+
+sym_node_t*
+sym_tab_add_int_lit(
+/*================*/
+ /* out: symbol table node */
+ sym_tab_t* sym_tab, /* in: symbol table */
+ ulint val) /* in: integer value */
+{
+ sym_node_t* node;
+ byte* data;
+
+ node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
+
+ node->common.type = QUE_NODE_SYMBOL;
+
+ node->resolved = TRUE;
+ node->token_type = SYM_LIT;
+
+ node->indirection = NULL;
+
+ dtype_set(&(node->common.val.type), DATA_INT, 0, 4, 0);
+
+ data = mem_heap_alloc(sym_tab->heap, 4);
+ mach_write_to_4(data, val);
+
+ dfield_set_data(&(node->common.val), data, 4);
+
+ node->common.val_buf_size = 0;
+ node->prefetch_buf = NULL;
+ node->cursor_def = NULL;
+
+ UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
+
+ node->sym_table = sym_tab;
+
+ return(node);
+}
+
+/**********************************************************************
+Adds a string literal to a symbol table. */
+
+sym_node_t*
+sym_tab_add_str_lit(
+/*================*/
+ /* out: symbol table node */
+ sym_tab_t* sym_tab, /* in: symbol table */
+ byte* str, /* in: string with no quotes around
+ it */
+ ulint len) /* in: string length */
+{
+ sym_node_t* node;
+ byte* data;
+
+ node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
+
+ node->common.type = QUE_NODE_SYMBOL;
+
+ node->resolved = TRUE;
+ node->token_type = SYM_LIT;
+
+ node->indirection = NULL;
+
+ dtype_set(&(node->common.val.type), DATA_VARCHAR, DATA_ENGLISH, 0, 0);
+
+ if (len) {
+ data = mem_heap_alloc(sym_tab->heap, len);
+ ut_memcpy(data, str, len);
+ } else {
+ data = NULL;
+ }
+
+ dfield_set_data(&(node->common.val), data, len);
+
+ node->common.val_buf_size = 0;
+ node->prefetch_buf = NULL;
+ node->cursor_def = NULL;
+
+ UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
+
+ node->sym_table = sym_tab;
+
+ return(node);
+}
+
+/**********************************************************************
+Adds an SQL null literal to a symbol table. */
+
+sym_node_t*
+sym_tab_add_null_lit(
+/*=================*/
+ /* out: symbol table node */
+ sym_tab_t* sym_tab) /* in: symbol table */
+{
+ sym_node_t* node;
+
+ node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
+
+ node->common.type = QUE_NODE_SYMBOL;
+
+ node->resolved = TRUE;
+ node->token_type = SYM_LIT;
+
+ node->indirection = NULL;
+
+ node->common.val.type.mtype = DATA_ERROR;
+
+ dfield_set_data(&(node->common.val), NULL, UNIV_SQL_NULL);
+
+ node->common.val_buf_size = 0;
+ node->prefetch_buf = NULL;
+ node->cursor_def = NULL;
+
+ UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
+
+ node->sym_table = sym_tab;
+
+ return(node);
+}
+
+/**********************************************************************
+Adds an identifier to a symbol table. */
+
+sym_node_t*
+sym_tab_add_id(
+/*===========*/
+ /* out: symbol table node */
+ sym_tab_t* sym_tab, /* in: symbol table */
+ byte* name, /* in: identifier name */
+ ulint len) /* in: identifier length */
+{
+ sym_node_t* node;
+
+ node = mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t));
+
+ node->common.type = QUE_NODE_SYMBOL;
+
+ node->resolved = FALSE;
+ node->indirection = NULL;
+
+ node->name = mem_heap_strdupl(sym_tab->heap, (char*) name, len + 1);
+ node->name_len = len;
+
+ UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
+
+ dfield_set_data(&(node->common.val), NULL, UNIV_SQL_NULL);
+
+ node->common.val_buf_size = 0;
+ node->prefetch_buf = NULL;
+ node->cursor_def = NULL;
+
+ node->sym_table = sym_tab;
+
+ return(node);
+}