Merge with 4.1 to get in latest bug fixes
This commit is contained in:
commit
071001950e
@ -98,12 +98,14 @@ kaj@work.mysql.com
|
||||
kent@mysql.com
|
||||
konstantin@mysql.com
|
||||
kostja@oak.local
|
||||
lars@mysql.com
|
||||
lenz@kallisto.mysql.com
|
||||
lenz@mysql.com
|
||||
magnus@neptunus.(none)
|
||||
magnus@shellback.(none)
|
||||
marko@hundin.mysql.fi
|
||||
matt@mysql.com
|
||||
matthias@three.local.lan
|
||||
miguel@hegel.(none)
|
||||
miguel@hegel.br
|
||||
miguel@hegel.local
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!PATH_TO_PERL -*- perl -*-
|
||||
#!/usr/bin/perl
|
||||
# Add path to perl on the previous line and make this executable
|
||||
# if you want to use this as a normal script.
|
||||
'di ';
|
||||
@ -12,7 +12,7 @@
|
||||
#-##############################################################################
|
||||
|
||||
# @(#)texi2html 1.52 971230 Written (mainly) by Lionel Cons, Lionel.Cons@cern.ch
|
||||
# Enhanced by David Axmark, david@detron.se
|
||||
# Enhanced by David Axmark
|
||||
|
||||
# The man page for this program is included at the end of this file and can be
|
||||
# viewed using the command 'nroff -man texi2html'.
|
||||
@ -40,8 +40,7 @@ $NODESRE = '[^@{}:\'`"]+'; # RE for a list of node names
|
||||
$XREFRE = '[^@{}]+'; # RE for a xref (should use NODERE)
|
||||
|
||||
$ERROR = "***"; # prefix for errors and warnings
|
||||
$THISPROG = "texi2html 1.52 (hacked by david\@detron.se)"; # program name and version
|
||||
$HOMEPAGE = "http://www.mathematik.uni-kl.de/~obachman/Texi2html/"; # program home page
|
||||
$THISPROG = "texi2html 1.52 (with additions by MySQL AB)"; # program name and version
|
||||
$TODAY = &pretty_date; # like "20 September 1993"
|
||||
$SPLITTAG = "<!-- SPLIT HERE -->\n"; # tag to know where to split
|
||||
$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections
|
||||
@ -114,10 +113,12 @@ $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//E
|
||||
#
|
||||
%accent_map = (
|
||||
'"', 'uml',
|
||||
'\'', 'acute',
|
||||
',{', 'cedil',
|
||||
'~', 'tilde',
|
||||
'^', 'circ',
|
||||
'`', 'grave',
|
||||
'\'', 'acute',
|
||||
'ringaccent{', 'ring',
|
||||
);
|
||||
|
||||
#
|
||||
@ -125,7 +126,7 @@ $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//E
|
||||
#
|
||||
%simple_map = (
|
||||
# cf. makeinfo.c
|
||||
"*", "<BR>", # HTML+
|
||||
"*", "<br />", # HTML+
|
||||
" ", " ",
|
||||
"\n", "\n",
|
||||
"|", "",
|
||||
@ -134,6 +135,8 @@ $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//E
|
||||
"!", "!",
|
||||
"?", "?",
|
||||
".", ".",
|
||||
# @- means "allow word break", not —
|
||||
"-", "",
|
||||
);
|
||||
|
||||
#
|
||||
@ -141,9 +144,10 @@ $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//E
|
||||
#
|
||||
%things_map = (
|
||||
'TeX', 'TeX',
|
||||
'br', '<P>', # paragraph break
|
||||
'br', '<p>', # paragraph break
|
||||
'bullet', '*',
|
||||
'copyright', '(C)',
|
||||
'registeredsymbol', '(R)',
|
||||
'dots', '...',
|
||||
'equiv', '==',
|
||||
'error', 'error-->',
|
||||
@ -161,27 +165,28 @@ $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//E
|
||||
%style_map = (
|
||||
'asis', '',
|
||||
'b', 'B',
|
||||
'cite', 'CITE',
|
||||
'code', 'CODE',
|
||||
'cite', 'cite',
|
||||
'code', 'code',
|
||||
'command', 'code',
|
||||
'ctrl', '&do_ctrl', # special case
|
||||
'dfn', 'STRONG', # DFN tag is illegal in the standard
|
||||
'dfn', 'strong', # DFN tag is illegal in the standard
|
||||
'dmn', '', # useless
|
||||
'email', '&fix_email', # special
|
||||
'emph', 'EM',
|
||||
'file', '"TT', # will put quotes, cf. &apply_style
|
||||
'i', 'I',
|
||||
'kbd', 'KBD',
|
||||
'key', 'KBD',
|
||||
'emph', 'em',
|
||||
'file', '"tt', # will put quotes, cf. &apply_style
|
||||
'i', 'i',
|
||||
'kbd', 'kbd',
|
||||
'key', 'kbd',
|
||||
'r', '', # unsupported
|
||||
'samp', '"SAMP', # will put quotes, cf. &apply_style
|
||||
'samp', '"samp', # will put quotes, cf. &apply_style
|
||||
'sc', '&do_sc', # special case
|
||||
'strong', 'STRONG',
|
||||
't', 'TT',
|
||||
'strong', 'strong',
|
||||
't', 'tt',
|
||||
'titlefont', '', # useless
|
||||
'image', '&fix_image', # Image
|
||||
'url', '&fix_url', # URL
|
||||
'uref', '&fix_uref', # URL Reference
|
||||
'var', 'VAR',
|
||||
'var', 'var',
|
||||
'w', '', # unsupported
|
||||
);
|
||||
|
||||
@ -317,6 +322,7 @@ $usage = <<EOT;
|
||||
This is $THISPROG
|
||||
To convert a Texinfo file to HMTL: $0 [options] file
|
||||
where options can be:
|
||||
-acc : convert @"-like accents to &entities;
|
||||
-expandinfo : use \@ifinfo sections, not \@iftex
|
||||
-glossary : handle a glossary
|
||||
-invisible name: use 'name' as an invisible anchor
|
||||
@ -445,11 +451,15 @@ $html_num = 0;
|
||||
if ($use_iso) {
|
||||
$things_map{'bullet'} = "•";
|
||||
$things_map{'copyright'} = "©";
|
||||
$things_map{'registeredsymbol'} = "®";
|
||||
$things_map{'dots'} = "…";
|
||||
$things_map{'equiv'} = "≡";
|
||||
$things_map{'expansion'} = "→";
|
||||
$things_map{'point'} = "∗";
|
||||
$things_map{'result'} = "⇒";
|
||||
$things_map{'ss'} = "ß";
|
||||
$things_map{'o'} = "ø";
|
||||
$things_map{'O'} = "Ø";
|
||||
}
|
||||
|
||||
#
|
||||
@ -505,23 +515,27 @@ $html_element = ''; # current HTML element
|
||||
# watch out for regexps, / and escaped characters!
|
||||
$subst_code = '';
|
||||
foreach (keys(%simple_map)) {
|
||||
($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
|
||||
$subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
|
||||
$re = quotemeta $_; # protect regexp chars
|
||||
$sub = quotemeta $simple_map{$_};
|
||||
$subst_code .= "s/\\\@$re/$sub/g;\n";
|
||||
}
|
||||
foreach (keys(%things_map)) {
|
||||
$subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
|
||||
$re = quotemeta $_; # protect regexp chars
|
||||
$sub = quotemeta $things_map{$_};
|
||||
$subst_code .= "s/\\\@$re\\{\\}/$sub/g;\n";
|
||||
}
|
||||
if ($use_acc) {
|
||||
# accentuated characters
|
||||
foreach (keys(%accent_map)) {
|
||||
my $brace = /{$/ ? '}' : '';
|
||||
if ($_ eq "`") {
|
||||
$subst_code .= "s/$;3";
|
||||
} elsif ($_ eq "'") {
|
||||
$subst_code .= "s/$;4";
|
||||
} else {
|
||||
$subst_code .= "s/\\\@\\$_";
|
||||
$subst_code .= "s/\\\@\\Q$_\\E";
|
||||
}
|
||||
$subst_code .= "([aeiou])/&\${1}$accent_map{$_};/gi;\n";
|
||||
$subst_code .= "(\\w)$brace/&\${1}$accent_map{$_};/gi;\n";
|
||||
}
|
||||
}
|
||||
eval("sub simple_substitutions { $subst_code }");
|
||||
@ -703,7 +717,7 @@ READ_LINE: while ($_ = &next_line)
|
||||
s/{[^{}]+}//g);
|
||||
print "# Multitable with $multitable_cols columns\n"
|
||||
if $debug and $DEBUG_USER;
|
||||
push(@lines, &debug("<TABLE BORDER WIDTH=\"100%\">\n", __LINE__));
|
||||
push(@lines, &debug("<TABLE BORDER>\n", __LINE__));
|
||||
} else {
|
||||
warn "$ERROR Bad table line: $_";
|
||||
}
|
||||
@ -873,7 +887,7 @@ READ_LINE: while ($_ = &next_line)
|
||||
&simple_substitutions;
|
||||
s/\@value{($VARRE)}/$value{$1}/eg;
|
||||
s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
|
||||
s|\s+\@tab\s*| </TD><TD> |g if ($in_multitable);
|
||||
s/(^|\s+)\@tab\s*/ <\/TD><TD> /g if ($in_multitable);
|
||||
|
||||
#
|
||||
# analyze the tag again
|
||||
@ -885,7 +899,7 @@ READ_LINE: while ($_ = &next_line)
|
||||
$name =~ s/\s+$//;
|
||||
$level = $sec2level{$tag};
|
||||
$name = &update_sec_num($tag, $level) . " $name"
|
||||
if $number_sections && $tag !~ /^unnumbered/;
|
||||
if $number_sections && $tag !~ /^unnumbered/ && $tag ne 'subsubheading';
|
||||
if ($tag =~ /heading$/) {
|
||||
push(@lines, &html_debug("\n", __LINE__));
|
||||
if ($html_element ne 'body') {
|
||||
@ -1079,7 +1093,7 @@ EOC
|
||||
push(@lines, &debug("</TD></TR>\n", __LINE__))
|
||||
unless $html_element eq 'TABLE';
|
||||
&html_pop_if('TR');
|
||||
$what =~ s|\s+\@tab\s*| </TD><TD> |g;
|
||||
$what =~ s/(^|\s+)\@tab\s*/ <\/TD><TD> /g;
|
||||
push(@lines, &debug("<TR><TD>$what\n", __LINE__));
|
||||
&html_push('TR');
|
||||
if ($deferred_ref)
|
||||
@ -1463,11 +1477,7 @@ print "# end of pass 4\n" if $verbose;
|
||||
# #
|
||||
#---############################################################################
|
||||
|
||||
$header = <<EOT;
|
||||
<!-- This HTML file has been created by $THISPROG
|
||||
from $docu on $TODAY -->
|
||||
EOT
|
||||
|
||||
$header = '';
|
||||
$full_title = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
|
||||
$title = $value{'_settitle'} || $full_title;
|
||||
$_ = &substitute_style($full_title);
|
||||
@ -1815,8 +1825,10 @@ sub fix_image
|
||||
die "error in image: '$text'" unless defined($1);
|
||||
$arg1 = $1;
|
||||
$arg1 =~ s/@@/@/g;
|
||||
$ext = "jpg" if -f "$arg1.jpg";
|
||||
$ext = "gif" if -f "$arg1.gif";
|
||||
foreach (@include_dirs) {
|
||||
$ext = "jpg" if -f "$_/$arg1.jpg";
|
||||
$ext = "gif" if -f "$_/$arg1.gif";
|
||||
}
|
||||
if (defined($ext))
|
||||
{
|
||||
"<IMG SRC=\"$arg1.$ext\">";
|
||||
@ -2010,7 +2022,7 @@ sub print_toplevel_header
|
||||
{
|
||||
local($_);
|
||||
|
||||
&print_header; # pass given arg...
|
||||
&print_header unless $opt_empty_headers; # pass given arg...
|
||||
print FILE $full_title;
|
||||
if ($value{'_subtitle'}) {
|
||||
$value{'_subtitle'} =~ s/\n+$//;
|
||||
@ -2042,13 +2054,7 @@ EOT
|
||||
|
||||
sub print_toplevel_footer
|
||||
{
|
||||
&print_ruler;
|
||||
print FILE <<EOT;
|
||||
This document was generated on $TODAY using the
|
||||
<A HREF=\"$HOMEPAGE\">texi2html</A>
|
||||
translator version 1.52 (extended by davida\@detron.se).</P>
|
||||
EOT
|
||||
&print_footer;
|
||||
&print_footer unless $opt_empty_headers;
|
||||
}
|
||||
|
||||
sub protect_texi
|
||||
@ -2065,8 +2071,10 @@ sub protect_html
|
||||
{
|
||||
local($what) = @_;
|
||||
# protect & < >
|
||||
# Avoid loop in & replacement. This instead bugs out for &# in text..
|
||||
$what =~ s/\&([^#]|$)/\&\#38;$1/g;
|
||||
# hack for the two entity-like variable reference in existing examples
|
||||
$what =~ s/\&(length|ts);/\&\#38;$1;/g;
|
||||
# this leaves alone entities, but encodes standalone ampersands
|
||||
$what =~ s/\&(?!([a-z0-9]+|#\d+);)/\&\#38;/ig;
|
||||
$what =~ s/\</\&\#60;/g;
|
||||
$what =~ s/\>/\&\#62;/g;
|
||||
# but recognize some HTML things
|
||||
|
@ -81,8 +81,13 @@ static struct my_option my_long_options[] =
|
||||
"To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
|
||||
(gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
#ifdef DBUG_OFF
|
||||
{"debug", '#', "This is a non-debug version. Catch this and exit.",
|
||||
0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#else
|
||||
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"default-character-set", OPT_DEFAULT_CHARSET,
|
||||
"Set the default character set.", (gptr*) &default_charset,
|
||||
(gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#define MTEST_VERSION "2.3"
|
||||
#define MTEST_VERSION "2.4"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_embed.h>
|
||||
@ -243,6 +243,7 @@ VAR var_reg[10];
|
||||
HASH var_hash;
|
||||
my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0;
|
||||
my_bool disable_info= 1; /* By default off */
|
||||
my_bool abort_on_error= 1;
|
||||
|
||||
struct connection cons[MAX_CONS];
|
||||
struct connection* cur_con, *next_con, *cons_end;
|
||||
@ -274,6 +275,7 @@ Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
|
||||
Q_ENABLE_INFO, Q_DISABLE_INFO,
|
||||
Q_ENABLE_METADATA, Q_DISABLE_METADATA,
|
||||
Q_EXEC, Q_DELIMITER,
|
||||
Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
|
||||
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
|
||||
Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
|
||||
Q_START_TIMER, Q_END_TIMER,
|
||||
@ -353,6 +355,8 @@ const char *command_names[]=
|
||||
"disable_metadata",
|
||||
"exec",
|
||||
"delimiter",
|
||||
"disable_abort_on_error",
|
||||
"enable_abort_on_error",
|
||||
"vertical_results",
|
||||
"horizontal_results",
|
||||
"query_vertical",
|
||||
@ -741,7 +745,7 @@ err:
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static VAR* var_obtain(char* name, int len)
|
||||
static VAR *var_obtain(const char* name, int len)
|
||||
{
|
||||
VAR* v;
|
||||
if ((v = (VAR*)hash_search(&var_hash, name, len)))
|
||||
@ -751,28 +755,33 @@ static VAR* var_obtain(char* name, int len)
|
||||
return v;
|
||||
}
|
||||
|
||||
int var_set(char* var_name, char* var_name_end, char* var_val,
|
||||
char* var_val_end)
|
||||
int var_set(const char *var_name, const char *var_name_end,
|
||||
const char *var_val, const char *var_val_end)
|
||||
{
|
||||
int digit;
|
||||
VAR* v;
|
||||
DBUG_ENTER("var_set");
|
||||
DBUG_PRINT("enter", ("var_name: '%.*s' = '%.*s' (length: %d)",
|
||||
(int) (var_name_end - var_name), var_name,
|
||||
(int) (var_val_end - var_val), var_val,
|
||||
(int) (var_val_end - var_val)));
|
||||
|
||||
if (*var_name++ != '$')
|
||||
{
|
||||
--var_name;
|
||||
*var_name_end = 0;
|
||||
die("Variable name in %s does not start with '$'", var_name);
|
||||
}
|
||||
{
|
||||
var_name--;
|
||||
die("Variable name in %s does not start with '$'", var_name);
|
||||
}
|
||||
digit = *var_name - '0';
|
||||
if (!(digit < 10 && digit >= 0))
|
||||
{
|
||||
v = var_obtain(var_name, var_name_end - var_name);
|
||||
}
|
||||
{
|
||||
v = var_obtain(var_name, (uint) (var_name_end - var_name));
|
||||
}
|
||||
else
|
||||
v = var_reg + digit;
|
||||
|
||||
v = var_reg + digit;
|
||||
return eval_expr(v, var_val, (const char**)&var_val_end);
|
||||
}
|
||||
|
||||
|
||||
int open_file(const char* name)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
@ -1241,6 +1250,22 @@ int do_let(struct st_query* q)
|
||||
return var_set(var_name, var_name_end, var_val_start, q->end);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Store an integer (typically the returncode of the last SQL)
|
||||
statement in the mysqltest builtin variable $mysql_errno, by
|
||||
simulating of a user statement "let $mysql_errno= <integer>"
|
||||
*/
|
||||
|
||||
int var_set_errno(int sql_errno)
|
||||
{
|
||||
const char *var_name= "$mysql_errno";
|
||||
char var_val[21];
|
||||
uint length= my_sprintf(var_val, (var_val, "%d", sql_errno));
|
||||
return var_set(var_name, var_name + 12, var_val, var_val + length);
|
||||
}
|
||||
|
||||
|
||||
int do_rpl_probe(struct st_query* q __attribute__((unused)))
|
||||
{
|
||||
DBUG_ENTER("do_rpl_probe");
|
||||
@ -1249,12 +1274,14 @@ int do_rpl_probe(struct st_query* q __attribute__((unused)))
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int do_enable_rpl_parse(struct st_query* q __attribute__((unused)))
|
||||
{
|
||||
mysql_enable_rpl_parse(&cur_con->mysql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
|
||||
{
|
||||
mysql_disable_rpl_parse(&cur_con->mysql);
|
||||
@ -1998,7 +2025,7 @@ int read_query(struct st_query** q_ptr)
|
||||
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
|
||||
sizeof(global_expected_errno));
|
||||
q->expected_errors= global_expected_errors;
|
||||
q->abort_on_error= global_expected_errors == 0;
|
||||
q->abort_on_error= (global_expected_errors == 0 && abort_on_error);
|
||||
bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
|
||||
global_expected_errors=0;
|
||||
if (p[0] == '-' && p[1] == '-')
|
||||
@ -2407,7 +2434,7 @@ static int run_query(MYSQL *mysql, struct st_query *q, int flags)
|
||||
|
||||
if (ps_protocol_enabled && disable_info &&
|
||||
(flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query))
|
||||
return run_query_stmt (mysql, q, flags);
|
||||
return run_query_stmt(mysql, q, flags);
|
||||
return run_query_normal(mysql, q, flags);
|
||||
}
|
||||
|
||||
@ -2644,6 +2671,13 @@ end:
|
||||
dynstr_free(&ds_tmp);
|
||||
if (q->type == Q_EVAL)
|
||||
dynstr_free(&eval_query);
|
||||
|
||||
/*
|
||||
We save the return code (mysql_errno(mysql)) from the last call sent
|
||||
to the server into the mysqltest builtin variable $mysql_errno. This
|
||||
variable then can be used from the test case itself.
|
||||
*/
|
||||
var_set_errno(mysql_errno(mysql));
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -2993,6 +3027,7 @@ end:
|
||||
dynstr_free(&ds_tmp);
|
||||
if (q->type == Q_EVAL)
|
||||
dynstr_free(&eval_query);
|
||||
var_set_errno(mysql_stmt_errno(stmt));
|
||||
mysql_stmt_close(stmt);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@ -3300,7 +3335,7 @@ static VAR* var_from_env(const char *name, const char *def_val)
|
||||
if (!(tmp = getenv(name)))
|
||||
tmp = def_val;
|
||||
|
||||
v = var_init(0, name, 0, tmp, 0);
|
||||
v = var_init(0, name, strlen(name), tmp, strlen(tmp));
|
||||
my_hash_insert(&var_hash, (byte*)v);
|
||||
return v;
|
||||
}
|
||||
@ -3396,6 +3431,13 @@ int main(int argc, char **argv)
|
||||
|
||||
init_var_hash(&cur_con->mysql);
|
||||
|
||||
/*
|
||||
Initialize $mysql_errno with -1, so we can
|
||||
- distinguish it from valid values ( >= 0 ) and
|
||||
- detect if there was never a command sent to the server
|
||||
*/
|
||||
var_set_errno(-1);
|
||||
|
||||
while (!abort_flag && !read_query(&q))
|
||||
{
|
||||
int current_line_inc = 1, processed = 0;
|
||||
@ -3415,6 +3457,8 @@ int main(int argc, char **argv)
|
||||
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
|
||||
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
|
||||
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
|
||||
case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
|
||||
case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break;
|
||||
case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
|
||||
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
||||
case Q_ENABLE_WARNINGS: disable_warnings=0; break;
|
||||
|
30
configure.in
30
configure.in
@ -974,8 +974,11 @@ case $SYSTEM_TYPE-$MACHINE_TYPE-$ac_cv_prog_gcc in
|
||||
CFLAGS="$CFLAGS -DBIG_TABLES"
|
||||
CXXFLAGS="$CXXFLAGS -DBIG_TABLES"
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
case $SYSTEM_TYPE-$ac_cv_prog_gcc in
|
||||
# workaround for Sun Forte compile problem for ndb
|
||||
*solaris2.10*-sparc-no)
|
||||
*solaris*-no)
|
||||
ndb_cxxflags_fix="$ndb_cxxflags_fix -instances=static"
|
||||
;;
|
||||
*) ;;
|
||||
@ -1036,8 +1039,8 @@ case $SYSTEM_TYPE in
|
||||
;;
|
||||
*hpux11.*)
|
||||
echo "Enabling workarounds for hpux 11"
|
||||
CFLAGS="$CFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
CXXFLAGS="$CXXFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
CFLAGS="$CFLAGS -DHPUX11 -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
CXXFLAGS="$CXXFLAGS -DHPUX11 -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
|
||||
if test "$with_named_thread" = "no"
|
||||
then
|
||||
echo "Using --with-named-thread=-lpthread"
|
||||
@ -1143,9 +1146,10 @@ dnl Is this the right match for DEC OSF on alpha?
|
||||
fi
|
||||
echo "Adding defines for OSF1"
|
||||
# gethostbyname_r is deprecated and doesn't work ok on OSF1
|
||||
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
|
||||
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
|
||||
ndb_cxxflags_fix="$ndb_cxxflags_fix -I/usr/include.dtk"
|
||||
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_TRUNC"
|
||||
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R -DSNPRINTF_RETURN_TRUNC"
|
||||
# fix to handle include of <stdint.h> correctly on OSF1 with cxx compiler
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/include/cxx -I/usr/include/cxx_cname -I/usr/include -I/usr/include.dtk"
|
||||
;;
|
||||
*netware*)
|
||||
# No need for curses library so set it to null
|
||||
@ -1916,7 +1920,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
|
||||
getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
|
||||
getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
|
||||
localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \
|
||||
mkstemp mlockall perror poll pread pthread_attr_create clock_gettime \
|
||||
mkstemp mlockall perror poll pread pthread_attr_create \
|
||||
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
|
||||
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
|
||||
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
|
||||
@ -1925,6 +1929,18 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
|
||||
snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \
|
||||
strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr)
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
case "$target" in
|
||||
*-*-aix4*)
|
||||
# (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS)
|
||||
# and using AC_TRY_RUN is hard when cross-compiling
|
||||
;;
|
||||
*) AC_CHECK_FUNCS(clock_gettime)
|
||||
;;
|
||||
esac
|
||||
|
||||
# isinf() could be a function or a macro (HPUX)
|
||||
AC_MSG_CHECKING(for isinf with <math.h>)
|
||||
AC_TRY_LINK([#include <math.h>], [float f = 0.0; isinf(f)],
|
||||
|
@ -33,8 +33,8 @@ extern LIST *list_delete(LIST *root,LIST *element);
|
||||
extern LIST *list_cons(void *data,LIST *root);
|
||||
extern LIST *list_reverse(LIST *root);
|
||||
extern void list_free(LIST *root,unsigned int free_data);
|
||||
extern unsigned int list_length(LIST *list);
|
||||
extern int list_walk(LIST *list,list_walk_action action,gptr argument);
|
||||
extern unsigned int list_length(LIST *);
|
||||
extern int list_walk(LIST *,list_walk_action action,gptr argument);
|
||||
|
||||
#define rest(a) ((a)->next)
|
||||
#define list_push(a,b) (a)=list_cons((b),(a))
|
||||
|
@ -653,23 +653,6 @@ typedef struct st_mysql_methods
|
||||
#endif
|
||||
} MYSQL_METHODS;
|
||||
|
||||
#ifdef HAVE_DEPRECATED_411_API
|
||||
/* Deprecated calls (since MySQL 4.1.2) */
|
||||
|
||||
/* Use mysql_stmt_init + mysql_stmt_prepare instead */
|
||||
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
|
||||
unsigned long length);
|
||||
#define mysql_execute mysql_stmt_execute
|
||||
#define mysql_fetch mysql_stmt_fetch
|
||||
#define mysql_fetch_column mysql_stmt_fetch_column
|
||||
#define mysql_bind_param mysql_stmt_bind_param
|
||||
#define mysql_bind_result mysql_stmt_bind_result
|
||||
#define mysql_param_count mysql_stmt_param_count
|
||||
#define mysql_param_result mysql_stmt_param_metadata
|
||||
#define mysql_get_metadata mysql_stmt_result_metadata
|
||||
#define mysql_send_long_data mysql_stmt_send_long_data
|
||||
|
||||
#endif /* HAVE_DEPRECATED_411_API */
|
||||
|
||||
MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
|
||||
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
|
||||
|
@ -312,13 +312,7 @@ void my_net_local_init(NET *net);
|
||||
void net_end(NET *net);
|
||||
void net_clear(NET *net);
|
||||
my_bool net_realloc(NET *net, unsigned long length);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY /* To be removed by HF */
|
||||
my_bool net_flush(NET *net);
|
||||
#else
|
||||
#define net_flush(A)
|
||||
#endif
|
||||
|
||||
my_bool my_net_write(NET *net,const char *packet,unsigned long len);
|
||||
my_bool net_write_command(NET *net,unsigned char command,
|
||||
const char *header, unsigned long head_len,
|
||||
|
@ -1067,6 +1067,12 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
there are 2 secondary indexes on SYS_FOREIGN, and they
|
||||
are defined just like below */
|
||||
|
||||
/* NOTE: when designing InnoDB's foreign key support in 2001, we made
|
||||
an error and made the table names and the foreign key id of type
|
||||
'CHAR' (internally, really a VARCHAR). We should have made the type
|
||||
VARBINARY, like in other InnoDB system tables, to get a clean
|
||||
design. */
|
||||
|
||||
str =
|
||||
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
|
||||
"BEGIN\n"
|
||||
@ -1284,9 +1290,17 @@ loop:
|
||||
fputs(".\nA foreign key constraint of name ", ef);
|
||||
ut_print_name(ef, trx, foreign->id);
|
||||
fputs("\nalready exists."
|
||||
" (Note that internally InnoDB adds 'databasename/'\n"
|
||||
" (Note that internally InnoDB adds 'databasename/'\n"
|
||||
"in front of the user-defined constraint name).\n",
|
||||
ef);
|
||||
fputs("Note that InnoDB's FOREIGN KEY system tables store\n"
|
||||
"constraint names as case-insensitive, with the\n"
|
||||
"MySQL standard latin1_swedish_ci collation. If you\n"
|
||||
"create tables or databases whose names differ only in\n"
|
||||
"the character case, then collisions in constraint\n"
|
||||
"names can occur. Workaround: name your constraints\n"
|
||||
"explicitly with unique names.\n",
|
||||
ef);
|
||||
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -156,7 +156,7 @@ dict_index_build_internal_non_clust(
|
||||
dict_index_t* index); /* in: user representation of a non-clustered
|
||||
index */
|
||||
/**************************************************************************
|
||||
Removes a foreign constraint struct from the dictionet cache. */
|
||||
Removes a foreign constraint struct from the dictionary cache. */
|
||||
static
|
||||
void
|
||||
dict_foreign_remove_from_cache(
|
||||
@ -606,7 +606,7 @@ dict_table_get_on_id(
|
||||
dict_table_t* table;
|
||||
|
||||
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
|
||||
|| trx->dict_operation) {
|
||||
|| trx->dict_operation_lock_mode == RW_X_LATCH) {
|
||||
/* It is a system table which will always exist in the table
|
||||
cache: we avoid acquiring the dictionary mutex, because
|
||||
if we are doing a rollback to handle an error in TABLE
|
||||
|
@ -19,7 +19,9 @@ Created 4/24/1996 Heikki Tuuri
|
||||
#include "mach0data.h"
|
||||
#include "dict0dict.h"
|
||||
#include "dict0boot.h"
|
||||
#include "rem0cmp.h"
|
||||
#include "srv0start.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/************************************************************************
|
||||
Finds the first table name in the given database. */
|
||||
@ -123,6 +125,13 @@ dict_print(void)
|
||||
ulint len;
|
||||
mtr_t mtr;
|
||||
|
||||
/* Enlarge the fatal semaphore wait timeout during the InnoDB table
|
||||
monitor printout */
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
mtr_start(&mtr);
|
||||
@ -145,6 +154,12 @@ loop:
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
/* Restore the fatal semaphore wait timeout */
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1242,12 +1257,26 @@ loop:
|
||||
rec = btr_pcur_get_rec(&pcur);
|
||||
field = rec_get_nth_field(rec, 0, &len);
|
||||
|
||||
/* Check if the table name in record is the one searched for */
|
||||
if (len != ut_strlen(table_name)
|
||||
|| 0 != ut_memcmp(field, table_name, len)) {
|
||||
/* Check if the table name in the record is the one searched for; the
|
||||
following call does the comparison in the latin1_swedish_ci
|
||||
charset-collation, in a case-insensitive way. */
|
||||
|
||||
if (0 != cmp_data_data(dfield_get_type(dfield),
|
||||
dfield_get_data(dfield), dfield_get_len(dfield),
|
||||
field, len)) {
|
||||
|
||||
goto load_next_index;
|
||||
}
|
||||
|
||||
/* Since table names in SYS_FOREIGN are stored in a case-insensitive
|
||||
order, we have to check that the table name matches also in a binary
|
||||
string comparison. On Unix, MySQL allows table names that only differ
|
||||
in character case. */
|
||||
|
||||
if (0 != ut_memcmp(field, table_name, len)) {
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
if (rec_get_deleted_flag(rec)) {
|
||||
|
||||
|
@ -627,7 +627,11 @@ eval_concat(
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Evaluates a predefined function node. */
|
||||
Evaluates a predefined function node. If the first argument is an integer,
|
||||
this function looks at the second argument which is the integer length in
|
||||
bytes, and converts the integer to a VARCHAR.
|
||||
If the first argument is of some other type, this function converts it to
|
||||
BINARY. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
eval_to_binary(
|
||||
@ -638,12 +642,24 @@ eval_to_binary(
|
||||
que_node_t* arg2;
|
||||
dfield_t* dfield;
|
||||
byte* str1;
|
||||
ulint len;
|
||||
ulint len1;
|
||||
|
||||
arg1 = func_node->args;
|
||||
|
||||
str1 = dfield_get_data(que_node_get_val(arg1));
|
||||
|
||||
if (dtype_get_mtype(que_node_get_data_type(arg1)) != DATA_INT) {
|
||||
|
||||
len = dfield_get_len(que_node_get_val(arg1));
|
||||
|
||||
dfield = que_node_get_val(func_node);
|
||||
|
||||
dfield_set_data(dfield, str1, len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
arg2 = que_node_get_next(arg1);
|
||||
|
||||
len1 = (ulint)eval_node_get_int_val(arg2);
|
||||
|
@ -2866,6 +2866,8 @@ ibuf_delete_rec(
|
||||
|
||||
#ifdef UNIV_IBUF_DEBUG
|
||||
ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
|
||||
#else
|
||||
UT_NOT_USED(space);
|
||||
#endif
|
||||
ibuf_data_sizes_update(ibuf_data, root, mtr);
|
||||
|
||||
@ -3267,11 +3269,11 @@ leave_loop:
|
||||
ibuf_data->n_merged_recs += n_inserts;
|
||||
|
||||
mutex_exit(&ibuf_mutex);
|
||||
|
||||
/*
|
||||
fprintf(stderr,
|
||||
"InnoDB: Discarded %lu ibuf entries for space %lu\n",
|
||||
(ulong) n_inserts, (ulong) space);
|
||||
|
||||
*/
|
||||
ibuf_exit();
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
@ -259,9 +259,13 @@ pars_resolve_func_data_type(
|
||||
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
|
||||
DATA_ENGLISH, 0, 0);
|
||||
} else if (func == PARS_TO_BINARY_TOKEN) {
|
||||
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
|
||||
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
|
||||
if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
|
||||
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
|
||||
DATA_ENGLISH, 0, 0);
|
||||
} else {
|
||||
dtype_set(que_node_get_data_type(node), DATA_BINARY,
|
||||
0, 0, 0);
|
||||
}
|
||||
} else if (func == PARS_TO_NUMBER_TOKEN) {
|
||||
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
|
||||
== DATA_VARCHAR);
|
||||
|
@ -2314,7 +2314,8 @@ row_drop_table_for_mysql(
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = table_name;\n"
|
||||
" WHERE FOR_NAME = table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE"
|
||||
@ -2769,7 +2770,8 @@ row_rename_table_for_mysql(
|
||||
"WHILE found = 1 LOOP\n"
|
||||
" SELECT ID INTO foreign_id\n"
|
||||
" FROM SYS_FOREIGN\n"
|
||||
" WHERE FOR_NAME = old_table_name;\n"
|
||||
" WHERE FOR_NAME = old_table_name\n"
|
||||
" AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);\n"
|
||||
" IF (SQL % NOTFOUND) THEN\n"
|
||||
" found := 0;\n"
|
||||
" ELSE\n"
|
||||
@ -2802,7 +2804,8 @@ row_rename_table_for_mysql(
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"UPDATE SYS_FOREIGN SET REF_NAME = new_table_name\n"
|
||||
"WHERE REF_NAME = old_table_name;\n";
|
||||
"WHERE REF_NAME = old_table_name\n"
|
||||
" AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);\n";
|
||||
static const char str5[] =
|
||||
"END;\n";
|
||||
|
||||
@ -3012,7 +3015,11 @@ row_rename_table_for_mysql(
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DUPLICATE_KEY) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
fputs(
|
||||
" InnoDB: Error; possible reasons:\n"
|
||||
"InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
|
||||
"InnoDB: to have the same internal name in case-insensitive comparison.\n"
|
||||
"InnoDB: 2) table ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
fputs(" exists in the InnoDB internal data\n"
|
||||
"InnoDB: dictionary though MySQL is trying rename table ", stderr);
|
||||
|
@ -1887,22 +1887,6 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEPRECATED_411_API
|
||||
MYSQL_STMT * STDCALL mysql_prepare(MYSQL *mysql, const char *query,
|
||||
unsigned long query_length)
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
DBUG_ENTER("mysql_prepare");
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
if (stmt && mysql_stmt_prepare(stmt, query, query_length))
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
DBUG_RETURN(stmt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Allocate memory and init prepared statement structure.
|
||||
|
@ -2037,7 +2037,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
||||
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
|
||||
sort_param.keyinfo->seg->charset->mbmaxlen;
|
||||
sort_info.max_records=
|
||||
(ha_rows) (sort_info.filelength/ft_max_word_len_for_sort+1);
|
||||
(ha_rows) (sort_info.filelength/ft_min_word_len+1);
|
||||
|
||||
sort_param.key_read=sort_ft_key_read;
|
||||
sort_param.key_write=sort_ft_key_write;
|
||||
|
@ -354,8 +354,12 @@ static void usage(void)
|
||||
puts("Description, check and repair of MyISAM tables.");
|
||||
puts("Used without options all tables on the command will be checked for errors");
|
||||
printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname_short);
|
||||
printf("\nGlobal options:\n\
|
||||
-#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n\
|
||||
printf("\nGlobal options:\n");
|
||||
#ifndef DBUG_OFF
|
||||
printf("\
|
||||
-#, --debug=... Output debug log. Often this is 'd:t:o,filename'.\n");
|
||||
#endif
|
||||
printf("\
|
||||
-?, --help Display this help and exit.\n\
|
||||
-O, --set-variable var=option.\n\
|
||||
Change the value of a variable. Please note that\n\
|
||||
|
@ -321,8 +321,11 @@ select a,b from t1 where a >= 1000 order by a ;
|
||||
delete from t1 where a >= 1000 ;
|
||||
|
||||
## replace
|
||||
--error 1295
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
|
||||
|
||||
|
||||
## multi table statements
|
||||
|
@ -996,9 +996,11 @@ start_master()
|
||||
if [ -n "$1" ] ; then
|
||||
id=`$EXPR $1 + 101`;
|
||||
this_master_myport=`$EXPR $MASTER_MYPORT + $1`
|
||||
NOT_FIRST_MASTER_EXTRA_OPTS="--skip-innodb"
|
||||
else
|
||||
id=1;
|
||||
this_master_myport=$MASTER_MYPORT
|
||||
NOT_FIRST_MASTER_EXTRA_OPTS=""
|
||||
fi
|
||||
if [ -z "$DO_BENCH" ]
|
||||
then
|
||||
@ -1022,7 +1024,8 @@ start_master()
|
||||
--open-files-limit=1024 \
|
||||
$MASTER_40_ARGS \
|
||||
$SMALL_SERVER \
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
|
||||
$NOT_FIRST_MASTER_EXTRA_OPTS"
|
||||
else
|
||||
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \
|
||||
--server-id=$id --rpl-recovery-rank=1 \
|
||||
@ -1041,7 +1044,8 @@ start_master()
|
||||
--innodb_data_file_path=ibdata1:50M \
|
||||
$MASTER_40_ARGS \
|
||||
$SMALL_SERVER \
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
|
||||
$NOT_FIRST_MASTER_EXTRA_OPTS"
|
||||
fi
|
||||
|
||||
CUR_MYERR=$MASTER_MYERR
|
||||
|
@ -146,7 +146,7 @@ fi
|
||||
rm -f "$cfgfile" 2>&1 | cat > /dev/null
|
||||
rm -f "$fs_ndb/$cfgfile" 2>&1 | cat > /dev/null
|
||||
|
||||
if ( cd "$fs_ndb" ; $exec_mgmtsrvr -c config.ini ) ; then :; else
|
||||
if ( cd "$fs_ndb" ; $exec_mgmtsrvr -f config.ini ) ; then :; else
|
||||
echo "Unable to start $exec_mgmtsrvr from `pwd`"
|
||||
exit 1
|
||||
fi
|
||||
@ -212,8 +212,8 @@ if [ -f "$fs_ndb/$pidfile" ] ; then
|
||||
attempt=`expr $attempt + 1`
|
||||
done
|
||||
if [ "$kill_pids" != "" ] ; then
|
||||
echo "Failed to shutdown ndbcluster, executing kill -9 "$kill_pids
|
||||
kill -9 $kill_pids
|
||||
echo "Failed to shutdown ndbcluster, executing kill "$kill_pids
|
||||
kill $kill_pids
|
||||
fi
|
||||
rm "$fs_ndb/$pidfile"
|
||||
fi
|
||||
|
@ -174,3 +174,69 @@ Warnings:
|
||||
Warning 1265 Data truncated for column 'a' at row 1
|
||||
Warning 1265 Data truncated for column 'b' at row 1
|
||||
drop table t1;
|
||||
set names koi8r;
|
||||
create table t1 (a char(10) character set cp1251);
|
||||
insert into t1 values (_koi8r'×ÁÓÑ');
|
||||
select * from t1 where a=_koi8r'×ÁÓÑ';
|
||||
a
|
||||
×ÁÓÑ
|
||||
select * from t1 where a=concat(_koi8r'×ÁÓÑ');
|
||||
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '='
|
||||
select * from t1 where a=_latin1'×ÁÓÑ';
|
||||
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
|
||||
drop table t1;
|
||||
set names latin1;
|
||||
set names koi8r;
|
||||
create table t1 (c1 char(10) character set cp1251);
|
||||
insert into t1 values ('ß');
|
||||
select c1 from t1 where c1 between 'ß' and 'ß';
|
||||
c1
|
||||
ß
|
||||
select ifnull(c1,'ß'), ifnull(null,c1) from t1;
|
||||
ifnull(c1,'ß') ifnull(null,c1)
|
||||
ß ß
|
||||
select if(1,c1,'ö'), if(0,c1,'ö') from t1;
|
||||
if(1,c1,'ö') if(0,c1,'ö')
|
||||
ß ö
|
||||
select coalesce('ö',c1), coalesce(null,c1) from t1;
|
||||
coalesce('ö',c1) coalesce(null,c1)
|
||||
ö ß
|
||||
select least(c1,'ö'), greatest(c1,'ö') from t1;
|
||||
least(c1,'ö') greatest(c1,'ö')
|
||||
ö ß
|
||||
select locate(c1,'ß'), locate('ß',c1) from t1;
|
||||
locate(c1,'ß') locate('ß',c1)
|
||||
1 1
|
||||
select field(c1,'ß'),field('ß',c1) from t1;
|
||||
field(c1,'ß') field('ß',c1)
|
||||
1 1
|
||||
select concat(c1,'ö'), concat('ö',c1) from t1;
|
||||
concat(c1,'ö') concat('ö',c1)
|
||||
ßö öß
|
||||
select concat_ws(c1,'ö','ß'), concat_ws('ö',c1,'ß') from t1;
|
||||
concat_ws(c1,'ö','ß') concat_ws('ö',c1,'ß')
|
||||
ößß ßöß
|
||||
select replace(c1,'ß','ö'), replace('ß',c1,'ö') from t1;
|
||||
replace(c1,'ß','ö') replace('ß',c1,'ö')
|
||||
ö ö
|
||||
select substring_index(c1,'öößß',2) from t1;
|
||||
substring_index(c1,'öößß',2)
|
||||
ß
|
||||
select elt(1,c1,'ö'),elt(1,'ö',c1) from t1;
|
||||
elt(1,c1,'ö') elt(1,'ö',c1)
|
||||
ß ö
|
||||
select make_set(3,c1,'ö'), make_set(3,'ö',c1) from t1;
|
||||
make_set(3,c1,'ö') make_set(3,'ö',c1)
|
||||
ß,ö ö,ß
|
||||
select insert(c1,1,2,'ö'),insert('ö',1,2,c1) from t1;
|
||||
insert(c1,1,2,'ö') insert('ö',1,2,c1)
|
||||
ö ß
|
||||
select trim(c1 from 'ß'),trim('ß' from c1) from t1;
|
||||
trim(c1 from 'ß') trim('ß' from c1)
|
||||
|
||||
select lpad(c1,3,'ö'), lpad('ö',3,c1) from t1;
|
||||
lpad(c1,3,'ö') lpad('ö',3,c1)
|
||||
ööß ßßö
|
||||
select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
|
||||
rpad(c1,3,'ö') rpad('ö',3,c1)
|
||||
ßöö ößß
|
||||
|
@ -60,3 +60,14 @@ hex(c)
|
||||
9353
|
||||
9373
|
||||
drop table t1;
|
||||
SET NAMES sjis;
|
||||
CREATE TABLE t1 (
|
||||
c char(16) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=sjis;
|
||||
insert into t1 values(0xb1),(0xb2),(0xb3);
|
||||
select hex(c) from t1;
|
||||
hex(c)
|
||||
B1
|
||||
B2
|
||||
B3
|
||||
drop table t1;
|
||||
|
@ -330,6 +330,9 @@ t1_id name t2_id t1_id name
|
||||
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
|
||||
t2_id t1_id name
|
||||
drop table t1,t2;
|
||||
create table t1 (a text, fulltext key (a));
|
||||
insert into t1 select "xxxx yyyy zzzz";
|
||||
drop table t1;
|
||||
SET NAMES latin1;
|
||||
CREATE TABLE t1 (t text character set utf8 not null, fulltext(t));
|
||||
INSERT t1 VALUES ('Mit freundlichem Grüß'), ('aus Osnabrück');
|
||||
|
@ -581,3 +581,77 @@ t1 CREATE TABLE `t1` (
|
||||
`POINT(1,3)` longblob NOT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE `t1` (`object_id` bigint(20) unsigned NOT NULL default '0', `geo`
|
||||
geometry NOT NULL default '') ENGINE=MyISAM ;
|
||||
insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
|
||||
36.305435,-114.992394 36.305202,-114.991219 36.305975,-114.991163
|
||||
36.306845,-114.989432 36.309452,-114.978275 36.312642,-114.977363
|
||||
36.311978,-114.975327 36.312344,-114.96502 36.31597,-114.963364
|
||||
36.313629,-114.961723 36.313721,-114.956398 36.316057,-114.951882
|
||||
36.320979,-114.947073 36.323475,-114.945207 36.326451,-114.945207
|
||||
36.326451,-114.944132 36.326061,-114.94003 36.326588,-114.924017
|
||||
36.334484,-114.923281 36.334146,-114.92564 36.331504,-114.94072
|
||||
36.319282,-114.945348 36.314812,-114.948091 36.314762,-114.951755
|
||||
36.316211,-114.952446 36.313883,-114.952644 36.309488,-114.944725
|
||||
36.313083,-114.93706 36.32043,-114.932478 36.323497,-114.924556
|
||||
36.327708,-114.922608 36.329715,-114.92009 36.328695,-114.912105
|
||||
36.323566,-114.901647 36.317952,-114.897436 36.313968,-114.895344
|
||||
36.309573,-114.891699 36.304398,-114.890569 36.303551,-114.886356
|
||||
36.302702,-114.885141 36.301351,-114.885709 36.297391,-114.892499
|
||||
36.290893,-114.902142 36.288974,-114.904941 36.288838,-114.905308
|
||||
36.289845,-114.906325 36.290395,-114.909916 36.289549,-114.914527
|
||||
36.287535,-114.918797 36.284423,-114.922982 36.279731,-114.924113
|
||||
36.277282,-114.924057 36.275817,-114.927733 36.27053,-114.929354
|
||||
36.269029,-114.929354 36.269029,-114.950856 36.268715,-114.950768
|
||||
36.264324,-114.960206 36.264293,-114.960301 36.268943,-115.006662
|
||||
36.268929,-115.008583 36.265619,-115.00665 36.264247,-115.006659
|
||||
36.246873,-115.006659 36.246873,-115.006838 36.247697,-115.010764
|
||||
36.247774,-115.015609 36.25113,-115.015765 36.254505,-115.029517
|
||||
36.254619,-115.038573 36.249317,-115.038573 36.249317,-115.023403
|
||||
36.25841,-115.023873 36.258994,-115.031845 36.259829,-115.03183
|
||||
36.261053,-115.025561 36.261095,-115.036417 36.274632,-115.033729
|
||||
36.276041,-115.032217 36.274851,-115.029845 36.273959,-115.029934
|
||||
36.274966,-115.025763 36.274896,-115.025406 36.281044,-115.028731
|
||||
36.284471,-115.036497 36.290377,-115.042071 36.291039,-115.026759
|
||||
36.298478,-115.008995 36.301966,-115.006363 36.305435),(-115.079835
|
||||
36.244369,-115.079735 36.260186,-115.076435 36.262369,-115.069758
|
||||
36.265,-115.070235 36.268757,-115.064542 36.268655,-115.061843
|
||||
36.269857,-115.062676 36.270693,-115.06305 36.272344,-115.059051
|
||||
36.281023,-115.05918 36.283008,-115.060591 36.285246,-115.061913
|
||||
36.290022,-115.062499 36.306353,-115.062499 36.306353,-115.060918
|
||||
36.30642,-115.06112 36.289779,-115.05713 36.2825,-115.057314
|
||||
36.279446,-115.060779 36.274659,-115.061366 36.27209,-115.057858
|
||||
36.26557,-115.055805 36.262883,-115.054688 36.262874,-115.047335
|
||||
36.25037,-115.044234 36.24637,-115.052434 36.24047,-115.061734
|
||||
36.23507,-115.061934 36.22677,-115.061934 36.22677,-115.061491
|
||||
36.225267,-115.062024 36.218194,-115.060134 36.218278,-115.060133
|
||||
36.210771,-115.057833 36.210771,-115.057433 36.196271,-115.062233
|
||||
36.196271,-115.062233 36.190371,-115.062233 36.190371,-115.065533
|
||||
36.190371,-115.071333 36.188571,-115.098331 36.188275,-115.098331
|
||||
36.188275,-115.098435 36.237569,-115.097535 36.240369,-115.097535
|
||||
36.240369,-115.093235 36.240369,-115.089135 36.240469,-115.083135
|
||||
36.240569,-115.083135 36.240569,-115.079835
|
||||
36.244369)))')),('85998',GeomFromText('MULTIPOLYGON(((-115.333107
|
||||
36.264587,-115.333168 36.280638,-115.333168 36.280638,-115.32226
|
||||
36.280643,-115.322538 36.274311,-115.327222 36.274258,-115.32733
|
||||
36.263026,-115.330675 36.262984,-115.332132 36.264673,-115.333107
|
||||
36.264587),(-115.247239 36.247066,-115.247438 36.218267,-115.247438
|
||||
36.218267,-115.278525 36.219263,-115.278525 36.219263,-115.301545
|
||||
36.219559,-115.332748 36.219197,-115.332757 36.220041,-115.332757
|
||||
36.220041,-115.332895 36.233514,-115.349023 36.233479,-115.351489
|
||||
36.234475,-115.353681 36.237021,-115.357106 36.239789,-115.36519
|
||||
36.243331,-115.368156 36.243487,-115.367389 36.244902,-115.364553
|
||||
36.246014,-115.359219 36.24616,-115.356186 36.248025,-115.353347
|
||||
36.248004,-115.350813 36.249507,-115.339673 36.25387,-115.333069
|
||||
36.255018,-115.333069 36.255018,-115.333042 36.247767,-115.279039
|
||||
36.248666,-115.263639 36.247466,-115.263839 36.252766,-115.261439
|
||||
36.252666,-115.261439 36.247366,-115.247239 36.247066)))'));
|
||||
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
|
||||
t1 where object_id=85998;
|
||||
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
|
||||
85998 MULTIPOLYGON 0 POINT(115.31877315203 -36.237472821022)
|
||||
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
|
||||
t1 where object_id=85984;
|
||||
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
|
||||
85984 MULTIPOLYGON 0 POINT(-114.87787186923 36.33101763469)
|
||||
drop table t1;
|
||||
|
@ -1,9 +1,17 @@
|
||||
select -1 as "before_use_test" ;
|
||||
before_use_test
|
||||
-1
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
select friedrich from (select 1 as otto) as t1;
|
||||
ERROR 42S22: Unknown column 'friedrich' in 'field list'
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
@ -14,10 +22,123 @@ ERROR 42S22: Unknown column 'friedrich' in 'field list'
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
select friedrich from (select 1 as otto) as t1;
|
||||
ERROR 42S22: Unknown column 'friedrich' in 'field list'
|
||||
select friedrich from (select 1 as otto) as t1;
|
||||
ERROR 42S22: Unknown column 'friedrich' in 'field list'
|
||||
select 0 as "after_successful_stmt_errno" ;
|
||||
after_successful_stmt_errno
|
||||
0
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 1064 as "after_wrong_syntax_errno" ;
|
||||
after_wrong_syntax_errno
|
||||
1064
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 1064 as "after_let_var_equal_value" ;
|
||||
after_let_var_equal_value
|
||||
1064
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
set @my_var= 'abc' ;
|
||||
select 0 as "after_set_var_equal_value" ;
|
||||
after_set_var_equal_value
|
||||
0
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 1064 as "after_disable_warnings_command" ;
|
||||
after_disable_warnings_command
|
||||
1064
|
||||
drop table if exists t1 ;
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
drop table if exists t1 ;
|
||||
select 0 as "after_disable_warnings" ;
|
||||
after_disable_warnings
|
||||
0
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 1146 as "after_minus_masked" ;
|
||||
after_minus_masked
|
||||
1146
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 1146 as "after_!_masked" ;
|
||||
after_!_masked
|
||||
1146
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select -1 as "after_let_errno_equal_value" ;
|
||||
after_let_errno_equal_value
|
||||
-1
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
prepare stmt from "select 3 from t1" ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 1146 as "after_failing_prepare" ;
|
||||
after_failing_prepare
|
||||
1146
|
||||
create table t1 ( f1 char(10));
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
prepare stmt from "select 3 from t1" ;
|
||||
select 0 as "after_successful_prepare" ;
|
||||
after_successful_prepare
|
||||
0
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
execute stmt;
|
||||
3
|
||||
select 0 as "after_successful_execute" ;
|
||||
after_successful_execute
|
||||
0
|
||||
drop table t1;
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
execute stmt;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 1146 as "after_failing_execute" ;
|
||||
after_failing_execute
|
||||
1146
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
execute __stmt_;
|
||||
ERROR HY000: Unknown prepared statement handler (__stmt_) given to EXECUTE
|
||||
select 1243 as "after_failing_execute" ;
|
||||
after_failing_execute
|
||||
1243
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
deallocate prepare stmt;
|
||||
select 0 as "after_successful_deallocate" ;
|
||||
after_successful_deallocate
|
||||
0
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
deallocate prepare __stmt_;
|
||||
ERROR HY000: Unknown prepared statement handler (__stmt_) given to DEALLOCATE PREPARE
|
||||
select 1243 as "after_failing_deallocate" ;
|
||||
after_failing_deallocate
|
||||
1243
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 1064 as "after_--disable_abort_on_error" ;
|
||||
after_--disable_abort_on_error
|
||||
1064
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select 1146 as "after_!errno_masked_error" ;
|
||||
after_!errno_masked_error
|
||||
1146
|
||||
garbage ;
|
||||
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 'garbage' at line 1
|
||||
select 1064 as "after_--enable_abort_on_error" ;
|
||||
after_--enable_abort_on_error
|
||||
1064
|
||||
select 3 from t1 ;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
|
@ -414,3 +414,150 @@ select * from t1 where b IS NOT NULL;
|
||||
a b
|
||||
1
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
c1 int,
|
||||
c2 int,
|
||||
c3 int,
|
||||
c4 int,
|
||||
c5 int,
|
||||
c6 int,
|
||||
c7 int,
|
||||
c8 int,
|
||||
c9 int,
|
||||
c10 int,
|
||||
c11 int,
|
||||
c12 int,
|
||||
c13 int,
|
||||
c14 int,
|
||||
c15 int,
|
||||
c16 int,
|
||||
c17 int,
|
||||
c18 int,
|
||||
c19 int,
|
||||
c20 int,
|
||||
c21 int,
|
||||
c22 int,
|
||||
c23 int,
|
||||
c24 int,
|
||||
c25 int,
|
||||
c26 int,
|
||||
c27 int,
|
||||
c28 int,
|
||||
c29 int,
|
||||
c30 int,
|
||||
c31 int,
|
||||
c32 int,
|
||||
c33 int,
|
||||
c34 int,
|
||||
c35 int,
|
||||
c36 int,
|
||||
c37 int,
|
||||
c38 int,
|
||||
c39 int,
|
||||
c40 int,
|
||||
c41 int,
|
||||
c42 int,
|
||||
c43 int,
|
||||
c44 int,
|
||||
c45 int,
|
||||
c46 int,
|
||||
c47 int,
|
||||
c48 int,
|
||||
c49 int,
|
||||
c50 int,
|
||||
c51 int,
|
||||
c52 int,
|
||||
c53 int,
|
||||
c54 int,
|
||||
c55 int,
|
||||
c56 int,
|
||||
c57 int,
|
||||
c58 int,
|
||||
c59 int,
|
||||
c60 int,
|
||||
c61 int,
|
||||
c62 int,
|
||||
c63 int,
|
||||
c64 int,
|
||||
c65 int,
|
||||
c66 int,
|
||||
c67 int,
|
||||
c68 int,
|
||||
c69 int,
|
||||
c70 int,
|
||||
c71 int,
|
||||
c72 int,
|
||||
c73 int,
|
||||
c74 int,
|
||||
c75 int,
|
||||
c76 int,
|
||||
c77 int,
|
||||
c78 int,
|
||||
c79 int,
|
||||
c80 int,
|
||||
c81 int,
|
||||
c82 int,
|
||||
c83 int,
|
||||
c84 int,
|
||||
c85 int,
|
||||
c86 int,
|
||||
c87 int,
|
||||
c88 int,
|
||||
c89 int,
|
||||
c90 int,
|
||||
c91 int,
|
||||
c92 int,
|
||||
c93 int,
|
||||
c94 int,
|
||||
c95 int,
|
||||
c96 int,
|
||||
c97 int,
|
||||
c98 int,
|
||||
c99 int,
|
||||
c100 int,
|
||||
c101 int,
|
||||
c102 int,
|
||||
c103 int,
|
||||
c104 int,
|
||||
c105 int,
|
||||
c106 int,
|
||||
c107 int,
|
||||
c108 int,
|
||||
c109 int,
|
||||
c110 int,
|
||||
c111 int,
|
||||
c112 int,
|
||||
c113 int,
|
||||
c114 int,
|
||||
c115 int,
|
||||
c116 int,
|
||||
c117 int,
|
||||
c118 int,
|
||||
c119 int,
|
||||
c120 int,
|
||||
c121 int,
|
||||
c122 int,
|
||||
c123 int,
|
||||
c124 int,
|
||||
c125 int,
|
||||
c126 int,
|
||||
c127 int,
|
||||
c128 int,
|
||||
primary key(c1)) engine=ndb;
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a1234567890123456789012345678901234567890 int primary key,
|
||||
a12345678901234567890123456789a1234567890 int,
|
||||
index(a12345678901234567890123456789a1234567890)
|
||||
) engine=ndb;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1
|
||||
insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2),(6,1),(7,1);
|
||||
explain select * from t1 where a12345678901234567890123456789a1234567890=2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a12345678901234567890123456789a1234567890 a12345678901234567890123456789a1234567890 5 const 10 Using where
|
||||
select * from t1 where a12345678901234567890123456789a1234567890=2;
|
||||
a1234567890123456789012345678901234567890 a12345678901234567890123456789a1234567890
|
||||
5 2
|
||||
drop table t1;
|
||||
|
@ -1,25 +1,5 @@
|
||||
drop table if exists t1;
|
||||
drop database if exists mysqltest;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b tinytext
|
||||
) engine=ndbcluster;
|
||||
insert into t1 values(1, 'x');
|
||||
update t1 set b = 'y';
|
||||
select * from t1;
|
||||
a b
|
||||
1 y
|
||||
delete from t1;
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) engine=ndbcluster;
|
||||
insert into t1 values(1, '');
|
||||
select * from t1;
|
||||
a b
|
||||
1
|
||||
drop table t1;
|
||||
drop database if exists test2;
|
||||
set autocommit=0;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
@ -102,6 +82,53 @@ commit;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
replace t1 set a=1,b=@b1,c=111,d=@d1;
|
||||
replace t1 set a=2,b=@b2,c=222,d=@d2;
|
||||
commit;
|
||||
explain select * from t1 where a = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
|
||||
from t1 where a=1;
|
||||
a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
|
||||
1 2256 b1 3000 dd1
|
||||
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
|
||||
from t1 where a=2;
|
||||
a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
|
||||
2 20000 b2 30000 dd2
|
||||
replace t1 set a=1,b=@b2,c=111,d=@d2;
|
||||
replace t1 set a=2,b=@b1,c=222,d=@d1;
|
||||
commit;
|
||||
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
|
||||
from t1 where a=1;
|
||||
a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
|
||||
1 20000 b2 30000 dd2
|
||||
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
|
||||
from t1 where a=2;
|
||||
a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
|
||||
2 2256 b1 3000 dd1
|
||||
replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
|
||||
replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
|
||||
commit;
|
||||
select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
|
||||
from t1 where a=1;
|
||||
a length(b) substr(b,1+4*9000,2) length(d) substr(d,1+6*9000,3)
|
||||
1 40000 b2 60000 dd2
|
||||
select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
|
||||
from t1 where a=2;
|
||||
a length(b) substr(b,1+4*900,2) length(d) substr(d,1+6*900,3)
|
||||
2 4512 b1 6000 dd1
|
||||
replace t1 set a=1,b='xyz',c=111,d=null;
|
||||
commit;
|
||||
select a,b from t1 where d is null;
|
||||
a b
|
||||
1 xyz
|
||||
delete from t1 where a=1;
|
||||
delete from t1 where a=2;
|
||||
commit;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
insert into t1 values(1,@b1,111,@d1);
|
||||
insert into t1 values(2,@b2,222,@d2);
|
||||
commit;
|
||||
@ -241,90 +268,6 @@ a b c d
|
||||
7 7xb7 777 7xdd7
|
||||
8 8xb8 888 8xdd8
|
||||
9 9xb9 999 9xdd9
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 1xb1 111 1xdd1
|
||||
2 2xb2 222 2xdd2
|
||||
3 3xb3 333 3xdd3
|
||||
4 4xb4 444 4xdd4
|
||||
5 5xb5 555 5xdd5
|
||||
6 6xb6 666 6xdd6
|
||||
7 7xb7 777 7xdd7
|
||||
8 8xb8 888 8xdd8
|
||||
9 9xb9 999 9xdd9
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
a b c d x
|
||||
1 1xb1 111 1xdd1 NULL
|
||||
2 2xb2 222 2xdd2 NULL
|
||||
3 3xb3 333 3xdd3 NULL
|
||||
4 4xb4 444 4xdd4 NULL
|
||||
5 5xb5 555 5xdd5 NULL
|
||||
6 6xb6 666 6xdd6 NULL
|
||||
7 7xb7 777 7xdd7 NULL
|
||||
8 8xb8 888 8xdd8 NULL
|
||||
9 9xb9 999 9xdd9 NULL
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 1xb1 111 1xdd1
|
||||
2 2xb2 222 2xdd2
|
||||
3 3xb3 333 3xdd3
|
||||
4 4xb4 444 4xdd4
|
||||
5 5xb5 555 5xdd5
|
||||
6 6xb6 666 6xdd6
|
||||
7 7xb7 777 7xdd7
|
||||
8 8xb8 888 8xdd8
|
||||
9 9xb9 999 9xdd9
|
||||
create database mysqltest;
|
||||
use mysqltest;
|
||||
CREATE TABLE t2 (
|
||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||
b int unsigned not null,
|
||||
c int unsigned
|
||||
) engine=ndbcluster;
|
||||
insert into t2 values (1,1,1),(2,2,2);
|
||||
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||
a b c d a b c
|
||||
1 1xb1 111 1xdd1 1 1 1
|
||||
2 2xb2 222 2xdd2 2 2 2
|
||||
drop table t2;
|
||||
use test;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 1xb1 111 1xdd1
|
||||
2 2xb2 222 2xdd2
|
||||
3 3xb3 333 3xdd3
|
||||
4 4xb4 444 4xdd4
|
||||
5 5xb5 555 5xdd5
|
||||
6 6xb6 666 6xdd6
|
||||
7 7xb7 777 7xdd7
|
||||
8 8xb8 888 8xdd8
|
||||
9 9xb9 999 9xdd9
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
a b c d x
|
||||
1 1xb1 111 1xdd1 NULL
|
||||
2 2xb2 222 2xdd2 NULL
|
||||
3 3xb3 333 3xdd3 NULL
|
||||
4 4xb4 444 4xdd4 NULL
|
||||
5 5xb5 555 5xdd5 NULL
|
||||
6 6xb6 666 6xdd6 NULL
|
||||
7 7xb7 777 7xdd7 NULL
|
||||
8 8xb8 888 8xdd8 NULL
|
||||
9 9xb9 999 9xdd9 NULL
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 1xb1 111 1xdd1
|
||||
2 2xb2 222 2xdd2
|
||||
3 3xb3 333 3xdd3
|
||||
4 4xb4 444 4xdd4
|
||||
5 5xb5 555 5xdd5
|
||||
6 6xb6 666 6xdd6
|
||||
7 7xb7 777 7xdd7
|
||||
8 8xb8 888 8xdd8
|
||||
9 9xb9 999 9xdd9
|
||||
delete from t1 where c >= 100;
|
||||
commit;
|
||||
select count(*) from t1;
|
||||
@ -375,8 +318,128 @@ rollback;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
insert into t1 values(1,'b1',111,'dd1');
|
||||
insert into t1 values(2,'b2',222,'dd2');
|
||||
insert into t1 values(3,'b3',333,'dd3');
|
||||
insert into t1 values(4,'b4',444,'dd4');
|
||||
insert into t1 values(5,'b5',555,'dd5');
|
||||
insert into t1 values(6,'b6',666,'dd6');
|
||||
insert into t1 values(7,'b7',777,'dd7');
|
||||
insert into t1 values(8,'b8',888,'dd8');
|
||||
insert into t1 values(9,'b9',999,'dd9');
|
||||
commit;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 b1 111 dd1
|
||||
2 b2 222 dd2
|
||||
3 b3 333 dd3
|
||||
4 b4 444 dd4
|
||||
5 b5 555 dd5
|
||||
6 b6 666 dd6
|
||||
7 b7 777 dd7
|
||||
8 b8 888 dd8
|
||||
9 b9 999 dd9
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
a b c d x
|
||||
1 b1 111 dd1 NULL
|
||||
2 b2 222 dd2 NULL
|
||||
3 b3 333 dd3 NULL
|
||||
4 b4 444 dd4 NULL
|
||||
5 b5 555 dd5 NULL
|
||||
6 b6 666 dd6 NULL
|
||||
7 b7 777 dd7 NULL
|
||||
8 b8 888 dd8 NULL
|
||||
9 b9 999 dd9 NULL
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 b1 111 dd1
|
||||
2 b2 222 dd2
|
||||
3 b3 333 dd3
|
||||
4 b4 444 dd4
|
||||
5 b5 555 dd5
|
||||
6 b6 666 dd6
|
||||
7 b7 777 dd7
|
||||
8 b8 888 dd8
|
||||
9 b9 999 dd9
|
||||
create database test2;
|
||||
use test2;
|
||||
CREATE TABLE t2 (
|
||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||
b int unsigned not null,
|
||||
c int unsigned
|
||||
) engine=ndbcluster;
|
||||
insert into t2 values (1,1,1),(2,2,2);
|
||||
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||
a b c d a b c
|
||||
1 b1 111 dd1 1 1 1
|
||||
2 b2 222 dd2 2 2 2
|
||||
drop table t2;
|
||||
use test;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 b1 111 dd1
|
||||
2 b2 222 dd2
|
||||
3 b3 333 dd3
|
||||
4 b4 444 dd4
|
||||
5 b5 555 dd5
|
||||
6 b6 666 dd6
|
||||
7 b7 777 dd7
|
||||
8 b8 888 dd8
|
||||
9 b9 999 dd9
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
a b c d x
|
||||
1 b1 111 dd1 NULL
|
||||
2 b2 222 dd2 NULL
|
||||
3 b3 333 dd3 NULL
|
||||
4 b4 444 dd4 NULL
|
||||
5 b5 555 dd5 NULL
|
||||
6 b6 666 dd6 NULL
|
||||
7 b7 777 dd7 NULL
|
||||
8 b8 888 dd8 NULL
|
||||
9 b9 999 dd9 NULL
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
a b c d
|
||||
1 b1 111 dd1
|
||||
2 b2 222 dd2
|
||||
3 b3 333 dd3
|
||||
4 b4 444 dd4
|
||||
5 b5 555 dd5
|
||||
6 b6 666 dd6
|
||||
7 b7 777 dd7
|
||||
8 b8 888 dd8
|
||||
9 b9 999 dd9
|
||||
drop table t1;
|
||||
drop database test2;
|
||||
set autocommit=0;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b tinytext
|
||||
) engine=ndbcluster;
|
||||
insert into t1 values(1, 'x');
|
||||
update t1 set b = 'y';
|
||||
select * from t1;
|
||||
a b
|
||||
1 y
|
||||
delete from t1;
|
||||
select * from t1;
|
||||
a b
|
||||
commit;
|
||||
drop table t1;
|
||||
set autocommit=0;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) engine=ndbcluster;
|
||||
insert into t1 values(1, '');
|
||||
select * from t1;
|
||||
a b
|
||||
1
|
||||
commit;
|
||||
drop table t1;
|
||||
drop database mysqltest;
|
||||
set autocommit=1;
|
||||
use test;
|
||||
CREATE TABLE t1 (
|
||||
@ -397,6 +460,7 @@ select * from t1 order by a;
|
||||
a b
|
||||
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
||||
set autocommit=1;
|
||||
alter table t1 engine=myisam;
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
|
@ -557,3 +557,32 @@ select * from t1 where pk1=1;
|
||||
pk1 b c
|
||||
1 2 3
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT) ENGINE=ndb;
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
|
@ -62,4 +62,15 @@ id emp salary l r
|
||||
4 Donna 1064.80 5 6
|
||||
5 Eddie 931.70 7 8
|
||||
6 Fred 798.60 9 10
|
||||
prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
|
||||
set @arg_round= 50;
|
||||
execute st_round using @arg_round, @arg_round;
|
||||
select * from t1;
|
||||
id emp salary l r
|
||||
1 Jerry 1350.00 1 12
|
||||
2 Bert 1200.00 2 3
|
||||
3 Chuck 1250.00 4 11
|
||||
4 Donna 1100.00 5 6
|
||||
5 Eddie 950.00 7 8
|
||||
6 Fred 800.00 9 10
|
||||
drop table t1;
|
||||
|
@ -1580,7 +1580,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -1563,7 +1563,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -1564,7 +1564,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -1606,7 +1606,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
@ -4613,7 +4615,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -1563,7 +1563,9 @@ a b
|
||||
1200 x1000_1updatedupdated
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
execute stmt1;
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -1543,7 +1543,6 @@ a b
|
||||
1000 x1000_1
|
||||
delete from t1 where a >= 1000 ;
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
test_sequence
|
||||
------ multi table tests ------
|
||||
delete from t1 ;
|
||||
|
@ -547,3 +547,20 @@ select count(*) from t2 where x = 18446744073709551601;
|
||||
count(*)
|
||||
0
|
||||
drop table t1,t2;
|
||||
set names latin1;
|
||||
create table t1 (a char(10), b text, key (a)) character set latin1;
|
||||
INSERT INTO t1 (a) VALUES
|
||||
('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
|
||||
explain select * from t1 where a='aaa';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 11 const 2 Using where
|
||||
explain select * from t1 where a=binary 'aaa';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 11 NULL 2 Using where
|
||||
explain select * from t1 where a='aaa' collate latin1_bin;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 11 NULL 2 Using where
|
||||
explain select * from t1 where a='aaa' collate latin1_german1_ci;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
|
||||
drop table t1;
|
||||
|
15
mysql-test/r/rpl_failed_optimize.result
Normal file
15
mysql-test/r/rpl_failed_optimize.result
Normal file
@ -0,0 +1,15 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize status Operation failed
|
||||
OPTIMIZE TABLE non_existing;
|
||||
Table Op Msg_type Msg_text
|
||||
test.non_existing optimize error Table 'test.non_existing' doesn't exist
|
@ -85,6 +85,36 @@ t1 CREATE TABLE "t1" (
|
||||
UNIQUE KEY "email" ("email")
|
||||
)
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
a char(10),
|
||||
b char(10) collate latin1_bin,
|
||||
c binary(10)
|
||||
) character set latin1;
|
||||
set @@sql_mode="";
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL,
|
||||
`b` char(10) character set latin1 collate latin1_bin default NULL,
|
||||
`c` binary(10) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
set @@sql_mode="mysql323";
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL,
|
||||
`b` char(10) binary default NULL,
|
||||
`c` binary(10) default NULL
|
||||
) TYPE=MyISAM
|
||||
set @@sql_mode="mysql40";
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL,
|
||||
`b` char(10) binary default NULL,
|
||||
`c` binary(10) default NULL
|
||||
) TYPE=MyISAM
|
||||
drop table t1;
|
||||
set session sql_mode = '';
|
||||
create table t1 ( min_num dec(6,6) default .000001);
|
||||
show create table t1;
|
||||
|
@ -1,2 +1,2 @@
|
||||
--disable_result_log
|
||||
--exec $TESTS_BINDIR/client_test --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT
|
||||
--exec $TESTS_BINDIR/client_test --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent
|
||||
|
@ -5,7 +5,8 @@
|
||||
select 1+2/*hello*/+3;
|
||||
select 1 /* long
|
||||
multi line comment */;
|
||||
!$1065 ;
|
||||
--error 1065
|
||||
;
|
||||
select 1 /*!32301 +1 */;
|
||||
select 1 /*!52301 +1 */;
|
||||
select 1--1;
|
||||
|
@ -131,3 +131,51 @@ create table t1 (a char(10) character set koi8r, b text character set koi8r);
|
||||
insert into t1 values ('test','test');
|
||||
insert into t1 values ('ÊÃÕË','ÊÃÕË');
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Try to apply an automatic conversion in some cases:
|
||||
# E.g. when mixing a column to a string, the string
|
||||
# is converted into the column character set.
|
||||
# If conversion loses data, then error. Otherwise,
|
||||
# the string is replaced by its converted representation
|
||||
#
|
||||
set names koi8r;
|
||||
create table t1 (a char(10) character set cp1251);
|
||||
insert into t1 values (_koi8r'×ÁÓÑ');
|
||||
# this is possible:
|
||||
select * from t1 where a=_koi8r'×ÁÓÑ';
|
||||
# this is not possible, because we have a function, not just a constant:
|
||||
--error 1267
|
||||
select * from t1 where a=concat(_koi8r'×ÁÓÑ');
|
||||
# this is not posible, cannot convert _latin1'×ÁÓÑ' into cp1251:
|
||||
--error 1267
|
||||
select * from t1 where a=_latin1'×ÁÓÑ';
|
||||
drop table t1;
|
||||
set names latin1;
|
||||
|
||||
#
|
||||
# Check more automatic conversion
|
||||
#
|
||||
set names koi8r;
|
||||
create table t1 (c1 char(10) character set cp1251);
|
||||
insert into t1 values ('ß');
|
||||
select c1 from t1 where c1 between 'ß' and 'ß';
|
||||
select ifnull(c1,'ß'), ifnull(null,c1) from t1;
|
||||
select if(1,c1,'ö'), if(0,c1,'ö') from t1;
|
||||
select coalesce('ö',c1), coalesce(null,c1) from t1;
|
||||
select least(c1,'ö'), greatest(c1,'ö') from t1;
|
||||
select locate(c1,'ß'), locate('ß',c1) from t1;
|
||||
select field(c1,'ß'),field('ß',c1) from t1;
|
||||
select concat(c1,'ö'), concat('ö',c1) from t1;
|
||||
select concat_ws(c1,'ö','ß'), concat_ws('ö',c1,'ß') from t1;
|
||||
select replace(c1,'ß','ö'), replace('ß',c1,'ö') from t1;
|
||||
select substring_index(c1,'öößß',2) from t1;
|
||||
select elt(1,c1,'ö'),elt(1,'ö',c1) from t1;
|
||||
select make_set(3,c1,'ö'), make_set(3,'ö',c1) from t1;
|
||||
select insert(c1,1,2,'ö'),insert('ö',1,2,c1) from t1;
|
||||
select trim(c1 from 'ß'),trim('ß' from c1) from t1;
|
||||
select lpad(c1,3,'ö'), lpad('ö',3,c1) from t1;
|
||||
select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
|
||||
# TODO
|
||||
#select case c1 when 'ß' then 'ß' when 'ö' then 'ö' else 'c' end from t1;
|
||||
#select export_set(5,c1,'ö'), export_set(5,'ö',c1) from t1;
|
||||
|
@ -51,3 +51,14 @@ insert into t1 values (0x9353);
|
||||
insert into t1 values (0x9373);
|
||||
select hex(c) from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #6223 Japanese half-width kana characters get truncated
|
||||
#
|
||||
SET NAMES sjis;
|
||||
CREATE TABLE t1 (
|
||||
c char(16) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=sjis;
|
||||
insert into t1 values(0xb1),(0xb2),(0xb3);
|
||||
select hex(c) from t1;
|
||||
drop table t1;
|
||||
|
@ -645,6 +645,7 @@ insert into t1 values(1,'foo'),(2,'foobar');
|
||||
select * from t1 where b like 'foob%';
|
||||
--disable_warnings
|
||||
alter table t1 engine=bdb;
|
||||
--enable_warnings
|
||||
select * from t1 where b like 'foob%';
|
||||
drop table t1;
|
||||
|
||||
|
@ -253,9 +253,16 @@ select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('
|
||||
# bug with many short (< ft_min_word_len) words in boolean search
|
||||
#
|
||||
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# bug with repair-by-sort and incorrect records estimation
|
||||
#
|
||||
|
||||
create table t1 (a text, fulltext key (a));
|
||||
insert into t1 select "xxxx yyyy zzzz";
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# UTF8
|
||||
#
|
||||
|
@ -284,3 +284,78 @@ drop table t1;
|
||||
create table t1 select POINT(1,3);
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE `t1` (`object_id` bigint(20) unsigned NOT NULL default '0', `geo`
|
||||
geometry NOT NULL default '') ENGINE=MyISAM ;
|
||||
|
||||
insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363
|
||||
36.305435,-114.992394 36.305202,-114.991219 36.305975,-114.991163
|
||||
36.306845,-114.989432 36.309452,-114.978275 36.312642,-114.977363
|
||||
36.311978,-114.975327 36.312344,-114.96502 36.31597,-114.963364
|
||||
36.313629,-114.961723 36.313721,-114.956398 36.316057,-114.951882
|
||||
36.320979,-114.947073 36.323475,-114.945207 36.326451,-114.945207
|
||||
36.326451,-114.944132 36.326061,-114.94003 36.326588,-114.924017
|
||||
36.334484,-114.923281 36.334146,-114.92564 36.331504,-114.94072
|
||||
36.319282,-114.945348 36.314812,-114.948091 36.314762,-114.951755
|
||||
36.316211,-114.952446 36.313883,-114.952644 36.309488,-114.944725
|
||||
36.313083,-114.93706 36.32043,-114.932478 36.323497,-114.924556
|
||||
36.327708,-114.922608 36.329715,-114.92009 36.328695,-114.912105
|
||||
36.323566,-114.901647 36.317952,-114.897436 36.313968,-114.895344
|
||||
36.309573,-114.891699 36.304398,-114.890569 36.303551,-114.886356
|
||||
36.302702,-114.885141 36.301351,-114.885709 36.297391,-114.892499
|
||||
36.290893,-114.902142 36.288974,-114.904941 36.288838,-114.905308
|
||||
36.289845,-114.906325 36.290395,-114.909916 36.289549,-114.914527
|
||||
36.287535,-114.918797 36.284423,-114.922982 36.279731,-114.924113
|
||||
36.277282,-114.924057 36.275817,-114.927733 36.27053,-114.929354
|
||||
36.269029,-114.929354 36.269029,-114.950856 36.268715,-114.950768
|
||||
36.264324,-114.960206 36.264293,-114.960301 36.268943,-115.006662
|
||||
36.268929,-115.008583 36.265619,-115.00665 36.264247,-115.006659
|
||||
36.246873,-115.006659 36.246873,-115.006838 36.247697,-115.010764
|
||||
36.247774,-115.015609 36.25113,-115.015765 36.254505,-115.029517
|
||||
36.254619,-115.038573 36.249317,-115.038573 36.249317,-115.023403
|
||||
36.25841,-115.023873 36.258994,-115.031845 36.259829,-115.03183
|
||||
36.261053,-115.025561 36.261095,-115.036417 36.274632,-115.033729
|
||||
36.276041,-115.032217 36.274851,-115.029845 36.273959,-115.029934
|
||||
36.274966,-115.025763 36.274896,-115.025406 36.281044,-115.028731
|
||||
36.284471,-115.036497 36.290377,-115.042071 36.291039,-115.026759
|
||||
36.298478,-115.008995 36.301966,-115.006363 36.305435),(-115.079835
|
||||
36.244369,-115.079735 36.260186,-115.076435 36.262369,-115.069758
|
||||
36.265,-115.070235 36.268757,-115.064542 36.268655,-115.061843
|
||||
36.269857,-115.062676 36.270693,-115.06305 36.272344,-115.059051
|
||||
36.281023,-115.05918 36.283008,-115.060591 36.285246,-115.061913
|
||||
36.290022,-115.062499 36.306353,-115.062499 36.306353,-115.060918
|
||||
36.30642,-115.06112 36.289779,-115.05713 36.2825,-115.057314
|
||||
36.279446,-115.060779 36.274659,-115.061366 36.27209,-115.057858
|
||||
36.26557,-115.055805 36.262883,-115.054688 36.262874,-115.047335
|
||||
36.25037,-115.044234 36.24637,-115.052434 36.24047,-115.061734
|
||||
36.23507,-115.061934 36.22677,-115.061934 36.22677,-115.061491
|
||||
36.225267,-115.062024 36.218194,-115.060134 36.218278,-115.060133
|
||||
36.210771,-115.057833 36.210771,-115.057433 36.196271,-115.062233
|
||||
36.196271,-115.062233 36.190371,-115.062233 36.190371,-115.065533
|
||||
36.190371,-115.071333 36.188571,-115.098331 36.188275,-115.098331
|
||||
36.188275,-115.098435 36.237569,-115.097535 36.240369,-115.097535
|
||||
36.240369,-115.093235 36.240369,-115.089135 36.240469,-115.083135
|
||||
36.240569,-115.083135 36.240569,-115.079835
|
||||
36.244369)))')),('85998',GeomFromText('MULTIPOLYGON(((-115.333107
|
||||
36.264587,-115.333168 36.280638,-115.333168 36.280638,-115.32226
|
||||
36.280643,-115.322538 36.274311,-115.327222 36.274258,-115.32733
|
||||
36.263026,-115.330675 36.262984,-115.332132 36.264673,-115.333107
|
||||
36.264587),(-115.247239 36.247066,-115.247438 36.218267,-115.247438
|
||||
36.218267,-115.278525 36.219263,-115.278525 36.219263,-115.301545
|
||||
36.219559,-115.332748 36.219197,-115.332757 36.220041,-115.332757
|
||||
36.220041,-115.332895 36.233514,-115.349023 36.233479,-115.351489
|
||||
36.234475,-115.353681 36.237021,-115.357106 36.239789,-115.36519
|
||||
36.243331,-115.368156 36.243487,-115.367389 36.244902,-115.364553
|
||||
36.246014,-115.359219 36.24616,-115.356186 36.248025,-115.353347
|
||||
36.248004,-115.350813 36.249507,-115.339673 36.25387,-115.333069
|
||||
36.255018,-115.333069 36.255018,-115.333042 36.247767,-115.279039
|
||||
36.248666,-115.263639 36.247466,-115.263839 36.252766,-115.261439
|
||||
36.252666,-115.261439 36.247366,-115.247239 36.247066)))'));
|
||||
|
||||
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
|
||||
t1 where object_id=85998;
|
||||
|
||||
select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
|
||||
t1 where object_id=85984;
|
||||
|
||||
drop table t1;
|
||||
|
@ -34,11 +34,14 @@ explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
|
||||
select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
|
||||
|
||||
# The next query should rearange the left joins to get this to work
|
||||
!$1120 explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
|
||||
!$1120 select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
|
||||
--error 1120
|
||||
explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
|
||||
--error 1120
|
||||
select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
|
||||
|
||||
# The next query should give an error in MySQL
|
||||
!$1120 select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
|
||||
--error 1120
|
||||
select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
|
||||
|
||||
# Test of inner join
|
||||
select t1.*,t2.* from t1 inner join t2 using (a);
|
||||
@ -94,7 +97,8 @@ WHERE t1.uniq_id = 4
|
||||
ORDER BY t2.c_amount;
|
||||
|
||||
INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
|
||||
!$1062 INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
|
||||
--error 1062
|
||||
INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
|
||||
INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes');
|
||||
|
||||
#3rd select should show that one record is returned with null entries for the
|
||||
@ -288,7 +292,8 @@ insert into t3 values (1);
|
||||
insert into t4 values (1,1);
|
||||
insert into t5 values (1,1);
|
||||
|
||||
!$1120 explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
|
||||
--error 1120
|
||||
explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
|
||||
|
||||
drop table t1,t2,t3,t4,t5;
|
||||
|
||||
|
@ -150,7 +150,8 @@ create table t1
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
|
||||
!$1062 INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
|
||||
--error 1062
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
@ -5,18 +5,25 @@
|
||||
#
|
||||
# ============================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# $mysql_errno contains the return code of the last command
|
||||
# send to the server.
|
||||
# ----------------------------------------------------------------------------
|
||||
# get $mysql_errno before the first statement
|
||||
# $mysql_errno should be -1
|
||||
eval select $mysql_errno as "before_use_test" ;
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Positive case(statement)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
select otto from (select 1 as otto) as t1;
|
||||
# expectation = response
|
||||
!$0 select otto from (select 1 as otto) as t1;
|
||||
--error 0
|
||||
select otto from (select 1 as otto) as t1;
|
||||
|
||||
# expectation <> response
|
||||
-- // !$1054 select otto from (select 1 as otto) as t1;
|
||||
-- // --error 1054
|
||||
-- // select otto from (select 1 as otto) as t1;
|
||||
|
||||
@ -29,12 +36,10 @@ select otto from (select 1 as otto) as t1;
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# expectation <> response
|
||||
#!$0 select friedrich from (select 1 as otto) as t1;
|
||||
#--error 0
|
||||
#select friedrich from (select 1 as otto) as t1;
|
||||
|
||||
# expectation = response
|
||||
!$1054 select friedrich from (select 1 as otto) as t1;
|
||||
--error 1054
|
||||
select friedrich from (select 1 as otto) as t1;
|
||||
|
||||
@ -76,3 +81,208 @@ select friedrich from (select 1 as otto) as t1;
|
||||
#--error S00000
|
||||
#select friedrich from (select 1 as otto) as t1;
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# test cases for $mysql_errno
|
||||
#
|
||||
# $mysql_errno is a builtin variable of mysqltest and contains the return code
|
||||
# of the last command send to the server.
|
||||
#
|
||||
# The following test cases often initialize $mysql_errno to 1064 by
|
||||
# a command with wrong syntax.
|
||||
# Example: --error 1064 To prevent the abort after the error.
|
||||
# garbage ;
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check mysql_errno = 0 after successful statement
|
||||
# ----------------------------------------------------------------------------
|
||||
select otto from (select 1 as otto) as t1;
|
||||
eval select $mysql_errno as "after_successful_stmt_errno" ;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# check mysql_errno = 1064 after statement with wrong syntax
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
eval select $mysql_errno as "after_wrong_syntax_errno" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check if let $my_var= 'abc' ; affects $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
let $my_var= 'abc' ;
|
||||
eval select $mysql_errno as "after_let_var_equal_value" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check if set @my_var= 'abc' ; affects $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
set @my_var= 'abc' ;
|
||||
eval select $mysql_errno as "after_set_var_equal_value" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check if the setting of --disable-warnings itself affects $mysql_errno
|
||||
# (May be --<whatever> modifies $mysql_errno.)
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
--disable_warnings
|
||||
eval select $mysql_errno as "after_disable_warnings_command" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check if --disable-warnings + command with warning affects the errno
|
||||
# stored within $mysql_errno
|
||||
# (May be disabled warnings affect $mysql_errno.)
|
||||
# ----------------------------------------------------------------------------
|
||||
drop table if exists t1 ;
|
||||
--error 1064
|
||||
garbage ;
|
||||
drop table if exists t1 ;
|
||||
eval select $mysql_errno as "after_disable_warnings" ;
|
||||
--enable_warnings
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check if masked errors affect $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1146
|
||||
select 3 from t1 ;
|
||||
eval select $mysql_errno as "after_minus_masked" ;
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1146
|
||||
select 3 from t1 ;
|
||||
eval select $mysql_errno as "after_!_masked" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Will manipulations of $mysql_errno be possible and visible ?
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
let $mysql_errno= -1;
|
||||
eval select $mysql_errno as "after_let_errno_equal_value" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# How affect actions on prepared statements $mysql_errno ?
|
||||
# ----------------------------------------------------------------------------
|
||||
# failing prepare
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1146
|
||||
prepare stmt from "select 3 from t1" ;
|
||||
eval select $mysql_errno as "after_failing_prepare" ;
|
||||
create table t1 ( f1 char(10));
|
||||
|
||||
# successful prepare
|
||||
--error 1064
|
||||
garbage ;
|
||||
prepare stmt from "select 3 from t1" ;
|
||||
eval select $mysql_errno as "after_successful_prepare" ;
|
||||
|
||||
# successful execute
|
||||
--error 1064
|
||||
garbage ;
|
||||
execute stmt;
|
||||
eval select $mysql_errno as "after_successful_execute" ;
|
||||
|
||||
# failing execute (table dropped)
|
||||
drop table t1;
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1146
|
||||
execute stmt;
|
||||
eval select $mysql_errno as "after_failing_execute" ;
|
||||
|
||||
# failing execute (unknown statement)
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1243
|
||||
execute __stmt_;
|
||||
eval select $mysql_errno as "after_failing_execute" ;
|
||||
|
||||
# successful deallocate
|
||||
--error 1064
|
||||
garbage ;
|
||||
deallocate prepare stmt;
|
||||
eval select $mysql_errno as "after_successful_deallocate" ;
|
||||
|
||||
# failing deallocate ( statement handle does not exist )
|
||||
--error 1064
|
||||
garbage ;
|
||||
--error 1243
|
||||
deallocate prepare __stmt_;
|
||||
eval select $mysql_errno as "after_failing_deallocate" ;
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# test cases for "--disable_abort_on_error"
|
||||
#
|
||||
# "--disable_abort_on_error" switches the abort of mysqltest
|
||||
# after "unmasked" failing statements off.
|
||||
#
|
||||
# The default is "--enable_abort_on_error".
|
||||
#
|
||||
# "Maskings" are
|
||||
# --error <error number> and --error <error number>
|
||||
# in the line before the failing statement.
|
||||
#
|
||||
# There are some additional test case for $mysql_errno
|
||||
# because "--disable_abort_on_error" enables a new situation.
|
||||
# Example: "unmasked" statement fails + analysis of $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Switch the abort on error off and check the effect on $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
--disable_abort_on_error
|
||||
eval select $mysql_errno as "after_--disable_abort_on_error" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# "unmasked" failing statement should not cause an abort
|
||||
# ----------------------------------------------------------------------------
|
||||
select 3 from t1 ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# masked failing statements
|
||||
# ----------------------------------------------------------------------------
|
||||
# expected error = response
|
||||
--error 1146
|
||||
select 3 from t1 ;
|
||||
--error 1146
|
||||
select 3 from t1 ;
|
||||
eval select $mysql_errno as "after_!errno_masked_error" ;
|
||||
# expected error <> response
|
||||
# --error 1000
|
||||
# select 3 from t1 ;
|
||||
# --error 1000
|
||||
# select 3 from t1 ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Switch the abort on error on and check the effect on $mysql_errno
|
||||
# ----------------------------------------------------------------------------
|
||||
--error 1064
|
||||
garbage ;
|
||||
--enable_abort_on_error
|
||||
eval select $mysql_errno as "after_--enable_abort_on_error" ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# masked failing statements
|
||||
# ----------------------------------------------------------------------------
|
||||
# expected error = response
|
||||
--error 1146
|
||||
select 3 from t1 ;
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# check that the old default behaviour is not changed
|
||||
# Please remove the '#' to get the abort on error
|
||||
# ----------------------------------------------------------------------------
|
||||
#--error 1064
|
||||
#select 3 from t1 ;
|
||||
#
|
||||
#select 3 from t1 ;
|
||||
|
@ -371,3 +371,154 @@ select * from t1 order by b;
|
||||
select * from t1 where b IS NULL;
|
||||
select * from t1 where b IS NOT NULL;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# test the limit of no of attributes in one table
|
||||
#
|
||||
|
||||
create table t1 (
|
||||
c1 int,
|
||||
c2 int,
|
||||
c3 int,
|
||||
c4 int,
|
||||
c5 int,
|
||||
c6 int,
|
||||
c7 int,
|
||||
c8 int,
|
||||
c9 int,
|
||||
c10 int,
|
||||
c11 int,
|
||||
c12 int,
|
||||
c13 int,
|
||||
c14 int,
|
||||
c15 int,
|
||||
c16 int,
|
||||
c17 int,
|
||||
c18 int,
|
||||
c19 int,
|
||||
c20 int,
|
||||
c21 int,
|
||||
c22 int,
|
||||
c23 int,
|
||||
c24 int,
|
||||
c25 int,
|
||||
c26 int,
|
||||
c27 int,
|
||||
c28 int,
|
||||
c29 int,
|
||||
c30 int,
|
||||
c31 int,
|
||||
c32 int,
|
||||
c33 int,
|
||||
c34 int,
|
||||
c35 int,
|
||||
c36 int,
|
||||
c37 int,
|
||||
c38 int,
|
||||
c39 int,
|
||||
c40 int,
|
||||
c41 int,
|
||||
c42 int,
|
||||
c43 int,
|
||||
c44 int,
|
||||
c45 int,
|
||||
c46 int,
|
||||
c47 int,
|
||||
c48 int,
|
||||
c49 int,
|
||||
c50 int,
|
||||
c51 int,
|
||||
c52 int,
|
||||
c53 int,
|
||||
c54 int,
|
||||
c55 int,
|
||||
c56 int,
|
||||
c57 int,
|
||||
c58 int,
|
||||
c59 int,
|
||||
c60 int,
|
||||
c61 int,
|
||||
c62 int,
|
||||
c63 int,
|
||||
c64 int,
|
||||
c65 int,
|
||||
c66 int,
|
||||
c67 int,
|
||||
c68 int,
|
||||
c69 int,
|
||||
c70 int,
|
||||
c71 int,
|
||||
c72 int,
|
||||
c73 int,
|
||||
c74 int,
|
||||
c75 int,
|
||||
c76 int,
|
||||
c77 int,
|
||||
c78 int,
|
||||
c79 int,
|
||||
c80 int,
|
||||
c81 int,
|
||||
c82 int,
|
||||
c83 int,
|
||||
c84 int,
|
||||
c85 int,
|
||||
c86 int,
|
||||
c87 int,
|
||||
c88 int,
|
||||
c89 int,
|
||||
c90 int,
|
||||
c91 int,
|
||||
c92 int,
|
||||
c93 int,
|
||||
c94 int,
|
||||
c95 int,
|
||||
c96 int,
|
||||
c97 int,
|
||||
c98 int,
|
||||
c99 int,
|
||||
c100 int,
|
||||
c101 int,
|
||||
c102 int,
|
||||
c103 int,
|
||||
c104 int,
|
||||
c105 int,
|
||||
c106 int,
|
||||
c107 int,
|
||||
c108 int,
|
||||
c109 int,
|
||||
c110 int,
|
||||
c111 int,
|
||||
c112 int,
|
||||
c113 int,
|
||||
c114 int,
|
||||
c115 int,
|
||||
c116 int,
|
||||
c117 int,
|
||||
c118 int,
|
||||
c119 int,
|
||||
c120 int,
|
||||
c121 int,
|
||||
c122 int,
|
||||
c123 int,
|
||||
c124 int,
|
||||
c125 int,
|
||||
c126 int,
|
||||
c127 int,
|
||||
c128 int,
|
||||
primary key(c1)) engine=ndb;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# test max size of attribute name and truncation
|
||||
#
|
||||
|
||||
create table t1 (
|
||||
a1234567890123456789012345678901234567890 int primary key,
|
||||
a12345678901234567890123456789a1234567890 int,
|
||||
index(a12345678901234567890123456789a1234567890)
|
||||
) engine=ndb;
|
||||
show tables;
|
||||
insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2),(6,1),(7,1);
|
||||
explain select * from t1 where a12345678901234567890123456789a1234567890=2;
|
||||
select * from t1 where a12345678901234567890123456789a1234567890=2;
|
||||
drop table t1;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop database if exists mysqltest;
|
||||
drop database if exists test2;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
@ -12,31 +12,7 @@ drop database if exists mysqltest;
|
||||
# A prerequisite for this handler test is that "testBlobs" succeeds.
|
||||
#
|
||||
|
||||
# -- bug-5252 tinytext crashes --
|
||||
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b tinytext
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t1 values(1, 'x');
|
||||
update t1 set b = 'y';
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
drop table t1;
|
||||
|
||||
# -- bug-5013 insert empty string to text --
|
||||
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t1 values(1, '');
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
-- general test starts --
|
||||
# -- general test starts --
|
||||
|
||||
# make test harder with autocommit off
|
||||
set autocommit=0;
|
||||
@ -117,7 +93,6 @@ from t1 where a=2;
|
||||
# pk update to null
|
||||
update t1 set d=null where a=1;
|
||||
commit;
|
||||
# FIXME now fails at random due to weird mixup between the 2 rows
|
||||
select a from t1 where d is null;
|
||||
|
||||
# pk delete
|
||||
@ -126,6 +101,49 @@ delete from t1 where a=2;
|
||||
commit;
|
||||
select count(*) from t1;
|
||||
|
||||
# -- replace ( bug-6018 ) --
|
||||
|
||||
# insert
|
||||
replace t1 set a=1,b=@b1,c=111,d=@d1;
|
||||
replace t1 set a=2,b=@b2,c=222,d=@d2;
|
||||
commit;
|
||||
explain select * from t1 where a = 1;
|
||||
|
||||
# pk read
|
||||
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
|
||||
from t1 where a=1;
|
||||
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
|
||||
from t1 where a=2;
|
||||
|
||||
# update
|
||||
replace t1 set a=1,b=@b2,c=111,d=@d2;
|
||||
replace t1 set a=2,b=@b1,c=222,d=@d1;
|
||||
commit;
|
||||
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
|
||||
from t1 where a=1;
|
||||
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
|
||||
from t1 where a=2;
|
||||
|
||||
# update
|
||||
replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
|
||||
replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
|
||||
commit;
|
||||
select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
|
||||
from t1 where a=1;
|
||||
select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
|
||||
from t1 where a=2;
|
||||
|
||||
# update to null
|
||||
replace t1 set a=1,b='xyz',c=111,d=null;
|
||||
commit;
|
||||
select a,b from t1 where d is null;
|
||||
|
||||
# pk delete
|
||||
delete from t1 where a=1;
|
||||
delete from t1 where a=2;
|
||||
commit;
|
||||
select count(*) from t1;
|
||||
|
||||
# -- hash index ops --
|
||||
|
||||
insert into t1 values(1,@b1,111,@d1);
|
||||
@ -231,39 +249,6 @@ where c >= 100;
|
||||
commit;
|
||||
select * from t1 where c >= 100 order by a;
|
||||
|
||||
# alter table
|
||||
|
||||
select * from t1 order by a;
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
|
||||
# multi db
|
||||
|
||||
create database mysqltest;
|
||||
use mysqltest;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||
b int unsigned not null,
|
||||
c int unsigned
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t2 values (1,1,1),(2,2,2);
|
||||
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||
|
||||
drop table t2;
|
||||
use test;
|
||||
|
||||
# alter table
|
||||
|
||||
select * from t1 order by a;
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
|
||||
# range scan delete
|
||||
delete from t1 where c >= 100;
|
||||
commit;
|
||||
@ -306,10 +291,82 @@ select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
|
||||
from t1 order by a;
|
||||
rollback;
|
||||
select count(*) from t1;
|
||||
drop table t1;
|
||||
drop database mysqltest;
|
||||
|
||||
# bug #5349
|
||||
# -- alter table and multi db --
|
||||
|
||||
insert into t1 values(1,'b1',111,'dd1');
|
||||
insert into t1 values(2,'b2',222,'dd2');
|
||||
insert into t1 values(3,'b3',333,'dd3');
|
||||
insert into t1 values(4,'b4',444,'dd4');
|
||||
insert into t1 values(5,'b5',555,'dd5');
|
||||
insert into t1 values(6,'b6',666,'dd6');
|
||||
insert into t1 values(7,'b7',777,'dd7');
|
||||
insert into t1 values(8,'b8',888,'dd8');
|
||||
insert into t1 values(9,'b9',999,'dd9');
|
||||
commit;
|
||||
|
||||
select * from t1 order by a;
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
|
||||
create database test2;
|
||||
use test2;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||
b int unsigned not null,
|
||||
c int unsigned
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t2 values (1,1,1),(2,2,2);
|
||||
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||
|
||||
drop table t2;
|
||||
use test;
|
||||
|
||||
select * from t1 order by a;
|
||||
alter table t1 add x int;
|
||||
select * from t1 order by a;
|
||||
alter table t1 drop x;
|
||||
select * from t1 order by a;
|
||||
|
||||
# -- end general test --
|
||||
|
||||
drop table t1;
|
||||
drop database test2;
|
||||
|
||||
# -- bug-5252 tinytext crashes plus no-commit result --
|
||||
|
||||
set autocommit=0;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b tinytext
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t1 values(1, 'x');
|
||||
update t1 set b = 'y';
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
select * from t1;
|
||||
commit;
|
||||
drop table t1;
|
||||
|
||||
# -- bug-5013 insert empty string to text --
|
||||
|
||||
set autocommit=0;
|
||||
create table t1 (
|
||||
a int not null primary key,
|
||||
b text not null
|
||||
) engine=ndbcluster;
|
||||
|
||||
insert into t1 values(1, '');
|
||||
select * from t1;
|
||||
commit;
|
||||
drop table t1;
|
||||
|
||||
# -- bug #5349 --
|
||||
set autocommit=1;
|
||||
use test;
|
||||
CREATE TABLE t1 (
|
||||
@ -327,7 +384,8 @@ select * from t1 order by a;
|
||||
alter table t1 engine=ndb;
|
||||
select * from t1 order by a;
|
||||
|
||||
# bug #5872
|
||||
# -- bug #5872 --
|
||||
set autocommit=1;
|
||||
alter table t1 engine=myisam;
|
||||
select * from t1 order by a;
|
||||
drop table t1;
|
||||
|
@ -583,3 +583,18 @@ INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
|
||||
select * from t1 where pk1=1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #6331: problem with 'insert ignore'
|
||||
#
|
||||
|
||||
CREATE TABLE t1(a INT) ENGINE=ndb;
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 SELECT a FROM t1;
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
@ -61,12 +61,11 @@ while ($1)
|
||||
|
||||
select * from t1;
|
||||
|
||||
# Waiting for the resolution of bug#6138
|
||||
# # Now, increase salary to a multiple of 50
|
||||
# prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
|
||||
# set @arg_round= 50;
|
||||
# execute st_round using @arg_round, @arg_round;
|
||||
#
|
||||
# select * from t1;
|
||||
# Now, increase salary to a multiple of 50 (checks for bug#6138)
|
||||
prepare st_round from 'update t1 set salary = salary + ? - ( salary MOD ? )';
|
||||
set @arg_round= 50;
|
||||
execute st_round using @arg_round, @arg_round;
|
||||
|
||||
select * from t1;
|
||||
|
||||
drop table t1;
|
||||
|
@ -339,8 +339,8 @@ select a,b from t1 where a >= 1000 order by a ;
|
||||
delete from t1 where a >= 1000 ;
|
||||
|
||||
## replace
|
||||
--error 1295
|
||||
prepare stmt1 from ' replace into t1 (a,b) select 100, ''hundred'' ';
|
||||
--error 1031
|
||||
|
||||
## multi table statements
|
||||
--disable_query_log
|
||||
|
@ -418,3 +418,17 @@ select count(*) from t2 where x > -16;
|
||||
select count(*) from t2 where x = 18446744073709551601;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# Bug #6045: Binary Comparison regression in MySQL 4.1
|
||||
# Binary searches didn't use a case insensitive index.
|
||||
#
|
||||
set names latin1;
|
||||
create table t1 (a char(10), b text, key (a)) character set latin1;
|
||||
INSERT INTO t1 (a) VALUES
|
||||
('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
|
||||
# all these three can be optimized
|
||||
explain select * from t1 where a='aaa';
|
||||
explain select * from t1 where a=binary 'aaa';
|
||||
explain select * from t1 where a='aaa' collate latin1_bin;
|
||||
# this one cannot:
|
||||
explain select * from t1 where a='aaa' collate latin1_german1_ci;
|
||||
|
1
mysql-test/t/rpl_failed_optimize-master.opt
Normal file
1
mysql-test/t/rpl_failed_optimize-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--innodb-lock-wait-timeout=1
|
18
mysql-test/t/rpl_failed_optimize.test
Normal file
18
mysql-test/t/rpl_failed_optimize.test
Normal file
@ -0,0 +1,18 @@
|
||||
source include/have_innodb.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
#
|
||||
# BUG#5551 "Failed OPTIMIZE TABLE is logged to binary log"
|
||||
# Replication should work when OPTIMIZE TABLE timeouts, and
|
||||
# when OPTIMIZE TABLE is executed on a non-existing table
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
connection master1;
|
||||
OPTIMIZE TABLE t1;
|
||||
|
||||
OPTIMIZE TABLE non_existing;
|
||||
sync_slave_with_master;
|
@ -21,7 +21,8 @@ check table t1 changed;
|
||||
check table t1 medium;
|
||||
check table t1 extended;
|
||||
show index from t1;
|
||||
!$1062 insert into t1 values (5,5,5);
|
||||
--error 1062
|
||||
insert into t1 values (5,5,5);
|
||||
optimize table t1;
|
||||
optimize table t1;
|
||||
drop table t1;
|
||||
|
@ -29,6 +29,37 @@ select @@sql_mode;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Check that a binary collation adds 'binary'
|
||||
# suffix into a char() column definition in
|
||||
# mysql40 and mysql2323 modes. This allows
|
||||
# not to lose the column's case sensitivity
|
||||
# when loading the dump in pre-4.1 servers.
|
||||
#
|
||||
# Thus, in 4.0 and 3.23 modes we dump:
|
||||
#
|
||||
# 'char(10) collate xxx_bin' as 'char(10) binary'
|
||||
# 'binary(10)' as 'binary(10)'
|
||||
#
|
||||
# In mysql-4.1 these types are different, and they will
|
||||
# be recreated differently.
|
||||
#
|
||||
# In mysqld-4.0 the the above two types were the same,
|
||||
# so it will create a 'char(10) binary' column for both definitions.
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
a char(10),
|
||||
b char(10) collate latin1_bin,
|
||||
c binary(10)
|
||||
) character set latin1;
|
||||
set @@sql_mode="";
|
||||
show create table t1;
|
||||
set @@sql_mode="mysql323";
|
||||
show create table t1;
|
||||
set @@sql_mode="mysql40";
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#5318 - failure: 'IGNORE_SPACE' affects numeric values after DEFAULT
|
||||
#
|
||||
|
@ -20,8 +20,10 @@ create TEMPORARY TABLE t2 engine=heap select * from t1;
|
||||
create TEMPORARY TABLE IF NOT EXISTS t2 (a int) engine=heap;
|
||||
|
||||
# This should give errors
|
||||
!$1050 CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
|
||||
!$1050 ALTER TABLE t1 RENAME t2;
|
||||
--error 1050
|
||||
CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
|
||||
--error 1050
|
||||
ALTER TABLE t1 RENAME t2;
|
||||
|
||||
select * from t2;
|
||||
alter table t2 add primary key (a,b);
|
||||
|
@ -135,7 +135,8 @@ drop table t1,t2;
|
||||
create table t1 (c int);
|
||||
insert into t1 values(1),(2);
|
||||
create table t2 select * from t1;
|
||||
!$1060 create table t3 select * from t1, t2; # Should give an error
|
||||
--error 1060
|
||||
create table t3 select * from t1, t2; # Should give an error
|
||||
create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2;
|
||||
show full columns from t3;
|
||||
drop table t1,t2,t3;
|
||||
|
@ -117,4 +117,9 @@
|
||||
*/
|
||||
#define NDB_BLOB_HEAD_SIZE 2 /* sizeof(NdbBlob::Head) >> 2 */
|
||||
|
||||
/*
|
||||
* Long signals
|
||||
*/
|
||||
#define NDB_SECTION_SEGMENT_SZ 60
|
||||
|
||||
#endif
|
||||
|
@ -51,7 +51,6 @@ class DictTabInfo {
|
||||
friend class Trix;
|
||||
friend class DbUtil;
|
||||
// API
|
||||
friend class Table;
|
||||
friend class NdbSchemaOp;
|
||||
|
||||
/**
|
||||
|
@ -82,19 +82,12 @@ extern "C" {
|
||||
/* call in main() - does not return on error */
|
||||
extern int ndb_init(void);
|
||||
extern void ndb_end(int);
|
||||
#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
extern char * strdup(const char *s);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
extern size_t strlcpy (char *dst, const char *src, size_t dst_sz);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
extern size_t strlcat (char *dst, const char *src, size_t dst_sz);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
extern int strcasecmp(const char *s1, const char *s2);
|
||||
extern int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
|
@ -36,7 +36,7 @@ class NdbColumnImpl;
|
||||
* Blob data is stored in 2 places:
|
||||
*
|
||||
* - "header" and "inline bytes" stored in the blob attribute
|
||||
* - "blob parts" stored in a separate table NDB$BLOB_<t>_<v>_<c>
|
||||
* - "blob parts" stored in a separate table NDB$BLOB_<tid>_<cid>
|
||||
*
|
||||
* Inline and part sizes can be set via NdbDictionary::Column methods
|
||||
* when the table is created.
|
||||
@ -74,23 +74,21 @@ class NdbColumnImpl;
|
||||
* NdbBlob methods return -1 on error and 0 on success, and use output
|
||||
* parameters when necessary.
|
||||
*
|
||||
* Notes:
|
||||
* - table and its blob part tables are not created atomically
|
||||
* - scan must use the "new" interface NdbScanOperation
|
||||
* - to update a blob in a read op requires exclusive tuple lock
|
||||
* - update op in scan must do its own getBlobHandle
|
||||
* - delete creates implicit, not-accessible blob handles
|
||||
* - NdbOperation::writeTuple does not support blobs
|
||||
* - there is no support for an asynchronous interface
|
||||
* Operation types:
|
||||
* - insertTuple must use setValue if blob column is non-nullable
|
||||
* - readTuple with exclusive lock can also update existing value
|
||||
* - updateTuple can overwrite with setValue or update existing value
|
||||
* - writeTuple always overwrites and must use setValue if non-nullable
|
||||
* - deleteTuple creates implicit non-accessible blob handles
|
||||
* - scan with exclusive lock can also update existing value
|
||||
* - scan "lock takeover" update op must do its own getBlobHandle
|
||||
*
|
||||
* Bugs / limitations:
|
||||
* - scan must use exclusive locking for now
|
||||
*
|
||||
* Todo:
|
||||
* - add scan method hold-read-lock + return-keyinfo
|
||||
* - check keyinfo length when setting keys
|
||||
* - check allowed blob ops vs locking mode
|
||||
* - overload control (too many pending ops)
|
||||
* - lock mode upgrade should be handled automatically
|
||||
* - lock mode vs allowed operation is not checked
|
||||
* - too many pending blob ops can blow up i/o buffers
|
||||
* - table and its blob part tables are not created atomically
|
||||
* - there is no support for an asynchronous interface
|
||||
*/
|
||||
class NdbBlob {
|
||||
public:
|
||||
@ -172,19 +170,11 @@ public:
|
||||
* read in the in/out bytes parameter.
|
||||
*/
|
||||
int readData(void* data, Uint32& bytes);
|
||||
/**
|
||||
* Read at given position. Does not use or update current position.
|
||||
*/
|
||||
int readData(Uint64 pos, void* data, Uint32& bytes);
|
||||
/**
|
||||
* Write at current position and set new position to first byte after
|
||||
* the data written. A write past blob end extends the blob value.
|
||||
*/
|
||||
int writeData(const void* data, Uint32 bytes);
|
||||
/**
|
||||
* Write at given position. Does not use or update current position.
|
||||
*/
|
||||
int writeData(Uint64 pos, const void* data, Uint32 bytes);
|
||||
/**
|
||||
* Return the blob column.
|
||||
*/
|
||||
@ -266,14 +256,17 @@ private:
|
||||
Buf();
|
||||
~Buf();
|
||||
void alloc(unsigned n);
|
||||
void copyfrom(const Buf& src);
|
||||
};
|
||||
Buf theKeyBuf;
|
||||
Buf theAccessKeyBuf;
|
||||
Buf theHeadInlineBuf;
|
||||
Buf theHeadInlineCopyBuf; // for writeTuple
|
||||
Buf thePartBuf;
|
||||
Head* theHead;
|
||||
char* theInlineData;
|
||||
NdbRecAttr* theHeadInlineRecAttr;
|
||||
NdbOperation* theHeadInlineReadOp;
|
||||
bool theHeadInlineUpdateFlag;
|
||||
// length and read/write position
|
||||
int theNullFlag;
|
||||
@ -294,6 +287,7 @@ private:
|
||||
bool isReadOp();
|
||||
bool isInsertOp();
|
||||
bool isUpdateOp();
|
||||
bool isWriteOp();
|
||||
bool isDeleteOp();
|
||||
bool isScanOp();
|
||||
// computations
|
||||
@ -309,12 +303,13 @@ private:
|
||||
void getHeadFromRecAttr();
|
||||
int setHeadInlineValue(NdbOperation* anOp);
|
||||
// data operations
|
||||
int readDataPrivate(Uint64 pos, char* buf, Uint32& bytes);
|
||||
int writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes);
|
||||
int readDataPrivate(char* buf, Uint32& bytes);
|
||||
int writeDataPrivate(const char* buf, Uint32 bytes);
|
||||
int readParts(char* buf, Uint32 part, Uint32 count);
|
||||
int insertParts(const char* buf, Uint32 part, Uint32 count);
|
||||
int updateParts(const char* buf, Uint32 part, Uint32 count);
|
||||
int deleteParts(Uint32 part, Uint32 count);
|
||||
int deletePartsUnknown(Uint32 part);
|
||||
// pending ops
|
||||
int executePendingBlobReads();
|
||||
int executePendingBlobWrites();
|
||||
|
@ -526,7 +526,7 @@ private:
|
||||
int sendCOMMIT(); // Send a TC_COMMITREQ signal;
|
||||
void setGCI(int GCI); // Set the global checkpoint identity
|
||||
|
||||
int OpCompleteFailure(Uint8 abortoption);
|
||||
int OpCompleteFailure(Uint8 abortoption, bool setFailure = true);
|
||||
int OpCompleteSuccess();
|
||||
void CompletedOperations(); // Move active ops to list of completed
|
||||
|
||||
@ -552,7 +552,7 @@ private:
|
||||
void setOperationErrorCode(int anErrorCode);
|
||||
|
||||
// Indicate something went wrong in the definition phase
|
||||
void setOperationErrorCodeAbort(int anErrorCode);
|
||||
void setOperationErrorCodeAbort(int anErrorCode, int abortOption = -1);
|
||||
|
||||
int checkMagicNumber(); // Verify correct object
|
||||
NdbOperation* getNdbOperation(const class NdbTableImpl* aTable,
|
||||
|
@ -49,6 +49,9 @@ public:
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** insert is not allowed */
|
||||
int insertTuple();
|
||||
|
||||
/**
|
||||
* Define the NdbIndexOperation to be a standard operation of type readTuple.
|
||||
* When calling NdbConnection::execute, this operation
|
||||
@ -193,6 +196,7 @@ private:
|
||||
|
||||
// Private attributes
|
||||
const NdbIndexImpl* m_theIndex;
|
||||
const NdbTableImpl* m_thePrimaryTable;
|
||||
Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
|
||||
Uint32 m_theIndexLen; // Length of the index in words
|
||||
Uint32 m_theNoOfIndexDefined; // The number of index attributes
|
||||
|
@ -918,6 +918,13 @@ protected:
|
||||
// Blobs in this operation
|
||||
NdbBlob* theBlobList;
|
||||
|
||||
/*
|
||||
* Abort option per operation, used by blobs. Default -1. If set,
|
||||
* overrides abort option on connection level. If set to IgnoreError,
|
||||
* does not cause execute() to return failure. This is different from
|
||||
* IgnoreError on connection level.
|
||||
*/
|
||||
Int8 m_abortOption;
|
||||
};
|
||||
|
||||
#ifdef NDB_NO_DROPPED_SIGNAL
|
||||
@ -1160,5 +1167,3 @@ NdbOperation::setValue(Uint32 anAttrId, double aPar)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -22,12 +22,13 @@
|
||||
#define NDB_MAX_DATABASE_NAME_SIZE 128
|
||||
#define NDB_MAX_SCHEMA_NAME_SIZE 128
|
||||
#define NDB_MAX_TAB_NAME_SIZE 128
|
||||
#define NDB_MAX_ATTRIBUTES_IN_TABLE 91
|
||||
#define NDB_MAX_ATTR_NAME_SIZE 32
|
||||
#define NDB_MAX_ATTRIBUTES_IN_TABLE 128
|
||||
|
||||
#define NDB_MAX_TUPLE_SIZE_IN_WORDS 1023
|
||||
#define NDB_MAX_TUPLE_SIZE_IN_WORDS 2013
|
||||
#define NDB_MAX_KEYSIZE_IN_WORDS 1023
|
||||
#define NDB_MAX_KEY_SIZE NDB_MAX_KEYSIZE_IN_WORDS*sizeof(Uint32)
|
||||
#define NDB_MAX_TUPLE_SIZE NDB_MAX_TUPLE_SIZE_IN_WORDS*sizeof(uint32)
|
||||
#define NDB_MAX_KEY_SIZE (NDB_MAX_KEYSIZE_IN_WORDS*4)
|
||||
#define NDB_MAX_TUPLE_SIZE (NDB_MAX_TUPLE_SIZE_IN_WORDS*4)
|
||||
#define NDB_MAX_ACTIVE_EVENTS 100
|
||||
|
||||
#endif
|
||||
|
57
ndb/include/util/ndb_opts.h
Normal file
57
ndb/include/util/ndb_opts.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2003 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 */
|
||||
|
||||
#ifndef _NDB_OPTS_H
|
||||
#define _NDB_OPTS_H
|
||||
|
||||
#include <my_sys.h>
|
||||
#include <my_getopt.h>
|
||||
#include <mysql_version.h>
|
||||
#include <ndb_version.h>
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
#define NDB_STD_OPTS(prog_name) \
|
||||
{ "debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", \
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "usage", '?', "Display this help and exit.", \
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "help", '?', "Display this help and exit.", \
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "version", 'V', "Output version information and exit.", 0, 0, 0, \
|
||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "connect-string", 'c', \
|
||||
"Set connect string for connecting to ndb_mgmd. " \
|
||||
"<constr>=\"host=<hostname:port>[;nodeid=<id>]\". " \
|
||||
"Overides specifying entries in NDB_CONNECTSTRING and config file", \
|
||||
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
|
||||
#else
|
||||
#define NDB_STD_OPTS(prog_name) \
|
||||
{ "usage", '?', "Display this help and exit.", \
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "help", '?', "Display this help and exit.", \
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "version", 'V', "Output version information and exit.", 0, 0, 0, \
|
||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \
|
||||
{ "connect-string", 'c', \
|
||||
"Set connect string for connecting to ndb_mgmd. " \
|
||||
"<constr>=\"host=<hostname:port>[;nodeid=<id>]\". " \
|
||||
"Overides specifying entries in NDB_CONNECTSTRING and config file", \
|
||||
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }
|
||||
#endif
|
||||
|
||||
#endif /*_NDB_OPTS_H */
|
@ -138,6 +138,11 @@ rl_add_slash(char *path, char *p, size_t p_len)
|
||||
{
|
||||
struct stat Sb;
|
||||
|
||||
if (stat(path, &Sb) >= 0)
|
||||
(void)strlcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ", p_len);
|
||||
if (stat(path, &Sb) >= 0) {
|
||||
size_t len= strlen(p);
|
||||
if (len+1 < p_len) {
|
||||
p[len]= S_ISDIR(Sb.st_mode) ? '/' : ' ';
|
||||
p[len+1]= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ libgeneral_la_SOURCES = \
|
||||
SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
|
||||
OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \
|
||||
NdbSqlUtil.cpp new.cpp \
|
||||
uucode.c random.c getarg.c version.c \
|
||||
strdup.c strlcat.c strlcpy.c \
|
||||
uucode.c random.c version.c \
|
||||
strdup.c \
|
||||
ConfigValues.cpp ndb_init.c basestring_vsnprintf.c
|
||||
|
||||
include $(top_srcdir)/ndb/config/common.mk.am
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
#include <basestring_vsnprintf.h>
|
||||
#include <my_config.h>
|
||||
|
||||
int
|
||||
basestring_snprintf(char *str, size_t size, const char *format, ...)
|
||||
@ -30,8 +31,30 @@ basestring_snprintf(char *str, size_t size, const char *format, ...)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SNPRINTF
|
||||
#define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
|
||||
#else
|
||||
#define SNPRINTF_RETURN_TRUNC
|
||||
/* #define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) my_vsnprintf(a,b,c,d)
|
||||
* we would like to use my_vsnprintf but it does not have enough features
|
||||
* Let's hope vsnprintf works anyways
|
||||
*/
|
||||
#define BASESTRING_VSNPRINTF_FUNC(a,b,c,d) vsnprintf(a,b,c,d)
|
||||
extern int my_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
#ifdef SNPRINTF_RETURN_TRUNC
|
||||
static char basestring_vsnprintf_buf[16*1024];
|
||||
#endif
|
||||
int
|
||||
basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
return(vsnprintf(str, size, format, ap));
|
||||
int ret= BASESTRING_VSNPRINTF_FUNC(str, size, format, ap);
|
||||
#ifdef SNPRINTF_RETURN_TRUNC
|
||||
if (ret == size-1 || ret == -1) {
|
||||
ret= BASESTRING_VSNPRINTF_FUNC(basestring_vsnprintf_buf,
|
||||
sizeof(basestring_vsnprintf_buf),
|
||||
format, ap);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
@ -172,22 +172,21 @@ vprint_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
|
||||
const char * fmt, va_list ap){
|
||||
char buf[1000];
|
||||
char *buf2 = buf;
|
||||
size_t size = sizeof(buf);
|
||||
size_t size;
|
||||
|
||||
if (fmt != 0) {
|
||||
if (fmt != 0 && fmt[0] != 0) {
|
||||
size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
/* Check if the output was truncated */
|
||||
if(size >= sizeof(buf)) {
|
||||
buf2 = (char *)malloc(size+1);
|
||||
if(size > sizeof(buf)) {
|
||||
buf2 = (char *)malloc(size);
|
||||
if(buf2 == NULL)
|
||||
return -1;
|
||||
BaseString::vsnprintf(buf2, size, fmt, ap);
|
||||
} else
|
||||
size = sizeof(buf);
|
||||
}
|
||||
} else
|
||||
buf[0] = 0;
|
||||
return 0;
|
||||
|
||||
int ret = write_socket(socket, timeout_millis, buf2, strlen(buf2));
|
||||
int ret = write_socket(socket, timeout_millis, buf2, size);
|
||||
if(buf2 != buf)
|
||||
free(buf2);
|
||||
return ret;
|
||||
@ -199,23 +198,23 @@ vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
|
||||
const char * fmt, va_list ap){
|
||||
char buf[1000];
|
||||
char *buf2 = buf;
|
||||
size_t size = sizeof(buf);
|
||||
size_t size;
|
||||
|
||||
if (fmt != 0) {
|
||||
size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
if (fmt != 0 && fmt[0] != 0) {
|
||||
size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap)+1;// extra byte for '/n'
|
||||
/* Check if the output was truncated */
|
||||
if(size >= sizeof(buf)-1) {
|
||||
buf2 = (char *)malloc(size+2);
|
||||
if(size > sizeof(buf)) {
|
||||
buf2 = (char *)malloc(size);
|
||||
if(buf2 == NULL)
|
||||
return -1;
|
||||
BaseString::vsnprintf(buf2, size+1, fmt, ap);
|
||||
} else
|
||||
size = sizeof(buf);
|
||||
} else
|
||||
buf[0] = 0;
|
||||
strlcat(buf2, "\n", size+2);
|
||||
BaseString::vsnprintf(buf2, size, fmt, ap);
|
||||
}
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
buf2[size-1]='\n';
|
||||
|
||||
int ret = write_socket(socket, timeout_millis, buf2, strlen(buf2));
|
||||
int ret = write_socket(socket, timeout_millis, buf2, size);
|
||||
if(buf2 != buf)
|
||||
free(buf2);
|
||||
return ret;
|
||||
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ndb_global.h>
|
||||
|
||||
/* RCSID("$KTH: strlcat.c,v 1.1 2000/08/16 01:23:47 lha Exp $"); */
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
|
||||
size_t
|
||||
strlcat (char *dst, const char *src, size_t dst_sz)
|
||||
{
|
||||
size_t len = strlen(dst);
|
||||
|
||||
return len + strlcpy (dst + len, src, dst_sz - len);
|
||||
}
|
||||
#endif
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ndb_global.h>
|
||||
|
||||
/* RCSID("$KTH: strlcpy.c,v 1.1 2000/08/16 01:23:48 lha Exp $"); */
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
|
||||
size_t
|
||||
strlcpy (char *dst, const char *src, size_t dst_sz)
|
||||
{
|
||||
size_t n;
|
||||
char *p;
|
||||
|
||||
for (p = dst, n = 0;
|
||||
n + 1 < dst_sz && *src != '\0';
|
||||
++p, ++src, ++n)
|
||||
*p = *src;
|
||||
*p = '\0';
|
||||
if (*src == '\0')
|
||||
return n;
|
||||
else
|
||||
return n + strlen (src);
|
||||
}
|
||||
|
||||
#endif
|
@ -96,66 +96,3 @@ insert_file(const char * filename, class Properties& p){
|
||||
if(f) fclose(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
parse_config_file(struct getargs args[], int num_arg, const Properties& p){
|
||||
Properties::Iterator it(&p);
|
||||
for(const char * name = it.first(); name != 0; name = it.next()){
|
||||
bool found = false;
|
||||
for(int i = 0; i<num_arg; i++){
|
||||
if(strcmp(name, args[i].long_name) != 0)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
|
||||
const char * tmp;
|
||||
p.get(name, &tmp);
|
||||
|
||||
int t = 1;
|
||||
|
||||
switch(args[i].type){
|
||||
case arg_integer:{
|
||||
int val = atoi(tmp);
|
||||
if(args[i].value){
|
||||
*((int*)args[i].value) = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case arg_string:
|
||||
if(args[i].value){
|
||||
*((const char**)args[i].value) = tmp;
|
||||
}
|
||||
break;
|
||||
case arg_negative_flag:
|
||||
t = 0;
|
||||
case arg_flag:
|
||||
if(args[i].value){
|
||||
if(!strcasecmp(tmp, "y") ||
|
||||
!strcasecmp(tmp, "on") ||
|
||||
!strcasecmp(tmp, "true") ||
|
||||
!strcasecmp(tmp, "1")){
|
||||
*((int*)args[i].value) = t;
|
||||
}
|
||||
if(!strcasecmp(tmp, "n") ||
|
||||
!strcasecmp(tmp, "off") ||
|
||||
!strcasecmp(tmp, "false") ||
|
||||
!strcasecmp(tmp, "0")){
|
||||
*((int*)args[i].value) = t;
|
||||
}
|
||||
}
|
||||
t = 1;
|
||||
break;
|
||||
case arg_strings:
|
||||
case arg_double:
|
||||
case arg_collect:
|
||||
case arg_counter:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
printf("Unknown parameter: %s\n", name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include <logger/Logger.hpp>
|
||||
#if 0
|
||||
#include <getarg.h>
|
||||
#endif
|
||||
|
||||
extern int debug;
|
||||
|
||||
@ -30,6 +32,5 @@ int insert(const char * pair, class Properties & p);
|
||||
|
||||
int insert_file(const char * filename, class Properties&);
|
||||
int insert_file(FILE *, class Properties&, bool break_on_empty = false);
|
||||
int parse_config_file(struct getargs args[], int num_arg, const Properties& p);
|
||||
|
||||
#endif /* ! __CPCD_COMMON_HPP_INCLUDED__ */
|
||||
|
@ -15,13 +15,13 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h> /* Needed for mkdir(2) */
|
||||
#include <ndb_opts.h>
|
||||
|
||||
#include "CPCD.hpp"
|
||||
#include "APIService.hpp"
|
||||
#include <NdbMain.h>
|
||||
#include <NdbSleep.h>
|
||||
#include <BaseString.hpp>
|
||||
#include <getarg.h>
|
||||
#include <logger/Logger.hpp>
|
||||
#include <logger/FileLogHandler.hpp>
|
||||
#include <logger/SysLogHandler.hpp>
|
||||
@ -29,28 +29,44 @@
|
||||
#include "common.hpp"
|
||||
|
||||
static const char *work_dir = CPCD_DEFAULT_WORK_DIR;
|
||||
static int port = CPCD_DEFAULT_TCP_PORT;
|
||||
static int use_syslog = 0;
|
||||
static int port;
|
||||
static int use_syslog;
|
||||
static const char *logfile = NULL;
|
||||
static const char *config_file = CPCD_DEFAULT_CONFIG_FILE;
|
||||
static const char *user = 0;
|
||||
|
||||
static struct getargs args[] = {
|
||||
{ "work-dir", 'w', arg_string, &work_dir,
|
||||
"Work directory", "directory" },
|
||||
{ "port", 'p', arg_integer, &port,
|
||||
"TCP port to listen on", "port" },
|
||||
{ "syslog", 'S', arg_flag, &use_syslog,
|
||||
"Log events to syslog", NULL},
|
||||
{ "logfile", 'L', arg_string, &logfile,
|
||||
"File to log events to", "file"},
|
||||
{ "debug", 'D', arg_flag, &debug,
|
||||
"Enable debug mode", NULL},
|
||||
{ "config", 'c', arg_string, &config_file, "Config file", NULL },
|
||||
{ "user", 'u', arg_string, &user, "Run as user", NULL }
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{ "work-dir", 'w', "Work directory",
|
||||
(gptr*) &work_dir, (gptr*) &work_dir, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "port", 'p', "TCP port to listen on",
|
||||
(gptr*) &port, (gptr*) &port, 0,
|
||||
GET_INT, REQUIRED_ARG, CPCD_DEFAULT_TCP_PORT, 0, 0, 0, 0, 0 },
|
||||
{ "syslog", 'S', "Log events to syslog",
|
||||
(gptr*) &use_syslog, (gptr*) &use_syslog, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "logfile", 'L', "File to log events to",
|
||||
(gptr*) &logfile, (gptr*) &logfile, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "debug", 'D', "Enable debug mode",
|
||||
(gptr*) &debug, (gptr*) &debug, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "config", 'c', "Config file",
|
||||
(gptr*) &config_file, (gptr*) &config_file, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "user", 'u', "Run as user",
|
||||
(gptr*) &user, (gptr*) &user, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static const int num_args = sizeof(args) / sizeof(args[0]);
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CPCD * g_cpcd = 0;
|
||||
#if 0
|
||||
@ -59,23 +75,16 @@ extern "C" static void sig_child(int signo, siginfo_t*, void*);
|
||||
|
||||
const char *progname = "ndb_cpcd";
|
||||
|
||||
NDB_MAIN(ndb_cpcd){
|
||||
int optind = 0;
|
||||
int main(int argc, char** argv){
|
||||
int save_argc= argc;
|
||||
char** save_argv= argv;
|
||||
const char *load_default_groups[]= { "ndb_cpcd",0 };
|
||||
MY_INIT(argv[0]);
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optind)) {
|
||||
arg_printusage(args, num_args, progname, "");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Properties p;
|
||||
insert_file(config_file, p);
|
||||
if(parse_config_file(args, num_args, p)){
|
||||
ndbout_c("Invalid config file: %s", config_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optind)) {
|
||||
arg_printusage(args, num_args, progname, "");
|
||||
load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
|
||||
if (handle_options(&argc, &argv, my_long_options, get_one_option)) {
|
||||
my_print_help(my_long_options);
|
||||
my_print_variables(my_long_options);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,8 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <getarg.h>
|
||||
#include <ndb_global.h>
|
||||
#include <ndb_opts.h>
|
||||
#include <Vector.hpp>
|
||||
#include <ndb_limits.h>
|
||||
#include <NdbTCP.h>
|
||||
@ -35,80 +36,107 @@ static Vector<class BackupConsumer *> g_consumers;
|
||||
|
||||
static const char* ga_backupPath = "." DIR_SEPARATOR;
|
||||
|
||||
static const char* ga_connect_NDB = NULL;
|
||||
static const char* opt_connect_str= NULL;
|
||||
|
||||
/**
|
||||
* print and restore flags
|
||||
*/
|
||||
static bool ga_restore = false;
|
||||
static bool ga_print = false;
|
||||
bool
|
||||
readArguments(const int argc, const char** argv)
|
||||
static int _print = 0;
|
||||
static int _print_meta = 0;
|
||||
static int _print_data = 0;
|
||||
static int _print_log = 0;
|
||||
static int _restore_data = 0;
|
||||
static int _restore_meta = 0;
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
NDB_STD_OPTS("ndb_restore"),
|
||||
{ "connect", 'c', "same as --connect-string",
|
||||
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "nodeid", 'n', "Backup files from node with id",
|
||||
(gptr*) &ga_nodeId, (gptr*) &ga_nodeId, 0,
|
||||
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "backupid", 'b', "Backup id",
|
||||
(gptr*) &ga_backupId, (gptr*) &ga_backupId, 0,
|
||||
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "restore_data", 'r',
|
||||
"Restore table data/logs into NDB Cluster using NDBAPI",
|
||||
(gptr*) &_restore_data, (gptr*) &_restore_data, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "restore_meta", 'm',
|
||||
"Restore meta data into NDB Cluster using NDBAPI",
|
||||
(gptr*) &_restore_meta, (gptr*) &_restore_meta, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "parallelism", 'p',
|
||||
"No of parallel transactions during restore of data."
|
||||
"(parallelism can be 1 to 1024)",
|
||||
(gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0,
|
||||
GET_INT, REQUIRED_ARG, 128, 0, 0, 0, 0, 0 },
|
||||
{ "print", 256, "Print data and log to stdout",
|
||||
(gptr*) &_print, (gptr*) &_print, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "print_data", 257, "Print data to stdout",
|
||||
(gptr*) &_print_data, (gptr*) &_print_data, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "print_meta", 258, "Print meta data to stdout",
|
||||
(gptr*) &_print_meta, (gptr*) &_print_meta, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "print_log", 259, "Print log to stdout",
|
||||
(gptr*) &_print_log, (gptr*) &_print_log, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "dont_ignore_systab_0", 'f',
|
||||
"Experimental. Do not ignore system table during restore.",
|
||||
(gptr*) &ga_dont_ignore_systab_0, (gptr*) &ga_dont_ignore_systab_0, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int _print = 0;
|
||||
int _print_meta = 0;
|
||||
int _print_data = 0;
|
||||
int _print_log = 0;
|
||||
int _restore_data = 0;
|
||||
int _restore_meta = 0;
|
||||
|
||||
|
||||
struct getargs args[] =
|
||||
{
|
||||
{ "connect", 'c', arg_string, &ga_connect_NDB,
|
||||
"NDB Cluster connection", "\"nodeid=<api id>;host=<hostname:port>\""},
|
||||
{ "nodeid", 'n', arg_integer, &ga_nodeId,
|
||||
"Backup files from node", "db node id"},
|
||||
{ "backupid", 'b',arg_integer, &ga_backupId, "Backup id", "backup id"},
|
||||
{ "print", '\0', arg_flag, &_print,
|
||||
"Print data and log to stdout", "print data and log"},
|
||||
{ "print_data", '\0', arg_flag, &_print_data,
|
||||
"Print data to stdout", "print data"},
|
||||
{ "print_meta", '\0', arg_flag, &_print_meta,
|
||||
"Print meta data to stdout", "print meta data"},
|
||||
{ "print_log", '\0', arg_flag, &_print_log,
|
||||
"Print log to stdout", "print log"},
|
||||
{ "restore_data", 'r', arg_flag, &_restore_data,
|
||||
"Restore table data/logs into NDB Cluster using NDBAPI",
|
||||
"Restore table data/log"},
|
||||
{ "restore_meta", 'm', arg_flag, &_restore_meta,
|
||||
"Restore meta data into NDB Cluster using NDBAPI", "Restore meta data"},
|
||||
{ "parallelism", 'p', arg_integer, &ga_nParallelism,
|
||||
"No of parallel transactions during restore of data."
|
||||
"(parallelism can be 1 to 1024)",
|
||||
"Parallelism"},
|
||||
#ifdef USE_MYSQL
|
||||
{ "use_mysql", '\0', arg_flag, &use_mysql,
|
||||
"Restore meta data via mysql. Systab will be ignored. Data is restored "
|
||||
"using NDBAPI.", "use mysql"},
|
||||
{ "user", '\0', arg_string, &ga_user, "MySQL user", "Default: root"},
|
||||
{ "password", '\0', arg_string, &ga_password, "MySQL user's password",
|
||||
"Default: \"\" "},
|
||||
{ "host", '\0', arg_string, &ga_host, "Hostname of MySQL server",
|
||||
"Default: localhost"},
|
||||
{ "socket", '\0', arg_string, &ga_socket, "Path to MySQL server socket file",
|
||||
"Default: /tmp/mysql.sock"},
|
||||
{ "port", '\0', arg_integer, &ga_port, "Port number of MySQL server",
|
||||
"Default: 3306"},
|
||||
#endif
|
||||
{ "dont_ignore_systab_0", 'f', arg_flag, &ga_dont_ignore_systab_0,
|
||||
"Experimental. Do not ignore system table during restore.",
|
||||
"dont_ignore_systab_0"}
|
||||
|
||||
};
|
||||
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
int optind = 0;
|
||||
|
||||
if (getarg(args, num_args, argc, argv, &optind) ||
|
||||
static void short_usage_sub(void)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS] [<path to backup files>]\n", my_progname);
|
||||
}
|
||||
static void print_version()
|
||||
{
|
||||
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
}
|
||||
static void usage()
|
||||
{
|
||||
short_usage_sub();
|
||||
print_version();
|
||||
my_print_help(my_long_options);
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
switch (optid) {
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_restore.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
bool
|
||||
readArguments(int *pargc, char*** pargv)
|
||||
{
|
||||
const char *load_default_groups[]= { "ndb_tools","ndb_restore",0 };
|
||||
load_defaults("my",load_default_groups,pargc,pargv);
|
||||
if (handle_options(pargc, pargv, my_long_options, get_one_option) ||
|
||||
ga_nodeId == 0 ||
|
||||
ga_backupId == 0 ||
|
||||
ga_nParallelism < 1 ||
|
||||
ga_nParallelism >1024)
|
||||
{
|
||||
arg_printusage(args, num_args, argv[0], "<path to backup files>\n");
|
||||
return false;
|
||||
ga_nParallelism >1024) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
BackupPrinter* printer = new BackupPrinter();
|
||||
@ -122,10 +150,6 @@ readArguments(const int argc, const char** argv)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Got segmentation fault when using the printer's attributes directly
|
||||
* in getargs... Do not have the time to found out why... this is faster...
|
||||
*/
|
||||
if (_print)
|
||||
{
|
||||
ga_print = true;
|
||||
@ -169,15 +193,14 @@ readArguments(const int argc, const char** argv)
|
||||
g_consumers.push_back(c);
|
||||
}
|
||||
// Set backup file path
|
||||
if (argv[optind] != NULL)
|
||||
if (*pargv[0] != NULL)
|
||||
{
|
||||
ga_backupPath = argv[optind];
|
||||
ga_backupPath = *pargv[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
clearConsumers()
|
||||
{
|
||||
@ -204,19 +227,16 @@ free_data_callback()
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char** argv)
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ndb_init();
|
||||
if (!readArguments(argc, argv))
|
||||
NDB_INIT(argv[0]);
|
||||
|
||||
if (!readArguments(&argc, &argv))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ga_connect_NDB != NULL)
|
||||
{
|
||||
// Use connection string
|
||||
Ndb::setConnectString(ga_connect_NDB);
|
||||
}
|
||||
Ndb::setConnectString(opt_connect_str);
|
||||
|
||||
/**
|
||||
* we must always load meta data, even if we will only print it to stdout
|
||||
|
@ -3661,9 +3661,8 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
|
||||
req->tableId = tabPtr.i;
|
||||
req->tableVersion = tabEntry->m_tableVersion + 1;
|
||||
|
||||
sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
|
||||
CreateTabReq::SignalLength, JBB);
|
||||
|
||||
sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal,
|
||||
CreateTabReq::SignalLength, JBB);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ ErrorReporter::formatMessage(ErrorCategory type,
|
||||
faultID,
|
||||
(problemData == NULL) ? "" : problemData,
|
||||
objRef,
|
||||
programName,
|
||||
my_progname,
|
||||
processId,
|
||||
theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>");
|
||||
|
||||
|
@ -53,11 +53,9 @@ extern "C" void handler_error(int signum); // for process signal handling
|
||||
void systemInfo(const Configuration & conf,
|
||||
const LogLevel & ll);
|
||||
|
||||
const char programName[] = "NDB Kernel";
|
||||
|
||||
NDB_MAIN(ndb_kernel){
|
||||
|
||||
ndb_init();
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
NDB_INIT(argv[0]);
|
||||
// Print to stdout/console
|
||||
g_eventLogger.createConsoleHandler();
|
||||
g_eventLogger.setCategory("NDB");
|
||||
|
@ -15,6 +15,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include <ndb_opts.h>
|
||||
|
||||
#include <LocalConfig.hpp>
|
||||
#include "Configuration.hpp"
|
||||
@ -28,8 +29,6 @@
|
||||
#include <NdbOut.hpp>
|
||||
#include <WatchDog.hpp>
|
||||
|
||||
#include <getarg.h>
|
||||
|
||||
#include <mgmapi_configuration.hpp>
|
||||
#include <mgmapi_config_parameters_debug.h>
|
||||
#include <kernel_config_parameters.h>
|
||||
@ -47,81 +46,86 @@ extern "C" {
|
||||
#include <EventLogger.hpp>
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
bool
|
||||
Configuration::init(int argc, const char** argv){
|
||||
|
||||
/**
|
||||
* Default values for arguments
|
||||
*/
|
||||
int _no_start = 0;
|
||||
int _initial = 0;
|
||||
const char* _connect_str = NULL;
|
||||
int _daemon = 1;
|
||||
int _no_daemon = 0;
|
||||
int _help = 0;
|
||||
int _print_version = 0;
|
||||
#ifndef DBUG_OFF
|
||||
const char *debug_option= 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Arguments to NDB process
|
||||
*/
|
||||
|
||||
struct getargs args[] = {
|
||||
{ "version", 'v', arg_flag, &_print_version, "Print ndbd version", "" },
|
||||
{ "nostart", 'n', arg_flag, &_no_start,
|
||||
"Don't start ndbd immediately. Ndbd will await command from ndb_mgmd", "" },
|
||||
{ "daemon", 'd', arg_flag, &_daemon, "Start ndbd as daemon (default)", "" },
|
||||
{ "nodaemon", 0, arg_flag, &_no_daemon, "Do not start ndbd as daemon, provided for testing purposes", "" },
|
||||
#ifndef DBUG_OFF
|
||||
{ "debug", 0, arg_string, &debug_option,
|
||||
"Specify debug options e.g. d:t:i:o,out.trace", "options" },
|
||||
#endif
|
||||
{ "initial", 0, arg_flag, &_initial,
|
||||
"Perform initial start of ndbd, including cleaning the file system. Consult documentation before using this", "" },
|
||||
|
||||
{ "connect-string", 'c', arg_string, &_connect_str,
|
||||
"Set connect string for connecting to ndb_mgmd. <constr>=\"host=<hostname:port>[;nodeid=<id>]\". Overides specifying entries in NDB_CONNECTSTRING and config file",
|
||||
"<constr>" },
|
||||
{ "usage", '?', arg_flag, &_help, "Print help", "" }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
int optind = 0;
|
||||
char desc[] =
|
||||
"The MySQL Cluster kernel";
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optind) || _help) {
|
||||
arg_printusage(args, num_args, argv[0], desc);
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (strcmp("-i",argv[i]) == 0) {
|
||||
printf("flag depricated %s, use %s\n", "-i", "--initial");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
static const char* opt_connect_str= 0;
|
||||
static int _daemon, _no_daemon, _initial, _no_start;
|
||||
/**
|
||||
* Arguments to NDB process
|
||||
*/
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
NDB_STD_OPTS("ndbd"),
|
||||
{ "initial", 256,
|
||||
"Perform initial start of ndbd, including cleaning the file system. "
|
||||
"Consult documentation before using this",
|
||||
(gptr*) &_initial, (gptr*) &_initial, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "nostart", 'n',
|
||||
"Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
|
||||
(gptr*) &_no_start, (gptr*) &_no_start, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "daemon", 'd', "Start ndbd as daemon (default)",
|
||||
(gptr*) &_daemon, (gptr*) &_daemon, 0,
|
||||
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
|
||||
{ "nodaemon", 257,
|
||||
"Do not start ndbd as daemon, provided for testing purposes",
|
||||
(gptr*) &_no_daemon, (gptr*) &_no_daemon, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
static void short_usage_sub(void)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n", my_progname);
|
||||
}
|
||||
static void print_version()
|
||||
{
|
||||
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
}
|
||||
static void usage()
|
||||
{
|
||||
short_usage_sub();
|
||||
print_version();
|
||||
my_print_help(my_long_options);
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
switch (optid) {
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndbd.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Configuration::init(int argc, char** argv)
|
||||
{
|
||||
const char *load_default_groups[]= { "ndbd",0 };
|
||||
load_defaults("my",load_default_groups,&argc,&argv);
|
||||
|
||||
int ho_error;
|
||||
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
|
||||
if (_no_daemon) {
|
||||
_daemon= 0;
|
||||
}
|
||||
// check for depricated flag '-i'
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (debug_option)
|
||||
DBUG_PUSH(debug_option);
|
||||
#endif
|
||||
|
||||
DBUG_PRINT("info", ("no_start=%d", _no_start));
|
||||
DBUG_PRINT("info", ("initial=%d", _initial));
|
||||
DBUG_PRINT("info", ("daemon=%d", _daemon));
|
||||
DBUG_PRINT("info", ("connect_str=%s", _connect_str));
|
||||
DBUG_PRINT("info", ("connect_str=%s", opt_connect_str));
|
||||
|
||||
ndbSetOwnVersion();
|
||||
|
||||
if (_print_version) {
|
||||
ndbPrintVersion();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the start flag
|
||||
if (_no_start)
|
||||
globalData.theRestartFlag = initial_state;
|
||||
@ -133,8 +137,8 @@ Configuration::init(int argc, const char** argv){
|
||||
_initialStart = true;
|
||||
|
||||
// Check connectstring
|
||||
if (_connect_str)
|
||||
_connectString = strdup(_connect_str);
|
||||
if (opt_connect_str)
|
||||
_connectString = strdup(opt_connect_str);
|
||||
|
||||
// Check daemon flag
|
||||
if (_daemon)
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
/**
|
||||
* Returns false if arguments are invalid
|
||||
*/
|
||||
bool init(int argc, const char** argv);
|
||||
bool init(int argc, char** argv);
|
||||
|
||||
void fetch_configuration(LocalConfig &local_config);
|
||||
void setupConfiguration();
|
||||
|
@ -25,6 +25,7 @@
|
||||
//
|
||||
//===========================================================================
|
||||
#include <kernel_types.h>
|
||||
#include <TransporterRegistry.hpp>
|
||||
|
||||
extern class JobTable globalJobTable;
|
||||
extern class TimeQueue globalTimeQueue;
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
struct SectionSegment {
|
||||
|
||||
STATIC_CONST( DataLength = 60 );
|
||||
STATIC_CONST( DataLength = NDB_SECTION_SEGMENT_SZ );
|
||||
|
||||
Uint32 m_ownerRef;
|
||||
Uint32 m_sz;
|
||||
|
@ -15,11 +15,12 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include <ndb_opts.h>
|
||||
|
||||
#include <NdbMain.h>
|
||||
#include <NdbHost.h>
|
||||
#include <util/getarg.h>
|
||||
#include <mgmapi.h>
|
||||
#include <ndb_version.h>
|
||||
#include <LocalConfig.hpp>
|
||||
|
||||
#include "CommandInterpreter.hpp"
|
||||
@ -43,28 +44,62 @@ handler(int sig){
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
ndb_init();
|
||||
int optind = 0;
|
||||
|
||||
static unsigned _try_reconnect;
|
||||
static char *opt_connect_str= 0;
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
NDB_STD_OPTS("ndb_mgm"),
|
||||
{ "try-reconnect", 't',
|
||||
"Specify number of retries for connecting to ndb_mgmd, default infinite",
|
||||
(gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0,
|
||||
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
static void short_usage_sub(void)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS] [hostname [port]]\n", my_progname);
|
||||
}
|
||||
static void print_version()
|
||||
{
|
||||
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
}
|
||||
static void usage()
|
||||
{
|
||||
short_usage_sub();
|
||||
print_version();
|
||||
my_print_help(my_long_options);
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
switch (optid) {
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_mgm.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv){
|
||||
NDB_INIT(argv[0]);
|
||||
const char *_host = 0;
|
||||
int _port = 0;
|
||||
int _help = 0;
|
||||
int _try_reconnect = 0;
|
||||
|
||||
struct getargs args[] = {
|
||||
{ "try-reconnect", 't', arg_integer, &_try_reconnect, "Specify number of retries for connecting to ndb_mgmd, default infinite", "#" },
|
||||
{ "usage", '?', arg_flag, &_help, "Print help", "" },
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]); /* Number of arguments */
|
||||
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optind) || _help) {
|
||||
arg_printusage(args, num_args, progname, "[host [port]]");
|
||||
exit(1);
|
||||
}
|
||||
const char *load_default_groups[]= { "ndb_mgm",0 };
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
load_defaults("my",load_default_groups,&argc,&argv);
|
||||
int ho_error;
|
||||
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
|
||||
LocalConfig cfg;
|
||||
|
||||
@ -74,7 +109,7 @@ int main(int argc, const char** argv){
|
||||
_port = atoi(argv[1]);
|
||||
}
|
||||
} else {
|
||||
if(cfg.init(0, 0) && cfg.ids.size() > 0 && cfg.ids[0].type == MgmId_TCP){
|
||||
if(cfg.init(opt_connect_str, 0) && cfg.ids.size() > 0 && cfg.ids[0].type == MgmId_TCP){
|
||||
_host = cfg.ids[0].name.c_str();
|
||||
_port = cfg.ids[0].port;
|
||||
} else {
|
||||
|
@ -407,7 +407,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
|
||||
// signals to other management servers.
|
||||
_ownReference(0),
|
||||
m_local_config(local_config),
|
||||
m_allocated_resources(*this),
|
||||
theSignalIdleList(NULL),
|
||||
theWaitState(WAIT_SUBSCRIBE_CONF),
|
||||
m_statisticsListner(this)
|
||||
@ -480,6 +479,13 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
|
||||
_ownNodeId= 0;
|
||||
NodeId tmp= nodeId;
|
||||
BaseString error_string;
|
||||
|
||||
if ((m_node_id_mutex = NdbMutex_Create()) == 0)
|
||||
{
|
||||
ndbout << "mutex creation failed line = " << __LINE__ << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
char my_hostname[256];
|
||||
struct sockaddr_in tmp_addr;
|
||||
@ -512,7 +518,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
|
||||
#endif
|
||||
_ownNodeId = tmp;
|
||||
|
||||
|
||||
{
|
||||
DBUG_PRINT("info", ("verifyConfig"));
|
||||
ConfigRetriever cr(m_local_config, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
|
||||
@ -534,12 +539,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
|
||||
m_statisticsListner.m_logLevel = se.m_logLevel;
|
||||
}
|
||||
|
||||
if ((m_node_id_mutex = NdbMutex_Create()) == 0)
|
||||
{
|
||||
ndbout << "mutex creation failed line = " << __LINE__ << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -534,7 +534,6 @@ private:
|
||||
Uint32 m_nextConfigGenerationNumber;
|
||||
|
||||
NodeBitmask m_reserved_nodes;
|
||||
Allocated_resources m_allocated_resources;
|
||||
struct in_addr m_connect_address[MAX_NODES];
|
||||
|
||||
//**************************************************************************
|
||||
|
@ -773,8 +773,10 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
|
||||
|
||||
/* XXX should use constants for this value */
|
||||
if(level > 15) {
|
||||
errorString.assign("Invalied loglevel");
|
||||
goto error;
|
||||
m_output->println("set cluster loglevel reply");
|
||||
m_output->println("result: Invalid loglevel");
|
||||
m_output->println("");
|
||||
return;
|
||||
}
|
||||
|
||||
EventSubscribeReq req;
|
||||
@ -786,11 +788,6 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
|
||||
m_output->println("set cluster loglevel reply");
|
||||
m_output->println("result: Ok");
|
||||
m_output->println("");
|
||||
return;
|
||||
error:
|
||||
m_output->println("set cluster loglevel reply");
|
||||
m_output->println("result: %s", errorString.c_str());
|
||||
m_output->println("");
|
||||
}
|
||||
|
||||
void
|
||||
@ -807,8 +804,10 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
|
||||
|
||||
/* XXX should use constants for this value */
|
||||
if(level > 15) {
|
||||
errorString.assign("Invalied loglevel");
|
||||
goto error;
|
||||
m_output->println("set loglevel reply");
|
||||
m_output->println("result: Invalid loglevel", errorString.c_str());
|
||||
m_output->println("");
|
||||
return;
|
||||
}
|
||||
|
||||
EventSubscribeReq req;
|
||||
@ -820,11 +819,6 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
|
||||
m_output->println("set loglevel reply");
|
||||
m_output->println("result: Ok");
|
||||
m_output->println("");
|
||||
return;
|
||||
error:
|
||||
m_output->println("set loglevel reply");
|
||||
m_output->println("result: %s", errorString.c_str());
|
||||
m_output->println("");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,6 +15,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <ndb_global.h>
|
||||
#include <ndb_opts.h>
|
||||
|
||||
#include "MgmtSrvr.hpp"
|
||||
#include "EventLogger.hpp"
|
||||
@ -33,7 +34,6 @@
|
||||
#include <ndb_version.h>
|
||||
#include <ConfigRetriever.hpp>
|
||||
#include <mgmapi_config_parameters.h>
|
||||
#include <getarg.h>
|
||||
|
||||
#include <NdbAutoPtr.hpp>
|
||||
|
||||
@ -97,41 +97,93 @@ bool g_StopServer;
|
||||
extern EventLogger g_EventLogger;
|
||||
|
||||
extern int global_mgmt_server_check;
|
||||
int _print_version = 0;
|
||||
#ifndef DBUG_OFF
|
||||
const char *debug_option= 0;
|
||||
#endif
|
||||
static char *opt_connect_str= 0;
|
||||
|
||||
struct getargs args[] = {
|
||||
{ "version", 'v', arg_flag, &_print_version,
|
||||
"Print ndb_mgmd version",""},
|
||||
{ "config-file", 'c', arg_string, &glob.config_filename,
|
||||
"Specify cluster configuration file (default config.ini if available)",
|
||||
"filename"},
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
{ "debug", 0, arg_string, &debug_option,
|
||||
"Specify debug options e.g. d:t:i:o,out.trace", "options"},
|
||||
{ "debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
#endif
|
||||
{ "daemon", 'd', arg_flag, &glob.daemon,
|
||||
"Run ndb_mgmd in daemon mode (default)",""},
|
||||
{ NULL, 'l', arg_string, &glob.local_config_filename,
|
||||
"Specify configuration file connect string (default Ndb.cfg if available)",
|
||||
"filename"},
|
||||
{ "interactive", 0, arg_flag, &glob.interactive,
|
||||
"Run interactive. Not supported but provided for testing purposes", ""},
|
||||
{ "no-nodeid-checks", 0, arg_flag, &g_no_nodeid_checks,
|
||||
"Do not provide any node id checks", ""},
|
||||
{ "nodaemon", 0, arg_flag, &glob.non_interactive,
|
||||
"Don't run as daemon, but don't read from stdin", "non-interactive"}
|
||||
{ "usage", '?', "Display this help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "help", '?', "Display this help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "version", 'V', "Output version information and exit.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "connect-string", 1023,
|
||||
"Set connect string for connecting to ndb_mgmd. "
|
||||
"<constr>=\"host=<hostname:port>[;nodeid=<id>]\". "
|
||||
"Overides specifying entries in NDB_CONNECTSTRING and config file",
|
||||
(gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "config-file", 'f', "Specify cluster configuration file",
|
||||
(gptr*) &glob.config_filename, (gptr*) &glob.config_filename, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "daemon", 'd', "Run ndb_mgmd in daemon mode (default)",
|
||||
(gptr*) &glob.daemon, (gptr*) &glob.daemon, 0,
|
||||
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
|
||||
{ "l", 'l', "Specify configuration file connect string (default Ndb.cfg if available)",
|
||||
(gptr*) &glob.local_config_filename, (gptr*) &glob.local_config_filename, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "interactive", 256, "Run interactive. Not supported but provided for testing purposes",
|
||||
(gptr*) &glob.interactive, (gptr*) &glob.interactive, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "no-nodeid-checks", 257, "Do not provide any node id checks",
|
||||
(gptr*) &g_no_nodeid_checks, (gptr*) &g_no_nodeid_checks, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "nodaemon", 258, "Don't run as daemon, but don't read from stdin",
|
||||
(gptr*) &glob.non_interactive, (gptr*) &glob.non_interactive, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "config-file", 'c',
|
||||
"-c provided for backwards compatability, will be removed in 5.0."
|
||||
" Use -f instead",
|
||||
(gptr*) &glob.config_filename, (gptr*) &glob.config_filename, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
static void short_usage_sub(void)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n", my_progname);
|
||||
}
|
||||
static void print_version()
|
||||
{
|
||||
printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
|
||||
}
|
||||
static void usage()
|
||||
{
|
||||
short_usage_sub();
|
||||
print_version();
|
||||
my_print_help(my_long_options);
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
{
|
||||
switch (optid) {
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_mgmd.trace");
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
case 'c':
|
||||
printf("Warning: -c will be removed in 5.0, use -f instead\n");
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MAIN
|
||||
*/
|
||||
NDB_MAIN(mgmsrv){
|
||||
ndb_init();
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
NDB_INIT(argv[0]);
|
||||
|
||||
/**
|
||||
* OSE specific. Enable shared ownership of file system resources.
|
||||
@ -143,31 +195,20 @@ NDB_MAIN(mgmsrv){
|
||||
#endif
|
||||
|
||||
global_mgmt_server_check = 1;
|
||||
glob.config_filename= "config.ini";
|
||||
|
||||
int optind = 0;
|
||||
if(getarg(args, num_args, argc, argv, &optind)) {
|
||||
arg_printusage(args, num_args, progname, "");
|
||||
exit(1);
|
||||
}
|
||||
const char *load_default_groups[]= { "ndb_mgmd",0 };
|
||||
load_defaults("my",load_default_groups,&argc,&argv);
|
||||
|
||||
int ho_error;
|
||||
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
|
||||
if (glob.interactive ||
|
||||
glob.non_interactive) {
|
||||
glob.daemon= 0;
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (debug_option)
|
||||
DBUG_PUSH(debug_option);
|
||||
#endif
|
||||
|
||||
if (_print_version) {
|
||||
ndbPrintVersion();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(glob.config_filename == NULL) {
|
||||
glob.config_filename= "config.ini";
|
||||
}
|
||||
glob.socketServer = new SocketServer();
|
||||
|
||||
MgmApiService * mapi = new MgmApiService();
|
||||
|
@ -1386,6 +1386,7 @@ Ndb::printState(const char* fmt, ...)
|
||||
va_end(ap);
|
||||
NdbMutex_Lock(ndb_print_state_mutex);
|
||||
bool dups = false;
|
||||
unsigned i;
|
||||
ndbout << buf << " ndb=" << hex << this << dec;
|
||||
#ifndef NDB_WIN32
|
||||
ndbout << " thread=" << (int)pthread_self();
|
||||
@ -1406,21 +1407,21 @@ Ndb::printState(const char* fmt, ...)
|
||||
ndbout << "!! DUPS !!" << endl;
|
||||
dups = true;
|
||||
}
|
||||
for (unsigned i = 0; i < theNoOfPreparedTransactions; i++)
|
||||
for (i = 0; i < theNoOfPreparedTransactions; i++)
|
||||
thePreparedTransactionsArray[i]->printState();
|
||||
ndbout << "sent: " << theNoOfSentTransactions<< endl;
|
||||
if (checkdups(theSentTransactionsArray, theNoOfSentTransactions)) {
|
||||
ndbout << "!! DUPS !!" << endl;
|
||||
dups = true;
|
||||
}
|
||||
for (unsigned i = 0; i < theNoOfSentTransactions; i++)
|
||||
for (i = 0; i < theNoOfSentTransactions; i++)
|
||||
theSentTransactionsArray[i]->printState();
|
||||
ndbout << "completed: " << theNoOfCompletedTransactions<< endl;
|
||||
if (checkdups(theCompletedTransactionsArray, theNoOfCompletedTransactions)) {
|
||||
ndbout << "!! DUPS !!" << endl;
|
||||
dups = true;
|
||||
}
|
||||
for (unsigned i = 0; i < theNoOfCompletedTransactions; i++)
|
||||
for (i = 0; i < theNoOfCompletedTransactions; i++)
|
||||
theCompletedTransactionsArray[i]->printState();
|
||||
NdbMutex_Unlock(ndb_print_state_mutex);
|
||||
}
|
||||
|
@ -33,21 +33,24 @@
|
||||
ndbout << prefix << " " << hex << (void*)this << " " << cname; \
|
||||
ndbout << " " << dec << __LINE__ << " " << x << " " << *this << endl; \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(x)
|
||||
#endif
|
||||
|
||||
static char*
|
||||
ndb_blob_debug(const Uint32* data, unsigned size)
|
||||
{
|
||||
static char buf[128 + 1]; // MT irrelevant
|
||||
static char buf[200]; // MT irrelevant
|
||||
buf[0] = 0;
|
||||
for (unsigned i = 0; i < size && i < 128 / 4; i++) {
|
||||
sprintf(buf + strlen(buf), "%*s%08x", i != 0, "", data[i]);
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
unsigned n = strlen(buf);
|
||||
if (n + 10 < sizeof(buf))
|
||||
sprintf(buf + n, "%*s%08x", i != 0, "", data[i]);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
#else
|
||||
#define DBG(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reading index table directly (as a table) is faster but there are
|
||||
* bugs or limitations. Keep the code and make possible to choose.
|
||||
@ -94,6 +97,14 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
|
||||
bt.setName(btname);
|
||||
bt.setLogging(t->getLogging());
|
||||
bt.setFragmentType(t->getFragmentType());
|
||||
{ NdbDictionary::Column bc("PK");
|
||||
bc.setType(NdbDictionary::Column::Unsigned);
|
||||
assert(t->m_sizeOfKeysInWords != 0);
|
||||
bc.setLength(t->m_sizeOfKeysInWords);
|
||||
bc.setPrimaryKey(true);
|
||||
bc.setDistributionKey(true);
|
||||
bt.addColumn(bc);
|
||||
}
|
||||
{ NdbDictionary::Column bc("DIST");
|
||||
bc.setType(NdbDictionary::Column::Unsigned);
|
||||
bc.setPrimaryKey(true);
|
||||
@ -103,13 +114,7 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
|
||||
{ NdbDictionary::Column bc("PART");
|
||||
bc.setType(NdbDictionary::Column::Unsigned);
|
||||
bc.setPrimaryKey(true);
|
||||
bt.addColumn(bc);
|
||||
}
|
||||
{ NdbDictionary::Column bc("PK");
|
||||
bc.setType(NdbDictionary::Column::Unsigned);
|
||||
assert(t->m_sizeOfKeysInWords != 0);
|
||||
bc.setLength(t->m_sizeOfKeysInWords);
|
||||
bc.setPrimaryKey(true);
|
||||
bc.setDistributionKey(false);
|
||||
bt.addColumn(bc);
|
||||
}
|
||||
{ NdbDictionary::Column bc("DATA");
|
||||
@ -162,6 +167,7 @@ NdbBlob::init()
|
||||
theHead = NULL;
|
||||
theInlineData = NULL;
|
||||
theHeadInlineRecAttr = NULL;
|
||||
theHeadInlineReadOp = NULL;
|
||||
theHeadInlineUpdateFlag = false;
|
||||
theNullFlag = -1;
|
||||
theLength = 0;
|
||||
@ -206,6 +212,13 @@ NdbBlob::Buf::alloc(unsigned n)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
NdbBlob::Buf::copyfrom(const NdbBlob::Buf& src)
|
||||
{
|
||||
assert(size == src.size);
|
||||
memcpy(data, src.data, size);
|
||||
}
|
||||
|
||||
// classify operations (inline)
|
||||
|
||||
inline bool
|
||||
@ -226,6 +239,7 @@ NdbBlob::isKeyOp()
|
||||
return
|
||||
theNdbOp->theOperationType == NdbOperation::InsertRequest ||
|
||||
theNdbOp->theOperationType == NdbOperation::UpdateRequest ||
|
||||
theNdbOp->theOperationType == NdbOperation::WriteRequest ||
|
||||
theNdbOp->theOperationType == NdbOperation::ReadRequest ||
|
||||
theNdbOp->theOperationType == NdbOperation::ReadExclusive ||
|
||||
theNdbOp->theOperationType == NdbOperation::DeleteRequest;
|
||||
@ -253,6 +267,13 @@ NdbBlob::isUpdateOp()
|
||||
theNdbOp->theOperationType == NdbOperation::UpdateRequest;
|
||||
}
|
||||
|
||||
inline bool
|
||||
NdbBlob::isWriteOp()
|
||||
{
|
||||
return
|
||||
theNdbOp->theOperationType == NdbOperation::WriteRequest;
|
||||
}
|
||||
|
||||
inline bool
|
||||
NdbBlob::isDeleteOp()
|
||||
{
|
||||
@ -373,9 +394,10 @@ NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
|
||||
Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_sizeOfKeysInWords;
|
||||
DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size));
|
||||
if (anOp->equal((Uint32)0, getDistKey(part)) == -1 ||
|
||||
anOp->equal((Uint32)1, part) == -1 ||
|
||||
anOp->equal((Uint32)2, theKeyBuf.data) == -1) {
|
||||
// TODO use attr ids after compatibility with 4.1.7 not needed
|
||||
if (anOp->equal("PK", theKeyBuf.data) == -1 ||
|
||||
anOp->equal("DIST", getDistKey(part)) == -1 ||
|
||||
anOp->equal("PART", part) == -1) {
|
||||
setErrorCode(anOp);
|
||||
return -1;
|
||||
}
|
||||
@ -401,7 +423,7 @@ NdbBlob::getHeadFromRecAttr()
|
||||
theNullFlag = theHeadInlineRecAttr->isNULL();
|
||||
assert(theNullFlag != -1);
|
||||
theLength = ! theNullFlag ? theHead->length : 0;
|
||||
DBG("getHeadFromRecAttr out");
|
||||
DBG("getHeadFromRecAttr [out]");
|
||||
}
|
||||
|
||||
int
|
||||
@ -453,7 +475,7 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
|
||||
setErrorCode(ErrState);
|
||||
return -1;
|
||||
}
|
||||
if (! isInsertOp() && ! isUpdateOp()) {
|
||||
if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
|
||||
setErrorCode(ErrUsage);
|
||||
return -1;
|
||||
}
|
||||
@ -466,11 +488,12 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
|
||||
theGetSetBytes = bytes;
|
||||
if (isInsertOp()) {
|
||||
// write inline part now
|
||||
if (theSetBuf != 0) {
|
||||
unsigned n = theGetSetBytes;
|
||||
if (theSetBuf != NULL) {
|
||||
Uint32 n = theGetSetBytes;
|
||||
if (n > theInlineSize)
|
||||
n = theInlineSize;
|
||||
if (writeDataPrivate(0, theSetBuf, n) == -1)
|
||||
assert(thePos == 0);
|
||||
if (writeDataPrivate(theSetBuf, n) == -1)
|
||||
return -1;
|
||||
} else {
|
||||
theNullFlag = true;
|
||||
@ -555,7 +578,7 @@ NdbBlob::getLength(Uint64& len)
|
||||
int
|
||||
NdbBlob::truncate(Uint64 length)
|
||||
{
|
||||
DBG("truncate length=" << length);
|
||||
DBG("truncate [in] length=" << length);
|
||||
if (theNullFlag == -1) {
|
||||
setErrorCode(ErrState);
|
||||
return -1;
|
||||
@ -573,7 +596,10 @@ NdbBlob::truncate(Uint64 length)
|
||||
}
|
||||
theLength = length;
|
||||
theHeadInlineUpdateFlag = true;
|
||||
if (thePos > length)
|
||||
thePos = length;
|
||||
}
|
||||
DBG("truncate [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -609,33 +635,21 @@ NdbBlob::setPos(Uint64 pos)
|
||||
|
||||
int
|
||||
NdbBlob::readData(void* data, Uint32& bytes)
|
||||
{
|
||||
if (readData(thePos, data, bytes) == -1)
|
||||
return -1;
|
||||
thePos += bytes;
|
||||
assert(thePos <= theLength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::readData(Uint64 pos, void* data, Uint32& bytes)
|
||||
{
|
||||
if (theState != Active) {
|
||||
setErrorCode(ErrState);
|
||||
return -1;
|
||||
}
|
||||
char* buf = static_cast<char*>(data);
|
||||
return readDataPrivate(pos, buf, bytes);
|
||||
return readDataPrivate(buf, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
|
||||
NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
|
||||
{
|
||||
DBG("readData pos=" << pos << " bytes=" << bytes);
|
||||
if (pos > theLength) {
|
||||
setErrorCode(ErrSeek);
|
||||
return -1;
|
||||
}
|
||||
DBG("readData [in] bytes=" << bytes);
|
||||
assert(thePos <= theLength);
|
||||
Uint64 pos = thePos;
|
||||
if (bytes > theLength - pos)
|
||||
bytes = theLength - pos;
|
||||
Uint32 len = bytes;
|
||||
@ -665,7 +679,6 @@ NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
|
||||
if (readParts(thePartBuf.data, part, 1) == -1)
|
||||
return -1;
|
||||
// need result now
|
||||
DBG("execute pending part reads");
|
||||
if (executePendingBlobReads() == -1)
|
||||
return -1;
|
||||
Uint32 n = thePartSize - off;
|
||||
@ -699,7 +712,6 @@ NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
|
||||
if (readParts(thePartBuf.data, part, 1) == -1)
|
||||
return -1;
|
||||
// need result now
|
||||
DBG("execute pending part reads");
|
||||
if (executePendingBlobReads() == -1)
|
||||
return -1;
|
||||
memcpy(buf, thePartBuf.data, len);
|
||||
@ -709,38 +721,29 @@ NdbBlob::readDataPrivate(Uint64 pos, char* buf, Uint32& bytes)
|
||||
len -= n;
|
||||
}
|
||||
assert(len == 0);
|
||||
thePos = pos;
|
||||
assert(thePos <= theLength);
|
||||
DBG("readData [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::writeData(const void* data, Uint32 bytes)
|
||||
{
|
||||
if (writeData(thePos, data, bytes) == -1)
|
||||
return -1;
|
||||
thePos += bytes;
|
||||
assert(thePos <= theLength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::writeData(Uint64 pos, const void* data, Uint32 bytes)
|
||||
{
|
||||
if (theState != Active) {
|
||||
setErrorCode(ErrState);
|
||||
return -1;
|
||||
}
|
||||
const char* buf = static_cast<const char*>(data);
|
||||
return writeDataPrivate(pos, buf, bytes);
|
||||
return writeDataPrivate(buf, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
|
||||
NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
|
||||
{
|
||||
DBG("writeData pos=" << pos << " bytes=" << bytes);
|
||||
if (pos > theLength) {
|
||||
setErrorCode(ErrSeek);
|
||||
return -1;
|
||||
}
|
||||
DBG("writeData [in] bytes=" << bytes);
|
||||
assert(thePos <= theLength);
|
||||
Uint64 pos = thePos;
|
||||
Uint32 len = bytes;
|
||||
// any write makes blob not NULL
|
||||
if (theNullFlag) {
|
||||
@ -771,14 +774,12 @@ NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
|
||||
if (off != 0) {
|
||||
DBG("partial first block pos=" << pos << " len=" << len);
|
||||
// flush writes to guarantee correct read
|
||||
DBG("execute pending part writes");
|
||||
if (executePendingBlobWrites() == -1)
|
||||
return -1;
|
||||
Uint32 part = (pos - theInlineSize) / thePartSize;
|
||||
if (readParts(thePartBuf.data, part, 1) == -1)
|
||||
return -1;
|
||||
// need result now
|
||||
DBG("execute pending part reafs");
|
||||
if (executePendingBlobReads() == -1)
|
||||
return -1;
|
||||
Uint32 n = thePartSize - off;
|
||||
@ -822,13 +823,11 @@ NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
|
||||
Uint32 part = (pos - theInlineSize) / thePartSize;
|
||||
if (theLength > pos + len) {
|
||||
// flush writes to guarantee correct read
|
||||
DBG("execute pending part writes");
|
||||
if (executePendingBlobWrites() == -1)
|
||||
return -1;
|
||||
if (readParts(thePartBuf.data, part, 1) == -1)
|
||||
return -1;
|
||||
// need result now
|
||||
DBG("execute pending part reads");
|
||||
if (executePendingBlobReads() == -1)
|
||||
return -1;
|
||||
memcpy(thePartBuf.data, buf, len);
|
||||
@ -855,14 +854,16 @@ NdbBlob::writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes)
|
||||
theLength = pos;
|
||||
theHeadInlineUpdateFlag = true;
|
||||
}
|
||||
DBG("writeData out");
|
||||
thePos = pos;
|
||||
assert(thePos <= theLength);
|
||||
DBG("writeData [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
|
||||
{
|
||||
DBG("readParts part=" << part << " count=" << count);
|
||||
DBG("readParts [in] part=" << part << " count=" << count);
|
||||
Uint32 n = 0;
|
||||
while (n < count) {
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||
@ -873,6 +874,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
|
||||
@ -884,7 +886,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
|
||||
int
|
||||
NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
|
||||
{
|
||||
DBG("insertParts part=" << part << " count=" << count);
|
||||
DBG("insertParts [in] part=" << part << " count=" << count);
|
||||
Uint32 n = 0;
|
||||
while (n < count) {
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||
@ -895,6 +897,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
|
||||
@ -906,7 +909,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
|
||||
int
|
||||
NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
|
||||
{
|
||||
DBG("updateParts part=" << part << " count=" << count);
|
||||
DBG("updateParts [in] part=" << part << " count=" << count);
|
||||
Uint32 n = 0;
|
||||
while (n < count) {
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||
@ -917,6 +920,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
|
||||
@ -928,7 +932,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
|
||||
int
|
||||
NdbBlob::deleteParts(Uint32 part, Uint32 count)
|
||||
{
|
||||
DBG("deleteParts part=" << part << " count=" << count);
|
||||
DBG("deleteParts [in] part=" << part << " count=" << count);
|
||||
Uint32 n = 0;
|
||||
while (n < count) {
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||
@ -938,6 +942,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
|
||||
theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
|
||||
@ -945,6 +950,59 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Number of blob parts not known. Used to check for race condition
|
||||
* when writeTuple is used for insert. Deletes all parts found.
|
||||
*/
|
||||
int
|
||||
NdbBlob::deletePartsUnknown(Uint32 part)
|
||||
{
|
||||
DBG("deletePartsUnknown [in] part=" << part << " count=all");
|
||||
static const unsigned maxbat = 256;
|
||||
static const unsigned minbat = 1;
|
||||
unsigned bat = minbat;
|
||||
NdbOperation* tOpList[maxbat];
|
||||
Uint32 count = 0;
|
||||
while (true) {
|
||||
Uint32 n;
|
||||
n = 0;
|
||||
while (n < bat) {
|
||||
NdbOperation*& tOp = tOpList[n]; // ref
|
||||
tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||
if (tOp == NULL ||
|
||||
tOp->deleteTuple() == -1 ||
|
||||
setPartKeyValue(tOp, part + count + n) == -1) {
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = IgnoreError;
|
||||
n++;
|
||||
}
|
||||
DBG("deletePartsUnknown: executeNoBlobs [in] bat=" << bat);
|
||||
if (theNdbCon->executeNoBlobs(NoCommit) == -1)
|
||||
return -1;
|
||||
DBG("deletePartsUnknown: executeNoBlobs [out]");
|
||||
n = 0;
|
||||
while (n < bat) {
|
||||
NdbOperation* tOp = tOpList[n];
|
||||
if (tOp->theError.code != 0) {
|
||||
if (tOp->theError.code != 626) {
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
// first non-existent part
|
||||
DBG("deletePartsUnknown [out] count=" << count);
|
||||
return 0;
|
||||
}
|
||||
n++;
|
||||
count++;
|
||||
}
|
||||
bat *= 4;
|
||||
if (bat > maxbat)
|
||||
bat = maxbat;
|
||||
}
|
||||
}
|
||||
|
||||
// pending ops
|
||||
|
||||
int
|
||||
@ -952,8 +1010,10 @@ NdbBlob::executePendingBlobReads()
|
||||
{
|
||||
Uint8 flags = (1 << NdbOperation::ReadRequest);
|
||||
if (thePendingBlobOps & flags) {
|
||||
DBG("executePendingBlobReads: executeNoBlobs [in]");
|
||||
if (theNdbCon->executeNoBlobs(NoCommit) == -1)
|
||||
return -1;
|
||||
DBG("executePendingBlobReads: executeNoBlobs [out]");
|
||||
thePendingBlobOps = 0;
|
||||
theNdbCon->thePendingBlobOps = 0;
|
||||
}
|
||||
@ -965,8 +1025,10 @@ NdbBlob::executePendingBlobWrites()
|
||||
{
|
||||
Uint8 flags = 0xFF & ~(1 << NdbOperation::ReadRequest);
|
||||
if (thePendingBlobOps & flags) {
|
||||
DBG("executePendingBlobWrites: executeNoBlobs [in]");
|
||||
if (theNdbCon->executeNoBlobs(NoCommit) == -1)
|
||||
return -1;
|
||||
DBG("executePendingBlobWrites: executeNoBlobs [out]");
|
||||
thePendingBlobOps = 0;
|
||||
theNdbCon->thePendingBlobOps = 0;
|
||||
}
|
||||
@ -978,10 +1040,10 @@ NdbBlob::executePendingBlobWrites()
|
||||
int
|
||||
NdbBlob::invokeActiveHook()
|
||||
{
|
||||
DBG("invokeActiveHook");
|
||||
DBG("invokeActiveHook [in]");
|
||||
assert(theState == Active && theActiveHook != NULL);
|
||||
int ret = (*theActiveHook)(this, theActiveHookArg);
|
||||
DBG("invokeActiveHook ret=" << ret);
|
||||
DBG("invokeActiveHook [out] ret=" << ret);
|
||||
if (ret != 0) {
|
||||
// no error is set on blob level
|
||||
return -1;
|
||||
@ -1007,7 +1069,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
theTable = anOp->m_currentTable;
|
||||
theAccessTable = anOp->m_accessTable;
|
||||
theColumn = aColumn;
|
||||
DBG("atPrepare");
|
||||
DBG("atPrepare [in]");
|
||||
NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
|
||||
switch (theColumn->getType()) {
|
||||
case NdbDictionary::Column::Blob:
|
||||
@ -1046,6 +1108,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2);
|
||||
theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2);
|
||||
theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
|
||||
theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize);
|
||||
thePartBuf.alloc(thePartSize);
|
||||
theHead = (Head*)theHeadInlineBuf.data;
|
||||
theInlineData = theHeadInlineBuf.data + sizeof(Head);
|
||||
@ -1080,6 +1143,12 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
theNullFlag = true;
|
||||
theLength = 0;
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
// becomes NULL unless set before execute
|
||||
theNullFlag = true;
|
||||
theLength = 0;
|
||||
theHeadInlineUpdateFlag = true;
|
||||
}
|
||||
supportedOp = true;
|
||||
}
|
||||
if (isScanOp()) {
|
||||
@ -1093,19 +1162,21 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
||||
return -1;
|
||||
}
|
||||
setState(Prepared);
|
||||
DBG("atPrepare out");
|
||||
DBG("atPrepare [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before execute of prepared operation. May add new operations before
|
||||
* this one. May ask that this operation and all before it (a "batch")
|
||||
* is executed immediately in no-commit mode.
|
||||
* is executed immediately in no-commit mode. In this case remaining
|
||||
* prepared operations are saved in a separate list. They are added
|
||||
* back after postExecute.
|
||||
*/
|
||||
int
|
||||
NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
{
|
||||
DBG("preExecute");
|
||||
DBG("preExecute [in]");
|
||||
if (theState == Invalid)
|
||||
return -1;
|
||||
assert(theState == Prepared);
|
||||
@ -1120,11 +1191,11 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
if (isInsertOp()) {
|
||||
if (theSetFlag && theGetSetBytes > theInlineSize) {
|
||||
// add ops to write rest of a setValue
|
||||
assert(theSetBuf != 0);
|
||||
Uint64 pos = theInlineSize;
|
||||
assert(theSetBuf != NULL);
|
||||
const char* buf = theSetBuf + theInlineSize;
|
||||
Uint32 bytes = theGetSetBytes - theInlineSize;
|
||||
if (writeDataPrivate(pos, buf, bytes) == -1)
|
||||
assert(thePos == theInlineSize);
|
||||
if (writeDataPrivate(buf, bytes) == -1)
|
||||
return -1;
|
||||
if (theHeadInlineUpdateFlag) {
|
||||
// add an operation to update head+inline
|
||||
@ -1136,11 +1207,12 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
setErrorCode(ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
DBG("add op to update head+inline");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isTableOp()) {
|
||||
if (isUpdateOp() || isDeleteOp()) {
|
||||
if (isUpdateOp() || isWriteOp() || isDeleteOp()) {
|
||||
// add operation before this one to read head+inline
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp);
|
||||
if (tOp == NULL ||
|
||||
@ -1150,8 +1222,13 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
tOp->m_abortOption = IgnoreError;
|
||||
}
|
||||
theHeadInlineReadOp = tOp;
|
||||
// execute immediately
|
||||
batch = true;
|
||||
DBG("add op before to read head+inline");
|
||||
}
|
||||
}
|
||||
if (isIndexOp()) {
|
||||
@ -1170,7 +1247,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
NdbOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
|
||||
NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
|
||||
if (tOp == NULL ||
|
||||
tOp->readTuple() == -1 ||
|
||||
setAccessKeyValue(tOp) == -1 ||
|
||||
@ -1180,6 +1257,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("added op before to read table key");
|
||||
if (isUpdateOp() || isDeleteOp()) {
|
||||
// add op before this one to read head+inline via index
|
||||
NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
|
||||
@ -1190,15 +1268,43 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
setErrorCode(tOp);
|
||||
return -1;
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
tOp->m_abortOption = IgnoreError;
|
||||
}
|
||||
theHeadInlineReadOp = tOp;
|
||||
// execute immediately
|
||||
batch = true;
|
||||
DBG("added index op before to read head+inline");
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
// XXX until IgnoreError fixed for index op
|
||||
batch = true;
|
||||
}
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
if (theSetFlag) {
|
||||
// write head+inline now
|
||||
theNullFlag = true;
|
||||
theLength = 0;
|
||||
if (theSetBuf != NULL) {
|
||||
Uint32 n = theGetSetBytes;
|
||||
if (n > theInlineSize)
|
||||
n = theInlineSize;
|
||||
assert(thePos == 0);
|
||||
if (writeDataPrivate(theSetBuf, n) == -1)
|
||||
return -1;
|
||||
}
|
||||
if (setHeadInlineValue(theNdbOp) == -1)
|
||||
return -1;
|
||||
// the read op before us may overwrite
|
||||
theHeadInlineCopyBuf.copyfrom(theHeadInlineBuf);
|
||||
}
|
||||
}
|
||||
if (theActiveHook != NULL) {
|
||||
// need blob head for callback
|
||||
batch = true;
|
||||
}
|
||||
DBG("preExecute out batch=" << batch);
|
||||
DBG("preExecute [out] batch=" << batch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1211,15 +1317,16 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
|
||||
int
|
||||
NdbBlob::postExecute(ExecType anExecType)
|
||||
{
|
||||
DBG("postExecute type=" << anExecType);
|
||||
DBG("postExecute [in] type=" << anExecType);
|
||||
if (theState == Invalid)
|
||||
return -1;
|
||||
if (theState == Active) {
|
||||
setState(anExecType == NoCommit ? Active : Closed);
|
||||
DBG("postExecute skip");
|
||||
DBG("postExecute [skip]");
|
||||
return 0;
|
||||
}
|
||||
assert(theState == Prepared);
|
||||
setState(anExecType == NoCommit ? Active : Closed);
|
||||
assert(isKeyOp());
|
||||
if (isIndexOp()) {
|
||||
NdbBlob* tFirstBlob = theNdbOp->theBlobList;
|
||||
@ -1231,22 +1338,13 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
}
|
||||
if (isReadOp()) {
|
||||
getHeadFromRecAttr();
|
||||
if (theGetFlag && theGetSetBytes > 0) {
|
||||
// copy inline bytes to user buffer
|
||||
assert(theGetBuf != NULL);
|
||||
unsigned n = theGetSetBytes;
|
||||
if (n > theInlineSize)
|
||||
n = theInlineSize;
|
||||
memcpy(theGetBuf, theInlineData, n);
|
||||
}
|
||||
if (theGetFlag && theGetSetBytes > theInlineSize) {
|
||||
// add ops to read rest of a getValue
|
||||
assert(anExecType == NoCommit);
|
||||
assert(theGetBuf != 0);
|
||||
Uint64 pos = theInlineSize;
|
||||
char* buf = theGetBuf + theInlineSize;
|
||||
Uint32 bytes = theGetSetBytes - theInlineSize;
|
||||
if (readDataPrivate(pos, buf, bytes) == -1)
|
||||
if (setPos(0) == -1)
|
||||
return -1;
|
||||
if (theGetFlag) {
|
||||
assert(theGetSetBytes == 0 || theGetBuf != 0);
|
||||
assert(theGetSetBytes <= theInlineSize || anExecType == NoCommit);
|
||||
Uint32 bytes = theGetSetBytes;
|
||||
if (readDataPrivate(theGetBuf, bytes) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1255,10 +1353,11 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
getHeadFromRecAttr();
|
||||
if (theSetFlag) {
|
||||
// setValue overwrites everything
|
||||
if (theSetBuf != 0) {
|
||||
if (theSetBuf != NULL) {
|
||||
if (truncate(0) == -1)
|
||||
return -1;
|
||||
if (writeDataPrivate(0, theSetBuf, theGetSetBytes) == -1)
|
||||
assert(thePos == 0);
|
||||
if (writeDataPrivate(theSetBuf, theGetSetBytes) == -1)
|
||||
return -1;
|
||||
} else {
|
||||
if (setNull() == -1)
|
||||
@ -1266,6 +1365,57 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isWriteOp() && isTableOp()) {
|
||||
assert(anExecType == NoCommit);
|
||||
if (theHeadInlineReadOp->theError.code == 0) {
|
||||
int tNullFlag = theNullFlag;
|
||||
Uint64 tLength = theLength;
|
||||
Uint64 tPos = thePos;
|
||||
getHeadFromRecAttr();
|
||||
DBG("tuple found");
|
||||
if (truncate(0) == -1)
|
||||
return -1;
|
||||
// restore previous head+inline
|
||||
theHeadInlineBuf.copyfrom(theHeadInlineCopyBuf);
|
||||
theNullFlag = tNullFlag;
|
||||
theLength = tLength;
|
||||
thePos = tPos;
|
||||
} else {
|
||||
if (theHeadInlineReadOp->theError.code != 626) {
|
||||
setErrorCode(theHeadInlineReadOp);
|
||||
return -1;
|
||||
}
|
||||
DBG("tuple not found");
|
||||
/*
|
||||
* Read found no tuple but it is possible that a tuple was
|
||||
* created after the read by another transaction. Delete all
|
||||
* blob parts which may exist.
|
||||
*/
|
||||
if (deletePartsUnknown(0) == -1)
|
||||
return -1;
|
||||
}
|
||||
if (theSetFlag && theGetSetBytes > theInlineSize) {
|
||||
assert(theSetBuf != NULL);
|
||||
const char* buf = theSetBuf + theInlineSize;
|
||||
Uint32 bytes = theGetSetBytes - theInlineSize;
|
||||
assert(thePos == theInlineSize);
|
||||
if (writeDataPrivate(buf, bytes) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (isWriteOp() && isIndexOp()) {
|
||||
// XXX until IgnoreError fixed for index op
|
||||
if (deletePartsUnknown(0) == -1)
|
||||
return -1;
|
||||
if (theSetFlag && theGetSetBytes > theInlineSize) {
|
||||
assert(theSetBuf != NULL);
|
||||
const char* buf = theSetBuf + theInlineSize;
|
||||
Uint32 bytes = theGetSetBytes - theInlineSize;
|
||||
assert(thePos == theInlineSize);
|
||||
if (writeDataPrivate(buf, bytes) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (isDeleteOp()) {
|
||||
assert(anExecType == NoCommit);
|
||||
getHeadFromRecAttr();
|
||||
@ -1278,7 +1428,19 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
if (invokeActiveHook() == -1)
|
||||
return -1;
|
||||
}
|
||||
DBG("postExecute out");
|
||||
if (anExecType == NoCommit && theHeadInlineUpdateFlag) {
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
|
||||
if (tOp == NULL ||
|
||||
tOp->updateTuple() == -1 ||
|
||||
setTableKeyValue(tOp) == -1 ||
|
||||
setHeadInlineValue(tOp) == -1) {
|
||||
setErrorCode(ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
DBG("added op to update head+inline");
|
||||
}
|
||||
DBG("postExecute [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1289,12 +1451,12 @@ NdbBlob::postExecute(ExecType anExecType)
|
||||
int
|
||||
NdbBlob::preCommit()
|
||||
{
|
||||
DBG("preCommit");
|
||||
DBG("preCommit [in]");
|
||||
if (theState == Invalid)
|
||||
return -1;
|
||||
assert(theState == Active);
|
||||
assert(isKeyOp());
|
||||
if (isInsertOp() || isUpdateOp()) {
|
||||
if (isInsertOp() || isUpdateOp() || isWriteOp()) {
|
||||
if (theHeadInlineUpdateFlag) {
|
||||
// add an operation to update head+inline
|
||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
|
||||
@ -1305,9 +1467,11 @@ NdbBlob::preCommit()
|
||||
setErrorCode(ErrAbort);
|
||||
return -1;
|
||||
}
|
||||
tOp->m_abortOption = AbortOnError;
|
||||
DBG("added op to update head+inline");
|
||||
}
|
||||
}
|
||||
DBG("preCommit out");
|
||||
DBG("preCommit [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1317,13 +1481,10 @@ NdbBlob::preCommit()
|
||||
int
|
||||
NdbBlob::atNextResult()
|
||||
{
|
||||
DBG("atNextResult");
|
||||
DBG("atNextResult [in]");
|
||||
if (theState == Invalid)
|
||||
return -1;
|
||||
assert(isScanOp());
|
||||
getHeadFromRecAttr();
|
||||
// reset position
|
||||
thePos = 0;
|
||||
// get primary key
|
||||
{ Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_sizeOfKeysInWords;
|
||||
@ -1332,26 +1493,14 @@ NdbBlob::atNextResult()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (! theNullFlag) {
|
||||
if (theGetFlag && theGetSetBytes > 0) {
|
||||
// copy inline bytes to user buffer
|
||||
assert(theGetBuf != NULL);
|
||||
unsigned n = theGetSetBytes;
|
||||
if (n > theLength)
|
||||
n = theLength;
|
||||
if (n > theInlineSize)
|
||||
n = theInlineSize;
|
||||
memcpy(theGetBuf, theInlineData, n);
|
||||
}
|
||||
if (theGetFlag && theGetSetBytes > theInlineSize && theLength > theInlineSize) {
|
||||
// add ops to read rest of a getValue
|
||||
assert(theGetBuf != 0);
|
||||
Uint64 pos = theInlineSize;
|
||||
char* buf = theGetBuf + theInlineSize;
|
||||
Uint32 bytes = theGetSetBytes - theInlineSize;
|
||||
if (readDataPrivate(pos, buf, bytes) == -1)
|
||||
return -1;
|
||||
}
|
||||
getHeadFromRecAttr();
|
||||
if (setPos(0) == -1)
|
||||
return -1;
|
||||
if (theGetFlag) {
|
||||
assert(theGetSetBytes == 0 || theGetBuf != 0);
|
||||
Uint32 bytes = theGetSetBytes;
|
||||
if (readDataPrivate(theGetBuf, bytes) == -1)
|
||||
return -1;
|
||||
}
|
||||
setState(Active);
|
||||
// activation callback
|
||||
@ -1359,7 +1508,7 @@ NdbBlob::atNextResult()
|
||||
if (invokeActiveHook() == -1)
|
||||
return -1;
|
||||
}
|
||||
DBG("atNextResult out");
|
||||
DBG("atNextResult [out]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1444,7 +1593,8 @@ operator<<(NdbOut& out, const NdbBlob& blob)
|
||||
ndbout << dec << " n=" << blob.theNullFlag;;
|
||||
ndbout << dec << " l=" << blob.theLength;
|
||||
ndbout << dec << " p=" << blob.thePos;
|
||||
ndbout << dec << " u=" << (Uint32) blob.theHeadInlineUpdateFlag;
|
||||
ndbout << dec << " u=" << (Uint32)blob.theHeadInlineUpdateFlag;
|
||||
ndbout << dec << " g=" << (Uint32)blob.theGetSetBytes;
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
@ -170,12 +170,14 @@ Remark: Sets an error code on the connection object from an
|
||||
operation object.
|
||||
*****************************************************************************/
|
||||
void
|
||||
NdbConnection::setOperationErrorCodeAbort(int error)
|
||||
NdbConnection::setOperationErrorCodeAbort(int error, int abortOption)
|
||||
{
|
||||
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
|
||||
if (abortOption == -1)
|
||||
abortOption = m_abortOption;
|
||||
if (theTransactionIsStarted == false) {
|
||||
theCommitStatus = Aborted;
|
||||
} else if ((m_abortOption == AbortOnError) &&
|
||||
} else if ((abortOption == AbortOnError) &&
|
||||
(theCommitStatus != Committed) &&
|
||||
(theCommitStatus != Aborted)) {
|
||||
theCommitStatus = NeedAbort;
|
||||
@ -335,8 +337,16 @@ NdbConnection::execute(ExecType aTypeOfExec,
|
||||
tOp = tOp->next();
|
||||
}
|
||||
}
|
||||
|
||||
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
|
||||
ret = -1;
|
||||
#ifndef VM_TRACE
|
||||
// can happen in complex abort cases
|
||||
theFirstOpInList = theLastOpInList = NULL;
|
||||
#else
|
||||
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
|
||||
#endif
|
||||
|
||||
{
|
||||
NdbOperation* tOp = theCompletedFirstOp;
|
||||
while (tOp != NULL) {
|
||||
@ -360,6 +370,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
|
||||
theLastOpInList->next(tRestOp);
|
||||
theLastOpInList = tLastOp;
|
||||
}
|
||||
assert(theFirstOpInList == NULL || tExecType == NoCommit);
|
||||
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
|
||||
|
||||
DBUG_RETURN(ret);
|
||||
@ -1806,11 +1817,12 @@ Parameters: aErrorCode: The error code.
|
||||
Remark: An operation was completed with failure.
|
||||
*******************************************************************************/
|
||||
int
|
||||
NdbConnection::OpCompleteFailure(Uint8 abortOption)
|
||||
NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure)
|
||||
{
|
||||
Uint32 tNoComp = theNoOfOpCompleted;
|
||||
Uint32 tNoSent = theNoOfOpSent;
|
||||
theCompletionStatus = NdbConnection::CompletedFailure;
|
||||
if (setFailure)
|
||||
theCompletionStatus = NdbConnection::CompletedFailure;
|
||||
tNoComp++;
|
||||
theNoOfOpCompleted = tNoComp;
|
||||
if (tNoComp == tNoSent) {
|
||||
|
@ -47,13 +47,13 @@
|
||||
* Column
|
||||
*/
|
||||
NdbColumnImpl::NdbColumnImpl()
|
||||
: NdbDictionary::Column(* this), m_facade(this)
|
||||
: NdbDictionary::Column(* this), m_attrId(-1), m_facade(this)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
|
||||
: NdbDictionary::Column(* this), m_facade(&f)
|
||||
: NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@ -93,8 +93,7 @@ NdbColumnImpl::init(Type t)
|
||||
{
|
||||
// do not use default_charset_info as it may not be initialized yet
|
||||
// use binary collation until NDB tests can handle charsets
|
||||
CHARSET_INFO* default_cs = &my_charset_latin1_bin;
|
||||
m_attrId = -1;
|
||||
CHARSET_INFO* default_cs = &my_charset_bin;
|
||||
m_type = t;
|
||||
switch (m_type) {
|
||||
case Tinyint:
|
||||
|
@ -71,6 +71,7 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
|
||||
return -1;
|
||||
}
|
||||
m_theIndex = anIndex;
|
||||
m_thePrimaryTable = aTable;
|
||||
m_accessTable = anIndex->m_table;
|
||||
m_theIndexLen = 0;
|
||||
m_theNoOfIndexDefined = 0;
|
||||
@ -102,6 +103,12 @@ int NdbIndexOperation::readTuple(NdbOperation::LockMode lm)
|
||||
};
|
||||
}
|
||||
|
||||
int NdbIndexOperation::insertTuple()
|
||||
{
|
||||
setErrorCode(4200);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbIndexOperation::readTuple()
|
||||
{
|
||||
// First check that index is unique
|
||||
@ -341,12 +348,11 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
||||
theDistrGroupIndicator = 1;
|
||||
}//if
|
||||
/**************************************************************************
|
||||
* If the operation is an insert request and the attribute is stored then
|
||||
* If the operation is a write request and the attribute is stored then
|
||||
* we also set the value in the stored part through putting the
|
||||
* information in the INDXATTRINFO signals.
|
||||
*************************************************************************/
|
||||
if ((tOpType == InsertRequest) ||
|
||||
(tOpType == WriteRequest)) {
|
||||
if ((tOpType == WriteRequest)) {
|
||||
if (!tAttrInfo->m_indexOnly){
|
||||
// invalid data can crash kernel
|
||||
if (cs != NULL &&
|
||||
@ -357,7 +363,13 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
||||
goto equal_error4;
|
||||
Uint32 ahValue;
|
||||
Uint32 sz = totalSizeInWords;
|
||||
AttributeHeader::init(&ahValue, tAttrId, sz);
|
||||
/*
|
||||
* XXX should be linked in metadata but cannot now because
|
||||
* things can be defined in arbitrary order
|
||||
*/
|
||||
const NdbColumnImpl* primaryCol = m_thePrimaryTable->getColumn(tAttrInfo->m_name.c_str());
|
||||
assert(primaryCol != NULL);
|
||||
AttributeHeader::init(&ahValue, primaryCol->m_attrId, sz);
|
||||
insertATTRINFO( ahValue );
|
||||
insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords);
|
||||
if (bitsInLastWord != 0) {
|
||||
@ -369,7 +381,6 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
||||
}//if
|
||||
}//if
|
||||
}//if
|
||||
|
||||
/**************************************************************************
|
||||
* Store the Key information in the TCINDXREQ and INDXKEYINFO signals.
|
||||
*************************************************************************/
|
||||
@ -734,13 +745,10 @@ NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||
}//if
|
||||
|
||||
theStatus = Finished;
|
||||
|
||||
|
||||
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
|
||||
Uint32 errorCode = tcIndxRef->errorCode;
|
||||
theError.code = errorCode;
|
||||
theNdbCon->setOperationErrorCodeAbort(errorCode);
|
||||
return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption);
|
||||
}//NdbIndexOperation::receiveTCINDXREF()
|
||||
|
||||
|
||||
|
||||
|
@ -78,7 +78,8 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
|
||||
m_tcReqGSN(GSN_TCKEYREQ),
|
||||
m_keyInfoGSN(GSN_KEYINFO),
|
||||
m_attrInfoGSN(GSN_ATTRINFO),
|
||||
theBlobList(NULL)
|
||||
theBlobList(NULL),
|
||||
m_abortOption(-1)
|
||||
{
|
||||
theReceiver.init(NdbReceiver::NDB_OPERATION, this);
|
||||
theError.code = 0;
|
||||
@ -167,6 +168,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){
|
||||
theTotalNrOfKeyWordInSignal = 8;
|
||||
theMagicNumber = 0xABCDEF01;
|
||||
theBlobList = NULL;
|
||||
m_abortOption = -1;
|
||||
|
||||
tSignal = theNdb->getSignal();
|
||||
if (tSignal == NULL)
|
||||
|
@ -191,7 +191,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
||||
Uint8 tDirtyIndicator = theDirtyIndicator;
|
||||
OperationType tOperationType = theOperationType;
|
||||
Uint32 tTupKeyLen = theTupKeyLen;
|
||||
Uint8 abortOption = theNdbCon->m_abortOption;
|
||||
Uint8 abortOption =
|
||||
m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption;
|
||||
|
||||
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
|
||||
tcKeyReq->setOperationType(tReqInfo, tOperationType);
|
||||
@ -541,17 +542,20 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
|
||||
return -1;
|
||||
}//if
|
||||
|
||||
AbortOption ao = (AbortOption)theNdbCon->m_abortOption;
|
||||
AbortOption ao = (AbortOption)
|
||||
(m_abortOption != (Int8)-1 ? m_abortOption : theNdbCon->m_abortOption);
|
||||
theReceiver.m_received_result_length = ~0;
|
||||
|
||||
theStatus = Finished;
|
||||
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
|
||||
// blobs want this
|
||||
if (m_abortOption != IgnoreError)
|
||||
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
|
||||
|
||||
theError.code = aSignal->readData(4);
|
||||
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4));
|
||||
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), m_abortOption);
|
||||
|
||||
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
|
||||
return theNdbCon->OpCompleteFailure(ao);
|
||||
return theNdbCon->OpCompleteFailure(ao, m_abortOption != IgnoreError);
|
||||
|
||||
/**
|
||||
* If TCKEYCONF has arrived
|
||||
|
@ -612,7 +612,7 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){
|
||||
LinearSectionPtr ptr[3];
|
||||
ptr[0].p = prep_array;
|
||||
ptr[0].sz = cnt;
|
||||
ret = tp->sendFragmentedSignal(&tSignal, nodeId, ptr, 1);
|
||||
ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
|
||||
} else {
|
||||
tSignal.setLength(4+cnt);
|
||||
ret = tp->sendSignal(&tSignal, nodeId);
|
||||
@ -803,7 +803,7 @@ NdbScanOperation::doSendScan(int aProcessorId)
|
||||
LinearSectionPtr ptr[3];
|
||||
ptr[0].p = m_prepared_receivers;
|
||||
ptr[0].sz = theParallelism;
|
||||
if (tp->sendFragmentedSignal(tSignal, aProcessorId, ptr, 1) == -1) {
|
||||
if (tp->sendSignal(tSignal, aProcessorId, ptr, 1) == -1) {
|
||||
setErrorCode(4002);
|
||||
return -1;
|
||||
}
|
||||
|
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