From 27de9ece815b04651db03ed3d413374f42c9d894 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Dec 2002 19:59:22 +0100 Subject: Simplistic, experimental framework for Stored Procedures (SPs). Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters, single-statement procedures, rudimentary multi-statement (begin-end) prodedures (when the client can handle it), and local variables. Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling, reparses procedures at each call (no caching), etc, etc. Certainly buggy too, but procedures can actually be created and called.... sql/Makefile.am: Added SP files. sql/item.cc: Added this*_item() methods for Item_splocal. (SP local variable) sql/item.h: Added this*_item() methods for SPs in Item, and the new Item_splocal class (SP local variable). sql/lex.h: Added new symbols for SPs. (Note: SPSET is temporary and will go away later.) sql/sql_class.cc: Initialize SP runtime context in THD. sql/sql_class.h: Add SP runtime context to THD. sql/sql_lex.cc: Init. buf pointer to beginning of command (needed by SPs). Also initialize SP head and parse time context. sql/sql_lex.h: New SQLCOM_ tags for SPs, and added pointer to beginning of command pointer and SP head and parse-time context to LEX. sql/sql_parse.cc: Added SQLCOM_CREATE_PROCEDURE, _CALL, _ALTER_PROCEDURE and _DROP_PROCEDURE cases. (Still rudimentary and lacking proper error handling...) sql/sql_yacc.yy: Lots and lots of additions for SPs... (Still even more missing, and no error messages...) --- sql/sp_pcontext.cc | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 sql/sp_pcontext.cc (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc new file mode 100644 index 00000000000..d2ab8cb93ac --- /dev/null +++ b/sql/sp_pcontext.cc @@ -0,0 +1,91 @@ +/* Copyright (C) 2002 MySQL AB + + 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; either version 2 of the License, or + (at your option) any later version. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __GNUC__ +#pragma implementation +#endif + +#if defined(WIN32) || defined(__WIN__) +#undef SAFEMALLOC /* Problems with threads */ +#endif + +#include "mysql_priv.h" +#include "sp_pcontext.h" + +sp_pcontext::sp_pcontext() + : m_params(0), m_framesize(0), m_i(0) +{ + m_pvar_size = 16; + m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME)); + if (m_pvar) + memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t)); +} + +void +sp_pcontext::grow() +{ + uint sz = m_pvar_size + 8; + sp_pvar_t *a = (sp_pvar_t *)my_realloc((char *)m_pvar, + sz * sizeof(sp_pvar_t), + MYF(MY_WME | MY_ALLOW_ZERO_PTR)); + + if (a) + { + m_pvar_size = sz; + m_pvar = a; + } +} + +/* This does a linear search (from newer to older variables, in case +** we have shadowed names). +** It's possible to have a more efficient allocation and search method, +** but it might not be worth it. The typical number of parameters and +** variables will in most cases be low (a handfull). +** And this is only called during parsing. +*/ +sp_pvar_t * +sp_pcontext::find_pvar(LEX_STRING *name) +{ + String n(name->str, name->length, default_charset_info); + uint i = m_i; + + while (i-- > 0) + { + if (stringcmp(&n, m_pvar[i].name->const_string()) == 0) + return m_pvar + i; + } + return NULL; +} + +void +sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, + sp_param_mode_t mode) +{ + if (m_i >= m_pvar_size) + grow(); + if (m_i < m_pvar_size) + { + if (m_i == m_framesize) + m_framesize += 1; + m_pvar[m_i].name= new Item_string(name->str, name->length, + default_charset_info); + m_pvar[m_i].type= type; + m_pvar[m_i].mode= mode; + m_pvar[m_i].offset= m_i; + m_pvar[m_i].isset= (mode == sp_param_out ? FALSE : TRUE); + m_i += 1; + } +} -- cgit v1.2.1 From 37ce17e2cd6e796ca19674fb42f91bd153aaedf2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 14:24:29 +0100 Subject: Fixed bugs in the parameter evaluation and modified the execution engine for better jump support. Some flow control support added too (but not complete). sql/lex.h: Added more keywords for embedded SQL. sql/sp_head.cc: Fixed bugs in the parameter evaluation. Modified execute() for better jump support. Added jump instruction and backpatch support. sql/sp_head.h: Fixed bugs in the parameter evaluation. Modified execute() for better jump support. Added jump instruction and backpatch support. sql/sp_pcontext.cc: Added label support. sql/sp_pcontext.h: Added label support. sql/sql_yacc.yy: Outlined flow control constructs (parses, but nothing generated yet). --- sql/sp_pcontext.cc | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index d2ab8cb93ac..9dc995f582f 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -24,14 +24,16 @@ #include "mysql_priv.h" #include "sp_pcontext.h" +#include "sp_head.h" sp_pcontext::sp_pcontext() - : m_params(0), m_framesize(0), m_i(0) + : m_params(0), m_framesize(0), m_i(0), m_genlab(0) { m_pvar_size = 16; m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME)); if (m_pvar) memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t)); + m_label.empty(); } void @@ -89,3 +91,41 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, m_i += 1; } } + +void +sp_pcontext::push_label(char *name, uint ip) +{ + sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME)); + + if (lab) + { + lab->name= name; + lab->ip= ip; + m_label.push_front(lab); + } +} + +void +sp_pcontext::push_gen_label(uint ip) +{ + char *s= my_malloc(10, MYF(MY_WME)); // 10=... + + if (s) + { + sprintf(s, ".%08x", m_genlab++); // ...9+1 + push_label(s, ip); + } +} + +sp_label_t * +sp_pcontext::find_label(char *name) +{ + List_iterator_fast li(m_label); + sp_label_t *lab; + + while ((lab= li++)) + if (strcasecmp(name, lab->name) == 0) + return lab; + + return NULL; +} -- cgit v1.2.1 From f6611aa0ab45aa5586101b34c444b8fab305fac9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Dec 2002 15:40:44 +0100 Subject: Fixed the broken backpatching implementation. Implemented IF-THEN-ELSE. sql/sp_head.cc: Reimplemented the broken backpatching, so it works for nested constructions and IF-THEN-ELSE too. sql/sp_head.h: Reimplemented the broken backpatching, so it works for nested constructions and IF-THEN-ELSE too. sql/sp_pcontext.cc: Return the value from push-methods, for convenience. sql/sp_pcontext.h: Return the value from push-methods, for convenience. sql/sql_yacc.yy: Implemented IF-THEN-ELSE. Corrected for the new backpatch method. --- sql/sp_pcontext.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9dc995f582f..96296e54184 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -92,7 +92,7 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, } } -void +sp_label_t * sp_pcontext::push_label(char *name, uint ip) { sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME)); @@ -103,18 +103,21 @@ sp_pcontext::push_label(char *name, uint ip) lab->ip= ip; m_label.push_front(lab); } + return lab; } -void +sp_label_t * sp_pcontext::push_gen_label(uint ip) { + sp_label_t *lab= NULL; char *s= my_malloc(10, MYF(MY_WME)); // 10=... if (s) { sprintf(s, ".%08x", m_genlab++); // ...9+1 - push_label(s, ip); + lab= push_label(s, ip); } + return lab; } sp_label_t * -- cgit v1.2.1 From b12330b3d9597b6da2ee8ef51765093e9de38e42 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Dec 2002 10:01:52 +0100 Subject: Added parsing of CASE (both generic and "simple"). sql/sp_head.cc: Init. the simple_case flag. sql/sp_head.h: New flag for (simple)case parsing. sql/sp_pcontext.cc: Removed push_gen_label method (not needed any more). sql/sp_pcontext.h: Removed push_gen_label method (not needed any more). Fixed bug in pop(). sql/sql_yacc.yy: Added CASE parsing. --- sql/sp_pcontext.cc | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 96296e54184..407151c3e38 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -106,20 +106,6 @@ sp_pcontext::push_label(char *name, uint ip) return lab; } -sp_label_t * -sp_pcontext::push_gen_label(uint ip) -{ - sp_label_t *lab= NULL; - char *s= my_malloc(10, MYF(MY_WME)); // 10=... - - if (s) - { - sprintf(s, ".%08x", m_genlab++); // ...9+1 - lab= push_label(s, ip); - } - return lab; -} - sp_label_t * sp_pcontext::find_label(char *name) { -- cgit v1.2.1 From addf8ea04ec295a679845cd1911d5e3504c91fab Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Mar 2003 11:36:32 +0100 Subject: Post-merge fixes. mysql-test/r/sp.result: Post-merge fixes. (And disabled the ip test, since some change in 4.1 broke it.) mysql-test/t/sp.test: Post-merge fixes. (And disabled the ip test, since some change in 4.1 broke it.) --- sql/sp_pcontext.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 407151c3e38..9cf7a45b46b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -61,13 +61,17 @@ sp_pcontext::grow() sp_pvar_t * sp_pcontext::find_pvar(LEX_STRING *name) { - String n(name->str, name->length, default_charset_info); uint i = m_i; while (i-- > 0) { - if (stringcmp(&n, m_pvar[i].name->const_string()) == 0) + if (my_strncasecmp(system_charset_info, + name->str, + m_pvar[i].name->const_string()->ptr(), + name->length) == 0) + { return m_pvar + i; + } } return NULL; } -- cgit v1.2.1 From fa870804d37c27a69551c9767b9a17224fe495b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Mar 2003 11:57:05 +0100 Subject: Post post merge fix. Made the broken ip test work again. sql/sp_head.cc: Added some more DBUG output. sql/sp_pcontext.cc: Post post merge fix. --- sql/sp_pcontext.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9cf7a45b46b..9d22c6be62b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -65,10 +65,14 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { + uint len= m_pvar[i].name->const_string()->length(); + + if (name->length > len) + len= name->length; if (my_strncasecmp(system_charset_info, name->str, m_pvar[i].name->const_string()->ptr(), - name->length) == 0) + len) == 0) { return m_pvar + i; } -- cgit v1.2.1 From 3946b8235c6f4dfbb5a1aeefed5b620bf89df34e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Mar 2003 12:29:58 +0100 Subject: Added IF EXISTS to DROP PROCEDURE|FUNCTION. Changed another unecessary use of Item_string into LEX_STRING (in sp_pcontext). Docs/sp-implemented.txt: Added IF EXISTS to DROP PROCEDURE|FUNCTION mysql-test/r/sp-error.result: Added IF EXISTS to DROP PROCEDURE|FUNCTION mysql-test/t/sp-error.test: Added IF EXISTS to DROP PROCEDURE|FUNCTION sql/sp_pcontext.cc: Changed another unecessary use of Item_string into LEX_STRING. sql/sp_pcontext.h: Changed another unecessary use of Item_string into LEX_STRING. sql/sql_parse.cc: Added IF EXISTS to DROP PROCEDURE|FUNCTION sql/sql_yacc.yy: Added IF EXISTS to DROP PROCEDURE|FUNCTION --- sql/sp_pcontext.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'sql/sp_pcontext.cc') diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9d22c6be62b..94eb8df4b95 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -65,13 +65,12 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { - uint len= m_pvar[i].name->const_string()->length(); + uint len= (m_pvar[i].name.length > name->length ? + m_pvar[i].name.length : name->length); - if (name->length > len) - len= name->length; if (my_strncasecmp(system_charset_info, name->str, - m_pvar[i].name->const_string()->ptr(), + m_pvar[i].name.str, len) == 0) { return m_pvar + i; @@ -90,8 +89,8 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, { if (m_i == m_framesize) m_framesize += 1; - m_pvar[m_i].name= new Item_string(name->str, name->length, - default_charset_info); + m_pvar[m_i].name.str= name->str; + m_pvar[m_i].name.length= name->length, m_pvar[m_i].type= type; m_pvar[m_i].mode= mode; m_pvar[m_i].offset= m_i; -- cgit v1.2.1