diff options
author | unknown <monty@mysql.com> | 2004-11-04 15:06:24 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-11-04 15:06:24 +0200 |
commit | 70d66da883b1d4bc5a9c22737461aba40023d8ff (patch) | |
tree | 9d4d27a72c18ead47fb83bd5ec0e2383cdd34ff6 /ndb/src | |
parent | f662de31e8441a4803b3487ef264a35695820a77 (diff) | |
parent | c9a75ccf1acfc4578496a1606fcf009301366997 (diff) | |
download | mariadb-git-70d66da883b1d4bc5a9c22737461aba40023d8ff.tar.gz |
Merge with 4.1 to get in latest bug fixes
BitKeeper/etc/logging_ok:
auto-union
Docs/Support/texi2html:
Auto merged
include/mysql.h:
Auto merged
include/mysql_com.h:
Auto merged
libmysql/libmysql.c:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/myisamchk.c:
Auto merged
mysql-test/include/ps_modify.inc:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
mysql-test/r/ctype_recoding.result:
Auto merged
mysql-test/r/fulltext.result:
Auto merged
mysql-test/r/gis.result:
Auto merged
mysql-test/r/ndb_blob.result:
Auto merged
mysql-test/r/ps_2myisam.result:
Auto merged
mysql-test/r/ps_3innodb.result:
Auto merged
mysql-test/r/ps_4heap.result:
Auto merged
mysql-test/r/ps_5merge.result:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/sql_mode.result:
Auto merged
mysql-test/t/join_outer.test:
Auto merged
mysql-test/t/key.test:
Auto merged
mysql-test/t/range.test:
Auto merged
mysql-test/t/show_check.test:
Auto merged
mysql-test/t/sql_mode.test:
Auto merged
sql/field.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/ha_ndbcluster.h:
Auto merged
sql/item.h:
Auto merged
sql/item_create.cc:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/item_timefunc.cc:
Auto merged
sql/mysqld.cc:
Auto merged
sql/net_serv.cc:
Auto merged
sql/protocol.cc:
Auto merged
sql/protocol.h:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_handler.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_string.cc:
Auto merged
sql/sql_string.h:
Auto merged
sql/sql_table.cc:
Auto merged
client/mysqltest.c:
Merge with 4.1
mysql-test/r/range.result:
Merge with 4.1
Added missing drop table test
sql/ha_innodb.cc:
Merge with 4.1
sql/item.cc:
Merge with 4.1
sql/item_cmpfunc.cc:
Merge with 4.1
sql/opt_range.cc:
Merge with 4.1
sql/sql_prepare.cc:
Merge with 4.1
tests/client_test.c:
Merge with 4.1
Added code to support --silent
configure.in:
Merge with 4.1
ndb/src/common/util/version.c:
Merge with 4.1
Diffstat (limited to 'ndb/src')
34 files changed, 892 insertions, 1259 deletions
diff --git a/ndb/src/common/editline/sysunix.c b/ndb/src/common/editline/sysunix.c index 000bca78dfc..d7437f6a9c7 100644 --- a/ndb/src/common/editline/sysunix.c +++ b/ndb/src/common/editline/sysunix.c @@ -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; + } + } } diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am index 0235adae7c9..61fd7992002 100644 --- a/ndb/src/common/util/Makefile.am +++ b/ndb/src/common/util/Makefile.am @@ -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 diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c index 10932226d18..7307279f345 100644 --- a/ndb/src/common/util/basestring_vsnprintf.c +++ b/ndb/src/common/util/basestring_vsnprintf.c @@ -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; } diff --git a/ndb/src/common/util/getarg.c b/ndb/src/common/util/getarg.c deleted file mode 100644 index 99b2840a5a6..00000000000 --- a/ndb/src/common/util/getarg.c +++ /dev/null @@ -1,589 +0,0 @@ -/* -*- c-basic-offset: 4; -*- */ -/* - * Copyright (c) 1997 - 2000 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> - -#include "getarg.h" - -#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag) - -#ifndef HAVE_STRLCPY -extern size_t strlcpy (char *dst, const char *src, size_t dst_sz); -#endif /* !HAVE_STRLCPY */ - -#ifndef HAVE_STRLCAT -extern size_t strlcat (char *dst, const char *src, size_t dst_sz); -#endif /* !HAVE_STRLCAT */ - -#ifndef max -#define max(a, b) (a) > (b) ? (a) : (b) -#endif - -#ifdef HAVE___PROGNAME -extern char *__progname; -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -char * -strupr(char *str) -{ - char *s; - - for(s = str; *s; s++) - *s = toupper(*s); - return str; -} - -static size_t -print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg) -{ - const char *s; - - *string = '\0'; - - if (ISFLAG(*arg) || (!longp && arg->type == arg_counter)) - return 0; - - if(mdoc){ - if(longp) - strlcat(string, "= Ns", len); - strlcat(string, " Ar ", len); - }else - if (longp) - strlcat (string, "=", len); - else - strlcat (string, " ", len); - - if (arg->arg_help) - s = arg->arg_help; - else if (arg->type == arg_integer || arg->type == arg_counter) - s = "integer"; - else if (arg->type == arg_string) - s = "string"; - else if (arg->type == arg_double) - s = "float"; - else - s = "<undefined>"; - - strlcat(string, s, len); - return 1 + strlen(s); -} - -#ifdef GETARGMANDOC -static void -mandoc_template(struct getargs *args, - size_t num_args, - const char *progname, - const char *extra_string) -{ - size_t i; - char timestr[64], cmd[64]; - char buf[128]; - const char *p; - time_t t; - - printf(".\\\" Things to fix:\n"); - printf(".\\\" * correct section, and operating system\n"); - printf(".\\\" * remove Op from mandatory flags\n"); - printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); - printf(".\\\"\n"); - t = time(NULL); - strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t)); - printf(".Dd %s\n", timestr); - p = strrchr(progname, '/'); - if(p) p++; else p = progname; - strlcpy(cmd, p, sizeof(cmd)); - strupr(cmd); - - printf(".Dt %s SECTION\n", cmd); - printf(".Os OPERATING_SYSTEM\n"); - printf(".Sh NAME\n"); - printf(".Nm %s\n", p); - printf(".Nd\n"); - printf("in search of a description\n"); - printf(".Sh SYNOPSIS\n"); - printf(".Nm\n"); - for(i = 0; i < num_args; i++){ - /* we seem to hit a limit on number of arguments if doing - short and long flags with arguments -- split on two lines */ - if(ISFLAG(args[i]) || - args[i].short_name == 0 || args[i].long_name == NULL) { - printf(".Op "); - - if(args[i].short_name) { - print_arg(buf, sizeof(buf), 1, 0, args + i); - printf("Fl %c%s", args[i].short_name, buf); - if(args[i].long_name) - printf(" | "); - } - if(args[i].long_name) { - print_arg(buf, sizeof(buf), 1, 1, args + i); - printf("Fl -%s%s%s", - args[i].type == arg_negative_flag ? "no-" : "", - args[i].long_name, buf); - } - printf("\n"); - } else { - print_arg(buf, sizeof(buf), 1, 0, args + i); - printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf); - print_arg(buf, sizeof(buf), 1, 1, args + i); - printf(".Fl -%s%s Oc\n.Xc\n", args[i].long_name, buf); - } - /* - if(args[i].type == arg_strings) - fprintf (stderr, "..."); - */ - } - if (extra_string && *extra_string) - printf (".Ar %s\n", extra_string); - printf(".Sh DESCRIPTION\n"); - printf("Supported options:\n"); - printf(".Bl -tag -width Ds\n"); - for(i = 0; i < num_args; i++){ - printf(".It Xo\n"); - if(args[i].short_name){ - printf(".Fl %c", args[i].short_name); - print_arg(buf, sizeof(buf), 1, 0, args + i); - printf("%s", buf); - if(args[i].long_name) - printf(" Ns ,"); - printf("\n"); - } - if(args[i].long_name){ - printf(".Fl -%s%s", - args[i].type == arg_negative_flag ? "no-" : "", - args[i].long_name); - print_arg(buf, sizeof(buf), 1, 1, args + i); - printf("%s\n", buf); - } - printf(".Xc\n"); - if(args[i].help) - printf("%s\n", args[i].help); - /* - if(args[i].type == arg_strings) - fprintf (stderr, "..."); - */ - } - printf(".El\n"); - printf(".\\\".Sh ENVIRONMENT\n"); - printf(".\\\".Sh FILES\n"); - printf(".\\\".Sh EXAMPLES\n"); - printf(".\\\".Sh DIAGNOSTICS\n"); - printf(".\\\".Sh SEE ALSO\n"); - printf(".\\\".Sh STANDARDS\n"); - printf(".\\\".Sh HISTORY\n"); - printf(".\\\".Sh AUTHORS\n"); - printf(".\\\".Sh BUGS\n"); -} -#endif /* GETARGMANDOC */ - -static int -check_column(FILE *f, int col, int len, int columns) -{ - if(col + len > columns) { - fprintf(f, "\n"); - col = fprintf(f, " "); - } - return col; -} - -void -arg_printusage (struct getargs *args, - size_t num_args, - const char *progname, - const char *extra_string) -{ - unsigned int i; - size_t max_len = 0; - char buf[128]; - int col = 0, columns; - -#ifdef HAVE___PROGNAME - if (progname == NULL) - progname = __progname; -#endif - if (progname == NULL) - progname = ""; - -#ifdef GETARGMANDOC - if(getenv("GETARGMANDOC")){ - mandoc_template(args, num_args, progname, extra_string); - return; - } -#endif - - columns = 80; /* Always assume that the window is 80 chars wide */ - col = 0; - col += fprintf (stderr, "Usage: %s", progname); - for (i = 0; i < num_args; ++i) { - size_t len = 0; - - if (args[i].long_name) { - buf[0] = '\0'; - strlcat(buf, "[--", sizeof(buf)); - len += 2; - if(args[i].type == arg_negative_flag) { - strlcat(buf, "no-", sizeof(buf)); - len += 3; - } - strlcat(buf, args[i].long_name, sizeof(buf)); - len += strlen(args[i].long_name); - len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), - 0, 1, &args[i]); - strlcat(buf, "]", sizeof(buf)); - if(args[i].type == arg_strings) - strlcat(buf, "...", sizeof(buf)); - col = check_column(stderr, col, strlen(buf) + 1, columns); - col += fprintf(stderr, " %s", buf); - } - if (args[i].short_name) { - snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); - len += 2; - len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), - 0, 0, &args[i]); - strlcat(buf, "]", sizeof(buf)); - if(args[i].type == arg_strings) - strlcat(buf, "...", sizeof(buf)); - col = check_column(stderr, col, strlen(buf) + 1, columns); - col += fprintf(stderr, " %s", buf); - } - if (args[i].long_name && args[i].short_name) - len += 2; /* ", " */ - max_len = max(max_len, len); - } - if (extra_string) { - col = check_column(stderr, col, strlen(extra_string) + 1, columns); - fprintf (stderr, " %s\n", extra_string); - } else - fprintf (stderr, "\n"); - for (i = 0; i < num_args; ++i) { - if (args[i].help) { - size_t count = 0; - - if (args[i].short_name) { - count += fprintf (stderr, "-%c", args[i].short_name); - print_arg (buf, sizeof(buf), 0, 0, &args[i]); - count += fprintf(stderr, "%s", buf); - } - if (args[i].short_name && args[i].long_name) - count += fprintf (stderr, ", "); - if (args[i].long_name) { - count += fprintf (stderr, "--"); - if (args[i].type == arg_negative_flag) - count += fprintf (stderr, "no-"); - count += fprintf (stderr, "%s", args[i].long_name); - print_arg (buf, sizeof(buf), 0, 1, &args[i]); - count += fprintf(stderr, "%s", buf); - } - while(count++ <= max_len) - putc (' ', stderr); - fprintf (stderr, "%s\n", args[i].help); - } - } -} - -static void -add_string(getarg_strings *s, char *value) -{ - s->strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings)); - s->strings[s->num_strings] = value; - s->num_strings++; -} - -static int -arg_match_long(struct getargs *args, size_t num_args, - char *argv, int argc, const char **rargv, int *optind) -{ - unsigned int i; - const char *optarg = NULL; - int negate = 0; - int partial_match = 0; - struct getargs *partial = NULL; - struct getargs *current = NULL; - int argv_len; - char *p; - - argv_len = strlen(argv); - p = strchr (argv, '='); - if (p != NULL) - argv_len = p - argv; - - for (i = 0; i < num_args; ++i) { - if(args[i].long_name) { - int len = strlen(args[i].long_name); - char *p = argv; - int p_len = argv_len; - negate = 0; - - for (;;) { - if (strncmp (args[i].long_name, p, p_len) == 0) { - if(p_len == len) - current = &args[i]; - else { - ++partial_match; - partial = &args[i]; - } - optarg = p + p_len; - } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) { - negate = !negate; - p += 3; - p_len -= 3; - continue; - } - break; - } - if (current) - break; - } - } - if (current == NULL) { - if (partial_match == 1) - current = partial; - else - return ARG_ERR_NO_MATCH; - } - - if(*optarg == '\0' - && !ISFLAG(*current) - && current->type != arg_collect - && current->type != arg_counter) - return ARG_ERR_NO_MATCH; - switch(current->type){ - case arg_integer: - { - int tmp; - if(sscanf(optarg + 1, "%d", &tmp) != 1) - return ARG_ERR_BAD_ARG; - *(int*)current->value = tmp; - return 0; - } - case arg_string: - { - *(char**)current->value = (char*)optarg + 1; - return 0; - } - case arg_strings: - { - add_string((getarg_strings*)current->value, (char*)optarg + 1); - return 0; - } - case arg_flag: - case arg_negative_flag: - { - int *flag = current->value; - if(*optarg == '\0' || - strcmp(optarg + 1, "yes") == 0 || - strcmp(optarg + 1, "true") == 0){ - *flag = !negate; - return 0; - } else if (*optarg && strcmp(optarg + 1, "maybe") == 0) { - *flag = rand() & 1; - } else { - *flag = negate; - return 0; - } - return ARG_ERR_BAD_ARG; - } - case arg_counter : - { - int val; - - if (*optarg == '\0') - val = 1; - else { - char *endstr; - - val = strtol (optarg, &endstr, 0); - if (endstr == optarg) - return ARG_ERR_BAD_ARG; - } - *(int *)current->value += val; - return 0; - } - case arg_double: - { - double tmp; - if(sscanf(optarg + 1, "%lf", &tmp) != 1) - return ARG_ERR_BAD_ARG; - *(double*)current->value = tmp; - return 0; - } - case arg_collect:{ - struct getarg_collect_info *c = current->value; - int o = argv - rargv[*optind]; - return (*c->func)(FALSE, argc, rargv, optind, &o, c->data); - } - - default: - abort (); - } -} - -static int -arg_match_short (struct getargs *args, size_t num_args, - char *argv, int argc, const char **rargv, int *optind) -{ - int j, k; - - for(j = 1; j > 0 && j < (int)strlen(rargv[*optind]); j++) { - for(k = 0; k < (int)num_args; k++) { - char *optarg; - - if(args[k].short_name == 0) - continue; - if(argv[j] == args[k].short_name) { - if(args[k].type == arg_flag) { - *(int*)args[k].value = 1; - break; - } - if(args[k].type == arg_negative_flag) { - *(int*)args[k].value = 0; - break; - } - if(args[k].type == arg_counter) { - ++*(int *)args[k].value; - break; - } - if(args[k].type == arg_collect) { - struct getarg_collect_info *c = args[k].value; - - if((*c->func)(TRUE, argc, rargv, optind, &j, c->data)) - return ARG_ERR_BAD_ARG; - break; - } - - if(argv[j + 1]) - optarg = &argv[j + 1]; - else { - ++*optind; - optarg = (char *) rargv[*optind]; - } - if(optarg == NULL) { - --*optind; - return ARG_ERR_NO_ARG; - } - if(args[k].type == arg_integer) { - int tmp; - if(sscanf(optarg, "%d", &tmp) != 1) - return ARG_ERR_BAD_ARG; - *(int*)args[k].value = tmp; - return 0; - } else if(args[k].type == arg_string) { - *(char**)args[k].value = optarg; - return 0; - } else if(args[k].type == arg_strings) { - add_string((getarg_strings*)args[k].value, optarg); - return 0; - } else if(args[k].type == arg_double) { - double tmp; - if(sscanf(optarg, "%lf", &tmp) != 1) - return ARG_ERR_BAD_ARG; - *(double*)args[k].value = tmp; - return 0; - } - return ARG_ERR_BAD_ARG; - } - } - if (k == (int)num_args) - return ARG_ERR_NO_MATCH; - } - return 0; -} - -int -getarg(struct getargs *args, size_t num_args, - int argc, const char **argv, int *optind) -{ - int i; - int ret = 0; - - srand (time(NULL)); - (*optind)++; - for(i = *optind; i < argc; i++) { - if(argv[i][0] != '-') - break; - if(argv[i][1] == '-'){ - if(argv[i][2] == 0){ - i++; - break; - } - ret = arg_match_long (args, num_args, (char *) argv[i] + 2, - argc, argv, &i); - } else { - ret = arg_match_short (args, num_args, (char *) argv[i], - argc, argv, &i); - } - if(ret) - break; - } - *optind = i; - return ret; -} - - -#if TEST -int foo_flag = 2; -int flag1 = 0; -int flag2 = 0; -int bar_int; -char *baz_string; - -struct getargs args[] = { - { NULL, '1', arg_flag, &flag1, "one", NULL }, - { NULL, '2', arg_flag, &flag2, "two", NULL }, - { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL }, - { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"}, - { "baz", 'x', arg_string, &baz_string, "baz", "name" }, -}; - -int main(int argc, char **argv) -{ - int optind = 0; - while(getarg(args, 5, argc, argv, &optind)) - printf("Bad arg: %s\n", argv[optind]); - printf("flag1 = %d\n", flag1); - printf("flag2 = %d\n", flag2); - printf("foo_flag = %d\n", foo_flag); - printf("bar_int = %d\n", bar_int); - printf("baz_flag = %s\n", baz_string); - arg_printusage (args, 5, argv[0], "nothing here"); -} -#endif diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp index 6f4c7e63684..83a546de773 100644 --- a/ndb/src/common/util/socket_io.cpp +++ b/ndb/src/common/util/socket_io.cpp @@ -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; diff --git a/ndb/src/common/util/strlcat.c b/ndb/src/common/util/strlcat.c deleted file mode 100644 index aa282abe48d..00000000000 --- a/ndb/src/common/util/strlcat.c +++ /dev/null @@ -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 diff --git a/ndb/src/common/util/strlcpy.c b/ndb/src/common/util/strlcpy.c deleted file mode 100644 index 97cff177d48..00000000000 --- a/ndb/src/common/util/strlcpy.c +++ /dev/null @@ -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 diff --git a/ndb/src/cw/cpcd/common.cpp b/ndb/src/cw/cpcd/common.cpp index cb1c0c37183..53c0e4d5a64 100644 --- a/ndb/src/cw/cpcd/common.cpp +++ b/ndb/src/cw/cpcd/common.cpp @@ -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; -} diff --git a/ndb/src/cw/cpcd/common.hpp b/ndb/src/cw/cpcd/common.hpp index c3d87b8b9f5..4f5f702762f 100644 --- a/ndb/src/cw/cpcd/common.hpp +++ b/ndb/src/cw/cpcd/common.hpp @@ -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__ */ diff --git a/ndb/src/cw/cpcd/main.cpp b/ndb/src/cw/cpcd/main.cpp index 207b81bfa89..300b51d7b5a 100644 --- a/ndb/src/cw/cpcd/main.cpp +++ b/ndb/src/cw/cpcd/main.cpp @@ -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; - - 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); - } +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, ""); + 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); } diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp index f7b1479cc93..482212911cb 100644 --- a/ndb/src/kernel/blocks/backup/restore/main.cpp +++ b/ndb/src/kernel/blocks/backup/restore/main.cpp @@ -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; +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} +}; + +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(const int argc, const char** argv) +readArguments(int *pargc, char*** pargv) { - - 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) || + 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 diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index d1a8128ea7f..882557daae1 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -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; } diff --git a/ndb/src/kernel/error/ErrorReporter.cpp b/ndb/src/kernel/error/ErrorReporter.cpp index 35c99b30994..35cd3f099d9 100644 --- a/ndb/src/kernel/error/ErrorReporter.cpp +++ b/ndb/src/kernel/error/ErrorReporter.cpp @@ -137,7 +137,7 @@ ErrorReporter::formatMessage(ErrorCategory type, faultID, (problemData == NULL) ? "" : problemData, objRef, - programName, + my_progname, processId, theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>"); diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index fa44704807d..926647838c9 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -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"); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 706f60fd9cf..b3a436275f7 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -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; +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, const char** argv){ +Configuration::init(int argc, char** argv) +{ + const char *load_default_groups[]= { "ndbd",0 }; + load_defaults("my",load_default_groups,&argc,&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", "" }, + int ho_error; + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); - { "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; - } 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) diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index 2ea32ffea37..e4cd64f5ca8 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -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(); diff --git a/ndb/src/kernel/vm/Emulator.hpp b/ndb/src/kernel/vm/Emulator.hpp index bd240f8679b..b3c64830802 100644 --- a/ndb/src/kernel/vm/Emulator.hpp +++ b/ndb/src/kernel/vm/Emulator.hpp @@ -25,6 +25,7 @@ // //=========================================================================== #include <kernel_types.h> +#include <TransporterRegistry.hpp> extern class JobTable globalJobTable; extern class TimeQueue globalTimeQueue; diff --git a/ndb/src/kernel/vm/LongSignal.hpp b/ndb/src/kernel/vm/LongSignal.hpp index f9ed443d995..9818358011f 100644 --- a/ndb/src/kernel/vm/LongSignal.hpp +++ b/ndb/src/kernel/vm/LongSignal.hpp @@ -25,7 +25,7 @@ */ struct SectionSegment { - STATIC_CONST( DataLength = 60 ); + STATIC_CONST( DataLength = NDB_SECTION_SEGMENT_SZ ); Uint32 m_ownerRef; Uint32 m_sz; diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index cc6d4bf600e..a37214d366b 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -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 { diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 29df10630f3..2e30d73290b 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -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; } diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index a5f21b6bc4a..c796e1e9219 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -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]; //************************************************************************** diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 5b552836955..2672d8c9d4b 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -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 diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 5ee48e4cfcc..15767e4766d 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -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(); diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index d7b8a695fe2..75ae539fc8b 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -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); } diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index feab95d8ca5..53c0a0e07f9 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -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,22 +97,24 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm bt.setName(btname); bt.setLogging(t->getLogging()); bt.setFragmentType(t->getFragmentType()); - { NdbDictionary::Column bc("DIST"); + { 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("PART"); + { NdbDictionary::Column bc("DIST"); bc.setType(NdbDictionary::Column::Unsigned); bc.setPrimaryKey(true); + bc.setDistributionKey(true); bt.addColumn(bc); } - { NdbDictionary::Column bc("PK"); + { NdbDictionary::Column bc("PART"); 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; @@ -254,6 +268,13 @@ NdbBlob::isUpdateOp() } inline bool +NdbBlob::isWriteOp() +{ + return + theNdbOp->theOperationType == NdbOperation::WriteRequest; +} + +inline bool NdbBlob::isDeleteOp() { return @@ -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; } @@ -610,32 +636,20 @@ 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); - return 0; -} - -int -NdbBlob::writeData(const void* data, Uint32 bytes) -{ - if (writeData(thePos, data, bytes) == -1) - return -1; - thePos += bytes; + thePos = pos; assert(thePos <= theLength); + DBG("readData [out]"); return 0; } int -NdbBlob::writeData(Uint64 pos, const void* data, Uint32 bytes) +NdbBlob::writeData(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 diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 1457792cf28..4f6468eb4ae 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -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) { diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index cf51a30fe0b..304d1b904d4 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -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: diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 9abde639914..3f174a61b64 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -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() - - - diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index b0b95d0ff43..88d8a000d50 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -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) diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index f1338ae01e4..13664794dcd 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -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 diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index fd63ce96f25..86bac7deb16 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -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; } diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index bc24110ea14..dfb090c8416 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -34,6 +34,7 @@ #include <NdbConfig.h> #include <ndb_version.h> #include <SignalLoggerManager.hpp> +#include <kernel/ndb_limits.h> //#define REPORT_TRANSPORTER //#define API_TRACE; @@ -475,7 +476,8 @@ TransporterFacade::TransporterFacade() : theTransporterRegistry(0), theStopReceive(0), theSendThread(NULL), - theReceiveThread(NULL) + theReceiveThread(NULL), + m_fragmented_signal_id(0) { theOwnId = 0; @@ -833,9 +835,129 @@ TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){ return (ss == SEND_OK ? 0 : -1); } +#define CHUNK_SZ NDB_SECTION_SEGMENT_SZ*64 // related to MAX_MESSAGE_SIZE int TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode, - LinearSectionPtr ptr[3], Uint32 secs){ + LinearSectionPtr ptr[3], Uint32 secs) +{ + if(getIsNodeSendable(aNode) != true) + return -1; + +#ifdef API_TRACE + if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ + Uint32 tmp = aSignal->theSendersBlockRef; + aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); + signalLogger.sendSignal(* aSignal, + 1, + aSignal->getDataPtrSend(), + aNode, + ptr, secs); + aSignal->theSendersBlockRef = tmp; + } +#endif + + NdbApiSignal tmp_signal(*(SignalHeader*)aSignal); + LinearSectionPtr tmp_ptr[3]; + Uint32 unique_id= m_fragmented_signal_id++; // next unique id + unsigned i; + for (i= 0; i < secs; i++) + tmp_ptr[i]= ptr[i]; + + unsigned start_i= 0; + unsigned chunk_sz= 0; + unsigned fragment_info= 0; + Uint32 *tmp_data= tmp_signal.getDataPtrSend(); + for (i= 0; i < secs;) { + unsigned save_sz= tmp_ptr[i].sz; + tmp_data[i-start_i]= i; + if (chunk_sz + save_sz > CHUNK_SZ) { + // truncate + unsigned send_sz= CHUNK_SZ - chunk_sz; + if (i != start_i) // first piece of a new section has to be a multiple of NDB_SECTION_SEGMENT_SZ + { + send_sz= + NDB_SECTION_SEGMENT_SZ + *(send_sz+NDB_SECTION_SEGMENT_SZ-1) + /NDB_SECTION_SEGMENT_SZ; + if (send_sz > save_sz) + send_sz= save_sz; + } + tmp_ptr[i].sz= send_sz; + + if (fragment_info < 2) // 1 = first fragment, 2 = middle fragments + fragment_info++; + + // send tmp_signal + tmp_data[i-start_i+1]= unique_id; + tmp_signal.setLength(i-start_i+2); + tmp_signal.m_fragmentInfo= fragment_info; + tmp_signal.m_noOfSections= i-start_i+1; + // do prepare send + { + SendStatus ss = theTransporterRegistry->prepareSend + (&tmp_signal, + 1, /*JBB*/ + tmp_data, + aNode, + &tmp_ptr[start_i]); + assert(ss != SEND_MESSAGE_TOO_BIG); + if (ss != SEND_OK) return -1; + } + // setup variables for next signal + start_i= i; + chunk_sz= 0; + tmp_ptr[i].sz= save_sz-send_sz; + tmp_ptr[i].p+= send_sz; + if (tmp_ptr[i].sz == 0) + i++; + } + else + { + chunk_sz+=save_sz; + i++; + } + } + + unsigned a_sz= aSignal->getLength(); + + if (fragment_info > 0) { + // update the original signal to include section info + Uint32 *a_data= aSignal->getDataPtrSend(); + unsigned tmp_sz= i-start_i; + memcpy(a_data+a_sz, + tmp_data, + tmp_sz*sizeof(Uint32)); + a_data[a_sz+tmp_sz]= unique_id; + aSignal->setLength(a_sz+tmp_sz+1); + + // send last fragment + aSignal->m_fragmentInfo= 3; // 3 = last fragment + aSignal->m_noOfSections= i-start_i; + } else { + aSignal->m_noOfSections= secs; + } + + // send aSignal + int ret; + { + SendStatus ss = theTransporterRegistry->prepareSend + (aSignal, + 1/*JBB*/, + aSignal->getDataPtrSend(), + aNode, + &tmp_ptr[start_i]); + assert(ss != SEND_MESSAGE_TOO_BIG); + ret = (ss == SEND_OK ? 0 : -1); + } + aSignal->m_noOfSections = 0; + aSignal->m_fragmentInfo = 0; + aSignal->setLength(a_sz); + return ret; +} + +int +TransporterFacade::sendSignal(NdbApiSignal* aSignal, NodeId aNode, + LinearSectionPtr ptr[3], Uint32 secs){ aSignal->m_noOfSections = secs; if(getIsNodeSendable(aNode) == true){ #ifdef API_TRACE @@ -865,39 +987,6 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode, return -1; } - - -int -TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal, - NodeId aNode, - LinearSectionPtr ptr[3], - Uint32 secs){ - aSignal->m_noOfSections = secs; - -#ifdef API_TRACE - if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){ - Uint32 tmp = aSignal->theSendersBlockRef; - aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); - signalLogger.sendSignal(* aSignal, - 1, - aSignal->getDataPtrSend(), - aNode, - ptr, secs); - aSignal->theSendersBlockRef = tmp; - } -#endif - SendStatus ss = theTransporterRegistry->prepareSend(aSignal, - 1, // JBB - aSignal->getDataPtrSend(), - aNode, - ptr); - assert(ss != SEND_MESSAGE_TOO_BIG); - aSignal->m_noOfSections = 0; - return (ss == SEND_OK ? 0 : -1); -} - - - /****************************************************************************** * CONNECTION METHODS Etc ******************************************************************************/ diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 5f473975585..5680e3a6f03 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -69,14 +69,11 @@ public: // Only sends to nodes which are alive int sendSignal(NdbApiSignal * signal, NodeId nodeId); + int sendSignal(NdbApiSignal*, NodeId, + LinearSectionPtr ptr[3], Uint32 secs); int sendFragmentedSignal(NdbApiSignal*, NodeId, LinearSectionPtr ptr[3], Uint32 secs); - //Dirrrrty - int sendFragmentedSignalUnCond(NdbApiSignal*, NodeId, - LinearSectionPtr ptr[3], Uint32 secs); - - // Is node available for running transactions bool get_node_alive(NodeId nodeId) const; bool get_node_stopping(NodeId nodeId) const; @@ -224,7 +221,8 @@ private: } m_threads; Uint32 m_max_trans_id; - + Uint32 m_fragmented_signal_id; + /** * execute function */ diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 20661b89517..17a80082023 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -150,7 +150,7 @@ ErrorBundle ErrorCodes[] = { { 623, IS, "623" }, { 624, IS, "624" }, { 625, IS, "Out of memory in Ndb Kernel, index part" }, - { 826, IS, "826" }, + { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes)" }, { 827, IS, "Out of memory in Ndb Kernel, data part" }, { 832, IS, "832" }, |