Merging 4.1->5.0.
This commit is contained in:
commit
28a2c6a96b
@ -385,6 +385,10 @@ libmysqld/repl_failsafe.cc
|
||||
libmysqld/set_var.cc
|
||||
libmysqld/simple-test
|
||||
libmysqld/slave.cc
|
||||
libmysqld/sp.cc
|
||||
libmysqld/sp_cache.cc
|
||||
libmysqld/sp_head.cc
|
||||
libmysqld/sp_pcontext.cc
|
||||
libmysqld/spatial.cc
|
||||
libmysqld/sql_acl.cc
|
||||
libmysqld/sql_analyse.cc
|
||||
|
@ -5,6 +5,7 @@ Administrator@fred.
|
||||
Miguel@light.local
|
||||
Sinisa@sinisa.nasamreza.org
|
||||
WAX@sergbook.mysql.com
|
||||
acurtis@pcgem.rdg.cyberkinetica.com
|
||||
administrador@light.hegel.local
|
||||
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
|
||||
akishkin@work.mysql.com
|
||||
@ -96,10 +97,12 @@ paul@ice.local
|
||||
paul@ice.snake.net
|
||||
paul@teton.kitebird.com
|
||||
pem@mysql.com
|
||||
pem@per-erik-martins-dator.local
|
||||
peter@linux.local
|
||||
peter@mysql.com
|
||||
peterg@mysql.com
|
||||
pgulutzan@linux.local
|
||||
pmartin@build.mysql2.com
|
||||
ram@deer.(none)
|
||||
ram@gw.mysql.r18.ru
|
||||
ram@gw.udmsearch.izhnet.ru
|
||||
|
@ -6,6 +6,7 @@ FROM=$USER@mysql.com
|
||||
INTERNALS=internals@lists.mysql.com
|
||||
DOCS=docs-commit@mysql.com
|
||||
LIMIT=10000
|
||||
REPOV=5.0
|
||||
|
||||
if [ "$REAL_EMAIL" = "" ]
|
||||
then
|
||||
@ -27,15 +28,15 @@ CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
|
||||
echo "Commit successful, notifying developers at $TO"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.1>
|
||||
List-ID: <bk.mysql-$REPOV>
|
||||
From: $FROM
|
||||
To: $TO
|
||||
Subject: bk commit - 4.1 tree ($CHANGESET)
|
||||
Subject: bk commit - $REPOV tree ($CHANGESET)
|
||||
|
||||
EOF
|
||||
bk changes -v -r+
|
||||
bk cset -r+ -d
|
||||
) | head -n $LIMIT | /usr/sbin/sendmail -t
|
||||
) | /usr/sbin/sendmail -t
|
||||
|
||||
#++
|
||||
# internals@ mail
|
||||
@ -43,13 +44,13 @@ EOF
|
||||
echo "Notifying internals list at $INTERNALS"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.1>
|
||||
List-ID: <bk.mysql-$REPOV>
|
||||
From: $FROM
|
||||
To: $INTERNALS
|
||||
Subject: bk commit into 4.1 tree ($CHANGESET)
|
||||
Subject: bk commit into $REPOV tree ($CHANGESET)
|
||||
|
||||
Below is the list of changes that have just been committed into a local
|
||||
4.1 repository of $USER. When $USER does a push these changes will
|
||||
$REPOV repository of $USER. When $USER does a push these changes will
|
||||
be propagated to the main repository and, within 24 hours after the
|
||||
push, to the public repository.
|
||||
For information on how to access the public repository
|
||||
@ -70,15 +71,15 @@ EOF
|
||||
echo "Notifying docs list at $DOCS"
|
||||
(
|
||||
cat <<EOF
|
||||
List-ID: <bk.mysql-4.1>
|
||||
List-ID: <bk.mysql-$REPOV>
|
||||
From: $FROM
|
||||
To: $DOCS
|
||||
Subject: bk commit - 4.1 tree (Manual) ($CHANGESET)
|
||||
Subject: bk commit - $REPOV tree (Manual) ($CHANGESET)
|
||||
|
||||
EOF
|
||||
bk changes -v -r+
|
||||
bk cset -r+ -d
|
||||
) | head -n $LIMIT | /usr/sbin/sendmail -t
|
||||
) | /usr/sbin/sendmail -t
|
||||
fi
|
||||
|
||||
else
|
||||
|
1055
Docs/sp-imp-spec.txt
Normal file
1055
Docs/sp-imp-spec.txt
Normal file
File diff suppressed because it is too large
Load Diff
114
Docs/sp-implemented.txt
Normal file
114
Docs/sp-implemented.txt
Normal file
@ -0,0 +1,114 @@
|
||||
Stored Procedures implemented 2003-09-16:
|
||||
|
||||
|
||||
Summary of Not Yet Implemented:
|
||||
|
||||
- SQL queries (like SELECT, INSERT, UPDATE etc) in FUNCTION bodies
|
||||
- External languages
|
||||
- Access control
|
||||
- Routine characteristics (mostly used for external languages)
|
||||
- SQL-99 COMMIT (related to BEGIN/END)
|
||||
- FOR-loops
|
||||
- CASCADE/RESTRICT for ALTER and DROP
|
||||
- ALTER/DROP METHOD (as it implies User Defined Types)
|
||||
- SIGNAL and RESIGNAL, and UNDO handlers
|
||||
|
||||
|
||||
Summary of what's implemented:
|
||||
|
||||
- SQL PROCEDUREs/FUNCTIONs (CREATE/DROP)
|
||||
- CALL
|
||||
- DECLARE of local variables
|
||||
- BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE
|
||||
- SELECT INTO local variables
|
||||
- "Non-query" FUNCTIONs only
|
||||
- Prepared SP caching
|
||||
- CONDITIONs and HANDLERs
|
||||
- Simple read-only CURSORs.
|
||||
|
||||
List of what's implemented:
|
||||
|
||||
- CREATE PROCEDURE|FUNCTION name ( args ) body
|
||||
No routine characteristics yet.
|
||||
|
||||
- ALTER PROCEDURE|FUNCTION name ...
|
||||
Is parsed, but a no-op (as there are no characteristics implemented yet).
|
||||
CASCADE/RESTRICT is not implemented (and CASCADE probably will not be).
|
||||
|
||||
- DROP PROCEDURE|FUNCTION [IF EXISTS] name
|
||||
CASCADE/RESTRICT is not implemented (and CASCADE probably will not be).
|
||||
|
||||
- CALL name (args)
|
||||
OUT and INOUT parameters are only supported for local variables, and
|
||||
therefore only useful when calling such procedures from within another
|
||||
procedure.
|
||||
Note: For the time being, when a procedure with OUT/INOUT parameter is
|
||||
called, the out values are silently discarded. In the future, this
|
||||
will either generate an error message, or it might even work to
|
||||
call all procedures from the top-level.
|
||||
|
||||
- Function/Procedure body:
|
||||
- BEGIN/END
|
||||
Is parsed, but not the real thing with (optional) transaction
|
||||
control, it only serves as block syntax for multiple statements (and
|
||||
local variable binding).
|
||||
Note: Multiple statements requires a client that can send bodies
|
||||
containing ";". This is handled in the CLI clients mysql and
|
||||
mysqltest with the "delimiter" command. Changing the end-of-query
|
||||
delimiter ";" to for instance "|" allows ";" to be used in the
|
||||
routine body.
|
||||
- SET of local variables
|
||||
Implemented as part of the pre-existing SET syntax. This allows an
|
||||
extended syntax of "SET a=x, b=y, ..." where different variable types
|
||||
(SP local and global) can be mixed. This also allows combinations
|
||||
of local variables and some options that only make sense for
|
||||
global/system variables; in that case the options are accepted but
|
||||
ignored.
|
||||
- The flow control constructs: CASE, IF, LOOP, WHILE, ITERATE and LEAVE
|
||||
are fully implemented.
|
||||
- SELECT ... INTO local variables (as well as global session variables)
|
||||
is implemented. (Note: This is not SQL-99 feature, but common in other
|
||||
databases.)
|
||||
- A FUNCTION can have flow control contructs, but must not contain
|
||||
an SQL query, like SELECT, INSERT, UPDATE, etc. The reason is that it's
|
||||
hard to allow this is that a FUNCTION is executed as part of another
|
||||
query (unlike a PROCEDURE, which is called as a statement). The table
|
||||
locking scheme used makes it difficult to allow "subqueries" during
|
||||
FUNCTION invokation.
|
||||
- SPs are cached, but with a separate cache for each thread (THD).
|
||||
There are still quite a few non-reentrant constructs in the lexical
|
||||
context which makes sharing prepared SPs impossible. And, even when
|
||||
this is resolved, it's not necessarily the case that it will be faster
|
||||
than a cache per thread. A global cache requires locks, which might
|
||||
become a buttleneck. (It would save memory though.)
|
||||
- CONDITIONs and HANDLERs are implemented, but not the SIGNAL and
|
||||
RESIGNAL statements. (It's unclear if these can be implemented.)
|
||||
The semantics of CONDITIONs is expanded to allow catching MySQL error
|
||||
codes as well. UNDO handlers are not implemented (since we don't have
|
||||
SQL-99 style transaction control yet).
|
||||
- Simple read-only CURSORs are implemented, but not yet any of the
|
||||
optional arguments to DECLARE (SCROLL, SENSITIVE, etc) or FETCH
|
||||
(NEXT, PRIOR, etc). Cursors are ASENSITIVE, READ-ONLY, non-SCROLLing.
|
||||
(The additional syntax will be added for completeness, but for the
|
||||
most part unsupported with the current underlying cursor mechanism.)
|
||||
|
||||
Closed questions:
|
||||
|
||||
- What is the expected result when creating a procedure with a name that
|
||||
already exists? An error or overwrite?
|
||||
Answer: Error
|
||||
|
||||
- Do PROCEDUREs and FUNCTIONs share namespace or not? I think not, but the
|
||||
we need to flag the type in the mysql.proc table and the name alone is
|
||||
not a unique key any more, or, we have separate tables.
|
||||
(Unfortunately, mysql.func is already taken. Use "sfunc" and maybe even
|
||||
rename "proc" into "sproc" while we still can, for consistency?)
|
||||
Answer: Same tables, with an additional key-field for the type.
|
||||
|
||||
|
||||
Open questions/issues:
|
||||
|
||||
- SQL-99 variables and parameters are typed. For the present we don't do
|
||||
any type checking, since this is the way MySQL works. I still don't know
|
||||
if we should keep it this way, or implement type checking. Possibly we
|
||||
should have optional, uset-settable, type checking.
|
@ -2815,6 +2815,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
NETWARE_YIELD
|
||||
va_start(args, fmt);
|
||||
(void) vfprintf(file, fmt, args);
|
||||
#ifdef OS2
|
||||
@ -2828,6 +2829,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
|
||||
|
||||
void tee_fputs(const char *s, FILE *file)
|
||||
{
|
||||
NETWARE_YIELD
|
||||
fputs(s, file);
|
||||
#ifdef OS2
|
||||
fflush( file);
|
||||
@ -2839,6 +2841,7 @@ void tee_fputs(const char *s, FILE *file)
|
||||
|
||||
void tee_puts(const char *s, FILE *file)
|
||||
{
|
||||
NETWARE_YIELD
|
||||
fputs(s, file);
|
||||
fputs("\n", file);
|
||||
#ifdef OS2
|
||||
|
@ -91,6 +91,7 @@
|
||||
|
||||
#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
|
||||
|
||||
#define DEFAULT_DELIMITER ';'
|
||||
|
||||
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
|
||||
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
|
||||
@ -137,6 +138,8 @@ static const char *embedded_server_groups[] = {
|
||||
NullS
|
||||
};
|
||||
|
||||
static char delimiter= DEFAULT_DELIMITER;
|
||||
|
||||
DYNAMIC_ARRAY q_lines;
|
||||
|
||||
#include "sslopt-vars.h"
|
||||
@ -215,6 +218,7 @@ Q_REQUIRE_VERSION,
|
||||
Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
|
||||
Q_ENABLE_INFO, Q_DISABLE_INFO,
|
||||
Q_EXEC,
|
||||
Q_DELIMITER,
|
||||
Q_UNKNOWN, /* Unknown command. */
|
||||
Q_COMMENT, /* Comments, ignored. */
|
||||
Q_COMMENT_WITH_COMMAND
|
||||
@ -286,6 +290,7 @@ const char *command_names[]=
|
||||
"enable_info",
|
||||
"disable_info",
|
||||
"exec",
|
||||
"delimiter",
|
||||
0
|
||||
};
|
||||
|
||||
@ -1627,6 +1632,17 @@ int do_while(struct st_query* q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_delimiter(char *p)
|
||||
{
|
||||
while (*p && my_isspace(charset_info,*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
die("Missing delimiter character\n");
|
||||
delimiter=*p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int read_line(char* buf, int size)
|
||||
{
|
||||
@ -1656,7 +1672,7 @@ int read_line(char* buf, int size)
|
||||
switch(state) {
|
||||
case R_NORMAL:
|
||||
/* Only accept '{' in the beginning of a line */
|
||||
if (c == ';')
|
||||
if (c == delimiter)
|
||||
{
|
||||
*p = 0;
|
||||
return 0;
|
||||
@ -1696,7 +1712,7 @@ int read_line(char* buf, int size)
|
||||
*buf = 0;
|
||||
return 0;
|
||||
}
|
||||
else if (c == ';' || c == '{')
|
||||
else if (c == delimiter || c == '{')
|
||||
{
|
||||
*p = 0;
|
||||
return 0;
|
||||
@ -1716,7 +1732,7 @@ int read_line(char* buf, int size)
|
||||
state = R_ESC_SLASH_Q1;
|
||||
break;
|
||||
case R_ESC_Q_Q1:
|
||||
if (c == ';')
|
||||
if (c == delimiter)
|
||||
{
|
||||
*p = 0;
|
||||
return 0;
|
||||
@ -1737,7 +1753,7 @@ int read_line(char* buf, int size)
|
||||
state = R_ESC_SLASH_Q2;
|
||||
break;
|
||||
case R_ESC_Q_Q2:
|
||||
if (c == ';')
|
||||
if (c == delimiter)
|
||||
{
|
||||
*p = 0;
|
||||
return 0;
|
||||
@ -2609,6 +2625,9 @@ int main(int argc, char **argv)
|
||||
do_sync_with_master2("");
|
||||
break;
|
||||
}
|
||||
case Q_DELIMITER:
|
||||
do_delimiter(q->first_argument);
|
||||
break;
|
||||
case Q_COMMENT: /* Ignore row */
|
||||
case Q_COMMENT_WITH_COMMAND:
|
||||
break;
|
||||
|
18
configure.in
18
configure.in
@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(sql/mysqld.cc)
|
||||
AC_CANONICAL_SYSTEM
|
||||
# The Docs Makefile.am parses this line!
|
||||
AM_INIT_AUTOMAKE(mysql, 4.1.1-alpha)
|
||||
AM_INIT_AUTOMAKE(mysql, 5.0.0-alpha)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
PROTOCOL_VERSION=10
|
||||
@ -36,7 +36,7 @@ for i in $AVAILABLE_LANGUAGES
|
||||
do
|
||||
AVAILABLE_LANGUAGES_ERRORS="$AVAILABLE_LANGUAGES_ERRORS $i/errmsg.sys"
|
||||
case $host_os in
|
||||
netware* | modesto*)
|
||||
netware*)
|
||||
echo "$i/errmsg.sys: $i/errmsg.txt
|
||||
\$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ \$^ $i/errmsg.sys" \
|
||||
>> $AVAILABLE_LANGUAGES_ERRORS_RULES
|
||||
@ -458,7 +458,7 @@ else
|
||||
*cygwin*)
|
||||
FIND_PROC="$PS -e | grep mysqld | grep \" \$\$PID \" > /dev/null"
|
||||
;;
|
||||
*netware* | *modesto*)
|
||||
*netware*)
|
||||
FIND_PROC=
|
||||
;;
|
||||
*)
|
||||
@ -1551,7 +1551,7 @@ AC_SUBST(LIBDL)
|
||||
|
||||
# System characteristics
|
||||
case $SYSTEM_TYPE in
|
||||
*netware* | *modesto*) ;;
|
||||
*netware*) ;;
|
||||
*)
|
||||
AC_SYS_RESTARTABLE_SYSCALLS
|
||||
;;
|
||||
@ -1581,10 +1581,12 @@ else
|
||||
fi
|
||||
|
||||
if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then
|
||||
DEBUG_CFLAGS="$DEBUG_CFLAGS -DDEBUG -sym internal,codeview4"
|
||||
DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -DDEBUG -sym internal,codeview4"
|
||||
OPTIMIZE_CFLAGS="$OPTIMIZE_CFLAGS -DNDEBUG"
|
||||
OPTIMIZE_CXXFLAGS="$OPTIMIZE_CXXFLAGS -DNDEBUG"
|
||||
DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4"
|
||||
DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4"
|
||||
DEBUG_OPTIMIZE_CC="-DDEBUG"
|
||||
DEBUG_OPTIMIZE_CXX="-DDEBUG"
|
||||
OPTIMIZE_CFLAGS="-O3 -DNDEBUG"
|
||||
OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(debug,
|
||||
|
@ -14,7 +14,10 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* Defines for netware compatible with MySQL */
|
||||
/* Header for NetWare compatible with MySQL */
|
||||
|
||||
#ifndef _config_netware_h
|
||||
#define _config_netware_h
|
||||
|
||||
/* required headers */
|
||||
#include <unistd.h>
|
||||
@ -32,6 +35,10 @@
|
||||
#include <pthread.h>
|
||||
#include <termios.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* required adjustments */
|
||||
#undef HAVE_READDIR_R
|
||||
#undef HAVE_RWLOCK_INIT
|
||||
@ -80,6 +87,15 @@
|
||||
/* do not use the extended time in LibC sys\stat.h */
|
||||
#define _POSIX_SOURCE
|
||||
|
||||
/* Some macros for portability */
|
||||
/* kernal call on NetWare that will only yield if our time slice is up */
|
||||
void kYieldIfTimeSliceUp(void);
|
||||
|
||||
/* some macros for portability */
|
||||
#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=(SEC); (ABSTIME).tv_nsec=0; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _config_netware_h */
|
||||
|
||||
|
@ -73,6 +73,13 @@
|
||||
#endif
|
||||
#endif /* _WIN32... */
|
||||
|
||||
/* extra protection against CPU Hogs on NetWare */
|
||||
#ifdef __NETWARE__
|
||||
#define NETWARE_YIELD { kYieldIfTimeSliceUp(); }
|
||||
#else
|
||||
#define NETWARE_YIELD { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
The macros below are borrowed from include/linux/compiler.h in the
|
||||
Linux kernel. Use them to indicate the likelyhood of the truthfulness
|
||||
|
@ -130,6 +130,8 @@ enum enum_server_command
|
||||
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
|
||||
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
|
||||
|
||||
#define ONLY_KILL_QUERY 1
|
||||
|
||||
struct st_vio; /* Only C */
|
||||
typedef struct st_vio Vio;
|
||||
|
||||
@ -291,6 +293,8 @@ typedef struct st_udf_args
|
||||
char **args; /* Pointer to argument */
|
||||
unsigned long *lengths; /* Length of string arguments */
|
||||
char *maybe_null; /* Set to 1 for all maybe_null args */
|
||||
char **attributes; /* Pointer to attribute name */
|
||||
unsigned long *attribute_lengths; /* Length of attribute arguments */
|
||||
} UDF_ARGS;
|
||||
|
||||
/* This holds information about the result */
|
||||
|
@ -300,4 +300,36 @@
|
||||
#define ER_WARN_QC_RESIZE 1281
|
||||
#define ER_BAD_FT_COLUMN 1282
|
||||
#define ER_UNKNOWN_KEY_CACHE 1283
|
||||
#define ER_ERROR_MESSAGES 284
|
||||
#define ER_SP_NO_RECURSIVE_CREATE 1284
|
||||
#define ER_SP_ALREADY_EXISTS 1285
|
||||
#define ER_SP_DOES_NOT_EXIST 1286
|
||||
#define ER_SP_DROP_FAILED 1287
|
||||
#define ER_SP_STORE_FAILED 1288
|
||||
#define ER_SP_LILABEL_MISMATCH 1289
|
||||
#define ER_SP_LABEL_REDEFINE 1290
|
||||
#define ER_SP_LABEL_MISMATCH 1291
|
||||
#define ER_SP_UNINIT_VAR 1292
|
||||
#define ER_SP_BADSELECT 1293
|
||||
#define ER_SP_BADRETURN 1294
|
||||
#define ER_SP_BADQUERY 1295
|
||||
#define ER_UPDATE_LOG_DEPRECATED_IGNORED 1296
|
||||
#define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1297
|
||||
#define ER_QUERY_INTERRUPTED 1298
|
||||
#define ER_SP_WRONG_NO_OF_ARGS 1299
|
||||
#define ER_SP_COND_MISMATCH 1300
|
||||
#define ER_SP_NORETURN 1301
|
||||
#define ER_SP_NORETURNEND 1302
|
||||
#define ER_SP_BAD_CURSOR_QUERY 1303
|
||||
#define ER_SP_BAD_CURSOR_SELECT 1304
|
||||
#define ER_SP_CURSOR_MISMATCH 1305
|
||||
#define ER_SP_CURSOR_ALREADY_OPEN 1306
|
||||
#define ER_SP_CURSOR_NOT_OPEN 1307
|
||||
#define ER_SP_UNDECLARED_VAR 1308
|
||||
#define ER_SP_WRONG_NO_OF_FETCH_ARGS 1309
|
||||
#define ER_SP_FETCH_NO_DATA 1310
|
||||
#define ER_SP_DUP_PARAM 1311
|
||||
#define ER_SP_DUP_VAR 1312
|
||||
#define ER_SP_DUP_COND 1313
|
||||
#define ER_SP_DUP_CURS 1314
|
||||
#define ER_SP_CANT_ALTER 1315
|
||||
#define ER_ERROR_MESSAGES 316
|
||||
|
@ -3167,6 +3167,7 @@ MYSQL_DATA * STDCALL cli_read_binary_rows(MYSQL_STMT *stmt)
|
||||
if (pkt_len > 1)
|
||||
{
|
||||
mysql->warning_count= uint2korr(cp+1);
|
||||
mysql->server_status= uint2korr(cp+3);
|
||||
DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count));
|
||||
}
|
||||
DBUG_PRINT("exit",("Got %d rows",result->rows));
|
||||
|
@ -57,7 +57,8 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
|
||||
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
|
||||
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
|
||||
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
|
||||
spatial.cc gstream.cc sql_help.cc
|
||||
spatial.cc gstream.cc sql_help.cc protocol_cursor.cc \
|
||||
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc
|
||||
|
||||
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
|
||||
libmysqld_a_SOURCES=
|
||||
|
@ -754,7 +754,7 @@ bool Protocol::convert_str(const char *from, uint length)
|
||||
bool setup_params_data(st_prep_stmt *stmt)
|
||||
{
|
||||
THD *thd= stmt->thd;
|
||||
List<Item> ¶ms= thd->lex.param_list;
|
||||
List<Item> ¶ms= thd->lex->param_list;
|
||||
List_iterator<Item> param_iterator(params);
|
||||
Item_param *param;
|
||||
ulong param_no= 0;
|
||||
@ -787,7 +787,7 @@ bool setup_params_data(st_prep_stmt *stmt)
|
||||
bool setup_params_data_withlog(st_prep_stmt *stmt)
|
||||
{
|
||||
THD *thd= stmt->thd;
|
||||
List<Item> ¶ms= thd->lex.param_list;
|
||||
List<Item> ¶ms= thd->lex->param_list;
|
||||
List_iterator<Item> param_iterator(params);
|
||||
Item_param *param;
|
||||
MYSQL_BIND *client_param= thd->client_params;
|
||||
|
@ -2633,7 +2633,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
||||
char llbuff[22],llbuff2[22];
|
||||
DBUG_ENTER("sort_get_next_record");
|
||||
|
||||
if (*killed_ptr(param))
|
||||
if (*killed_ptr(param->thd))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
switch (share->data_file_type) {
|
||||
|
@ -1667,9 +1667,9 @@ err:
|
||||
DBUG_RETURN(1);
|
||||
} /* sort_record_index */
|
||||
|
||||
volatile bool *killed_ptr(MI_CHECK *param)
|
||||
int *killed_ptr(void *thd)
|
||||
{
|
||||
return (bool *)(& param->thd); /* always NULL */
|
||||
return (int *)thd; /* always NULL */
|
||||
}
|
||||
|
||||
/* print warnings and errors */
|
||||
|
@ -703,7 +703,7 @@ int mi_open_keyfile(MYISAM_SHARE *share);
|
||||
void mi_setup_functions(register MYISAM_SHARE *share);
|
||||
|
||||
/* Functions needed by mi_check */
|
||||
volatile bool *killed_ptr(MI_CHECK *param);
|
||||
int *killed_ptr(void *thd);
|
||||
void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...));
|
||||
void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...));
|
||||
void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...));
|
||||
|
@ -848,7 +848,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
|
||||
uchar *strpos;
|
||||
BUFFPEK *buffpek,**refpek;
|
||||
QUEUE queue;
|
||||
volatile bool *killed= killed_ptr(info->sort_info->param);
|
||||
int *killed= killed_ptr(info->sort_info->param->thd);
|
||||
|
||||
DBUG_ENTER("merge_buffers");
|
||||
|
||||
count=error=0;
|
||||
|
@ -8,6 +8,7 @@ help_keyword
|
||||
help_relation
|
||||
help_topic
|
||||
host
|
||||
proc
|
||||
tables_priv
|
||||
user
|
||||
show tables;
|
||||
@ -24,6 +25,7 @@ help_keyword
|
||||
help_relation
|
||||
help_topic
|
||||
host
|
||||
proc
|
||||
tables_priv
|
||||
user
|
||||
show tables;
|
||||
@ -41,6 +43,7 @@ help_keyword
|
||||
help_relation
|
||||
help_topic
|
||||
host
|
||||
proc
|
||||
tables_priv
|
||||
user
|
||||
show tables;
|
||||
|
@ -457,10 +457,10 @@ drop table t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
html varchar(5) default NULL,
|
||||
rin int(11) default '0',
|
||||
out int(11) default '0'
|
||||
rout int(11) default '0'
|
||||
) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('1',1,0);
|
||||
SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
html prod
|
||||
1 0.00
|
||||
drop table t1;
|
||||
|
@ -86,3 +86,16 @@ use mysqltest;
|
||||
create table t1 (c int);
|
||||
insert into mysqltest.t1 set mysqltest.t1.c = '1';
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
drop table if exists t1,t2,t3;
|
||||
create table t1(id1 int not null auto_increment primary key, t char(12));
|
||||
create table t2(id2 int not null, t char(12));
|
||||
create table t3(id3 int not null, t char(12), index(id3));
|
||||
select count(*) from t2;
|
||||
count(*)
|
||||
500
|
||||
insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
|
||||
select count(*) from t2;
|
||||
count(*)
|
||||
25500
|
||||
drop table if exists t1,t2,t3;
|
||||
|
@ -809,4 +809,29 @@ show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
DROP TABLE t1;
|
||||
create table t1 (a int);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 48
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
/**/ select * from t1;
|
||||
a
|
||||
/**/ select * from t1;
|
||||
a
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 49
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 13
|
||||
drop table t1;
|
||||
|
||||
SET GLOBAL query_cache_size=0;
|
||||
|
@ -127,6 +127,7 @@ insert into t1 values (1);
|
||||
show open tables;
|
||||
Database Table In_use Name_locked
|
||||
test t1 0 0
|
||||
mysql proc 0 0
|
||||
drop table t1;
|
||||
create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
|
||||
show create table t1;
|
||||
|
258
mysql-test/r/sp-error.result
Normal file
258
mysql-test/r/sp-error.result
Normal file
@ -0,0 +1,258 @@
|
||||
delete from mysql.proc;
|
||||
create procedure syntaxerror(t int);
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
|
||||
create procedure syntaxerror(t int);
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
|
||||
create procedure syntaxerror(t int);
|
||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
|
||||
create procedure proc1()
|
||||
set @x = 42;
|
||||
create function func1() returns int
|
||||
return 42;
|
||||
create procedure foo()
|
||||
create procedure bar() set @x=3;
|
||||
ERROR HY000: Can't create a PROCEDURE from within another stored routine
|
||||
create procedure foo()
|
||||
create function bar() returns double return 2.3;
|
||||
ERROR HY000: Can't create a FUNCTION from within another stored routine
|
||||
create procedure proc1()
|
||||
set @x = 42;
|
||||
ERROR HY000: PROCEDURE proc1 already exists
|
||||
create function func1() returns int
|
||||
return 42;
|
||||
ERROR HY000: FUNCTION func1 already exists
|
||||
drop procedure proc1;
|
||||
drop function func1;
|
||||
alter procedure foo;
|
||||
ERROR HY000: PROCEDURE foo does not exist
|
||||
alter function foo;
|
||||
ERROR HY000: FUNCTION foo does not exist
|
||||
drop procedure foo;
|
||||
ERROR HY000: PROCEDURE foo does not exist
|
||||
drop function foo;
|
||||
ERROR HY000: FUNCTION foo does not exist
|
||||
call foo();
|
||||
ERROR HY000: PROCEDURE foo does not exist
|
||||
drop procedure if exists foo;
|
||||
Warnings:
|
||||
Warning 1282 PROCEDURE foo does not exist
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
leave bar;
|
||||
end loop;
|
||||
ERROR HY000: LEAVE with no matching label: bar
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
iterate bar;
|
||||
end loop;
|
||||
ERROR HY000: ITERATE with no matching label: bar
|
||||
create procedure foo()
|
||||
foo: begin
|
||||
iterate foo;
|
||||
end;
|
||||
ERROR HY000: ITERATE with no matching label: foo
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
foo: loop
|
||||
set @x=2;
|
||||
end loop foo;
|
||||
end loop foo;
|
||||
ERROR HY000: Redefining label foo
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
set @x=2;
|
||||
end loop bar;
|
||||
ERROR HY000: End-label bar without match
|
||||
create procedure foo(out x int)
|
||||
begin
|
||||
declare y int;
|
||||
set x = y;
|
||||
end;
|
||||
ERROR HY000: Referring to uninitialized variable y
|
||||
create procedure foo()
|
||||
begin
|
||||
select name from mysql.proc;
|
||||
select type from mysql.proc;
|
||||
end;
|
||||
call foo();
|
||||
ERROR HY000: SELECT in a stored procedure must have INTO
|
||||
drop procedure foo;
|
||||
create procedure foo()
|
||||
return 42;
|
||||
ERROR HY000: RETURN is only allowed in a FUNCTION
|
||||
create function foo() returns int
|
||||
begin
|
||||
declare x int;
|
||||
select max(c) into x from test.t;
|
||||
return x;
|
||||
end;
|
||||
ERROR HY000: Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION
|
||||
create procedure p(x int)
|
||||
insert into test.t1 values (x);
|
||||
create function f(x int) returns int
|
||||
return x+42;
|
||||
call p();
|
||||
ERROR HY000: Wrong number of arguments for PROCEDURE p, expected 1, got 0
|
||||
call p(1, 2);
|
||||
ERROR HY000: Wrong number of arguments for PROCEDURE p, expected 1, got 2
|
||||
select f();
|
||||
ERROR HY000: Wrong number of arguments for FUNCTION f, expected 1, got 0
|
||||
select f(1, 2);
|
||||
ERROR HY000: Wrong number of arguments for FUNCTION f, expected 1, got 2
|
||||
drop procedure p;
|
||||
drop function f;
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for foo set x = 1;
|
||||
insert into test.t1 values (val);
|
||||
if (x) then
|
||||
set res = 0;
|
||||
else
|
||||
set res = 1;
|
||||
end if;
|
||||
end;
|
||||
ERROR HY000: Undefined CONDITION: foo
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare foo condition for 1146;
|
||||
declare continue handler for bar set x = 1;
|
||||
insert into test.t1 values (val);
|
||||
if (x) then
|
||||
set res = 0;
|
||||
else
|
||||
set res = 1;
|
||||
end if;
|
||||
end;
|
||||
ERROR HY000: Undefined CONDITION: bar
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
set x = val+3;
|
||||
end;
|
||||
ERROR HY000: No RETURN found in FUNCTION f
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
set x = val+3;
|
||||
if x < 4 then
|
||||
return x;
|
||||
end if;
|
||||
end;
|
||||
select f(10);
|
||||
ERROR HY000: FUNCTION f ended without RETURN
|
||||
drop function f;
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for insert into test.t1 values ("foo", 42);
|
||||
open c;
|
||||
close c;
|
||||
end;
|
||||
ERROR HY000: Cursor statement must be a SELECT
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
declare c cursor for select * into x from test.t limit 1;
|
||||
open c;
|
||||
close c;
|
||||
end;
|
||||
ERROR HY000: Cursor SELECT must not have INTO
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t;
|
||||
open cc;
|
||||
close c;
|
||||
end;
|
||||
ERROR HY000: Undefined CURSOR: cc
|
||||
drop table if exists t1;
|
||||
create table t1 (val int);
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t1;
|
||||
open c;
|
||||
open c;
|
||||
close c;
|
||||
end;
|
||||
call p();
|
||||
ERROR HY000: Cursor is already open
|
||||
drop procedure p;
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t1;
|
||||
open c;
|
||||
close c;
|
||||
close c;
|
||||
end;
|
||||
call p();
|
||||
ERROR HY000: Cursor is not open
|
||||
drop procedure p;
|
||||
alter procedure bar3 sql security invoker;
|
||||
ERROR HY000: PROCEDURE bar3 does not exist
|
||||
alter procedure bar3 name
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
|
||||
ERROR 42000: Identifier name 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' is too long
|
||||
drop table t1;
|
||||
drop table if exists t1;
|
||||
create table t1 (val int, x float);
|
||||
insert into t1 values (42, 3.1), (19, 1.2);
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
open c;
|
||||
fetch c into x, y;
|
||||
close c;
|
||||
end;
|
||||
ERROR HY000: Undeclared variable: y
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
open c;
|
||||
fetch c into x;
|
||||
close c;
|
||||
end;
|
||||
call p();
|
||||
ERROR HY000: Wrong number of FETCH variables
|
||||
drop procedure p;
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
declare y float;
|
||||
declare z int;
|
||||
open c;
|
||||
fetch c into x, y, z;
|
||||
close c;
|
||||
end;
|
||||
call p();
|
||||
ERROR HY000: Wrong number of FETCH variables
|
||||
drop procedure p;
|
||||
create procedure p(in x int, x char(10))
|
||||
begin
|
||||
end;
|
||||
ERROR HY000: Duplicate parameter: x
|
||||
create function p(x int, x char(10))
|
||||
begin
|
||||
end;
|
||||
ERROR HY000: Duplicate parameter: x
|
||||
create procedure p()
|
||||
begin
|
||||
declare x float;
|
||||
declare x int;
|
||||
end;
|
||||
ERROR HY000: Duplicate variable: x
|
||||
create procedure p()
|
||||
begin
|
||||
declare c condition for 1064;
|
||||
declare c condition for 1065;
|
||||
end;
|
||||
ERROR HY000: Duplicate condition: c
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare c cursor for select field from t1;
|
||||
end;
|
||||
ERROR HY000: Duplicate cursor: c
|
||||
drop table t1;
|
930
mysql-test/r/sp.result
Normal file
930
mysql-test/r/sp.result
Normal file
@ -0,0 +1,930 @@
|
||||
use test;
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
create table t1 (
|
||||
id char(16) not null,
|
||||
data int not null
|
||||
);
|
||||
create table t2 (
|
||||
s char(16) not null,
|
||||
i int not null,
|
||||
d double not null
|
||||
);
|
||||
create procedure foo42()
|
||||
insert into test.t1 values ("foo", 42);
|
||||
call foo42();
|
||||
select * from t1;
|
||||
id data
|
||||
foo 42
|
||||
delete from t1;
|
||||
drop procedure foo42;
|
||||
create procedure u()
|
||||
use sptmp;
|
||||
drop database if exists sptmp;
|
||||
create database sptmp;
|
||||
use test;
|
||||
call u();
|
||||
select database();
|
||||
database()
|
||||
test
|
||||
drop database sptmp;
|
||||
drop procedure u;
|
||||
create procedure bar(x char(16), y int)
|
||||
insert into test.t1 values (x, y);
|
||||
call bar("bar", 666);
|
||||
select * from t1;
|
||||
id data
|
||||
bar 666
|
||||
delete from t1;
|
||||
create procedure empty()
|
||||
begin
|
||||
end;
|
||||
call empty();
|
||||
drop procedure empty;
|
||||
create procedure scope(a int, b float)
|
||||
begin
|
||||
declare b int;
|
||||
declare c float;
|
||||
begin
|
||||
declare c int;
|
||||
end;
|
||||
end;
|
||||
drop procedure scope;
|
||||
create procedure two(x1 char(16), x2 char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x1, y);
|
||||
insert into test.t1 values (x2, y);
|
||||
end;
|
||||
call two("one", "two", 3);
|
||||
select * from t1;
|
||||
id data
|
||||
one 3
|
||||
two 3
|
||||
delete from t1;
|
||||
drop procedure two;
|
||||
create procedure locset(x char(16), y int)
|
||||
begin
|
||||
declare z1, z2 int;
|
||||
set z1 = y;
|
||||
set z2 = z1+2;
|
||||
insert into test.t1 values (x, z2);
|
||||
end;
|
||||
call locset("locset", 19);
|
||||
select * from t1;
|
||||
id data
|
||||
locset 21
|
||||
delete from t1;
|
||||
drop procedure locset;
|
||||
drop table if exists t3;
|
||||
create table t3 ( d date, i int, f double, s varchar(32) );
|
||||
create procedure nullset()
|
||||
begin
|
||||
declare ld date;
|
||||
declare li int;
|
||||
declare lf double;
|
||||
declare ls varchar(32);
|
||||
set ld = null, li = null, lf = null, ls = null;
|
||||
insert into t3 values (ld, li, lf, ls);
|
||||
end;
|
||||
call nullset();
|
||||
select * from t3;
|
||||
d i f s
|
||||
NULL NULL NULL NULL
|
||||
drop table t3;
|
||||
drop procedure nullset;
|
||||
create procedure mixset(x char(16), y int)
|
||||
begin
|
||||
declare z int;
|
||||
set @z = y, z = 666, max_join_size = 100;
|
||||
insert into test.t1 values (x, z);
|
||||
end;
|
||||
call mixset("mixset", 19);
|
||||
show variables like 'max_join_size';
|
||||
Variable_name Value
|
||||
max_join_size 100
|
||||
select id,data,@z from t1;
|
||||
id data @z
|
||||
mixset 666 19
|
||||
delete from t1;
|
||||
drop procedure mixset;
|
||||
create procedure zip(x char(16), y int)
|
||||
begin
|
||||
declare z int;
|
||||
call zap(y, z);
|
||||
call bar(x, z);
|
||||
end;
|
||||
create procedure zap(x int, out y int)
|
||||
begin
|
||||
declare z int;
|
||||
set z = x+1, y = z;
|
||||
end;
|
||||
call zip("zip", 99);
|
||||
select * from t1;
|
||||
id data
|
||||
zip 100
|
||||
delete from t1;
|
||||
drop procedure zip;
|
||||
drop procedure bar;
|
||||
call zap(7, @zap);
|
||||
select @zap;
|
||||
@zap
|
||||
8
|
||||
drop procedure zap;
|
||||
create procedure c1(x int)
|
||||
call c2("c", x);
|
||||
create procedure c2(s char(16), x int)
|
||||
call c3(x, s);
|
||||
create procedure c3(x int, s char(16))
|
||||
call c4("level", x, s);
|
||||
create procedure c4(l char(8), x int, s char(16))
|
||||
insert into t1 values (concat(l,s), x);
|
||||
call c1(42);
|
||||
select * from t1;
|
||||
id data
|
||||
levelc 42
|
||||
delete from t1;
|
||||
drop procedure c1;
|
||||
drop procedure c2;
|
||||
drop procedure c3;
|
||||
drop procedure c4;
|
||||
create procedure iotest(x1 char(16), x2 char(16), y int)
|
||||
begin
|
||||
call inc2(x2, y);
|
||||
insert into test.t1 values (x1, y);
|
||||
end;
|
||||
create procedure inc2(x char(16), y int)
|
||||
begin
|
||||
call inc(y);
|
||||
insert into test.t1 values (x, y);
|
||||
end;
|
||||
create procedure inc(inout io int)
|
||||
set io = io + 1;
|
||||
call iotest("io1", "io2", 1);
|
||||
select * from t1;
|
||||
id data
|
||||
io2 2
|
||||
io1 1
|
||||
delete from t1;
|
||||
drop procedure iotest;
|
||||
drop procedure inc2;
|
||||
create procedure incr(inout x int)
|
||||
call inc(x);
|
||||
select @zap;
|
||||
@zap
|
||||
8
|
||||
call incr(@zap);
|
||||
select @zap;
|
||||
@zap
|
||||
9
|
||||
drop procedure inc;
|
||||
drop procedure incr;
|
||||
create procedure cbv1()
|
||||
begin
|
||||
declare y int default 3;
|
||||
call cbv2(y+1, y);
|
||||
insert into test.t1 values ("cbv1", y);
|
||||
end;
|
||||
create procedure cbv2(y1 int, inout y2 int)
|
||||
begin
|
||||
set y2 = 4711;
|
||||
insert into test.t1 values ("cbv2", y1);
|
||||
end;
|
||||
call cbv1();
|
||||
select * from t1;
|
||||
id data
|
||||
cbv2 4
|
||||
cbv1 4711
|
||||
delete from t1;
|
||||
drop procedure cbv1;
|
||||
drop procedure cbv2;
|
||||
insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3);
|
||||
create procedure sub1(id char(16), x int)
|
||||
insert into test.t1 values (id, x);
|
||||
create function sub3(i int) returns int
|
||||
return i+1;
|
||||
call sub1("sub1a", (select 7));
|
||||
call sub1("sub1b", (select max(i) from t2));
|
||||
call sub1("sub1c", (select i,d from t2 limit 1));
|
||||
call sub1("sub1d", (select 1 from (select 1) a));
|
||||
select * from t1;
|
||||
id data
|
||||
sub1a 7
|
||||
sub1b 3
|
||||
sub1c 1
|
||||
sub1d 1
|
||||
select sub3((select max(i) from t2));
|
||||
sub3((select max(i) from t2))
|
||||
4
|
||||
drop procedure sub1;
|
||||
drop function sub3;
|
||||
create procedure a0(x int)
|
||||
while x do
|
||||
set x = x-1;
|
||||
insert into test.t1 values ("a0", x);
|
||||
end while;
|
||||
call a0(3);
|
||||
select * from t1;
|
||||
id data
|
||||
sub1a 7
|
||||
sub1b 3
|
||||
sub1c 1
|
||||
sub1d 1
|
||||
a0 2
|
||||
a0 1
|
||||
a0 0
|
||||
delete from t1;
|
||||
drop procedure a0;
|
||||
create procedure a(x int)
|
||||
while x > 0 do
|
||||
set x = x-1;
|
||||
insert into test.t1 values ("a", x);
|
||||
end while;
|
||||
call a(3);
|
||||
select * from t1;
|
||||
id data
|
||||
a 2
|
||||
a 1
|
||||
a 0
|
||||
delete from t1;
|
||||
drop procedure a;
|
||||
create procedure b(x int)
|
||||
repeat
|
||||
insert into test.t1 values (repeat("b",3), x);
|
||||
set x = x-1;
|
||||
until x = 0 end repeat;
|
||||
call b(3);
|
||||
select * from t1;
|
||||
id data
|
||||
bbb 3
|
||||
bbb 2
|
||||
bbb 1
|
||||
delete from t1;
|
||||
drop procedure b;
|
||||
create procedure b2(x int)
|
||||
repeat(select 1 into outfile 'b2');
|
||||
insert into test.t1 values (repeat("b2",3), x);
|
||||
set x = x-1;
|
||||
until x = 0 end repeat;
|
||||
drop procedure b2;
|
||||
create procedure c(x int)
|
||||
hmm: while x > 0 do
|
||||
insert into test.t1 values ("c", x);
|
||||
set x = x-1;
|
||||
iterate hmm;
|
||||
insert into test.t1 values ("x", x);
|
||||
end while hmm;
|
||||
call c(3);
|
||||
select * from t1;
|
||||
id data
|
||||
c 3
|
||||
c 2
|
||||
c 1
|
||||
delete from t1;
|
||||
drop procedure c;
|
||||
create procedure d(x int)
|
||||
hmm: while x > 0 do
|
||||
insert into test.t1 values ("d", x);
|
||||
set x = x-1;
|
||||
leave hmm;
|
||||
insert into test.t1 values ("x", x);
|
||||
end while;
|
||||
call d(3);
|
||||
select * from t1;
|
||||
id data
|
||||
d 3
|
||||
delete from t1;
|
||||
drop procedure d;
|
||||
create procedure e(x int)
|
||||
foo: loop
|
||||
if x = 0 then
|
||||
leave foo;
|
||||
end if;
|
||||
insert into test.t1 values ("e", x);
|
||||
set x = x-1;
|
||||
end loop foo;
|
||||
call e(3);
|
||||
select * from t1;
|
||||
id data
|
||||
e 3
|
||||
e 2
|
||||
e 1
|
||||
delete from t1;
|
||||
drop procedure e;
|
||||
create procedure f(x int)
|
||||
if x < 0 then
|
||||
insert into test.t1 values ("f", 0);
|
||||
elseif x = 0 then
|
||||
insert into test.t1 values ("f", 1);
|
||||
else
|
||||
insert into test.t1 values ("f", 2);
|
||||
end if;
|
||||
call f(-2);
|
||||
call f(0);
|
||||
call f(4);
|
||||
select * from t1;
|
||||
id data
|
||||
f 0
|
||||
f 1
|
||||
f 2
|
||||
delete from t1;
|
||||
drop procedure f;
|
||||
create procedure g(x int)
|
||||
case
|
||||
when x < 0 then
|
||||
insert into test.t1 values ("g", 0);
|
||||
when x = 0 then
|
||||
insert into test.t1 values ("g", 1);
|
||||
else
|
||||
insert into test.t1 values ("g", 2);
|
||||
end case;
|
||||
call g(-42);
|
||||
call g(0);
|
||||
call g(1);
|
||||
select * from t1;
|
||||
id data
|
||||
g 0
|
||||
g 1
|
||||
g 2
|
||||
delete from t1;
|
||||
drop procedure g;
|
||||
create procedure h(x int)
|
||||
case x
|
||||
when 0 then
|
||||
insert into test.t1 values ("h0", x);
|
||||
when 1 then
|
||||
insert into test.t1 values ("h1", x);
|
||||
else
|
||||
insert into test.t1 values ("h?", x);
|
||||
end case;
|
||||
call h(0);
|
||||
call h(1);
|
||||
call h(17);
|
||||
select * from t1;
|
||||
id data
|
||||
h0 0
|
||||
h1 1
|
||||
h? 17
|
||||
delete from t1;
|
||||
drop procedure h;
|
||||
create procedure i(x int)
|
||||
foo:
|
||||
begin
|
||||
if x = 0 then
|
||||
leave foo;
|
||||
end if;
|
||||
insert into test.t1 values ("i", x);
|
||||
end foo;
|
||||
call i(0);
|
||||
call i(3);
|
||||
select * from t1;
|
||||
id data
|
||||
i 3
|
||||
delete from t1;
|
||||
drop procedure i;
|
||||
create procedure into_test(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select id,data into x,y from test.t1 limit 1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end;
|
||||
call into_test("into", 100);
|
||||
select * from t1;
|
||||
id data
|
||||
into 100
|
||||
into2 102
|
||||
delete from t1;
|
||||
drop procedure into_test;
|
||||
create procedure into_test2(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select id,data into x,@z from test.t1 limit 1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end;
|
||||
call into_test2("into", 100);
|
||||
select id,data,@z from t1;
|
||||
id data @z
|
||||
into 100 100
|
||||
into2 102 100
|
||||
delete from t1;
|
||||
drop procedure into_test2;
|
||||
create procedure into_test3()
|
||||
begin
|
||||
declare x char(16);
|
||||
declare y int;
|
||||
select * into x,y from test.t1 limit 1;
|
||||
insert into test.t2 values (x, y, 0.0);
|
||||
end;
|
||||
insert into t1 values ("into3", 19);
|
||||
delete from t2;
|
||||
call into_test3();
|
||||
call into_test3();
|
||||
select * from t2;
|
||||
s i d
|
||||
into3 19 0
|
||||
into3 19 0
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
drop procedure into_test3;
|
||||
create procedure into_test4()
|
||||
begin
|
||||
declare x int;
|
||||
select data into x from test.t1 limit 1;
|
||||
insert into test.t3 values ("into4", x);
|
||||
end;
|
||||
delete from t1;
|
||||
drop table if exists t3;
|
||||
create table t3 ( s char(16), d int);
|
||||
call into_test4();
|
||||
Warnings:
|
||||
select * from t3;
|
||||
s d
|
||||
into4 NULL
|
||||
insert into t1 values ("i4", 77);
|
||||
call into_test4();
|
||||
select * from t3;
|
||||
s d
|
||||
into4 NULL
|
||||
into4 77
|
||||
delete from t1;
|
||||
drop table t3;
|
||||
drop procedure into_test4;
|
||||
create procedure into_outfile(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select * into outfile "/tmp/spout" from test.t1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end;
|
||||
call into_outfile("ofile", 1);
|
||||
delete from t1;
|
||||
drop procedure into_outfile;
|
||||
create procedure into_dumpfile(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select * into dumpfile "/tmp/spdump" from test.t1 limit 1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end;
|
||||
call into_dumpfile("dfile", 1);
|
||||
delete from t1;
|
||||
drop procedure into_dumpfile;
|
||||
create procedure create_select(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
create table test.t3 select * from test.t1;
|
||||
insert into test.t3 values (concat(x, "2"), y+2);
|
||||
end;
|
||||
drop table if exists t3;
|
||||
call create_select("cs", 90);
|
||||
select * from t1, t3;
|
||||
id data id data
|
||||
cs 90 cs 90
|
||||
cs 90 cs2 92
|
||||
drop table if exists t3;
|
||||
delete from t1;
|
||||
drop procedure create_select;
|
||||
create function e() returns double
|
||||
return 2.7182818284590452354;
|
||||
set @e = e();
|
||||
select e(), @e;
|
||||
e() @e
|
||||
2.718281828459 2.718281828459
|
||||
create function inc(i int) returns int
|
||||
return i+1;
|
||||
select inc(1), inc(99), inc(-71);
|
||||
inc(1) inc(99) inc(-71)
|
||||
2 100 -70
|
||||
create function mul(x int, y int) returns int
|
||||
return x*y;
|
||||
select mul(1,1), mul(3,5), mul(4711, 666);
|
||||
mul(1,1) mul(3,5) mul(4711, 666)
|
||||
1 15 3137526
|
||||
create function append(s1 char(8), s2 char(8)) returns char(16)
|
||||
return concat(s1, s2);
|
||||
select append("foo", "bar");
|
||||
append("foo", "bar")
|
||||
foobar
|
||||
create function fac(n int unsigned) returns bigint unsigned
|
||||
begin
|
||||
declare f bigint unsigned default 1;
|
||||
while n > 1 do
|
||||
set f = f * n;
|
||||
set n = n - 1;
|
||||
end while;
|
||||
return f;
|
||||
end;
|
||||
select fac(1), fac(2), fac(5), fac(10);
|
||||
fac(1) fac(2) fac(5) fac(10)
|
||||
1 2 120 3628800
|
||||
create function fun(d double, i int, u int unsigned) returns double
|
||||
return mul(inc(i), fac(u)) / e();
|
||||
select fun(2.3, 3, 5);
|
||||
fun(2.3, 3, 5)
|
||||
176.58213176229
|
||||
insert into t2 values (append("xxx", "yyy"), mul(4,3), e());
|
||||
insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6));
|
||||
select * from t2 where s = append("a", "b");
|
||||
s i d
|
||||
ab 24 1324.36598821719
|
||||
select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2);
|
||||
s i d
|
||||
xxxyyy 12 2.71828182845905
|
||||
ab 24 1324.36598821719
|
||||
select * from t2 where d = e();
|
||||
s i d
|
||||
xxxyyy 12 2.71828182845905
|
||||
select * from t2;
|
||||
s i d
|
||||
xxxyyy 12 2.71828182845905
|
||||
ab 24 1324.36598821719
|
||||
delete from t2;
|
||||
drop function e;
|
||||
drop function inc;
|
||||
drop function mul;
|
||||
drop function append;
|
||||
drop function fun;
|
||||
create procedure hndlr1(val int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare foo condition for 1146;
|
||||
declare bar condition for sqlstate '42S98'; # Just for testing syntax
|
||||
declare zip condition for sqlstate value '42S99'; # Just for testing syntax
|
||||
declare continue handler for foo set x = 1;
|
||||
insert into test.t666 values ("hndlr1", val); # Non-existing table
|
||||
if (x) then
|
||||
insert into test.t1 values ("hndlr1", val); # This instead then
|
||||
end if;
|
||||
end;
|
||||
call hndlr1(42);
|
||||
select * from t1;
|
||||
id data
|
||||
hndlr1 42
|
||||
delete from t1;
|
||||
drop procedure hndlr1;
|
||||
create procedure hndlr2(val int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
begin
|
||||
declare exit handler for sqlstate '42S02' set x = 1;
|
||||
insert into test.t666 values ("hndlr2", val); # Non-existing table
|
||||
end;
|
||||
insert into test.t1 values ("hndlr2", x);
|
||||
end;
|
||||
call hndlr2(42);
|
||||
select * from t1;
|
||||
id data
|
||||
hndlr2 1
|
||||
delete from t1;
|
||||
drop procedure hndlr2;
|
||||
create procedure hndlr3(val int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlexception # Any error
|
||||
begin
|
||||
declare z int;
|
||||
set z = 2 * val;
|
||||
set x = 1;
|
||||
end;
|
||||
if val < 10 then
|
||||
begin
|
||||
declare y int;
|
||||
set y = val + 10;
|
||||
insert into test.t666 values ("hndlr3", y); # Non-existing table
|
||||
if x then
|
||||
insert into test.t1 values ("hndlr3", y);
|
||||
end if;
|
||||
end;
|
||||
end if;
|
||||
end;
|
||||
call hndlr3(3);
|
||||
select * from t1;
|
||||
id data
|
||||
hndlr3 13
|
||||
delete from t1;
|
||||
drop procedure hndlr3;
|
||||
drop table if exists t3;
|
||||
create table t3 ( id char(16), data int );
|
||||
create procedure hndlr4()
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare val int; # No default
|
||||
declare continue handler for 1306 set x=1;
|
||||
select data into val from test.t3 where id='z' limit 1; # No hits
|
||||
insert into test.t3 values ('z', val);
|
||||
end;
|
||||
call hndlr4();
|
||||
select * from t3;
|
||||
id data
|
||||
z NULL
|
||||
drop table t3;
|
||||
drop procedure hndlr4;
|
||||
create procedure cur1()
|
||||
begin
|
||||
declare done int default 0;
|
||||
declare continue handler for 1306 set done = 1;
|
||||
declare c cursor for select * from test.t2;
|
||||
declare a char(16);
|
||||
declare b int;
|
||||
declare c double;
|
||||
open c;
|
||||
repeat
|
||||
fetch c into a, b, c;
|
||||
if not done then
|
||||
insert into test.t1 values (a, b+c);
|
||||
end if;
|
||||
until done end repeat;
|
||||
close c;
|
||||
end;
|
||||
insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14);
|
||||
call cur1();
|
||||
select * from t1;
|
||||
id data
|
||||
foo 40
|
||||
bar 15
|
||||
zap 663
|
||||
drop procedure cur1;
|
||||
drop table if exists t3;
|
||||
create table t3 ( s char(16), i int );
|
||||
create procedure cur2()
|
||||
begin
|
||||
declare done int default 0;
|
||||
declare continue handler for 1306 set done = 1;
|
||||
declare c1 cursor for select id,data from test.t1;
|
||||
declare c2 cursor for select i from test.t2;
|
||||
open c1;
|
||||
open c2;
|
||||
repeat
|
||||
begin
|
||||
declare a char(16);
|
||||
declare b,c int;
|
||||
fetch c1 into a, b;
|
||||
fetch c2 into c;
|
||||
if not done then
|
||||
if b < c then
|
||||
insert into test.t3 values (a, b);
|
||||
else
|
||||
insert into test.t3 values (a, c);
|
||||
end if;
|
||||
end if;
|
||||
end;
|
||||
until done end repeat;
|
||||
close c1;
|
||||
close c2;
|
||||
end;
|
||||
call cur2();
|
||||
select * from t3;
|
||||
s i
|
||||
foo 40
|
||||
bar 3
|
||||
zap 663
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
drop table t3;
|
||||
drop procedure cur2;
|
||||
create procedure bug822(a_id char(16), a_data int)
|
||||
begin
|
||||
declare n int;
|
||||
select count(*) into n from t1 where id = a_id and data = a_data;
|
||||
if n = 0 then
|
||||
insert into t1 (id, data) values (a_id, a_data);
|
||||
end if;
|
||||
end;
|
||||
call bug822('foo', 42);
|
||||
call bug822('foo', 42);
|
||||
call bug822('bar', 666);
|
||||
select * from t1;
|
||||
id data
|
||||
foo 42
|
||||
bar 666
|
||||
delete from t1;
|
||||
drop procedure bug822;
|
||||
create procedure bug1495()
|
||||
begin
|
||||
declare x int;
|
||||
select data into x from t1 order by id limit 1;
|
||||
if x > 10 then
|
||||
insert into t1 values ("less", x-10);
|
||||
else
|
||||
insert into t1 values ("more", x+10);
|
||||
end if;
|
||||
end;
|
||||
insert into t1 values ('foo', 12);
|
||||
call bug1495();
|
||||
delete from t1 where id='foo';
|
||||
insert into t1 values ('bar', 7);
|
||||
call bug1495();
|
||||
delete from t1 where id='bar';
|
||||
select * from t1;
|
||||
id data
|
||||
less 2
|
||||
more 17
|
||||
delete from t1;
|
||||
drop procedure bug1495;
|
||||
create procedure bug1547(s char(16))
|
||||
begin
|
||||
declare x int;
|
||||
select data into x from t1 where s = id limit 1;
|
||||
if x > 10 then
|
||||
insert into t1 values ("less", x-10);
|
||||
else
|
||||
insert into t1 values ("more", x+10);
|
||||
end if;
|
||||
end;
|
||||
insert into t1 values ("foo", 12), ("bar", 7);
|
||||
call bug1547("foo");
|
||||
call bug1547("bar");
|
||||
select * from t1;
|
||||
id data
|
||||
foo 12
|
||||
bar 7
|
||||
less 2
|
||||
more 17
|
||||
delete from t1;
|
||||
drop procedure bug1547;
|
||||
drop table if exists t70;
|
||||
create table t70 (s1 int,s2 int);
|
||||
insert into t70 values (1,2);
|
||||
create procedure bug1656(out p1 int, out p2 int)
|
||||
select * into p1, p1 from t70;
|
||||
call bug1656(@1, @2);
|
||||
select @1, @2;
|
||||
@1 @2
|
||||
2 NULL
|
||||
drop table t70;
|
||||
drop procedure bug1656;
|
||||
drop table if exists t3;
|
||||
create table t3(a int);
|
||||
create procedure bug1862()
|
||||
begin
|
||||
insert into t3 values(2);
|
||||
flush tables;
|
||||
end;
|
||||
call bug1862();
|
||||
call bug1862();
|
||||
select * from t3;
|
||||
a
|
||||
2
|
||||
2
|
||||
drop table t3;
|
||||
drop procedure bug1862;
|
||||
drop table if exists fac;
|
||||
create table fac (n int unsigned not null primary key, f bigint unsigned);
|
||||
create procedure ifac(n int unsigned)
|
||||
begin
|
||||
declare i int unsigned default 1;
|
||||
if n > 20 then
|
||||
set n = 20; # bigint overflow otherwise
|
||||
end if;
|
||||
while i <= n do
|
||||
begin
|
||||
insert into test.fac values (i, fac(i));
|
||||
set i = i + 1;
|
||||
end;
|
||||
end while;
|
||||
end;
|
||||
call ifac(20);
|
||||
select * from fac;
|
||||
n f
|
||||
1 1
|
||||
2 2
|
||||
3 6
|
||||
4 24
|
||||
5 120
|
||||
6 720
|
||||
7 5040
|
||||
8 40320
|
||||
9 362880
|
||||
10 3628800
|
||||
11 39916800
|
||||
12 479001600
|
||||
13 6227020800
|
||||
14 87178291200
|
||||
15 1307674368000
|
||||
16 20922789888000
|
||||
17 355687428096000
|
||||
18 6402373705728000
|
||||
19 121645100408832000
|
||||
20 2432902008176640000
|
||||
drop table fac;
|
||||
show function status like '%f%';
|
||||
Name Type Creator Modified Created Suid Comment
|
||||
fac function root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y
|
||||
drop procedure ifac;
|
||||
drop function fac;
|
||||
drop table if exists primes;
|
||||
create table primes (
|
||||
i int unsigned not null primary key,
|
||||
p bigint unsigned not null
|
||||
);
|
||||
insert into primes values
|
||||
( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13),
|
||||
( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31),
|
||||
(10, 37), (11, 41), (12, 43), (13, 47), (14, 53),
|
||||
(15, 59), (16, 61), (17, 67), (18, 71), (19, 73),
|
||||
(20, 79), (21, 83), (22, 89), (23, 97), (24, 101),
|
||||
(25, 103), (26, 107), (27, 109), (28, 113), (29, 127),
|
||||
(30, 131), (31, 137), (32, 139), (33, 149), (34, 151),
|
||||
(35, 157), (36, 163), (37, 167), (38, 173), (39, 179),
|
||||
(40, 181), (41, 191), (42, 193), (43, 197), (44, 199);
|
||||
create procedure opp(n bigint unsigned, out pp bool)
|
||||
begin
|
||||
declare r double;
|
||||
declare b, s bigint unsigned default 0;
|
||||
set r = sqrt(n);
|
||||
again:
|
||||
loop
|
||||
if s = 45 then
|
||||
set b = b+200, s = 0;
|
||||
else
|
||||
begin
|
||||
declare p bigint unsigned;
|
||||
select t.p into p from test.primes t where t.i = s;
|
||||
if b+p > r then
|
||||
set pp = 1;
|
||||
leave again;
|
||||
end if;
|
||||
if mod(n, b+p) = 0 then
|
||||
set pp = 0;
|
||||
leave again;
|
||||
end if;
|
||||
set s = s+1;
|
||||
end;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
create procedure ip(m int unsigned)
|
||||
begin
|
||||
declare p bigint unsigned;
|
||||
declare i int unsigned;
|
||||
set i=45, p=201;
|
||||
while i < m do
|
||||
begin
|
||||
declare pp bool default 0;
|
||||
call opp(p, pp);
|
||||
if pp then
|
||||
insert into test.primes values (i, p);
|
||||
set i = i+1;
|
||||
end if;
|
||||
set p = p+2;
|
||||
end;
|
||||
end while;
|
||||
end;
|
||||
show create procedure opp;
|
||||
Procedure Create Procedure
|
||||
opp create procedure opp(n bigint unsigned, out pp bool)
|
||||
begin
|
||||
declare r double;
|
||||
declare b, s bigint unsigned default 0;
|
||||
set r = sqrt(n);
|
||||
again:
|
||||
loop
|
||||
if s = 45 then
|
||||
set b = b+200, s = 0;
|
||||
else
|
||||
begin
|
||||
declare p bigint unsigned;
|
||||
select t.p into p from test.primes t where t.i = s;
|
||||
if b+p > r then
|
||||
set pp = 1;
|
||||
leave again;
|
||||
end if;
|
||||
if mod(n, b+p) = 0 then
|
||||
set pp = 0;
|
||||
leave again;
|
||||
end if;
|
||||
set s = s+1;
|
||||
end;
|
||||
end if;
|
||||
end loop;
|
||||
end
|
||||
show procedure status like '%p%';
|
||||
Name Type Creator Modified Created Suid Comment
|
||||
ip procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y
|
||||
opp procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y
|
||||
call ip(200);
|
||||
select * from primes where i=45 or i=100 or i=199;
|
||||
i p
|
||||
45 211
|
||||
100 557
|
||||
199 1229
|
||||
drop table primes;
|
||||
drop procedure opp;
|
||||
drop procedure ip;
|
||||
create procedure bar(x char(16), y int)
|
||||
comment "111111111111" sql security invoker
|
||||
insert into test.t1 values (x, y);
|
||||
show procedure status like 'bar';
|
||||
Name Type Creator Modified Created Suid Comment
|
||||
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111
|
||||
alter procedure bar name bar2 comment "2222222222" sql security definer;
|
||||
alter procedure bar2 name bar comment "3333333333";
|
||||
alter procedure bar;
|
||||
show create procedure bar;
|
||||
Procedure Create Procedure
|
||||
bar create procedure bar(x char(16), y int)
|
||||
comment "111111111111" sql security invoker
|
||||
insert into test.t1 values (x, y)
|
||||
show procedure status like 'bar';
|
||||
Name Type Creator Modified Created Suid Comment
|
||||
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333
|
||||
drop procedure bar;
|
||||
drop table t1;
|
||||
drop table t2;
|
@ -14,6 +14,6 @@ update t1 set n = 3;
|
||||
unlock tables;
|
||||
show status like 'Table_lock%';
|
||||
Variable_name Value
|
||||
Table_locks_immediate 3
|
||||
Table_locks_immediate 4
|
||||
Table_locks_waited 1
|
||||
drop table t1;
|
||||
|
@ -647,6 +647,14 @@ x
|
||||
3
|
||||
3
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
1
|
||||
2
|
||||
3
|
||||
3
|
||||
11
|
||||
11
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
|
||||
ERROR 42S22: Unknown column 'x' in 'field list'
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
|
@ -1,8 +1,30 @@
|
||||
drop table if exists t1,t2;
|
||||
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
|
||||
select @test,@`select`,@TEST,@not_used;
|
||||
@test @`select` @TEST @not_used
|
||||
1 2 3 NULL
|
||||
set @`test`=1;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
@test @`test` @TEST @`TEST` @"teSt"
|
||||
1 1 1 1 1
|
||||
set @TEST=2;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
@test @`test` @TEST @`TEST` @"teSt"
|
||||
2 2 2 2 2
|
||||
set @"tEST"=3;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
@test @`test` @TEST @`TEST` @"teSt"
|
||||
3 3 3 3 3
|
||||
set @`TeST`=4;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
@test @`test` @TEST @`TEST` @"teSt"
|
||||
4 4 4 4 4
|
||||
select @`teST`:=5;
|
||||
@`teST`:=5
|
||||
5
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
@test @`test` @TEST @`TEST` @"teSt"
|
||||
5 5 5 5 5
|
||||
set @select=2,@t5=1.23456;
|
||||
select @`select`,@not_used;
|
||||
@`select` @not_used
|
||||
2 NULL
|
||||
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
||||
select @test_int,@test_double,@test_string,@test_string2,@select;
|
||||
@test_int @test_double @test_string @test_string2 @select
|
||||
@ -337,6 +359,8 @@ set sql_buffer_result=1;
|
||||
set sql_log_bin=1;
|
||||
set sql_log_off=1;
|
||||
set sql_log_update=1;
|
||||
Warnings:
|
||||
Note 1292 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored.
|
||||
set sql_low_priority_updates=1;
|
||||
set sql_max_join_size=200;
|
||||
select @@sql_max_join_size,@@max_join_size;
|
||||
|
@ -326,9 +326,9 @@ drop table t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
html varchar(5) default NULL,
|
||||
rin int(11) default '0',
|
||||
out int(11) default '0'
|
||||
rout int(11) default '0'
|
||||
) TYPE=MyISAM;
|
||||
|
||||
INSERT INTO t1 VALUES ('1',1,0);
|
||||
SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
drop table t1;
|
||||
|
@ -87,3 +87,34 @@ use mysqltest;
|
||||
create table t1 (c int);
|
||||
insert into mysqltest.t1 set mysqltest.t1.c = '1';
|
||||
drop database mysqltest;
|
||||
use test;
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3;
|
||||
--enable_warnings
|
||||
create table t1(id1 int not null auto_increment primary key, t char(12));
|
||||
create table t2(id2 int not null, t char(12));
|
||||
create table t3(id3 int not null, t char(12), index(id3));
|
||||
disable_query_log;
|
||||
let $1 = 100;
|
||||
while ($1)
|
||||
{
|
||||
let $2 = 5;
|
||||
eval insert into t1(t) values ('$1');
|
||||
while ($2)
|
||||
{
|
||||
eval insert into t2(id2,t) values ($1,'$2');
|
||||
let $3 = 10;
|
||||
while ($3)
|
||||
{
|
||||
eval insert into t3(id3,t) values ($1,'$2');
|
||||
dec $3;
|
||||
}
|
||||
dec $2;
|
||||
}
|
||||
dec $1;
|
||||
}
|
||||
enable_query_log;
|
||||
select count(*) from t2;
|
||||
insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3;
|
||||
select count(*) from t2;
|
||||
drop table if exists t1,t2,t3;
|
||||
|
@ -581,6 +581,21 @@ set character_set_results=cp1251;
|
||||
SELECT a,'Â','â'='Â' FROM t1;
|
||||
show status like "Qcache_hits";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# comments before command
|
||||
#
|
||||
create table t1 (a int);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_inserts";
|
||||
show status like "Qcache_hits";
|
||||
/**/ select * from t1;
|
||||
/**/ select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_inserts";
|
||||
show status like "Qcache_hits";
|
||||
|
||||
#
|
||||
# Keep things tidy
|
||||
#
|
||||
|
344
mysql-test/t/sp-error.test
Normal file
344
mysql-test/t/sp-error.test
Normal file
@ -0,0 +1,344 @@
|
||||
#
|
||||
# Stored PROCEDURE error tests
|
||||
#
|
||||
|
||||
# Make sure we don't have any procedures left.
|
||||
delete from mysql.proc;
|
||||
|
||||
delimiter |;
|
||||
|
||||
# This should give three syntax errors (sometimes crashed; bug #643)
|
||||
# (Unfortunately, this is not a 100% test, on some platforms this
|
||||
# passed despite the bug.)
|
||||
--error 1064
|
||||
create procedure syntaxerror(t int)|
|
||||
--error 1064
|
||||
create procedure syntaxerror(t int)|
|
||||
--error 1064
|
||||
create procedure syntaxerror(t int)|
|
||||
|
||||
# Check that we get the right error, i.e. UDF declaration parses correctly,
|
||||
# but foo.so doesn't exist.
|
||||
# QQ This generates an error message containing a misleading errno which
|
||||
# might vary between systems (it usually doesn't have anything to do with
|
||||
# the actual failing dlopen()).
|
||||
#--error 1126
|
||||
#create function foo returns real soname "foo.so"|
|
||||
|
||||
create procedure proc1()
|
||||
set @x = 42|
|
||||
|
||||
create function func1() returns int
|
||||
return 42|
|
||||
|
||||
# Can't create recursively
|
||||
--error 1280
|
||||
create procedure foo()
|
||||
create procedure bar() set @x=3|
|
||||
--error 1280
|
||||
create procedure foo()
|
||||
create function bar() returns double return 2.3|
|
||||
|
||||
# Already exists
|
||||
--error 1281
|
||||
create procedure proc1()
|
||||
set @x = 42|
|
||||
--error 1281
|
||||
create function func1() returns int
|
||||
return 42|
|
||||
|
||||
drop procedure proc1|
|
||||
drop function func1|
|
||||
|
||||
# Does not exist
|
||||
--error 1282
|
||||
alter procedure foo|
|
||||
--error 1282
|
||||
alter function foo|
|
||||
--error 1282
|
||||
drop procedure foo|
|
||||
--error 1282
|
||||
drop function foo|
|
||||
--error 1282
|
||||
call foo()|
|
||||
drop procedure if exists foo|
|
||||
|
||||
# LEAVE/ITERATE with no match
|
||||
--error 1285
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
leave bar;
|
||||
end loop|
|
||||
--error 1285
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
iterate bar;
|
||||
end loop|
|
||||
--error 1285
|
||||
create procedure foo()
|
||||
foo: begin
|
||||
iterate foo;
|
||||
end|
|
||||
|
||||
# Redefining label
|
||||
--error 1286
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
foo: loop
|
||||
set @x=2;
|
||||
end loop foo;
|
||||
end loop foo|
|
||||
|
||||
# End label mismatch
|
||||
--error 1287
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
set @x=2;
|
||||
end loop bar|
|
||||
|
||||
# Referring to undef variable
|
||||
--error 1288
|
||||
create procedure foo(out x int)
|
||||
begin
|
||||
declare y int;
|
||||
set x = y;
|
||||
end|
|
||||
|
||||
# We require INTO in SELECTs for some older clients (as mysql and mysqltest,
|
||||
# for now).
|
||||
create procedure foo()
|
||||
begin
|
||||
select name from mysql.proc;
|
||||
select type from mysql.proc;
|
||||
end|
|
||||
--error 1289
|
||||
call foo()|
|
||||
drop procedure foo|
|
||||
|
||||
# RETURN in FUNCTION only
|
||||
--error 1290
|
||||
create procedure foo()
|
||||
return 42|
|
||||
|
||||
# Doesn't allow queries in FUNCTIONs (for now :-( )
|
||||
--error 1291
|
||||
create function foo() returns int
|
||||
begin
|
||||
declare x int;
|
||||
select max(c) into x from test.t;
|
||||
return x;
|
||||
end|
|
||||
|
||||
# Wrong number of arguments
|
||||
create procedure p(x int)
|
||||
insert into test.t1 values (x)|
|
||||
create function f(x int) returns int
|
||||
return x+42|
|
||||
|
||||
--error 1295
|
||||
call p()|
|
||||
--error 1295
|
||||
call p(1, 2)|
|
||||
--error 1295
|
||||
select f()|
|
||||
--error 1295
|
||||
select f(1, 2)|
|
||||
|
||||
drop procedure p|
|
||||
drop function f|
|
||||
|
||||
--error 1296
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for foo set x = 1;
|
||||
|
||||
insert into test.t1 values (val);
|
||||
if (x) then
|
||||
set res = 0;
|
||||
else
|
||||
set res = 1;
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1296
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare foo condition for 1146;
|
||||
declare continue handler for bar set x = 1;
|
||||
|
||||
insert into test.t1 values (val);
|
||||
if (x) then
|
||||
set res = 0;
|
||||
else
|
||||
set res = 1;
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1297
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
|
||||
set x = val+3;
|
||||
end|
|
||||
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
|
||||
set x = val+3;
|
||||
if x < 4 then
|
||||
return x;
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1298
|
||||
select f(10)|
|
||||
|
||||
drop function f|
|
||||
|
||||
--error 1299
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for insert into test.t1 values ("foo", 42);
|
||||
|
||||
open c;
|
||||
close c;
|
||||
end|
|
||||
|
||||
--error 1300
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
declare c cursor for select * into x from test.t limit 1;
|
||||
|
||||
open c;
|
||||
close c;
|
||||
end|
|
||||
|
||||
--error 1301
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t;
|
||||
|
||||
open cc;
|
||||
close c;
|
||||
end|
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1|
|
||||
--enable_warnings
|
||||
create table t1 (val int)|
|
||||
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t1;
|
||||
|
||||
open c;
|
||||
open c;
|
||||
close c;
|
||||
end|
|
||||
--error 1302
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t1;
|
||||
|
||||
open c;
|
||||
close c;
|
||||
close c;
|
||||
end|
|
||||
--error 1303
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
--error 1282
|
||||
alter procedure bar3 sql security invoker|
|
||||
--error 1059
|
||||
alter procedure bar3 name
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
|
||||
|
||||
drop table t1|
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1|
|
||||
--enable_warnings
|
||||
create table t1 (val int, x float)|
|
||||
insert into t1 values (42, 3.1), (19, 1.2)|
|
||||
|
||||
--error 1304
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
|
||||
open c;
|
||||
fetch c into x, y;
|
||||
close c;
|
||||
end|
|
||||
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
|
||||
open c;
|
||||
fetch c into x;
|
||||
close c;
|
||||
end|
|
||||
--error 1305
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
declare y float;
|
||||
declare z int;
|
||||
|
||||
open c;
|
||||
fetch c into x, y, z;
|
||||
close c;
|
||||
end|
|
||||
--error 1305
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
--error 1307
|
||||
create procedure p(in x int, x char(10))
|
||||
begin
|
||||
end|
|
||||
--error 1307
|
||||
create function p(x int, x char(10))
|
||||
begin
|
||||
end|
|
||||
|
||||
--error 1308
|
||||
create procedure p()
|
||||
begin
|
||||
declare x float;
|
||||
declare x int;
|
||||
end|
|
||||
|
||||
--error 1309
|
||||
create procedure p()
|
||||
begin
|
||||
declare c condition for 1064;
|
||||
declare c condition for 1065;
|
||||
end|
|
||||
|
||||
--error 1310
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare c cursor for select field from t1;
|
||||
end|
|
||||
|
||||
drop table t1|
|
||||
|
||||
delimiter ;|
|
1054
mysql-test/t/sp.test
Normal file
1054
mysql-test/t/sp.test
Normal file
File diff suppressed because it is too large
Load Diff
@ -352,7 +352,9 @@ INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
# After this, only data based on old t1 records should have been added.
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
-- error 1054
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
@ -507,6 +509,9 @@ select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
|
||||
select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# DO & SET
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1);
|
||||
do @a:=(SELECT a from t1);
|
||||
|
@ -5,8 +5,20 @@
|
||||
drop table if exists t1,t2;
|
||||
--enable_warnings
|
||||
|
||||
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
|
||||
select @test,@`select`,@TEST,@not_used;
|
||||
# case insensitivity tests (new in 5.0)
|
||||
set @`test`=1;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
set @TEST=2;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
set @"tEST"=3;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
set @`TeST`=4;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
select @`teST`:=5;
|
||||
select @test, @`test`, @TEST, @`TEST`, @"teSt";
|
||||
|
||||
set @select=2,@t5=1.23456;
|
||||
select @`select`,@not_used;
|
||||
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
|
||||
select @test_int,@test_double,@test_string,@test_string2,@select;
|
||||
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
|
||||
|
@ -29,7 +29,7 @@ rm -rf Makefile.in.bk
|
||||
make clean bin-dist
|
||||
|
||||
# mark the build
|
||||
for file in *.tar.gz
|
||||
for file in *.tar.gz *.zip
|
||||
do
|
||||
if (expr "$file" : "mysql-[1-9].*" > /dev/null)
|
||||
then
|
||||
|
@ -8,6 +8,7 @@ set -e
|
||||
|
||||
path=`dirname $0`
|
||||
|
||||
$path/compile-netware-src
|
||||
$path/compile-netware-standard
|
||||
$path/compile-netware-debug
|
||||
#$path/compile-netware-max
|
||||
|
@ -13,7 +13,7 @@ path=`dirname $0`
|
||||
suffix="standard"
|
||||
|
||||
extra_configs=" \
|
||||
--with-innodb
|
||||
--with-innodb \
|
||||
"
|
||||
|
||||
. $path/compile-netware-END
|
||||
|
@ -7,8 +7,8 @@
|
||||
export MYDEV="WINE_BUILD_DIR"
|
||||
|
||||
export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/zlib-1.1.4"
|
||||
export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/zlib-1.1.4"
|
||||
export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a"
|
||||
export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/mysql-VERSION/netware/BUILD;$MYDEV/zlib-1.1.4"
|
||||
export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;knetware.imp;libz.a"
|
||||
|
||||
export WINEPATH="$MYDEV/mw/bin"
|
||||
|
||||
@ -19,9 +19,9 @@ export AR='mwldnlm'
|
||||
export AR_FLAGS='-type library -o'
|
||||
export AS='mwasmnlm'
|
||||
export CC='mwccnlm -gccincludes'
|
||||
export CFLAGS='-dialect c -proc 686 -relax_pointers'
|
||||
export CFLAGS='-align 8 -proc 686 -relax_pointers -dialect c'
|
||||
export CXX='mwccnlm -gccincludes'
|
||||
export CXXFLAGS='-dialect c++ -proc 686 -bool on -wchar_t on -relax_pointers -D_WCHAR_T'
|
||||
export CXXFLAGS='-align 8 -proc 686 -relax_pointers -dialect c++ -bool on -wchar_t on -D_WCHAR_T'
|
||||
export LD='mwldnlm'
|
||||
export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -flags pseudopreemption'
|
||||
export RANLIB=:
|
||||
|
@ -147,10 +147,12 @@ then
|
||||
fi
|
||||
|
||||
# make files writeable
|
||||
echo "making files writable..."
|
||||
cd $target_dir
|
||||
chmod -R u+rw,g+rw .
|
||||
|
||||
# edit the mvenv file
|
||||
echo "updating the mwenv environment file..."
|
||||
mwenv="./netware/BUILD/mwenv"
|
||||
mv -f $mwenv $mwenv.org
|
||||
sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \
|
||||
@ -158,6 +160,17 @@ sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \
|
||||
-e "s;VERSION;$version;g" $mwenv.org > $mwenv
|
||||
chmod +rwx $mwenv
|
||||
|
||||
#edit the def file versions
|
||||
echo "updating *.def file versions..."
|
||||
nlm_version=`echo "$version" | sed -e "s;\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*;\1, \2, \3;"`
|
||||
|
||||
for file in ./netware/*.def
|
||||
do
|
||||
mv -f $file $file.org
|
||||
sed -e "s;VERSION.*;VERSION $nlm_version;g" $file.org > $file
|
||||
rm $file.org
|
||||
done
|
||||
|
||||
# build linux tools
|
||||
echo "compiling linux tools..."
|
||||
./netware/BUILD/compile-linux-tools
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2002 Novell, Inc. All Rights Reserved.
|
||||
# Copyright (c) 2002 Novell, Inc. All Rights Reserved.
|
||||
#
|
||||
# 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
|
||||
@ -11,38 +11,37 @@
|
||||
# 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
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
INCLUDES = -I$(srcdir)/../include -I../include -I..
|
||||
bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
|
||||
mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
|
||||
mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
|
||||
mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
|
||||
libmysql_SOURCES= libmysqlmain.c
|
||||
libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a
|
||||
INCLUDES= -I$(srcdir)/../include -I../include -I..
|
||||
bin_PROGRAMS= mysqld_safe mysql_install_db mysql_test_run libmysql
|
||||
mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
|
||||
mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
|
||||
mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
|
||||
libmysql_SOURCES= libmysqlmain.c
|
||||
libmysql_LDADD= ../libmysql/.libs/libmysqlclient.a
|
||||
|
||||
netware_build_files = client/mysql.def client/mysqladmin.def \
|
||||
client/mysqlbinlog.def client/mysqlcheck.def \
|
||||
client/mysqldump.def client/mysqlimport.def \
|
||||
client/mysqlshow.def client/mysqltest.def \
|
||||
extra/mysql_install.def extra/my_print_defaults.def \
|
||||
extra/perror.def extra/replace.def \
|
||||
extra/resolveip.def extra/comp_err.def \
|
||||
isam/isamchk.def \
|
||||
isam/isamlog.def isam/pack_isam.def \
|
||||
libmysqld/libmysqld.def myisam/myisamchk.def \
|
||||
myisam/myisamlog.def myisam/myisampack.def \
|
||||
sql/mysqld.def
|
||||
|
||||
netware_build_files = client/mysql.def client/mysqladmin.def \
|
||||
client/mysqlbinlog.def client/mysqlcheck.def \
|
||||
client/mysqldump.def client/mysqlimport.def \
|
||||
client/mysqlshow.def client/mysqltest.def \
|
||||
extra/mysql_install.def extra/my_print_defaults.def \
|
||||
extra/perror.def extra/replace.def \
|
||||
extra/resolveip.def extra/comp_err.def \
|
||||
isam/isamchk.def \
|
||||
isam/isamlog.def isam/pack_isam.def \
|
||||
libmysqld/libmysqld.def myisam/myisamchk.def \
|
||||
myisam/myisamlog.def myisam/myisampack.def \
|
||||
sql/mysqld.def
|
||||
|
||||
link_sources:
|
||||
set -x; \
|
||||
for f in $(netware_build_files); do \
|
||||
rm -f $(srcdir)/../$$f; \
|
||||
org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \
|
||||
@LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \
|
||||
done;
|
||||
|
||||
set -x; \
|
||||
for f in $(netware_build_files); do \
|
||||
rm -f $(srcdir)/../$$f; \
|
||||
org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \
|
||||
@LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \
|
||||
done;
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
@ -1,90 +1,104 @@
|
||||
/*
|
||||
Copyright (c) 2003 Novell, Inc. All Rights Reserved.
|
||||
Copyright (c) 2003 MySQL AB
|
||||
Copyright (c) 2003 Novell, Inc.
|
||||
|
||||
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 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.
|
||||
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
|
||||
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
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <screen.h>
|
||||
#include <proc.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
/*****************************************************************************
|
||||
** Utility functions for support programs
|
||||
*****************************************************************************/
|
||||
|
||||
/* MySQL library headers */
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <my_dir.h>
|
||||
#include <m_string.h>
|
||||
|
||||
/* These 'should' be POSIX or ANSI */
|
||||
#include <assert.h> /* ASSERT */
|
||||
#include <stdarg.h> /* vsprintf, va_* */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#ifndef __WIN__
|
||||
#include <unistd.h> /* fork, rmdir, execve */
|
||||
#endif
|
||||
#include <stdio.h> /* freopen */
|
||||
#include <stdlib.h> /* FILE */
|
||||
#ifndef __WIN__
|
||||
#include <dirent.h> /* opendir, readdir */
|
||||
#endif
|
||||
|
||||
#if !defined(__NETWARE__) && !defined(__WIN__)
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__NETWARE__)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
/* For ASSERT -- Not totally sure about this one: */
|
||||
#if !defined(ASSERT)
|
||||
#define ASSERT(A) assert(A)
|
||||
#endif
|
||||
|
||||
#include "my_manage.h"
|
||||
|
||||
#define __STDC__ 1
|
||||
#include "process.h"
|
||||
/******************************************************************************
|
||||
|
||||
macros
|
||||
|
||||
******************************************************************************/
|
||||
init_args()
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
global variables
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
functions
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
init_args()
|
||||
|
||||
Init an argument list.
|
||||
Init an argument list.
|
||||
|
||||
******************************************************************************/
|
||||
void init_args(arg_list_t *al)
|
||||
{
|
||||
#ifndef __WIN__
|
||||
ASSERT(al != NULL);
|
||||
|
||||
|
||||
al->argc = 0;
|
||||
al->size = ARG_BUF;
|
||||
al->argv = malloc(al->size * sizeof(char *));
|
||||
al->argv = (char **)my_malloc(al->size * sizeof(char *), MYF(MY_WME));
|
||||
ASSERT(al->argv != NULL);
|
||||
|
||||
#else
|
||||
win_args[0]= '\0';
|
||||
skip_first_param= TRUE;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
add_arg()
|
||||
|
||||
Add an argument to a list.
|
||||
add_arg()
|
||||
|
||||
Add an argument to a list.
|
||||
|
||||
******************************************************************************/
|
||||
void add_arg(arg_list_t *al, char *format, ...)
|
||||
void add_arg(arg_list_t *al, const char *format, ...)
|
||||
{
|
||||
#ifndef __WIN__
|
||||
va_list ap;
|
||||
char temp[PATH_MAX];
|
||||
|
||||
ASSERT(al != NULL);
|
||||
|
||||
// increase size
|
||||
if (al->argc >= al->size)
|
||||
/* increase size */
|
||||
if (al->argc >= (int)al->size)
|
||||
{
|
||||
al->size += ARG_BUF;
|
||||
al->argv = realloc(al->argv, al->size * sizeof(char *));
|
||||
al->argv = (char **)my_realloc((char *)al->argv, al->size * sizeof(char *), MYF(MY_WME));
|
||||
ASSERT(al->argv != NULL);
|
||||
}
|
||||
|
||||
@ -94,7 +108,7 @@ void add_arg(arg_list_t *al, char *format, ...)
|
||||
vsprintf(temp, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
al->argv[al->argc] = malloc(strlen(temp)+1);
|
||||
al->argv[al->argc] = my_malloc(strlen(temp)+1, MYF(MY_WME));
|
||||
ASSERT(al->argv[al->argc] != NULL);
|
||||
strcpy(al->argv[al->argc], temp);
|
||||
|
||||
@ -104,19 +118,36 @@ void add_arg(arg_list_t *al, char *format, ...)
|
||||
{
|
||||
al->argv[al->argc] = NULL;
|
||||
}
|
||||
#else
|
||||
va_list ap;
|
||||
char param[PATH_MAX];
|
||||
|
||||
if (!skip_first_param)
|
||||
{
|
||||
va_start(ap, format);
|
||||
vsprintf(¶m, format, ap);
|
||||
va_end(ap);
|
||||
strcat(win_args," ");
|
||||
strcat(win_args,param);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip_first_param= FALSE;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
free_args()
|
||||
|
||||
Free an argument list.
|
||||
free_args()
|
||||
|
||||
Free an argument list.
|
||||
|
||||
******************************************************************************/
|
||||
void free_args(arg_list_t *al)
|
||||
{
|
||||
#ifndef __WIN__
|
||||
int i;
|
||||
|
||||
ASSERT(al != NULL);
|
||||
@ -124,74 +155,110 @@ void free_args(arg_list_t *al)
|
||||
for(i = 0; i < al->argc; i++)
|
||||
{
|
||||
ASSERT(al->argv[i] != NULL);
|
||||
free(al->argv[i]);
|
||||
my_free(al->argv[i], MYF(MY_WME));
|
||||
al->argv[i] = NULL;
|
||||
}
|
||||
|
||||
free(al->argv);
|
||||
my_free((char *)al->argv, MYF(MY_WME));
|
||||
al->argc = 0;
|
||||
al->argv = NULL;
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
sleep_until_file_deleted()
|
||||
|
||||
Sleep until the given file is no longer found.
|
||||
sleep_until_file_deleted()
|
||||
|
||||
Sleep until the given file is no longer found.
|
||||
|
||||
******************************************************************************/
|
||||
int sleep_until_file_deleted(char *pid_file)
|
||||
{
|
||||
struct stat buf;
|
||||
int i, err;
|
||||
|
||||
for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1);
|
||||
|
||||
if (err != 0) err = errno;
|
||||
|
||||
return err;
|
||||
MY_STAT stat_info;
|
||||
int i, err = 0;
|
||||
#ifndef __WIN__
|
||||
for(i = 0; i < TRY_MAX; i++)
|
||||
{
|
||||
if (my_stat(pid_file, &stat_info, MYF(0)) == (MY_STAT *) NULL)
|
||||
{
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
my_sleep(1);
|
||||
}
|
||||
#else
|
||||
switch (pid_mode)
|
||||
{
|
||||
case MASTER_PID:
|
||||
err= (WaitForSingleObject(master_server, TRY_MAX*1000) == WAIT_TIMEOUT);
|
||||
pid_mode= 0;
|
||||
break;
|
||||
case SLAVE_PID:
|
||||
err= (WaitForSingleObject(slave_server, TRY_MAX*1000) == WAIT_TIMEOUT);
|
||||
pid_mode= 0;
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
sleep_until_file_exists()
|
||||
|
||||
Sleep until the given file exists.
|
||||
sleep_until_file_exists()
|
||||
|
||||
Sleep until the given file exists.
|
||||
|
||||
******************************************************************************/
|
||||
int sleep_until_file_exists(char *pid_file)
|
||||
{
|
||||
struct stat buf;
|
||||
int i, err;
|
||||
|
||||
for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1);
|
||||
|
||||
if (err != 0) err = errno;
|
||||
|
||||
return err;
|
||||
MY_STAT stat_info;
|
||||
int i, err = 0;
|
||||
|
||||
#ifndef __WIN__
|
||||
for(i = 0; i < TRY_MAX; i++)
|
||||
{
|
||||
if (my_stat(pid_file, &stat_info, MYF(0)) == (MY_STAT *) NULL)
|
||||
{
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
my_sleep(1);
|
||||
}
|
||||
#else
|
||||
switch (pid_mode)
|
||||
{
|
||||
case MASTER_PID:
|
||||
WaitForSingleObject(master_server, TRY_MAX*1000);
|
||||
pid_mode= 0;
|
||||
break;
|
||||
case SLAVE_PID:
|
||||
WaitForSingleObject(slave_server, TRY_MAX*1000);
|
||||
pid_mode= 0;
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
wait_for_server_start()
|
||||
|
||||
Wait for the server on the given port to start.
|
||||
wait_for_server_start()
|
||||
|
||||
Wait for the server on the given port to start.
|
||||
|
||||
******************************************************************************/
|
||||
int wait_for_server_start(char *bin_dir, char *user, char *password, int port)
|
||||
{
|
||||
arg_list_t al;
|
||||
int err, i;
|
||||
char mysqladmin_file[PATH_MAX];
|
||||
int err = 0, i;
|
||||
char trash[PATH_MAX];
|
||||
|
||||
// mysqladmin file
|
||||
snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
|
||||
snprintf(trash, PATH_MAX, "/tmp/trash.out");
|
||||
|
||||
// args
|
||||
/* mysqladmin file */
|
||||
my_snprintf(trash, PATH_MAX, "/tmp/trash.out");
|
||||
|
||||
/* args */
|
||||
init_args(&al);
|
||||
add_arg(&al, "%s", mysqladmin_file);
|
||||
add_arg(&al, "--no-defaults");
|
||||
@ -205,13 +272,13 @@ int wait_for_server_start(char *bin_dir, char *user, char *password, int port)
|
||||
add_arg(&al, "--host=localhost");
|
||||
add_arg(&al, "ping");
|
||||
|
||||
// NetWare does not support the connect timeout in the TCP/IP stack
|
||||
// -- we will try the ping multiple times
|
||||
for(i = 0; (i < TRY_MAX)
|
||||
&& (err = spawn(mysqladmin_file, &al, TRUE, NULL,
|
||||
trash, NULL)); i++) sleep(1);
|
||||
|
||||
// free args
|
||||
/* NetWare does not support the connect timeout in the TCP/IP stack
|
||||
-- we will try the ping multiple times */
|
||||
for(i = 0; (i < TRY_MAX)
|
||||
&& (err = spawn(mysqladmin_file, &al, TRUE, NULL,
|
||||
trash, NULL, NOT_NEED_PID)); i++) sleep(1);
|
||||
|
||||
/* free args */
|
||||
free_args(&al);
|
||||
|
||||
return err;
|
||||
@ -219,20 +286,23 @@ int wait_for_server_start(char *bin_dir, char *user, char *password, int port)
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
spawn()
|
||||
|
||||
Spawn the given path with the given arguments.
|
||||
spawn()
|
||||
|
||||
Spawn the executable at the given path with the given arguments.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __NETWARE__
|
||||
|
||||
int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
char *output, char *error)
|
||||
{
|
||||
pid_t pid;
|
||||
pid_t pid;
|
||||
int result = 0;
|
||||
wiring_t wiring = { FD_UNUSED, FD_UNUSED, FD_UNUSED };
|
||||
unsigned long flags = PROC_CURRENT_SPACE | PROC_INHERIT_CWD;
|
||||
|
||||
// open wiring
|
||||
/* open wiring */
|
||||
if (input)
|
||||
wiring.infd = open(input, O_RDONLY);
|
||||
|
||||
@ -242,14 +312,14 @@ int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
if (error)
|
||||
wiring.errfd = open(error, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
|
||||
// procve requires a NULL
|
||||
/* procve requires a NULL */
|
||||
add_arg(al, NULL);
|
||||
|
||||
// go
|
||||
/* go */
|
||||
pid = procve(path, flags, NULL, &wiring, NULL, NULL, 0,
|
||||
NULL, (const char **)al->argv);
|
||||
|
||||
if (pid == -1)
|
||||
if (pid == -1)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
@ -257,8 +327,8 @@ int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
{
|
||||
waitpid(pid, &result, 0);
|
||||
}
|
||||
|
||||
// close wiring
|
||||
|
||||
/* close wiring */
|
||||
if (wiring.infd != -1)
|
||||
close(wiring.infd);
|
||||
|
||||
@ -268,207 +338,411 @@ int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
if (wiring.errfd != -1)
|
||||
close(wiring.errfd);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* NOT __NETWARE__ */
|
||||
|
||||
#ifdef __WIN__
|
||||
|
||||
int my_vsnprintf_(char *to, size_t n, const char* value, ...)
|
||||
{
|
||||
char *start=to, *end=to+n-1;
|
||||
uint length, num_state, pre_zero;
|
||||
reg2 char *par;// = value;
|
||||
va_list args;
|
||||
va_start(args,value);
|
||||
|
||||
par = va_arg(args, char *);
|
||||
while (par != NULL)
|
||||
{
|
||||
uint plen,left_len = (uint)(end-to)+1;
|
||||
if (!par) par = (char*)"(null)";
|
||||
plen = (uint) strlen(par);
|
||||
if (left_len <= plen)
|
||||
plen = left_len - 1;
|
||||
to=strnmov(to+strlen(to),par,plen);
|
||||
par = va_arg(args, char *);
|
||||
}
|
||||
va_end(args);
|
||||
DBUG_ASSERT(to <= end);
|
||||
*to='\0';
|
||||
return (uint) (to - start);
|
||||
}
|
||||
|
||||
int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
char *output, char *error)
|
||||
{
|
||||
char *cl;
|
||||
char *arg;
|
||||
intptr_t result;
|
||||
int j;
|
||||
int err;
|
||||
STARTUPINFO startup_info;
|
||||
PROCESS_INFORMATION process_information;
|
||||
ULONG dosretval;
|
||||
int retval;
|
||||
DWORD exit_code;
|
||||
SECURITY_ATTRIBUTES process_attributes, thread_attributes;
|
||||
char command_line[1024]= "";
|
||||
|
||||
|
||||
memset(&startup_info,0,sizeof(STARTUPINFO));
|
||||
startup_info.cb = sizeof(STARTUPINFO);
|
||||
|
||||
if (input)
|
||||
freopen(input, "rb", stdin);
|
||||
|
||||
if (output)
|
||||
freopen(output, "wb", stdout);
|
||||
|
||||
if (error)
|
||||
freopen(error, "wb", stderr);
|
||||
|
||||
result= CreateProcess(
|
||||
path,
|
||||
&win_args,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&startup_info,
|
||||
&process_information
|
||||
);
|
||||
|
||||
if (process_information.hProcess)
|
||||
{
|
||||
if (join)
|
||||
{
|
||||
if (WaitForSingleObject(process_information.hProcess, mysqld_timeout) == WAIT_TIMEOUT)
|
||||
{
|
||||
exit_code= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetExitCodeProcess(process_information.hProcess, &exit_code);
|
||||
}
|
||||
CloseHandle(process_information.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
exit_code= 0;
|
||||
}
|
||||
if (run_server)
|
||||
{
|
||||
switch (pid_mode)
|
||||
{
|
||||
case MASTER_PID:
|
||||
master_server= process_information.hProcess;
|
||||
break;
|
||||
case SLAVE_PID:
|
||||
slave_server= process_information.hProcess;
|
||||
break;
|
||||
};
|
||||
pid_mode= 0;
|
||||
run_server= FALSE;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
exit_code= -1;
|
||||
}
|
||||
if (input)
|
||||
freopen("CONIN$","rb",stdin);
|
||||
if (output)
|
||||
freopen("CONOUT$","wb",stdout);
|
||||
if (error)
|
||||
freopen("CONOUT$","wb",stderr);
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
#else /* NOT __NETWARE__, NOT __WIN__ */
|
||||
|
||||
/* This assumes full POSIX.1 compliance */
|
||||
int spawn(char *path, arg_list_t *al, int join, char *input,
|
||||
char *output, char *error)
|
||||
{
|
||||
int result = 0;
|
||||
pid_t pid;
|
||||
|
||||
if ((pid = fork()))
|
||||
{
|
||||
/* Remains in parent process */
|
||||
if (join && (pid != -1))
|
||||
waitpid(pid, &result, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Child process */
|
||||
|
||||
/* Reassign streams */
|
||||
if (input)
|
||||
freopen(input, "r", stdin);
|
||||
|
||||
if (output)
|
||||
freopen(output, "w", stdout);
|
||||
|
||||
if (error)
|
||||
freopen(error, "w", stderr);
|
||||
|
||||
/* Spawn the process */
|
||||
execve(path, al->argv, environ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* __WIN__ */
|
||||
|
||||
#endif /* __NETWARE__ */
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
stop_server()
|
||||
|
||||
Stop the server with the given port and pid file.
|
||||
stop_server()
|
||||
|
||||
Stop the server with the given port and pid file.
|
||||
|
||||
******************************************************************************/
|
||||
int stop_server(char *bin_dir, char *user, char *password, int port,
|
||||
char *pid_file)
|
||||
{
|
||||
arg_list_t al;
|
||||
int err, i, argc = 0;
|
||||
char mysqladmin_file[PATH_MAX];
|
||||
arg_list_t al;
|
||||
int err;
|
||||
char trash[PATH_MAX];
|
||||
|
||||
// mysqladmin file
|
||||
snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
|
||||
snprintf(trash, PATH_MAX, "/tmp/trash.out");
|
||||
|
||||
// args
|
||||
init_args(&al);
|
||||
add_arg(&al, "%s", mysqladmin_file);
|
||||
add_arg(&al, "--no-defaults");
|
||||
add_arg(&al, "--port=%u", port);
|
||||
add_arg(&al, "--user=%s", user);
|
||||
add_arg(&al, "--password=%s", password);
|
||||
add_arg(&al, "-O");
|
||||
add_arg(&al, "shutdown_timeout=20");
|
||||
add_arg(&al, "shutdown");
|
||||
my_snprintf(trash, PATH_MAX, "/tmp/trash.out");
|
||||
|
||||
// spawn
|
||||
if ((err = spawn(mysqladmin_file, &al, TRUE, NULL,
|
||||
trash, NULL)) == 0)
|
||||
{
|
||||
sleep_until_file_deleted(pid_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* args */
|
||||
init_args(&al);
|
||||
add_arg(&al, "%s", mysqladmin_file);
|
||||
add_arg(&al, "--no-defaults");
|
||||
add_arg(&al, "--port=%u", port);
|
||||
add_arg(&al, "--user=%s", user);
|
||||
add_arg(&al, "--password=%s", password);
|
||||
add_arg(&al, "-O");
|
||||
add_arg(&al, "shutdown_timeout=20");
|
||||
add_arg(&al, "shutdown");
|
||||
|
||||
/* spawn */
|
||||
if ((err = spawn(mysqladmin_file, &al, TRUE, NULL,
|
||||
trash, NULL)) == 0)
|
||||
{
|
||||
sleep_until_file_deleted(pid_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
pid_t pid = get_server_pid(pid_file);
|
||||
|
||||
// shutdown failed - kill server
|
||||
kill_server(pid);
|
||||
|
||||
sleep(TRY_MAX);
|
||||
|
||||
// remove pid file if possible
|
||||
err = remove(pid_file);
|
||||
/* shutdown failed - kill server */
|
||||
kill_server(pid);
|
||||
|
||||
sleep(TRY_MAX);
|
||||
|
||||
/* remove pid file if possible */
|
||||
err = my_delete(pid_file, MYF(MY_WME));
|
||||
}
|
||||
|
||||
// free args
|
||||
/* free args */
|
||||
free_args(&al);
|
||||
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
get_server_pid()
|
||||
|
||||
Get the VM id with the given pid file.
|
||||
get_server_pid()
|
||||
|
||||
Get the VM id with the given pid file.
|
||||
|
||||
******************************************************************************/
|
||||
pid_t get_server_pid(char *pid_file)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
int fd, err;
|
||||
char *p;
|
||||
pid_t id;
|
||||
|
||||
// discover id
|
||||
fd = open(pid_file, O_RDONLY);
|
||||
|
||||
err = read(fd, buf, PATH_MAX);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
// terminate string
|
||||
if ((p = strchr(buf, '\n')) != NULL)
|
||||
{
|
||||
*p = NULL;
|
||||
|
||||
// check for a '\r'
|
||||
if ((p = strchr(buf, '\r')) != NULL)
|
||||
{
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[err] = NULL;
|
||||
}
|
||||
|
||||
id = strtol(buf, NULL, 0);
|
||||
}
|
||||
char buf[PATH_MAX];
|
||||
int err;
|
||||
File fd;
|
||||
char *p;
|
||||
pid_t id = 0;
|
||||
|
||||
/* discover id */
|
||||
fd = my_open(pid_file, O_RDONLY, MYF(MY_WME));
|
||||
|
||||
err = my_read(fd, buf, PATH_MAX, MYF(MY_WME));
|
||||
|
||||
my_close(fd, MYF(MY_WME));
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
/* terminate string */
|
||||
if ((p = strchr(buf, '\n')) != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
|
||||
/* check for a '\r' */
|
||||
if ((p = strchr(buf, '\r')) != NULL)
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[err] = '\0';
|
||||
}
|
||||
|
||||
id = strtol(buf, NULL, 0);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
kill_server()
|
||||
|
||||
Force a kill of the server with the given pid.
|
||||
kill_server()
|
||||
|
||||
Force a kill of the server with the given pid.
|
||||
|
||||
******************************************************************************/
|
||||
void kill_server(pid_t pid)
|
||||
{
|
||||
if (pid > 0)
|
||||
{
|
||||
// destroy vm
|
||||
|
||||
#if !defined(__NETWARE__)
|
||||
/* Send SIGTERM to pid */
|
||||
kill(pid, SIGTERM);
|
||||
#else /* __NETWARE__ */
|
||||
/* destroy vm */
|
||||
NXVmDestroy(pid);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
del_tree()
|
||||
|
||||
Delete the directory and subdirectories.
|
||||
del_tree()
|
||||
|
||||
Delete the directory and subdirectories.
|
||||
|
||||
******************************************************************************/
|
||||
void del_tree(char *dir)
|
||||
{
|
||||
DIR *parent = opendir(dir);
|
||||
DIR *entry;
|
||||
char temp[PATH_MAX];
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while((entry = readdir(parent)) != NULL)
|
||||
{
|
||||
// create long name
|
||||
snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name);
|
||||
|
||||
if (entry->d_name[0] == '.')
|
||||
{
|
||||
// Skip
|
||||
}
|
||||
else if (S_ISDIR(entry->d_type))
|
||||
{
|
||||
// delete subdirectory
|
||||
del_tree(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove file
|
||||
remove(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// remove directory
|
||||
rmdir(dir);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
removef()
|
||||
|
||||
******************************************************************************/
|
||||
int removef(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char path[PATH_MAX];
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
vsnprintf(path, PATH_MAX, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
MY_DIR *current;
|
||||
uint i;
|
||||
char temp[PATH_MAX];
|
||||
|
||||
return remove(path);
|
||||
current = my_dir(dir, MYF(MY_WME | MY_WANT_STAT));
|
||||
|
||||
/* current is NULL if dir does not exist */
|
||||
if (current == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < current->number_off_files; i++)
|
||||
{
|
||||
/* create long name */
|
||||
my_snprintf(temp, PATH_MAX, "%s/%s", dir, current->dir_entry[i].name);
|
||||
|
||||
if (current->dir_entry[i].name[0] == '.')
|
||||
{
|
||||
/* Skip */
|
||||
}
|
||||
else if (MY_S_ISDIR(current->dir_entry[i].mystat.st_mode))
|
||||
{
|
||||
/* delete subdirectory */
|
||||
del_tree(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove file */
|
||||
my_delete(temp, MYF(MY_WME));
|
||||
}
|
||||
}
|
||||
|
||||
my_dirend(current);
|
||||
|
||||
/* remove directory */
|
||||
rmdir(dir);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
get_basedir()
|
||||
|
||||
removef()
|
||||
|
||||
******************************************************************************/
|
||||
int removef(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char path[PATH_MAX];
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
my_vsnprintf(path, PATH_MAX, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
#ifdef __WIN__
|
||||
{
|
||||
MY_DIR *current;
|
||||
uint i;
|
||||
struct _finddata_t find;
|
||||
char temp[PATH_MAX];
|
||||
#ifdef _WIN64
|
||||
__int64 handle;
|
||||
#else
|
||||
long handle;
|
||||
#endif
|
||||
char *p;
|
||||
|
||||
p= strrchr(path,'\\');
|
||||
if (p == NULL)
|
||||
{
|
||||
p= strrchr(path,'/');
|
||||
if (p == NULL)
|
||||
p= &path;
|
||||
else
|
||||
p++;
|
||||
}
|
||||
else
|
||||
p++;
|
||||
|
||||
if ((handle=_findfirst(path,&find)) == -1L)
|
||||
return 0;
|
||||
do
|
||||
{
|
||||
strcpy(p,find.name);
|
||||
my_delete(path, MYF(MY_WME));
|
||||
} while (!_findnext(handle,&find));
|
||||
_findclose(handle);
|
||||
}
|
||||
#else
|
||||
return my_delete(path, MYF(MY_WME));
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
get_basedir()
|
||||
|
||||
******************************************************************************/
|
||||
void get_basedir(char *argv0, char *basedir)
|
||||
{
|
||||
char temp[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
ASSERT(argv0 != NULL);
|
||||
char temp[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
ASSERT(argv0 != NULL);
|
||||
ASSERT(basedir != NULL);
|
||||
|
||||
strcpy(temp, strlwr(argv0));
|
||||
while((p = strchr(temp, '\\')) != NULL) *p = '/';
|
||||
|
||||
if ((p = strindex(temp, "/bin/")) != NULL)
|
||||
{
|
||||
*p = NULL;
|
||||
strcpy(basedir, temp);
|
||||
}
|
||||
strcpy(temp, argv0);
|
||||
#ifndef __WIN__
|
||||
casedn_str(temp);
|
||||
#endif
|
||||
while((p = strchr(temp, '\\')) != NULL) *p = '/';
|
||||
|
||||
if ((p = strstr(temp, "/bin/")) != NullS)
|
||||
{
|
||||
*p = '\0';
|
||||
strcpy(basedir, temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,17 +26,41 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifndef __WIN__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
macros
|
||||
|
||||
******************************************************************************/
|
||||
#ifdef __WIN__
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#define NAME_MAX _MAX_FNAME
|
||||
#define kill(A,B) TerminateProcess((HANDLE)A,0)
|
||||
#define NOT_NEED_PID 0
|
||||
#define MASTER_PID 1
|
||||
#define SLAVE_PID 2
|
||||
#define mysqld_timeout 60000
|
||||
|
||||
intptr_t master_server;
|
||||
intptr_t slave_server;
|
||||
int pid_mode;
|
||||
bool run_server;
|
||||
char win_args[1024];
|
||||
bool skip_first_param;
|
||||
#endif
|
||||
|
||||
|
||||
#define ARG_BUF 10
|
||||
#define TRY_MAX 5
|
||||
|
||||
#ifdef __NETWARE__
|
||||
#define strstr(A,B) strindex(A,B)
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
structures
|
||||
@ -53,6 +77,8 @@ typedef struct
|
||||
|
||||
} arg_list_t;
|
||||
|
||||
|
||||
typedef int pid_t;
|
||||
/******************************************************************************
|
||||
|
||||
global variables
|
||||
@ -66,7 +92,7 @@ typedef struct
|
||||
******************************************************************************/
|
||||
|
||||
void init_args(arg_list_t *);
|
||||
void add_arg(arg_list_t *, char *, ...);
|
||||
void add_arg(arg_list_t *, const char *, ...);
|
||||
void free_args(arg_list_t *);
|
||||
|
||||
int sleep_until_file_exists(char *);
|
||||
@ -80,8 +106,12 @@ pid_t get_server_pid(char *);
|
||||
void kill_server(pid_t pid);
|
||||
|
||||
void del_tree(char *);
|
||||
int removef(char *, ...);
|
||||
int removef(const char *, ...);
|
||||
|
||||
void get_basedir(char *, char *);
|
||||
|
||||
char mysqladmin_file[PATH_MAX];
|
||||
|
||||
#endif /* _MY_MANAGE */
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -85,8 +85,25 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
for i in COPYING COPYING.LIB README Docs/INSTALL-BINARY \
|
||||
MySQLEULA.txt LICENSE.doc README.NW
|
||||
# Non platform-specific doc files:
|
||||
DOC_FILES=" \
|
||||
COPYING COPYING.LIB README LICENSE.doc \
|
||||
Docs/mysqlbug.txt \
|
||||
";
|
||||
|
||||
# Platform-specific doc files:
|
||||
if [ $BASE_SYSTEM = "netware" ] ; then
|
||||
DOC_FILES="$DOC_FILES \
|
||||
README.NW \
|
||||
";
|
||||
# For all other platforms:
|
||||
else
|
||||
DOC_FILES="$DOC_FILES \
|
||||
Docs/INSTALL-BINARY MySQLEULA.txt \
|
||||
";
|
||||
fi
|
||||
|
||||
for i in $DOC_FILES
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
@ -94,7 +111,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
# Non platform-specific bin dir files:
|
||||
# Non platform-specific bin files:
|
||||
BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
|
||||
extra/resolveip$BS extra/my_print_defaults$BS \
|
||||
extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \
|
||||
@ -104,18 +121,18 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
|
||||
client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
|
||||
client/mysqldump$BS client/mysqlimport$BS \
|
||||
client/mysqltest$BS client/mysqlcheck$BS \
|
||||
client/mysqlbinlog$BS
|
||||
client/mysqlbinlog$BS \
|
||||
";
|
||||
|
||||
# Platform-specific bin dir files:
|
||||
# Platform-specific bin files:
|
||||
if [ $BASE_SYSTEM = "netware" ] ; then
|
||||
BIN_FILES="$BIN_FILES \
|
||||
netware/mysqld_safe$BS netware/mysql_install_db$BS \
|
||||
netware/init_db.sql netware/test_db.sql netware/mysql_explain_log$BS \
|
||||
netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql
|
||||
netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql \
|
||||
";
|
||||
# For all other platforms:
|
||||
else
|
||||
# For all other platforms:
|
||||
BIN_FILES="$BIN_FILES \
|
||||
client/mysqlmanagerc \
|
||||
client/mysqlmanager-pwgen tools/mysqlmanager \
|
||||
@ -235,7 +252,9 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh $BASE/bin/mysql_install_
|
||||
|
||||
# Make safe_mysqld a symlink to mysqld_safe for backwards portability
|
||||
# To be removed in MySQL 4.1
|
||||
(cd $BASE/bin ; ln -s mysqld_safe safe_mysqld )
|
||||
if [ $BASE_SYSTEM != "netware" ] ; then
|
||||
(cd $BASE/bin ; ln -s mysqld_safe safe_mysqld )
|
||||
fi
|
||||
|
||||
# Clean up if we did this from a bk tree
|
||||
if [ -d $BASE/sql-bench/SCCS ] ; then
|
||||
@ -294,29 +313,48 @@ which_1 ()
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Create the result tar file
|
||||
#
|
||||
|
||||
tar=`which_1 gnutar gtar`
|
||||
if test "$?" = "1" -o "$tar" = ""
|
||||
then
|
||||
tar=tar
|
||||
fi
|
||||
|
||||
echo "Using $tar to create archive"
|
||||
cd $TMP
|
||||
|
||||
if [ $BASE_SYSTEM = "netware" ] ; then
|
||||
|
||||
#
|
||||
# Create a zip file for NetWare users
|
||||
#
|
||||
|
||||
if test -e "$SOURCE/$NEW_NAME.zip"; then rm $SOURCE/$NEW_NAME.zip; fi
|
||||
zip -r $SOURCE/$NEW_NAME.zip $NEW_NAME
|
||||
echo "$NEW_NAME.zip created"
|
||||
|
||||
else
|
||||
|
||||
#
|
||||
# Create the result tar file
|
||||
#
|
||||
|
||||
tar=`which_1 gnutar gtar`
|
||||
if test "$?" = "1" -o "$tar" = ""
|
||||
then
|
||||
tar=tar
|
||||
fi
|
||||
|
||||
echo "Using $tar to create archive"
|
||||
|
||||
OPT=cvf
|
||||
if [ x$SILENT = x1 ] ; then
|
||||
OPT=cf
|
||||
fi
|
||||
|
||||
$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME
|
||||
cd $SOURCE
|
||||
|
||||
echo "Compressing archive"
|
||||
gzip -9 $NEW_NAME.tar
|
||||
|
||||
echo "$NEW_NAME.tar.gz created"
|
||||
|
||||
OPT=cvf
|
||||
if [ x$SILENT = x1 ] ; then
|
||||
OPT=cf
|
||||
fi
|
||||
|
||||
$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME
|
||||
cd $SOURCE
|
||||
echo "Compressing archive"
|
||||
gzip -9 $NEW_NAME.tar
|
||||
echo "Removing temporary directory"
|
||||
rm -r -f $BASE
|
||||
|
||||
echo "$NEW_NAME.tar.gz created"
|
||||
|
||||
|
@ -39,6 +39,7 @@ c_hc=""
|
||||
c_hr=""
|
||||
c_hk=""
|
||||
i_ht=""
|
||||
c_p=""
|
||||
|
||||
# Check for old tables
|
||||
if test ! -f $mdata/db.frm
|
||||
@ -285,6 +286,22 @@ then
|
||||
c_hr="$c_hr comment='keyword-topic relation';"
|
||||
fi
|
||||
|
||||
if test ! -f $mdata/proc.frm
|
||||
then
|
||||
c_p="$c_p CREATE TABLE proc ("
|
||||
c_p="$c_p name char(64) binary DEFAULT '' NOT NULL,"
|
||||
c_p="$c_p type enum('function','procedure') NOT NULL,"
|
||||
c_p="$c_p body blob DEFAULT '' NOT NULL,"
|
||||
c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL,"
|
||||
c_p="$c_p modified timestamp,"
|
||||
c_p="$c_p created timestamp,"
|
||||
c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL,"
|
||||
c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL,"
|
||||
c_p="$c_p PRIMARY KEY (name,type)"
|
||||
c_p="$c_p )"
|
||||
c_p="$c_p comment='Stored Procedures';"
|
||||
fi
|
||||
|
||||
cat << END_OF_DATA
|
||||
use mysql;
|
||||
$c_d
|
||||
@ -306,5 +323,8 @@ $c_ht
|
||||
$c_hc
|
||||
$c_hr
|
||||
$c_hk
|
||||
|
||||
$c_p
|
||||
|
||||
END_OF_DATA
|
||||
|
||||
|
@ -134,3 +134,20 @@ name varchar(64) not null,
|
||||
primary key (help_keyword_id),
|
||||
unique index (name)
|
||||
) comment='help keywords';
|
||||
|
||||
#
|
||||
# Create proc table if it doesn't exists
|
||||
#
|
||||
|
||||
CREATE TABLE IF NOT EXISTS proc (
|
||||
name char(64) binary DEFAULT '' NOT NULL,
|
||||
type enum('function','procedure') NOT NULL,
|
||||
body blob DEFAULT '' NOT NULL,
|
||||
creator char(77) binary DEFAULT '' NOT NULL,
|
||||
modified timestamp,
|
||||
created timestamp,
|
||||
suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL,
|
||||
comment char(64) binary DEFAULT '' NOT NULL,
|
||||
PRIMARY KEY (name,type)
|
||||
) comment='Stored Procedures';
|
||||
|
||||
|
@ -58,6 +58,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
||||
log_event.h sql_repl.h slave.h \
|
||||
stacktrace.h sql_sort.h sql_cache.h set_var.h \
|
||||
spatial.h gstream.h client_settings.h
|
||||
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h
|
||||
mysqld_SOURCES = sql_lex.cc sql_handler.cc \
|
||||
item.cc item_sum.cc item_buff.cc item_func.cc \
|
||||
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
|
||||
@ -86,7 +87,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
|
||||
slave.cc sql_repl.cc sql_union.cc sql_derived.cc \
|
||||
client.c sql_client.cc mini_client_errors.c pack.c\
|
||||
stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\
|
||||
gstream.cc spatial.cc sql_help.cc protocol_cursor.cc
|
||||
gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \
|
||||
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
|
||||
sp_cache.cc
|
||||
gen_lex_hash_SOURCES = gen_lex_hash.cc
|
||||
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
|
||||
|
||||
|
@ -330,7 +330,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
byte *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
|
||||
my_off_t record;
|
||||
TABLE *sort_form;
|
||||
volatile bool *killed= ¤t_thd->killed;
|
||||
volatile THD::killed_state *killed= ¤t_thd->killed;
|
||||
handler *file;
|
||||
DBUG_ENTER("find_all_keys");
|
||||
DBUG_PRINT("info",("using: %s",(select?select->quick?"ranges":"where":"every row")));
|
||||
@ -774,15 +774,15 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||
BUFFPEK *buffpek,**refpek;
|
||||
QUEUE queue;
|
||||
qsort2_cmp cmp;
|
||||
volatile bool *killed= ¤t_thd->killed;
|
||||
bool not_killable;
|
||||
volatile THD::killed_state *killed= ¤t_thd->killed;
|
||||
THD::killed_state not_killable;
|
||||
DBUG_ENTER("merge_buffers");
|
||||
|
||||
statistic_increment(filesort_merge_passes, &LOCK_status);
|
||||
if (param->not_killable)
|
||||
{
|
||||
killed= ¬_killable;
|
||||
not_killable= 0;
|
||||
not_killable=THD::NOT_KILLED;
|
||||
}
|
||||
|
||||
error=0;
|
||||
@ -1128,7 +1128,7 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
|
||||
The fact is the filter 'field->query_id != thd->query_id'
|
||||
doesn't work for alter table
|
||||
*/
|
||||
if (thd->lex.sql_command != SQLCOM_SELECT)
|
||||
if (thd->lex->sql_command != SQLCOM_SELECT)
|
||||
return 0;
|
||||
for (pfield= ptabfield; (field= *pfield) ; pfield++)
|
||||
{
|
||||
|
@ -2113,7 +2113,7 @@ static void print_msg(THD *thd, const char *table_name, const char *op_name,
|
||||
protocol->store(msg_type);
|
||||
protocol->store(msgbuf);
|
||||
if (protocol->write())
|
||||
thd->killed=1;
|
||||
thd->killed=THD::KILL_CONNECTION;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2253,8 +2253,8 @@ ha_innobase::write_row(
|
||||
skip_auto_inc_decr = FALSE;
|
||||
|
||||
if (error == DB_DUPLICATE_KEY
|
||||
&& (user_thd->lex.sql_command == SQLCOM_REPLACE
|
||||
|| user_thd->lex.sql_command
|
||||
&& (user_thd->lex->sql_command == SQLCOM_REPLACE
|
||||
|| user_thd->lex->sql_command
|
||||
== SQLCOM_REPLACE_SELECT)) {
|
||||
|
||||
skip_auto_inc_decr= TRUE;
|
||||
|
@ -89,9 +89,9 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
|
||||
|
||||
extern "C" {
|
||||
|
||||
volatile bool *killed_ptr(MI_CHECK *param)
|
||||
int *killed_ptr(void *thd)
|
||||
{
|
||||
return &(((THD *)(param->thd))->killed);
|
||||
return (int*)&((THD *)thd)->killed;
|
||||
}
|
||||
|
||||
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
|
||||
@ -391,7 +391,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
|
||||
int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
HA_CHECK_OPT tmp_check_opt;
|
||||
char* backup_dir = thd->lex.backup_dir;
|
||||
char* backup_dir = thd->lex->backup_dir;
|
||||
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
|
||||
char* table_name = table->real_name;
|
||||
int error;
|
||||
@ -431,7 +431,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
|
||||
|
||||
int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
char* backup_dir = thd->lex.backup_dir;
|
||||
char* backup_dir = thd->lex->backup_dir;
|
||||
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
|
||||
char* table_name = table->real_name;
|
||||
int error;
|
||||
|
@ -70,6 +70,37 @@ const char *tx_isolation_names[] =
|
||||
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
|
||||
tx_isolation_names};
|
||||
|
||||
enum db_type ha_resolve_by_name(char *name, uint namelen)
|
||||
{
|
||||
enum db_type result = DB_TYPE_UNKNOWN;
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "HEAP") ||
|
||||
!my_strcasecmp(&my_charset_latin1, name, "MEMORY")) {
|
||||
result = DB_TYPE_HEAP;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "MRG_MYISAM") ||
|
||||
!my_strcasecmp(&my_charset_latin1, name, "MERGE")) {
|
||||
result = DB_TYPE_MRG_MYISAM;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "MYISAM")) {
|
||||
result = DB_TYPE_MYISAM;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "BDB") ||
|
||||
!my_strcasecmp(&my_charset_latin1, name, "BERKELEYDB")) {
|
||||
result = DB_TYPE_BERKELEY_DB;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "INNODB") ||
|
||||
!my_strcasecmp(&my_charset_latin1, name, "INNOBASE")) {
|
||||
result = DB_TYPE_INNODB;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "ISAM")) {
|
||||
result = DB_TYPE_ISAM;
|
||||
} else
|
||||
if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) {
|
||||
result = (enum db_type) current_thd->variables.table_type;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Use other database handler if databasehandler is not incompiled */
|
||||
|
||||
enum db_type ha_checktype(enum db_type database_type)
|
||||
@ -77,18 +108,21 @@ enum db_type ha_checktype(enum db_type database_type)
|
||||
switch (database_type) {
|
||||
#ifdef HAVE_BERKELEY_DB
|
||||
case DB_TYPE_BERKELEY_DB:
|
||||
return(berkeley_skip ? DB_TYPE_MYISAM : database_type);
|
||||
if (berkeley_skip) break;
|
||||
return (database_type);
|
||||
#endif
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
case DB_TYPE_INNODB:
|
||||
return(innodb_skip ? DB_TYPE_MYISAM : database_type);
|
||||
if (innodb_skip) break;
|
||||
return (database_type);
|
||||
#endif
|
||||
#ifndef NO_HASH
|
||||
case DB_TYPE_HASH:
|
||||
#endif
|
||||
#ifdef HAVE_ISAM
|
||||
case DB_TYPE_ISAM:
|
||||
return (isam_skip ? DB_TYPE_MYISAM : database_type);
|
||||
if (isam_skip) break;
|
||||
return (database_type);
|
||||
case DB_TYPE_MRG_ISAM:
|
||||
return (isam_skip ? DB_TYPE_MRG_MYISAM : database_type);
|
||||
#else
|
||||
@ -102,7 +136,12 @@ enum db_type ha_checktype(enum db_type database_type)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return(DB_TYPE_MYISAM); /* Use this as default */
|
||||
/* Use this as default */
|
||||
#if 0
|
||||
return((enum db_type) current_thd->variables.table_type);
|
||||
#else
|
||||
return(DB_TYPE_MYISAM);
|
||||
#endif
|
||||
} /* ha_checktype */
|
||||
|
||||
|
||||
|
@ -383,6 +383,7 @@ extern TYPELIB ha_table_typelib, tx_isolation_typelib;
|
||||
|
||||
#define ha_supports_generate(T) (T != DB_TYPE_INNODB)
|
||||
|
||||
enum db_type ha_resolve_by_name(char *name, uint namelen);
|
||||
handler *get_new_handler(TABLE *table, enum db_type db_type);
|
||||
my_off_t ha_get_ptr(byte *ptr, uint pack_length);
|
||||
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
|
||||
|
53
sql/item.cc
53
sql/item.cc
@ -22,6 +22,7 @@
|
||||
#include "mysql_priv.h"
|
||||
#include <m_ctype.h>
|
||||
#include "my_dir.h"
|
||||
#include "sp_rcontext.h"
|
||||
|
||||
static void mark_as_dependent(THD *thd,
|
||||
SELECT_LEX *last, SELECT_LEX *current,
|
||||
@ -39,7 +40,7 @@ void item_init(void)
|
||||
}
|
||||
|
||||
Item::Item():
|
||||
fixed(0)
|
||||
name_length(0), fixed(0)
|
||||
{
|
||||
marker= 0;
|
||||
maybe_null=null_value=with_sum_func=unsigned_flag=0;
|
||||
@ -56,13 +57,13 @@ Item::Item():
|
||||
command => we should check thd->lex.current_select on zero (thd->lex
|
||||
can be uninitialised)
|
||||
*/
|
||||
if (thd->lex.current_select)
|
||||
if (thd->lex->current_select)
|
||||
{
|
||||
SELECT_LEX_NODE::enum_parsing_place place=
|
||||
thd->lex.current_select->parsing_place;
|
||||
thd->lex->current_select->parsing_place;
|
||||
if (place == SELECT_LEX_NODE::SELECT_LIST ||
|
||||
place == SELECT_LEX_NODE::IN_HAVING)
|
||||
thd->lex.current_select->select_n_having_items++;
|
||||
thd->lex->current_select->select_n_having_items++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +137,7 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
|
||||
{
|
||||
/* Empty string, used by AS or internal function like last_insert_id() */
|
||||
name= (char*) str;
|
||||
name_length= 0;
|
||||
return;
|
||||
}
|
||||
while (length && !my_isgraph(cs,*str))
|
||||
@ -146,12 +148,12 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
|
||||
if (!my_charset_same(cs, system_charset_info))
|
||||
{
|
||||
uint32 res_length;
|
||||
name= sql_strmake_with_convert(str, length, cs,
|
||||
name= sql_strmake_with_convert(str, name_length= length, cs,
|
||||
MAX_ALIAS_NAME, system_charset_info,
|
||||
&res_length);
|
||||
}
|
||||
else
|
||||
name=sql_strmake(str, min(length,MAX_ALIAS_NAME));
|
||||
name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
|
||||
}
|
||||
|
||||
|
||||
@ -221,6 +223,23 @@ CHARSET_INFO * Item::default_charset() const
|
||||
return current_thd->variables.collation_connection;
|
||||
}
|
||||
|
||||
|
||||
Item *
|
||||
Item_splocal::this_item()
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
return thd->spcont->get_item(m_offset);
|
||||
}
|
||||
|
||||
Item *
|
||||
Item_splocal::this_const_item() const
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
|
||||
return thd->spcont->get_item(m_offset);
|
||||
}
|
||||
|
||||
bool DTCollation::aggregate(DTCollation &dt)
|
||||
{
|
||||
if (!my_charset_same(collation, dt.collation))
|
||||
@ -790,7 +809,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
|
||||
// store pointer on SELECT_LEX from wich item is dependent
|
||||
item->depended_from= last;
|
||||
current->mark_as_dependent(last);
|
||||
if (thd->lex.describe & DESCRIBE_EXTENDED)
|
||||
if (thd->lex->describe & DESCRIBE_EXTENDED)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_WARN_FIELD_RESOLVED),
|
||||
@ -831,7 +850,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
Item **refer= (Item **)not_found_item;
|
||||
uint counter;
|
||||
// Prevent using outer fields in subselects, that is not supported now
|
||||
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
|
||||
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex->current_select;
|
||||
if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
|
||||
{
|
||||
SELECT_LEX_UNIT *prev_unit= cursel->master_unit();
|
||||
@ -1407,7 +1426,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
TABLE_LIST *where= 0, *table_list;
|
||||
bool upward_lookup= 0;
|
||||
SELECT_LEX_UNIT *prev_unit= thd->lex.current_select->master_unit();
|
||||
SELECT_LEX_UNIT *prev_unit= thd->lex->current_select->master_unit();
|
||||
SELECT_LEX *sl= prev_unit->outer_select();
|
||||
/*
|
||||
Finding only in current select will be performed for selects that have
|
||||
@ -1415,10 +1434,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
fields for now)
|
||||
*/
|
||||
if ((ref= find_item_in_list(this,
|
||||
*(thd->lex.current_select->get_item_list()),
|
||||
*(thd->lex->current_select->get_item_list()),
|
||||
&counter,
|
||||
((sl &&
|
||||
thd->lex.current_select->master_unit()->
|
||||
thd->lex->current_select->master_unit()->
|
||||
first_select()->linkage !=
|
||||
DERIVED_TABLE_TYPE) ?
|
||||
REPORT_EXCEPT_NOT_FOUND :
|
||||
@ -1494,7 +1513,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
// Call to report error
|
||||
find_item_in_list(this,
|
||||
*(thd->lex.current_select->get_item_list()),
|
||||
*(thd->lex->current_select->get_item_list()),
|
||||
&counter,
|
||||
REPORT_ALL_ERRORS);
|
||||
}
|
||||
@ -1507,7 +1526,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
Item_field* fld;
|
||||
if (!((*reference)= fld= new Item_field(tmp)))
|
||||
return 1;
|
||||
mark_as_dependent(thd, last, thd->lex.current_select, fld);
|
||||
mark_as_dependent(thd, last, thd->lex->current_select, fld);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@ -1518,7 +1537,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
mark_as_dependent(thd, last, thd->lex.current_select,
|
||||
mark_as_dependent(thd, last, thd->lex->current_select,
|
||||
this);
|
||||
ref= last->ref_pointer_array + counter;
|
||||
}
|
||||
@ -1533,7 +1552,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
ref= thd->lex.current_select->ref_pointer_array + counter;
|
||||
ref= thd->lex->current_select->ref_pointer_array + counter;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1546,8 +1565,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
*/
|
||||
if (((*ref)->with_sum_func && name &&
|
||||
(depended_from ||
|
||||
!(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE &&
|
||||
thd->lex.current_select->having_fix_field))) ||
|
||||
!(thd->lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
|
||||
thd->lex->current_select->having_fix_field))) ||
|
||||
!(*ref)->fixed)
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
|
71
sql/item.h
71
sql/item.h
@ -106,6 +106,7 @@ public:
|
||||
my_string name; /* Name from select */
|
||||
Item *next;
|
||||
uint32 max_length;
|
||||
uint name_length; /* Length of name */
|
||||
uint8 marker,decimals;
|
||||
my_bool maybe_null; /* If item may be null */
|
||||
my_bool null_value; /* if item is null */
|
||||
@ -203,6 +204,9 @@ public:
|
||||
virtual bool remove_dependence_processor(byte * arg) { return 0; }
|
||||
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
|
||||
|
||||
virtual Item *this_item() { return this; } /* For SPs mostly. */
|
||||
virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
|
||||
|
||||
// Row emulation
|
||||
virtual uint cols() { return 1; }
|
||||
virtual Item* el(uint i) { return this; }
|
||||
@ -220,6 +224,73 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// A local SP variable (incl. parameters), used in runtime
|
||||
class Item_splocal : public Item
|
||||
{
|
||||
private:
|
||||
|
||||
uint m_offset;
|
||||
|
||||
public:
|
||||
|
||||
Item_splocal(uint offset)
|
||||
: m_offset(offset)
|
||||
{
|
||||
Item::maybe_null= TRUE;
|
||||
}
|
||||
|
||||
Item *this_item();
|
||||
Item *this_const_item() const;
|
||||
|
||||
inline uint get_offset()
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
// Abstract methods inherited from Item. Just defer the call to
|
||||
// the item in the frame
|
||||
inline enum Type type() const
|
||||
{
|
||||
return this_const_item()->type();
|
||||
}
|
||||
|
||||
inline double val()
|
||||
{
|
||||
return this_item()->val();
|
||||
}
|
||||
|
||||
inline longlong val_int()
|
||||
{
|
||||
return this_item()->val_int();
|
||||
}
|
||||
|
||||
inline String *val_str(String *sp)
|
||||
{
|
||||
return this_item()->val_str(sp);
|
||||
}
|
||||
|
||||
inline void make_field(Send_field *field)
|
||||
{
|
||||
this_item()->make_field(field);
|
||||
}
|
||||
|
||||
inline Item_result result_type() const
|
||||
{
|
||||
return this_const_item()->result_type();
|
||||
}
|
||||
|
||||
inline bool const_item() const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
inline int save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
return this_item()->save_in_field(field, no_conversions);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class st_select_lex;
|
||||
class Item_ident :public Item
|
||||
{
|
||||
|
@ -1696,7 +1696,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
if (item->maybe_null)
|
||||
maybe_null=1;
|
||||
}
|
||||
thd->lex.current_select->cond_count+=list.elements;
|
||||
thd->lex->current_select->cond_count+=list.elements;
|
||||
fix_length_and_dec();
|
||||
fixed= 1;
|
||||
return 0;
|
||||
|
@ -76,7 +76,7 @@ Item *create_func_ceiling(Item* a)
|
||||
Item *create_func_connection_id(void)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
thd->lex.safe_to_cache_query=0;
|
||||
thd->lex->safe_to_cache_query=0;
|
||||
return new Item_int(NullS,(longlong)
|
||||
((thd->slave_thread) ?
|
||||
thd->variables.pseudo_thread_id :
|
||||
@ -148,7 +148,7 @@ Item *create_func_floor(Item* a)
|
||||
Item *create_func_found_rows(void)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
thd->lex.safe_to_cache_query=0;
|
||||
thd->lex->safe_to_cache_query=0;
|
||||
return new Item_int(NullS,(longlong) thd->found_rows(),21);
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ Item *create_func_from_days(Item* a)
|
||||
|
||||
Item *create_func_get_lock(Item* a, Item *b)
|
||||
{
|
||||
current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
return new Item_func_get_lock(a, b);
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ Item *create_func_radians(Item *a)
|
||||
|
||||
Item *create_func_release_lock(Item* a)
|
||||
{
|
||||
current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
return new Item_func_release_lock(a);
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ Item *create_func_year(Item* a)
|
||||
|
||||
Item *create_load_file(Item* a)
|
||||
{
|
||||
current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
return new Item_load_file(a);
|
||||
}
|
||||
|
||||
@ -472,13 +472,13 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len,
|
||||
|
||||
Item *create_func_is_free_lock(Item* a)
|
||||
{
|
||||
current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
return new Item_func_is_free_lock(a);
|
||||
}
|
||||
|
||||
Item *create_func_is_used_lock(Item* a)
|
||||
{
|
||||
current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
return new Item_func_is_used_lock(a);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,9 @@
|
||||
#include <time.h>
|
||||
#include <ft_global.h>
|
||||
|
||||
#include "sp_head.h"
|
||||
#include "sp_rcontext.h"
|
||||
#include "sp.h"
|
||||
|
||||
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
|
||||
const char *fname)
|
||||
@ -1492,11 +1495,16 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
|
||||
const_item_cache&=item->const_item();
|
||||
f_args.arg_type[i]=item->result_type();
|
||||
}
|
||||
//TODO: why all folowing memory is not allocated with 1 call of sql_alloc?
|
||||
if (!(buffers=new String[arg_count]) ||
|
||||
!(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) ||
|
||||
!(f_args.lengths=(ulong*) sql_alloc(arg_count * sizeof(long))) ||
|
||||
!(f_args.maybe_null=(char*) sql_alloc(arg_count * sizeof(char))) ||
|
||||
!(num_buffer= (char*) sql_alloc(ALIGN_SIZE(sizeof(double))*arg_count)))
|
||||
!(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) ||
|
||||
!(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) ||
|
||||
!(num_buffer= (char*) sql_alloc(arg_count *
|
||||
ALIGN_SIZE(sizeof(double)))) ||
|
||||
!(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) ||
|
||||
!(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count *
|
||||
sizeof(long))))
|
||||
{
|
||||
free_udf(u_d);
|
||||
DBUG_RETURN(1);
|
||||
@ -1515,8 +1523,10 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
|
||||
for (uint i=0; i < arg_count; i++)
|
||||
{
|
||||
f_args.args[i]=0;
|
||||
f_args.lengths[i]=arguments[i]->max_length;
|
||||
f_args.maybe_null[i]=(char) arguments[i]->maybe_null;
|
||||
f_args.lengths[i]= arguments[i]->max_length;
|
||||
f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
|
||||
f_args.attributes[i]= arguments[i]->name;
|
||||
f_args.attribute_lengths[i]= arguments[i]->name_length;
|
||||
|
||||
switch(arguments[i]->type()) {
|
||||
case Item::STRING_ITEM: // Constant string !
|
||||
@ -2486,8 +2496,7 @@ void Item_func_get_user_var::fix_length_and_dec()
|
||||
|
||||
if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
|
||||
null_value= 1;
|
||||
|
||||
if (!(opt_bin_log && is_update_query(thd->lex.sql_command)))
|
||||
if (!(opt_bin_log && is_update_query(thd->lex->sql_command)))
|
||||
return;
|
||||
|
||||
if (!var_entry)
|
||||
@ -2950,7 +2959,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
|
||||
}
|
||||
if (!(item=var->item(thd, var_type, component_name)))
|
||||
return 0; // Impossible
|
||||
thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
buff[0]='@';
|
||||
buff[1]='@';
|
||||
pos=buff+2;
|
||||
@ -2990,7 +2999,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
|
||||
DBUG_ASSERT(var != 0);
|
||||
if (!(item=var->item(thd, var_type, &null_lex_string)))
|
||||
return 0; // Impossible
|
||||
thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
item->set_name(item_name, 0, system_charset_info); // Will use original name
|
||||
return item;
|
||||
}
|
||||
@ -3051,3 +3060,74 @@ longlong Item_func_is_used_lock::val_int()
|
||||
null_value=0;
|
||||
return ull->thread_id;
|
||||
}
|
||||
|
||||
int
|
||||
Item_func_sp::execute(Item **itp)
|
||||
{
|
||||
DBUG_ENTER("Item_func_sp::execute");
|
||||
THD *thd= current_thd;
|
||||
|
||||
if (! m_sp)
|
||||
m_sp= sp_find_function(thd, &m_name);
|
||||
if (! m_sp)
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
DBUG_RETURN(m_sp->execute_function(thd, args, arg_count, itp));
|
||||
}
|
||||
|
||||
enum enum_field_types
|
||||
Item_func_sp::field_type() const
|
||||
{
|
||||
DBUG_ENTER("Item_func_sp::field_type");
|
||||
|
||||
if (! m_sp)
|
||||
m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name));
|
||||
if (m_sp)
|
||||
{
|
||||
DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns));
|
||||
DBUG_RETURN(m_sp->m_returns);
|
||||
}
|
||||
DBUG_RETURN(MYSQL_TYPE_STRING);
|
||||
}
|
||||
|
||||
Item_result
|
||||
Item_func_sp::result_type() const
|
||||
{
|
||||
DBUG_ENTER("Item_func_sp::result_type");
|
||||
DBUG_PRINT("info", ("m_sp = %p", m_sp));
|
||||
|
||||
if (! m_sp)
|
||||
m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name));
|
||||
if (m_sp)
|
||||
{
|
||||
DBUG_RETURN(m_sp->result());
|
||||
}
|
||||
DBUG_RETURN(STRING_RESULT);
|
||||
}
|
||||
|
||||
void
|
||||
Item_func_sp::fix_length_and_dec()
|
||||
{
|
||||
DBUG_ENTER("Item_func_sp::fix_length_and_dec");
|
||||
|
||||
if (! m_sp)
|
||||
m_sp= sp_find_function(current_thd, &m_name);
|
||||
if (m_sp)
|
||||
{
|
||||
switch (m_sp->result()) {
|
||||
case STRING_RESULT:
|
||||
maybe_null= 1;
|
||||
max_length= 0;
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
decimals= NOT_FIXED_DEC;
|
||||
max_length= float_length(decimals);
|
||||
break;
|
||||
case INT_RESULT:
|
||||
decimals= 0;
|
||||
max_length= 21;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -47,7 +47,8 @@ public:
|
||||
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
|
||||
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
|
||||
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
|
||||
NOT_FUNC, NOT_ALL_FUNC};
|
||||
NOT_FUNC, NOT_ALL_FUNC,
|
||||
GUSERVAR_FUNC};
|
||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
|
||||
enum Type type() const { return FUNC_ITEM; }
|
||||
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
|
||||
@ -946,6 +947,8 @@ class Item_func_get_user_var :public Item_func
|
||||
public:
|
||||
Item_func_get_user_var(LEX_STRING a):
|
||||
Item_func(), name(a) {}
|
||||
enum Functype functype() const { return GUSERVAR_FUNC; }
|
||||
LEX_STRING get_name() { return name; }
|
||||
double val();
|
||||
longlong val_int();
|
||||
String *val_str(String* str);
|
||||
@ -1058,3 +1061,69 @@ enum Cast_target
|
||||
ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
|
||||
ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Stored FUNCTIONs
|
||||
*
|
||||
*/
|
||||
|
||||
class sp_head;
|
||||
|
||||
class Item_func_sp :public Item_func
|
||||
{
|
||||
private:
|
||||
LEX_STRING m_name;
|
||||
mutable sp_head *m_sp;
|
||||
|
||||
int execute(Item **itp);
|
||||
|
||||
public:
|
||||
|
||||
Item_func_sp(LEX_STRING name)
|
||||
:Item_func(), m_name(name), m_sp(NULL)
|
||||
{}
|
||||
|
||||
Item_func_sp(LEX_STRING name, List<Item> &list)
|
||||
:Item_func(list), m_name(name), m_sp(NULL)
|
||||
{}
|
||||
|
||||
virtual ~Item_func_sp()
|
||||
{}
|
||||
|
||||
const char *func_name() const
|
||||
{
|
||||
return m_name.str;
|
||||
}
|
||||
|
||||
enum enum_field_types field_type() const;
|
||||
|
||||
Item_result result_type() const;
|
||||
|
||||
longlong val_int()
|
||||
{
|
||||
return (longlong)Item_func_sp::val();
|
||||
}
|
||||
|
||||
double val()
|
||||
{
|
||||
Item *it;
|
||||
|
||||
if (execute(&it))
|
||||
return 0.0;
|
||||
return it->val();
|
||||
}
|
||||
|
||||
String *val_str(String *str)
|
||||
{
|
||||
Item *it;
|
||||
|
||||
if (execute(&it))
|
||||
return NULL;
|
||||
return it->val_str(str);
|
||||
}
|
||||
|
||||
void fix_length_and_dec();
|
||||
|
||||
};
|
||||
|
@ -253,7 +253,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||
{
|
||||
|
||||
have_to_be_excluded= 1;
|
||||
if (join->thd->lex.describe)
|
||||
if (join->thd->lex->describe)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
||||
@ -609,14 +609,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
subs= new Item_maxmin_subselect(this, select_lex, func->l_op());
|
||||
}
|
||||
// left expression belong to outer select
|
||||
SELECT_LEX *current= thd->lex.current_select, *up;
|
||||
thd->lex.current_select= up= current->return_after_parsing();
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
if (left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
|
||||
{
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
substitution= func->create(left_expr, subs);
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
@ -627,16 +627,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
|
||||
SELECT_LEX *current= thd->lex.current_select, *up;
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
|
||||
thd->lex.current_select= up= current->return_after_parsing();
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
//optimizer never use Item **ref => we can pass 0 as parameter
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
|
||||
/*
|
||||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
@ -725,7 +725,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
// fix_field of item will be done in time of substituting
|
||||
substitution= item;
|
||||
have_to_be_excluded= 1;
|
||||
if (thd->lex.describe)
|
||||
if (thd->lex->describe)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
||||
@ -761,15 +761,15 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
|
||||
SELECT_LEX *current= thd->lex.current_select, *up;
|
||||
thd->lex.current_select= up= current->return_after_parsing();
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
//optimizer never use Item **ref => we can pass 0 as parameter
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
thd->lex.current_select= current;
|
||||
thd->lex->current_select= current;
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
}
|
||||
|
||||
@ -912,8 +912,8 @@ int subselect_single_select_engine::prepare()
|
||||
return 1;
|
||||
}
|
||||
prepared= 1;
|
||||
SELECT_LEX *save_select= thd->lex.current_select;
|
||||
thd->lex.current_select= select_lex;
|
||||
SELECT_LEX *save_select= thd->lex->current_select;
|
||||
thd->lex->current_select= select_lex;
|
||||
if (join->prepare(&select_lex->ref_pointer_array,
|
||||
(TABLE_LIST*) select_lex->table_list.first,
|
||||
select_lex->with_wild,
|
||||
@ -926,7 +926,7 @@ int subselect_single_select_engine::prepare()
|
||||
(ORDER*) 0, select_lex,
|
||||
select_lex->master_unit(), 0))
|
||||
return 1;
|
||||
thd->lex.current_select= save_select;
|
||||
thd->lex->current_select= save_select;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1032,8 +1032,8 @@ int subselect_single_select_engine::exec()
|
||||
{
|
||||
DBUG_ENTER("subselect_single_select_engine::exec");
|
||||
char const *save_where= join->thd->where;
|
||||
SELECT_LEX *save_select= join->thd->lex.current_select;
|
||||
join->thd->lex.current_select= select_lex;
|
||||
SELECT_LEX *save_select= join->thd->lex->current_select;
|
||||
join->thd->lex->current_select= select_lex;
|
||||
if (!optimized)
|
||||
{
|
||||
optimized=1;
|
||||
@ -1041,7 +1041,7 @@ int subselect_single_select_engine::exec()
|
||||
{
|
||||
join->thd->where= save_where;
|
||||
executed= 1;
|
||||
join->thd->lex.current_select= save_select;
|
||||
join->thd->lex->current_select= save_select;
|
||||
DBUG_RETURN(join->error?join->error:1);
|
||||
}
|
||||
if (item->engine_changed)
|
||||
@ -1054,7 +1054,7 @@ int subselect_single_select_engine::exec()
|
||||
if (join->reinit())
|
||||
{
|
||||
join->thd->where= save_where;
|
||||
join->thd->lex.current_select= save_select;
|
||||
join->thd->lex->current_select= save_select;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
item->reset();
|
||||
@ -1065,11 +1065,11 @@ int subselect_single_select_engine::exec()
|
||||
join->exec();
|
||||
executed= 1;
|
||||
join->thd->where= save_where;
|
||||
join->thd->lex.current_select= save_select;
|
||||
join->thd->lex->current_select= save_select;
|
||||
DBUG_RETURN(join->error||thd->is_fatal_error);
|
||||
}
|
||||
join->thd->where= save_where;
|
||||
join->thd->lex.current_select= save_select;
|
||||
join->thd->lex->current_select= save_select;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ Item_sum::Item_sum(THD *thd, Item_sum &item):
|
||||
|
||||
void Item_sum::mark_as_sum_func()
|
||||
{
|
||||
current_thd->lex.current_select->with_sum_func= 1;
|
||||
current_thd->lex->current_select->with_sum_func= 1;
|
||||
with_sum_func= 1;
|
||||
}
|
||||
|
||||
@ -1140,7 +1140,7 @@ void Item_sum_count_distinct::make_unique()
|
||||
bool Item_sum_count_distinct::setup(THD *thd)
|
||||
{
|
||||
List<Item> list;
|
||||
SELECT_LEX *select_lex= thd->lex.current_select;
|
||||
SELECT_LEX *select_lex= thd->lex->current_select;
|
||||
if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
|
||||
return 1;
|
||||
|
||||
@ -1643,7 +1643,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
|
||||
quick_group= 0;
|
||||
mark_as_sum_func();
|
||||
item_thd= current_thd;
|
||||
SELECT_LEX *select_lex= item_thd->lex.current_select;
|
||||
SELECT_LEX *select_lex= item_thd->lex->current_select;
|
||||
order= 0;
|
||||
group_concat_max_len= item_thd->variables.group_concat_max_len;
|
||||
|
||||
@ -1825,7 +1825,7 @@ bool Item_func_group_concat::setup(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Item_func_group_concat::setup");
|
||||
List<Item> list;
|
||||
SELECT_LEX *select_lex= thd->lex.current_select;
|
||||
SELECT_LEX *select_lex= thd->lex->current_select;
|
||||
|
||||
if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
|
||||
DBUG_RETURN(1);
|
||||
|
48
sql/lex.h
48
sql/lex.h
@ -60,6 +60,7 @@ static SYMBOL symbols[] = {
|
||||
{ "AS", SYM(AS),0,0},
|
||||
{ "ASC", SYM(ASC),0,0},
|
||||
{ "ASCII", SYM(ASCII_SYM),0,0},
|
||||
{ "ASENSITIVE", SYM(ASENSITIVE_SYM),0,0},
|
||||
{ "AVG", SYM(AVG_SYM),0,0},
|
||||
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0},
|
||||
{ "AUTO_INCREMENT", SYM(AUTO_INC),0,0},
|
||||
@ -81,6 +82,7 @@ static SYMBOL symbols[] = {
|
||||
{ "BY", SYM(BY),0,0},
|
||||
{ "BYTE", SYM(BYTE_SYM), 0, 0},
|
||||
{ "CACHE", SYM(CACHE_SYM),0,0},
|
||||
{ "CALL", SYM(CALL_SYM),0,0},
|
||||
{ "CASCADE", SYM(CASCADE),0,0},
|
||||
{ "CASE", SYM(CASE_SYM),0,0},
|
||||
{ "CHAR", SYM(CHAR_SYM),0,0},
|
||||
@ -102,13 +104,17 @@ static SYMBOL symbols[] = {
|
||||
{ "COMMITTED", SYM(COMMITTED_SYM),0,0},
|
||||
{ "COMPRESSED", SYM(COMPRESSED_SYM),0,0},
|
||||
{ "CONCURRENT", SYM(CONCURRENT),0,0},
|
||||
{ "CONDITION", SYM(CONDITION_SYM),0,0},
|
||||
{ "CONNECTION", SYM(CONNECTION_SYM),0,0},
|
||||
{ "CONSTRAINT", SYM(CONSTRAINT),0,0},
|
||||
{ "CONTINUE", SYM(CONTINUE_SYM),0,0},
|
||||
{ "CREATE", SYM(CREATE),0,0},
|
||||
{ "CROSS", SYM(CROSS),0,0},
|
||||
{ "CUBE", SYM(CUBE_SYM),0,0},
|
||||
{ "CURRENT_DATE", SYM(CURDATE),0,0},
|
||||
{ "CURRENT_TIME", SYM(CURTIME),0,0},
|
||||
{ "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0},
|
||||
{ "CURSOR", SYM(CURSOR_SYM),0,0},
|
||||
{ "DATA", SYM(DATA_SYM),0,0},
|
||||
{ "DATABASE", SYM(DATABASE),0,0},
|
||||
{ "DATABASES", SYM(DATABASES),0,0},
|
||||
@ -121,8 +127,10 @@ static SYMBOL symbols[] = {
|
||||
{ "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0},
|
||||
{ "DEC", SYM(DECIMAL_SYM),0,0},
|
||||
{ "DECIMAL", SYM(DECIMAL_SYM),0,0},
|
||||
{ "DECLARE", SYM(DECLARE_SYM),0,0},
|
||||
{ "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
|
||||
{ "DEFAULT", SYM(DEFAULT),0,0},
|
||||
{ "DEFINER", SYM(DEFINER_SYM),0,0},
|
||||
{ "DELAYED", SYM(DELAYED_SYM),0,0},
|
||||
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
|
||||
{ "DELETE", SYM(DELETE_SYM),0,0},
|
||||
@ -144,6 +152,7 @@ static SYMBOL symbols[] = {
|
||||
{ "ERRORS", SYM(ERRORS),0,0},
|
||||
{ "END", SYM(END),0,0},
|
||||
{ "ELSE", SYM(ELSE),0,0},
|
||||
{ "ELSEIF", SYM(ELSEIF_SYM),0,0},
|
||||
{ "ESCAPE", SYM(ESCAPE_SYM),0,0},
|
||||
{ "ESCAPED", SYM(ESCAPED),0,0},
|
||||
{ "ENABLE", SYM(ENABLE_SYM),0,0},
|
||||
@ -151,11 +160,14 @@ static SYMBOL symbols[] = {
|
||||
{ "ENUM", SYM(ENUM),0,0},
|
||||
{ "EVENTS", SYM(EVENTS_SYM),0,0},
|
||||
{ "EXECUTE", SYM(EXECUTE_SYM),0,0},
|
||||
{ "EXPLAIN", SYM(DESCRIBE),0,0},
|
||||
{ "EXISTS", SYM(EXISTS),0,0},
|
||||
{ "EXIT", SYM(EXIT_SYM),0,0},
|
||||
{ "EXPANSION", SYM(EXPANSION_SYM),0,0},
|
||||
{ "EXPLAIN", SYM(DESCRIBE),0,0},
|
||||
{ "EXTENDED", SYM(EXTENDED_SYM),0,0},
|
||||
{ "FALSE", SYM(FALSE_SYM),0,0},
|
||||
{ "FAST", SYM(FAST_SYM),0,0},
|
||||
{ "FETCH", SYM(FETCH_SYM),0,0},
|
||||
{ "FIELDS", SYM(COLUMNS),0,0},
|
||||
{ "FILE", SYM(FILE_SYM),0,0},
|
||||
{ "FIRST", SYM(FIRST_SYM),0,0},
|
||||
@ -164,9 +176,9 @@ static SYMBOL symbols[] = {
|
||||
{ "FLOAT4", SYM(FLOAT_SYM),0,0},
|
||||
{ "FLOAT8", SYM(DOUBLE_SYM),0,0},
|
||||
{ "FLUSH", SYM(FLUSH_SYM),0,0},
|
||||
{ "FALSE", SYM(FALSE_SYM),0,0},
|
||||
{ "FOREIGN", SYM(FOREIGN),0,0},
|
||||
{ "FORCE", SYM(FORCE_SYM),0,0},
|
||||
{ "FOUND", SYM(FOUND_SYM),0,0},
|
||||
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
|
||||
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
|
||||
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
|
||||
@ -175,7 +187,7 @@ static SYMBOL symbols[] = {
|
||||
{ "FOR", SYM(FOR_SYM),0,0},
|
||||
{ "FULL", SYM(FULL),0,0},
|
||||
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
|
||||
{ "FUNCTION", SYM(UDF_SYM),0,0},
|
||||
{ "FUNCTION", SYM(FUNCTION_SYM),0,0},
|
||||
{ "GEOMETRY", SYM(GEOMETRY_SYM),0,0},
|
||||
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0},
|
||||
{ "GET_FORMAT", SYM(GET_FORMAT),0,0},
|
||||
@ -186,7 +198,6 @@ static SYMBOL symbols[] = {
|
||||
{ "HAVING", SYM(HAVING),0,0},
|
||||
{ "HANDLER", SYM(HANDLER_SYM),0,0},
|
||||
{ "HASH", SYM(HASH_SYM),0,0},
|
||||
{ "HEAP", SYM(HEAP_SYM),0,0},
|
||||
{ "HELP", SYM(HELP_SYM),0,0},
|
||||
{ "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0},
|
||||
{ "HOUR", SYM(HOUR_SYM),0,0},
|
||||
@ -204,6 +215,8 @@ static SYMBOL symbols[] = {
|
||||
{ "INNOBASE", SYM(INNOBASE_SYM),0,0},
|
||||
{ "INNODB", SYM(INNOBASE_SYM),0,0},
|
||||
{ "IMPORT", SYM(IMPORT),0,0},
|
||||
{ "INOUT", SYM(INOUT_SYM),0,0},
|
||||
{ "INSENSITIVE", SYM(INSENSITIVE_SYM),0,0},
|
||||
{ "INSERT", SYM(INSERT),0,0},
|
||||
{ "INSERT_METHOD", SYM(INSERT_METHOD),0,0},
|
||||
{ "INT", SYM(INT_SYM),0,0},
|
||||
@ -219,14 +232,16 @@ static SYMBOL symbols[] = {
|
||||
{ "IF", SYM(IF),0,0},
|
||||
{ "IS", SYM(IS),0,0},
|
||||
{ "ISOLATION", SYM(ISOLATION),0,0},
|
||||
{ "ISAM", SYM(ISAM_SYM),0,0},
|
||||
{ "ISSUER", SYM(ISSUER_SYM),0,0},
|
||||
{ "ITERATE", SYM(ITERATE_SYM),0,0},
|
||||
{ "INVOKER", SYM(INVOKER_SYM),0,0},
|
||||
{ "JOIN", SYM(JOIN_SYM),0,0},
|
||||
{ "KEY", SYM(KEY_SYM),0,0},
|
||||
{ "KEYS", SYM(KEYS),0,0},
|
||||
{ "KILL", SYM(KILL_SYM),0,0},
|
||||
{ "LAST", SYM(LAST_SYM),0,0},
|
||||
{ "LEADING", SYM(LEADING),0,0},
|
||||
{ "LEAVE", SYM(LEAVE_SYM),0,0},
|
||||
{ "LEAVES", SYM(LEAVES),0,0},
|
||||
{ "LEFT", SYM(LEFT),0,0},
|
||||
{ "LEVEL", SYM(LEVEL_SYM),0,0},
|
||||
@ -243,6 +258,7 @@ static SYMBOL symbols[] = {
|
||||
{ "LOGS", SYM(LOGS_SYM),0,0},
|
||||
{ "LONG", SYM(LONG_SYM),0,0},
|
||||
{ "LONGBLOB", SYM(LONGBLOB),0,0},
|
||||
{ "LOOP", SYM(LOOP_SYM),0,0},
|
||||
{ "LONGTEXT", SYM(LONGTEXT),0,0},
|
||||
{ "LOW_PRIORITY", SYM(LOW_PRIORITY),0,0},
|
||||
{ "MASTER", SYM(MASTER_SYM),0,0},
|
||||
@ -268,9 +284,7 @@ static SYMBOL symbols[] = {
|
||||
{ "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0},
|
||||
{ "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0},
|
||||
{ "MEDIUMINT", SYM(MEDIUMINT),0,0},
|
||||
{ "MERGE", SYM(MERGE_SYM),0,0},
|
||||
{ "MEDIUM", SYM(MEDIUM_SYM),0,0},
|
||||
{ "MEMORY", SYM(MEMORY_SYM),0,0},
|
||||
{ "MICROSECOND", SYM(MICROSECOND_SYM),0,0},
|
||||
{ "MIDDLEINT", SYM(MEDIUMINT),0,0}, /* For powerbuilder */
|
||||
{ "MIN_ROWS", SYM(MIN_ROWS),0,0},
|
||||
@ -284,8 +298,7 @@ static SYMBOL symbols[] = {
|
||||
{ "MULTILINESTRING", SYM(MULTILINESTRING),0,0},
|
||||
{ "MULTIPOINT", SYM(MULTIPOINT),0,0},
|
||||
{ "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0},
|
||||
{ "MRG_MYISAM", SYM(MERGE_SYM),0,0},
|
||||
{ "MYISAM", SYM(MYISAM_SYM),0,0},
|
||||
{ "NAME", SYM(NAME_SYM),0,0},
|
||||
{ "NAMES", SYM(NAMES_SYM),0,0},
|
||||
{ "NATURAL", SYM(NATURAL),0,0},
|
||||
{ "NATIONAL", SYM(NATIONAL_SYM),0,0},
|
||||
@ -307,6 +320,7 @@ static SYMBOL symbols[] = {
|
||||
{ "OPTIONALLY", SYM(OPTIONALLY),0,0},
|
||||
{ "OR", SYM(OR),0,0},
|
||||
{ "ORDER", SYM(ORDER_SYM),0,0},
|
||||
{ "OUT", SYM(OUT_SYM),0,0},
|
||||
{ "OUTER", SYM(OUTER),0,0},
|
||||
{ "OUTFILE", SYM(OUTFILE),0,0},
|
||||
{ "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0},
|
||||
@ -337,13 +351,15 @@ static SYMBOL symbols[] = {
|
||||
{ "REPAIR", SYM(REPAIR),0,0},
|
||||
{ "REPLACE", SYM(REPLACE),0,0},
|
||||
{ "REPLICATION", SYM(REPLICATION),0,0},
|
||||
{ "REPEAT", SYM(REPEAT_SYM),0,0},
|
||||
{ "REPEATABLE", SYM(REPEATABLE_SYM),0,0},
|
||||
{ "REQUIRE", SYM(REQUIRE_SYM),0,0},
|
||||
{ "RESET", SYM(RESET_SYM),0,0},
|
||||
{ "USER_RESOURCES", SYM(RESOURCES),0,0},
|
||||
{ "RESTORE", SYM(RESTORE_SYM),0,0},
|
||||
{ "RESTRICT", SYM(RESTRICT),0,0},
|
||||
{ "RETURNS", SYM(UDF_RETURNS_SYM),0,0},
|
||||
{ "RETURN", SYM(RETURN_SYM),0,0},
|
||||
{ "RETURNS", SYM(RETURNS_SYM),0,0},
|
||||
{ "REVOKE", SYM(REVOKE),0,0},
|
||||
{ "RIGHT", SYM(RIGHT),0,0},
|
||||
{ "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */
|
||||
@ -355,8 +371,10 @@ static SYMBOL symbols[] = {
|
||||
{ "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0},
|
||||
{ "SECOND", SYM(SECOND_SYM),0,0},
|
||||
{ "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0},
|
||||
{ "SECURITY", SYM(SECURITY_SYM),0,0},
|
||||
{ "SEPARATOR", SYM(SEPARATOR_SYM),0,0},
|
||||
{ "SELECT", SYM(SELECT_SYM),0,0},
|
||||
{ "SENSITIVE", SYM(SENSITIVE_SYM),0,0},
|
||||
{ "SERIAL", SYM(SERIAL_SYM),0,0},
|
||||
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
|
||||
{ "SESSION", SYM(SESSION_SYM),0,0},
|
||||
@ -371,6 +389,11 @@ static SYMBOL symbols[] = {
|
||||
{ "SOME", SYM(ANY_SYM),0,0},
|
||||
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
|
||||
{ "SPATIAL", SYM(SPATIAL_SYM),0,0},
|
||||
{ "SPECIFIC", SYM(SPECIFIC_SYM),0,0},
|
||||
{ "SQL", SYM(SQL_SYM),0,0},
|
||||
{ "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0},
|
||||
{ "SQLSTATE", SYM(SQLSTATE_SYM),0,0},
|
||||
{ "SQLWARNING", SYM(SQLWARNING_SYM),0,0},
|
||||
{ "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0},
|
||||
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
|
||||
{ "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
|
||||
@ -409,15 +432,16 @@ static SYMBOL symbols[] = {
|
||||
{ "TYPE", SYM(TYPE_SYM),0,0},
|
||||
{ "TYPES", SYM(TYPES_SYM),0,0},
|
||||
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM),0,0},
|
||||
{ "UNDO", SYM(UNDO_SYM),0,0},
|
||||
{ "UNICODE", SYM(UNICODE_SYM),0,0},
|
||||
{ "UNION", SYM(UNION_SYM),0,0},
|
||||
{ "UNIQUE", SYM(UNIQUE_SYM),0,0},
|
||||
{ "UNLOCK", SYM(UNLOCK_SYM),0,0},
|
||||
{ "UNSIGNED", SYM(UNSIGNED),0,0},
|
||||
{ "UNTIL", SYM(UNTIL_SYM),0,0},
|
||||
{ "USE", SYM(USE_SYM),0,0},
|
||||
{ "USE_FRM", SYM(USE_FRM),0,0},
|
||||
{ "USER", SYM(USER),0,0},
|
||||
{ "UNTIL", SYM(UNTIL_SYM),0,0},
|
||||
{ "USING", SYM(USING),0,0},
|
||||
{ "UTC_DATE", SYM(UTC_DATE_SYM),0,0},
|
||||
{ "UTC_TIME", SYM(UTC_TIME_SYM),0,0},
|
||||
@ -437,6 +461,7 @@ static SYMBOL symbols[] = {
|
||||
{ "WRITE", SYM(WRITE_SYM),0,0},
|
||||
{ "WHEN", SYM(WHEN_SYM),0,0},
|
||||
{ "WHERE", SYM(WHERE),0,0},
|
||||
{ "WHILE", SYM(WHILE_SYM),0,0},
|
||||
{ "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG),0,0},
|
||||
{ "XOR", SYM(XOR),0,0},
|
||||
{ "X509", SYM(X509_SYM),0,0},
|
||||
@ -624,7 +649,6 @@ static SYMBOL sql_functions[] = {
|
||||
{ "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)},
|
||||
{ "RAND", SYM(RAND),0,0},
|
||||
{ "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
|
||||
{ "REPEAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_repeat)},
|
||||
{ "REVERSE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
|
||||
{ "ROUND", SYM(ROUND),0,0},
|
||||
{ "RPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
|
||||
|
@ -152,7 +152,7 @@ retry:
|
||||
thd->proc_info=0;
|
||||
if (thd->killed)
|
||||
{
|
||||
my_error(ER_SERVER_SHUTDOWN,MYF(0));
|
||||
thd->send_kill_message();
|
||||
if (sql_lock)
|
||||
{
|
||||
mysql_unlock_tables(thd,sql_lock);
|
||||
|
16
sql/log.cc
16
sql/log.cc
@ -30,7 +30,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <m_ctype.h> // For test_if_number
|
||||
|
||||
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
|
||||
MYSQL_LOG mysql_log, mysql_slow_log, mysql_bin_log;
|
||||
|
||||
static bool test_if_number(const char *str,
|
||||
long *res, bool allow_wildcards);
|
||||
@ -1069,7 +1069,7 @@ err:
|
||||
|
||||
/*
|
||||
Write to normal (not rotable) log
|
||||
This is the format for the 'normal', 'slow' and 'update' logs.
|
||||
This is the format for the 'normal' log.
|
||||
*/
|
||||
|
||||
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
||||
@ -1538,8 +1538,7 @@ err:
|
||||
|
||||
|
||||
/*
|
||||
Write update log in a format suitable for incremental backup
|
||||
This is also used by the slow query log.
|
||||
Write to the slow query log.
|
||||
*/
|
||||
|
||||
bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
||||
@ -1555,15 +1554,6 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
||||
int tmp_errno=0;
|
||||
char buff[80],*end;
|
||||
end=buff;
|
||||
if (!(thd->options & OPTION_UPDATE_LOG)
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
&& (thd->master_access & SUPER_ACL)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||
return 0;
|
||||
}
|
||||
if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT) || query_start_arg)
|
||||
{
|
||||
current_time=time(NULL);
|
||||
|
@ -832,7 +832,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
|
||||
data_buf(0), query(query_arg),
|
||||
db(thd_arg->db), q_len((uint32) query_length),
|
||||
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
|
||||
error_code(thd_arg->killed != THD::NOT_KILLED ? thd->killed_errno() : thd_arg->net.last_errno),
|
||||
thread_id(thd_arg->thread_id),
|
||||
/* save the original thread id; we already know the server id */
|
||||
slave_proxy_id(thd_arg->variables.pseudo_thread_id)
|
||||
|
@ -54,7 +54,7 @@ char *sql_strmake_with_convert(const char *str, uint32 arg_length,
|
||||
CHARSET_INFO *from_cs,
|
||||
uint32 max_res_length,
|
||||
CHARSET_INFO *to_cs, uint32 *result_length);
|
||||
void kill_one_thread(THD *thd, ulong id);
|
||||
void kill_one_thread(THD *thd, ulong id, bool only_kill_query);
|
||||
bool net_request_file(NET* net, const char* fname);
|
||||
char* query_table_status(THD *thd,const char *db,const char *table_name);
|
||||
|
||||
@ -408,7 +408,7 @@ bool is_update_query(enum enum_sql_command command);
|
||||
void free_items(Item *item);
|
||||
bool alloc_query(THD *thd, char *packet, ulong packet_length);
|
||||
void mysql_init_select(LEX *lex);
|
||||
void mysql_init_query(THD *thd);
|
||||
void mysql_init_query(THD *thd, bool lexonly=0);
|
||||
bool mysql_new_select(LEX *lex, bool move_down);
|
||||
void create_select_for_variable(const char *var_name);
|
||||
void mysql_init_multi_delete(LEX *lex);
|
||||
@ -419,7 +419,7 @@ extern "C" pthread_handler_decl(handle_one_connection,arg);
|
||||
extern "C" pthread_handler_decl(handle_bootstrap,arg);
|
||||
void end_thread(THD *thd,bool put_in_cache);
|
||||
void flush_thread_cache();
|
||||
void mysql_execute_command(THD *thd);
|
||||
int mysql_execute_command(THD *thd);
|
||||
bool do_command(THD *thd);
|
||||
bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
char* packet, uint packet_length);
|
||||
@ -1045,22 +1045,22 @@ SQL_CRYPT *get_crypt_for_frm(void);
|
||||
|
||||
inline bool add_item_to_list(THD *thd, Item *item)
|
||||
{
|
||||
return thd->lex.current_select->add_item_to_list(thd, item);
|
||||
return thd->lex->current_select->add_item_to_list(thd, item);
|
||||
}
|
||||
|
||||
inline bool add_value_to_list(THD *thd, Item *value)
|
||||
{
|
||||
return thd->lex.value_list.push_back(value);
|
||||
return thd->lex->value_list.push_back(value);
|
||||
}
|
||||
|
||||
inline bool add_order_to_list(THD *thd, Item *item, bool asc)
|
||||
{
|
||||
return thd->lex.current_select->add_order_to_list(thd, item, asc);
|
||||
return thd->lex->current_select->add_order_to_list(thd, item, asc);
|
||||
}
|
||||
|
||||
inline bool add_group_to_list(THD *thd, Item *item, bool asc)
|
||||
{
|
||||
return thd->lex.current_select->add_group_to_list(thd, item, asc);
|
||||
return thd->lex->current_select->add_group_to_list(thd, item, asc);
|
||||
}
|
||||
|
||||
inline void mark_as_null_row(TABLE *table)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "sql_repl.h"
|
||||
#include "repl_failsafe.h"
|
||||
#include "stacktrace.h"
|
||||
#include "mysys_err.h"
|
||||
#ifdef HAVE_BERKELEY_DB
|
||||
#include "ha_berkeley.h"
|
||||
#endif
|
||||
@ -36,6 +37,8 @@
|
||||
#include <thr_alarm.h>
|
||||
#include <ft_global.h>
|
||||
#include <errmsg.h>
|
||||
#include "sp_rcontext.h"
|
||||
#include "sp_cache.h"
|
||||
|
||||
#define mysqld_charset &my_charset_latin1
|
||||
|
||||
@ -613,7 +616,7 @@ static void close_connections(void)
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
tmp->killed=1;
|
||||
tmp->killed= THD::KILL_CONNECTION;
|
||||
if (tmp->mysys_var)
|
||||
{
|
||||
tmp->mysys_var->abort=1;
|
||||
@ -796,6 +799,7 @@ static void __cdecl kill_server(int sig_ptr)
|
||||
unireg_abort(1); /* purecov: inspected */
|
||||
else
|
||||
unireg_end();
|
||||
|
||||
#ifdef __NETWARE__
|
||||
pthread_join(select_thread, NULL); // wait for main thread
|
||||
#endif /* __NETWARE__ */
|
||||
@ -887,7 +891,6 @@ void clean_up(bool print_message)
|
||||
|
||||
mysql_log.cleanup();
|
||||
mysql_slow_log.cleanup();
|
||||
mysql_update_log.cleanup();
|
||||
mysql_bin_log.cleanup();
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
@ -1268,12 +1271,12 @@ static void server_init(void)
|
||||
void yyerror(const char *s)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
char *yytext=(char*) thd->lex.tok_start;
|
||||
char *yytext=(char*) thd->lex->tok_start;
|
||||
/* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
|
||||
if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
|
||||
s=ER(ER_SYNTAX_ERROR);
|
||||
net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
|
||||
thd->lex.yylineno);
|
||||
thd->lex->yylineno);
|
||||
}
|
||||
|
||||
|
||||
@ -1403,7 +1406,7 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
||||
THD *thd=current_thd;
|
||||
DBUG_ENTER("abort_thread");
|
||||
if (thd)
|
||||
thd->killed=1;
|
||||
thd->killed= THD::KILL_CONNECTION;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif
|
||||
@ -1887,12 +1890,16 @@ extern "C" int my_message_sql(uint error, const char *str,
|
||||
DBUG_PRINT("error", ("Message: '%s'", str));
|
||||
if ((thd= current_thd))
|
||||
{
|
||||
if (thd->spcont && thd->spcont->find_handler(error))
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/*
|
||||
thd->lex.current_select == 0 if lex structure is not inited
|
||||
(not query command (COM_QUERY))
|
||||
*/
|
||||
if (thd->lex.current_select &&
|
||||
thd->lex.current_select->no_error && !thd->is_fatal_error)
|
||||
if (thd->lex->current_select &&
|
||||
thd->lex->current_select->no_error && !thd->is_fatal_error)
|
||||
{
|
||||
DBUG_PRINT("error", ("above error converted to warning"));
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
|
||||
@ -2093,7 +2100,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
|
||||
before MY_INIT(). So we do it here.
|
||||
*/
|
||||
mysql_log.init_pthread_objects();
|
||||
mysql_update_log.init_pthread_objects();
|
||||
mysql_slow_log.init_pthread_objects();
|
||||
mysql_bin_log.init_pthread_objects();
|
||||
|
||||
@ -2211,6 +2217,7 @@ static int init_thread_environment()
|
||||
(void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_cond_init(&COND_rpl_status, NULL);
|
||||
#endif
|
||||
sp_cache_init();
|
||||
/* Parameter for threads created for connections */
|
||||
(void) pthread_attr_init(&connection_attrib);
|
||||
(void) pthread_attr_setdetachstate(&connection_attrib,
|
||||
@ -2268,9 +2275,55 @@ static int init_server_components()
|
||||
LOG_NORMAL, 0, 0, 0);
|
||||
if (opt_update_log)
|
||||
{
|
||||
open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
|
||||
NullS, LOG_NEW, 0, 0, 0);
|
||||
using_update_log=1;
|
||||
/*
|
||||
Update log is removed since 5.0. But we still accept the option.
|
||||
The idea is if the user already uses the binlog and the update log,
|
||||
we completely ignore any option/variable related to the update log, like
|
||||
if the update log did not exist. But if the user uses only the update log,
|
||||
then we translate everything into binlog for him (with warnings).
|
||||
Implementation of the above :
|
||||
- If mysqld is started with --log-update and --log-bin,
|
||||
ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
|
||||
is used, and turn off --sql-bin-update-same.
|
||||
This will completely ignore SQL_LOG_UPDATE
|
||||
- If mysqld is started with --log-update only,
|
||||
change it to --log-bin (with the filename passed to log-update,
|
||||
plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
|
||||
used, and turn on --sql-bin-update-same.
|
||||
This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
|
||||
|
||||
Note that we tell the user that --sql-bin-update-same is deprecated and
|
||||
does nothing, and we don't take into account if he used this option or
|
||||
not; but internally we give this variable a value to have the behaviour we
|
||||
want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
|
||||
As sql-bin-update-same, log-update and log-bin cannot be changed by the user
|
||||
after starting the server (they are not variables), the user will not
|
||||
later interfere with the settings we do here.
|
||||
*/
|
||||
if (opt_bin_log)
|
||||
{
|
||||
opt_sql_bin_update= 0;
|
||||
sql_print_error("The update log is no longer supported by MySQL in \
|
||||
version 5.0 and above. It is replaced by the binary log.");
|
||||
}
|
||||
else
|
||||
{
|
||||
opt_sql_bin_update= 1;
|
||||
opt_bin_log= 1;
|
||||
if (opt_update_logname)
|
||||
{
|
||||
// as opt_bin_log==0, no need to free opt_bin_logname
|
||||
if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
|
||||
exit(EXIT_OUT_OF_MEMORY);
|
||||
sql_print_error("The update log is no longer supported by MySQL in \
|
||||
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
|
||||
with --log-bin='%s' instead.",opt_bin_logname);
|
||||
}
|
||||
else
|
||||
sql_print_error("The update log is no longer supported by MySQL in \
|
||||
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
|
||||
with --log-bin instead.");
|
||||
}
|
||||
}
|
||||
if (opt_slow_log)
|
||||
open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
|
||||
@ -2968,7 +3021,7 @@ static void create_new_thread(THD *thd)
|
||||
("Can't create thread to handle request (error %d)",
|
||||
error));
|
||||
thread_count--;
|
||||
thd->killed=1; // Safety
|
||||
thd->killed= THD::KILL_CONNECTION; // Safety
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
net_printf(thd,ER_CANT_CREATE_THREAD,error);
|
||||
@ -3863,7 +3916,8 @@ Disable with --skip-bdb (will save memory).",
|
||||
(gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR,
|
||||
OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"log-update", OPT_UPDATE_LOG,
|
||||
"Log updates to file.# where # is a unique number if not given.",
|
||||
"The update log is deprecated since version 5.0, is replaced by the binary \
|
||||
log and this option justs turns on --log-bin instead.",
|
||||
(gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR,
|
||||
OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"log-slow-queries", OPT_SLOW_QUERY_LOG,
|
||||
@ -4141,9 +4195,9 @@ replicating a LOAD DATA INFILE command.",
|
||||
(gptr*) &mysqld_unix_port, (gptr*) &mysqld_unix_port, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
|
||||
"If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.",
|
||||
(gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL,
|
||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
"The update log is deprecated since version 5.0, is replaced by the binary \
|
||||
log and this option does nothing anymore.",
|
||||
0, 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"sql-mode", OPT_SQL_MODE,
|
||||
"Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
|
||||
(gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
|
||||
|
@ -24,6 +24,7 @@
|
||||
#endif
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "sp_rcontext.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -62,6 +63,10 @@ void send_error(THD *thd, uint sql_errno, const char *err)
|
||||
err ? err : net->last_error[0] ?
|
||||
net->last_error : "NULL"));
|
||||
|
||||
if (thd->spcont && thd->spcont->find_handler(sql_errno))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
|
||||
query_cache_abort(net);
|
||||
#endif
|
||||
@ -145,6 +150,10 @@ void send_error(THD *thd, uint sql_errno, const char *err)
|
||||
void send_warning(THD *thd, uint sql_errno, const char *err)
|
||||
{
|
||||
DBUG_ENTER("send_warning");
|
||||
if (thd->spcont && thd->spcont->find_handler(sql_errno))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno,
|
||||
err ? err : ER(sql_errno));
|
||||
send_ok(thd);
|
||||
@ -175,6 +184,10 @@ net_printf(THD *thd, uint errcode, ...)
|
||||
DBUG_ENTER("net_printf");
|
||||
DBUG_PRINT("enter",("message: %u",errcode));
|
||||
|
||||
if (thd->spcont && thd->spcont->find_handler(errcode))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
thd->query_error= 1; // needed to catch query errors during replication
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
query_cache_abort(net); // Safety
|
||||
@ -1140,12 +1153,3 @@ bool Protocol_prep::store_time(TIME *tm)
|
||||
buff[0]=(char) length; // Length is stored first
|
||||
return packet->append(buff, length+1, PACKET_BUFFET_EXTRA_ALLOC);
|
||||
}
|
||||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
/* Should be removed when we define the Protocol_cursor's future */
|
||||
bool Protocol_cursor::write()
|
||||
{
|
||||
return Protocol_simple::write();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -47,17 +47,13 @@ public:
|
||||
Protocol(THD *thd) { init(thd); }
|
||||
virtual ~Protocol() {}
|
||||
void init(THD* thd);
|
||||
bool send_fields(List<Item> *list, uint flag);
|
||||
virtual bool send_fields(List<Item> *list, uint flag);
|
||||
bool send_records_num(List<Item> *list, ulonglong records);
|
||||
bool store(I_List<i_string> *str_list);
|
||||
bool store(const char *from, CHARSET_INFO *cs);
|
||||
String *storage_packet() { return packet; }
|
||||
inline void free() { packet->free(); }
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool write();
|
||||
#else
|
||||
virtual bool write();
|
||||
#endif
|
||||
inline bool store(uint32 from)
|
||||
{ return store_long((longlong) from); }
|
||||
inline bool store(longlong from)
|
||||
@ -158,6 +154,7 @@ public:
|
||||
Protocol_cursor(THD *thd, MEM_ROOT *ini_alloc) :Protocol_simple(thd), alloc(ini_alloc) {}
|
||||
bool prepare_for_send(List<Item> *item_list)
|
||||
{
|
||||
row_count= 0;
|
||||
fields= NULL;
|
||||
data= NULL;
|
||||
prev_record= &data;
|
||||
@ -165,6 +162,7 @@ public:
|
||||
}
|
||||
bool send_fields(List<Item> *list, uint flag);
|
||||
bool write();
|
||||
uint get_field_count() { return field_count; }
|
||||
};
|
||||
|
||||
void send_warning(THD *thd, uint sql_errno, const char *err=0);
|
||||
|
@ -51,6 +51,7 @@ bool Protocol_cursor::send_fields(List<Item> *list, uint flag)
|
||||
client_field->name= strdup_root(alloc, server_field.col_name);
|
||||
client_field->org_table= strdup_root(alloc, server_field.org_table_name);
|
||||
client_field->org_name= strdup_root(alloc, server_field.org_col_name);
|
||||
client_field->catalog= strdup_root(alloc, "");
|
||||
client_field->length= server_field.length;
|
||||
client_field->type= server_field.type;
|
||||
client_field->flags= server_field.flags;
|
||||
@ -60,6 +61,7 @@ bool Protocol_cursor::send_fields(List<Item> *list, uint flag)
|
||||
client_field->name_length= strlen(client_field->name);
|
||||
client_field->org_name_length= strlen(client_field->org_name);
|
||||
client_field->org_table_length= strlen(client_field->org_table);
|
||||
client_field->catalog_length= 0;
|
||||
client_field->charsetnr= server_field.charsetnr;
|
||||
|
||||
if (INTERNAL_NUM_FIELD(client_field))
|
||||
@ -100,17 +102,17 @@ bool Protocol_cursor::write()
|
||||
byte *to;
|
||||
|
||||
new_record= (MYSQL_ROWS *)alloc_root(alloc,
|
||||
sizeof(MYSQL_ROWS) + (field_count + 1)*sizeof(char *) + packet->length());
|
||||
sizeof(MYSQL_ROWS) + (field_count + 1)*sizeof(char *) + packet->length());
|
||||
if (!new_record)
|
||||
goto err;
|
||||
data= (byte **)(new_record + 1);
|
||||
new_record->data= (char **)data;
|
||||
|
||||
to= (byte *)(fields + field_count + 1);
|
||||
to= (byte *)data + (field_count + 1)*sizeof(char *);
|
||||
|
||||
for (; cur_field < fields_end; ++cur_field, ++data)
|
||||
{
|
||||
if ((len=net_field_length((uchar **)&cp)))
|
||||
if ((len= net_field_length((uchar **)&cp)) == 0)
|
||||
{
|
||||
*data= 0;
|
||||
}
|
||||
@ -121,6 +123,7 @@ bool Protocol_cursor::write()
|
||||
// TODO error signal send_error(thd, CR_MALFORMED_PACKET);
|
||||
return TRUE;
|
||||
}
|
||||
*data= to;
|
||||
memcpy(to,(char*) cp,len);
|
||||
to[len]=0;
|
||||
to+=len+1;
|
||||
@ -129,6 +132,7 @@ bool Protocol_cursor::write()
|
||||
cur_field->max_length=len;
|
||||
}
|
||||
}
|
||||
*data= 0;
|
||||
|
||||
*prev_record= new_record;
|
||||
prev_record= &new_record->next;
|
||||
@ -139,5 +143,3 @@ bool Protocol_cursor::write()
|
||||
// TODO error signal send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,7 +174,7 @@ static int rr_sequential(READ_RECORD *info)
|
||||
{
|
||||
if (info->thd->killed)
|
||||
{
|
||||
my_error(ER_SERVER_SHUTDOWN,MYF(0));
|
||||
info->thd->send_kill_message();
|
||||
return 1;
|
||||
}
|
||||
if (tmp != HA_ERR_RECORD_DELETED)
|
||||
|
@ -435,7 +435,7 @@ int show_new_master(THD* thd)
|
||||
DBUG_ENTER("show_new_master");
|
||||
List<Item> field_list;
|
||||
char errmsg[SLAVE_ERRMSG_SIZE];
|
||||
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
|
||||
LEX_MASTER_INFO* lex_mi = &thd->lex->mi;
|
||||
|
||||
errmsg[0]=0; // Safety
|
||||
if (translate_master(thd, lex_mi, errmsg))
|
||||
|
@ -79,6 +79,7 @@ static void sys_set_default_charset(THD *thd, enum_var_type type);
|
||||
static bool set_option_bit(THD *thd, set_var *var);
|
||||
static bool set_option_autocommit(THD *thd, set_var *var);
|
||||
static bool set_log_update(THD *thd, set_var *var);
|
||||
static bool set_log_bin(THD *thd, set_var *var);
|
||||
static void fix_low_priority_updates(THD *thd, enum_var_type type);
|
||||
static void fix_tx_isolation(THD *thd, enum_var_type type);
|
||||
static void fix_net_read_timeout(THD *thd, enum_var_type type);
|
||||
@ -340,7 +341,7 @@ static sys_var_thd_bit sys_log_update("sql_log_update",
|
||||
set_log_update,
|
||||
OPTION_UPDATE_LOG);
|
||||
static sys_var_thd_bit sys_log_binlog("sql_log_bin",
|
||||
set_log_update,
|
||||
set_log_bin,
|
||||
OPTION_BIN_LOG);
|
||||
static sys_var_thd_bit sys_sql_warnings("sql_warnings",
|
||||
set_option_bit,
|
||||
@ -2118,6 +2119,30 @@ static bool set_option_autocommit(THD *thd, set_var *var)
|
||||
|
||||
|
||||
static bool set_log_update(THD *thd, set_var *var)
|
||||
{
|
||||
/*
|
||||
The update log is not supported anymore since 5.0.
|
||||
See sql/mysqld.cc/, comments in function init_server_components() for an
|
||||
explaination of the different warnings we send below
|
||||
*/
|
||||
|
||||
if (opt_sql_bin_update)
|
||||
{
|
||||
((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
|
||||
OPTION_UPDATE_LOG);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
|
||||
ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
|
||||
}
|
||||
else
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_UPDATE_LOG_DEPRECATED_IGNORED,
|
||||
ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
|
||||
set_option_bit(thd, var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool set_log_bin(THD *thd, set_var *var)
|
||||
{
|
||||
if (opt_sql_bin_update)
|
||||
((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
|
||||
@ -2126,6 +2151,7 @@ static bool set_log_update(THD *thd, set_var *var)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static byte *get_warning_count(THD *thd)
|
||||
{
|
||||
thd->sys_var_tmp.long_value=
|
||||
|
@ -296,3 +296,35 @@ character-set=latin2
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -290,3 +290,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -298,3 +298,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -292,3 +292,35 @@ character-set=latin7
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -299,3 +299,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=greek
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=latin2
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=ujis
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=euckr
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -291,3 +291,35 @@ character-set=latin2
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -288,3 +288,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -291,3 +291,35 @@ character-set=latin2
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=koi8r
|
||||
"Кеш запросов не может установить размер %lu, новый размер кеша зпросов - %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -282,3 +282,35 @@ character-set=cp1250
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -295,3 +295,35 @@ character-set=latin2
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -289,3 +289,35 @@ character-set=latin1
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -287,3 +287,35 @@ character-set=latin1
|
||||
"Storleken av "Query cache" kunde inte sättas till %lu, ny storlek är %lu",
|
||||
"Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
@ -292,3 +292,35 @@ character-set=koi8u
|
||||
"Кеш запит╕в неспроможен встановити розм╕р %lu, новий розм╕р кеша запит╕в - %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
"Can't create a %s from within another stored routine"
|
||||
"%s %s already exists"
|
||||
"%s %s does not exist"
|
||||
"Failed to DROP %s %s"
|
||||
"Failed to CREATE %s %s"
|
||||
"%s with no matching label: %s"
|
||||
"Redefining label %s"
|
||||
"End-label %s without match"
|
||||
"Referring to uninitialized variable %s"
|
||||
"SELECT in a stored procedure must have INTO"
|
||||
"RETURN is only allowed in a FUNCTION"
|
||||
"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION"
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored."
|
||||
"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN."
|
||||
"Query execution was interrupted"
|
||||
"Wrong number of arguments for %s %s, expected %u, got %u"
|
||||
"Undefined CONDITION: %s"
|
||||
"No RETURN found in FUNCTION %s"
|
||||
"FUNCTION %s ended without RETURN"
|
||||
"Cursor statement must be a SELECT"
|
||||
"Cursor SELECT must not have INTO"
|
||||
"Undefined CURSOR: %s"
|
||||
"Cursor is already open"
|
||||
"Cursor is not open"
|
||||
"Undeclared variable: %s"
|
||||
"Wrong number of FETCH variables"
|
||||
"No data to FETCH"
|
||||
"Duplicate parameter: %s"
|
||||
"Duplicate variable: %s"
|
||||
"Duplicate condition: %s"
|
||||
"Duplicate cursor: %s"
|
||||
"Failed to ALTER %s %s"
|
||||
|
11
sql/slave.cc
11
sql/slave.cc
@ -583,7 +583,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
|
||||
if (thd->killed)
|
||||
{
|
||||
pthread_mutex_unlock(cond_lock);
|
||||
DBUG_RETURN(ER_SERVER_SHUTDOWN);
|
||||
DBUG_RETURN(thd->killed_errno());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1103,12 +1103,11 @@ static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi)
|
||||
BINLOG_FORMAT_323_GEQ_57 ;
|
||||
break;
|
||||
case '4':
|
||||
case '5':
|
||||
mi->old_format = BINLOG_FORMAT_CURRENT;
|
||||
break;
|
||||
default:
|
||||
/* 5.0 is not supported */
|
||||
errmsg = "Master reported an unrecognized MySQL version. Note that 4.0 \
|
||||
slaves can't replicate a 5.0 or newer master.";
|
||||
errmsg = "Master reported unrecognized MySQL version";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2330,7 +2329,7 @@ err:
|
||||
pthread_mutex_unlock(&data_lock);
|
||||
DBUG_PRINT("exit",("killed: %d abort: %d slave_running: %d \
|
||||
improper_arguments: %d timed_out: %d",
|
||||
(int) thd->killed,
|
||||
thd->killed_errno(),
|
||||
(int) (init_abort_pos_wait != abort_pos_wait),
|
||||
(int) slave_running,
|
||||
(int) (error == -2),
|
||||
@ -2735,7 +2734,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||
|
||||
thd->server_id = ev->server_id; // use the original server id for logging
|
||||
thd->set_time(); // time the query
|
||||
thd->lex.current_select= 0;
|
||||
thd->lex->current_select= 0;
|
||||
if (!ev->when)
|
||||
ev->when = time(NULL);
|
||||
ev->thd = thd;
|
||||
|
733
sql/sp.cc
Normal file
733
sql/sp.cc
Normal file
@ -0,0 +1,733 @@
|
||||
/* 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 */
|
||||
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "sp.h"
|
||||
#include "sp_head.h"
|
||||
#include "sp_cache.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* DB storage of Stored PROCEDUREs and FUNCTIONs
|
||||
*
|
||||
*/
|
||||
|
||||
#define MYSQL_PROC_FIELD_NAME 0
|
||||
#define MYSQL_PROC_FIELD_TYPE 1
|
||||
#define MYSQL_PROC_FIELD_DEFINITION 2
|
||||
#define MYSQL_PROC_FIELD_CREATOR 3
|
||||
#define MYSQL_PROC_FIELD_MODIFIED 4
|
||||
#define MYSQL_PROC_FIELD_CREATED 5
|
||||
#define MYSQL_PROC_FIELD_SUID 6
|
||||
#define MYSQL_PROC_FIELD_COMMENT 7
|
||||
#define MYSQL_PROC_FIELD_COUNT 8
|
||||
|
||||
/* *opened=true means we opened ourselves */
|
||||
static int
|
||||
db_find_routine_aux(THD *thd, int type, char *name, uint namelen,
|
||||
enum thr_lock_type ltype, TABLE **tablep, bool *opened)
|
||||
{
|
||||
DBUG_ENTER("db_find_routine_aux");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
|
||||
TABLE *table;
|
||||
byte key[65]; // We know name is 64 and the enum is 1 byte
|
||||
uint keylen;
|
||||
int ret;
|
||||
|
||||
// Put the key together
|
||||
keylen= namelen;
|
||||
if (keylen > sizeof(key)-1)
|
||||
keylen= sizeof(key)-1;
|
||||
memcpy(key, name, keylen);
|
||||
memset(key+keylen, (int)' ', sizeof(key)-1 - keylen); // Pad with space
|
||||
key[sizeof(key)-1]= type;
|
||||
keylen= sizeof(key);
|
||||
|
||||
for (table= thd->open_tables ; table ; table= table->next)
|
||||
if (strcmp(table->table_cache_key, "mysql") == 0 &&
|
||||
strcmp(table->real_name, "proc") == 0)
|
||||
break;
|
||||
if (table)
|
||||
*opened= FALSE;
|
||||
else
|
||||
{
|
||||
TABLE_LIST tables;
|
||||
|
||||
memset(&tables, 0, sizeof(tables));
|
||||
tables.db= (char*)"mysql";
|
||||
tables.real_name= tables.alias= (char*)"proc";
|
||||
if (! (table= open_ltable(thd, &tables, ltype)))
|
||||
{
|
||||
*tablep= NULL;
|
||||
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
|
||||
}
|
||||
*opened= TRUE;
|
||||
}
|
||||
|
||||
if (table->file->index_read_idx(table->record[0], 0,
|
||||
key, keylen,
|
||||
HA_READ_KEY_EXACT))
|
||||
{
|
||||
*tablep= NULL;
|
||||
DBUG_RETURN(SP_KEY_NOT_FOUND);
|
||||
}
|
||||
*tablep= table;
|
||||
|
||||
DBUG_RETURN(SP_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
|
||||
{
|
||||
DBUG_ENTER("db_find_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
|
||||
extern int yyparse(void *thd);
|
||||
TABLE *table;
|
||||
const char *defstr;
|
||||
int ret;
|
||||
bool opened;
|
||||
const char *creator;
|
||||
longlong created;
|
||||
longlong modified;
|
||||
bool suid= 1;
|
||||
char *ptr;
|
||||
uint length;
|
||||
char buff[65];
|
||||
String str(buff, sizeof(buff), &my_charset_bin);
|
||||
|
||||
ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened);
|
||||
if (ret != SP_OK)
|
||||
goto done;
|
||||
|
||||
if (table->fields != MYSQL_PROC_FIELD_COUNT)
|
||||
{
|
||||
ret= SP_GET_FIELD_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((defstr= get_field(&thd->mem_root,
|
||||
table->field[MYSQL_PROC_FIELD_DEFINITION])) == NULL)
|
||||
{
|
||||
ret= SP_GET_FIELD_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Get additional information
|
||||
if ((creator= get_field(&thd->mem_root,
|
||||
table->field[MYSQL_PROC_FIELD_CREATOR])) == NULL)
|
||||
{
|
||||
ret= SP_GET_FIELD_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
modified= table->field[MYSQL_PROC_FIELD_MODIFIED]->val_int();
|
||||
created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int();
|
||||
|
||||
if ((ptr= get_field(&thd->mem_root,
|
||||
table->field[MYSQL_PROC_FIELD_SUID])) == NULL)
|
||||
{
|
||||
ret= SP_GET_FIELD_FAILED;
|
||||
goto done;
|
||||
}
|
||||
if (ptr[0] == 'N')
|
||||
suid= 0;
|
||||
|
||||
table->field[MYSQL_PROC_FIELD_COMMENT]->val_str(&str, &str);
|
||||
|
||||
ptr= 0;
|
||||
if ((length= str.length()))
|
||||
ptr= strmake_root(&thd->mem_root, str.ptr(), length);
|
||||
|
||||
if (opened)
|
||||
{
|
||||
close_thread_tables(thd, 0, 1);
|
||||
opened= FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
LEX *oldlex= thd->lex;
|
||||
enum enum_sql_command oldcmd= thd->lex->sql_command;
|
||||
|
||||
lex_start(thd, (uchar*)defstr, strlen(defstr));
|
||||
if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL)
|
||||
{
|
||||
LEX *newlex= thd->lex;
|
||||
sp_head *sp= newlex->sphead;
|
||||
|
||||
if (sp)
|
||||
{
|
||||
if (oldlex != newlex)
|
||||
sp->restore_lex(thd);
|
||||
delete sp;
|
||||
newlex->sphead= NULL;
|
||||
}
|
||||
ret= SP_PARSE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sphp= thd->lex->sphead;
|
||||
(*sphp)->sp_set_info((char *) creator, (uint) strlen(creator),
|
||||
created, modified, suid,
|
||||
ptr, length);
|
||||
}
|
||||
thd->lex->sql_command= oldcmd;
|
||||
}
|
||||
|
||||
done:
|
||||
if (opened)
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
db_create_routine(THD *thd, int type,
|
||||
char *name, uint namelen, char *def, uint deflen,
|
||||
char *comment, uint commentlen, bool suid)
|
||||
{
|
||||
DBUG_ENTER("db_create_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s def: %*s", type, namelen, name, deflen, def));
|
||||
int ret;
|
||||
TABLE *table;
|
||||
TABLE_LIST tables;
|
||||
char creator[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
|
||||
|
||||
memset(&tables, 0, sizeof(tables));
|
||||
tables.db= (char*)"mysql";
|
||||
tables.real_name= tables.alias= (char*)"proc";
|
||||
|
||||
if (! (table= open_ltable(thd, &tables, TL_WRITE)))
|
||||
ret= SP_OPEN_TABLE_FAILED;
|
||||
else
|
||||
{
|
||||
restore_record(table, default_values); // Get default values for fields
|
||||
strxmov(creator, thd->user, "@", thd->host_or_ip, NullS);
|
||||
|
||||
if (table->fields != MYSQL_PROC_FIELD_COUNT)
|
||||
{
|
||||
ret= SP_GET_FIELD_FAILED;
|
||||
goto done;
|
||||
}
|
||||
table->field[MYSQL_PROC_FIELD_NAME]->store(name, namelen,
|
||||
system_charset_info);
|
||||
table->field[MYSQL_PROC_FIELD_TYPE]->store((longlong)type);
|
||||
table->field[MYSQL_PROC_FIELD_DEFINITION]->store(def, deflen,
|
||||
system_charset_info);
|
||||
table->field[MYSQL_PROC_FIELD_CREATOR]->store(creator,
|
||||
(uint)strlen(creator),
|
||||
system_charset_info);
|
||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
|
||||
if (!suid)
|
||||
table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) 1);
|
||||
if (comment)
|
||||
table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, commentlen,
|
||||
system_charset_info);
|
||||
|
||||
if (table->file->write_row(table->record[0]))
|
||||
ret= SP_WRITE_ROW_FAILED;
|
||||
else
|
||||
ret= SP_OK;
|
||||
}
|
||||
|
||||
done:
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
db_drop_routine(THD *thd, int type, char *name, uint namelen)
|
||||
{
|
||||
DBUG_ENTER("db_drop_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
|
||||
TABLE *table;
|
||||
int ret;
|
||||
bool opened;
|
||||
|
||||
ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened);
|
||||
if (ret == SP_OK)
|
||||
{
|
||||
if (table->file->delete_row(table->record[0]))
|
||||
ret= SP_DELETE_ROW_FAILED;
|
||||
}
|
||||
|
||||
if (opened)
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
db_update_routine(THD *thd, int type, char *name, uint namelen,
|
||||
char *newname, uint newnamelen,
|
||||
char *comment, uint commentlen, enum suid_behaviour suid)
|
||||
{
|
||||
DBUG_ENTER("db_update_routine");
|
||||
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
|
||||
TABLE *table;
|
||||
int ret;
|
||||
bool opened;
|
||||
|
||||
ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened);
|
||||
if (ret == SP_OK)
|
||||
{
|
||||
store_record(table,record[1]);
|
||||
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
|
||||
if (suid)
|
||||
table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) suid);
|
||||
if (newname)
|
||||
table->field[MYSQL_PROC_FIELD_NAME]->store(newname,
|
||||
newnamelen,
|
||||
system_charset_info);
|
||||
if (comment)
|
||||
table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment,
|
||||
commentlen,
|
||||
system_charset_info);
|
||||
if ((table->file->update_row(table->record[1],table->record[0])))
|
||||
ret= SP_WRITE_ROW_FAILED;
|
||||
}
|
||||
if (opened)
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
struct st_used_field
|
||||
{
|
||||
const char *field_name;
|
||||
uint field_length;
|
||||
enum enum_field_types field_type;
|
||||
Field *field;
|
||||
};
|
||||
|
||||
static struct st_used_field init_fields[]=
|
||||
{
|
||||
{ "Name", NAME_LEN, MYSQL_TYPE_STRING, 0},
|
||||
{ "Type", 9, MYSQL_TYPE_STRING, 0},
|
||||
{ "Creator", 77, MYSQL_TYPE_STRING, 0},
|
||||
{ "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0},
|
||||
{ "Created", 0, MYSQL_TYPE_TIMESTAMP, 0},
|
||||
{ "Suid", 1, MYSQL_TYPE_STRING, 0},
|
||||
{ "Comment", NAME_LEN, MYSQL_TYPE_STRING, 0},
|
||||
{ 0, 0, MYSQL_TYPE_STRING, 0}
|
||||
};
|
||||
|
||||
int print_field_values(THD *thd, TABLE *table,
|
||||
struct st_used_field *used_fields,
|
||||
int type, const char *wild)
|
||||
{
|
||||
Protocol *protocol= thd->protocol;
|
||||
|
||||
if (table->field[MYSQL_PROC_FIELD_TYPE]->val_int() == type)
|
||||
{
|
||||
String *tmp_string= new String();
|
||||
struct st_used_field *used_field= used_fields;
|
||||
get_field(&thd->mem_root,
|
||||
used_field->field,
|
||||
tmp_string);
|
||||
if (!wild || !wild[0] || !wild_compare(tmp_string->ptr(), wild, 0))
|
||||
{
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(tmp_string);
|
||||
for (used_field++;
|
||||
used_field->field_name;
|
||||
used_field++)
|
||||
{
|
||||
switch (used_field->field_type) {
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
{
|
||||
TIME tmp_time;
|
||||
((Field_timestamp *) used_field->field)->get_time(&tmp_time);
|
||||
protocol->store(&tmp_time);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
String *tmp_string1= new String();
|
||||
get_field(&thd->mem_root, used_field->field, tmp_string1);
|
||||
protocol->store(tmp_string1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (protocol->write())
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
db_show_routine_status(THD *thd, int type, const char *wild)
|
||||
{
|
||||
DBUG_ENTER("db_show_routine_status");
|
||||
|
||||
TABLE *table;
|
||||
TABLE_LIST tables;
|
||||
|
||||
memset(&tables, 0, sizeof(tables));
|
||||
tables.db= (char*)"mysql";
|
||||
tables.real_name= tables.alias= (char*)"proc";
|
||||
|
||||
if (! (table= open_ltable(thd, &tables, TL_READ)))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Item *item;
|
||||
List<Item> field_list;
|
||||
struct st_used_field *used_field;
|
||||
st_used_field used_fields[array_elements(init_fields)];
|
||||
memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields));
|
||||
/* Init header */
|
||||
for (used_field= &used_fields[0];
|
||||
used_field->field_name;
|
||||
used_field++)
|
||||
{
|
||||
switch (used_field->field_type) {
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
field_list.push_back(item=new Item_datetime(used_field->field_name));
|
||||
break;
|
||||
default:
|
||||
field_list.push_back(item=new Item_empty_string(used_field->field_name,
|
||||
used_field->
|
||||
field_length));
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Print header */
|
||||
if (thd->protocol->send_fields(&field_list,1))
|
||||
goto err_case;
|
||||
|
||||
/* Init fields */
|
||||
setup_tables(&tables);
|
||||
for (used_field= &used_fields[0];
|
||||
used_field->field_name;
|
||||
used_field++)
|
||||
{
|
||||
TABLE_LIST *not_used;
|
||||
Item_field *field= new Item_field("mysql", "proc",
|
||||
used_field->field_name);
|
||||
if (!(used_field->field= find_field_in_tables(thd, field, &tables,
|
||||
¬_used, TRUE)))
|
||||
goto err_case1;
|
||||
}
|
||||
|
||||
table->file->index_init(0);
|
||||
table->file->index_first(table->record[0]);
|
||||
if (print_field_values(thd, table, used_fields, type, wild))
|
||||
goto err_case1;
|
||||
while (!table->file->index_next(table->record[0]))
|
||||
{
|
||||
if (print_field_values(thd, table, used_fields, type, wild))
|
||||
goto err_case1;
|
||||
}
|
||||
send_eof(thd);
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
err_case1:
|
||||
send_eof(thd);
|
||||
err_case:
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* PROCEDURE
|
||||
*
|
||||
*/
|
||||
|
||||
sp_head *
|
||||
sp_find_procedure(THD *thd, LEX_STRING *name)
|
||||
{
|
||||
DBUG_ENTER("sp_find_procedure");
|
||||
sp_head *sp;
|
||||
|
||||
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
|
||||
|
||||
sp= sp_cache_lookup(&thd->sp_proc_cache, name->str, name->length);
|
||||
if (! sp)
|
||||
{
|
||||
if (db_find_routine(thd, TYPE_ENUM_PROCEDURE,
|
||||
name->str, name->length, &sp) == SP_OK)
|
||||
{
|
||||
sp_cache_insert(&thd->sp_proc_cache, sp);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(sp);
|
||||
}
|
||||
|
||||
int
|
||||
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen,
|
||||
char *comment, uint commentlen, bool suid)
|
||||
{
|
||||
DBUG_ENTER("sp_create_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def));
|
||||
int ret;
|
||||
|
||||
ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen,
|
||||
comment, commentlen, suid);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_drop_procedure(THD *thd, char *name, uint namelen)
|
||||
{
|
||||
DBUG_ENTER("sp_drop_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", namelen, name));
|
||||
sp_head *sp;
|
||||
int ret;
|
||||
|
||||
sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen);
|
||||
if (sp)
|
||||
delete sp;
|
||||
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_update_procedure(THD *thd, char *name, uint namelen,
|
||||
char *newname, uint newnamelen,
|
||||
char *comment, uint commentlen, enum suid_behaviour suid)
|
||||
{
|
||||
DBUG_ENTER("sp_update_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", namelen, name));
|
||||
sp_head *sp;
|
||||
int ret;
|
||||
|
||||
sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen);
|
||||
if (sp)
|
||||
delete sp;
|
||||
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
|
||||
newname, newnamelen,
|
||||
comment, commentlen, suid);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_show_create_procedure(THD *thd, LEX_STRING *name)
|
||||
{
|
||||
DBUG_ENTER("sp_show_create_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
|
||||
sp_head *sp;
|
||||
|
||||
sp= sp_find_procedure(thd, name);
|
||||
if (sp)
|
||||
DBUG_RETURN(sp->show_create_procedure(thd));
|
||||
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
int
|
||||
db_show_status_procedure(THD *thd, const char *wild)
|
||||
{
|
||||
DBUG_ENTER("db_show_status_procedure");
|
||||
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild));
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* FUNCTION
|
||||
*
|
||||
*/
|
||||
|
||||
sp_head *
|
||||
sp_find_function(THD *thd, LEX_STRING *name)
|
||||
{
|
||||
DBUG_ENTER("sp_find_function");
|
||||
sp_head *sp;
|
||||
|
||||
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
|
||||
|
||||
sp= sp_cache_lookup(&thd->sp_func_cache, name->str, name->length);
|
||||
if (! sp)
|
||||
{
|
||||
if (db_find_routine(thd, TYPE_ENUM_FUNCTION,
|
||||
name->str, name->length, &sp) != SP_OK)
|
||||
sp= NULL;
|
||||
}
|
||||
DBUG_RETURN(sp);
|
||||
}
|
||||
|
||||
int
|
||||
sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen,
|
||||
char *comment, uint commentlen, bool suid)
|
||||
{
|
||||
DBUG_ENTER("sp_create_function");
|
||||
DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def));
|
||||
int ret;
|
||||
|
||||
ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen,
|
||||
comment, commentlen, suid);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_drop_function(THD *thd, char *name, uint namelen)
|
||||
{
|
||||
DBUG_ENTER("sp_drop_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", namelen, name));
|
||||
sp_head *sp;
|
||||
int ret;
|
||||
|
||||
sp= sp_cache_remove(&thd->sp_func_cache, name, namelen);
|
||||
if (sp)
|
||||
delete sp;
|
||||
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_update_function(THD *thd, char *name, uint namelen,
|
||||
char *newname, uint newnamelen,
|
||||
char *comment, uint commentlen, enum suid_behaviour suid)
|
||||
{
|
||||
DBUG_ENTER("sp_update_procedure");
|
||||
DBUG_PRINT("enter", ("name: %*s", namelen, name));
|
||||
sp_head *sp;
|
||||
int ret;
|
||||
|
||||
sp= sp_cache_remove(&thd->sp_func_cache, name, namelen);
|
||||
if (sp)
|
||||
delete sp;
|
||||
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
|
||||
newname, newnamelen,
|
||||
comment, commentlen, suid);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
int
|
||||
sp_show_create_function(THD *thd, LEX_STRING *name)
|
||||
{
|
||||
DBUG_ENTER("sp_show_create_function");
|
||||
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
|
||||
sp_head *sp;
|
||||
|
||||
sp= sp_find_function(thd, name);
|
||||
if (sp)
|
||||
DBUG_RETURN(sp->show_create_function(thd));
|
||||
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
int
|
||||
db_show_status_function(THD *thd, const char *wild)
|
||||
{
|
||||
DBUG_ENTER("db_show_status_function");
|
||||
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild));
|
||||
}
|
||||
|
||||
// QQ Temporary until the function call detection in sql_lex has been reworked.
|
||||
bool
|
||||
sp_function_exists(THD *thd, LEX_STRING *name)
|
||||
{
|
||||
TABLE *table;
|
||||
bool ret= FALSE;
|
||||
bool opened= FALSE;
|
||||
|
||||
if (sp_cache_lookup(&thd->sp_func_cache, name->str, name->length) ||
|
||||
db_find_routine_aux(thd, TYPE_ENUM_FUNCTION,
|
||||
name->str, name->length, TL_READ,
|
||||
&table, &opened) == SP_OK)
|
||||
{
|
||||
ret= TRUE;
|
||||
}
|
||||
if (opened)
|
||||
close_thread_tables(thd, 0, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
byte *
|
||||
sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first)
|
||||
{
|
||||
LEX_STRING *lsp= (LEX_STRING *)ptr;
|
||||
*plen= lsp->length;
|
||||
return (byte *)lsp->str;
|
||||
}
|
||||
|
||||
void
|
||||
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun)
|
||||
{
|
||||
if (! hash_search(&lex->spfuns, (byte *)fun.str, fun.length))
|
||||
{
|
||||
LEX_STRING *ls= (LEX_STRING *)sql_alloc(sizeof(LEX_STRING));
|
||||
ls->str= sql_strmake(fun.str, fun.length);
|
||||
ls->length= fun.length;
|
||||
|
||||
my_hash_insert(&lex->spfuns, (byte *)ls);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sp_merge_funs(LEX *dst, LEX *src)
|
||||
{
|
||||
for (uint i=0 ; i < src->spfuns.records ; i++)
|
||||
{
|
||||
LEX_STRING *ls= (LEX_STRING *)hash_element(&src->spfuns, i);
|
||||
|
||||
if (! hash_search(&dst->spfuns, (byte *)ls->str, ls->length))
|
||||
my_hash_insert(&dst->spfuns, (byte *)ls);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sp_cache_functions(THD *thd, LEX *lex)
|
||||
{
|
||||
HASH *h= &lex->spfuns;
|
||||
int ret= 0;
|
||||
|
||||
for (uint i=0 ; i < h->records ; i++)
|
||||
{
|
||||
LEX_STRING *ls= (LEX_STRING *)hash_element(h, i);
|
||||
|
||||
if (! sp_cache_lookup(&thd->sp_func_cache, ls->str, ls->length))
|
||||
{
|
||||
sp_head *sp;
|
||||
LEX *oldlex= thd->lex;
|
||||
LEX *newlex= new st_lex;
|
||||
|
||||
thd->lex= newlex;
|
||||
if (db_find_routine(thd, TYPE_ENUM_FUNCTION, ls->str, ls->length, &sp)
|
||||
== SP_OK)
|
||||
{
|
||||
ret= sp_cache_functions(thd, newlex);
|
||||
delete newlex;
|
||||
thd->lex= oldlex;
|
||||
if (ret)
|
||||
break;
|
||||
sp_cache_insert(&thd->sp_func_cache, sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete newlex;
|
||||
thd->lex= oldlex;
|
||||
net_printf(thd, ER_SP_DOES_NOT_EXIST, "FUNCTION", ls->str);
|
||||
ret= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user