From bd537f091372fb3d31cf6356c65ce90cf919ad8d Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:04:37 +0200 Subject: [PATCH 001/188] Backported libedit changes. --- cmd-line-utils/libedit/Makefile.am | 28 +- cmd-line-utils/libedit/chared.c | 45 +- cmd-line-utils/libedit/chared.h | 9 +- cmd-line-utils/libedit/common.c | 27 +- cmd-line-utils/libedit/config.h | 14 - cmd-line-utils/libedit/el.c | 204 +++-- cmd-line-utils/libedit/el.h | 6 +- cmd-line-utils/libedit/el_term.h | 28 +- cmd-line-utils/libedit/emacs.c | 15 +- cmd-line-utils/libedit/hist.c | 8 +- cmd-line-utils/libedit/histedit.h | 24 +- cmd-line-utils/libedit/history.c | 62 +- cmd-line-utils/libedit/key.c | 148 ++-- cmd-line-utils/libedit/key.h | 6 +- cmd-line-utils/libedit/makelist.sh | 16 +- cmd-line-utils/libedit/map.c | 64 +- cmd-line-utils/libedit/np/fgetln.c | 50 +- cmd-line-utils/libedit/np/strlcat.c | 82 +- cmd-line-utils/libedit/np/strlcpy.c | 77 +- cmd-line-utils/libedit/np/unvis.c | 103 ++- cmd-line-utils/libedit/np/vis.c | 413 +++++----- cmd-line-utils/libedit/np/vis.h | 19 +- cmd-line-utils/libedit/parse.c | 12 +- cmd-line-utils/libedit/parse.h | 4 +- cmd-line-utils/libedit/prompt.c | 8 +- cmd-line-utils/libedit/read.c | 60 +- cmd-line-utils/libedit/read.h | 9 +- cmd-line-utils/libedit/readline.c | 838 ++++++++------------- cmd-line-utils/libedit/readline/readline.h | 38 +- cmd-line-utils/libedit/refresh.c | 76 +- cmd-line-utils/libedit/search.c | 9 +- cmd-line-utils/libedit/sig.c | 20 +- cmd-line-utils/libedit/sig.h | 3 +- cmd-line-utils/libedit/sys.h | 27 +- cmd-line-utils/libedit/term.c | 336 ++++++--- cmd-line-utils/libedit/tokenizer.c | 8 +- cmd-line-utils/libedit/tty.c | 89 ++- cmd-line-utils/libedit/tty.h | 6 +- cmd-line-utils/libedit/vi.c | 39 +- 39 files changed, 1644 insertions(+), 1386 deletions(-) diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index bb4b40180d1..ddafa4aab44 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -1,6 +1,4 @@ ## Process this file with automake to create Makefile.in -# Makefile for the GNU readline library. -# Copyright (C) 1994,1996,1997 Free Software Foundation, Inc. ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c AHDR = vi.h emacs.h common.h @@ -12,10 +10,9 @@ noinst_LIBRARIES = libedit.a libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \ search.c tokenizer.c vi.c common.c emacs.c \ hist.c key.c parse.c read.c refresh.c sig.c term.c \ - tty.c help.c fcns.c - -EXTRA_libedit_a_SOURCES = np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ - np/fgetln.c + tty.c help.c fcns.c filecomplete.c \ + np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ + np/fgetln.c libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ @@ -23,22 +20,13 @@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \ - sys.h tokenizer.h config.h hist.h map.h prompt.h read.h \ - search.h tty.h libedit_term.h vis.h + sys.h config.h hist.h map.h prompt.h read.h \ + search.h tty.h filecomplete.h np/vis.h -EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/vis.h np/strlcat.c np/fgetln.c +EXTRA_DIST = makelist.sh CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c -# Make sure to include stuff from this directory first, to get right "config.h" -# Automake puts into DEFAULT_INCLUDES this source and corresponding -# build directory together with ../../include to let all make files -# find the central "config.h". This variable is used before INCLUDES -# above. But in automake 1.10 the order of these are changed. Put the -# includes of this directory into DEFS to always be sure it is first -# before DEFAULT_INCLUDES on the compile line. -DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR -I. -I$(srcdir) - SUFFIXES = .sh .sh: @@ -101,6 +89,4 @@ term.o: vi.h emacs.h common.h help.h fcns.h tty.o: vi.h emacs.h common.h help.h fcns.h help.o: vi.h emacs.h common.h help.h fcns.h fcns.o: vi.h emacs.h common.h help.h fcns.h - -# Don't update the files from bitkeeper -%::SCCS/s.% +filecomplete.o: vi.h emacs.h common.h help.h fcns.h diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index 4cb6e00d26e..e4823db7147 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $ */ +/* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * chared.c: Character editor utilities @@ -40,6 +46,8 @@ #include #include "el.h" +private void ch__clearmacro (EditLine *); + /* value to leave unused in line buffer */ #define EL_LEAVE 2 @@ -51,13 +59,13 @@ cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; c_redo_t *r = &el->el_chared.c_redo; - int size; + unsigned int size; /* Save entire line for undo */ size = el->el_line.lastchar - el->el_line.buffer; vu->len = size; vu->cursor = el->el_line.cursor - el->el_line.buffer; - memcpy(vu->buf, el->el_line.buffer, (size_t)size); + memcpy(vu->buf, el->el_line.buffer, size); /* save command info for redo */ r->count = el->el_state.doingarg ? el->el_state.argument : 0; @@ -439,6 +447,8 @@ cv__endword(char *p, char *high, int n, int (*wtest)(int)) protected int ch_init(EditLine *el) { + c_macro_t *ma = &el->el_chared.c_macro; + el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); if (el->el_line.buffer == NULL) return (-1); @@ -479,11 +489,10 @@ ch_init(EditLine *el) el->el_state.argument = 1; el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.level = -1; - el->el_chared.c_macro.offset = 0; - el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * - sizeof(char *)); - if (el->el_chared.c_macro.macro == NULL) + ma->level = -1; + ma->offset = 0; + ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *)); + if (ma->macro == NULL) return (-1); return (0); } @@ -492,7 +501,7 @@ ch_init(EditLine *el) * Reset the character editor */ protected void -ch_reset(EditLine *el) +ch_reset(EditLine *el, int mclear) { el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; @@ -513,9 +522,19 @@ ch_reset(EditLine *el) el->el_state.argument = 1; el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.level = -1; - el->el_history.eventno = 0; + + if (mclear) + ch__clearmacro(el); +} + +private void +ch__clearmacro(el) + EditLine *el; +{ + c_macro_t *ma = &el->el_chared.c_macro; + while (ma->level >= 0) + el_free((ptr_t)ma->macro[ma->level--]); } /* ch_enlargebufs(): @@ -623,9 +642,9 @@ ch_end(EditLine *el) el->el_chared.c_redo.cmd = ED_UNASSIGNED; el_free((ptr_t) el->el_chared.c_kill.buf); el->el_chared.c_kill.buf = NULL; + ch_reset(el, 1); el_free((ptr_t) el->el_chared.c_macro.macro); el->el_chared.c_macro.macro = NULL; - ch_reset(el); } diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h index 2dd0a5795c7..fa8f5a58d83 100644 --- a/cmd-line-utils/libedit/chared.h +++ b/cmd-line-utils/libedit/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,7 +48,7 @@ #define EL_MAXMACRO 10 /* - * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works + * This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works * like real vi: i.e. the transition from command<->insert modes moves * the cursor. * @@ -116,11 +116,10 @@ typedef struct el_chared_t { } el_chared_t; -#define STReof "^D\b\b" #define STRQQ "\"\"" #define isglob(a) (strchr("*[]?", (a)) != NULL) -#define isword(a) (isprint(a)) +#define isword(a) (el_isprint(a)) #define NOP 0x00 #define DELETE 0x01 @@ -161,7 +160,7 @@ protected int c_gets(EditLine *, char *, const char *); protected int c_hpos(EditLine *); protected int ch_init(EditLine *); -protected void ch_reset(EditLine *); +protected void ch_reset(EditLine *, int); protected int ch_enlargebufs(EditLine *, size_t); protected void ch_end(EditLine *); diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index 81bf9bf29ff..d4d024eae10 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */ +/* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * common.c: Common Editor functions @@ -130,7 +136,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) +ed_delete_next_char(EditLine *el, int c) { #ifdef notdef /* XXX */ #define EL el->el_line @@ -147,9 +153,8 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) #ifdef KSHVI return (CC_ERROR); #else - term_overwrite(el, STReof, 4); - /* then do a EOF */ - term__flush(); + /* then do an EOF */ + term_writechar(el, c); return (CC_EOF); #endif } else { @@ -207,13 +212,13 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) el->el_line.cursor = el->el_line.lastchar; if (el->el_map.type == MAP_VI) { -#ifdef VI_MOVE - el->el_line.cursor--; -#endif if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } +#ifdef VI_MOVE + el->el_line.cursor--; +#endif } return (CC_CURSOR); } @@ -609,7 +614,7 @@ protected el_action_t ed_start_over(EditLine *el, int c __attribute__((__unused__))) { - ch_reset(el); + ch_reset(el, 0); return (CC_REFRESH); } @@ -904,7 +909,7 @@ ed_command(EditLine *el, int c __attribute__((__unused__))) int tmplen; tmplen = c_gets(el, tmpbuf, "\n: "); - term__putc('\n'); + term__putc(el, '\n'); if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) term_beep(el); diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h index 642123d1ddc..2c3989ee316 100644 --- a/cmd-line-utils/libedit/config.h +++ b/cmd-line-utils/libedit/config.h @@ -1,16 +1,2 @@ - #include "my_config.h" #include "sys.h" - -#if defined(LIBC_SCCS) && !defined(lint) -#define __RCSID(x) -#define __COPYRIGHT(x) -#endif -#define __RENAME(x) -#define _DIAGASSERT(x) - -#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) -#define __attribute__(A) -#endif - - diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c index c32a01b2151..d99946eb68f 100644 --- a/cmd-line-utils/libedit/el.c +++ b/cmd-line-utils/libedit/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $ */ +/* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * el.c: EditLine interface functions @@ -58,9 +64,12 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) memset(el, 0, sizeof(EditLine)); - el->el_infd = fileno(fin); + el->el_infile = fin; el->el_outfile = fout; el->el_errfile = ferr; + + el->el_infd = fileno(fin); + if ((el->el_prog = el_strdup(prog)) == NULL) { el_free(el); return NULL; @@ -126,7 +135,7 @@ el_reset(EditLine *el) { tty_cookedmode(el); - ch_reset(el); /* XXX: Do we want that? */ + ch_reset(el, 0); /* XXX: Do we want that? */ } @@ -136,29 +145,29 @@ el_reset(EditLine *el) public int el_set(EditLine *el, int op, ...) { - va_list va; + va_list ap; int rv = 0; if (el == NULL) return (-1); - va_start(va, op); + va_start(ap, op); switch (op) { case EL_PROMPT: case EL_RPROMPT: - rv = prompt_set(el, va_arg(va, el_pfunc_t), op); + rv = prompt_set(el, va_arg(ap, el_pfunc_t), op); break; case EL_TERMINAL: - rv = term_set(el, va_arg(va, char *)); + rv = term_set(el, va_arg(ap, char *)); break; case EL_EDITOR: - rv = map_set_editor(el, va_arg(va, char *)); + rv = map_set_editor(el, va_arg(ap, char *)); break; case EL_SIGNAL: - if (va_arg(va, int)) + if (va_arg(ap, int)) el->el_flags |= HANDLE_SIGNALS; else el->el_flags &= ~HANDLE_SIGNALS; @@ -167,6 +176,7 @@ el_set(EditLine *el, int op, ...) case EL_BIND: case EL_TELLTC: case EL_SETTC: + case EL_GETTC: case EL_ECHOTC: case EL_SETTY: { @@ -174,7 +184,7 @@ el_set(EditLine *el, int op, ...) int i; for (i = 1; i < 20; i++) - if ((argv[i] = va_arg(va, char *)) == NULL) + if ((argv[i] = va_arg(ap, char *)) == NULL) break; switch (op) { @@ -213,9 +223,9 @@ el_set(EditLine *el, int op, ...) case EL_ADDFN: { - char *name = va_arg(va, char *); - char *help = va_arg(va, char *); - el_func_t func = va_arg(va, el_func_t); + char *name = va_arg(ap, char *); + char *help = va_arg(ap, char *); + el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); break; @@ -223,15 +233,15 @@ el_set(EditLine *el, int op, ...) case EL_HIST: { - hist_fun_t func = va_arg(va, hist_fun_t); - ptr_t ptr = va_arg(va, char *); + hist_fun_t func = va_arg(ap, hist_fun_t); + ptr_t ptr = va_arg(ap, char *); rv = hist_set(el, func, ptr); break; } case EL_EDITMODE: - if (va_arg(va, int)) + if (va_arg(ap, int)) el->el_flags &= ~EDIT_DISABLED; else el->el_flags |= EDIT_DISABLED; @@ -240,17 +250,17 @@ el_set(EditLine *el, int op, ...) case EL_GETCFN: { - el_rfunc_t rc = va_arg(va, el_rfunc_t); + el_rfunc_t rc = va_arg(ap, el_rfunc_t); rv = el_read_setfn(el, rc); break; } case EL_CLIENTDATA: - el->el_data = va_arg(va, void *); + el->el_data = va_arg(ap, void *); break; case EL_UNBUFFERED: - rv = va_arg(va, int); + rv = va_arg(ap, int); if (rv && !(el->el_flags & UNBUFFERED)) { el->el_flags |= UNBUFFERED; read_prepare(el); @@ -262,7 +272,7 @@ el_set(EditLine *el, int op, ...) break; case EL_PREP_TERM: - rv = va_arg(va, int); + rv = va_arg(ap, int); if (rv) (void) tty_rawmode(el); else @@ -270,12 +280,45 @@ el_set(EditLine *el, int op, ...) rv = 0; break; + case EL_SETFP: + { + FILE *fp; + int what; + + what = va_arg(ap, int); + fp = va_arg(ap, FILE *); + + rv = 0; + switch (what) { + case 0: + el->el_infile = fp; + el->el_infd = fileno(fp); + break; + case 1: + el->el_outfile = fp; + break; + case 2: + el->el_errfile = fp; + break; + default: + rv = -1; + break; + } + break; + } + + case EL_REFRESH: + re_clear_display(el); + re_refresh(el); + term__flush(el); + break; + default: rv = -1; break; } - va_end(va); + va_end(ap); return (rv); } @@ -284,90 +327,71 @@ el_set(EditLine *el, int op, ...) * retrieve the editline parameters */ public int -el_get(EditLine *el, int op, void *ret) +el_get(EditLine *el, int op, ...) { + va_list ap; int rv; - if (el == NULL || ret == NULL) - return (-1); + if (el == NULL) + return -1; + + va_start(ap, op); + switch (op) { case EL_PROMPT: case EL_RPROMPT: - rv = prompt_get(el, (void *) &ret, op); + rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op); break; case EL_EDITOR: - rv = map_get_editor(el, (void *) &ret); + rv = map_get_editor(el, va_arg(ap, const char **)); break; case EL_SIGNAL: - *((int *) ret) = (el->el_flags & HANDLE_SIGNALS); + *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS); rv = 0; break; case EL_EDITMODE: - *((int *) ret) = (!(el->el_flags & EDIT_DISABLED)); + *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED); rv = 0; break; case EL_TERMINAL: - term_get(el, (const char **)ret); + term_get(el, va_arg(ap, const char **)); rv = 0; break; -#if 0 /* XXX */ - case EL_BIND: - case EL_TELLTC: - case EL_SETTC: - case EL_ECHOTC: - case EL_SETTY: + case EL_GETTC: { - const char *argv[20]; + static char name[] = "gettc"; + char *argv[20]; int i; - for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++) - if ((argv[i] = va_arg(va, char *)) == NULL) + for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++) + if ((argv[i] = va_arg(ap, char *)) == NULL) break; switch (op) { - case EL_BIND: - argv[0] = "bind"; - rv = map_bind(el, i, argv); - break; - - case EL_TELLTC: - argv[0] = "telltc"; - rv = term_telltc(el, i, argv); - break; - - case EL_SETTC: - argv[0] = "settc"; - rv = term_settc(el, i, argv); - break; - - case EL_ECHOTC: - argv[0] = "echotc"; - rv = term_echotc(el, i, argv); - break; - - case EL_SETTY: - argv[0] = "setty"; - rv = tty_stty(el, i, argv); + case EL_GETTC: + argv[0] = name; + rv = term_gettc(el, i, argv); break; default: rv = -1; - EL_ABORT((el->errfile, "Bad op %d\n", op)); + EL_ABORT((el->el_errfile, "Bad op %d\n", op)); break; } break; } +#if 0 /* XXX */ case EL_ADDFN: { - char *name = va_arg(va, char *); - char *help = va_arg(va, char *); - el_func_t func = va_arg(va, el_func_t); + char *name = va_arg(ap, char *); + char *help = va_arg(ap, char *); + el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); break; @@ -375,31 +399,57 @@ el_get(EditLine *el, int op, void *ret) case EL_HIST: { - hist_fun_t func = va_arg(va, hist_fun_t); - ptr_t ptr = va_arg(va, char *); + hist_fun_t func = va_arg(ap, hist_fun_t); + ptr_t ptr = va_arg(ap, char *); rv = hist_set(el, func, ptr); } break; #endif /* XXX */ case EL_GETCFN: - *((el_rfunc_t *)ret) = el_read_getfn(el); + *va_arg(ap, el_rfunc_t *) = el_read_getfn(el); rv = 0; break; case EL_CLIENTDATA: - *((void **)ret) = el->el_data; + *va_arg(ap, void **) = el->el_data; rv = 0; break; case EL_UNBUFFERED: - *((int *) ret) = (!(el->el_flags & UNBUFFERED)); + *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED)); rv = 0; break; + case EL_GETFP: + { + int what; + FILE **fpp; + + what = va_arg(ap, int); + fpp = va_arg(ap, FILE **); + rv = 0; + switch (what) { + case 0: + *fpp = el->el_infile; + break; + case 1: + *fpp = el->el_outfile; + break; + case 2: + *fpp = el->el_errfile; + break; + default: + rv = -1; + break; + } + break; + } default: rv = -1; + break; } + va_end(ap); return (rv); } @@ -428,17 +478,17 @@ el_source(EditLine *el, const char *fname) fp = NULL; if (fname == NULL) { +#ifdef HAVE_ISSETUGID static const char elpath[] = "/.editrc"; +/* XXXMYSQL: Portability fix (for which platforms?) */ #ifdef MAXPATHLEN char path[MAXPATHLEN]; #else char path[4096]; #endif -#ifdef HAVE_ISSETUGID if (issetugid()) return (-1); -#endif if ((ptr = getenv("HOME")) == NULL) return (-1); if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) @@ -446,6 +496,14 @@ el_source(EditLine *el, const char *fname) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) return (-1); fname = path; +#else + /* + * If issetugid() is missing, always return an error, in order + * to keep from inadvertently opening up the user to a security + * hole. + */ + return (-1); +#endif } if (fp == NULL) fp = fopen(fname, "r"); diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h index d9379d7c8aa..05d88ad88ba 100644 --- a/cmd-line-utils/libedit/el.h +++ b/cmd-line-utils/libedit/el.h @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */ +/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -110,6 +110,7 @@ typedef struct el_state_t { struct editline { char *el_prog; /* the program name */ + FILE *el_infile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */ int el_infd; /* Input file descriptor */ @@ -136,7 +137,8 @@ struct editline { protected int el_editmode(EditLine *, int, const char **); -#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) +/* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */ +#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) #ifdef DEBUG #define EL_ABORT(a) do { \ diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h index 00ca48e38e2..0e7ddd555f4 100644 --- a/cmd-line-utils/libedit/el_term.h +++ b/cmd-line-utils/libedit/el_term.h @@ -1,4 +1,4 @@ -/* $NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $ */ +/* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -81,25 +81,6 @@ typedef struct { #define A_K_EN 5 #define A_K_NKEYS 6 -#ifdef _SUNOS -extern int tgetent(char *, const char *); -extern int tgetflag(char *); -extern int tgetnum(char *); -extern int tputs(const char *, int, int (*)(int)); -extern char* tgoto(const char*, int, int); -extern char* tgetstr(char*, char**); -#endif - - -#if !HAVE_DECL_TGOTO -/* - 'tgoto' is not declared in the system header files, this causes - problems on 64-bit systems. The function returns a 64 bit pointer - but caller see it as "int" and it's thus truncated to 32-bit -*/ -extern char* tgoto(const char*, int, int); -#endif - protected void term_move_to_line(EditLine *, int); protected void term_move_to_char(EditLine *, int); protected void term_clear_EOL(EditLine *, int); @@ -119,10 +100,12 @@ protected void term_end(EditLine *); protected void term_get(EditLine *, const char **); protected int term_set(EditLine *, const char *); protected int term_settc(EditLine *, int, const char **); +protected int term_gettc(EditLine *, int, char **); protected int term_telltc(EditLine *, int, const char **); protected int term_echotc(EditLine *, int, const char **); -protected int term__putc(int); -protected void term__flush(void); +protected void term_writec(EditLine *, int); +protected int term__putc(EditLine *, int); +protected void term__flush(EditLine *); /* * Easy access macros @@ -134,6 +117,7 @@ protected void term__flush(void); #define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) #define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) #define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) +#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP) #define EL_HAS_META (EL_FLAGS & TERM_HAS_META) #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c index 79f2bf0c818..135bd75f566 100644 --- a/cmd-line-utils/libedit/emacs.c +++ b/cmd-line-utils/libedit/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */ +/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * emacs.c: Emacs functions @@ -45,15 +51,14 @@ */ protected el_action_t /*ARGSUSED*/ -em_delete_or_list(EditLine *el, int c __attribute__((__unused__))) +em_delete_or_list(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */ if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); + term_writec(el, c); /* then do an EOF */ return (CC_EOF); } else { /* diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c index e8f5c0f39ba..c0b23ee6641 100644 --- a/cmd-line-utils/libedit/hist.c +++ b/cmd-line-utils/libedit/hist.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index c58eb62dcfa..37823141c06 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $ */ +/* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,11 +41,15 @@ #define _HISTEDIT_H_ #define LIBEDIT_MAJOR 2 -#define LIBEDIT_MINOR 9 +#define LIBEDIT_MINOR 11 #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* * ==== Editing ==== */ @@ -88,7 +92,7 @@ void el_reset(EditLine *); */ const char *el_gets(EditLine *, int *); int el_getc(EditLine *, char *); -void el_push(EditLine *, char *); +void el_push(EditLine *, const char *); /* * Beep! @@ -105,7 +109,8 @@ int el_parse(EditLine *, int, const char **); * Low level editline access functions */ int el_set(EditLine *, int, ...); -int el_get(EditLine *, int, void *); +int el_get(EditLine *, int, ...); +unsigned char _el_fn_complete(EditLine *, int); /* * el_set/el_get parameters @@ -128,8 +133,12 @@ int el_get(EditLine *, int, void *); #define EL_CLIENTDATA 14 /* , void *); */ #define EL_UNBUFFERED 15 /* , int); */ #define EL_PREP_TERM 16 /* , int); */ +#define EL_GETTC 17 /* , const char *, ..., NULL); */ +#define EL_GETFP 18 /* , int, FILE **); */ +#define EL_SETFP 19 /* , int, FILE *); */ +#define EL_REFRESH 20 /* , void); */ -#define EL_BUILTIN_GETCFN (NULL) +#define EL_BUILTIN_GETCFN (NULL) /* * Source named file or $PWD/.editrc or $HOME/.editrc @@ -192,6 +201,7 @@ int history(History *, HistEvent *, int, ...); #define H_CLEAR 19 /* , void); */ #define H_SETUNIQUE 20 /* , int); */ #define H_GETUNIQUE 21 /* , void); */ +#define H_DEL 22 /* , int); */ /* @@ -211,4 +221,8 @@ int tok_line(Tokenizer *, const LineInfo *, int tok_str(Tokenizer *, const char *, int *, const char ***); +#ifdef __cplusplus +} +#endif + #endif /* _HISTEDIT_H_ */ diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index c0fa7cc717d..3080dd231f6 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $ */ +/* $NetBSD: history.c,v 1.33 2009/02/06 14:40:32 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions @@ -40,7 +46,11 @@ #include #include #include +#ifdef HAVE_VIS_H #include +#else +#include "np/vis.h" +#endif #include static const char hist_cookie[] = "_HiStOrY_V2_\n"; @@ -61,6 +71,7 @@ struct history { history_gfun_t h_prev; /* Get the previous element */ history_gfun_t h_curr; /* Get the current element */ history_sfun_t h_set; /* Set the current element */ + history_sfun_t h_del; /* Set the given element */ history_vfun_t h_clear; /* Clear the history list */ history_efun_t h_enter; /* Add an element */ history_efun_t h_add; /* Append to an element */ @@ -75,6 +86,7 @@ struct history { #define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) +#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) #define h_strdup(a) strdup(a) #define h_malloc(a) malloc(a) @@ -122,16 +134,18 @@ typedef struct history_t { #define H_UNIQUE 1 /* Store only unique elements */ } history_t; -private int history_def_first(ptr_t, HistEvent *); -private int history_def_last(ptr_t, HistEvent *); private int history_def_next(ptr_t, HistEvent *); +private int history_def_first(ptr_t, HistEvent *); private int history_def_prev(ptr_t, HistEvent *); +private int history_def_last(ptr_t, HistEvent *); private int history_def_curr(ptr_t, HistEvent *); -private int history_def_set(ptr_t, HistEvent *, const int n); +private int history_def_set(ptr_t, HistEvent *, const int); +private void history_def_clear(ptr_t, HistEvent *); private int history_def_enter(ptr_t, HistEvent *, const char *); private int history_def_add(ptr_t, HistEvent *, const char *); +private int history_def_del(ptr_t, HistEvent *, const int); + private int history_def_init(ptr_t *, HistEvent *, int); -private void history_def_clear(ptr_t, HistEvent *); private int history_def_insert(history_t *, HistEvent *, const char *); private void history_def_delete(history_t *, HistEvent *, hentry_t *); @@ -353,6 +367,24 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) } +/* history_def_del(): + * Delete element hp of the h list + */ +/* ARGSUSED */ +private int +history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)), + const int num) +{ + history_t *h = (history_t *) p; + if (history_def_set(h, ev, num) != 0) + return (-1); + ev->str = strdup(h->cursor->ev.str); + ev->num = h->cursor->ev.num; + history_def_delete(h, ev, h->cursor); + return (0); +} + + /* history_def_delete(): * Delete element hp of the h list */ @@ -364,6 +396,8 @@ history_def_delete(history_t *h, HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) abort(); + if (h->cursor == hp) + h->cursor = hp->prev; hp->prev->next = hp->next; hp->next->prev = hp->prev; h_free((ptr_t) evp->str); @@ -497,6 +531,7 @@ history_init(void) h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; + h->h_del = history_def_del; return (h); } @@ -512,6 +547,8 @@ history_end(History *h) if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); + h_free(h->h_ref); + h_free(h); } @@ -597,7 +634,7 @@ history_set_fun(History *h, History *nh) if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || - nh->h_ref == NULL) { + nh->h_del == NULL || nh->h_ref == NULL) { if (h->h_next != history_def_next) { history_def_init(&h->h_ref, &ev, 0); h->h_first = history_def_first; @@ -609,6 +646,7 @@ history_set_fun(History *h, History *nh) h->h_clear = history_def_clear; h->h_enter = history_def_enter; h->h_add = history_def_add; + h->h_del = history_def_del; } return (-1); } @@ -625,6 +663,7 @@ history_set_fun(History *h, History *nh) h->h_clear = nh->h_clear; h->h_enter = nh->h_enter; h->h_add = nh->h_add; + h->h_del = nh->h_del; return (0); } @@ -676,8 +715,8 @@ history_load(History *h, const char *fname) (void) strunvis(ptr, line); line[sz] = c; if (HENTER(h, &ev, ptr) == -1) { - i = -1; - goto oomem; + i = -1; + goto oomem; } } oomem: @@ -841,6 +880,10 @@ history(History *h, HistEvent *ev, int fun, ...) retval = HADD(h, ev, str); break; + case H_DEL: + retval = HDEL(h, ev, va_arg(va, const int)); + break; + case H_ENTER: str = va_arg(va, const char *); if ((retval = HENTER(h, ev, str)) != -1) @@ -925,6 +968,7 @@ history(History *h, HistEvent *ev, int fun, ...) hf.h_clear = va_arg(va, history_vfun_t); hf.h_enter = va_arg(va, history_efun_t); hf.h_add = va_arg(va, history_efun_t); + hf.h_del = va_arg(va, history_sfun_t); if ((retval = history_set_fun(h, &hf)) == -1) he_seterrev(ev, _HE_PARAM_MISSING); diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c index 35fcf0651b2..cda02816861 100644 --- a/cmd-line-utils/libedit/key.c +++ b/cmd-line-utils/libedit/key.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $ */ +/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,14 +32,20 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * key.c: This module contains the procedures for maintaining * the extended-key map. * * An extended-key (key) is a sequence of keystrokes introduced - * with an sequence introducer and consisting of an arbitrary + * with a sequence introducer and consisting of an arbitrary * number of characters. This module maintains a map (the el->el_key.map) * to convert these extended-key sequences into input strs * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). @@ -78,12 +84,12 @@ private int node_trav(EditLine *, key_node_t *, char *, private int node__try(EditLine *, key_node_t *, const char *, key_value_t *, int); private key_node_t *node__get(int); +private void node__free(key_node_t *); private void node__put(EditLine *, key_node_t *); private int node__delete(EditLine *, key_node_t **, const char *); private int node_lookup(EditLine *, const char *, key_node_t *, int); private int node_enum(EditLine *, key_node_t *, int); -private int key__decode_char(char *, int, int); #define KEY_BUFSIZ EL_BUFSIZ @@ -103,7 +109,6 @@ key_init(EditLine *el) return (0); } - /* key_end(): * Free the key maps */ @@ -113,8 +118,7 @@ key_end(EditLine *el) el_free((ptr_t) el->el_key.buf); el->el_key.buf = NULL; - /* XXX: provide a function to clear the keys */ - el->el_key.map = NULL; + node__free(el->el_key.map); } @@ -443,7 +447,7 @@ node__put(EditLine *el, key_node_t *ptr) /* node__get(): - * Returns pointer to an key_node_t for ch. + * Returns pointer to a key_node_t for ch. */ private key_node_t * node__get(int ch) @@ -461,7 +465,15 @@ node__get(int ch) return (ptr); } - +private void +node__free(key_node_t *k) +{ + if (k == NULL) + return; + node__free(k->sibling); + node__free(k->next); + el_free((ptr_t) k); +} /* node_lookup(): * look for the str starting at node ptr. @@ -483,7 +495,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) /* If match put this char into el->el_key.buf. Recurse */ if (ptr->ch == *str) { /* match found */ - ncnt = key__decode_char(el->el_key.buf, cnt, + ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, (unsigned char) ptr->ch); if (ptr->next != NULL) /* not yet at leaf */ @@ -537,7 +549,8 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt) return (-1); } /* put this char at end of str */ - ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); + ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, + (unsigned char)ptr->ch); if (ptr->next == NULL) { /* print this key and function */ el->el_key.buf[ncnt + 1] = '"'; @@ -568,9 +581,10 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) switch (ntype) { case XK_STR: case XK_EXE: - (void) fprintf(el->el_outfile, fmt, key, - key__decode_str(val->str, unparsbuf, - ntype == XK_STR ? "\"\"" : "[]")); + (void) key__decode_str(val->str, unparsbuf, + sizeof(unparsbuf), + ntype == XK_STR ? "\"\"" : "[]"); + (void) fprintf(el->el_outfile, fmt, key, unparsbuf); break; case XK_CMD: for (fp = el->el_map.help; fp->name; fp++) @@ -595,83 +609,97 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) } +#define ADDC(c) \ + if (b < eb) \ + *b++ = c; \ + else \ + b++ /* key__decode_char(): * Put a printable form of char in buf. */ -private int -key__decode_char(char *buf, int cnt, int ch) +protected int +key__decode_char(char *buf, int cnt, int off, int ch) { + char *sb = buf + off; + char *eb = buf + cnt; + char *b = sb; if (ch == 0) { - buf[cnt++] = '^'; - buf[cnt] = '@'; - return (cnt); + ADDC('^'); + ADDC('@'); + return b - sb; } if (iscntrl(ch)) { - buf[cnt++] = '^'; + ADDC('^'); if (ch == '\177') - buf[cnt] = '?'; + ADDC('?'); else - buf[cnt] = ch | 0100; + ADDC(ch | 0100); } else if (ch == '^') { - buf[cnt++] = '\\'; - buf[cnt] = '^'; + ADDC('\\'); + ADDC('^'); } else if (ch == '\\') { - buf[cnt++] = '\\'; - buf[cnt] = '\\'; + ADDC('\\'); + ADDC('\\'); } else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) { - buf[cnt] = ch; + ADDC(ch); } else { - buf[cnt++] = '\\'; - buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0'; - buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0'; - buf[cnt] = (ch & 7) + '0'; + ADDC('\\'); + ADDC((((unsigned int) ch >> 6) & 7) + '0'); + ADDC((((unsigned int) ch >> 3) & 7) + '0'); + ADDC((ch & 7) + '0'); } - return (cnt); + return b - sb; } /* key__decode_str(): * Make a printable version of the ey */ -protected char * -key__decode_str(const char *str, char *buf, const char *sep) +protected int +key__decode_str(const char *str, char *buf, int len, const char *sep) { - char *b; + char *b = buf, *eb = b + len; const char *p; b = buf; - if (sep[0] != '\0') - *b++ = sep[0]; - if (*str == 0) { - *b++ = '^'; - *b++ = '@'; - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return (buf); + if (sep[0] != '\0') { + ADDC(sep[0]); + } + if (*str == '\0') { + ADDC('^'); + ADDC('@'); + if (sep[0] != '\0' && sep[1] != '\0') { + ADDC(sep[1]); + } + goto done; } for (p = str; *p != 0; p++) { if (iscntrl((unsigned char) *p)) { - *b++ = '^'; - if (*p == '\177') - *b++ = '?'; - else - *b++ = *p | 0100; + ADDC('^'); + if (*p == '\177') { + ADDC('?'); + } else { + ADDC(*p | 0100); + } } else if (*p == '^' || *p == '\\') { - *b++ = '\\'; - *b++ = *p; + ADDC('\\'); + ADDC(*p); } else if (*p == ' ' || (el_isprint((unsigned char) *p) && !isspace((unsigned char) *p))) { - *b++ = *p; + ADDC(*p); } else { - *b++ = '\\'; - *b++ = (((unsigned int) *p >> 6) & 7) + '0'; - *b++ = (((unsigned int) *p >> 3) & 7) + '0'; - *b++ = (*p & 7) + '0'; + ADDC('\\'); + ADDC((((unsigned int) *p >> 6) & 7) + '0'); + ADDC((((unsigned int) *p >> 3) & 7) + '0'); + ADDC((*p & 7) + '0'); } } - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return (buf); /* should check for overflow */ + if (sep[0] != '\0' && sep[1] != '\0') { + ADDC(sep[1]); + } +done: + ADDC('\0'); + if (b - buf >= len) + buf[len - 1] = '\0'; + return b - buf; } diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h index 39a075c504e..9c6844e6d99 100644 --- a/cmd-line-utils/libedit/key.h +++ b/cmd-line-utils/libedit/key.h @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -74,6 +74,8 @@ protected int key_delete(EditLine *, const char *); protected void key_print(EditLine *, const char *); protected void key_kprint(EditLine *, const char *, key_value_t *, int); -protected char *key__decode_str(const char *, char *, const char *); +protected int key__decode_str(const char *, char *, int, + const char *); +protected int key__decode_char(char *, int, int, int); #endif /* _h_el_key */ diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh index f15b3d1eb9f..5d25b4776c9 100644 --- a/cmd-line-utils/libedit/makelist.sh +++ b/cmd-line-utils/libedit/makelist.sh @@ -1,5 +1,5 @@ #!/bin/sh - -# $NetBSD: makelist,v 1.8 2003/03/10 21:21:10 christos Exp $ +# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -15,11 +15,7 @@ # 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. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 4. Neither the name of the University nor the names of its contributors +# 3. Neither the name of the University nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # @@ -68,6 +64,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2,"(") - 1); # # XXX: need a space between name and prototype so that -fc and -fh @@ -97,6 +94,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2,"(") - 1); uname = ""; fname = ""; @@ -117,13 +115,13 @@ case $FLAG in printf(" \""); for (i = 2; i < NF; i++) printf("%s ", $i); - sub("\r", "", $i); + # XXXMYSQL: support CRLF + sub("\r", "", $i); printf("%s\" },\n", $i); ok = 0; } } END { - printf(" { NULL, 0, NULL }\n"); printf("};\n"); printf("\nprotected const el_bindings_t* help__get()"); printf("{ return el_func_help; }\n"); @@ -144,6 +142,7 @@ case $FLAG in # generate fcns.h from various .h files # +# XXXMYSQL: use portable tr syntax -fh) cat $FILES | $AWK '/el_action_t/ { print $3 }' | \ sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK ' @@ -220,6 +219,7 @@ case $FLAG in /\(\):/ { pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { + # XXXMYSQL: support CRLF name = substr($2, 1, index($2, "(") - 1); fname = ""; for (i = 1; i <= length(name); i++) { diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c index 6be9279b5e5..693b56c82ba 100644 --- a/cmd-line-utils/libedit/map.c +++ b/cmd-line-utils/libedit/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * map.c: Editor function definitions @@ -1118,11 +1124,12 @@ private void map_print_key(EditLine *el, el_action_t *map, const char *in) { char outbuf[EL_BUFSIZ]; - el_bindings_t *bp; + el_bindings_t *bp, *ep; if (in[0] == '\0' || in[1] == '\0') { - (void) key__decode_str(in, outbuf, ""); - for (bp = el->el_map.help; bp->name != NULL; bp++) + (void) key__decode_str(in, outbuf, sizeof(outbuf), ""); + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) if (bp->func == map[(unsigned char) *in]) { (void) fprintf(el->el_outfile, "%s\t->\t%s\n", outbuf, bp->name); @@ -1139,7 +1146,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in) private void map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) { - el_bindings_t *bp; + el_bindings_t *bp, *ep; char firstbuf[2], lastbuf[2]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; @@ -1148,39 +1155,47 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) lastbuf[0] = last; lastbuf[1] = 0; if (map[first] == ED_UNASSIGNED) { - if (first == last) + if (first == last) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "%-15s-> is undefined\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "%-15s-> is undefined\n", unparsbuf); + } return; } - for (bp = el->el_map.help; bp->name != NULL; bp++) { + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) { if (bp->func == map[first]) { if (first == last) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, "%-15s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - bp->name); + unparsbuf, bp->name); } else { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); + (void) key__decode_str(lastbuf, extrabuf, + sizeof(extrabuf), STRQQ); (void) fprintf(el->el_outfile, "%-4s to %-7s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - key__decode_str(lastbuf, extrabuf, STRQQ), - bp->name); + unparsbuf, extrabuf, bp->name); } return; } } #ifdef MAP_DEBUG if (map == el->el_map.key) { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "BUG!!! %s isn't bound to anything.\n", unparsbuf); (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", first, el->el_map.key[first]); } else { + (void) key__decode_str(firstbuf, unparsbuf, + sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); + "BUG!!! %s isn't bound to anything.\n", unparsbuf); (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", first, el->el_map.alt[first]); } @@ -1237,7 +1252,7 @@ map_bind(EditLine *el, int argc, const char **argv) char outbuf[EL_BUFSIZ]; const char *in = NULL; char *out = NULL; - el_bindings_t *bp; + el_bindings_t *bp, *ep; int cmd; int key; @@ -1279,8 +1294,8 @@ map_bind(EditLine *el, int argc, const char **argv) return (0); case 'l': - for (bp = el->el_map.help; bp->name != NULL; - bp++) + ep = &el->el_map.help[el->el_map.nfunc]; + for (bp = el->el_map.help; bp < ep; bp++) (void) fprintf(el->el_outfile, "%s\n\t%s\n", bp->name, bp->description); @@ -1367,7 +1382,7 @@ map_bind(EditLine *el, int argc, const char **argv) break; default: - EL_ABORT((el->el_errfile, "Bad XK_ type\n", ntype)); + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); break; } return (0); @@ -1381,7 +1396,7 @@ protected int map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) { void *p; - int nf = el->el_map.nfunc + 2; + int nf = el->el_map.nfunc + 1; if (name == NULL || help == NULL || func == NULL) return (-1); @@ -1400,7 +1415,6 @@ map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) el->el_map.help[nf].name = name; el->el_map.help[nf].func = nf; el->el_map.help[nf].description = help; - el->el_map.help[++nf].name = NULL; el->el_map.nfunc++; return (0); diff --git a/cmd-line-utils/libedit/np/fgetln.c b/cmd-line-utils/libedit/np/fgetln.c index 93da9914dc8..898abc758dc 100644 --- a/cmd-line-utils/libedit/np/fgetln.c +++ b/cmd-line-utils/libedit/np/fgetln.c @@ -1,4 +1,4 @@ -/* $NetBSD: fgetln.c,v 1.1.1.1 1999/04/12 07:43:21 crooksa Exp $ */ +/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -36,17 +29,24 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifdef HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" -#include +#endif + +#if !HAVE_FGETLN #include +#ifndef HAVE_NBTOOL_CONFIG_H +/* These headers are required, but included from nbtool_config.h */ +#include #include #include #include +#endif char * -fgetln(fp, len) - FILE *fp; - size_t *len; +fgetln(FILE *fp, size_t *len) { static char *buf = NULL; static size_t bufsiz = 0; @@ -61,8 +61,8 @@ fgetln(fp, len) if (fgets(buf, bufsiz, fp) == NULL) return NULL; - *len = 0; + *len = 0; while ((ptr = strchr(&buf[*len], '\n')) == NULL) { size_t nbufsiz = bufsiz + BUFSIZ; char *nbuf = realloc(buf, nbufsiz); @@ -76,13 +76,33 @@ fgetln(fp, len) } else buf = nbuf; - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) { + buf[bufsiz] = '\0'; + *len = strlen(buf); return buf; + } + *len = bufsiz; bufsiz = nbufsiz; } *len = (ptr - buf) + 1; return buf; } + +#endif + +#ifdef TEST +int +main(int argc, char *argv[]) +{ + char *p; + size_t len; + + while ((p = fgetln(stdin, &len)) != NULL) { + (void)printf("%zu %s", len, p); + free(p); + } + return 0; +} +#endif diff --git a/cmd-line-utils/libedit/np/strlcat.c b/cmd-line-utils/libedit/np/strlcat.c index 6c9f1e92d79..4e2897d8f35 100644 --- a/cmd-line-utils/libedit/np/strlcat.c +++ b/cmd-line-utils/libedit/np/strlcat.c @@ -1,59 +1,68 @@ +/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ +/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ + /* * Copyright (c) 1998 Todd C. Miller - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(_KERNEL) && !defined(_STANDALONE) +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcat.c,v 1.2.4.2 2001/07/09 23:30:06 obrien Exp $"; #endif +#if defined(LIBC_SCCS) && !defined(lint) +#endif /* LIBC_SCCS and not lint */ + +#ifdef _LIBC +#include "namespace.h" +#endif #include +#include #include +#ifdef _LIBC +# ifdef __weak_alias +__weak_alias(strlcat, _strlcat) +# endif +#endif + +#else +#include +#endif /* !_KERNEL && !_STANDALONE */ + +#if !HAVE_STRLCAT /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(initial dst) + strlen(src); if retval >= siz, - * truncation occurred. + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. */ -size_t strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcat(char *dst, const char *src, size_t siz) { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; size_t dlen; + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; @@ -73,3 +82,4 @@ size_t strlcat(dst, src, siz) return(dlen + (s - src)); /* count does not include NUL */ } +#endif diff --git a/cmd-line-utils/libedit/np/strlcpy.c b/cmd-line-utils/libedit/np/strlcpy.c index 1f154bcf2ea..092a9757c0f 100644 --- a/cmd-line-utils/libedit/np/strlcpy.c +++ b/cmd-line-utils/libedit/np/strlcpy.c @@ -1,59 +1,63 @@ -/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ +/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ +/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(_KERNEL) && !defined(_STANDALONE) +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#else #include "config.h" +#endif #if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; -#endif #endif /* LIBC_SCCS and not lint */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.2.4.1 2001/07/09 23:30:06 obrien Exp $"; -#endif +#ifdef _LIBC +#include "namespace.h" +#endif #include +#include #include +#ifdef _LIBC +# ifdef __weak_alias +__weak_alias(strlcpy, _strlcpy) +# endif +#endif +#else +#include +#endif /* !_KERNEL && !_STANDALONE */ + + +#if !HAVE_STRLCPY /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ -size_t strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; +size_t +strlcpy(char *dst, const char *src, size_t siz) { - register char *d = dst; - register const char *s = src; - register size_t n = siz; + char *d = dst; + const char *s = src; + size_t n = siz; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { @@ -73,3 +77,4 @@ size_t strlcpy(dst, src, siz) return(s - src - 1); /* count does not include NUL */ } +#endif diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c index 895ff2059ac..3c37c231ceb 100644 --- a/cmd-line-utils/libedit/np/unvis.c +++ b/cmd-line-utils/libedit/np/unvis.c @@ -1,4 +1,4 @@ -/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ +/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -12,11 +12,7 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -34,34 +30,30 @@ */ #include "config.h" + #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ -#define __LIBC12_SOURCE__ - #include #include #include #include +#ifdef HAVE_VIS_H +#include +#else #include "np/vis.h" +#endif #ifdef __weak_alias __weak_alias(strunvis,_strunvis) -__weak_alias(unvis,_unvis) #endif -#ifdef __warn_references -__warn_references(unvis, - "warning: reference to compatibility unvis(); include for correct reference") -#endif - -#if !HAVE_VIS_H +#if !HAVE_VIS /* * decode driven by state machine */ @@ -72,30 +64,22 @@ __warn_references(unvis, #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX1 7 /* hex digit */ -#define S_HEX2 8 /* hex digit 2 */ +#define S_HEX1 7 /* hex digit */ +#define S_HEX2 8 /* hex digit 2 */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) +/* + * unvis - decode characters previously encoded by vis + */ int unvis(cp, c, astate, flag) char *cp; int c; int *astate, flag; { - return __unvis13(cp, (int)c, astate, flag); -} - -/* - * unvis - decode characters previously encoded by vis - */ -int -__unvis13(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ + unsigned char uc = (unsigned char)c; _DIAGASSERT(cp != NULL); _DIAGASSERT(astate != NULL); @@ -105,7 +89,7 @@ __unvis13(cp, c, astate, flag) || *astate == S_HEX2) { *astate = S_GROUND; return (UNVIS_VALID); - } + } return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } @@ -116,7 +100,7 @@ __unvis13(cp, c, astate, flag) if (c == '\\') { *astate = S_START; return (0); - } + } if ((flag & VIS_HTTPSTYLE) && c == '%') { *astate = S_HEX1; return (0); @@ -193,7 +177,7 @@ __unvis13(cp, c, astate, flag) } *astate = S_GROUND; return (UNVIS_SYNBAD); - + case S_META: if (c == '-') *astate = S_META1; @@ -204,12 +188,12 @@ __unvis13(cp, c, astate, flag) return (UNVIS_SYNBAD); } return (0); - + case S_META1: *astate = S_GROUND; *cp |= c; return (UNVIS_VALID); - + case S_CTRL: if (c == '?') *cp |= 0177; @@ -219,23 +203,23 @@ __unvis13(cp, c, astate, flag) return (UNVIS_VALID); case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { - /* - * yes - and maybe a third + if (isoctal(uc)) { + /* + * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; + *astate = S_OCTAL3; return (0); - } - /* - * no - done with current sequence, push back passed char + } + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); case S_OCTAL3: /* third possible octal digit */ *astate = S_GROUND; - if (isoctal(c)) { + if (isoctal(uc)) { *cp = (*cp << 3) + (c - '0'); return (UNVIS_VALID); } @@ -243,27 +227,30 @@ __unvis13(cp, c, astate, flag) * we were done, push back passed char */ return (UNVIS_VALIDPUSH); + case S_HEX1: - if (isxdigit(c)) { - *cp = xtod(c); + if (isxdigit(uc)) { + *cp = xtod(uc); *astate = S_HEX2; return (0); } - /* - * no - done with current sequence, push back passed char + /* + * no - done with current sequence, push back passed char */ *astate = S_GROUND; return (UNVIS_VALIDPUSH); + case S_HEX2: - *astate = S_GROUND; - if (isxdigit(c)) { - *cp = xtod(c) | (*cp << 4); + *astate = S_GROUND; + if (isxdigit(uc)) { + *cp = xtod(uc) | (*cp << 4); return (UNVIS_VALID); } - return (UNVIS_VALIDPUSH); - default: - /* - * decoder in unknown state - (probably uninitialized) + return (UNVIS_VALIDPUSH); + + default: + /* + * decoder in unknown state - (probably uninitialized) */ *astate = S_GROUND; return (UNVIS_SYNBAD); @@ -271,7 +258,7 @@ __unvis13(cp, c, astate, flag) } /* - * strunvis - decode src into dst + * strunvis - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. @@ -291,8 +278,8 @@ strunvisx(dst, src, flag) _DIAGASSERT(dst != NULL); while ((c = *src++) != '\0') { - again: - switch (__unvis13(dst, c, &state, flag)) { + again: + switch (unvis(dst, c, &state, flag)) { case UNVIS_VALID: dst++; break; @@ -306,7 +293,7 @@ strunvisx(dst, src, flag) return (-1); } } - if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) + if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) dst++; *dst = '\0'; return (dst - start); diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c index e8f5c195f10..2a746274681 100644 --- a/cmd-line-utils/libedit/np/vis.c +++ b/cmd-line-utils/libedit/np/vis.c @@ -1,7 +1,6 @@ -/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ +/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */ /*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -13,11 +12,7 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -34,21 +29,47 @@ * SUCH DAMAGE. */ +/*- + * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "config.h" #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include + #include -#ifdef HAVE_ALLOCA_H -#include +#ifdef HAVE_VIS_H +#include +#else +#include "np/vis.h" #endif #include -#include "np/vis.h" - #ifdef __weak_alias __weak_alias(strsvis,_strsvis) __weak_alias(strsvisx,_strsvisx) @@ -58,63 +79,61 @@ __weak_alias(svis,_svis) __weak_alias(vis,_vis) #endif -#if !HAVE_VIS_H +#if !HAVE_VIS || !HAVE_SVIS #include #include #include #include -#include -#undef BELL -#if defined(__STDC__) -#define BELL '\a' -#else -#define BELL '\007' -#endif -#define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7') +static char *do_svis(char *, int, int, int, const char *); + +#undef BELL +#define BELL '\a' + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define issafe(c) (c == '\b' || c == BELL || c == '\r') #define xtoa(c) "0123456789abcdef"[c] -#define MAXEXTRAS 5 +#define MAXEXTRAS 5 +#define MAKEEXTRALIST(flag, extra, orig_str) \ +do { \ + const char *orig = orig_str; \ + const char *o = orig; \ + char *e; \ + while (*o++) \ + continue; \ + extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \ + if (!extra) break; \ + for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ + continue; \ + e--; \ + if (flag & VIS_SP) *e++ = ' '; \ + if (flag & VIS_TAB) *e++ = '\t'; \ + if (flag & VIS_NL) *e++ = '\n'; \ + if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ + *e = '\0'; \ +} while (/*CONSTCOND*/0) -char *MAKEEXTRALIST(unsigned int flag, const char *orig) -{ - const char *o = orig; - char *e, *extra; - while (*o++) - continue; - extra = (char*) malloc((size_t)((o - orig) + MAXEXTRAS)); - assert(extra); - for (o = orig, e = extra; (*e++ = *o++) != '\0';) - continue; - e--; - if (flag & VIS_SP) *e++ = ' '; - if (flag & VIS_TAB) *e++ = '\t'; - if (flag & VIS_NL) *e++ = '\n'; - if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; - *e = '\0'; - return extra; +/* + * This is do_hvis, for HTTP style (RFC 1808) + */ +static char * +do_hvis(char *dst, int c, int flag, int nextc, const char *extra) +{ + if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { + *dst++ = '%'; + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); + *dst++ = xtoa((unsigned int)c & 0xf); + } else { + dst = do_svis(dst, c, flag, nextc, extra); + } + return dst; } - /* - * This is HVIS, the macro of vis used to HTTP style (RFC 1808) - */ -#define HVIS(dst, c, flag, nextc, extra) \ -do \ - if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ - *dst++ = '%'; \ - *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ - *dst++ = xtoa((unsigned int)c & 0xf); \ - } else { \ - SVIS(dst, c, flag, nextc, extra); \ - } \ -while (/*CONSTCOND*/0) - -/* - * This is SVIS, the central macro of vis. + * This is do_vis, the central code of vis. * dst: Pointer to the destination buffer * c: Character to encode * flag: Flag word @@ -122,95 +141,103 @@ while (/*CONSTCOND*/0) * extra: Pointer to the list of extra characters to be * backslash-protected. */ -#define SVIS(dst, c, flag, nextc, extra) \ -do { \ - int isextra, isc; \ - isextra = strchr(extra, c) != NULL; \ - if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ - ((flag & VIS_SAFE) && issafe(c)))) { \ - *dst++ = c; \ - break; \ - } \ - isc = 0; \ - if (flag & VIS_CSTYLE) { \ - switch (c) { \ - case '\n': \ - isc = 1; *dst++ = '\\'; *dst++ = 'n'; \ - break; \ - case '\r': \ - isc = 1; *dst++ = '\\'; *dst++ = 'r'; \ - break; \ - case '\b': \ - isc = 1; *dst++ = '\\'; *dst++ = 'b'; \ - break; \ - case BELL: \ - isc = 1; *dst++ = '\\'; *dst++ = 'a'; \ - break; \ - case '\v': \ - isc = 1; *dst++ = '\\'; *dst++ = 'v'; \ - break; \ - case '\t': \ - isc = 1; *dst++ = '\\'; *dst++ = 't'; \ - break; \ - case '\f': \ - isc = 1; *dst++ = '\\'; *dst++ = 'f'; \ - break; \ - case ' ': \ - isc = 1; *dst++ = '\\'; *dst++ = 's'; \ - break; \ - case '\0': \ - isc = 1; *dst++ = '\\'; *dst++ = '0'; \ - if (isoctal(nextc)) { \ - *dst++ = '0'; \ - *dst++ = '0'; \ - } \ - } \ - } \ - if (isc) break; \ - if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ - *dst++ = '\\'; \ - *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 6) & 03) + '0'; \ - *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 3) & 07) + '0'; \ - *dst++ = (c & 07) + '0'; \ - } else { \ - if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ - if (c & 0200) { \ - c &= 0177; *dst++ = 'M'; \ - } \ - if (iscntrl(c)) { \ - *dst++ = '^'; \ - if (c == 0177) \ - *dst++ = '?'; \ - else \ - *dst++ = c + '@'; \ - } else { \ - *dst++ = '-'; *dst++ = c; \ - } \ - } \ -} while (/*CONSTCOND*/0) +static char * +do_svis(char *dst, int c, int flag, int nextc, const char *extra) +{ + int isextra; + isextra = strchr(extra, c) != NULL; + if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || + ((flag & VIS_SAFE) && issafe(c)))) { + *dst++ = c; + return dst; + } + if (flag & VIS_CSTYLE) { + switch (c) { + case '\n': + *dst++ = '\\'; *dst++ = 'n'; + return dst; + case '\r': + *dst++ = '\\'; *dst++ = 'r'; + return dst; + case '\b': + *dst++ = '\\'; *dst++ = 'b'; + return dst; + case BELL: + *dst++ = '\\'; *dst++ = 'a'; + return dst; + case '\v': + *dst++ = '\\'; *dst++ = 'v'; + return dst; + case '\t': + *dst++ = '\\'; *dst++ = 't'; + return dst; + case '\f': + *dst++ = '\\'; *dst++ = 'f'; + return dst; + case ' ': + *dst++ = '\\'; *dst++ = 's'; + return dst; + case '\0': + *dst++ = '\\'; *dst++ = '0'; + if (isoctal(nextc)) { + *dst++ = '0'; + *dst++ = '0'; + } + return dst; + default: + if (isgraph(c)) { + *dst++ = '\\'; *dst++ = c; + return dst; + } + } + } + if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + *dst++ = '\\'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; + *dst++ = (c & 07) + '0'; + } else { + if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; + if (c & 0200) { + c &= 0177; *dst++ = 'M'; + } + if (iscntrl(c)) { + *dst++ = '^'; + if (c == 0177) + *dst++ = '?'; + else + *dst++ = c + '@'; + } else { + *dst++ = '-'; *dst++ = c; + } + } + return dst; +} /* * svis - visually encode characters, also encoding the characters - * pointed to by `extra' + * pointed to by `extra' */ char * -svis(dst, c, flag, nextc, extra) - char *dst; - int c, flag, nextc; - const char *extra; +svis(char *dst, int c, int flag, int nextc, const char *extra) { - char *nextra, *to_be_freed; + char *nextra = NULL; + _DIAGASSERT(dst != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (!nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return dst; + } if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, nextra); + dst = do_hvis(dst, c, flag, nextc, nextra); else - SVIS(dst, c, flag, nextc, nextra); + dst = do_svis(dst, c, flag, nextc, nextra); + free(nextra); *dst = '\0'; - free(to_be_freed); - return(dst); + return dst; } @@ -221,140 +248,146 @@ svis(dst, c, flag, nextc, extra) * be encoded, too. These functions are useful e. g. to * encode strings in such a way so that they are not interpreted * by a shell. - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strsvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ int -strsvis(dst, src, flag, extra) - char *dst; - const char *src; - int flag; - const char *extra; +strsvis(char *dst, const char *csrc, int flag, const char *extra) { - char c; + int c; char *start; - char *nextra, *to_be_freed; + char *nextra = NULL; + const unsigned char *src = (const unsigned char *)csrc; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (!nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return 0; + } if (flag & VIS_HTTPSTYLE) { for (start = dst; (c = *src++) != '\0'; /* empty */) - HVIS(dst, c, flag, *src, nextra); + dst = do_hvis(dst, c, flag, *src, nextra); } else { for (start = dst; (c = *src++) != '\0'; /* empty */) - SVIS(dst, c, flag, *src, nextra); + dst = do_svis(dst, c, flag, *src, nextra); } + free(nextra); *dst = '\0'; - free(to_be_freed); return (dst - start); } int -strsvisx(dst, src, len, flag, extra) - char *dst; - const char *src; - size_t len; - int flag; - const char *extra; +strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) { - char c; + unsigned char c; char *start; - char *nextra, *to_be_freed; + char *nextra = NULL; + const unsigned char *src = (const unsigned char *)csrc; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); - nextra= to_be_freed= MAKEEXTRALIST(flag, extra); + MAKEEXTRALIST(flag, nextra, extra); + if (! nextra) { + *dst = '\0'; /* can't create nextra, return "" */ + return 0; + } if (flag & VIS_HTTPSTYLE) { for (start = dst; len > 0; len--) { c = *src++; - HVIS(dst, c, flag, len ? *src : '\0', nextra); + dst = do_hvis(dst, c, flag, + len > 1 ? *src : '\0', nextra); } } else { for (start = dst; len > 0; len--) { c = *src++; - SVIS(dst, c, flag, len ? *src : '\0', nextra); + dst = do_svis(dst, c, flag, + len > 1 ? *src : '\0', nextra); } } + free(nextra); *dst = '\0'; - free(to_be_freed); return (dst - start); } +#endif - +#if !HAVE_VIS /* * vis - visually encode characters */ char * -vis(dst, c, flag, nextc) - char *dst; - int c, flag, nextc; - +vis(char *dst, int c, int flag, int nextc) { - char *extra, *to_be_freed; + char *extra = NULL; + unsigned char uc = (unsigned char)c; _DIAGASSERT(dst != NULL); - extra= to_be_freed= MAKEEXTRALIST(flag, ""); - + MAKEEXTRALIST(flag, extra, ""); + if (! extra) { + *dst = '\0'; /* can't create extra, return "" */ + return dst; + } if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, extra); + dst = do_hvis(dst, uc, flag, nextc, extra); else - SVIS(dst, c, flag, nextc, extra); + dst = do_svis(dst, uc, flag, nextc, extra); + free(extra); *dst = '\0'; - free(to_be_freed); - return (dst); + return dst; } /* * strvis, strvisx - visually encode characters from src into dst - * + * * Dst must be 4 times the size of src to account for possible * expansion. The length of dst, not including the trailing NULL, - * is returned. + * is returned. * * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ int -strvis(dst, src, flag) - char *dst; - const char *src; - int flag; +strvis(char *dst, const char *src, int flag) { - char *extra; - int tmp; + char *extra = NULL; + int rv; - extra= MAKEEXTRALIST(flag, ""); - tmp= strsvis(dst, src, flag, extra); + MAKEEXTRALIST(flag, extra, ""); + if (!extra) { + *dst = '\0'; /* can't create extra, return "" */ + return 0; + } + rv = strsvis(dst, src, flag, extra); free(extra); - return tmp; + return rv; } int -strvisx(dst, src, len, flag) - char *dst; - const char *src; - size_t len; - int flag; +strvisx(char *dst, const char *src, size_t len, int flag) { - char *extra; - int tmp; + char *extra = NULL; + int rv; - extra= MAKEEXTRALIST(flag, ""); - tmp= strsvisx(dst, src, len, flag, extra); + MAKEEXTRALIST(flag, extra, ""); + if (!extra) { + *dst = '\0'; /* can't create extra, return "" */ + return 0; + } + rv = strsvisx(dst, src, len, flag, extra); free(extra); - return tmp; + return rv; } #endif diff --git a/cmd-line-utils/libedit/np/vis.h b/cmd-line-utils/libedit/np/vis.h index 1a49c9e3ed2..11f5b740e2d 100644 --- a/cmd-line-utils/libedit/np/vis.h +++ b/cmd-line-utils/libedit/np/vis.h @@ -1,4 +1,4 @@ -/* $NetBSD: vis.h,v 1.12 2002/03/23 17:39:05 christos Exp $ */ +/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -12,11 +12,7 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,9 +34,7 @@ #ifndef _VIS_H_ #define _VIS_H_ -#ifdef HAVE_SYS_CDEFS_H -#include -#endif +#include /* * to select alternate encoding format @@ -78,6 +72,7 @@ */ #define UNVIS_END 1 /* no more characters */ +__BEGIN_DECLS char *vis(char *, int, int, int); char *svis(char *, int, int, int, const char *); int strvis(char *, const char *, int); @@ -86,11 +81,7 @@ int strvisx(char *, const char *, size_t, int); int strsvisx(char *, const char *, size_t, int, const char *); int strunvis(char *, const char *); int strunvisx(char *, const char *, int); -#ifdef __LIBC12_SOURCE__ int unvis(char *, int, int *, int); -int __unvis13(char *, int, int *, int); -#else -int unvis(char *, int, int *, int) __RENAME(__unvis13); -#endif +__END_DECLS #endif /* !_VIS_H_ */ diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c index 993cf5b752d..5bdefb5a0e4 100644 --- a/cmd-line-utils/libedit/parse.c +++ b/cmd-line-utils/libedit/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */ +/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * parse.c: parse an editline extended command @@ -129,7 +135,7 @@ el_parse(EditLine *el, int argc, const char *argv[]) * the appropriate character or -1 if the escape is not valid */ protected int -parse__escape(const char **const ptr) +parse__escape(const char **ptr) { const char *p; int c; diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h index 4b796666b8e..58dced1aeaa 100644 --- a/cmd-line-utils/libedit/parse.h +++ b/cmd-line-utils/libedit/parse.h @@ -1,4 +1,4 @@ -/* $NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,7 +41,7 @@ #define _h_el_parse protected int parse_line(EditLine *, const char *); -protected int parse__escape(const char ** const); +protected int parse__escape(const char **); protected char *parse__string(char *, const char *); protected int parse_cmd(EditLine *, const char *); diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c index 455dd60331b..982943afd30 100644 --- a/cmd-line-utils/libedit/prompt.c +++ b/cmd-line-utils/libedit/prompt.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * prompt.c: Prompt printing functions diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c index 51848c2038e..ac768142e79 100644 --- a/cmd-line-utils/libedit/read.c +++ b/cmd-line-utils/libedit/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $ */ +/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * read.c: Clean this junk up! This is horrible code. @@ -50,6 +56,7 @@ private int read__fixio(int, int); private int read_preread(EditLine *); private int read_char(EditLine *, char *); private int read_getcmd(EditLine *, el_action_t *, char *); +private void read_pop(c_macro_t *); /* read_init(): * Initialize the read stuff @@ -205,7 +212,7 @@ read_preread(EditLine *el) * Push a macro */ public void -el_push(EditLine *el, char *str) +el_push(EditLine *el, const char *str) { c_macro_t *ma = &el->el_chared.c_macro; @@ -216,7 +223,7 @@ el_push(EditLine *el, char *str) ma->level--; } term_beep(el); - term__flush(); + term__flush(el); } @@ -294,6 +301,19 @@ read_char(EditLine *el, char *cp) return (num_read); } +/* read_pop(): + * Pop a macro from the stack + */ +private void +read_pop(c_macro_t *ma) +{ + int i; + + el_free(ma->macro[0]); + for (i = ma->level--; i > 0; i--) + ma->macro[i - 1] = ma->macro[i]; + ma->offset = 0; +} /* el_getc(): * Read a character @@ -304,26 +324,28 @@ el_getc(EditLine *el, char *cp) int num_read; c_macro_t *ma = &el->el_chared.c_macro; - term__flush(); + term__flush(el); for (;;) { if (ma->level < 0) { if (!read_preread(el)) break; } + if (ma->level < 0) break; - if (ma->macro[ma->level][ma->offset] == '\0') { - el_free(ma->macro[ma->level--]); - ma->offset = 0; + if (ma->macro[0][ma->offset] == '\0') { + read_pop(ma); continue; } - *cp = ma->macro[ma->level][ma->offset++] & 0377; - if (ma->macro[ma->level][ma->offset] == '\0') { + + *cp = ma->macro[0][ma->offset++] & 0377; + + if (ma->macro[0][ma->offset] == '\0') { /* Needed for QuoteMode On */ - el_free(ma->macro[ma->level--]); - ma->offset = 0; + read_pop(ma); } + return (1); } @@ -357,11 +379,11 @@ read_prepare(EditLine *el) we have the wrong size. */ el_resize(el); re_clear_display(el); /* reset the display stuff */ - ch_reset(el); + ch_reset(el, 0); re_refresh(el); /* print the prompt */ if (el->el_flags & UNBUFFERED) - term__flush(); + term__flush(el); } protected void @@ -438,7 +460,7 @@ el_gets(EditLine *el, int *nread) else cp = el->el_line.lastchar; - term__flush(); + term__flush(el); while ((*el->el_read.read_char)(el, cp) == 1) { /* make sure there is space next character */ @@ -478,7 +500,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ break; } - if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ + if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, "ERROR: illegal command from key 0%o\r\n", ch); @@ -570,7 +592,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ /* put (real) cursor in a known place */ re_clear_display(el); /* reset the display stuff */ - ch_reset(el); /* reset the input pointers */ + ch_reset(el, 1); /* reset the input pointers */ re_refresh(el); /* print the prompt again */ break; @@ -581,7 +603,7 @@ el_gets(EditLine *el, int *nread) "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ term_beep(el); - term__flush(); + term__flush(el); break; } el->el_state.argument = 1; @@ -591,7 +613,7 @@ el_gets(EditLine *el, int *nread) break; } - term__flush(); /* flush any buffered output */ + term__flush(el); /* flush any buffered output */ /* make sure the tty is set up correctly */ if ((el->el_flags & UNBUFFERED) == 0) { read_finish(el); diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h index 1982f47253b..bd8d4c1f5bb 100644 --- a/cmd-line-utils/libedit/read.h +++ b/cmd-line-utils/libedit/read.h @@ -1,4 +1,4 @@ -/* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */ +/* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 004fcf7d183..1f1b18c97d8 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.49 2005/03/10 19:34:46 christos Exp $ */ +/* $NetBSD: readline.c,v 1.78 2009/02/05 19:15:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -36,25 +29,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (__GNUC__) - #pragma alloca -#endif - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -#else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifndef _AIX -extern char *alloca (); -# endif -# endif -#endif +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ #include #include @@ -68,12 +45,20 @@ extern char *alloca (); #include #include #include +#include +#ifdef HAVE_VIS_H #include - +#else +#include "np/vis.h" +#endif #include "readline/readline.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" +#include "filecomplete.h" + +void rl_prep_terminal(int); +void rl_deprep_terminal(void); /* for rl_complete() */ #define TAB '\r' @@ -94,9 +79,12 @@ FILE *rl_outstream = NULL; int rl_point = 0; int rl_end = 0; char *rl_line_buffer = NULL; -VFunction *rl_linefunc = NULL; +VCPFunction *rl_linefunc = NULL; int rl_done = 0; VFunction *rl_event_hook = NULL; +KEYMAP_ENTRY_ARRAY emacs_standard_keymap, + emacs_meta_keymap, + emacs_ctlx_keymap; int history_base = 1; /* probably never subject to change */ int history_length = 0; @@ -112,21 +100,23 @@ int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -CPFunction *rl_completion_entry_function = NULL; +Function *rl_completion_entry_function = NULL; CPPFunction *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; -Function *rl_getc_function = NULL; +int (*rl_getc_function)(FILE *) = NULL; char *rl_terminal_name = NULL; int rl_already_prompted = 0; int rl_filename_completion_desired = 0; int rl_ignore_completion_duplicates = 0; int rl_catch_signals = 1; +int readline_echoing_p = 1; +int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; Function *rl_startup_hook = NULL; VFunction *rl_completion_display_matches_hook = NULL; -VFunction *rl_prep_term_function = NULL; -VFunction *rl_deprep_term_function = NULL; +VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; +VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; /* * The current prompt string. @@ -150,7 +140,7 @@ int rl_completion_query_items = 100; * in the parsed text when it is passed to the completion function. * Shell uses this to help determine what kind of completing to do. */ -char *rl_special_prefixes = (char *)NULL; +char *rl_special_prefixes = NULL; /* * This is the character appended to the completed words if at the end of @@ -160,25 +150,21 @@ int rl_completion_append_character = ' '; /* stuff below is used internally by libedit for readline emulation */ -/* if not zero, non-unique completions always show list of possible matches */ -static int _rl_complete_show_all = 0; - static History *h = NULL; static EditLine *e = NULL; static Function *map[256]; -static int el_rl_complete_cmdnum = 0; +static jmp_buf topbuf; /* internal functions */ static unsigned char _el_rl_complete(EditLine *, int); static unsigned char _el_rl_tstp(EditLine *, int); static char *_get_prompt(EditLine *); +static int _getc_function(EditLine *, char *); static HIST_ENTRY *_move_history(int); static int _history_expand_command(const char *, size_t, size_t, char **); static char *_rl_compat_sub(const char *, const char *, const char *, int); -static int _rl_complete_internal(int); -static int _rl_qsort_string_compare(const void *, const void *); static int _rl_event_read_char(EditLine *, char *); static void _rl_update_pos(void); @@ -205,16 +191,49 @@ _move_history(int op) return (HIST_ENTRY *) NULL; rl_he.line = ev.str; - rl_he.data = (histdata_t) &(ev.num); + rl_he.data = NULL; return (&rl_he); } +/* + * read one key from user defined input function + */ +static int +/*ARGSUSED*/ +_getc_function(EditLine *el, char *c) +{ + int i; + + i = (*rl_getc_function)(NULL); + if (i == -1) + return 0; + *c = i; + return 1; +} + + /* * READLINE compatibility stuff */ +/* + * Set the prompt + */ +int +rl_set_prompt(const char *prompt) +{ + if (!prompt) + prompt = ""; + if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) + return 0; + if (rl_prompt) + free(rl_prompt); + rl_prompt = strdup(prompt); + return rl_prompt == NULL ? -1 : 0; +} + /* * initialize rl compat stuff */ @@ -223,7 +242,6 @@ rl_initialize(void) { HistEvent ev; const LineInfo *li; - int i; int editmode = 1; struct termios t; @@ -257,9 +275,12 @@ rl_initialize(void) max_input_history = INT_MAX; el_set(e, EL_HIST, history, h); + /* setup getc function if valid */ + if (rl_getc_function) + el_set(e, EL_GETCFN, _getc_function); + /* for proper prompt printing in readline() */ - rl_prompt = strdup(""); - if (rl_prompt == NULL) { + if (rl_set_prompt("") == -1) { history_end(h); el_end(e); return -1; @@ -291,17 +312,6 @@ rl_initialize(void) "ReadLine compatible suspend function", _el_rl_tstp); el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - - /* - * Find out where the rl_complete function was added; this is - * used later to detect that lastcmd was also rl_complete. - */ - for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) { - if (e->el_map.func[i] == _el_rl_complete) { - el_rl_complete_cmdnum = i; - break; - } - } /* read settings from configuration file */ el_source(e, NULL); @@ -327,9 +337,10 @@ rl_initialize(void) * trailing newline (if there is any) */ char * -readline(const char *prompt) +readline(const char *p) { HistEvent ev; + const char * volatile prompt = p; int count; const char *ret; char *buf; @@ -340,15 +351,11 @@ readline(const char *prompt) rl_done = 0; + (void)setjmp(topbuf); + /* update prompt accordingly to what has been passed */ - if (!prompt) - prompt = ""; - if (strcmp(rl_prompt, prompt) != 0) { - free(rl_prompt); - rl_prompt = strdup(prompt); - if (rl_prompt == NULL) - return NULL; - } + if (rl_set_prompt(prompt) == -1) + return NULL; if (rl_pre_input_hook) (*rl_pre_input_hook)(NULL, 0); @@ -446,7 +453,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else *r++ = *s++; } - *r = 0; + *r = '\0'; return(result); } @@ -467,7 +474,7 @@ get_history_event(const char *cmd, int *cindex, int qchar) return(NULL); /* find out which event to take */ - if (cmd[idx] == history_expansion_char || cmd[idx] == 0) { + if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { if (history(h, &ev, H_FIRST) != 0) return(NULL); *cindex = cmd[idx]? (idx + 1):idx; @@ -689,7 +696,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, if (aptr) free(aptr); - if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) { + if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { *result = tmp; return(1); } @@ -699,7 +706,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, continue; else if (*cmd == 'h') { /* remove trailing path */ if ((aptr = strrchr(tmp, '/')) != NULL) - *aptr = 0; + *aptr = '\0'; } else if (*cmd == 't') { /* remove leading path */ if ((aptr = strrchr(tmp, '/')) != NULL) { aptr = strdup(aptr + 1); @@ -708,7 +715,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } } else if (*cmd == 'r') { /* remove trailing suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) - *aptr = 0; + *aptr = '\0'; } else if (*cmd == 'e') { /* remove all but suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) { aptr = strdup(aptr); @@ -732,6 +739,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, what = realloc(from, size); if (what == NULL) { free(from); + free(tmp); return 0; } len = 0; @@ -744,6 +752,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, (size <<= 1)); if (nwhat == NULL) { free(what); + free(tmp); return 0; } what = nwhat; @@ -756,10 +765,13 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, free(what); if (search) { from = strdup(search); - if (from == NULL) + if (from == NULL) { + free(tmp); return 0; + } } else { from = NULL; + free(tmp); return (-1); } } @@ -771,6 +783,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, with = realloc(to, size); if (with == NULL) { free(to); + free(tmp); return -1; } len = 0; @@ -782,6 +795,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, nwith = realloc(with, size); if (nwith == NULL) { free(with); + free(tmp); return -1; } with = nwith; @@ -850,12 +864,14 @@ history_expand(char *str, char **output) return 0; } -#define ADD_STRING(what, len) \ +#define ADD_STRING(what, len, fr) \ { \ if (idx + len + 1 > size) { \ char *nresult = realloc(result, (size += len + 1));\ if (nresult == NULL) { \ free(*output); \ + if (/*CONSTCOND*/fr) \ + free(tmp); \ return 0; \ } \ result = nresult; \ @@ -867,6 +883,7 @@ history_expand(char *str, char **output) result = NULL; size = idx = 0; + tmp = NULL; for (i = 0; str[i];) { int qchar, loop_again; size_t len, start, j; @@ -904,13 +921,11 @@ loop: goto loop; } len = i - start; - tmp = &str[start]; - ADD_STRING(tmp, len); + ADD_STRING(&str[start], len, 0); if (str[i] == '\0' || str[i] != history_expansion_char) { len = j - i; - tmp = &str[i]; - ADD_STRING(tmp, len); + ADD_STRING(&str[i], len, 0); if (start == 0) ret = 0; else @@ -920,8 +935,11 @@ loop: ret = _history_expand_command (str, i, (j - i), &tmp); if (ret > 0 && tmp) { len = strlen(tmp); - ADD_STRING(tmp, len); + ADD_STRING(tmp, len, 1); + } + if (tmp) { free(tmp); + tmp = NULL; } i = j; } @@ -973,23 +991,23 @@ history_arg_extract(int start, int end, const char *str) if (start < 0) start = end; - if (start < 0 || end < 0 || start > max || end > max || start > end) + if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end) return(NULL); - for (i = start, len = 0; i <= end; i++) + for (i = start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; result = malloc(len); if (result == NULL) return NULL; - for (i = start, len = 0; i <= end; i++) { + for (i = start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); - if (i < end) + if (i < (size_t)end) result[len++] = ' '; } - result[len] = 0; + result[len] = '\0'; for (i = 0; arr[i]; i++) free(arr[i]); @@ -1152,7 +1170,7 @@ history_get(int num) return (NULL); /* error */ /* look backwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVENT, num)) + if (history(h, &ev, H_NEXT_EVENT, num + 1)) return (NULL); she.line = ev.str; @@ -1184,6 +1202,31 @@ add_history(const char *line) } +/* + * remove the specified entry from the history list and return it. + */ +HIST_ENTRY * +remove_history(int num) +{ + HIST_ENTRY *she; + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + + if (history(h, &ev, H_DEL, num) != 0) + return NULL; + + if ((she = malloc(sizeof(*she))) == NULL) + return NULL; + + she->line = ev.str; + she->data = NULL; + + return she; +} + + /* * clear the history list - delete all entries */ @@ -1377,172 +1420,18 @@ history_search_pos(const char *str, /********************************/ /* completion functions */ -/* - * does tilde expansion of strings of type ``~user/foo'' - * if ``user'' isn't valid user name or ``txt'' doesn't start - * w/ '~', returns pointer to strdup()ed copy of ``txt'' - * - * it's callers's responsibility to free() returned string - */ char * -tilde_expand(char *txt) +tilde_expand(char *name) { - struct passwd *pass; - char *temp; - size_t len = 0; - - if (txt[0] != '~') - return (strdup(txt)); - - temp = strchr(txt + 1, '/'); - if (temp == NULL) { - temp = strdup(txt + 1); - if (temp == NULL) - return NULL; - } else { - len = temp - txt + 1; /* text until string after slash */ - temp = malloc(len); - if (temp == NULL) - return NULL; - (void)strncpy(temp, txt + 1, len - 2); - temp[len - 2] = '\0'; - } - pass = getpwnam(temp); - free(temp); /* value no more needed */ - if (pass == NULL) - return (strdup(txt)); - - /* update pointer txt to point at string immedially following */ - /* first slash */ - txt += len; - - temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); - if (temp == NULL) - return NULL; - (void)sprintf(temp, "%s/%s", pass->pw_dir, txt); - - return (temp); + return fn_tilde_expand(name); } - -/* - * return first found file name starting by the ``text'' or NULL if no - * such file can be found - * value of ``state'' is ignored - * - * it's caller's responsibility to free returned string - */ char * -filename_completion_function(const char *text, int state) +filename_completion_function(const char *name, int state) { - static DIR *dir = NULL; - static char *filename = NULL, *dirname = NULL; - static size_t filename_len = 0; - struct dirent *entry; - char *temp; - size_t len; - - if (state == 0 || dir == NULL) { - temp = strrchr(text, '/'); - if (temp) { - char *nptr; - temp++; - nptr = realloc(filename, strlen(temp) + 1); - if (nptr == NULL) { - free(filename); - return NULL; - } - filename = nptr; - (void)strcpy(filename, temp); - len = temp - text; /* including last slash */ - nptr = realloc(dirname, len + 1); - if (nptr == NULL) { - free(filename); - return NULL; - } - dirname = nptr; - (void)strncpy(dirname, text, len); - dirname[len] = '\0'; - } else { - if (*text == 0) - filename = NULL; - else { - filename = strdup(text); - if (filename == NULL) - return NULL; - } - dirname = NULL; - } - - /* support for ``~user'' syntax */ - if (dirname && *dirname == '~') { - char *nptr; - temp = tilde_expand(dirname); - if (temp == NULL) - return NULL; - nptr = realloc(dirname, strlen(temp) + 1); - if (nptr == NULL) { - free(dirname); - return NULL; - } - dirname = nptr; - (void)strcpy(dirname, temp); /* safe */ - free(temp); /* no longer needed */ - } - /* will be used in cycle */ - filename_len = filename ? strlen(filename) : 0; - - if (dir != NULL) { - (void)closedir(dir); - dir = NULL; - } - dir = opendir(dirname ? dirname : "."); - if (!dir) - return (NULL); /* cannot open the directory */ - } - /* find the match */ - while ((entry = readdir(dir)) != NULL) { - /* skip . and .. */ - if (entry->d_name[0] == '.' && (!entry->d_name[1] - || (entry->d_name[1] == '.' && !entry->d_name[2]))) - continue; - if (filename_len == 0) - break; - /* otherwise, get first entry where first */ - /* filename_len characters are equal */ - if (entry->d_name[0] == filename[0] - /* Some dirents have d_namlen, but it is not portable. */ - && strlen(entry->d_name) >= filename_len - && strncmp(entry->d_name, filename, - filename_len) == 0) - break; - } - - if (entry) { /* match found */ - - struct stat stbuf; - /* Some dirents have d_namlen, but it is not portable. */ - len = strlen(entry->d_name) + - ((dirname) ? strlen(dirname) : 0) + 1 + 1; - temp = malloc(len); - if (temp == NULL) - return NULL; - (void)sprintf(temp, "%s%s", - dirname ? dirname : "", entry->d_name); /* safe */ - - /* test, if it's directory */ - if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) - strcat(temp, "/"); /* safe */ - } else { - (void)closedir(dir); - dir = NULL; - temp = NULL; - } - - return (temp); + return fn_filename_completion_function(name, state); } - /* * a completion generator for usernames; returns _first_ username * which starts with supplied text @@ -1564,6 +1453,7 @@ username_completion_function(const char *text, int state) if (state == 0) setpwent(); + /* XXXMYSQL: just use non-_r functions for now */ while ((pwd = getpwent()) && text[0] == pwd->pw_name[0] && strcmp(text, pwd->pw_name) == 0); @@ -1575,16 +1465,6 @@ username_completion_function(const char *text, int state) } -/* - * el-compatible wrapper around rl_complete; needed for key binding - */ -/* ARGSUSED */ -static unsigned char -_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) -{ - return (unsigned char) rl_complete(0, ch); -} - /* * el-compatible wrapper to send TSTP on ^Z */ @@ -1596,273 +1476,36 @@ _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__un return CC_NORM; } -/* - * returns list of completions for text given - */ -char ** -completion_matches(const char *text, CPFunction *genfunc) -{ - char **match_list = NULL, *retstr, *prevstr; - size_t match_list_len, max_equal, which, i; - size_t matches; - - if (h == NULL || e == NULL) - rl_initialize(); - - matches = 0; - match_list_len = 1; - while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { - /* allow for list terminator here */ - if (matches + 3 >= match_list_len) { - char **nmatch_list; - while (matches + 3 >= match_list_len) - match_list_len <<= 1; - nmatch_list = realloc(match_list, - match_list_len * sizeof(char *)); - if (nmatch_list == NULL) { - free(match_list); - return NULL; - } - match_list = nmatch_list; - - } - match_list[++matches] = retstr; - } - - if (!match_list) - return NULL; /* nothing found */ - - /* find least denominator and insert it to match_list[0] */ - which = 2; - prevstr = match_list[1]; - max_equal = strlen(prevstr); - for (; which <= matches; which++) { - for (i = 0; i < max_equal && - prevstr[i] == match_list[which][i]; i++) - continue; - max_equal = i; - } - - retstr = malloc(max_equal + 1); - if (retstr == NULL) { - free(match_list); - return NULL; - } - (void)strncpy(retstr, match_list[1], max_equal); - retstr[max_equal] = '\0'; - match_list[0] = retstr; - - /* add NULL as last pointer to the array */ - match_list[matches + 1] = (char *) NULL; - - return (match_list); -} - -/* - * Sort function for qsort(). Just wrapper around strcasecmp(). - */ -static int -_rl_qsort_string_compare(i1, i2) - const void *i1, *i2; -{ - const char *s1 = ((const char * const *)i1)[0]; - const char *s2 = ((const char * const *)i2)[0]; - - return strcasecmp(s1, s2); -} - /* * Display list of strings in columnar format on readline's output stream. * 'matches' is list of strings, 'len' is number of strings in 'matches', * 'max' is maximum length of string in 'matches'. */ void -rl_display_match_list (matches, len, max) - char **matches; - int len, max; +rl_display_match_list(char **matches, int len, int max) { - int i, idx, limit, count; - int screenwidth = e->el_term.t_size.h; - /* - * Find out how many entries can be put on one line, count - * with two spaces between strings. - */ - limit = screenwidth / (max + 2); - if (limit == 0) - limit = 1; - - /* how many lines of output */ - count = len / limit; - if (count * limit < len) - count++; - - /* Sort the items if they are not already sorted. */ - qsort(&matches[1], (size_t)(len - 1), sizeof(char *), - _rl_qsort_string_compare); - - idx = 1; - for(; count > 0; count--) { - for(i = 0; i < limit && matches[idx]; i++, idx++) - (void)fprintf(e->el_outfile, "%-*s ", max, - matches[idx]); - (void)fprintf(e->el_outfile, "\n"); - } + fn_display_match_list(e, matches, len, max); } -/* - * Complete the word at or before point, called by rl_complete() - * 'what_to_do' says what to do with the completion. - * `?' means list the possible completions. - * TAB means do standard completion. - * `*' means insert all of the possible completions. - * `!' means to do standard completion, and list all possible completions if - * there is more than one. - * - * Note: '*' support is not implemented - */ -static int -_rl_complete_internal(int what_to_do) +static const char * +/*ARGSUSED*/ +_rl_completion_append_character_function(const char *dummy + __attribute__((__unused__))) { - CPFunction *complet_func; - const LineInfo *li; - char *temp, **matches; - const char *ctemp; - size_t len; - - rl_completion_type = what_to_do; - - if (h == NULL || e == NULL) - rl_initialize(); - - complet_func = rl_completion_entry_function; - if (!complet_func) - complet_func = filename_completion_function; - - /* We now look backwards for the start of a filename/variable word */ - li = el_line(e); - ctemp = (const char *) li->cursor; - while (ctemp > li->buffer - && !strchr(rl_basic_word_break_characters, ctemp[-1]) - && (!rl_special_prefixes - || !strchr(rl_special_prefixes, ctemp[-1]) ) ) - ctemp--; - - len = li->cursor - ctemp; - temp = alloca(len + 1); - (void)strncpy(temp, ctemp, len); - temp[len] = '\0'; - - /* these can be used by function called in completion_matches() */ - /* or (*rl_attempted_completion_function)() */ - _rl_update_pos(); - - if (rl_attempted_completion_function) { - int end = li->cursor - li->buffer; - matches = (*rl_attempted_completion_function) (temp, (int) - (end - len), end); - } else - matches = 0; - if (!rl_attempted_completion_function || !matches) - matches = completion_matches(temp, complet_func); - - if (matches) { - int i, retval = CC_REFRESH; - int matches_num, maxlen, match_len, match_display=1; - - /* - * Only replace the completed string with common part of - * possible matches if there is possible completion. - */ - if (matches[0][0] != '\0') { - el_deletestr(e, (int) len); - el_insertstr(e, matches[0]); - } - - if (what_to_do == '?') - goto display_matches; - - if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { - /* - * We found exact match. Add a space after - * it, unless we do filename completion and the - * object is a directory. - */ - size_t alen = strlen(matches[0]); - if ((complet_func != filename_completion_function - || (alen > 0 && (matches[0])[alen - 1] != '/')) - && rl_completion_append_character) { - char buf[2]; - buf[0] = rl_completion_append_character; - buf[1] = '\0'; - el_insertstr(e, buf); - } - } else if (what_to_do == '!') { - display_matches: - /* - * More than one match and requested to list possible - * matches. - */ - - for(i=1, maxlen=0; matches[i]; i++) { - match_len = strlen(matches[i]); - if (match_len > maxlen) - maxlen = match_len; - } - matches_num = i - 1; - - /* newline to get on next line from command line */ - (void)fprintf(e->el_outfile, "\n"); - - /* - * If there are too many items, ask user for display - * confirmation. - */ - if (matches_num > rl_completion_query_items) { - (void)fprintf(e->el_outfile, - "Display all %d possibilities? (y or n) ", - matches_num); - (void)fflush(e->el_outfile); - if (getc(stdin) != 'y') - match_display = 0; - (void)fprintf(e->el_outfile, "\n"); - } - - if (match_display) - rl_display_match_list(matches, matches_num, - maxlen); - retval = CC_REDISPLAY; - } else if (matches[0][0]) { - /* - * There was some common match, but the name was - * not complete enough. Next tab will print possible - * completions. - */ - el_beep(e); - } else { - /* lcd is not a valid object - further specification */ - /* is needed */ - el_beep(e); - retval = CC_NORM; - } - - /* free elements of array and the array itself */ - for (i = 0; matches[i]; i++) - free(matches[i]); - free(matches), matches = NULL; - - return (retval); - } - return (CC_NORM); + static char buf[2]; + buf[0] = rl_completion_append_character; + buf[1] = '\0'; + return buf; } /* * complete word at current point */ +/* ARGSUSED */ int -/*ARGSUSED*/ -rl_complete(int ignore, int invoking_key) +rl_complete(int ignore __attribute__((__unused__)), int invoking_key) { if (h == NULL || e == NULL) rl_initialize(); @@ -1873,15 +1516,26 @@ rl_complete(int ignore, int invoking_key) arr[1] = '\0'; el_insertstr(e, arr); return (CC_REFRESH); - } else if (e->el_state.lastcmd == el_rl_complete_cmdnum) - return _rl_complete_internal('?'); - else if (_rl_complete_show_all) - return _rl_complete_internal('!'); - else - return _rl_complete_internal(TAB); + } + + /* Just look at how many global variables modify this operation! */ + return fn_complete(e, + (CPFunction *)rl_completion_entry_function, + rl_attempted_completion_function, + rl_basic_word_break_characters, rl_special_prefixes, + _rl_completion_append_character_function, rl_completion_query_items, + &rl_completion_type, &rl_attempted_completion_over, + &rl_point, &rl_end); } +/* ARGSUSED */ +static unsigned char +_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) +{ + return (unsigned char)rl_complete(0, ch); +} + /* * misc other functions */ @@ -1989,7 +1643,7 @@ int rl_add_defun(const char *name, Function *fun, int c) { char dest[8]; - if (c >= sizeof(map) / sizeof(map[0]) || c < 0) + if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) return -1; map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); @@ -2007,11 +1661,7 @@ rl_callback_read_char() if (buf == NULL || count-- <= 0) return; -#ifdef CTRL2 /* _AIX */ - if (count == 0 && buf[0] == CTRL2('d')) -#else - if (count == 0 && buf[0] == CTRL('d')) -#endif + if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF]) done = 1; if (buf[count] == '\n' || buf[count] == '\r') done = 2; @@ -2029,14 +1679,12 @@ rl_callback_read_char() } void -rl_callback_handler_install (const char *prompt, VFunction *linefunc) +rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) { if (e == NULL) { rl_initialize(); } - if (rl_prompt) - free(rl_prompt); - rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL; + (void)rl_set_prompt(prompt); rl_linefunc = linefunc; el_set(e, EL_UNBUFFERED, 1); } @@ -2045,17 +1693,14 @@ void rl_callback_handler_remove(void) { el_set(e, EL_UNBUFFERED, 0); + rl_linefunc = NULL; } void rl_redisplay(void) { char a[2]; -#ifdef CTRL2 /* _AIX */ - a[0] = CTRL2('r'); -#else - a[0] = CTRL('r'); -#endif + a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; a[1] = '\0'; el_push(e, a); } @@ -2079,7 +1724,7 @@ rl_prep_terminal(int meta_flag) } void -rl_deprep_terminal() +rl_deprep_terminal(void) { el_set(e, EL_PREP_TERM, 0); } @@ -2104,6 +1749,16 @@ rl_parse_and_bind(const char *line) return (argc ? 1 : 0); } +int +rl_variable_bind(const char *var, const char *value) +{ + /* + * The proper return value is undocument, but this is what the + * readline source seems to do. + */ + return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0); +} + void rl_stuff_char(int c) { @@ -2119,7 +1774,7 @@ _rl_event_read_char(EditLine *el, char *cp) { int n, num_read = 0; - *cp = 0; + *cp = '\0'; while (rl_event_hook) { (*rl_event_hook)(); @@ -2164,3 +1819,142 @@ _rl_update_pos(void) rl_point = li->cursor - li->buffer; rl_end = li->lastchar - li->buffer; } + +void +rl_get_screen_size(int *rows, int *cols) +{ + if (rows) + el_get(e, EL_GETTC, "li", rows); + if (cols) + el_get(e, EL_GETTC, "co", cols); +} + +void +rl_set_screen_size(int rows, int cols) +{ + char buf[64]; + (void)snprintf(buf, sizeof(buf), "%d", rows); + el_set(e, EL_SETTC, "li", buf); + (void)snprintf(buf, sizeof(buf), "%d", cols); + el_set(e, EL_SETTC, "co", buf); +} + +char ** +rl_completion_matches(const char *str, rl_compentry_func_t *fun) +{ + size_t len, max, i, j, min; + char **list, *match, *a, *b; + + len = 1; + max = 10; + if ((list = malloc(max * sizeof(*list))) == NULL) + return NULL; + + while ((match = (*fun)(str, (int)(len - 1))) != NULL) { + if (len == max) { + char **nl; + max += 10; + if ((nl = realloc(list, max * sizeof(*nl))) == NULL) + goto out; + list = nl; + } + list[len++] = match; + } + if (len == 1) + goto out; + list[len] = NULL; + if (len == 2) { + if ((list[0] = strdup(list[1])) == NULL) + goto out; + return list; + } + qsort(&list[1], len - 1, sizeof(*list), + (int (*)(const void *, const void *)) strcmp); + min = SIZE_T_MAX; + for (i = 1, a = list[i]; i < len - 1; i++, a = b) { + b = list[i + 1]; + for (j = 0; a[j] && a[j] == b[j]; j++) + continue; + if (min > j) + min = j; + } + if (min == 0 && *str) { + if ((list[0] = strdup(str)) == NULL) + goto out; + } else { + if ((list[0] = malloc(min + 1)) == NULL) + goto out; + (void)memcpy(list[0], list[1], min); + list[0][min] = '\0'; + } + return list; + +out: + free(list); + return NULL; +} + +char * +rl_filename_completion_function (const char *text, int state) +{ + return fn_filename_completion_function(text, state); +} + +void +rl_forced_update_display(void) +{ + el_set(e, EL_REFRESH); +} + +int +_rl_abort_internal(void) +{ + el_beep(e); + longjmp(topbuf, 1); + /*NOTREACHED*/ +} + +int +_rl_qsort_string_compare(char **s1, char **s2) +{ + return strcoll(*s1, *s2); +} + +int +/*ARGSUSED*/ +rl_kill_text(int from, int to) +{ + return 0; +} + +Keymap +rl_make_bare_keymap(void) +{ + return NULL; +} + +Keymap +rl_get_keymap(void) +{ + return NULL; +} + +void +/*ARGSUSED*/ +rl_set_keymap(Keymap k) +{ +} + +int +/*ARGSUSED*/ +rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +{ + return 0; +} + +int +/*ARGSUSED*/ +rl_bind_key_in_map(int key, Function *fun, Keymap k) +{ + return 0; +} diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index 6b1fa186512..c77b080c439 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $ */ +/* $NetBSD: readline.h,v 1.24 2009/02/05 19:15:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -15,13 +15,6 @@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -45,14 +38,14 @@ /* typedefs */ typedef int Function(const char *, int); typedef void VFunction(void); +typedef void VCPFunction(char *); typedef char *CPFunction(const char *, int); typedef char **CPPFunction(const char *, int, int); - -typedef void *histdata_t; +typedef char *rl_compentry_func_t(const char *, int); typedef struct _hist_entry { const char *line; - histdata_t *data; + const char *data; } HIST_ENTRY; typedef struct _keymap_entry { @@ -73,7 +66,7 @@ typedef KEYMAP_ENTRY *Keymap; #ifndef CTRL #include -#if defined(__GLIBC__) || defined(__MWERKS__) +#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) #include #endif #ifndef CTRL @@ -102,8 +95,9 @@ extern int max_input_history; extern char *rl_basic_word_break_characters; extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; -extern CPFunction *rl_completion_entry_function; +extern Function *rl_completion_entry_function; extern CPPFunction *rl_attempted_completion_function; +extern int rl_attempted_completion_over; extern int rl_completion_type; extern int rl_completion_query_items; extern char *rl_special_prefixes; @@ -122,11 +116,13 @@ extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_ctlx_keymap; extern int rl_filename_completion_desired; extern int rl_ignore_completion_duplicates; -extern Function *rl_getc_function; +extern int (*rl_getc_function)(FILE *); extern VFunction *rl_redisplay_function; extern VFunction *rl_completion_display_matches_hook; extern VFunction *rl_prep_term_function; extern VFunction *rl_deprep_term_function; +extern int readline_echoing_p; +extern int _rl_print_completions_horizontally; /* supported functions */ char *readline(const char *); @@ -141,6 +137,7 @@ int history_is_stifled(void); int where_history(void); HIST_ENTRY *current_history(void); HIST_ENTRY *history_get(int); +HIST_ENTRY *remove_history(int); int history_total_bytes(void); int history_set_pos(int); HIST_ENTRY *previous_history(void); @@ -168,7 +165,7 @@ void rl_reset_terminal(const char *); int rl_bind_key(int, int (*)(int, int)); int rl_newline(int, int); void rl_callback_read_char(void); -void rl_callback_handler_install(const char *, VFunction *); +void rl_callback_handler_install(const char *, VCPFunction *); void rl_callback_handler_remove(void); void rl_redisplay(void); int rl_get_previous_history(int, int); @@ -176,13 +173,24 @@ void rl_prep_terminal(int); void rl_deprep_terminal(void); int rl_read_init_file(const char *); int rl_parse_and_bind(const char *); +int rl_variable_bind(const char *, const char *); void rl_stuff_char(int); int rl_add_defun(const char *, Function *, int); +void rl_get_screen_size(int *, int *); +void rl_set_screen_size(int, int); +char *rl_filename_completion_function (const char *, int); +int _rl_abort_internal(void); +int _rl_qsort_string_compare(char **, char **); +char **rl_completion_matches(const char *, rl_compentry_func_t *); +void rl_forced_update_display(void); +int rl_set_prompt(const char *); /* * The following are not implemented */ +int rl_kill_text(int, int); Keymap rl_get_keymap(void); +void rl_set_keymap(Keymap); Keymap rl_make_bare_keymap(void); int rl_generic_bind(int, const char *, const char *, Keymap); int rl_bind_key_in_map(int, Function *, Keymap); diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index 46aca15ef08..5edd1fe78fc 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * refresh.c: Lower level screen refreshing functions @@ -49,6 +55,7 @@ private void re_update_line(EditLine *, char *, char *, int); private void re_insert (EditLine *, char *, int, int, char *, int); private void re_delete(EditLine *, char *, int, int, int); private void re_fastputc(EditLine *, int); +private void re_clear_eol(EditLine *, int, int, int); private void re__strncopy(char *, char *, size_t); private void re__copy_and_pad(char *, const char *, size_t); @@ -315,9 +322,9 @@ re_goto_bottom(EditLine *el) { term_move_to_line(el, el->el_refresh.r_oldcv); - term__putc('\n'); + term__putc(el, '\n'); re_clear_display(el); - term__flush(); + term__flush(el); } @@ -340,7 +347,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); /* open up the space for num chars */ if (num > 0) { @@ -353,7 +360,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); /* copy the characters */ for (a = d + dat; (a < d + dlen) && (num > 0); num--) @@ -362,7 +369,7 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", num, dat, dlen, d, s)); - ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); } @@ -411,6 +418,32 @@ re__strncopy(char *a, char *b, size_t n) *a++ = *b++; } +/* re_clear_eol(): + * Find the number of characters we need to clear till the end of line + * in order to make sure that we have cleared the previous contents of + * the line. fx and sx is the number of characters inserted or deleted + * int the first or second diff, diff is the difference between the + * number of characters between the new and old line. + */ +private void +re_clear_eol(EditLine *el, int fx, int sx, int diff) +{ + + ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n", + sx, fx, diff)); + + if (fx < 0) + fx = -fx; + if (sx < 0) + sx = -sx; + if (fx > diff) + diff = fx; + if (sx > diff) + diff = sx; + + ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); + term_clear_EOL(el, diff); +} /***************************************************************** re_update_line() is based on finding the middle difference of each line @@ -626,7 +659,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) fx = (nsb - nfd) - (osb - ofd); sx = (nls - nse) - (ols - ose); - ELRE_DEBUG(1, (__F, "\n")); + ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", ofd - old, osb - old, ose - old, ols - old, oe - old)); ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n", @@ -775,9 +808,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * write (nsb-nfd) chars of new starting at nfd */ term_overwrite(el, nfd, (nsb - nfd)); - ELRE_DEBUG(1, (__F, - "cleareol %d\n", (oe - old) - (ne - new))); - term_clear_EOL(el, (oe - old) - (ne - new)); + re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); /* * Done */ @@ -818,10 +849,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) ELRE_DEBUG(1, (__F, "but with nothing left to save\r\n")); term_overwrite(el, nse, (nls - nse)); - ELRE_DEBUG(1, (__F, - "cleareol %d\n", (oe - old) - (ne - new))); - if ((oe - old) - (ne - new) != 0) - term_clear_EOL(el, (oe - old) - (ne - new)); + re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); } } /* @@ -982,7 +1010,7 @@ re_refresh_cursor(EditLine *el) /* now go there */ term_move_to_line(el, v); term_move_to_char(el, h); - term__flush(); + term__flush(el); } @@ -993,7 +1021,7 @@ private void re_fastputc(EditLine *el, int c) { - term__putc(c); + term__putc(el, c); el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; if (el->el_cursor.h >= el->el_term.t_size.h) { /* if we must overflow */ @@ -1020,12 +1048,12 @@ re_fastputc(EditLine *el, int c) } if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_MAGIC_MARGINS) { - term__putc(' '); - term__putc('\b'); + term__putc(el, ' '); + term__putc(el, '\b'); } } else { - term__putc('\r'); - term__putc('\n'); + term__putc(el, '\r'); + term__putc(el, '\n'); } } } @@ -1065,7 +1093,7 @@ re_fastaddc(EditLine *el) re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); re_fastputc(el, (c & 7) + '0'); } - term__flush(); + term__flush(el); } @@ -1104,7 +1132,7 @@ re_clear_lines(EditLine *el) } else { term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */ - term__putc('\r'); /* go to BOL */ - term__putc('\n'); /* go to new line */ + term__putc(el, '\r'); /* go to BOL */ + term__putc(el, '\n'); /* go to new line */ } } diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index 850c5f27140..df50c7e7370 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -32,12 +32,17 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * search.c: History and character search functions */ -#include #include #if defined(REGEX) #include diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c index 8e70933d606..5307ee6ec60 100644 --- a/cmd-line-utils/libedit/sig.c +++ b/cmd-line-utils/libedit/sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * sig.c: Signal handling stuff. @@ -51,15 +57,15 @@ private const int sighdl[] = { - 1 }; -private void sig_handler(int); +private void el_sig_handler(int); -/* sig_handler(): +/* el_sig_handler(): * This is the handler called for all signals * XXX: we cannot pass any data so we just store the old editline * state in a private variable */ private void -sig_handler(int signo) +el_sig_handler(int signo) { int i; sigset_t nset, oset; @@ -73,7 +79,7 @@ sig_handler(int signo) tty_rawmode(sel); if (ed_redisplay(sel, 0) == CC_REFRESH) re_refresh(sel); - term__flush(); + term__flush(sel); break; case SIGWINCH: @@ -154,7 +160,7 @@ sig_set(EditLine *el) for (i = 0; sighdl[i] != -1; i++) { el_signalhandler_t s; /* This could happen if we get interrupted */ - if ((s = signal(sighdl[i], sig_handler)) != sig_handler) + if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler) el->el_signal[i] = s; } sel = el; diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h index 0bf1fc37e39..2bd3c516d46 100644 --- a/cmd-line-utils/libedit/sig.h +++ b/cmd-line-utils/libedit/sig.h @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -51,7 +51,6 @@ #define ALLSIGS \ _DO(SIGINT) \ _DO(SIGTSTP) \ - _DO(SIGSTOP) \ _DO(SIGQUIT) \ _DO(SIGHUP) \ _DO(SIGTERM) \ diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index c8a29dbfb05..a0369affbb0 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -48,14 +48,14 @@ # define __attribute__(A) #endif -#ifndef __P -# define __P(x) x -#endif - #ifndef _DIAGASSERT # define _DIAGASSERT(x) #endif +#ifndef SIZE_T_MAX +# define SIZE_T_MAX UINT_MAX +#endif + #ifndef __BEGIN_DECLS # ifdef __cplusplus # define __BEGIN_DECLS extern "C" { @@ -113,6 +113,25 @@ char *fgetln(FILE *fp, size_t *len); #define REGEX /* Use POSIX.2 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */ +#ifdef __SunOS +extern int tgetent(char *, const char *); +extern int tgetflag(char *); +extern int tgetnum(char *); +extern int tputs(const char *, int, int (*)(int)); +extern char* tgoto(const char*, int, int); +extern char* tgetstr(char*, char**); +#endif + +/* XXXMYSQL: Bug#10218 Command line recall rolls into segfault */ +#if !HAVE_DECL_TGOTO +/* + 'tgoto' is not declared in the system header files, this causes + problems on 64-bit systems. The function returns a 64 bit pointer + but caller see it as "int" and it's thus truncated to 32-bit +*/ +extern char* tgoto(const char*, int, int); +#endif + #ifdef notdef # undef REGEX # undef REGEXP diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index b516d6753c3..488c760da14 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */ +/* $NetBSD: term.c,v 1.48 2009/02/06 20:08:13 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * term.c: Editor/termcap-curses interface @@ -44,21 +50,28 @@ #include #include #include - +#if 0 /* TODO: do we need this */ +#ifdef HAVE_TERMCAP_H +#include +#endif +#endif #ifdef HAVE_CURSES_H -# include -#elif HAVE_NCURSES_H -# include +#include +#endif +#ifdef HAVE_NCURSES_H +#include #endif - /* Solaris's term.h does horrid things. */ -#if (defined(HAVE_TERM_H) && !defined(_SUNOS)) -# include +#if (defined(HAVE_TERM_H) && !defined(__SunOS)) +#include #endif - #include #include +#ifdef _REENTRANT +#include +#endif + #include "el.h" /* @@ -263,9 +276,13 @@ private int term_alloc_display(EditLine *); private void term_alloc(EditLine *, const struct termcapstr *, const char *); private void term_init_arrow(EditLine *); private void term_reset_arrow(EditLine *); +private int term_putc(int); +private void term_tputs(EditLine *, const char *, int); - -private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ +#ifdef _REENTRANT +private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif +private FILE *term_outfile = NULL; /* term_setflags(): @@ -313,7 +330,6 @@ term_setflags(EditLine *el) #endif /* DEBUG_SCREEN */ } - /* term_init(): * Initialize the terminal stuff */ @@ -339,7 +355,6 @@ term_init(EditLine *el) if (el->el_term.t_val == NULL) return (-1); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); - term_outfile = el->el_outfile; (void) term_set(el, NULL); term_init_arrow(el); return (0); @@ -390,7 +405,8 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) * New string is shorter; no need to allocate space */ if (clen <= tlen) { - (void) strcpy(*str, cap); /* XXX strcpy is safe */ + if (*str) + (void) strcpy(*str, cap); /* XXX strcpy is safe */ return; } /* @@ -464,8 +480,12 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + while (--i >= 0) + el_free((ptr_t) b[i]); + el_free((ptr_t) b); return (-1); + } } b[c->v] = NULL; el->el_display = b; @@ -475,8 +495,12 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + while (--i >= 0) + el_free((ptr_t) b[i]); + el_free((ptr_t) b); return (-1); + } } b[c->v] = NULL; el->el_vdisplay = b; @@ -542,12 +566,12 @@ term_move_to_line(EditLine *el, int where) del--; } else { if ((del > 1) && GoodStr(T_DO)) { - (void) tputs(tgoto(Str(T_DO), del, del), - del, term__putc); + term_tputs(el, tgoto(Str(T_DO), del, + del), del); del = 0; } else { for (; del > 0; del--) - term__putc('\n'); + term__putc(el, '\n'); /* because the \n will become \r\n */ el->el_cursor.h = 0; } @@ -555,12 +579,11 @@ term_move_to_line(EditLine *el, int where) } } else { /* del < 0 */ if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - (void) tputs(tgoto(Str(T_UP), -del, -del), -del, - term__putc); + term_tputs(el, tgoto(Str(T_UP), -del, -del), -del); else { if (GoodStr(T_up)) for (; del < 0; del++) - (void) tputs(Str(T_up), 1, term__putc); + term_tputs(el, Str(T_up), 1); } } el->el_cursor.v = where;/* now where is here */ @@ -587,7 +610,7 @@ mc_again: return; } if (!where) { /* if where is first column */ - term__putc('\r'); /* do a CR */ + term__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; return; } @@ -595,12 +618,11 @@ mc_again: if ((del < -4 || del > 4) && GoodStr(T_ch)) /* go there directly */ - (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); + term_tputs(el, tgoto(Str(T_ch), where, where), where); else { if (del > 0) { /* moving forward */ if ((del > 4) && GoodStr(T_RI)) - (void) tputs(tgoto(Str(T_RI), del, del), - del, term__putc); + term_tputs(el, tgoto(Str(T_RI), del, del), del); else { /* if I can do tabs, use them */ if (EL_CAN_TAB) { @@ -611,7 +633,7 @@ mc_again: (el->el_cursor.h & 0370); i < (where & 0370); i += 8) - term__putc('\t'); + term__putc(el, '\t'); /* then tab over */ el->el_cursor.h = where & 0370; } @@ -631,8 +653,8 @@ mc_again: } } else { /* del < 0 := moving backward */ if ((-del > 4) && GoodStr(T_LE)) - (void) tputs(tgoto(Str(T_LE), -del, -del), - -del, term__putc); + term_tputs(el, tgoto(Str(T_LE), -del, -del), + -del); else { /* can't go directly there */ /* * if the "cost" is greater than the "cost" @@ -643,12 +665,12 @@ mc_again: (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { - term__putc('\r'); /* do a CR */ + term__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; goto mc_again; /* and try again */ } for (i = 0; i < -del; i++) - term__putc('\b'); + term__putc(el, '\b'); } } } @@ -673,7 +695,7 @@ term_overwrite(EditLine *el, const char *cp, int n) return; } do { - term__putc(*cp++); + term__putc(el, *cp++); el->el_cursor.h++; } while (--n); @@ -689,7 +711,7 @@ term_overwrite(EditLine *el, const char *cp, int n) != '\0') term_overwrite(el, &c, 1); else - term__putc(' '); + term__putc(el, ' '); el->el_cursor.h = 1; } } else /* no wrap, but cursor stays on screen */ @@ -723,19 +745,18 @@ term_deletechars(EditLine *el, int num) if (GoodStr(T_DC)) /* if I have multiple delete */ if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more * expen. */ - (void) tputs(tgoto(Str(T_DC), num, num), - num, term__putc); + term_tputs(el, tgoto(Str(T_DC), num, num), num); return; } if (GoodStr(T_dm)) /* if I have delete mode */ - (void) tputs(Str(T_dm), 1, term__putc); + term_tputs(el, Str(T_dm), 1); if (GoodStr(T_dc)) /* else do one at a time */ while (num--) - (void) tputs(Str(T_dc), 1, term__putc); + term_tputs(el, Str(T_dc), 1); if (GoodStr(T_ed)) /* if I have delete mode */ - (void) tputs(Str(T_ed), 1, term__putc); + term_tputs(el, Str(T_ed), 1); } @@ -764,37 +785,35 @@ term_insertwrite(EditLine *el, char *cp, int num) if (GoodStr(T_IC)) /* if I have multiple insert */ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expensive */ - (void) tputs(tgoto(Str(T_IC), num, num), - num, term__putc); + term_tputs(el, tgoto(Str(T_IC), num, num), num); term_overwrite(el, cp, num); /* this updates el_cursor.h */ return; } if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - (void) tputs(Str(T_im), 1, term__putc); + term_tputs(el, Str(T_im), 1); el->el_cursor.h += num; do - term__putc(*cp++); + term__putc(el, *cp++); while (--num); if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc); + term_tputs(el, Str(T_ip), 1); - (void) tputs(Str(T_ei), 1, term__putc); + term_tputs(el, Str(T_ei), 1); return; } do { if (GoodStr(T_ic)) /* have to make num chars insert */ - (void) tputs(Str(T_ic), 1, term__putc); - /* insert a char */ + term_tputs(el, Str(T_ic), 1); - term__putc(*cp++); + term__putc(el, *cp++); el->el_cursor.h++; if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc); + term_tputs(el, Str(T_ip), 1); /* pad the inserted char */ } while (--num); @@ -810,10 +829,10 @@ term_clear_EOL(EditLine *el, int num) int i; if (EL_CAN_CEOL && GoodStr(T_ce)) - (void) tputs(Str(T_ce), 1, term__putc); + term_tputs(el, Str(T_ce), 1); else { for (i = 0; i < num; i++) - term__putc(' '); + term__putc(el, ' '); el->el_cursor.h += num; /* have written num spaces */ } } @@ -828,14 +847,14 @@ term_clear_screen(EditLine *el) if (GoodStr(T_cl)) /* send the clear screen code */ - (void) tputs(Str(T_cl), Val(T_li), term__putc); + term_tputs(el, Str(T_cl), Val(T_li)); else if (GoodStr(T_ho) && GoodStr(T_cd)) { - (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ + term_tputs(el, Str(T_ho), Val(T_li)); /* home */ /* clear to bottom of screen */ - (void) tputs(Str(T_cd), Val(T_li), term__putc); + term_tputs(el, Str(T_cd), Val(T_li)); } else { - term__putc('\r'); - term__putc('\n'); + term__putc(el, '\r'); + term__putc(el, '\n'); } } @@ -848,9 +867,9 @@ term_beep(EditLine *el) { if (GoodStr(T_bl)) /* what termcap says we should use */ - (void) tputs(Str(T_bl), 1, term__putc); + term_tputs(el, Str(T_bl), 1); else - term__putc('\007'); /* an ASCII bell; ^G */ + term__putc(el, '\007'); /* an ASCII bell; ^G */ } @@ -862,9 +881,9 @@ protected void term_clear_to_bottom(EditLine *el) { if (GoodStr(T_cd)) - (void) tputs(Str(T_cd), Val(T_li), term__putc); + term_tputs(el, Str(T_cd), Val(T_li)); else if (GoodStr(T_ce)) - (void) tputs(Str(T_ce), Val(T_li), term__putc); + term_tputs(el, Str(T_ce), Val(T_li)); } #endif @@ -936,7 +955,7 @@ term_set(EditLine *el, const char *term) Val(T_co) = tgetnum("co"); Val(T_li) = tgetnum("li"); for (t = tstr; t->name != NULL; t++) { - /* XXX: some systems tgetstr needs non const */ + /* XXX: some systems' tgetstr needs non const */ term_alloc(el, t, tgetstr(strchr(t->name, *t->name), &area)); } @@ -1220,26 +1239,62 @@ term_bind_arrow(EditLine *el) } } +/* term_putc(): + * Add a character + */ +private int +term_putc(int c) +{ + + if (term_outfile == NULL) + return -1; + return fputc(c, term_outfile); +} + +private void +term_tputs(EditLine *el, const char *cap, int affcnt) +{ +#ifdef _REENTRANT + pthread_mutex_lock(&term_mutex); +#endif + term_outfile = el->el_outfile; + (void)tputs(cap, affcnt, term_putc); +#ifdef _REENTRANT + pthread_mutex_unlock(&term_mutex); +#endif +} /* term__putc(): * Add a character */ protected int -term__putc(int c) +term__putc(EditLine *el, int c) { - return (fputc(c, term_outfile)); + return fputc(c, el->el_outfile); } - /* term__flush(): * Flush output */ protected void -term__flush(void) +term__flush(EditLine *el) { - (void) fflush(term_outfile); + (void) fflush(el->el_outfile); +} + +/* term_writec(): + * Write the given character out, in a human readable form + */ +protected void +term_writec(EditLine *el, int c) +{ + char buf[8]; + int cnt = key__decode_char(buf, sizeof(buf), 0, c); + buf[cnt] = '\0'; + term_overwrite(el, buf, cnt); + term__flush(el); } @@ -1269,11 +1324,17 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)), (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); - for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) + for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) { + const char *ub; + if (*ts && **ts) { + (void) key__decode_str(*ts, upbuf, sizeof(upbuf), ""); + ub = upbuf; + } else { + ub = "(empty)"; + } (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", - t->long_name, - t->name, *ts && **ts ? - key__decode_str(*ts, upbuf, "") : "(empty)"); + t->long_name, t->name, ub); + } (void) fputc('\n', el->el_outfile); return (0); } @@ -1292,7 +1353,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), const char *what, *how; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return (-1); + return -1; what = argv[1]; how = argv[2]; @@ -1307,7 +1368,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), if (ts->name != NULL) { term_alloc(el, ts, how); term_setflags(el); - return (0); + return 0; } /* * Do the numeric ones second @@ -1316,46 +1377,100 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), if (strcmp(tv->name, what) == 0) break; - if (tv->name != NULL) { - if (tv == &tval[T_pt] || tv == &tval[T_km] || - tv == &tval[T_am] || tv == &tval[T_xn]) { - if (strcmp(how, "yes") == 0) - el->el_term.t_val[tv - tval] = 1; - else if (strcmp(how, "no") == 0) - el->el_term.t_val[tv - tval] = 0; - else { - (void) fprintf(el->el_errfile, - "settc: Bad value `%s'.\n", how); - return (-1); - } - term_setflags(el); - if (term_change_size(el, Val(T_li), Val(T_co)) == -1) - return (-1); - return (0); - } else { - long i; - char *ep; + if (tv->name != NULL) + return -1; - i = strtol(how, &ep, 10); - if (*ep != '\0') { - (void) fprintf(el->el_errfile, - "settc: Bad value `%s'.\n", how); - return (-1); - } - el->el_term.t_val[tv - tval] = (int) i; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); - if (tv == &tval[T_co] || tv == &tval[T_li]) - if (term_change_size(el, Val(T_li), Val(T_co)) - == -1) - return (-1); - return (0); + if (tv == &tval[T_pt] || tv == &tval[T_km] || + tv == &tval[T_am] || tv == &tval[T_xn]) { + if (strcmp(how, "yes") == 0) + el->el_term.t_val[tv - tval] = 1; + else if (strcmp(how, "no") == 0) + el->el_term.t_val[tv - tval] = 0; + else { + (void) fprintf(el->el_errfile, + "%s: Bad value `%s'.\n", argv[0], how); + return -1; } + term_setflags(el); + if (term_change_size(el, Val(T_li), Val(T_co)) == -1) + return -1; + return 0; + } else { + long i; + char *ep; + + i = strtol(how, &ep, 10); + if (*ep != '\0') { + (void) fprintf(el->el_errfile, + "%s: Bad value `%s'.\n", argv[0], how); + return -1; + } + el->el_term.t_val[tv - tval] = (int) i; + el->el_term.t_size.v = Val(T_co); + el->el_term.t_size.h = Val(T_li); + if (tv == &tval[T_co] || tv == &tval[T_li]) + if (term_change_size(el, Val(T_li), Val(T_co)) + == -1) + return -1; + return 0; } - return (-1); } +/* term_gettc(): + * Get the current terminal characteristics + */ +protected int +/*ARGSUSED*/ +term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) +{ + const struct termcapstr *ts; + const struct termcapval *tv; + char *what; + void *how; + + if (argv == NULL || argv[1] == NULL || argv[2] == NULL) + return (-1); + + what = argv[1]; + how = argv[2]; + + /* + * Do the strings first + */ + for (ts = tstr; ts->name != NULL; ts++) + if (strcmp(ts->name, what) == 0) + break; + + if (ts->name != NULL) { + *(char **)how = el->el_term.t_str[ts - tstr]; + return 0; + } + /* + * Do the numeric ones second + */ + for (tv = tval; tv->name != NULL; tv++) + if (strcmp(tv->name, what) == 0) + break; + + if (tv->name == NULL) + return -1; + + if (tv == &tval[T_pt] || tv == &tval[T_km] || + tv == &tval[T_am] || tv == &tval[T_xn]) { + static char yes[] = "yes"; + static char no[] = "no"; + if (el->el_term.t_val[tv - tval]) + *(char **)how = yes; + else + *(char **)how = no; + return 0; + } else { + *(int *)how = el->el_term.t_val[tv - tval]; + return 0; + } +} + /* term_echotc(): * Print the termcap string out with variable substitution */ @@ -1441,7 +1556,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), break; } if (t->name == NULL) { - /* XXX: some systems tgetstr needs non const */ + /* XXX: some systems' tgetstr needs non const */ scap = tgetstr(strchr(*argv, **argv), &area); } if (!scap || scap[0] == '\0') { @@ -1494,7 +1609,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(scap, 1, term__putc); + term_tputs(el, scap, 1); break; case 1: argv++; @@ -1522,7 +1637,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); + term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); break; default: /* This is wrong, but I will ignore it... */ @@ -1578,8 +1693,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), *argv); return (-1); } - (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, - term__putc); + term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); break; } return (0); diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c index 561b41740f8..5161cdd0a22 100644 --- a/cmd-line-utils/libedit/tokenizer.c +++ b/cmd-line-utils/libedit/tokenizer.c @@ -32,7 +32,13 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * tokenize.c: Bourne shell like tokenizer diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c index 6f73fb4f9e7..3706905fc79 100644 --- a/cmd-line-utils/libedit/tty.c +++ b/cmd-line-utils/libedit/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,18 +32,25 @@ * SUCH DAMAGE. */ -#include +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * tty.c: tty interface stuff */ #include +#include #include "tty.h" #include "el.h" typedef struct ttymodes_t { const char *m_name; - u_int m_value; + unsigned int m_value; int m_type; } ttymodes_t; @@ -438,13 +445,12 @@ private const ttymodes_t ttymodes[] = { -#define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) -#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) - #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) +private int tty_getty(EditLine *, struct termios *); +private int tty_setty(EditLine *, int, const struct termios *); private int tty__getcharindex(int); private void tty__getchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *); @@ -453,6 +459,29 @@ private int tty_setup(EditLine *); #define t_qu t_ts +/* tty_getty(): + * Wrapper for tcgetattr to handle EINTR + */ +private int +tty_getty(EditLine *el, struct termios *t) +{ + int rv; + while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) + continue; + return rv; +} + +/* tty_setty(): + * Wrapper for tcsetattr to handle EINTR + */ +private int +tty_setty(EditLine *el, int action, const struct termios *t) +{ + int rv; + while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) + continue; + return rv; +} /* tty_setup(): * Get the tty parameters and initialize the editing state @@ -514,7 +543,7 @@ tty_setup(EditLine *el) el->el_tty.t_c[TS_IO][rst]; } tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", @@ -522,8 +551,11 @@ tty_setup(EditLine *el) #endif /* DEBUG_TTY */ return (-1); } - } else + } +#ifdef notdef + else tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); +#endif el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; @@ -1040,7 +1072,7 @@ tty_rawmode(EditLine *el) } } } - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", strerror(errno)); @@ -1065,7 +1097,7 @@ tty_cookedmode(EditLine *el) if (el->el_flags & EDIT_DISABLED) return (0); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n", @@ -1101,7 +1133,7 @@ tty_quotemode(EditLine *el) el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; - if (tty_setty(el, &el->el_tty.t_qu) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", strerror(errno)); @@ -1122,7 +1154,7 @@ tty_noquotemode(EditLine *el) if (el->el_tty.t_mode != QU_IO) return (0); - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", strerror(errno)); @@ -1193,10 +1225,14 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name); } - x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) - ? '+' : '\0'; - x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) - ? '-' : x; + if (i != -1) { + x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) + ? '+' : '\0'; + x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) + ? '-' : x; + } else { + x = '\0'; + } if (x != '\0' || aflag) { @@ -1221,7 +1257,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) return (0); } while (argv && (s = *argv++)) { - char *p; + const char *p; switch (*s) { case '+': case '-': @@ -1232,10 +1268,10 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) break; } d = s; - if ((p = strchr(s, '=')) != NULL) - *p++ = '\0'; + p = strchr(s, '='); for (m = ttymodes; m->m_name; m++) - if (strcmp(m->m_name, d) == 0 && + if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) : + strcmp(m->m_name, d)) == 0 && (p == NULL || m->m_type == MD_CHAR)) break; @@ -1246,7 +1282,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) } if (p) { int c = ffs((int)m->m_value); - int v = *p ? parse__escape((const char **const) &p) : + int v = *++p ? parse__escape((const char **) &p) : el->el_tty.t_vdisable; assert(c-- != 0); c = tty__getcharindex(c); @@ -1269,6 +1305,17 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) break; } } + + if (el->el_tty.t_mode == z) { + if (tty_setty(el, TCSADRAIN, tios) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, + "tty_stty: tty_setty: %s\n", strerror(errno)); +#endif /* DEBUG_TTY */ + return (-1); + } + } + return (0); } diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h index cc7c4ad8c66..10e9b98c953 100644 --- a/cmd-line-utils/libedit/tty.h +++ b/cmd-line-utils/libedit/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $ */ +/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -450,8 +450,8 @@ typedef struct { const char *t_name; - u_int t_setmask; - u_int t_clrmask; + unsigned int t_setmask; + unsigned int t_clrmask; } ttyperm_t[NN_IO][MD_NN]; typedef unsigned char ttychar_t[NN_IO][C_NCC]; diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index b977ce716c6..00a9f493a9b 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ +/* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -32,11 +32,17 @@ * SUCH DAMAGE. */ -#include +#include "config.h" #include #include #include +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; +#else +#endif +#endif /* not lint && not SCCSID */ /* * vi.c: Vi mode commands. @@ -64,8 +70,10 @@ cv_action(EditLine *el, int c) el->el_line.lastchar - el->el_line.buffer); el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; + if (!(c & YANK)) { + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + } if (c & INSERT) el->el_map.current = el->el_map.key; @@ -82,7 +90,6 @@ cv_action(EditLine *el, int c) private el_action_t cv_paste(EditLine *el, int c) { - char *ptr; c_kill_t *k = &el->el_chared.c_kill; int len = k->last - k->buf; @@ -96,12 +103,12 @@ cv_paste(EditLine *el, int c) if (!c && el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; - ptr = el->el_line.cursor; c_insert(el, len); if (el->el_line.cursor + len > el->el_line.lastchar) return (CC_ERROR); - (void) memcpy(ptr, k->buf, len +0u); + (void) memcpy(el->el_line.cursor, k->buf, len +0u); + return (CC_REFRESH); } @@ -592,13 +599,12 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_list_or_eof(EditLine *el, int c __attribute__((__unused__))) +vi_list_or_eof(EditLine *el, int c) { if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.buffer) { - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); + term_writec(el, c); /* then do a EOF */ return (CC_EOF); } else { /* @@ -888,7 +894,7 @@ vi_yank(EditLine *el, int c) /* vi_comment_out(): * Vi comment out current command - * [c] + * [#] */ protected el_action_t /*ARGSUSED*/ @@ -905,18 +911,19 @@ vi_comment_out(EditLine *el, int c) /* vi_alias(): * Vi include shell alias * [@] - * NB: posix impiles that we should enter insert mode, however + * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ +#if defined(__weak_reference) && !defined(__FreeBSD__) +extern char *get_alias_text(const char *) __weak_reference(get_alias_text); +#endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el, int c) { -#ifdef __weak_extern +#if defined(__weak_reference) && !defined(__FreeBSD__) char alias_name[3]; char *alias_text; - extern char *get_alias_text(const char *); - __weak_extern(get_alias_text); if (get_alias_text == 0) { return CC_ERROR; @@ -1014,7 +1021,7 @@ vi_histedit(EditLine *el, int c) return CC_ERROR; case 0: close(fd); - execlp("vi", "vi", tempfile, (char *) NULL); + execlp("vi", "vi", tempfile, (char *)NULL); exit(0); /*NOTREACHED*/ default: From 8c1bb95156851b142750b61203e760042646d166 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:16:50 +0200 Subject: [PATCH 002/188] backport #43748, applying commits 70359 and 70377 --- sql/sql_class.cc | 7 +++++++ sql/sql_class.h | 1 + sql/sql_parse.cc | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 883291ec460..ed68d7fad54 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2125,6 +2125,13 @@ void Security_context::skip_grants() } +bool Security_context::user_matches(Security_context *them) +{ + return ((user != NULL) && (them->user != NULL) && + !strcmp(user, them->user)); +} + + /**************************************************************************** Handling of open and locked tables states. diff --git a/sql/sql_class.h b/sql/sql_class.h index c8d42d44df7..6316aca444d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -978,6 +978,7 @@ public: { return (*priv_host ? priv_host : (char *)"%"); } + bool user_matches(Security_context *); }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 91c5cacc4d0..23761b400f0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7339,8 +7339,26 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (tmp) { + + /* + If we're SUPER, we can KILL anything, including system-threads. + No further checks. + + KILLer: thd->security_ctx->user could in theory be NULL while + we're still in "unauthenticated" state. This is a theoretical + case (the code suggests this could happen, so we play it safe). + + KILLee: tmp->security_ctx->user will be NULL for system threads. + We need to check so Jane Random User doesn't crash the server + when trying to kill a) system threads or b) unauthenticated users' + threads (Bug#43748). + + If user of both killer and killee are non-NULL, proceed with + slayage if both are string-equal. + */ + if ((thd->security_ctx->master_access & SUPER_ACL) || - !strcmp(thd->security_ctx->user, tmp->security_ctx->user)) + thd->security_ctx->user_matches(tmp->security_ctx)) { tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); error=0; From 4c60b1d4b74798ae55da9e2f49493e058df67b38 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:36:18 +0200 Subject: [PATCH 003/188] backport #42419, commits 66925, 66999 --- mysql-test/r/innodb_mysql.result | 32 +++++++++++++++ mysql-test/t/innodb_mysql.test | 69 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 36 +++++++++++------ 3 files changed, 125 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 682cc2e82e2..0cf0d0f5536 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1267,4 +1267,36 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; a DROP TABLE t1; +CREATE DATABASE systest1; +USE systest1; +CREATE TABLE tb1_eng1 ( +i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1), +f1 INT +) ENGINE = InnoDB; +INSERT INTO systest1.tb1_eng1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE systest1.t1_tmp ( f1 INT ); +INSERT INTO systest1.t1_tmp (f1) +SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 3; +INSERT INTO systest1.t1_tmp (f1) +SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 2; +SET AUTOCOMMIT = 0; +USE systest1; +CREATE TEMPORARY TABLE systest1.t2_tmp ( i1 int, new_i1 int ); +INSERT INTO systest1.t2_tmp VALUES +(1,51),(2,52),(3,53); +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) +WHERE i1 = 1; +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) +WHERE i1 = 2; +INSERT INTO systest1.t1_tmp (f1) +SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) +WHERE i1 = 3; +drop database systest1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b4fc425cb7c..f830399b919 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1025,4 +1025,73 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; DROP TABLE t1; +# +# Bug #42419: Server crash with "Pure virtual method called" on two +# concurrent connections +# + +connect (c1, localhost, root,,); +connect (c2, localhost, root,,); + +CREATE DATABASE systest1; +USE systest1; + +CREATE TABLE tb1_eng1 ( + i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1), + f1 INT +) ENGINE = InnoDB; + +INSERT INTO systest1.tb1_eng1 VALUES (1,1),(2,2),(3,3); +COMMIT; + +connection c1; + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE systest1.t1_tmp ( f1 INT ); + +INSERT INTO systest1.t1_tmp (f1) + SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 3; +INSERT INTO systest1.t1_tmp (f1) + SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 2; + + +connection c2; + +SET AUTOCOMMIT = 0; +USE systest1; + +CREATE TEMPORARY TABLE systest1.t2_tmp ( i1 int, new_i1 int ); +INSERT INTO systest1.t2_tmp VALUES +(1,51),(2,52),(3,53); + +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) + WHERE i1 = 1; + +--send +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) + WHERE i1 = 2; + +--sleep 2 + +connection c1; + +--error ER_LOCK_DEADLOCK +INSERT INTO systest1.t1_tmp (f1) + SELECT f1 FROM systest1.tb1_eng1 WHERE i1 = 1; + +connection c2; + +--reap +UPDATE systest1.tb1_eng1 target +SET i1 = (SELECT new_i1 FROM systest1.t2_tmp source WHERE source.i1 = target.i1) + WHERE i1 = 3; + +connection default; +disconnect c1; +disconnect c2; +drop database systest1; + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2ac33c4e07f..f78991073bb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2366,11 +2366,12 @@ typedef struct st_sargable_param */ static bool -make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, +make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DYNAMIC_ARRAY *keyuse_array) { int error; TABLE *table; + TABLE_LIST *tables= tables_arg; uint i,table_count,const_count,key; table_map found_const_table_map, all_table_map, found_ref, refs; key_map const_ref, eq_part; @@ -2408,10 +2409,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, table_vector[i]=s->table=table=tables->table; table->pos_in_table_list= tables; error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (error) { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(1); + table->file->print_error(error, MYF(0)); + goto error; } table->quick_keys.clear_all(); table->reginfo.join_tab=s; @@ -2496,7 +2497,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { join->tables=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); - DBUG_RETURN(1); + goto error; } s->key_dependent= s->dependent; } @@ -2506,7 +2507,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) - DBUG_RETURN(1); + goto error; /* Read tables with 0 or 1 rows (system tables) */ join->const_table_map= 0; @@ -2522,7 +2523,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp=join_read_const_table(s, p_pos))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= s->table->map; @@ -2594,7 +2595,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if ((tmp= join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2643,12 +2644,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) - DBUG_RETURN(1); + goto error; if ((tmp=join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2725,7 +2726,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error); if (!select) - DBUG_RETURN(1); + goto error; records= get_quick_record_count(join->thd, select, s->table, &s->const_keys, join->row_limit); s->quick=select->quick; @@ -2771,7 +2772,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, { optimize_keyuse(join, keyuse_array); if (choose_plan(join, all_table_map & ~join->const_table_map)) - DBUG_RETURN(TRUE); + goto error; } else { @@ -2781,6 +2782,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, } /* Generate an execution plan from the found optimal join order. */ DBUG_RETURN(join->thd->killed || get_best_combination(join)); + +error: + /* + Need to clean up join_tab from TABLEs in case of error. + They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab + may not be assigned yet by this function (which is building join_tab). + Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. + */ + for (tables= tables_arg; tables; tables= tables->next_leaf) + tables->table->reginfo.join_tab= NULL; + DBUG_RETURN (1); } From ce81eaeefd9d6f4de659ac6b868ca12b823a571d Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:38:22 +0200 Subject: [PATCH 004/188] backport 42366, copying certificates from 5.0 --- mysql-test/std_data/cacert.pem | 24 +-- mysql-test/std_data/client-cert.pem | 75 +++++---- mysql-test/std_data/client-key.pem | 14 +- mysql-test/std_data/server-cert-des.pem | 16 -- mysql-test/std_data/server-cert.pem | 73 +++++---- mysql-test/std_data/server-key-des.pem | 18 --- mysql-test/std_data/server-key.pem | 14 +- mysql-test/std_data/server8k-cert.pem | 185 ++++++++++++++++------ mysql-test/std_data/server8k-key.pem | 194 ++++++++++++------------ 9 files changed, 346 insertions(+), 267 deletions(-) delete mode 100644 mysql-test/std_data/server-cert-des.pem delete mode 100644 mysql-test/std_data/server-key-des.pem diff --git a/mysql-test/std_data/cacert.pem b/mysql-test/std_data/cacert.pem index b445e77d7c4..5473e4b153e 100644 --- a/mysql-test/std_data/cacert.pem +++ b/mysql-test/std_data/cacert.pem @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICrTCCAhagAwIBAgIJAIAO/Ybiptv1MA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV +MIICrTCCAhagAwIBAgIJAJXpePU0UOTVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD -VQQKEwhNeVNRTCBBQjAeFw0wNjA1MDMwODQ4NTRaFw0wOTAxMjcwODQ4NTRaMEQx +VQQKEwhNeVNRTCBBQjAeFw0wOTAxMjgxMDQ5NDZaFw0xNDAxMjcxMDQ5NDZaMEQx CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA -+C46EQl1u7tQ6gb9eqc8V079gr8YmDPCEqtjO8bCIbchpjOpDITx0WZz36Sn9E72 -GPJwNip4FxLaPRIA3xNQHM5cE5U53qznlRx1Fc4O3hcWCvyCqNDl/vzPAh3pI6Bl -Ku9hfHXpp93W812smVPe9haShEXGgbEPYGzvOfVdu/MCAwEAAaOBpjCBozAdBgNV -HQ4EFgQUjIy/6OCTmqtPHBFha6/qzVk3yTcwdAYDVR0jBG0wa4AUjIy/6OCTmqtP -HBFha6/qzVk3yTehSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh -MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAIAO/Ybiptv1 -MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA8lD9zyB820Oq1aj7ZafX -De/hbdt9RIl2tzgw2K3r1KZGdXJVL0vSt5fZ51Nq9lg7OPJy3iXf+caBJEp0IJpB -uf4Gfr6zfXw+UlY6ZthRtHQHoXKcbskECjH5/ps/Uaa+dpVQ9O+Ii1rPzmgo6ztM -s+xZ46ESBt4WiHXm8kwbU9Y= +4XQHAe5R1+TXC8noZtWf+d5E0v1C59FWpn9SWEUCBjE5UiIwuJvi4Y+7xWGOXLAI +/JzJx5gNXLBiTsE/zh0uX9fKlajLhxB0GN+QU0ZlpQ1BeYipEcNXeI/7cT499f6v +XWabnTflivdCgHSWUOQ20/Lzs6kP6/e6OoZd/DPSjPECAwEAAaOBpjCBozAdBgNV +HQ4EFgQU8uLqVWWkmuKsnZf1RWz294wRrd8wdAYDVR0jBG0wa4AU8uLqVWWkmuKs +nZf1RWz294wRrd+hSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh +MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTV +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAMMTE5sDN+Z0ZlV7KvH3g +6+aKvql8dTpRT3hYukeQlWua0nq74WPGVw0c4e/M/vbiMwmJcCYpB9pd4+dHqzSw +aPyoenjY6UF8n7B4quWy3SIUk2LSHeJLW+kzJn2afN9gvipFhdVh/uU2TIyLGOur +Z/vmJX2W7hF1uqPnbfa8Lrw= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-cert.pem b/mysql-test/std_data/client-cert.pem index fdd5c86a23f..9300520793e 100644 --- a/mysql-test/std_data/client-cert.pem +++ b/mysql-test/std_data/client-cert.pem @@ -1,42 +1,55 @@ Certificate: Data: - Version: 1 (0x0) - Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha1WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: May 3 08:55:39 2006 GMT - Not After : Jan 27 08:55:39 2009 GMT - Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 28 11:04:39 2009 GMT + Not After : Jan 28 11:04:39 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:d8:db:68:28:49:84:4d:d6:0f:5c:bc:3d:9a:ab: - 70:d5:3e:f5:b5:17:ba:ef:e1:f8:87:54:30:22:1f: - 81:07:bf:f9:24:7f:8a:54:10:e9:5f:e6:99:50:04: - d4:3b:55:a9:f1:52:ad:12:2b:5a:da:5c:be:8c:3e: - 5b:9e:b0:5a:19 + 00:e1:52:30:2c:d9:be:64:28:91:5d:7a:fd:d9:e9: + 14:35:7a:d2:94:4e:91:46:e0:db:9f:6b:79:f4:4c: + ac:6e:07:61:34:86:74:62:a7:a8:44:af:fa:87:87: + a8:7d:42:61:ff:ab:50:d4:7b:bf:75:fa:d5:d5:b3: + 74:fb:56:1e:37 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - 07:57:bf:07:92:c2:8e:86:24:6b:0a:bf:e5:31:21:44:c3:60: - 02:a6:ac:9e:f7:db:7a:6e:fc:4f:d4:7b:54:18:80:47:d2:4a: - 63:0e:e3:f8:af:6e:58:e3:97:5a:2b:82:5d:76:20:d1:33:a0: - f5:43:a1:d1:51:f4:ca:c8:b3:1a:66:4e:0e:55:df:d2:e8:fa: - 83:18:42:f5:ec:66:40:f0:39:e8:f9:d7:cf:f6:dd:e4:7b:69: - dd:0c:92:d8:52:95:43:6f:29:3d:f0:8d:4c:dd:52:ea:6b:a0: - 39:0f:dc:59:a7:5c:37:6b:8b:05:44:b7:69:ea:a3:58:e0:4e: - ce:d6 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 58:30:B5:9B:2C:05:94:06:BA:3D:3C:F0:B2:CD:1D:67:65:E3:7F:85 + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + 05:19:e3:13:14:fc:c5:28:bf:69:f8:00:b3:25:cb:bd:ca:9f: + 2f:4c:b3:a8:04:11:f0:74:27:bd:82:2c:b4:49:9b:a7:59:f0: + f7:87:d1:e0:ba:99:a2:fe:4b:1d:10:6f:e4:a2:b3:cd:7f:8b: + 68:31:46:ee:cd:9e:e2:47:e1:4c:fa:74:d1:e2:8b:cc:a0:4b: + a8:24:d1:a4:c3:6b:2a:c6:28:cd:41:e0:06:48:e6:cf:f2:3c: + ca:37:95:d7:29:64:6b:91:91:83:e7:ac:c8:0b:87:bc:da:a6: + aa:f1:44:43:c8:74:7b:15:26:91:2e:03:c4:71:50:6c:f8:68: + dc:8c -----BEGIN CERTIFICATE----- -MIIB5jCCAU8CAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC -MB4XDTA2MDUwMzA4NTUzOVoXDTA5MDEyNzA4NTUzOVowdzELMAkGA1UEBhMCU0Ux -EDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15 -U1FMIEFCMTEwLwYJKoZIhvcNAQkBFiJhYnN0cmFjdC5teXNxbC5kZXZlbG9wZXJA -bXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANjbaChJhE3WD1y8PZqr -cNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ6V/mmVAE1DtVqfFSrRIrWtpcvow+W56w -WhkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQAHV78HksKOhiRrCr/lMSFEw2ACpqye -99t6bvxP1HtUGIBH0kpjDuP4r25Y45daK4JddiDRM6D1Q6HRUfTKyLMaZk4OVd/S -6PqDGEL17GZA8Dno+dfP9t3ke2ndDJLYUpVDbyk98I1M3VLqa6A5D9xZp1w3a4sF -RLdp6qNY4E7O1g== +MIICfzCCAeigAwIBAgIBAzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTEwNDM5WhcNMTAwMTI4MTEwNDM5WjBlMQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxMTAvBgkq +hkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wXDAN +BgkqhkiG9w0BAQEFAANLADBIAkEA4VIwLNm+ZCiRXXr92ekUNXrSlE6RRuDbn2t5 +9EysbgdhNIZ0YqeoRK/6h4eofUJh/6tQ1Hu/dfrV1bN0+1YeNwIDAQABo4GjMIGg +MAkGA1UdEwQCMAAwHQYDVR0OBBYEFFgwtZssBZQGuj088LLNHWdl43+FMHQGA1Ud +IwRtMGuAFPLi6lVlpJrirJ2X9UVs9veMEa3foUikRjBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUKCCQCV6Xj1NFDk1TANBgkqhkiG9w0BAQUFAAOBgQAFGeMTFPzFKL9p+ACz +Jcu9yp8vTLOoBBHwdCe9giy0SZunWfD3h9Hgupmi/ksdEG/korPNf4toMUbuzZ7i +R+FM+nTR4ovMoEuoJNGkw2sqxijNQeAGSObP8jzKN5XXKWRrkZGD56zIC4e82qaq +8URDyHR7FSaRLgPEcVBs+GjcjA== -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-key.pem b/mysql-test/std_data/client-key.pem index 22f8e23ab2a..9ef464d0875 100644 --- a/mysql-test/std_data/client-key.pem +++ b/mysql-test/std_data/client-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBANjbaChJhE3WD1y8PZqrcNU+9bUXuu/h+IdUMCIfgQe/+SR/ilQQ -6V/mmVAE1DtVqfFSrRIrWtpcvow+W56wWhkCAwEAAQJAK27WT6tZylUjQomZNQ89 -TBiOEbUtBbqWklQ0R8FTkH9uKV+8KYQ+k+tMkoAEGFfChB0YfofNQ2KZYWWw4yOB -WQIhAPXXDQt73aou10s+cmKM3C3WzLmIZtrvm9wNBXWDGxgTAiEA4dG4cXrZfa1M -TTbjzNU1/Jf50/M8SvZDWMPQWxJ8oqMCIH6zBpYUkHlVCsBMvsbrsc4uFfTIx7mu -I7WVQGr/1sbhAiBf4uFirjtztgZUMx5/d3k5DH80lG/hlLf8FQl/4lWx6QIhAPHw -CXfPUbUFl4r/i9Br5+exGol50qX4F3aP5Sh5EnZT +MIIBOQIBAAJBAOFSMCzZvmQokV16/dnpFDV60pROkUbg259refRMrG4HYTSGdGKn +qESv+oeHqH1CYf+rUNR7v3X61dWzdPtWHjcCAwEAAQJAXYooM8ZlcuEgj+VKU1ee +qyEFIMqJJxqcMk+E/nWCM96WxCP3zHNSrqNfSpI3ld7QzMwhdRz+gFLxT2gGNpIw +MQIhAPxzM/lDihe67X3ADYtDl9ZjA8Pm430x9sXlcxI17tCZAiEA5H1SyFl4mUee +9VnfSC2XGW7lwz72ZygfVX+b7tLWF08CIEh40gzW5MfXM+KLxdea+fXjyursV5ZT +R6KcMiKiNQLRAiAcmHqlzFzFgisotai2Fc6VRkXHG7gmzOSvBJt1VjmpDQIge6jf +2N7whTdvC4ferB+zUlgWQdyvx1c3T4gnt6PYdaY= -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-cert-des.pem b/mysql-test/std_data/server-cert-des.pem deleted file mode 100644 index 3b93d865d5b..00000000000 --- a/mysql-test/std_data/server-cert-des.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICljCCAX4CAQEwDQYJKoZIhvcNAQEEBQAwUTELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMRAwDgYDVQQLEwdTdXBwb3J0 -MQswCQYDVQQDEwJDQTAeFw0wNjA4MjgxMTA4NTlaFw0wOTA1MjQxMTA4NTlaMFUx -CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBB -QjEQMA4GA1UECxMHU3VwcG9ydDEPMA0GA1UEAxMGc2VydmVyMIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQDEiOVZcWYzZe7I8xhhUwCzvmkZifAXeMTH+8XKGLHX -NWF3FLduAmeAad9oOZgBKb+oWTdRDWXqwu6nYYUBfrUpaY27/wLkgWRgewL3LZnw -W2FjhNsjx3gI2NK+Pix47q9d+a+5T4AW5+lK499l0K0k2cvyFdIerhDW8R0t8Uru -twIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQC2LQcqLg52RbelWrKutlJ5E6rzugnJ -ZAlbN9sM98O2xFiIGDA3tb5j9LAEjE0E+RqdptEYnvy9b3szhLYXtIILZTkClf9r -Uwu1nUYPTyp+9ZYCa4fovOU5h1Ogv+9UZPds/LPDwWEn8K+lvscB4X57wJyuoEck -1Mu41OA6h77181MydSdgZo0oquJDWhdCsYHXVFVs0F6naMm2uPMCTDiQVlhHJuTO -VQMNIwxRFtvsv2tpsXsaP/8sT32d5CFebfxxSVnqQvJ4ZdIrphl6L43XU01rsEcE -K8KYujZQ6SKws+HVcGqsr7TPgJfJE6D+5RazvvIQISPvx4eduebqzqdC ------END CERTIFICATE----- diff --git a/mysql-test/std_data/server-cert.pem b/mysql-test/std_data/server-cert.pem index f420b4f3124..cab54db8b23 100644 --- a/mysql-test/std_data/server-cert.pem +++ b/mysql-test/std_data/server-cert.pem @@ -1,42 +1,55 @@ Certificate: Data: - Version: 1 (0x0) + Version: 3 (0x2) Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption + Signature Algorithm: sha1WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: May 3 08:54:13 2006 GMT - Not After : Jan 27 08:54:13 2009 GMT - Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 28 10:55:13 2009 GMT + Not After : Jan 28 10:55:13 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): - 00:d9:fd:da:b3:fb:7c:e0:b0:03:be:97:c6:a4:36: - ac:71:af:bb:2d:e5:84:ed:f3:8f:2b:eb:11:e5:aa: - 66:ed:bf:62:6b:e3:ce:fa:80:ed:90:ff:b9:4a:39: - 20:40:b6:f2:99:bf:2f:33:b5:f2:ec:3a:90:60:1d: - 9e:94:7e:a4:1b + 00:b6:8f:e5:b7:b4:86:83:13:8a:f9:bf:63:cb:64: + 2d:b9:51:d1:de:ab:7b:45:1f:aa:b5:66:73:13:f9: + a6:07:d5:ba:7c:fa:92:bd:37:e2:ad:87:db:3e:b6: + 6a:12:64:f8:ee:17:e3:15:06:2f:a8:82:68:bf:57: + 8d:c3:04:98:27 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - de:5e:35:cd:7b:11:e6:7c:c5:7c:d6:27:4e:72:12:49:42:eb: - 6f:2c:96:f3:f4:00:78:a7:4f:9f:2d:7b:d7:30:39:af:49:4d: - df:b1:55:0d:30:be:23:6f:06:67:fd:dd:ba:98:66:36:c6:32: - b7:ed:63:fc:aa:49:cd:4f:72:98:3b:13:0e:f6:28:d7:d4:eb: - 04:6b:dc:e8:c7:04:80:92:e4:04:86:0b:ed:32:25:76:1d:a9: - 5c:a9:2c:18:2c:bd:bc:15:ed:e1:76:96:4d:bb:0d:41:44:06: - 2c:ad:45:bb:db:61:ad:17:11:cb:49:70:67:eb:c6:27:d3:91: - c8:f2 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + D9:9A:B8:5F:22:EA:04:10:C8:25:7D:82:57:E6:2E:FD:19:29:E7:DA + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + 54:07:2d:21:0b:a5:af:3b:58:23:32:5e:56:7f:ab:58:63:48: + 91:aa:38:90:89:16:f9:cc:bf:a4:0e:78:2b:9f:c5:1b:58:a6: + e6:08:8f:2e:ae:97:03:21:9b:f1:cd:c0:26:8f:1d:d7:28:27: + a0:8e:81:09:1b:1c:0f:c9:a5:41:3a:2d:44:3f:9c:fa:87:ff: + c8:4c:2b:44:f7:1b:c1:3e:4f:01:7f:e9:26:cc:9f:1c:06:b5: + 0b:27:d1:10:90:be:93:0c:9c:e7:b0:d1:ea:27:99:4e:06:14: + 0c:7a:e9:c1:52:c5:33:68:bc:61:0d:db:81:3b:57:48:57:bf: + 42:9a -----BEGIN CERTIFICATE----- -MIIB+zCCAWQCAQEwDQYJKoZIhvcNAQEEBQAwRDELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFC -MB4XDTA2MDUwMzA4NTQxM1oXDTA5MDEyNzA4NTQxM1owgYsxCzAJBgNVBAYTAlNF -MRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhN -eVNRTCBBQjESMBAGA1UEAxMJbG9jYWxob3N0MTEwLwYJKoZIhvcNAQkBFiJhYnN0 -cmFjdC5teXNxbC5kZXZlbG9wZXJAbXlzcWwuY29tMFwwDQYJKoZIhvcNAQEBBQAD -SwAwSAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA7ZD/ -uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAATANBgkqhkiG9w0BAQQFAAOBgQDe -XjXNexHmfMV81idOchJJQutvLJbz9AB4p0+fLXvXMDmvSU3fsVUNML4jbwZn/d26 -mGY2xjK37WP8qknNT3KYOxMO9ijX1OsEa9zoxwSAkuQEhgvtMiV2HalcqSwYLL28 -Fe3hdpZNuw1BRAYsrUW722GtFxHLSXBn68Yn05HI8g== +MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTA1NTEzWhcNMTAwMTI4MTA1NTEzWjB5MQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNV +BAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2 +ZWxvcGVyQG15c3FsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2j+W3tIaD +E4r5v2PLZC25UdHeq3tFH6q1ZnMT+aYH1bp8+pK9N+Kth9s+tmoSZPjuF+MVBi+o +gmi/V43DBJgnAgMBAAGjgaMwgaAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU2Zq4XyLq +BBDIJX2CV+Yu/Rkp59owdAYDVR0jBG0wa4AU8uLqVWWkmuKsnZf1RWz294wRrd+h +SKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdV +cHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTVMA0GCSqGSIb3DQEB +BQUAA4GBAFQHLSELpa87WCMyXlZ/q1hjSJGqOJCJFvnMv6QOeCufxRtYpuYIjy6u +lwMhm/HNwCaPHdcoJ6COgQkbHA/JpUE6LUQ/nPqH/8hMK0T3G8E+TwF/6SbMnxwG +tQsn0RCQvpMMnOew0eonmU4GFAx66cFSxTNovGEN24E7V0hXv0Ka -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-key-des.pem b/mysql-test/std_data/server-key-des.pem deleted file mode 100644 index b35d4ab223b..00000000000 --- a/mysql-test/std_data/server-key-des.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,D2BE7598C7E3BDA5 - -1W3qPgw5ut80OhaAGVZZe/tfFiBAlwpX1SohdApWj+QYP+dK/mdEBhgI3BXTFNLW -pJqDTzGlKtft7hHN6QDFEdZMKxej5+2iLu14V62o+5yQgUoqswoXcmmqJCJ7AvyJ -yMBmGAzxRFlQsT8lf6o5TS1/efBvjvWhh3NG2Zq2LpyhWRRqA3kNhzktzt2WjDZe -ZkKmZJJnArr/Aw7jEBC4sH+nmgxoR18GzDddRG12hv1AWyHc3+VisTBpyNzeBy17 -rxuQtqLzkAJmId723ddw83RVNSvBUUS3G0rx5O3HPobvZK89UqVxcXtIgc11WTVU -N3DbcJq5it43Loo0W3gAngtESDm2E3rTadrmdUSDGv2wQ5dNFl6cQ1f397Sdd/WC -A0grn1tKjJ6COp80Ymdyvn+stjv/+Rl1/KHSeG0lNeZxqjPPOJ7NHaKv7qjYsJ6W -LT35/Xc3oCo5qk9FOlq/0tGjHxf6RcFr5U7k5ILKZs+RmvJ4Sv/VYShLfLTcfGbJ -wBNfRKvcHZBQJQBb1+s/kRrjFFtvhrUwLz4+c9kskp+t4qRVYywUAnGGGsMs/GPm -wYsLQZO6Bs5/taaVUyaJQW015J7FGGv+/7/A1dIhu73S/Xl/YcFbX/CMEVq2Lxxd -hZdFIuaZ7LE+0MDQWsvYMYPDPLDH11diczb/jeKBdLPOzk/FUqVx3Fin1PpcaBxY -b+7oZJhYdg/rAWDeQ/nji9qnEG8waK6x1hdkYPOrqqWQPfgM/LPsSrgWeuTSdx2B -Ixi01UlBb5UP4K7UrjyddPobmcVjXaQLNe7zaq0+OS3UnIG85GtHrQ== ------END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-key.pem b/mysql-test/std_data/server-key.pem index a4842624c0c..0d8274b77f6 100644 --- a/mysql-test/std_data/server-key.pem +++ b/mysql-test/std_data/server-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBANn92rP7fOCwA76XxqQ2rHGvuy3lhO3zjyvrEeWqZu2/YmvjzvqA -7ZD/uUo5IEC28pm/LzO18uw6kGAdnpR+pBsCAwEAAQJBAMieYdpmRoUaODf9wqh6 -ULXH/sG8i1vaXRcUHcJ50oRVfVK8/tGGvUuTDu6MeINTdahNDlYfjwOjKWVXys1w -h6ECIQDs6s7DfczK2bKCLt0zqg24mZL3rOpGmDU+TatwN1yVgwIhAOuMzdVTX39p -328+5WxJvBOFfxmSmqdDhIFpnRMvgguJAiByvKjT/km+970+1OllyvaIL0AA2OpA -tBgdC0p6tyUMdwIgKuHAWzTJbu28UolVxQgLaFZmVCZ/ZzIAfnrWsLZ2a1kCIBq/ -ywJ2cpyFlgazu8AH6KCQa0ok9s70ElaB6FEC85Al +MIIBOQIBAAJBALaP5be0hoMTivm/Y8tkLblR0d6re0UfqrVmcxP5pgfVunz6kr03 +4q2H2z62ahJk+O4X4xUGL6iCaL9XjcMEmCcCAwEAAQJASA5VwgNb0CKHiPm0ntOk +hG+54SRX3DmafEy6gRjZIl/bZ/asSLhXUZ+CeohyrQh7BZgYWvykd8pRISL9eKsU +GQIhAOXkUrOtP/EtjyqNluEqZdG+RZi/7p61JS3Ce13Myu+LAiEAy0uMlV34AJpM +b40FPKqlHxw8DD/Dt1iKhNVAg8+LDVUCIFjv7fbJDbW2VG63/Cj8CAwOukoP5rbL +iaicVrHBKrllAiB9+MiaXeopZXNrxDS0jQFYr8Q9yt1aJVFgUkxx4Q9HKQIgZPs0 +KlF3NNNWw78INaAEkyf0IEssnLMsuoCWw0DIOak= -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server8k-cert.pem b/mysql-test/std_data/server8k-cert.pem index a0750f9e69e..3b86effd699 100644 --- a/mysql-test/std_data/server8k-cert.pem +++ b/mysql-test/std_data/server8k-cert.pem @@ -1,51 +1,138 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB + Validity + Not Before: Jan 28 11:12:27 2009 GMT + Not After : Jan 28 11:12:27 2010 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (8192 bit) + Modulus (8192 bit): + 00:c0:8f:22:03:24:59:67:46:14:d6:8f:60:09:58: + 06:07:45:f1:78:71:55:f1:ea:b9:30:8a:cd:c3:3c: + b9:bf:65:6e:18:ed:a0:b8:c9:19:56:6f:c4:90:19: + c8:65:09:db:ff:bf:82:a1:08:ad:01:4f:5a:a3:d4: + 3d:78:7e:4b:4a:01:a4:7d:e8:7b:05:3e:7d:d8:b9: + 55:58:60:d6:1c:ce:e8:32:62:2c:19:60:f3:ed:05: + 99:6d:c9:77:07:2e:11:6d:0b:9a:c7:68:38:46:e8: + fa:31:80:df:e8:79:f0:f1:fd:a9:94:c3:fa:0d:f5: + 78:ac:49:7e:d5:17:fd:e1:ee:44:f3:c7:0e:30:32: + 5d:a9:19:25:e4:bb:21:1d:fe:3c:84:48:40:f5:58: + f4:bf:13:8c:85:68:bb:ec:f5:dd:c6:38:d1:b0:77: + 1f:a6:8e:4f:8d:e2:6f:49:74:f5:3f:90:65:8e:99: + 1e:59:9c:1c:b5:26:24:c4:b1:de:1e:fb:96:65:c4: + 31:14:1a:53:b8:5e:62:8a:c7:04:f7:b4:36:a4:af: + 07:c8:27:06:ed:dd:e6:f4:8c:62:f1:65:40:d0:9f: + 9f:a9:14:c8:8e:8b:74:d6:67:5a:d0:c9:4d:35:a1: + d5:7b:39:3a:42:9f:e4:d0:f4:c6:0f:2e:42:30:4b: + 56:b2:3d:6d:8e:2d:58:c5:69:99:35:49:95:95:99: + b6:87:29:2b:32:d1:50:08:cd:25:14:48:6d:10:99: + 85:61:3c:41:26:21:55:cc:1f:cf:ad:b0:2f:b9:89: + d8:4e:a0:18:ff:75:1d:b6:97:7c:c5:fa:8b:dc:93: + 17:86:0a:64:d4:09:35:d5:83:34:6d:5c:6d:c6:8c: + cd:b9:ec:c2:93:c6:c1:b7:cc:04:6f:22:e0:07:bf: + e0:d9:9b:2f:d5:a0:50:cc:f9:f0:95:83:8f:f4:30: + 83:72:94:d7:b5:4b:da:cc:9f:54:3b:8d:78:77:0b: + 24:6c:0f:c2:96:61:96:2f:b8:5f:b5:7a:ab:7a:5b: + 97:7a:a9:ad:40:8b:f2:d6:c6:8d:81:d9:94:61:8f: + 9d:03:c5:b9:10:03:68:83:bf:04:81:cc:ac:bd:34: + 89:e8:d4:8d:43:20:e2:b6:a4:11:3d:15:2a:82:0c: + d6:3a:6a:8c:62:d4:93:bc:c3:80:bf:1b:b4:2b:0a: + 7a:34:f0:cd:1e:82:3f:25:0f:d1:04:a8:0a:05:19: + b0:d6:16:83:39:af:0b:45:7d:cb:14:7e:4d:aa:aa: + c2:39:a8:46:38:ab:bd:ab:2a:bd:34:43:7f:da:25: + de:2b:fb:69:3b:fe:3b:87:fd:98:94:76:4a:bf:04: + a3:31:e3:3a:ff:6f:04:fa:fa:24:e4:2a:89:e9:0e: + bf:44:4c:72:85:82:3c:89:4a:03:63:01:41:92:53: + d0:82:60:6e:d8:ff:8c:a2:b4:1a:3b:20:6d:ae:74: + 92:30:4e:48:e3:51:a6:cb:73:97:06:13:03:32:23: + 9b:7d:a2:c7:3a:a9:af:97:8c:51:ed:fe:fa:b4:b4: + 1a:a3:87:fc:cf:8c:8e:e6:80:15:03:fd:fe:7d:bd: + b1:76:f1:5f:b3:09:2b:4c:4d:a7:7c:b5:72:b1:d6: + db:38:c0:67:a4:54:bc:87:09:a5:39:ba:1a:7e:3f: + 74:60:ad:3d:4b:be:94:53:f3:64:16:c7:33:35:ec: + 41:00:95:b6:de:99:62:a2:7a:28:9a:45:4d:fa:cd: + a6:77:f6:de:58:72:50:c8:7d:69:38:db:07:04:84: + d8:4d:39:f7:50:13:43:ae:2d:af:45:a4:2a:39:56: + 3c:b8:b7:d8:26:a4:36:c9:23:aa:aa:b8:49:0b:21: + ba:9e:7a:2b:7f:4d:29:9f:0e:00:1e:b4:5e:a6:fa: + 49:fe:8d:e5:74:57:d8:ba:d9:92:2c:d2:ac:84:1d: + f2:a6:a4:44:1c:bf:88:41:32:7e:d1:c3:2f:6e:bc: + 0f:5d:19:a6:8f:74:2b:67:ba:dd:a9:db:68:b5:ce: + 9d:25:48:df:54:08:d0:1d:4f:2e:5b:24:bc:05:0f: + fb:58:46:fa:02:ca:53:93:29:cf:10:27:c2:a0:18: + d0:f5:d4:b9:3c:5e:df:8e:6c:f5:7c:b9:b4:54:cc: + 39:16:5d:3c:da:96:b3:c3:6c:d4:70:5d:d3:30:a7: + a6:bd:6f:dd:41:bc:a8:de:42:60:59:9a:85:25:0d: + 2a:45:c3:05:b4:6e:7a:4a:4d:ca:8c:0a:e5:6c:34: + bc:20:9b:6d:4a:ca:ca:b6:a6:3a:a0:db:c3:0e:20: + 1a:12:1b:77:dd:cb:1d:7f:c3:0d:0d:e7:c1:fd:96: + d2:c7:68:80:99:a0:d9:8a:33:21:a3:8b:a2:5a:a7: + 7e:27:06:02:7f:ed:60:11:37:34:54:17:7f:4d:90: + 14:1e:69:37:0d:ba:f0:2b:f0:a3:2d:62:79:c8:76: + a8:ea:c8:e7:3b:1f:c6:4f:c2:0c:d7:ac:f0:77:53: + 5d:f0:50:b4:df:9b:03:ca:4d:41:e1:18:b2:25:30: + 86:1d:63:e5:67:b1:53:cd:6b:4e:83:1a:b9:5e:2d: + 05:15:6b:d4:8e:b1:97:fc:31:03:57:cb:bf:27:7f: + cd:5f:27:7e:66:e7:3c:17:09:b6:11:2a:4f:33:cd: + eb:1a:d3:6f:d5:15:8b:8b:ce:68:6b:7e:9a:95:e5: + 74:7f:17:57:d9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 58:12:24:59:A7:3C:29:15:89:5A:C2:12:DB:E7:A5:42:10:21:B7:BA + X509v3 Authority Key Identifier: + keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF + DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB + serial:95:E9:78:F5:34:50:E4:D5 + + Signature Algorithm: sha1WithRSAEncryption + cd:cb:5c:83:35:ea:cb:cb:c3:a8:c3:95:e2:e6:6f:4d:d8:e4: + ee:41:dd:3f:35:82:ac:2f:fd:63:89:4f:3a:19:d7:81:75:b3: + a3:fc:36:b2:12:d5:c6:56:bc:13:60:37:33:6e:a0:d8:ae:7c: + 88:f9:4b:ee:7b:1f:c8:f0:56:19:07:4d:bb:45:52:1c:78:81: + 07:7c:13:86:b8:86:70:85:e4:71:25:58:78:d1:be:de:22:82: + 6d:1a:4b:06:ac:f0:e8:50:87:c7:69:64:c2:61:43:cd:96:06: + a6:7e:09:a9:02:01:2a:a2:40:f3:cd:10:80:48:d0:34:55:40: + b9:ce -----BEGIN CERTIFICATE----- -MIIJHDCCBQQCAQEwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCU0UxEDAOBgNV -BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMQ0wCwYDVQQLEwRUZXN0MQsw -CQYDVQQDEwJDQTAeFw0wNzA3MTMwNzU2MjVaFw0xMDA0MDgwNzU2MjVaMFoxCzAJ -BgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRkwFwYDVQQKFBBNeVNRTCAgIAog -ICAgIEFCMQ0wCwYDVQQLEwRUZXN0MQ8wDQYDVQQDEwZzZXJ2ZXIwggQiMA0GCSqG -SIb3DQEBAQUAA4IEDwAwggQKAoIEAQDUFlh/3mwov5YaICFXOdJXgHV/uDkTjXB6 -9oxlipshQaYPX8LDT5vhI3gPciS1Z1sRE2dTcC4Mk2K4LDUIjp3WkeTfFAHZPV3E -Y+3OH/ftH4N6SEIBTKE4EY6ah0nJtU98M0JhxOh5zHje6zQp1SkBnhEOQYexYRqj -OtGloZ9RyF0iFAXcyu2Ap14u37l5Yla0cyPzvZqP4mFYlcXwaRfAacJmqMM1vuQv -Fx1JITUTBugMF3VGZ1F0tw63EIUH/FW/WWncPqvG18na40qlv9ZkBw0FhZeKS8cK -JIY5y4J30jn/eV8p1lTO7K+ASTuGZWmdRDgjUG0Y9OGuKsPPoaE6ml0HTnMBsBSQ -fXUq9XkwGt8DTgPioAKHBHjLbILEy4FMYWrlTZlPTzNqyhayec/2T15oDladNSt7 -JpDLpX70UECXFhdEGxsGxtXdKbIBvNm2yT4X2nxW9ItsECjSSgD+94TgGoa8QKDw -rpmgq+Wqpm54CZ1vN1oqyMUw1sjNEX/iLByHAjSALby2Kffk5cl5mnsR6d/k4jsi -c3Qsciwkd+rQt/8VMhS2ns3nkez/BK3FvQA2Ms8xJhFLfszVrBhnjcFRTNT2+/KM -lr1oT5Q1XZKL7qVXTpabPL51JlVBL5CSHl1QRkffsqfqcgJkcHBq+kKjUiFs4lad -hTrvNBCXYa5+NkA2QqIfdOpNwl62/gdE7/7zU1uh40vkVKyzL+APkLPywPEXBOpQ -yIDNkgoXmS10+JMD44K7uZyUmxZL7W7Xbi30NuEFrVOzoUmVXhapPbpQnkQHxn8n -tqKPYXdBcvXcCKyJ6i79H2Vk9fM6rBYiwNcE7QyWqfd2QMjzr76veF04sXkPR+tG -5Y1lrF9Zp3vabFXQg2RJuGA3rV6MR2GFNXuChIYu410vhIhPNtmdKEVoIVZsFsug -+dtn0PDCFrR8VEd/sshp0naNa9Ad1lY+marJkOJOVpPgCs2yJDPAUB/YdvSJ4avW -6ZdvNTwhBL8fEJMS2DSqkaa6A3+i/SqITpU8ToJxsMGagBsLieXgvJALFysSRfR/ -2dmEu9/J0PPc28inHXwjiLb99VKlkuEz8wX9UkuoqFl0pLa8jrlM8hzdPQ9QHb3k -9c5knfgPCYkOIWwGXH+NwANHdQRK7CmGAFV24k9+P3q0g5ikabVHr+4ZQ3WPd+1H -K0+Msbb/vv53vFJWa+pYeNeFcwNCyW2kJBTMiI6qmlL4IWCcX+QDzpRLalbAWWHj -l5Zk39QEaCL024DYK948IDXCqDg6utEs7YnMdaIF0meYMKjehZFp0fVQ8e8Od+rp -bbjdj/w60wMgBpSOeYxVrs3QKNZd/if4Az3LggoVHB09SjXKiWpvAgMBAAEwDQYJ -KoZIhvcNAQEEBQADggQBABncOBW0wQwJdEB6W3d9CrhFp40q1OM54GPfX0/0aUfP -aOQPxS1uCKcFhxAmR4OT9RiJx+0bhDctekkuMkj5yy3u0a/4PxHIhnVxXTyB0/Hj -N1gLz6cQricunl6Q4Ldi54gR5/KUehKLBWnqsfxhgzWBHosvhlJC0xh/uio7JTqz -ns60djyL7R4wGbSqiGdhT9L2HfpJo3dmmWLDxe02jaHkbL1Z6NQMxrRgs3+gctp/ -Wd5UxNl4BHbNsSbzaK9V9gXUcj4TjZGGSqVki0+pEZ3dmksGZdoW9cSKtzKvgUQ6 -vhhqO4dcopxkY2zYeVOpspgTm0XLZSbNPXv5rSFwa4cpWSfD7u8o8KhHvkkSMahw -cMuH17W4voHHFDtWP8Oq9rA7uE/4/LKCl0JmJl2RWM+G6PMH8w4X4auHPssgRvb/ -Ge1AvgqQJrvi7zWx3XYKKJ0ISBy7fi5Jo/wYgLagRYcG3mwdm1+gAdw+77C/ZGmG -FbWFIPB1+Mc6azhhk9m/vqP7o/Wuncc99mp2zPMzdAEzuzp/IJ9UJNat0edA7jiC -bQ7JSRJ1DSzdJZSWWHdardLNKipPfrEHVm7f5QvL5DQLnGpt+rCWL361KsGtvETC -o+Ph7+kDJsJLokUYfs/BEZopzspNPy/NQ2ECwQp7T4Yq/PBE6Ce/dFaoZysMUOrG -TcALtJW6It98dRmTJPiqjlrlHNTrfoV3Aiy+tK4rpyGuApSHc+1Y+t7YvWotRlQ4 -GEboBqR8evjDPJ1xAaUZqwLkebf3mlpl4MzHM9uNWBkQdJilkQs/IrAaApG3Ayt0 -nIymNHmDslBEdrRGmT4aNWAWYvVYzyKDy3H0fzYdWwuA9goJUL4tj3eMJa8pgEU/ -rG3HfflVi+xuwm1UnLXPSIE8hixgV8ebnwcCnEjlUBvwpl7f5Ub40jKcdycdGvVu -gcTUzuRl1+Ikfk/MXKPbdi4A5Pjtz6AG4Ez9q5j7X77JqskTI5Z/f1RPiKwFBJHg -cN4+BPnEuSWGcjiNDOfQxhk5exlWRf/gpEhnQpGHe3a7tZgfxHUb/pWU9BYpf8OH -vtV3WSDXlUqsEEH6/bmvj8lmFWJLmeZv+qLy1wHxcXR9/GJ6TwCF8niQIl3MrBAL -sKPLft1drmpqdIQpZQIJxtN/AQuD9mxEdW7XA6rkvFySKcswJpS1QjkSWpafCBWE -wu+SPxZL8oFrnNMTU3JloUjcRp70FkNXLLm/Dy+MjW2qFBtIoBgNptVGp94L1uZS -amd2XJMcOQ+X9fcH3wAdM3IHGn3NiLf6eTW92JNNA0IN6aNtyVaJKmFJ1JfXOl9r -ujr4SorRSesaerjIcuzW1u1YE5RlgeI4kizV2/D5kYc= +MIIGJTCCBY6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ +MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT +UUwgQUIwHhcNMDkwMTI4MTExMjI3WhcNMTAwMTI4MTExMjI3WjBDMQswCQYDVQQG +EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNV +BAMTBnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMCPIgMk +WWdGFNaPYAlYBgdF8XhxVfHquTCKzcM8ub9lbhjtoLjJGVZvxJAZyGUJ2/+/gqEI +rQFPWqPUPXh+S0oBpH3oewU+fdi5VVhg1hzO6DJiLBlg8+0FmW3JdwcuEW0Lmsdo +OEbo+jGA3+h58PH9qZTD+g31eKxJftUX/eHuRPPHDjAyXakZJeS7IR3+PIRIQPVY +9L8TjIVou+z13cY40bB3H6aOT43ib0l09T+QZY6ZHlmcHLUmJMSx3h77lmXEMRQa +U7heYorHBPe0NqSvB8gnBu3d5vSMYvFlQNCfn6kUyI6LdNZnWtDJTTWh1Xs5OkKf +5ND0xg8uQjBLVrI9bY4tWMVpmTVJlZWZtocpKzLRUAjNJRRIbRCZhWE8QSYhVcwf +z62wL7mJ2E6gGP91HbaXfMX6i9yTF4YKZNQJNdWDNG1cbcaMzbnswpPGwbfMBG8i +4Ae/4NmbL9WgUMz58JWDj/Qwg3KU17VL2syfVDuNeHcLJGwPwpZhli+4X7V6q3pb +l3qprUCL8tbGjYHZlGGPnQPFuRADaIO/BIHMrL00iejUjUMg4rakET0VKoIM1jpq +jGLUk7zDgL8btCsKejTwzR6CPyUP0QSoCgUZsNYWgzmvC0V9yxR+TaqqwjmoRjir +vasqvTRDf9ol3iv7aTv+O4f9mJR2Sr8EozHjOv9vBPr6JOQqiekOv0RMcoWCPIlK +A2MBQZJT0IJgbtj/jKK0Gjsgba50kjBOSONRpstzlwYTAzIjm32ixzqpr5eMUe3+ ++rS0GqOH/M+MjuaAFQP9/n29sXbxX7MJK0xNp3y1crHW2zjAZ6RUvIcJpTm6Gn4/ +dGCtPUu+lFPzZBbHMzXsQQCVtt6ZYqJ6KJpFTfrNpnf23lhyUMh9aTjbBwSE2E05 +91ATQ64tr0WkKjlWPLi32CakNskjqqq4SQshup56K39NKZ8OAB60Xqb6Sf6N5XRX +2LrZkizSrIQd8qakRBy/iEEyftHDL268D10Zpo90K2e63anbaLXOnSVI31QI0B1P +LlskvAUP+1hG+gLKU5MpzxAnwqAY0PXUuTxe345s9Xy5tFTMORZdPNqWs8Ns1HBd +0zCnpr1v3UG8qN5CYFmahSUNKkXDBbRuekpNyowK5Ww0vCCbbUrKyramOqDbww4g +GhIbd93LHX/DDQ3nwf2W0sdogJmg2YozIaOLolqnficGAn/tYBE3NFQXf02QFB5p +Nw268Cvwoy1iech2qOrI5zsfxk/CDNes8HdTXfBQtN+bA8pNQeEYsiUwhh1j5Wex +U81rToMauV4tBRVr1I6xl/wxA1fLvyd/zV8nfmbnPBcJthEqTzPN6xrTb9UVi4vO +aGt+mpXldH8XV9kCAwEAAaOBozCBoDAJBgNVHRMEAjAAMB0GA1UdDgQWBBRYEiRZ +pzwpFYlawhLb56VCECG3ujB0BgNVHSMEbTBrgBTy4upVZaSa4qydl/VFbPb3jBGt +36FIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcT +B1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAlel49TRQ5NUwDQYJKoZIhvcN +AQEFBQADgYEAzctcgzXqy8vDqMOV4uZvTdjk7kHdPzWCrC/9Y4lPOhnXgXWzo/w2 +shLVxla8E2A3M26g2K58iPlL7nsfyPBWGQdNu0VSHHiBB3wThriGcIXkcSVYeNG+ +3iKCbRpLBqzw6FCHx2lkwmFDzZYGpn4JqQIBKqJA880QgEjQNFVAuc4= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server8k-key.pem b/mysql-test/std_data/server8k-key.pem index 608593a5096..493ad2350c8 100644 --- a/mysql-test/std_data/server8k-key.pem +++ b/mysql-test/std_data/server8k-key.pem @@ -1,99 +1,99 @@ -----BEGIN RSA PRIVATE KEY----- -MIISKQIBAAKCBAEA1BZYf95sKL+WGiAhVznSV4B1f7g5E41wevaMZYqbIUGmD1/C -w0+b4SN4D3IktWdbERNnU3AuDJNiuCw1CI6d1pHk3xQB2T1dxGPtzh/37R+DekhC -AUyhOBGOmodJybVPfDNCYcToecx43us0KdUpAZ4RDkGHsWEaozrRpaGfUchdIhQF -3MrtgKdeLt+5eWJWtHMj872aj+JhWJXF8GkXwGnCZqjDNb7kLxcdSSE1EwboDBd1 -RmdRdLcOtxCFB/xVv1lp3D6rxtfJ2uNKpb/WZAcNBYWXikvHCiSGOcuCd9I5/3lf -KdZUzuyvgEk7hmVpnUQ4I1BtGPThrirDz6GhOppdB05zAbAUkH11KvV5MBrfA04D -4qAChwR4y2yCxMuBTGFq5U2ZT08zasoWsnnP9k9eaA5WnTUreyaQy6V+9FBAlxYX -RBsbBsbV3SmyAbzZtsk+F9p8VvSLbBAo0koA/veE4BqGvECg8K6ZoKvlqqZueAmd -bzdaKsjFMNbIzRF/4iwchwI0gC28tin35OXJeZp7Eenf5OI7InN0LHIsJHfq0Lf/ -FTIUtp7N55Hs/wStxb0ANjLPMSYRS37M1awYZ43BUUzU9vvyjJa9aE+UNV2Si+6l -V06Wmzy+dSZVQS+Qkh5dUEZH37Kn6nICZHBwavpCo1IhbOJWnYU67zQQl2GufjZA -NkKiH3TqTcJetv4HRO/+81NboeNL5FSssy/gD5Cz8sDxFwTqUMiAzZIKF5ktdPiT -A+OCu7mclJsWS+1u124t9DbhBa1Ts6FJlV4WqT26UJ5EB8Z/J7aij2F3QXL13Ais -ieou/R9lZPXzOqwWIsDXBO0Mlqn3dkDI86++r3hdOLF5D0frRuWNZaxfWad72mxV -0INkSbhgN61ejEdhhTV7goSGLuNdL4SITzbZnShFaCFWbBbLoPnbZ9Dwwha0fFRH -f7LIadJ2jWvQHdZWPpmqyZDiTlaT4ArNsiQzwFAf2Hb0ieGr1umXbzU8IQS/HxCT -Etg0qpGmugN/ov0qiE6VPE6CcbDBmoAbC4nl4LyQCxcrEkX0f9nZhLvfydDz3NvI -px18I4i2/fVSpZLhM/MF/VJLqKhZdKS2vI65TPIc3T0PUB295PXOZJ34DwmJDiFs -Blx/jcADR3UESuwphgBVduJPfj96tIOYpGm1R6/uGUN1j3ftRytPjLG2/77+d7xS -VmvqWHjXhXMDQsltpCQUzIiOqppS+CFgnF/kA86US2pWwFlh45eWZN/UBGgi9NuA -2CvePCA1wqg4OrrRLO2JzHWiBdJnmDCo3oWRadH1UPHvDnfq6W243Y/8OtMDIAaU -jnmMVa7N0CjWXf4n+AM9y4IKFRwdPUo1yolqbwIDAQABAoIEAQDI3u0tFoWMRoCs -99d8HLiaxYED2YC9gw2QeKjal198LQhRsVnu0ByMLKLOxkX8RgrbbmxDe5Exufob -A0urciAOFJoXqoRhs5x2oEqgGmkf/ePx0jQptOFREFfnBdGeKIpC0O3DWdLxYPbt -8wixwkEXVhVDUk9pcdXf2ZqsbBpQRBvpZdtzlgNCAcLTVHP/gmMqf48CkIauVjPq -ydfybibfx4sm3hodclH+Q78p/zicb8MhiKo7ZymgCKz4N743pQe1tsLrpbPeHY0C -MpoFyF8O2Bq+KxwvELxQX+19GcHVKJhj3hmCr4wde9BxCWtGTBCusekVkVvy8iQ5 -aCmTIrtonMEVZXjJlXK0sw5hBKOmKx0jrSVC5FfgdxzNVlW4fCJXLEEpMsjMc+/3 -6bV7jqGn4N5CYaopNS2ccxdaucE3NjcmofahO6bqUTJHSPFecfYmCA42W2m+ldjj -HZ78JLkyw03nT1hjPjbwHf5FTem1KfKg4EJrDprowMT7D8KZb0SW+z59pFoDOM5u -Heu6sOSUtvpvKfozdw2ZAI58dhpW4/jTfCEtewRhPqE3/V7g3haTnQFxU8gm/a4N -uefZTCjFE16QWNuvnUrJWw/DlvOBY8GjpQCWY0mDeBHPNOI0Xg9oRTgOCrKSLUya -YSbg6BmhSKwKsYQU834jrQb3fXFlXZVIxlcNePOWMhHFFNAHucHF822Nr7u/3FOT -twcbBIOXCGfDT6ed8d4dNum1L7k9Blju16CWkfuciL8PGXY4mGAmF4nZMXGZgK8B -Cz9cxhtvFLe8gz5615DtBAsuVm7Q4AAHiULAMg6t6auyxCb8pXbAL0Ec5X4zS3+f -I2riODYiyHCh/qTtjawOzUZZEtjZRMSDi+jk8wjjDdkFU8McOaYoPyqT3TDy2v6m -NiPJs8GWQ2NCNo9CNoGbEIIFFP5iSz18XLFAOF+2dN/KHHl9nKyi7kOhYbbzoNku -2wQV40yVsrS4E/hd/7+2IB2Muduxiu7NxCUSUXsw6p0hZTYMpIoduEfRSk1al0lS -862GD8JgJ4RhJ0uIOTDJS52MQmO8zFIL86emdjjV1CzVvadYSQLTX7ZgR0i8g46A -y0muCFAC8EJpnEtHzqtQ/z22zB8TCJShFuUK9KF6K8nOlbc6ShcUXU2J6r1sc8aT -Dx0yzRXfCL15fpCJBP49EYaKhArTNmFRa2GaLiJP0OYkTrrwVOGuS6x2+kRVoP/8 -BcNMZ5x8mXP1LgotHCztgMKX30Hn5CLxbH8QfcWKemGva1jBmhCWxS17Gh3Ld9T3 -/WKkBa6JDq83rlO84x/iF3mB3tYkZPfcYtYURn5wwm/BmVV/9G1VwAatJdxmfCSy -5JwC9WDBAoICAQD7xStPk3lq+qYHAtLZidujmzSNv7XG+E8UC9yvMRFuBwSM5ZE4 -YGD2LDev2nghB+7OSR8KJIkxeaNjP91Zf3s8wjCuxLg/cLGI6mf6uWy9+zypFg3i -J+ylDKa6NBuqYyY75W7Pj63xvGQlw5kX5+mB3ulQbActT4cUiVdEkyDytzubqLzY -s15QGFrL9gqLow+C+7LKQKdeXq8OavFV1PWkMDAJUki6cIir9m+f5Mqr2cQCLKgx -38aX8c9UWJv6pI5zQQuBjpaBOwz07WnyTXiFpc71x/8i85uLGDM0e3VO5ZPGeRBj -jZ0ucHatOHJ3i/nPRG16rsPR+q97QiDHoLF0quHEG+ND+rwTBzNGIwzYRE16p1o3 -UdzFk1RzlDCfOX7QgszCwK6mf8TbCK9f/FxJ5e6TCkt3iHXSrlLS4op6k9nEpKFH -KHf4nPtCy9GriP+A8+dA6K1s+DgejoIojBMBTsnl4TEf+m8BaenTXGuU7KYyc8dR -JqmpmDggDRT/ImHRhXirY7lIIYXnI7tRjN5gmnKpEiHScT1r848zpQ4gWH1Dx/ks -mKT6NZ8nF45saQCYbKEYc0RH9Kw0O7vr1kVtNPc2dEZtVgt4bC5fnl7xX1/YTk3m -+h1qfzbku/+MX5rRjHLR2l8a71UltlnnnpP5NKBBgtxll6aCIkk6CdH8YQKCAgEA -16aBaVa0cOZmiOQwPQkpuXIbV7msz1ttWEAHElCy6waniOCON89PYFCb7F0NjV3Q -i+pGaRgG1iZGbjjHwyqTrHhMloFm+IsSWZqOZzrHgSJgA4bgTJFgp+5b31sQXGfJ -14QQSqMJLC61/M+CnrNtiuI3IVHx6BFRxI42uE7PfTyUMaFhL9F0/SLl0Mw0oMPj -S5kmarduuKpRn1tN9WO+ywEvYwopvH3e9PBssZzPpttlLiE/Wulb0iEtlVXYB9DS -Vzc94N2dzFMIvWUDF9BQ+IBMRzXRm15Psy6LfzoK+9S6w38Dx3BVV8ykSMKeW1UR -ZwTajjdnIBLdE3onD5XMmrSOPw/WtV5zXEYY4DObhIPoN2iD8GJP0IubPb6fonH5 -VHmuVZoXrroFEe7rdt2wgmBdPPl6fqvBKVhjJOpYQctrFLgWh63bXZKaBWqbQM9W -fECq8We1VN3fzqwfwJQit3z5R/DjQNk8eQx7SnnkOzAY6ZgpysHCwaoPOnPVuiYF -ZU0+X3iwfsdeefWmGEDIzoZk6nYaljs61lOhhEoWHngZHDkMOp5kg0n9f8BUP02+ -WJ4QhwzZ73hr4FPBuPHHXECw9TCAgCBHBFrnrXg5QalDhRXz4F+3tCY7UUpD/ikZ -L6Daxm5zGJ5u3rXs6WwKy2EHVVS9zfqs4Q259pQdWM8CggIAcIKpGzOVM+h033c0 -kIBZxeAq+Rlt+0+lzxiJ80RjPJ8oOmqwndf8HKaf8BcaTfCEmGz20QqIwLJSAJ1e -posgoINLTB6fE8Kho8TU2KeaX7/xWMKBS8p5pzxjGZ0Fq/wI7wVVoq3blsaQnout -U5CQujfKXeUYw/fhLp09gWiadbzKh4I9ej2V7QclNDZsegBRg0BForqH0NVRN4k0 -9h1n9IqQPOonlCGMAgTr1zFgHLIBNNOOClOtJOOruk6qzbRR8FFl+eyld3TTEnUy -PlS+gkMZnJ5WduEUZnFXGKH/R1Wy1yPs3gA/+KvLbRdnl+LWrPgwUH3fBmwXlWZ0 -zaETDEb9Ay1PP2bCO2KhWDt7lv3W/fPhjg0oMqbnO4tCuzTvZfC93l5K7h708skL -zkIxX9i/57fXB8DUnmTGoHUaWzLNQ2IqrGj6TACjDDOXLCfZvl/AvTH9pk+6jHU0 -1zfZmmECOpeK43Z/ussA8jI/5Vpn3u38aVh0w1RB6JjQBD/yJLaXuUekWgaZFzTR -ldz014jNqp5uvONcBmzeVr7w9CV3PR4VTQed2i6yQ770J6A44uTQjOOd5OYDOohj -Lz4e4nGj9BK8Eko8cAEwLAzS8tyjMT+08n5dPOVCu68DwVBMGE7CVONYUuoXS/YU -cTxddiU9ZGk9Yq0FfOwjeys+SqECggIAdn3M2b6Egwx2Bn2ra74fKQBjub4SEBWi -bT0xJYUl6jHL2E/alRvZ94gTRLqUebq0nkxpx9El4IFDbcjRKpG4dqnbG0+a7rIr -sQRVfq8zc+cZbparpCa1P1CfNojo4n080KiF8xzGK3q3EGRM1zqr1AYcWLiX/PWX -QjMKKhdTtvKUUvjjV8z1RSnpsOKjgDpiJ+XM0BJeSiV7l94pZc4axZyvFvI8oI9g -9KEueCE7j+k5HTGziBZ1F26Xh1iVzSWWjcmSvH3I+L4fLUHVgz45X3HPd8lAlOgr -Tr8icxPHeTwYKtcdknZMzmNpWXlmXbTOTRbDqCUVCvCSfOM/lzauJ8tR5aCkTx/I -r0js3jQ9HYEFFXzeEjVSubob4L9fI3kQkLQTcIGsxZr8si/fPX7uP5UHZjuGbRee -mUMxptUFDZHiEo5cAs0qna2x54v+JoxGbxtxUhez8R/Am+TDxaMfuEZ5Cmh31egH -bFPJYtC68TKqXZ/4RqpUgukYWPvQ0emWSWU6AmdkQyT06nppeyYNsDz0MkgWr7l3 -yNBHDVNP+Anxcip+Z68kd2cuXQWmxOnIzxR67FnJXeWDEM20whRHgI8jLHYsBTq3 -CtOQPSaz/zosGXJIgF7Xp6riKPZvibW3Ww49Z47EuyBCtyirNk7hV4LG7sITUJyO -ZVKPfcdAoM0CggIBANz3EBZGyt3af2UjFFKbazV01KcHF8OxqdQzsLqHCXWb98V6 -PggQnrF76U7DvqOWho9djDBPrbQU55HG5nXq+eZKPwhsOdwQ8bxOhaVxQcATZOI7 -FtJYnjM1/+zMzzS0iPR5DA2pbB3AKH2Z+wODmF23CK2XTwoJyPKxvlyGKrIqq3gN -kOmocNu2Qm5bJf+D/hYPm5Ust2wzD52NnvJU536bZ0ZMo1/kaK2idqSAzqo4TkR1 -j9U0fdW2rIBDo/qFmBBdJhYVjYLj4qR8CEEoIjshD4Nztf1xRM5C8irE/gJcT5+r -4bPJJ5TjAtHxPiQqZruSprSEUbMsPqBap64ow0SmbNNWSgyaz2ha1rG0p52NBzH4 -XM52LBqS9QHPHvB0ooYfBTfPpDM3CePuuNyzjPAw86ncUo38FKXuc2oViJJ6C5I7 -v2sKhLK5gu3uPBB2ludDEXSpWBqiraynolOT/o52r+taYp9YY2WU3GrhOiV/A1FV -Nl118xiF6FOFpEeTbhHvy27A8kZEKXgeSs+f4aC0XG9kLVD1CiCbQiqHTDcDS4nV -O1N1eQxhP81X+YKE4Lgufh07REqYVwtCj2lQcMp73WDyfBLKTEFlmHusoqmT5JCH -X0BWNjk5Dn1g5h63/lQb+EjNRILBhDFYhrDRDQtw5p0/7IY3AcNKDUHv+XGn +MIISKAIBAAKCBAEAwI8iAyRZZ0YU1o9gCVgGB0XxeHFV8eq5MIrNwzy5v2VuGO2g +uMkZVm/EkBnIZQnb/7+CoQitAU9ao9Q9eH5LSgGkfeh7BT592LlVWGDWHM7oMmIs +GWDz7QWZbcl3By4RbQuax2g4Ruj6MYDf6Hnw8f2plMP6DfV4rEl+1Rf94e5E88cO +MDJdqRkl5LshHf48hEhA9Vj0vxOMhWi77PXdxjjRsHcfpo5PjeJvSXT1P5Bljpke +WZwctSYkxLHeHvuWZcQxFBpTuF5iiscE97Q2pK8HyCcG7d3m9Ixi8WVA0J+fqRTI +jot01mda0MlNNaHVezk6Qp/k0PTGDy5CMEtWsj1tji1YxWmZNUmVlZm2hykrMtFQ +CM0lFEhtEJmFYTxBJiFVzB/PrbAvuYnYTqAY/3Udtpd8xfqL3JMXhgpk1Ak11YM0 +bVxtxozNuezCk8bBt8wEbyLgB7/g2Zsv1aBQzPnwlYOP9DCDcpTXtUvazJ9UO414 +dwskbA/ClmGWL7hftXqreluXeqmtQIvy1saNgdmUYY+dA8W5EANog78EgcysvTSJ +6NSNQyDitqQRPRUqggzWOmqMYtSTvMOAvxu0Kwp6NPDNHoI/JQ/RBKgKBRmw1haD +Oa8LRX3LFH5NqqrCOahGOKu9qyq9NEN/2iXeK/tpO/47h/2YlHZKvwSjMeM6/28E ++vok5CqJ6Q6/RExyhYI8iUoDYwFBklPQgmBu2P+MorQaOyBtrnSSME5I41Gmy3OX +BhMDMiObfaLHOqmvl4xR7f76tLQao4f8z4yO5oAVA/3+fb2xdvFfswkrTE2nfLVy +sdbbOMBnpFS8hwmlOboafj90YK09S76UU/NkFsczNexBAJW23plionoomkVN+s2m +d/beWHJQyH1pONsHBITYTTn3UBNDri2vRaQqOVY8uLfYJqQ2ySOqqrhJCyG6nnor +f00pnw4AHrRepvpJ/o3ldFfYutmSLNKshB3ypqREHL+IQTJ+0cMvbrwPXRmmj3Qr +Z7rdqdtotc6dJUjfVAjQHU8uWyS8BQ/7WEb6AspTkynPECfCoBjQ9dS5PF7fjmz1 +fLm0VMw5Fl082pazw2zUcF3TMKemvW/dQbyo3kJgWZqFJQ0qRcMFtG56Sk3KjArl +bDS8IJttSsrKtqY6oNvDDiAaEht33csdf8MNDefB/ZbSx2iAmaDZijMho4uiWqd+ +JwYCf+1gETc0VBd/TZAUHmk3DbrwK/CjLWJ5yHao6sjnOx/GT8IM16zwd1Nd8FC0 +35sDyk1B4RiyJTCGHWPlZ7FTzWtOgxq5Xi0FFWvUjrGX/DEDV8u/J3/NXyd+Zuc8 +Fwm2ESpPM83rGtNv1RWLi85oa36aleV0fxdX2QIDAQABAoIEAGv5ltvmLQ/A93xc +x0BWEINRkBa2jrfpo9B5dOnuikWtza/Cx+X2NfQHFlSrcHhfr/JX5BsCb2iVo8DM +CXAgeX1VMHS9wQXuxciaHCZDnqxmxUNDU3EjsYQOKLusRcdL6M+Zuz/ny+7PQ0Qw +/N0yS46Wa9oUjon3RKRvTeSV4HIpFpcP3n/eLjDc/ielWuujnTGcBnjNWegvQROp +5/7221YElGh8U84kbK2l9DtfjwoGoTv11lPvOxXE/scg6em7r9j+y3p3TMzMeDtT +YBC6CA4Oa7GrWLJXROOKOQ0ddtvFNlUsZ02vG2QCbqU2y8mwJrJDI80qNbeKGel3 +SfwkssedtGoOOYHxNczwpyVNHVHrHuMPBe75gbo+5pFxVJ5ymCGWfbLJf73oVsqW +ZimoknvkozW4+mlVlcmo3X73IxTW2U4RlXthYdj9KXsBLRaKVCQJDc934eHWkXHU +GF2U2NonqOVd8YG/FmZQ2ig6EcW97hC6wnsWT2Uc7UNAE2RM4bY0xCUHaQiKTrEs +CI6wpbbTV+XhDu2HmL9G+fsuSIu0RoSOCmr5jQDAVwCNPXFgBgcIxbPZ/UCJ7RHj +GrWPBldAN8ip4osiA+B3XwBabcvwXP2fgBP/eLWN1St3q3tw5xpHpqCuhNuPSqsc +0ntz0oIdJyRR6fXWmRFex4kXQ597z5ozm0uyg8arV3HJFxDC3DI6kKfs86/oqMSW +l+9g+d4x6VrUOCTDk0bjN3T8HQ9ASfy9JVacqk6yuXX7a0WeeT+x9JsvFAjg2KmG +CJUtm5w5siItMDSPpcRE4hlfgh+M7ZKS3PFgH3vvwfPMbC/IC93QoSaFzRJMyobX +ei6PNwqJvL+HADlMfLmehE2w9ycp4Fe1Gw/NW0Ed1S6Ajo45hgXQJSIrzla6eglg +JPsPpQ8b+weZNQ8zvc0KvfRJmZKKEb9dHvFdi68I1kV8aapQsjrMOjwHC2pnCFh/ +axkVc7a59fKUs7L6nAJhCs2sSixTorZz5PvJ6mXhWu72TCzu+kThNnEORrlWPHQl +RFEAFpDDaGSzOMlhb92CWUMPyZU2qtzMzv4QGbP5YqTy121hXuT5OBKCF3eNLihV +aje16k0RMFqqW3Olbm7Mp2P1C6DuwzsUJBnNwB5JzhC79Po88zNAl2d1h+qysKU1 +jxF316nhpWJ2dGJ/sbJ+XpUMd/tVrNFQMA254GFfXycsfBoQOSY5d6GfRwKUDOou +xImbIzGUAaIYdsGKDuKtqs5S21JMJjJ/J5CwjLu9tbpP/jsp22KHCpraHAQCupSp ++SFwWI7tRUXzREuxJixfUOnJFQYOATnMFvvtk1d6v4xoPYCVEhHq8gHqJkTyTi3Y +BPVwT1UCggIBAOEy5gThTrEqSVFUcFJm9bJxtWZt/YhOIJWNNxeaxExHzy5hPpsw +fZXtN4MUCeMSWI4isgIujmltwgOHMjQqsJPISn/1gVrqLmrZ2PnFzko/WA8rMUfd +EUnOOpj2bKpChlRGHi76ZV4XGgoTXyO6mrVUcUgf3reSImdcdQ5IHa7J+lWhCQGb +neZIyDOk41LX1TxjcYkY7vuUgmbBYComXPm2UaY3HN4E/3ElXntj6PrlozL33A56 +z4UPfv2Vv9kl0ydkTJe/WcUN2htqLFCYygF2XLlwbv2SYDCT31PkJUORbScUM46A +DOhlxvLBFcpF+l0RtCtvnrKyFy9yZJKrcLh9x6xVChZ/aQqSptSHjll5IEcVm54Y +Z1TjWizCI4txnaBFV0UCLt1CZrllXnyIksZLS4/dVqUIKmkxPBQUpiD5dmgDcmPB +/LdWzS6k4MH3J3Y3tu3MNPHDwgUtnifSZrsWSYPK0F8J0dMU/mLaS9eOplAH7Eo1 +t7OrrImvitM6tUdErRYilIaoS/6YPmsPST5gY1N4n8Lf4sAE/tY8fwaWRpTVSrIw +CoFwLtHESUOhqfuAOdr1EkDfo/RQTUVdnmWZ+D0j3du8MmsMje4x3f2CjBDXqArl +gNnBQELDmrdif8KELNjlEpTIz0T7wEfquhVQ2dzhFpL7RLAgggD+oEBLAoICAQDa +5WOWrAtaI1cC5C7LFxM2qXTHGRttfAtVxuigJapLqNASJuu59GGRxsCVwhthbNFh +aCMSj+fZK7QNFkaoPwuZCEtzy0ErkVZzxYp3cP6b99mzGoCcuqiHiW5qhEkbxwdC +f3YEsSGqE6j8TPW8feiziqo8q+QPSudI9ngkH1gjgbIrTu9iaxKJcF2CwBxe5tfB +uFBNPIgJAaLPejRKQu17MAV2jDnBDIsZUZnm53IxQ+giIYUBay3cfC1KMJu/AnZ/ +CxETjgqqnzqdFW0b0o49Q6YQa6QXAiSjs+lL/BhjbdA5quVdFmA3CoASFQbihYfM +4vilUg7Y4wXfzS7DyBZdfppIn+HI8PPSMv/lfdsQXecl5TU1fBDPRWYPpTZqm1II +HDCkmGRKet/j4/oobabNRrJ6PJcxNjqeMVv/a72pypDRPIXzNxLb1BkfWDGfgu2R +YAdRNBSJSpdoHDZ+1VO2A+/8gz9Zuiv1WxoX7+u3pCAd+0vCfHiaXiFVc7fI8F+m +rtDmN5p3DD9l1+/v7yd+7eUezwxYecElw5E5MyAJRTYGrim8g7XvF/u9rXvH09VP +TeIE8oJ7XzrxCmtGIxlJs6FmgUbUblOyfPZDUqPnzlo8Ru1H2iKRo2FPiMfij8mh +H3wgFTnZpGDQjw/xop51bxVueXrmOeguS0wmk/8Z6wKCAgEA0y+bPApadJRWS1nn +N69sTBqMZfFR6Eh0ECts9criuTJCXZk+T+SqcTYTb+4T04k52Jk63Aby8HXIkuxv +LTK3gu86xkLiOvMP8o43Bwz0BvbeSuNThLQQ6Wjn1NiLUSOvu0pCNgYFl7YMalR+ +TRBK0y/MSDny762wa8Pt1iXVCDxLcY/h1UstSW8JqDzCHcdgJhCPwWTLgMxleZ1w +5DYzzM2oRjq67I49Sssjjo1ESD2fzUVZbY7IG11L1t1fG3F4UiGiHlCJC92Qo1Lv +Geoezj5EeHay70Mcx5F0xsRWGcZAWXx9WO5GrI39g1uFZro3Lp5SmsVDSwrt6UXa +gR0bSThTTw40tqJnTE34+6ff25JWrbLay+jQxm+q+fxZvwQeMNW2IHYKot4JXWVt +tVWSZzjnNJP6FCvTMfDFCYPPw26OFr7cwCaEKx7QriRazitMK3XWK6zsHalZwudj +wK50PpCJAnno7KdVySCP6v4ST6Rr3POBKJq1ml2tITWo96u/ooUJ2I83QAyFr8zw +BBBCvKdBnl6pW+P/TdmhbiEvcmrs59gaA34/6+DbV0Y++piZwswd9XML2iCgLZY8 +0IcZ6uf4PsXq4Yzcrz0HwM+tAXcyiPzkjstpCUxMShALgFxzuWOgdwpjYXnrviJk +0EyUkzbOCHBhbhcK9CyYHfyrJX8CggIAdWwgJC9eV5glkPN+9osGT4hPkI4zXGPy +YK03FNGfrL59/37JbRNfU6fen3dk4LpTB4Gpbserg6AiEfMlLBPF0O3WK+OYrhpk +2e3Z/YCr1Fb8fUt2Op0W0r4ycQlNfo0ho9ZkJNgwSuAJAm72U4rnTYjREYLT8DAq +KcWtZRM7YLCuNvU9DPqLExcn0n/juDT1AIIy8XvLLamnAM15R2znn/F+vL00Lg7g +f1B60pbNdwgKemSoyL4J+ADU+rtgkPJtRnFVU7walLSd6K4ZvZcRnmOvrZdQitcn +eHmGaLBvFMdPr9+w8mKScnQ7h3eoHdOrqYkIAQcn18jQ2eFjeLrY5IaJlPPPVs+K +u/OHuj/tR7ZXzMhL5skK62U6/qGNs1pmgts8bM8i3aFUgRdGlnFbzTpje5cNM+T3 +RO0NgNL3ByIW1Wc2I+YjQ7FfWKUi2YKOljGBO1pIue09kyevRBKDuVwbXMW7MhLg +idm5AaY+OGDeqbaoSUgkGgrsrr5IlI39gZi9jwG85qe3Spavq3ILKdfL1N8UrFGD +/xIN0TVPtilede7vjKTK79tZu8JYaDWGc+g/mo/M1wmawLrqGNGzOwoVRruKl2In +m9PU9wBZ1HuphDQ4DRdC/AU8qkGhmDOx4bDWEQ/R3KKFHNvhnamyfyR7xqt79gyS +NGNIElnJuskCggIARFaK6yAVmaL74Qu3iiELj8FU9Cw8kPP5HeWUfGxCjlegdH3R +FBtoQlDcQjYzO2uZR94Itg3yk3Dt+xbf7KxUsODwlgLj1UhV4eOXUDTosBFTrbTG +v9gnRVH0Eyu9tF+CMUcCXhq6tnIrQOVv1ozcdXfIpk9gvIbfh4rlo6X0iM8Xge2t +Vo7awq05t4wJBkO1xUtOaw9HabaszK/CU1iNV7cIBmaFF3AEP/KVfOs+kjubc9AF +mqC+LVVClvJPNzm1YA5JZlxmQ0u1xXFqZv0OMoibgY+gSzaiAQz3eKB6vEv4Xv4U +kaF9nEUTEjowpTE6uX9X0mGkXXT2wXmlTjosZFnxRX5IIrRNug30plRra5CNYPGp +3uTmD/D7Nzi1iYitJg3yhrTQmCWiJY3x4Z0xophLkio2nlJ9WoTKf1AwTIATY7fa +pX9bxEKldYXrYZNFlbqBPFgA/36v+JDVfMf2E9yRMCt0LAJ0HUM6zP0ngMv+S1TP +Pu6X0WXR9JeuoaF4uJSty/xwdpST/CkHflFLVsk5n3tNQfWGjqoTSOJMgL9NRY9e +Pc/OshHZHeCVFUSXtcf1pfmmBtT6FHX0L4cgVqA5xO8RYapnLDAFLXq2/dRv3NwW +W9CzZcZKh7jmJw4iSIY5IU1+ThgugWoxlkcmjs/egjBclL8BBfqRIwx/vOE= -----END RSA PRIVATE KEY----- From 3aabe4eb605f15fa361206eb6fa5b8236b4f641f Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:42:50 +0200 Subject: [PATCH 005/188] missing files from 42419 --- mysql-test/include/wait_show_condition.inc | 78 ++++++++++++++++++++++ mysql-test/r/innodb_bug42419.result | 17 +++++ mysql-test/t/innodb_bug42419.test | 77 +++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 mysql-test/include/wait_show_condition.inc create mode 100644 mysql-test/r/innodb_bug42419.result create mode 100644 mysql-test/t/innodb_bug42419.test diff --git a/mysql-test/include/wait_show_condition.inc b/mysql-test/include/wait_show_condition.inc new file mode 100644 index 00000000000..253101d1e07 --- /dev/null +++ b/mysql-test/include/wait_show_condition.inc @@ -0,0 +1,78 @@ +# include/wait_show_condition.inc +# +# SUMMARY +# +# Waits until the show statement ($show_statement) has at least within one of +# the rows of the result set for the field ($field) a value which fulfils +# a condition ($condition), or the operation times out. +# +# +# USAGE +# +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# OR +# +# let $wait_timeout= 60; # Override default of 30 seconds with 60. +# let $show_statement= SHOW PROCESSLIST; +# let $field= State; +# let $condition= = 'Updating'; +# --source include/wait_show_condition.inc +# +# Please do not use this use routine if you can replace the SHOW statement +# with a select. In such a case include/wait_condition.inc is recommended. +# +# Created: 2009-02-18 mleich +# + +let $max_run_time= 30; +if ($wait_timeout) +{ + let $max_run_time= $wait_timeout; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +# The smallest timespan till UNIX_TIMESTAMP() gets incremented is ~0 seconds. +# We add one second to avoid the case that somebody measures timespans on a +# real clock with fractions of seconds, detects that n seconds are sufficient, +# assigns n to this routine and suffers because he sometimes gets n - 1 +# seconds in reality. +inc $max_run_time; + +let $found= 0; +let $max_end_time= `SELECT UNIX_TIMESTAMP() + $max_run_time`; +while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`) +{ + # Sleep a bit to avoid too heavy load. + real_sleep 0.2; + let $rowno= 1; + let $process_result= 1; + while (`SELECT $process_result = 1 AND $found = 0`) + { + let $field_value= query_get_value($show_statement, $field, $rowno); + if (`SELECT '$field_value' $condition`) + { + let $found= 1; + } + if (`SELECT '$field_value' = 'No such row'`) + { + # We are behind the last row of the result set. + let $process_result= 0; + } + inc $rowno; + } +} +if (!$found) +{ + echo # Timeout in include/wait_show_condition.inc for $wait_condition; + echo # show_statement : $show_statement; + echo # field : $field; + echo # condition : $condition; + echo # max_run_time : $max_run_time; +} + diff --git a/mysql-test/r/innodb_bug42419.result b/mysql-test/r/innodb_bug42419.result new file mode 100644 index 00000000000..f304bb634cb --- /dev/null +++ b/mysql-test/r/innodb_bug42419.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp ( b INT ); +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Reap the server message for connection user2 UPDATE t1 ... +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; diff --git a/mysql-test/t/innodb_bug42419.test b/mysql-test/t/innodb_bug42419.test new file mode 100644 index 00000000000..389093a8465 --- /dev/null +++ b/mysql-test/t/innodb_bug42419.test @@ -0,0 +1,77 @@ +# +# Testcase for InnoDB +# Bug#42419 Server crash with "Pure virtual method called" on two concurrent connections +# + +--source include/have_innodb.inc + +let $innodb_lock_wait_timeout= query_get_value(SHOW VARIABLES LIKE 'innodb_lock_wait_timeout%', Value, 1); +if (`SELECT $innodb_lock_wait_timeout < 10`) +{ + --echo # innodb_lock_wait_timeout must be >= 10 seconds + --echo # so that this test can work all time fine on an overloaded testing box + SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; + exit; +} + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# First session +connection default; + + +--enable_warnings +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp ( b INT ); + +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; + +# Second session +connect (user2,localhost,root,,,$MASTER_MYPORT,$MASTER_MYSOCK); + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +# The last update will wait for a lock held by the first session + +# First session +connection default; + +# Poll till the UPDATE of the second session waits for lock +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Updating'; +--source include/wait_show_condition.inc + +# If the testing box is overloadeded and innodb_lock_wait_timeout is too small +# we might get here ER_LOCK_WAIT_TIMEOUT. +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; + +# Second session +connection user2; +--echo Reap the server message for connection user2 UPDATE t1 ... +reap; + +# The server crashed when executing this UPDATE or the succeeding SQL command. +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect user2; +DROP TABLE t1; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc From 195ea7ea9de0ff1027824b71bdab9604ba896e5b Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:45:37 +0200 Subject: [PATCH 006/188] backport #42014, commit 65523 --- mysql-test/r/func_misc.result | 5 +++++ mysql-test/t/func_misc.test | 9 +++++++++ sql/item.cc | 25 +++++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index ce177b511b9..e57d46c006a 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -319,4 +319,9 @@ select @my_uuid_date - @my_uuid_synthetic; @my_uuid_date - @my_uuid_synthetic 0 set @@session.time_zone=@save_tz; +CREATE TABLE t1 (a DATE); +SELECT * FROM t1 WHERE a = NAME_CONST('reportDate', +_binary'2009-01-09' COLLATE 'binary'); +a +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 93fe94ec94f..c8075c42fc7 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -436,5 +436,14 @@ select @my_uuid_date - @my_uuid_synthetic; set @@session.time_zone=@save_tz; + +# +# Bug#42014: Crash, name_const with collate +# +CREATE TABLE t1 (a DATE); +SELECT * FROM t1 WHERE a = NAME_CONST('reportDate', + _binary'2009-01-09' COLLATE 'binary'); +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 182f4abdfe6..49b2010c581 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1243,13 +1243,26 @@ Item::Type Item_name_const::type() const valid_args guarantees value_item->basic_const_item(); if type is FUNC_ITEM, then we have a fudged item_func_neg() on our hands and return the underlying type. + For Item_func_set_collation() + e.g. NAME_CONST('name', 'value' COLLATE collation) we return its + 'value' argument type. */ - return valid_args ? - (((value_item->type() == FUNC_ITEM) && - (((Item_func *) value_item)->functype() == Item_func::NEG_FUNC)) ? - ((Item_func *) value_item)->key_item()->type() : - value_item->type()) : - NULL_ITEM; + if (!valid_args) + return NULL_ITEM; + Item::Type value_type= value_item->type(); + if (value_type == FUNC_ITEM) + { + /* + The second argument of NAME_CONST('name', 'value') must be + a simple constant item or a NEG_FUNC/COLLATE_FUNC. + */ + DBUG_ASSERT(((Item_func *) value_item)->functype() == + Item_func::NEG_FUNC || + ((Item_func *) value_item)->functype() == + Item_func::COLLATE_FUNC); + return ((Item_func *) value_item)->key_item()->type(); + } + return value_type; } From bb575dcc575b1b35083223f5f6dd165410eebedd Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:52:45 +0200 Subject: [PATCH 007/188] backport #41470, commit 62661 --- mysql-test/r/date_formats.result | 10 ++++++++++ mysql-test/t/date_formats.test | 12 ++++++++++++ sql-common/my_time.c | 13 +++++++------ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 6833a7f1594..43f656e3c99 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -593,3 +593,13 @@ select str_to_date('04/30/2004 ', '%m/%d/%Y '); str_to_date('04/30/2004 ', '%m/%d/%Y ') 2004-04-30 "End of 4.1 tests" +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +valid_date +Sunday 01 January 0000 +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +valid_date +Tuesday 28 February 0000 +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; +valid_date +Thursday 01 January 2009 +"End of 5.0 tests" diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index faa6d4242db..0c02398acc1 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -337,3 +337,15 @@ select str_to_date('04/30 /2004', '%m /%d /%Y'); select str_to_date('04/30/2004 ', '%m/%d/%Y '); --echo "End of 4.1 tests" + +# +# Bug #41470: DATE_FORMAT() crashes the complete server with a valid date +# + +# show that these two do not crash the server: +SELECT DATE_FORMAT("0000-01-01",'%W %d %M %Y') as valid_date; +SELECT DATE_FORMAT("0000-02-28",'%W %d %M %Y') as valid_date; +# show that date within the Gregorian range render correct results: (THU) +SELECT DATE_FORMAT("2009-01-01",'%W %d %M %Y') as valid_date; + +--echo "End of 5.0 tests" diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 1781251fca1..16a64ebd947 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -765,19 +765,20 @@ long calc_daynr(uint year,uint month,uint day) { long delsum; int temp; + int y= year; /* may be < 0 temporarily */ DBUG_ENTER("calc_daynr"); - if (year == 0 && month == 0 && day == 0) + if (y == 0 && month == 0 && day == 0) DBUG_RETURN(0); /* Skip errors */ - delsum= (long) (365L * year+ 31*(month-1) +day); + delsum= (long) (365L * y+ 31*(month-1) +day); if (month <= 2) - year--; + y--; else delsum-= (long) (month*4+23)/10; - temp=(int) ((year/100+1)*3)/4; + temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", - year+(month <= 2),month,day,delsum+year/4-temp)); - DBUG_RETURN(delsum+(int) year/4-temp); + y+(month <= 2),month,day,delsum+y/4-temp)); + DBUG_RETURN(delsum+(int) y/4-temp); } /* calc_daynr */ From 2d1c6ed62efcf8413c14bf7d2de5f7948014d015 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 12:57:03 +0200 Subject: [PATCH 008/188] backport #41456, commit 61847 --- mysql-test/r/grant.result | 5 +++++ mysql-test/t/grant.test | 7 +++++++ sql/set_var.cc | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index d56020c3090..ee328d461ac 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1151,4 +1151,9 @@ drop user 'greg'@'localhost'; drop view v1; drop table test; drop function test_function; +SELECT CURRENT_USER(); +CURRENT_USER() +root@localhost +SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); +SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); End of 5.0 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index e4b95502143..14c5879d007 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1175,4 +1175,11 @@ drop view v1; drop table test; drop function test_function; +# +# Bug#41456 SET PASSWORD hates CURRENT_USER() +# +SELECT CURRENT_USER(); +SET PASSWORD FOR CURRENT_USER() = PASSWORD("admin"); +SET PASSWORD FOR CURRENT_USER() = PASSWORD(""); + --echo End of 5.0 tests diff --git a/sql/set_var.cc b/sql/set_var.cc index 59741e5683d..a29abe6581f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3475,6 +3475,7 @@ int set_var_password::check(THD *thd) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!user->host.str) { + DBUG_ASSERT(thd->security_ctx->priv_host); if (*thd->security_ctx->priv_host != 0) { user->host.str= (char *) thd->security_ctx->priv_host; @@ -3486,6 +3487,12 @@ int set_var_password::check(THD *thd) user->host.length= 1; } } + if (!user->user.str) + { + DBUG_ASSERT(thd->security_ctx->priv_user); + user->user.str= (char *) thd->security_ctx->priv_user; + user->user.length= strlen(thd->security_ctx->priv_user); + } /* Returns 1 as the function sends error to client */ return check_change_password(thd, user->host.str, user->user.str, password, strlen(password)) ? 1 : 0; From 13973ee7546cfd78024c5005fd581bec536e6c18 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 13:03:29 +0200 Subject: [PATCH 009/188] backport #41437, commit 62803 --- mysql-test/r/mysql.result | 2 ++ mysql-test/t/mysql.test | 5 +++++ sql/item_strfunc.cc | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index eded1a3fc3b..bff0c32dca6 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -180,4 +180,6 @@ ERROR at line 1: DELIMITER cannot contain a backslash character 1 This is a file starting with UTF8 BOM 0xEFBBBF This is a file starting with UTF8 BOM 0xEFBBBF +@z:='1' @z=database() +1 NULL End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 182b292c817..2ef3dc84e5b 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -290,4 +290,9 @@ EOF --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug29323.sql 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/bug29323.sql; +# +# Bug #41437: Value stored in 'case' lacks charset, causees segfault +# +--exec $MYSQL -e "select @z:='1',@z=database()" + --echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d1e3f45bba1..34f974042a5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1696,6 +1696,12 @@ Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs) Item_string *conv; uint conv_errors; String tmp, cstr, *ostr= val_str(&tmp); + if (null_value) + { + Item *null_item= new Item_null((char *) fully_qualified_func_name()); + null_item->collation.set (tocs); + return null_item; + } cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); if (conv_errors || !(conv= new Item_static_string_func(fully_qualified_func_name(), From 37741cae58704c8c260fc64244b09de594f84da0 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 13:14:37 +0200 Subject: [PATCH 010/188] backport #39591, commit 59390 --- mysql-test/r/strict.result | 7 +++++++ mysql-test/t/strict.test | 9 +++++++++ sql/unireg.cc | 26 ++++++++++++++++++-------- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 34869862a63..22a9e941241 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1348,6 +1348,13 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*' drop table t1; +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f1` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן' +DROP TABLE t3; set sql_mode= 'traditional'; create table t1(col1 tinyint, col2 tinyint unsigned, col3 smallint, col4 smallint unsigned, diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 2b71bf1093c..877da3f2b37 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1199,6 +1199,15 @@ comment '123456789*123456789*123456789*123456789*123456789*123456789*'; show create table t1; drop table t1; +# +# Bug #39591: Crash if table comment is longer than 62 characters +# + +#60 chars, 120 (+1) bytes (UTF-8 with 2-byte chars) +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +SHOW CREATE TABLE t3; +DROP TABLE t3; + # # Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode # diff --git a/sql/unireg.cc b/sql/unireg.cc index b581ad4655a..f20d3e8cc6b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -143,6 +143,24 @@ bool mysql_create_frm(THD *thd, my_string file_name, (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); + /* + This gives us the byte-position of the character at + (character-position, not byte-position) TABLE_COMMENT_MAXLEN. + The trick here is that character-positions start at 0, so the last + character in a maximum-allowed length string would be at char-pos + MAXLEN-1; charpos MAXLEN will be the position of the terminator. + Consequently, bytepos(charpos(MAXLEN)) should be equal to + comment[length] (which should also be the terminator, or at least + the first byte after the payload in the strict sense). If this is + not so (bytepos(charpos(MAXLEN)) comes /before/ the end of the + string), the string is too long. + + For additional credit, realise that UTF-8 has 1-3 bytes before 6.0, + and 1-4 bytes in 6.0 (6.0 also has UTF-32). This means that the + inlined COMMENT supposedly does not exceed 60 character plus + terminator, vulgo, 181 bytes. + */ + tmp_len= system_charset_info->cset->charpos(system_charset_info, create_info->comment.str, create_info->comment.str + @@ -165,14 +183,6 @@ bool mysql_create_frm(THD *thd, my_string file_name, strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; -#ifdef EXTRA_DEBUG - /* - EXTRA_DEBUG causes strmake() to initialize its buffer behind the - payload with a magic value to detect wrong buffer-sizes. We - explicitly zero that segment again. - */ - memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]); -#endif if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) || my_pwrite(file,(byte*) keybuff,key_info_length, (ulong) uint2korr(fileinfo+6),MYF_RW)) From 1ba56d53ed01110460a201f46361892702fcc393 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 13:35:25 +0200 Subject: [PATCH 011/188] backport #34773, commit 61127 --- mysql-test/r/explain.result | 48 +++++++++++++++++++++++++++++++++++++ mysql-test/t/explain.test | 29 ++++++++++++++++++++++ sql/item.cc | 4 ++-- sql/item_sum.cc | 37 +++++++++++++++++++++++++--- sql/item_sum.h | 25 +++++++++++++------ sql/opt_range.cc | 2 +- sql/opt_sum.cc | 6 ++--- sql/sql_select.cc | 16 ++++++------- 8 files changed, 143 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index a4c8432d2a4..3aa189f4a9d 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -107,3 +107,51 @@ X X X X X X X X X X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF) DROP TABLE t2; DROP TABLE t1; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN EXTENDED SELECT 1 +FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +EXPLAIN EXTENDED SELECT 1 +FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +execute s1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +Warnings: +Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1` +DROP TABLE t1,t2; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index c9ae8aceaf6..0247aca82df 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -94,4 +94,33 @@ EXPLAIN SELECT 1 FROM DROP TABLE t2; DROP TABLE t1; +# +# Bug #34773: query with explain extended and derived table / other table +# crashes server +# + +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); + +EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; + +EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1; + +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; + +prepare s1 from +'EXPLAIN EXTENDED SELECT 1 + FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1'; +execute s1; +execute s1; + +DROP TABLE t1,t2; + # End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 49b2010c581..ceb8cfd4ac4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6805,7 +6805,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item) */ Item_sum *item_sum= (Item_sum *) item; if (item_sum->keep_field_type()) - return get_real_type(item_sum->args[0]); + return get_real_type(item_sum->get_arg(0)); break; } case FUNC_ITEM: @@ -7069,7 +7069,7 @@ void Item_type_holder::get_full_info(Item *item) if (item->type() == Item::SUM_FUNC_ITEM && (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC || ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC)) - item = ((Item_sum*)item)->args[0]; + item = ((Item_sum*)item)->get_arg(0); /* We can have enum/set type after merging only if we have one enum|set field (or MIN|MAX(enum|set field)) and number of NULL fields diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 91320d6b56b..d33d92a5238 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -370,6 +370,10 @@ Item_sum::Item_sum(List &list) :arg_count(list.elements), args[i++]= item; } } + if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) + { + args= NULL; + } mark_as_sum_func(); list.empty(); // Fields are used } @@ -380,18 +384,28 @@ Item_sum::Item_sum(List &list) :arg_count(list.elements), */ Item_sum::Item_sum(THD *thd, Item_sum *item): - Item_result_field(thd, item), arg_count(item->arg_count), + Item_result_field(thd, item), aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), - quick_group(item->quick_group), used_tables_cache(item->used_tables_cache), + quick_group(item->quick_group), + arg_count(item->arg_count), orig_args(NULL), + used_tables_cache(item->used_tables_cache), forced_const(item->forced_const) { if (arg_count <= 2) + { args=tmp_args; + orig_args=tmp_orig_args; + } else + { if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) return; + if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) + return; + } memcpy(args, item->args, sizeof(Item*)*arg_count); + memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count); } @@ -426,12 +440,13 @@ void Item_sum::make_field(Send_field *tmp_field) void Item_sum::print(String *str) { + Item **pargs= orig_args; str->append(func_name()); for (uint i=0 ; i < arg_count ; i++) { if (i) str->append(','); - args[i]->print(str); + pargs[i]->print(str); } str->append(')'); } @@ -532,6 +547,13 @@ void Item_sum::update_used_tables () } +Item *Item_sum::set_arg(int i, THD *thd, Item *new_val) +{ + thd->change_item_tree(args + i, new_val); + return new_val; +} + + String * Item_sum_num::val_str(String *str) { @@ -583,6 +605,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); fixed= 1; return FALSE; } @@ -670,6 +693,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + orig_args[0]= args[0]; fixed= 1; return FALSE; } @@ -3107,6 +3131,12 @@ Item_func_group_concat(Name_resolution_context *context_arg, sizeof(ORDER*)*arg_count_order))) return; + if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) + { + args= NULL; + return; + } + order= (ORDER**)(args + arg_count); /* fill args items of show and sort */ @@ -3334,6 +3364,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) if (check_sum_func(thd, ref)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); fixed= 1; return FALSE; } diff --git a/sql/item_sum.h b/sql/item_sum.h index d39fc96e254..51a1eff9bbf 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -228,10 +228,8 @@ public: VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC }; - Item **args, *tmp_args[2]; Item **ref_by; /* pointer to a ref to the object used to register it */ Item_sum *next; /* next in the circular chain of registered objects */ - uint arg_count; Item_sum *in_sum_func; /* embedding set function if any */ st_select_lex * aggr_sel; /* select where the function is aggregated */ int8 nest_level; /* number of the nesting level of the set function */ @@ -248,24 +246,32 @@ public: List outer_fields; protected: + uint arg_count; + Item **args, *tmp_args[2]; + /* + Copy of the arguments list to hold the original set of arguments. + Used in EXPLAIN EXTENDED instead of the current argument list because + the current argument list can be altered by usage of temporary tables. + */ + Item **orig_args, *tmp_orig_args[2]; table_map used_tables_cache; bool forced_const; public: void mark_as_sum_func(); - Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE) + Item_sum() :quick_group(1), arg_count(0), forced_const(FALSE) { mark_as_sum_func(); } - Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1), - forced_const(FALSE) + Item_sum(Item *a) :quick_group(1), arg_count(1), args(tmp_args), + orig_args(tmp_orig_args), forced_const(FALSE) { args[0]=a; mark_as_sum_func(); } - Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1), - forced_const(FALSE) + Item_sum( Item *a, Item *b ) :quick_group(1), arg_count(2), args(tmp_args), + orig_args(tmp_orig_args), forced_const(FALSE) { args[0]=a; args[1]=b; mark_as_sum_func(); @@ -374,6 +380,10 @@ public: bool register_sum_func(THD *thd, Item **ref); st_select_lex *depended_from() { return (nest_level == aggr_level ? 0 : aggr_sel); } + + Item *get_arg(int i) { return args[i]; } + Item *set_arg(int i, THD *thd, Item *new_val); + uint get_arg_count() { return arg_count; } }; @@ -981,6 +991,7 @@ public: if (udf.fix_fields(thd, this, this->arg_count, this->args)) return TRUE; + memcpy (orig_args, args, sizeof (Item *) * arg_count); return check_sum_func(thd, ref); } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 204ebdb6f33..7d9b1179d87 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7735,7 +7735,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) DBUG_RETURN(NULL); /* The argument of MIN/MAX. */ - Item *expr= min_max_item->args[0]->real_item(); + Item *expr= min_max_item->get_arg(0)->real_item(); if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */ { if (! min_max_arg_item) diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 3fc62d05ae5..39db1344588 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -160,7 +160,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) to the number of rows in the tables if this number is exact and there are no outer joins. */ - if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null && + if (!conds && !((Item_sum_count*) item)->get_arg(0)->maybe_null && !outer_tables && is_exact_count) { ((Item_sum_count*) item)->make_const(count); @@ -176,7 +176,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) parts of the key is found in the COND, then we can use indexes to find the key. */ - Item *expr=item_sum->args[0]; + Item *expr=item_sum->get_arg(0); if (expr->real_item()->type() == Item::FIELD_ITEM) { byte key_buff[MAX_KEY_LENGTH]; @@ -319,7 +319,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) parts of the key is found in the COND, then we can use indexes to find the key. */ - Item *expr=item_sum->args[0]; + Item *expr=item_sum->get_arg(0); if (expr->real_item()->type() == Item::FIELD_ITEM) { byte key_buff[MAX_KEY_LENGTH]; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f78991073bb..4c199b1bda6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9456,11 +9456,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) { /* Can't calc group yet */ - ((Item_sum*) item)->result_field=0; - for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++) + Item_sum *sum_item= (Item_sum *) item; + sum_item->result_field=0; + for (i=0 ; i < sum_item->get_arg_count() ; i++) { - Item **argp= ((Item_sum*) item)->args + i; - Item *arg= *argp; + Item *arg= sum_item->get_arg(i); if (!arg->const_item()) { uint field_index= (uint) (reg_field - table->field); @@ -9490,7 +9490,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, string_total_length+= new_field->pack_length(); } thd->mem_root= mem_root_save; - thd->change_item_tree(argp, new Item_field(new_field)); + arg= sum_item->set_arg(i, thd, new Item_field(new_field)); thd->mem_root= &table->mem_root; if (!(new_field->flags & NOT_NULL_FLAG)) { @@ -9499,7 +9499,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, new_field->maybe_null() is still false, it will be changed below. But we have to setup Item_field correctly */ - (*argp)->maybe_null=1; + arg->maybe_null=1; } new_field->query_id= thd->query_id; } @@ -13930,9 +13930,9 @@ count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, param->quick_group=0; // UDF SUM function param->sum_func_count++; - for (uint i=0 ; i < sum_item->arg_count ; i++) + for (uint i=0 ; i < sum_item->get_arg_count() ; i++) { - if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM) + if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM) param->field_count++; else param->func_count++; From ac4ab1413f8b96f27a76d2a43fd521f0c75e6025 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 13:38:10 +0200 Subject: [PATCH 012/188] adjust version string --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 448d3c90a26..4cd69277f20 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.74) +AM_INIT_AUTOMAKE(mysql, 5.0.74sp1) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From 475a4eb74ebf6a630fdfde5500de9037f36408ce Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 13:53:30 +0200 Subject: [PATCH 013/188] missing files for libedit --- cmd-line-utils/libedit/README | 50 +++ cmd-line-utils/libedit/filecomplete.c | 558 ++++++++++++++++++++++++++ cmd-line-utils/libedit/filecomplete.h | 44 ++ 3 files changed, 652 insertions(+) create mode 100644 cmd-line-utils/libedit/README create mode 100644 cmd-line-utils/libedit/filecomplete.c create mode 100644 cmd-line-utils/libedit/filecomplete.h diff --git a/cmd-line-utils/libedit/README b/cmd-line-utils/libedit/README new file mode 100644 index 00000000000..0b698a6150d --- /dev/null +++ b/cmd-line-utils/libedit/README @@ -0,0 +1,50 @@ +An approximate method to merge from upstream is: + + # Fetch latest from upstream (we also include some compat stuff) + $ CVS_RSH=ssh; export CVS_RSH + $ CVSROOT="anoncvs@stripped:/cvsroot" + $ cvs co -d libedit -P src/lib/libedit + $ mkdir libedit/np + $ for f in src/common/lib/libc/string/strlcat.c \ + > src/common/lib/libc/string/strlcpy.c \ + > src/include/vis.h \ + > src/lib/libc/gen/unvis.c \ + > src/lib/libc/gen/vis.c \ + > src/tools/compat/fgetln.c + > do + > cvs co -P ${f} + > mv ${f} libedit/np + > done + $ rm -rf src + $ cd libedit + + # Remove files we don't need/use + $ rm -rf CVS TEST Makefile shlib_version *.[0-9] + $ (cd readline; rm -rf CVS Makefile) + + # Rename files to match our naming + $ mv makelist makelist.sh + $ mv term.h el_term.h + + # Remove NetBSD-specific bits + $ for file in $(find . -type f) + > do + > cp ${file} ${file}.orig + > sed -e 's/#include "term.h"/#include "el_term.h"/g' \ + > -e 's/sig_handler/el_sig_handler/g' \ + > -e 's/isprint/el_isprint/g' \ + > -e '/^__RCSID/d' \ + > ${file}.orig >${file} + > rm ${file}.orig + > done + +then merge remaining bits by hand. All MySQL-specific changes should be +marked with XXXMYSQL to make them easier to identify and merge. To generate +a 'clean' diff against upstream you can use the above commands but use + + cvs co -D "2009/02/06 20:09:00" [..] + +to fetch the baseline of most recent merge. + +Please feed any fixes to Jonathan Perkin who will endeavour +to merge them upstream and keep diffs minimal. diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c new file mode 100644 index 00000000000..4c63f57bc45 --- /dev/null +++ b/cmd-line-utils/libedit/filecomplete.c @@ -0,0 +1,558 @@ +/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#include "config.h" + +/* XXXMYSQL */ +#ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +#else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifndef _AIX +extern char *alloca (); +# endif +# endif +#endif + +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_VIS_H +#include +#else +#include "np/vis.h" +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif +#include "el.h" +#include "fcns.h" /* for EL_NUM_FCNS */ +#include "histedit.h" +#include "filecomplete.h" + +static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', + '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; + + +/********************************/ +/* completion functions */ + +/* + * does tilde expansion of strings of type ``~user/foo'' + * if ``user'' isn't valid user name or ``txt'' doesn't start + * w/ '~', returns pointer to strdup()ed copy of ``txt'' + * + * it's callers's responsibility to free() returned string + */ +char * +fn_tilde_expand(const char *txt) +{ + struct passwd pwres, *pass; + char *temp; + size_t len = 0; + char pwbuf[1024]; + + if (txt[0] != '~') + return (strdup(txt)); + + temp = strchr(txt + 1, '/'); + if (temp == NULL) { + temp = strdup(txt + 1); + if (temp == NULL) + return NULL; + } else { + len = temp - txt + 1; /* text until string after slash */ + temp = malloc(len); + if (temp == NULL) + return NULL; + (void)strncpy(temp, txt + 1, len - 2); + temp[len - 2] = '\0'; + } + /* XXXMYSQL: use non-_r functions for now */ + if (temp[0] == 0) { + pass = getpwuid(getuid()); + } else { + pass = getpwnam(temp); + } + free(temp); /* value no more needed */ + if (pass == NULL) + return (strdup(txt)); + + /* update pointer txt to point at string immedially following */ + /* first slash */ + txt += len; + + temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); + if (temp == NULL) + return NULL; + (void)sprintf(temp, "%s/%s", pass->pw_dir, txt); + + return (temp); +} + + +/* + * return first found file name starting by the ``text'' or NULL if no + * such file can be found + * value of ``state'' is ignored + * + * it's caller's responsibility to free returned string + */ +char * +fn_filename_completion_function(const char *text, int state) +{ + static DIR *dir = NULL; + static char *filename = NULL, *dirname = NULL, *dirpath = NULL; + static size_t filename_len = 0; + struct dirent *entry; + char *temp; + size_t len; + + if (state == 0 || dir == NULL) { + temp = strrchr(text, '/'); + if (temp) { + char *nptr; + temp++; + nptr = realloc(filename, strlen(temp) + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + filename = nptr; + (void)strcpy(filename, temp); + len = temp - text; /* including last slash */ + nptr = realloc(dirname, len + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + dirname = nptr; + (void)strncpy(dirname, text, len); + dirname[len] = '\0'; + } else { + if (*text == 0) + filename = NULL; + else { + filename = strdup(text); + if (filename == NULL) + return NULL; + } + dirname = NULL; + } + + if (dir != NULL) { + (void)closedir(dir); + dir = NULL; + } + + /* support for ``~user'' syntax */ + free(dirpath); + + if (dirname == NULL && (dirname = strdup("./")) == NULL) + return NULL; + + if (*dirname == '~') + dirpath = fn_tilde_expand(dirname); + else + dirpath = strdup(dirname); + + if (dirpath == NULL) + return NULL; + + dir = opendir(dirpath); + if (!dir) + return (NULL); /* cannot open the directory */ + + /* will be used in cycle */ + filename_len = filename ? strlen(filename) : 0; + } + + /* find the match */ + while ((entry = readdir(dir)) != NULL) { + /* skip . and .. */ + if (entry->d_name[0] == '.' && (!entry->d_name[1] + || (entry->d_name[1] == '.' && !entry->d_name[2]))) + continue; + if (filename_len == 0) + break; + /* otherwise, get first entry where first */ + /* filename_len characters are equal */ + if (entry->d_name[0] == filename[0] +#if HAVE_STRUCT_DIRENT_D_NAMLEN + && entry->d_namlen >= filename_len +#else + && strlen(entry->d_name) >= filename_len +#endif + && strncmp(entry->d_name, filename, + filename_len) == 0) + break; + } + + if (entry) { /* match found */ + +#if HAVE_STRUCT_DIRENT_D_NAMLEN + len = entry->d_namlen; +#else + len = strlen(entry->d_name); +#endif + + temp = malloc(strlen(dirname) + len + 1); + if (temp == NULL) + return NULL; + (void)sprintf(temp, "%s%s", dirname, entry->d_name); + } else { + (void)closedir(dir); + dir = NULL; + temp = NULL; + } + + return (temp); +} + + +static const char * +append_char_function(const char *name) +{ + struct stat stbuf; + char *expname = *name == '~' ? fn_tilde_expand(name) : NULL; + const char *rs = " "; + + if (stat(expname ? expname : name, &stbuf) == -1) + goto out; + if (S_ISDIR(stbuf.st_mode)) + rs = "/"; +out: + if (expname) + free(expname); + return rs; +} +/* + * returns list of completions for text given + * non-static for readline. + */ +char ** completion_matches(const char *, char *(*)(const char *, int)); +char ** +completion_matches(const char *text, char *(*genfunc)(const char *, int)) +{ + char **match_list = NULL, *retstr, *prevstr; + size_t match_list_len, max_equal, which, i; + size_t matches; + + matches = 0; + match_list_len = 1; + while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { + /* allow for list terminator here */ + if (matches + 3 >= match_list_len) { + char **nmatch_list; + while (matches + 3 >= match_list_len) + match_list_len <<= 1; + nmatch_list = realloc(match_list, + match_list_len * sizeof(char *)); + if (nmatch_list == NULL) { + free(match_list); + return NULL; + } + match_list = nmatch_list; + + } + match_list[++matches] = retstr; + } + + if (!match_list) + return NULL; /* nothing found */ + + /* find least denominator and insert it to match_list[0] */ + which = 2; + prevstr = match_list[1]; + max_equal = strlen(prevstr); + for (; which <= matches; which++) { + for (i = 0; i < max_equal && + prevstr[i] == match_list[which][i]; i++) + continue; + max_equal = i; + } + + retstr = malloc(max_equal + 1); + if (retstr == NULL) { + free(match_list); + return NULL; + } + (void)strncpy(retstr, match_list[1], max_equal); + retstr[max_equal] = '\0'; + match_list[0] = retstr; + + /* add NULL as last pointer to the array */ + match_list[matches + 1] = (char *) NULL; + + return (match_list); +} + +/* + * Sort function for qsort(). Just wrapper around strcasecmp(). + */ +static int +_fn_qsort_string_compare(const void *i1, const void *i2) +{ + const char *s1 = ((const char * const *)i1)[0]; + const char *s2 = ((const char * const *)i2)[0]; + + return strcasecmp(s1, s2); +} + +/* + * Display list of strings in columnar format on readline's output stream. + * 'matches' is list of strings, 'len' is number of strings in 'matches', + * 'max' is maximum length of string in 'matches'. + */ +void +fn_display_match_list (EditLine *el, char **matches, int len, int max) +{ + int i, idx, limit, count; + int screenwidth = el->el_term.t_size.h; + + /* + * Find out how many entries can be put on one line, count + * with two spaces between strings. + */ + limit = screenwidth / (max + 2); + if (limit == 0) + limit = 1; + + /* how many lines of output */ + count = len / limit; + if (count * limit < len) + count++; + + /* Sort the items if they are not already sorted. */ + qsort(&matches[1], (size_t)(len - 1), sizeof(char *), + _fn_qsort_string_compare); + + idx = 1; + for(; count > 0; count--) { + for(i = 0; i < limit && matches[idx]; i++, idx++) + (void)fprintf(el->el_outfile, "%-*s ", max, + matches[idx]); + (void)fprintf(el->el_outfile, "\n"); + } +} + +/* + * Complete the word at or before point, + * 'what_to_do' says what to do with the completion. + * \t means do standard completion. + * `?' means list the possible completions. + * `*' means insert all of the possible completions. + * `!' means to do standard completion, and list all possible completions if + * there is more than one. + * + * Note: '*' support is not implemented + * '!' could never be invoked + */ +int +fn_complete(EditLine *el, + char *(*complet_func)(const char *, int), + char **(*attempted_completion_function)(const char *, int, int), + const char *word_break, const char *special_prefixes, + const char *(*app_func)(const char *), int query_items, + int *completion_type, int *over, int *point, int *end) +{ + const LineInfo *li; + char *temp, **matches; + const char *ctemp; + size_t len; + int what_to_do = '\t'; + int retval = CC_NORM; + + if (el->el_state.lastcmd == el->el_state.thiscmd) + what_to_do = '?'; + + /* readline's rl_complete() has to be told what we did... */ + if (completion_type != NULL) + *completion_type = what_to_do; + + if (!complet_func) + complet_func = fn_filename_completion_function; + if (!app_func) + app_func = append_char_function; + + /* We now look backwards for the start of a filename/variable word */ + li = el_line(el); + ctemp = (const char *) li->cursor; + while (ctemp > li->buffer + && !strchr(word_break, ctemp[-1]) + && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) + ctemp--; + + len = li->cursor - ctemp; +#if defined(__SSP__) || defined(__SSP_ALL__) + temp = malloc(len + 1); +#else + temp = alloca(len + 1); +#endif + (void)strncpy(temp, ctemp, len); + temp[len] = '\0'; + + /* these can be used by function called in completion_matches() */ + /* or (*attempted_completion_function)() */ + if (point != 0) + *point = li->cursor - li->buffer; + if (end != NULL) + *end = li->lastchar - li->buffer; + + if (attempted_completion_function) { + int cur_off = li->cursor - li->buffer; + matches = (*attempted_completion_function) (temp, + (int)(cur_off - len), cur_off); + } else + matches = 0; + if (!attempted_completion_function || + (over != NULL && !*over && !matches)) + matches = completion_matches(temp, complet_func); + + if (over != NULL) + *over = 0; + + if (matches) { + int i; + int matches_num, maxlen, match_len, match_display=1; + + retval = CC_REFRESH; + /* + * Only replace the completed string with common part of + * possible matches if there is possible completion. + */ + if (matches[0][0] != '\0') { + el_deletestr(el, (int) len); + el_insertstr(el, matches[0]); + } + + if (what_to_do == '?') + goto display_matches; + + if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { + /* + * We found exact match. Add a space after + * it, unless we do filename completion and the + * object is a directory. + */ + el_insertstr(el, (*app_func)(matches[0])); + } else if (what_to_do == '!') { + display_matches: + /* + * More than one match and requested to list possible + * matches. + */ + + for(i=1, maxlen=0; matches[i]; i++) { + match_len = strlen(matches[i]); + if (match_len > maxlen) + maxlen = match_len; + } + matches_num = i - 1; + + /* newline to get on next line from command line */ + (void)fprintf(el->el_outfile, "\n"); + + /* + * If there are too many items, ask user for display + * confirmation. + */ + if (matches_num > query_items) { + (void)fprintf(el->el_outfile, + "Display all %d possibilities? (y or n) ", + matches_num); + (void)fflush(el->el_outfile); + if (getc(stdin) != 'y') + match_display = 0; + (void)fprintf(el->el_outfile, "\n"); + } + + if (match_display) + fn_display_match_list(el, matches, matches_num, + maxlen); + retval = CC_REDISPLAY; + } else if (matches[0][0]) { + /* + * There was some common match, but the name was + * not complete enough. Next tab will print possible + * completions. + */ + el_beep(el); + } else { + /* lcd is not a valid object - further specification */ + /* is needed */ + el_beep(el); + retval = CC_NORM; + } + + /* free elements of array and the array itself */ + for (i = 0; matches[i]; i++) + free(matches[i]); + free(matches); + matches = NULL; + } +#if defined(__SSP__) || defined(__SSP_ALL__) + free(temp); +#endif + return retval; +} + +/* + * el-compatible wrapper around rl_complete; needed for key binding + */ +/* ARGSUSED */ +unsigned char +_el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) +{ + return (unsigned char)fn_complete(el, NULL, NULL, + break_chars, NULL, NULL, 100, + NULL, NULL, NULL, NULL); +} diff --git a/cmd-line-utils/libedit/filecomplete.h b/cmd-line-utils/libedit/filecomplete.h new file mode 100644 index 00000000000..12e0c6f14b0 --- /dev/null +++ b/cmd-line-utils/libedit/filecomplete.h @@ -0,0 +1,44 @@ +/* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ +#ifndef _FILECOMPLETE_H_ +#define _FILECOMPLETE_H_ + +int fn_complete(EditLine *, + char *(*)(const char *, int), + char **(*)(const char *, int, int), + const char *, const char *, const char *(*)(const char *), int, + int *, int *, int *, int *); + +void fn_display_match_list(EditLine *, char **, int, int); +char *fn_tilde_expand(const char *); +char *fn_filename_completion_function(const char *, int); + +#endif From a5b6707a3f67f234b960d8cfd2a9cf562c048045 Mon Sep 17 00:00:00 2001 From: Daniel Fischer Date: Thu, 30 Apr 2009 15:38:00 +0200 Subject: [PATCH 014/188] after-backport fixes --- client/mysql.cc | 4 +- cmd-line-utils/libedit/TEST/test.c | 269 -------- cmd-line-utils/libedit/compat.h | 43 -- cmd-line-utils/libedit/compat_conf.h | 2 - cmd-line-utils/libedit/editline.3 | 619 ------------------ cmd-line-utils/libedit/editrc.5 | 491 -------------- cmd-line-utils/libedit/fgetln.c | 88 --- cmd-line-utils/libedit/fgetln.h | 3 - cmd-line-utils/libedit/libedit_term.h | 124 ---- cmd-line-utils/libedit/strlcpy.c | 73 --- cmd-line-utils/libedit/strlcpy.h | 2 - cmd-line-utils/libedit/tokenizer.h | 54 -- cmd-line-utils/libedit/unvis.c | 311 --------- cmd-line-utils/libedit/vis.c | 392 ----------- cmd-line-utils/libedit/vis.h | 92 --- mysql-test/include/count_sessions.inc | 21 + .../include/wait_until_count_sessions.inc | 126 ++++ mysql-test/r/strict.result | 4 +- mysql-test/t/strict.test | 2 +- 19 files changed, 153 insertions(+), 2567 deletions(-) delete mode 100644 cmd-line-utils/libedit/TEST/test.c delete mode 100644 cmd-line-utils/libedit/compat.h delete mode 100644 cmd-line-utils/libedit/compat_conf.h delete mode 100644 cmd-line-utils/libedit/editline.3 delete mode 100644 cmd-line-utils/libedit/editrc.5 delete mode 100644 cmd-line-utils/libedit/fgetln.c delete mode 100644 cmd-line-utils/libedit/fgetln.h delete mode 100644 cmd-line-utils/libedit/libedit_term.h delete mode 100644 cmd-line-utils/libedit/strlcpy.c delete mode 100644 cmd-line-utils/libedit/strlcpy.h delete mode 100644 cmd-line-utils/libedit/tokenizer.h delete mode 100644 cmd-line-utils/libedit/unvis.c delete mode 100644 cmd-line-utils/libedit/vis.c delete mode 100644 cmd-line-utils/libedit/vis.h create mode 100644 mysql-test/include/count_sessions.inc create mode 100644 mysql-test/include/wait_until_count_sessions.inc diff --git a/client/mysql.cc b/client/mysql.cc index 9b14f9fb3ef..82de215efd1 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2262,8 +2262,10 @@ static char **new_mysql_completion (const char *text, int start, int end); if not. */ -#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE) +#if defined(USE_NEW_READLINE_INTERFACE) char *no_completion(const char*,int) +#elif defined(USE_LIBEDIT_INTERFACE) +int no_completion(const char*,int) #else char *no_completion() #endif diff --git a/cmd-line-utils/libedit/TEST/test.c b/cmd-line-utils/libedit/TEST/test.c deleted file mode 100644 index 605341eac62..00000000000 --- a/cmd-line-utils/libedit/TEST/test.c +++ /dev/null @@ -1,269 +0,0 @@ -/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#include "compat.h" -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * test.c: A little test program - */ -#include "sys.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include "histedit.h" -#include "tokenizer.h" - -static int continuation = 0; -static EditLine *el = NULL; - -static u_char complete(EditLine *, int); - int main(int, char **); -static char *prompt(EditLine *); -static void sig(int); - -static char * -prompt(EditLine *el) -{ - static char a[] = "Edit$"; - static char b[] = "Edit>"; - - return (continuation ? b : a); -} - -static void -sig(int i) -{ - - (void) fprintf(stderr, "Got signal %d.\n", i); - el_reset(el); -} - -static unsigned char -complete(EditLine *el, int ch) -{ - DIR *dd = opendir("."); - struct dirent *dp; - const char* ptr; - const LineInfo *lf = el_line(el); - int len; - - /* - * Find the last word - */ - for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--) - continue; - len = lf->cursor - ++ptr; - - for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { - if (len > strlen(dp->d_name)) - continue; - if (strncmp(dp->d_name, ptr, len) == 0) { - closedir(dd); - if (el_insertstr(el, &dp->d_name[len]) == -1) - return (CC_ERROR); - else - return (CC_REFRESH); - } - } - - closedir(dd); - return (CC_ERROR); -} - -int -main(int argc, char *argv[]) -{ - int num; - const char *buf; - Tokenizer *tok; - int lastevent = 0, ncontinuation; - History *hist; - HistEvent ev; - - (void) signal(SIGINT, sig); - (void) signal(SIGQUIT, sig); - (void) signal(SIGHUP, sig); - (void) signal(SIGTERM, sig); - - hist = history_init(); /* Init the builtin history */ - /* Remember 100 events */ - history(hist, &ev, H_SETSIZE, 100); - - tok = tok_init(NULL); /* Initialize the tokenizer */ - - /* Initialize editline */ - el = el_init(*argv, stdin, stdout, stderr); - - el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ - el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ - el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ - - /* Tell editline to use this history interface */ - el_set(el, EL_HIST, history, hist); - - /* Add a user-defined function */ - el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); - - /* Bind tab to it */ - el_set(el, EL_BIND, "^I", "ed-complete", NULL); - - /* - * Bind j, k in vi command mode to previous and next line, instead - * of previous and next history. - */ - el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); - el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); - - /* - * Source the user's defaults file. - */ - el_source(el, NULL); - - while ((buf = el_gets(el, &num)) != NULL && num != 0) { - int ac; - char **av; -#ifdef DEBUG - (void) fprintf(stderr, "got %d %s", num, buf); -#endif - if (!continuation && num == 1) - continue; - - if (tok_line(tok, buf, &ac, &av) > 0) - ncontinuation = 1; - -#if 0 - if (continuation) { - /* - * Append to the right event in case the user - * moved around in history. - */ - if (history(hist, &ev, H_SET, lastevent) == -1) - err(1, "%d: %s\n", lastevent, ev.str); - history(hist, &ev, H_ADD , buf); - } else { - history(hist, &ev, H_ENTER, buf); - lastevent = ev.num; - } -#else - /* Simpler */ - history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); -#endif - - continuation = ncontinuation; - ncontinuation = 0; - - if (strcmp(av[0], "history") == 0) { - int rv; - - switch (ac) { - case 1: - for (rv = history(hist, &ev, H_LAST); rv != -1; - rv = history(hist, &ev, H_PREV)) - (void) fprintf(stdout, "%4d %s", - ev.num, ev.str); - break; - - case 2: - if (strcmp(av[1], "clear") == 0) - history(hist, &ev, H_CLEAR); - else - goto badhist; - break; - - case 3: - if (strcmp(av[1], "load") == 0) - history(hist, &ev, H_LOAD, av[2]); - else if (strcmp(av[1], "save") == 0) - history(hist, &ev, H_SAVE, av[2]); - break; - - badhist: - default: - (void) fprintf(stderr, - "Bad history arguments\n"); - break; - } - } else if (el_parse(el, ac, av) == -1) { - switch (fork()) { - case 0: - execvp(av[0], av); - perror(av[0]); - _exit(1); - /*NOTREACHED*/ - break; - - case -1: - perror("fork"); - break; - - default: - if (wait(&num) == -1) - perror("wait"); - (void) fprintf(stderr, "Exit %x\n", num); - break; - } - } - - tok_reset(tok); - } - - el_end(el); - tok_end(tok); - history_end(hist); - - return (0); -} diff --git a/cmd-line-utils/libedit/compat.h b/cmd-line-utils/libedit/compat.h deleted file mode 100644 index 3693a2db809..00000000000 --- a/cmd-line-utils/libedit/compat.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LIBEDIT_COMPATH_H -#define __LIBEDIT_COMPATH_H - -#define __RCSID(x) -#define __COPYRIGHT(x) - -#include "compat_conf.h" - -#ifndef HAVE_VIS_H -/* string visual representation - may want to reimplement */ -#define strvis(d,s,m) strcpy(d,s) -#define strunvis(d,s) strcpy(d,s) -#endif - -#ifndef HAVE_FGETLN -#include "fgetln.h" -#endif - -#ifndef HAVE_ISSETUGID -#define issetugid() (getuid()!=geteuid() || getegid()!=getgid()) -#endif - -#ifndef HAVE_STRLCPY -#include "strlcpy.h" -#endif - -#if HAVE_SYS_CDEFS_H -#include -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) -#define __attribute__(A) -#endif - -#endif diff --git a/cmd-line-utils/libedit/compat_conf.h b/cmd-line-utils/libedit/compat_conf.h deleted file mode 100644 index e2b9557f5b1..00000000000 --- a/cmd-line-utils/libedit/compat_conf.h +++ /dev/null @@ -1,2 +0,0 @@ - -#include "my_config.h" diff --git a/cmd-line-utils/libedit/editline.3 b/cmd-line-utils/libedit/editline.3 deleted file mode 100644 index 1b812ebcc79..00000000000 --- a/cmd-line-utils/libedit/editline.3 +++ /dev/null @@ -1,619 +0,0 @@ -.\" $NetBSD: editline.3,v 1.21 2001/04/02 18:29:49 wiz Exp $ -.\" -.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. -.\" -.\" 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. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. -.\" -.Dd November 12, 1999 -.Os -.Dt EDITLINE 3 -.Sh NAME -.Nm editline , -.Nm el_init , -.Nm el_end , -.Nm el_reset , -.Nm el_gets , -.Nm el_getc , -.Nm el_push , -.Nm el_parse , -.Nm el_set , -.Nm el_source , -.Nm el_resize , -.Nm el_line , -.Nm el_insertstr , -.Nm el_deletestr , -.Nm history_init , -.Nm history_end , -.Nm history -.Nd line editor and history functions -.Sh LIBRARY -.Lb libedit -.Sh SYNOPSIS -.Fd #include -.Ft EditLine * -.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" -.Ft void -.Fn el_end "EditLine *e" -.Ft void -.Fn el_reset "EditLine *e" -.Ft const char * -.Fn el_gets "EditLine *e" "int *count" -.Ft int -.Fn el_getc "EditLine *e" "char *ch" -.Ft void -.Fn el_push "EditLine *e" "const char *str" -.Ft int -.Fn el_parse "EditLine *e" "int argc" "char *argv[]" -.Ft int -.Fn el_set "EditLine *e" "int op" "..." -.Ft int -.Fn el_get "EditLine *e" "int op" "void *result" -.Ft int -.Fn el_source "EditLine *e" "const char *file" -.Ft void -.Fn el_resize "EditLine *e" -.Ft const LineInfo * -.Fn el_line "EditLine *e" -.Ft int -.Fn el_insertstr "EditLine *e" "const char *str" -.Ft void -.Fn el_deletestr "EditLine *e" "int count" -.Ft History * -.Fn history_init -.Ft void -.Fn history_end "History *h" -.Ft int -.Fn history "History *h" "HistEvent *ev" "int op" "..." -.Sh DESCRIPTION -The -.Nm -library provides generic line editing and history functions, -similar to those found in -.Xr sh 1 . -.Pp -These functions are available in the -.Nm libedit -library (which needs the -.Nm libtermcap -library). -Programs should be linked with -.Fl ledit ltermcap . -.Sh LINE EDITING FUNCTIONS -The line editing functions use a common data structure, -.Fa EditLine , -which is created by -.Fn el_init -and freed by -.Fn el_end . -.Pp -The following functions are available: -.Bl -tag -width 4n -.It Fn el_init -Initialise the line editor, and return a data structure -to be used by all other line editing functions. -.Fa prog -is the name of the invoking program, used when reading the -.Xr editrc 5 -file to determine which settings to use. -.Fa fin , -.Fa fout -and -.Fa ferr -are the input, output, and error streams (respectively) to use. -In this documentation, references to -.Dq the tty -are actually to this input/output stream combination. -.It Fn el_end -Clean up and finish with -.Fa e , -assumed to have been created with -.Fn el_init . -.It Fn el_reset -Reset the tty and the parser. -This should be called after an error which may have upset the tty's -state. -.It Fn el_gets -Read a line from the tty. -.Fa count -is modified to contain the number of characters read. -Returns the line read if successful, or -.Dv NULL -if no characters were read or if an error occurred. -.It Fn el_getc -Read a character from the tty. -.Fa ch -is modified to contain the character read. -Returns the number of characters read if successful, -1 otherwise. -.It Fn el_push -Pushes -.Fa str -back onto the input stream. -This is used by the macro expansion mechanism. -Refer to the description of -.Ic bind -.Fl s -in -.Xr editrc 5 -for more information. -.It Fn el_parse -Parses the -.Fa argv -array (which is -.Fa argc -elements in size) -to execute builtin -.Nm -commands. -If the command is prefixed with -.Dq prog: -then -.Fn el_parse -will only execute the command if -.Dq prog -matches the -.Fa prog -argument supplied to -.Fn el_init . -The return value is --1 if the command is unknown, -0 if there was no error or -.Dq prog -didn't match, or -1 if the command returned an error. -Refer to -.Xr editrc 5 -for more information. -.It Fn el_set -Set -.Nm -parameters. -.Fa op -determines which parameter to set, and each operation has its -own parameter list. -.Pp -The following values for -.Fa op -are supported, along with the required argument list: -.Bl -tag -width 4n -.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" -Define prompt printing function as -.Fa f , -which is to return a string that contains the prompt. -.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" -Define right side prompt printing function as -.Fa f , -which is to return a string that contains the prompt. -.It Dv EL_TERMINAL , Fa "const char *type" -Define terminal type of the tty to be -.Fa type , -or to -.Ev TERM -if -.Fa type -is -.Dv NULL . -.It Dv EL_EDITOR , Fa "const char *mode" -Set editing mode to -.Fa mode , -which must be one of -.Dq emacs -or -.Dq vi . -.It Dv EL_SIGNAL , Fa "int flag" -If -.Fa flag -is non-zero, -.Nm -will install its own signal handler for the following signals when -reading command input: -.Dv SIGCONT , -.Dv SIGHUP , -.Dv SIGINT , -.Dv SIGQUIT , -.Dv SIGSTOP , -.Dv SIGTERM , -.Dv SIGTSTP , -and -.Dv SIGWINCH . -Otherwise, the current signal handlers will be used. -.It Dv EL_BIND , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic bind -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_ECHOTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic echotc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_SETTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic settc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_SETTY , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic setty -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_TELLTC , Xo -.Fa "const char *" , -.Fa "..." , -.Dv NULL -.Xc -Perform the -.Ic telltc -builtin command. -Refer to -.Xr editrc 5 -for more information. -.It Dv EL_ADDFN , Xo -.Fa "const char *name" , -.Fa "const char *help" , -.Fa "unsigned char (*func)(EditLine *e, int ch) -.Xc -Add a user defined function, -.Fn func , -referred to as -.Fa name -which is invoked when a key which is bound to -.Fa name -is entered. -.Fa help -is a description of -.Fa name . -At invocation time, -.Fa ch -is the key which caused the invocation. -The return value of -.Fn func -should be one of: -.Bl -tag -width "CC_REDISPLAY" -.It Dv CC_NORM -Add a normal character. -.It Dv CC_NEWLINE -End of line was entered. -.It Dv CC_EOF -EOF was entered. -.It Dv CC_ARGHACK -Expecting further command input as arguments, do nothing visually. -.It Dv CC_REFRESH -Refresh display. -.It Dv CC_REFRESH_BEEP -Refresh display, and beep. -.It Dv CC_CURSOR -Cursor moved, so update and perform -.Dv CC_REFRESH. -.It Dv CC_REDISPLAY -Redisplay entire input line. -This is useful if a key binding outputs extra information. -.It Dv CC_ERROR -An error occurred. -Beep, and flush tty. -.It Dv CC_FATAL -Fatal error, reset tty to known state. -.El -.It Dv EL_HIST , Xo -.Fa "History *(*func)(History *, int op, ...)" , -.Fa "const char *ptr" -.Xc -Defines which history function to use, which is usually -.Fn history . -.Fa ptr -should be the value returned by -.Fn history_init . -.It Dv EL_EDITMODE , Fa "int flag" -If -.Fa flag -is non-zero, -editing is enabled (the default). -Note that this is only an indication, and does not -affect the operation of -.Nm "" . -At this time, it is the caller's responsibility to -check this -(using -.Fn el_get ) -to determine if editing should be enabled or not. -.El -.It Fn el_get -Get -.Nm -parameters. -.Fa op -determines which parameter to retrieve into -.Fa result . -.Pp -The following values for -.Fa op -are supported, along with actual type of -.Fa result : -.Bl -tag -width 4n -.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" -Return a pointer to the function that displays the prompt. -.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" -Return a pointer to the function that displays the rightside prompt. -.It Dv EL_EDITOR , Fa "const char *" -Return the name of the editor, which will be one of -.Dq emacs -or -.Dq vi . -.It Dv EL_SIGNAL , Fa "int *" -Return non-zero if -.Nm -has installed private signal handlers (see -.Fn el_get -above). -.It Dv EL_EDITMODE, Fa "int *" -Return non-zero if editing is enabled. -.El -.It Fn el_source -Initialise -.Nm -by reading the contents of -.Fa file . -.Fn el_parse -is called for each line in -.Fa file . -If -.Fa file -is -.Dv NULL , -try -.Pa $PWD/.editrc -then -.Pa $HOME/.editrc . -Refer to -.Xr editrc 5 -for details on the format of -.Fa file . -.It Fn el_resize -Must be called if the terminal size changes. -If -.Dv EL_SIGNAL -has been set with -.Fn el_set , -then this is done automatically. -Otherwise, it's the responsibility of the application to call -.Fn el_resize -on the appropriate occasions. -.It Fn el_line -Return the editing information for the current line in a -.Fa LineInfo -structure, which is defined as follows: -.Bd -literal -typedef struct lineinfo { - const char *buffer; /* address of buffer */ - const char *cursor; /* address of cursor */ - const char *lastchar; /* address of last character */ -} LineInfo; -.Ed -.It Fn el_insertstr -Insert -.Fa str -into the line at the cursor. -Returns -1 if -.Fa str -is empty or won't fit, and 0 otherwise. -.It Fn el_deletestr -Delete -.Fa num -characters before the cursor. -.El -.Sh HISTORY LIST FUNCTIONS -The history functions use a common data structure, -.Fa History , -which is created by -.Fn history_init -and freed by -.Fn history_end . -.Pp -The following functions are available: -.Bl -tag -width 4n -.It Fn history_init -Initialise the history list, and return a data structure -to be used by all other history list functions. -.It Fn history_end -Clean up and finish with -.Fa h , -assumed to have been created with -.Fn history_init . -.It Fn history -Perform operation -.Fa op -on the history list, with optional arguments as needed by the -operation. -.Fa ev -is changed accordingly to operation. -The following values for -.Fa op -are supported, along with the required argument list: -.Bl -tag -width 4n -.It Dv H_SETSIZE , Fa "int size" -Set size of history to -.Fa size -elements. -.It Dv H_GETSIZE -Get number of events currently in history. -.It Dv H_END -Cleans up and finishes with -.Fa h , -assumed to be created with -.Fn history_init . -.It Dv H_CLEAR -Clear the history. -.It Dv H_FUNC , Xo -.Fa "void *ptr" , -.Fa "history_gfun_t first" , -.Fa "history_gfun_t next" , -.Fa "history_gfun_t last" , -.Fa "history_gfun_t prev" , -.Fa "history_gfun_t curr" , -.Fa "history_sfun_t set" , -.Fa "history_vfun_t clear" , -.Fa "history_efun_t enter" , -.Fa "history_efun_t add" -.Xc -Define functions to perform various history operations. -.Fa ptr -is the argument given to a function when it's invoked. -.It Dv H_FIRST -Return the first element in the history. -.It Dv H_LAST -Return the last element in the history. -.It Dv H_PREV -Return the previous element in the history. -.It Dv H_NEXT -Return the next element in the history. -.It Dv H_CURR -Return the current element in the history. -.It Dv H_SET -Set the cursor to point to the requested element. -.It Dv H_ADD , Fa "const char *str" -Append -.Fa str -to the current element of the history, or create an element with -.It Dv H_APPEND , Fa "const char *str" -Append -.Fa str -to the last new element of the history. -.It Dv H_ENTER , Fa "const char *str" -Add -.Fa str -as a new element to the history, and, if necessary, -removing the oldest entry to keep the list to the created size. -.It Dv H_PREV_STR , Fa "const char *str" -Return the closest previous event that starts with -.Fa str . -.It Dv H_NEXT_STR , Fa "const char *str" -Return the closest next event that starts with -.Fa str . -.It Dv H_PREV_EVENT , Fa "int e" -Return the previous event numbered -.Fa e . -.It Dv H_NEXT_EVENT , Fa "int e" -Return the next event numbered -.Fa e . -.It Dv H_LOAD , Fa "const char *file" -Load the history list stored in -.Fa file . -.It Dv H_SAVE , Fa "const char *file" -Save the history list to -.Fa file . -.El -.Pp -.Fn history -returns 0 if the operation -.Fa op -succeeds. Otherwise, -1 is returned and -.Fa ev -is updated to contain more details about the error. -.El -.\"XXX.Sh EXAMPLES -.\"XXX: provide some examples -.Sh SEE ALSO -.Xr editrc 5 , -.Xr sh 1 , -.Xr signal 3 , -.Xr termcap 3 -.Sh HISTORY -The -.Nm -library first appeared in -.Bx 4.4 . -.Dv CC_REDISPLAY -appeared in -.Nx 1.3 . -.Dv CC_REFRESH_BEEP , -.Dv EL_EDITMODE -and the readline emulation appeared in -.Nx 1.4 . -.Dv EL_RPROMPT -appeared in -.Nx 1.5 . -.Sh AUTHORS -The -.Nm -library was written by Christos Zoulas. -Luke Mewburn wrote this manual and implemented -.Dv CC_REDISPLAY , -.Dv CC_REFRESH_BEEP , -.Dv EL_EDITMODE , -and -.Dv EL_RPROMPT . -Jaromir Dolecek implemented the readline emulation. -.Sh BUGS -The tokenization functions are not publically defined in -.Fd . -.Pp -At this time, it is the responsibility of the caller to -check the result of the -.Dv EL_EDITMODE -operation of -.Fn el_get -(after an -.Fn el_source -or -.Fn el_parse ) -to determine if -.Nm -should be used for further input. -I.e., -.Dv EL_EDITMODE -is purely an indication of the result of the most recent -.Xr editrc 5 -.Ic edit -command. diff --git a/cmd-line-utils/libedit/editrc.5 b/cmd-line-utils/libedit/editrc.5 deleted file mode 100644 index b1122618939..00000000000 --- a/cmd-line-utils/libedit/editrc.5 +++ /dev/null @@ -1,491 +0,0 @@ -.\" $NetBSD: editrc.5,v 1.11 2001/06/19 13:42:09 wiz Exp $ -.\" -.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. -.\" -.\" 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. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. -.\" -.Dd November 8, 2000 -.Os -.Dt EDITRC 5 -.Sh NAME -.Nm editrc -.Nd configuration file for editline library -.Sh SYNOPSIS -.Nm -.Sh DESCRIPTION -The -.Nm -file defines various settings to be used by the -.Xr editline 3 -library. -.Pp -The format of each line is: -.Dl [prog:]command [arg [...]] -.Pp -.Ar command -is one of the -.Xr editline 3 -builtin commands. -Refer to -.Sx BUILTIN COMMANDS -for more information. -.Pp -.Ar prog -is the program name string that a program defines when it calls -.Xr el_init 3 -to setup -.Xr editline 3 , -which is usually -.Va argv[0] . -.Ar command -will be executed for any program which matches -.Ar prog . -.Pp -.Ar prog -may also be a -.Xr regex 3 -style -regular expression, in which case -.Ar command -will be executed for any program that matches the regular expression. -.Pp -If -.Ar prog -is absent, -.Ar command -is executed for all programs. -.Sh BUILTIN COMMANDS -The -.Nm editline -library has some builtin commands, which affect the way -that the line editing and history functions operate. -These are based on similar named builtins present in the -.Xr tcsh 1 -shell. -.Pp -The following builtin commands are available: -.Bl -tag -width 4n -.It Ic bind Xo -.Op Fl a -.Op Fl e -.Op Fl k -.Op Fl l -.Op Fl r -.Op Fl s -.Op Fl v -.Op Ar key Op Ar command -.Xc -Without options, list all bound keys, and the editor command to which -each is bound. -If -.Ar key -is supplied, show the bindings for -.Ar key . -If -.Ar key command -is supplied, bind -.Ar command -to -.Ar key . -Options include: -.Bl -tag -width 4n -.It Fl e -Bind all keys to the standard GNU Emacs-like bindings. -.It Fl v -Bind all keys to the standard -.Xr vi 1 -like -bindings. -.It Fl a -List or change key bindings in the -.Xr vi 1 -mode alternate (command mode) key map. -.It Fl k -.Ar key -is interpreted as a symbolic arrow key name, which may be one of -.Sq up , -.Sq down , -.Sq left -or -.Sq right . -.It Fl l -List all editor commands and a short description of each. -.It Fl r -Remove a key's binding. -.It Fl s -.Ar command -is taken as a literal string and treated as terminal input when -.Ar key -is typed. -Bound keys in -.Ar command -are themselves reinterpreted, and this continues for ten levels of -interpretation. -.El -.Pp -.Ar command -may be one of the commands documented in -.Sx "EDITOR COMMANDS" -below, or another key. -.Pp -.Ar key -and -.Ar command -can contain control characters of the form -.Sm off -.Sq No ^ Ar character -.Sm on -.Po -e.g. -.Sq ^A -.Pc , -and the following backslashed escape sequences: -.Pp -.Bl -tag -compact -offset indent -width 4n -.It Ic \ea -Bell -.It Ic \eb -Backspace -.It Ic \ee -Escape -.It Ic \ef -Formfeed -.It Ic \en -Newline -.It Ic \er -Carriage return -.It Ic \et -Horizontal tab -.It Ic \ev -Vertical tab -.Sm off -.It Sy \e Ar nnn -.Sm on -The ASCII character corresponding to the octal number -.Ar nnn . -.El -.Pp -.Sq \e -nullifies the special meaning of the following character, -if it has any, notably -.Sq \e -and -.Sq ^ . -.It Ic echotc Xo -.Op Fl sv -.Ar arg -.Ar ... -.Xc -Exercise terminal capabilities given in -.Ar arg Ar ... . -If -.Ar arg -is -.Sq baud , -.Sq cols , -.Sq lines , -.Sq rows , -.Sq meta or -.Sq tabs , -the value of that capability is printed, with -.Dq yes -or -.Dq no -indicating that the terminal does or does not have that capability. -.Pp -.Fl s -returns an emptry string for non-existent capabilities, rather than -causing an error. -.Fl v -causes messages to be verbose. -.It Ic edit Op Li on | Li off -Enable or disable the -.Nm editline -functionality in a program. -.It Ic history -List the history. -.It Ic telltc -List the values of all the terminal capabilities (see -.Xr termcap 5 ). -.It Ic settc Ar cap Ar val -Set the terminal capability -.Ar cap -to -.Ar val , -as defined in -.Xr termcap 5 . -No sanity checking is done. -.It Ic setty Xo -.Op Fl a -.Op Fl d -.Op Fl q -.Op Fl x -.Op Ar +mode -.Op Ar -mode -.Op Ar mode -.Xc -Control which tty modes that -.Nm -won't allow the user to change. -.Fl d , -.Fl q -or -.Fl x -tells -.Ic setty -to act on the -.Sq edit , -.Sq quote -or -.Sq execute -set of tty modes respectively; defaulting to -.Fl x . -.Pp -Without other arguments, -.Ic setty -lists the modes in the chosen set which are fixed on -.Po -.Sq +mode -.Pc -or off -.Po -.Sq -mode -.Pc . -.Fl a -lists all tty modes in the chosen set regardless of the setting. -With -.Ar +mode , -.Ar -mode -or -.Ar mode , -fixes -.Ar mode -on or off or removes control of -.Ar mode -in the chosen set. -.El -.Sh EDITOR COMMANDS -The following editor commands are available for use in key bindings: -.\" Section automatically generated with makelist -.Bl -tag -width 4n -.It Ic vi-paste-next -Vi paste previous deletion to the right of the cursor. -.It Ic vi-paste-prev -Vi paste previous deletion to the left of the cursor. -.It Ic vi-prev-space-word -Vi move to the previous space delimited word. -.It Ic vi-prev-word -Vi move to the previous word. -.It Ic vi-next-space-word -Vi move to the next space delimited word. -.It Ic vi-next-word -Vi move to the next word. -.It Ic vi-change-case -Vi change case of character under the cursor and advance one character. -.It Ic vi-change-meta -Vi change prefix command. -.It Ic vi-insert-at-bol -Vi enter insert mode at the beginning of line. -.It Ic vi-replace-char -Vi replace character under the cursor with the next character typed. -.It Ic vi-replace-mode -Vi enter replace mode. -.It Ic vi-substitute-char -Vi replace character under the cursor and enter insert mode. -.It Ic vi-substitute-line -Vi substitute entire line. -.It Ic vi-change-to-eol -Vi change to end of line. -.It Ic vi-insert -Vi enter insert mode. -.It Ic vi-add -Vi enter insert mode after the cursor. -.It Ic vi-add-at-eol -Vi enter insert mode at end of line. -.It Ic vi-delete-meta -Vi delete prefix command. -.It Ic vi-end-word -Vi move to the end of the current space delimited word. -.It Ic vi-to-end-word -Vi move to the end of the current word. -.It Ic vi-undo -Vi undo last change. -.It Ic vi-command-mode -Vi enter command mode (use alternative key bindings). -.It Ic vi-zero -Vi move to the beginning of line. -.It Ic vi-delete-prev-char -Vi move to previous character (backspace). -.It Ic vi-list-or-eof -Vi list choices for completion or indicate end of file if empty line. -.It Ic vi-kill-line-prev -Vi cut from beginning of line to cursor. -.It Ic vi-search-prev -Vi search history previous. -.It Ic vi-search-next -Vi search history next. -.It Ic vi-repeat-search-next -Vi repeat current search in the same search direction. -.It Ic vi-repeat-search-prev -Vi repeat current search in the opposite search direction. -.It Ic vi-next-char -Vi move to the character specified next. -.It Ic vi-prev-char -Vi move to the character specified previous. -.It Ic vi-to-next-char -Vi move up to the character specified next. -.It Ic vi-to-prev-char -Vi move up to the character specified previous. -.It Ic vi-repeat-next-char -Vi repeat current character search in the same search direction. -.It Ic vi-repeat-prev-char -Vi repeat current character search in the opposite search direction. -.It Ic em-delete-or-list -Delete character under cursor or list completions if at end of line. -.It Ic em-delete-next-word -Cut from cursor to end of current word. -.It Ic em-yank -Paste cut buffer at cursor position. -.It Ic em-kill-line -Cut the entire line and save in cut buffer. -.It Ic em-kill-region -Cut area between mark and cursor and save in cut buffer. -.It Ic em-copy-region -Copy area between mark and cursor to cut buffer. -.It Ic em-gosmacs-traspose -Exchange the two characters before the cursor. -.It Ic em-next-word -Move next to end of current word. -.It Ic em-upper-case -Uppercase the characters from cursor to end of current word. -.It Ic em-capitol-case -Capitalize the characters from cursor to end of current word. -.It Ic em-lower-case -Lowercase the characters from cursor to end of current word. -.It Ic em-set-mark -Set the mark at cursor. -.It Ic em-exchange-mark -Exchange the cursor and mark. -.It Ic em-universal-argument -Universal argument (argument times 4). -.It Ic em-meta-next -Add 8th bit to next character typed. -.It Ic em-toggle-overwrite -Switch from insert to overwrite mode or vice versa. -.It Ic em-copy-prev-word -Copy current word to cursor. -.It Ic em-inc-search-next -Emacs incremental next search. -.It Ic em-inc-search-prev -Emacs incremental reverse search. -.It Ic ed-end-of-file -Indicate end of file. -.It Ic ed-insert -Add character to the line. -.It Ic ed-delete-prev-word -Delete from beginning of current word to cursor. -.It Ic ed-delete-next-char -Delete character under cursor. -.It Ic ed-kill-line -Cut to the end of line. -.It Ic ed-move-to-end -Move cursor to the end of line. -.It Ic ed-move-to-beg -Move cursor to the beginning of line. -.It Ic ed-transpose-chars -Exchange the character to the left of the cursor with the one under it. -.It Ic ed-next-char -Move to the right one character. -.It Ic ed-prev-word -Move to the beginning of the current word. -.It Ic ed-prev-char -Move to the left one character. -.It Ic ed-quoted-insert -Add the next character typed verbatim. -.It Ic ed-digit -Adds to argument or enters a digit. -.It Ic ed-argument-digit -Digit that starts argument. -.It Ic ed-unassigned -Indicates unbound character. -.It Ic ed-tty-sigint -Tty interrupt character. -.It Ic ed-tty-dsusp -Tty delayed suspend character. -.It Ic ed-tty-flush-output -Tty flush output characters. -.It Ic ed-tty-sigquit -Tty quit character. -.It Ic ed-tty-sigtstp -Tty suspend character. -.It Ic ed-tty-stop-output -Tty disallow output characters. -.It Ic ed-tty-start-output -Tty allow output characters. -.It Ic ed-newline -Execute command. -.It Ic ed-delete-prev-char -Delete the character to the left of the cursor. -.It Ic ed-clear-screen -Clear screen leaving current line at the top. -.It Ic ed-redisplay -Redisplay everything. -.It Ic ed-start-over -Erase current line and start from scratch. -.It Ic ed-sequence-lead-in -First character in a bound sequence. -.It Ic ed-prev-history -Move to the previous history line. -.It Ic ed-next-history -Move to the next history line. -.It Ic ed-search-prev-history -Search previous in history for a line matching the current. -.It Ic ed-search-next-history -Search next in history for a line matching the current. -.It Ic ed-prev-line -Move up one line. -.It Ic ed-next-line -Move down one line. -.It Ic ed-command -Editline extended command. -.El -.\" End of section automatically generated with makelist -.Sh SEE ALSO -.Xr editline 3 , -.Xr regex 3 , -.Xr termcap 5 -.Sh AUTHORS -The -.Nm editline -library was written by Christos Zoulas, -and this manual was written by Luke Mewburn, -with some sections inspired by -.Xr tcsh 1 . diff --git a/cmd-line-utils/libedit/fgetln.c b/cmd-line-utils/libedit/fgetln.c deleted file mode 100644 index 5b95b2f6584..00000000000 --- a/cmd-line-utils/libedit/fgetln.c +++ /dev/null @@ -1,88 +0,0 @@ -/* $NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 -#include -#include -#include -#include -#include - - -char * -fgetln(FILE *fp, size_t *len) -{ - static char *buf = NULL; - static size_t bufsiz = 0; - char *ptr; - - - if (buf == NULL) { - bufsiz = BUFSIZ; - if ((buf = malloc(bufsiz)) == NULL) - return NULL; - } - - if (fgets(buf, bufsiz, fp) == NULL) - return NULL; - *len = 0; - - while ((ptr = strchr(&buf[*len], '\n')) == NULL) { - size_t nbufsiz = bufsiz + BUFSIZ; - char *nbuf = realloc(buf, nbufsiz); - - if (nbuf == NULL) { - int oerrno = errno; - free(buf); - errno = oerrno; - buf = NULL; - return NULL; - } else - buf = nbuf; - - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) - return buf; - - bufsiz = nbufsiz; - } - - *len = (ptr - buf) + 1; - return buf; -} - diff --git a/cmd-line-utils/libedit/fgetln.h b/cmd-line-utils/libedit/fgetln.h deleted file mode 100644 index b2ddce01da9..00000000000 --- a/cmd-line-utils/libedit/fgetln.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -char *fgetln(FILE *stream, size_t *len); diff --git a/cmd-line-utils/libedit/libedit_term.h b/cmd-line-utils/libedit/libedit_term.h deleted file mode 100644 index 9f03c549515..00000000000 --- a/cmd-line-utils/libedit/libedit_term.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $NetBSD: term.h,v 1.12 2001/01/04 15:56:32 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)term.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.term.h: Termcap header - */ -#ifndef _h_el_term -#define _h_el_term - -#include "histedit.h" - -typedef struct { /* Symbolic function key bindings */ - const char *name; /* name of the key */ - int key; /* Index in termcap table */ - key_value_t fun; /* Function bound to it */ - int type; /* Type of function */ -} fkey_t; - -typedef struct { - coord_t t_size; /* # lines and cols */ - int t_flags; -#define TERM_CAN_INSERT 0x001 /* Has insert cap */ -#define TERM_CAN_DELETE 0x002 /* Has delete cap */ -#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ -#define TERM_CAN_TAB 0x008 /* Can use tabs */ -#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ -#define TERM_CAN_UP 0x020 /* Can move up */ -#define TERM_HAS_META 0x040 /* Has a meta key */ -#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ -#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ - char *t_buf; /* Termcap buffer */ - int t_loc; /* location used */ - char **t_str; /* termcap strings */ - int *t_val; /* termcap values */ - char *t_cap; /* Termcap buffer */ - fkey_t *t_fkey; /* Array of keys */ -} el_term_t; - -/* - * fKey indexes - */ -#define A_K_DN 0 -#define A_K_UP 1 -#define A_K_LT 2 -#define A_K_RT 3 -#define A_K_HO 4 -#define A_K_EN 5 -#define A_K_NKEYS 6 - -protected void term_move_to_line(EditLine *, int); -protected void term_move_to_char(EditLine *, int); -protected void term_clear_EOL(EditLine *, int); -protected void term_overwrite(EditLine *, const char *, int); -protected void term_insertwrite(EditLine *, char *, int); -protected void term_deletechars(EditLine *, int); -protected void term_clear_screen(EditLine *); -protected void term_beep(EditLine *); -protected int term_change_size(EditLine *, int, int); -protected int term_get_size(EditLine *, int *, int *); -protected int term_init(EditLine *); -protected void term_bind_arrow(EditLine *); -protected void term_print_arrow(EditLine *, const char *); -protected int term_clear_arrow(EditLine *, const char *); -protected int term_set_arrow(EditLine *, const char *, key_value_t *, int); -protected void term_end(EditLine *); -protected int term_set(EditLine *, const char *); -protected int term_settc(EditLine *, int, const char **); -protected int term_telltc(EditLine *, int, const char **); -protected int term_echotc(EditLine *, int, const char **); -protected int term__putc(int); -protected void term__flush(void); - -/* - * Easy access macros - */ -#define EL_FLAGS (el)->el_term.t_flags - -#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) -#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) -#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) -#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) -#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) -#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) -#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) -#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) - -#endif /* _h_el_term */ diff --git a/cmd-line-utils/libedit/strlcpy.c b/cmd-line-utils/libedit/strlcpy.c deleted file mode 100644 index e38d6cf1c4b..00000000000 --- a/cmd-line-utils/libedit/strlcpy.c +++ /dev/null @@ -1,73 +0,0 @@ -/* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */ -/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include - -#ifdef _LIBC -# ifdef __weak_alias -__weak_alias(strlcpy, _strlcpy) -# endif -#endif - -#if !HAVE_STRLCPY -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -#ifdef _LIBC -_strlcpy(dst, src, siz) -#else -strlcpy(dst, src, siz) -#endif - char *dst; - const char *src; - size_t siz; -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/cmd-line-utils/libedit/strlcpy.h b/cmd-line-utils/libedit/strlcpy.h deleted file mode 100644 index e4d3a7ffa3f..00000000000 --- a/cmd-line-utils/libedit/strlcpy.h +++ /dev/null @@ -1,2 +0,0 @@ -size_t strlcpy(char *dst, const char *src, size_t size); -size_t strlcat(char *dst, const char *src, size_t size); diff --git a/cmd-line-utils/libedit/tokenizer.h b/cmd-line-utils/libedit/tokenizer.h deleted file mode 100644 index 7cc7a3346e4..00000000000 --- a/cmd-line-utils/libedit/tokenizer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: tokenizer.h,v 1.5 2002/03/18 16:01:00 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)tokenizer.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * tokenizer.h: Header file for tokenizer routines - */ -#ifndef _h_tokenizer -#define _h_tokenizer - -typedef struct tokenizer Tokenizer; - -Tokenizer *tok_init(const char *); -void tok_reset(Tokenizer *); -void tok_end(Tokenizer *); -int tok_line(Tokenizer *, const char *, int *, const char ***); - -#endif /* _h_tokenizer */ diff --git a/cmd-line-utils/libedit/unvis.c b/cmd-line-utils/libedit/unvis.c deleted file mode 100644 index ffa8ac4251c..00000000000 --- a/cmd-line-utils/libedit/unvis.c +++ /dev/null @@ -1,311 +0,0 @@ -/* $NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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 - -#define __LIBC12_SOURCE__ - -#include - -#include -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strunvis,_strunvis) -__weak_alias(unvis,_unvis) -#endif - -#ifdef __warn_references -__warn_references(unvis, - "warning: reference to compatibility unvis(); include for correct reference") -#endif - -#if !HAVE_VIS -/* - * decode driven by state machine - */ -#define S_GROUND 0 /* haven't seen escape char */ -#define S_START 1 /* start decoding special sequence */ -#define S_META 2 /* metachar started (M) */ -#define S_META1 3 /* metachar more, regular char (-) */ -#define S_CTRL 4 /* control char started (^) */ -#define S_OCTAL2 5 /* octal digit 2 */ -#define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX1 7 /* hex digit */ -#define S_HEX2 8 /* hex digit 2 */ - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) - -int -unvis(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ - return __unvis13(cp, (int)c, astate, flag); -} - -/* - * unvis - decode characters previously encoded by vis - */ -int -__unvis13(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; -{ - - _DIAGASSERT(cp != NULL); - _DIAGASSERT(astate != NULL); - - if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3 - || *astate == S_HEX2) { - *astate = S_GROUND; - return (UNVIS_VALID); - } - return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); - } - - switch (*astate) { - - case S_GROUND: - *cp = 0; - if (c == '\\') { - *astate = S_START; - return (0); - } - if ((flag & VIS_HTTPSTYLE) && c == '%') { - *astate = S_HEX1; - return (0); - } - *cp = c; - return (UNVIS_VALID); - - case S_START: - switch(c) { - case '\\': - *cp = c; - *astate = S_GROUND; - return (UNVIS_VALID); - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - *cp = (c - '0'); - *astate = S_OCTAL2; - return (0); - case 'M': - *cp = (char)0200; - *astate = S_META; - return (0); - case '^': - *astate = S_CTRL; - return (0); - case 'n': - *cp = '\n'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'r': - *cp = '\r'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'b': - *cp = '\b'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'a': - *cp = '\007'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'v': - *cp = '\v'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 't': - *cp = '\t'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'f': - *cp = '\f'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 's': - *cp = ' '; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'E': - *cp = '\033'; - *astate = S_GROUND; - return (UNVIS_VALID); - case '\n': - /* - * hidden newline - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - case '$': - /* - * hidden marker - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - } - *astate = S_GROUND; - return (UNVIS_SYNBAD); - - case S_META: - if (c == '-') - *astate = S_META1; - else if (c == '^') - *astate = S_CTRL; - else { - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } - return (0); - - case S_META1: - *astate = S_GROUND; - *cp |= c; - return (UNVIS_VALID); - - case S_CTRL: - if (c == '?') - *cp |= 0177; - else - *cp |= c & 037; - *astate = S_GROUND; - return (UNVIS_VALID); - - case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { - /* - * yes - and maybe a third - */ - *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; - return (0); - } - /* - * no - done with current sequence, push back passed char - */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); - - case S_OCTAL3: /* third possible octal digit */ - *astate = S_GROUND; - if (isoctal(c)) { - *cp = (*cp << 3) + (c - '0'); - return (UNVIS_VALID); - } - /* - * we were done, push back passed char - */ - return (UNVIS_VALIDPUSH); - case S_HEX1: - if (isxdigit(c)) { - *cp = xtod(c); - *astate = S_HEX2; - return (0); - } - /* - * no - done with current sequence, push back passed char - */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); - case S_HEX2: - *astate = S_GROUND; - if (isxdigit(c)) { - *cp = xtod(c) | (*cp << 4); - return (UNVIS_VALID); - } - return (UNVIS_VALIDPUSH); - default: - /* - * decoder in unknown state - (probably uninitialized) - */ - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } -} - -/* - * strunvis - decode src into dst - * - * Number of chars decoded into dst is returned, -1 on error. - * Dst is null terminated. - */ - -int -strunvisx(dst, src, flag) - char *dst; - const char *src; - int flag; -{ - char c; - char *start = dst; - int state = 0; - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - while ((c = *src++) != '\0') { - again: - switch (__unvis13(dst, c, &state, flag)) { - case UNVIS_VALID: - dst++; - break; - case UNVIS_VALIDPUSH: - dst++; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - default: - return (-1); - } - } - if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; - *dst = '\0'; - return (dst - start); -} - -int -strunvis(dst, src) - char *dst; - const char *src; -{ - return strunvisx(dst, src, 0); -} -#endif diff --git a/cmd-line-utils/libedit/vis.c b/cmd-line-utils/libedit/vis.c deleted file mode 100644 index 127d28733a8..00000000000 --- a/cmd-line-utils/libedit/vis.c +++ /dev/null @@ -1,392 +0,0 @@ -/* $NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (__GNUC__) - #pragma alloca -#endif - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca(n) __builtin_alloca (n) -#else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifndef _AIX -extern char *alloca (); -# endif -# endif -#endif - -#include - -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strsvis,_strsvis) -__weak_alias(strsvisx,_strsvisx) -__weak_alias(strvis,_strvis) -__weak_alias(strvisx,_strvisx) -__weak_alias(svis,_svis) -__weak_alias(vis,_vis) -#endif - -#if !HAVE_VIS || !HAVE_SVIS -#include -#include -#include -#include - -#undef BELL -#define BELL '\a' - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') -#define issafe(c) (c == '\b' || c == BELL || c == '\r') -#define xtoa(c) "0123456789abcdef"[c] - -#define MAXEXTRAS 5 - - -#define MAKEEXTRALIST(flag, extra, orig) \ -do { \ - const char *o = orig; \ - char *e; \ - while (*o++) \ - continue; \ - extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \ - for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ - continue; \ - e--; \ - if (flag & VIS_SP) *e++ = ' '; \ - if (flag & VIS_TAB) *e++ = '\t'; \ - if (flag & VIS_NL) *e++ = '\n'; \ - if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ - *e = '\0'; \ -} while (/*CONSTCOND*/0) - - -/* - * This is HVIS, the macro of vis used to HTTP style (RFC 1808) - */ -#define HVIS(dst, c, flag, nextc, extra) \ -do \ - if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ - *dst++ = '%'; \ - *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ - *dst++ = xtoa((unsigned int)c & 0xf); \ - } else { \ - SVIS(dst, c, flag, nextc, extra); \ - } \ -while (/*CONSTCOND*/0) - -/* - * This is SVIS, the central macro of vis. - * dst: Pointer to the destination buffer - * c: Character to encode - * flag: Flag word - * nextc: The character following 'c' - * extra: Pointer to the list of extra characters to be - * backslash-protected. - */ -#define SVIS(dst, c, flag, nextc, extra) \ -do { \ - int isextra; \ - isextra = strchr(extra, c) != NULL; \ - if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ - ((flag & VIS_SAFE) && issafe(c)))) { \ - *dst++ = c; \ - break; \ - } \ - if (flag & VIS_CSTYLE) { \ - switch (c) { \ - case '\n': \ - *dst++ = '\\'; *dst++ = 'n'; \ - continue; \ - case '\r': \ - *dst++ = '\\'; *dst++ = 'r'; \ - continue; \ - case '\b': \ - *dst++ = '\\'; *dst++ = 'b'; \ - continue; \ - case BELL: \ - *dst++ = '\\'; *dst++ = 'a'; \ - continue; \ - case '\v': \ - *dst++ = '\\'; *dst++ = 'v'; \ - continue; \ - case '\t': \ - *dst++ = '\\'; *dst++ = 't'; \ - continue; \ - case '\f': \ - *dst++ = '\\'; *dst++ = 'f'; \ - continue; \ - case ' ': \ - *dst++ = '\\'; *dst++ = 's'; \ - continue; \ - case '\0': \ - *dst++ = '\\'; *dst++ = '0'; \ - if (isoctal(nextc)) { \ - *dst++ = '0'; \ - *dst++ = '0'; \ - } \ - continue; \ - default: \ - if (isgraph(c)) { \ - *dst++ = '\\'; *dst++ = c; \ - continue; \ - } \ - } \ - } \ - if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ - *dst++ = '\\'; \ - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \ - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \ - *dst++ = (c & 07) + '0'; \ - } else { \ - if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ - if (c & 0200) { \ - c &= 0177; *dst++ = 'M'; \ - } \ - if (iscntrl(c)) { \ - *dst++ = '^'; \ - if (c == 0177) \ - *dst++ = '?'; \ - else \ - *dst++ = c + '@'; \ - } else { \ - *dst++ = '-'; *dst++ = c; \ - } \ - } \ -} while (/*CONSTCOND*/0) - - -/* - * svis - visually encode characters, also encoding the characters - * pointed to by `extra' - */ -char * -svis(dst, c, flag, nextc, extra) - char *dst; - int c, flag, nextc; - const char *extra; -{ - char *nextra; - _DIAGASSERT(dst != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, nextra); - else - SVIS(dst, c, flag, nextc, nextra); - *dst = '\0'; - return(dst); -} - - -/* - * strsvis, strsvisx - visually encode characters from src into dst - * - * Extra is a pointer to a \0-terminated list of characters to - * be encoded, too. These functions are useful e. g. to - * encode strings in such a way so that they are not interpreted - * by a shell. - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strsvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. - */ -int -strsvis(dst, csrc, flag, extra) - char *dst; - const char *csrc; - int flag; - const char *extra; -{ - int c; - char *start; - char *nextra; - const unsigned char *src = (const unsigned char *)csrc; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - if (flag & VIS_HTTPSTYLE) { - for (start = dst; (c = *src++) != '\0'; /* empty */) - HVIS(dst, c, flag, *src, nextra); - } else { - for (start = dst; (c = *src++) != '\0'; /* empty */) - SVIS(dst, c, flag, *src, nextra); - } - *dst = '\0'; - return (dst - start); -} - - -int -strsvisx(dst, csrc, len, flag, extra) - char *dst; - const char *csrc; - size_t len; - int flag; - const char *extra; -{ - int c; - char *start; - char *nextra; - const unsigned char *src = (const unsigned char *)csrc; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - _DIAGASSERT(extra != NULL); - MAKEEXTRALIST(flag, nextra, extra); - - if (flag & VIS_HTTPSTYLE) { - for (start = dst; len > 0; len--) { - c = *src++; - HVIS(dst, c, flag, len ? *src : '\0', nextra); - } - } else { - for (start = dst; len > 0; len--) { - c = *src++; - SVIS(dst, c, flag, len ? *src : '\0', nextra); - } - } - *dst = '\0'; - return (dst - start); -} -#endif - -#if !HAVE_VIS -/* - * vis - visually encode characters - */ -char * -vis(dst, c, flag, nextc) - char *dst; - int c, flag, nextc; - -{ - char *extra; - - _DIAGASSERT(dst != NULL); - - MAKEEXTRALIST(flag, extra, ""); - if (flag & VIS_HTTPSTYLE) - HVIS(dst, c, flag, nextc, extra); - else - SVIS(dst, c, flag, nextc, extra); - *dst = '\0'; - return (dst); -} - - -/* - * strvis, strvisx - visually encode characters from src into dst - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. - */ -int -strvis(dst, src, flag) - char *dst; - const char *src; - int flag; -{ - char *extra; - - MAKEEXTRALIST(flag, extra, ""); - return (strsvis(dst, src, flag, extra)); -} - - -int -strvisx(dst, src, len, flag) - char *dst; - const char *src; - size_t len; - int flag; -{ - char *extra; - - MAKEEXTRALIST(flag, extra, ""); - return (strsvisx(dst, src, len, flag, extra)); -} -#endif diff --git a/cmd-line-utils/libedit/vis.h b/cmd-line-utils/libedit/vis.h deleted file mode 100644 index 44f6fc7d785..00000000000 --- a/cmd-line-utils/libedit/vis.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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. - * - * @(#)vis.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _VIS_H_ -#define _VIS_H_ - -#include - -/* - * to select alternate encoding format - */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */ - -/* - * to alter set of characters encoded (default is to encode all - * non-graphic except space, tab, and newline). - */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ -#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ - -/* - * other - */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ - -/* - * unvis return codes - */ -#define UNVIS_VALID 1 /* character valid */ -#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ -#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ -#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ -#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ - -/* - * unvis flags - */ -#define UNVIS_END 1 /* no more characters */ - -__BEGIN_DECLS -char *vis(char *, int, int, int); -char *svis(char *, int, int, int, const char *); -int strvis(char *, const char *, int); -int strsvis(char *, const char *, int, const char *); -int strvisx(char *, const char *, size_t, int); -int strsvisx(char *, const char *, size_t, int, const char *); -int strunvis(char *, const char *); -int strunvisx(char *, const char *, int); -#ifdef __LIBC12_SOURCE__ -int unvis(char *, int, int *, int); -int __unvis13(char *, int, int *, int); -#else -int unvis(char *, int, int *, int); -#endif -__END_DECLS - -#endif /* !_VIS_H_ */ diff --git a/mysql-test/include/count_sessions.inc b/mysql-test/include/count_sessions.inc new file mode 100644 index 00000000000..4728e39ce74 --- /dev/null +++ b/mysql-test/include/count_sessions.inc @@ -0,0 +1,21 @@ +# include/count_sessions.inc +# +# SUMMARY +# +# Stores the number of current sessions in $count_sessions. +# +# +# USAGE +# +# Please look into include/wait_until_count_sessions.inc +# for examples of typical usage. +# +# +# EXAMPLE +# backup.test, grant3.test +# +# +# Created: 2009-01-14 mleich +# + +let $count_sessions= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); diff --git a/mysql-test/include/wait_until_count_sessions.inc b/mysql-test/include/wait_until_count_sessions.inc new file mode 100644 index 00000000000..56d2b0b1dcd --- /dev/null +++ b/mysql-test/include/wait_until_count_sessions.inc @@ -0,0 +1,126 @@ +# include/wait_until_count_sessions.inc +# +# SUMMARY +# +# Waits until the passed number ($count_sessions) of concurrent sessions or +# a smaller number was observed via +# SHOW STATUS LIKE 'Threads_connected' +# or the operation times out. +# Note: +# 1. We wait for $current_sessions <= $count_sessions because in the use case +# with count_sessions.inc before and wait_until_count_sessions.inc after +# the core of the test it could happen that the disconnects of sessions +# belonging to the preceeding test are not finished. +# sessions at test begin($count_sessions) = m + n +# sessions of the previous test which will be soon disconnected = n (n >= 0) +# sessions at test end ($current sessions, assuming the test disconnects +# all additional sessions) = m +# 2. Starting with 5.1 we could also use +# SELECT COUNT(*) FROM information_schema.processlist +# I stay with "SHOW STATUS LIKE 'Threads_connected'" because this +# runs in all versions 5.0+ +# +# +# USAGE +# +# let $count_sessions= 3; +# --source include/wait_until_count_sessions.inc +# +# OR typical example of a test which uses more than one session +# Such a test could harm successing tests if there is no server shutdown +# and start between. +# +# If the testing box is slow than the disconnect of sessions belonging to +# the current test might happen when the successing test gets executed. +# This means the successing test might see activities like unexpected +# rows within the general log or the PROCESSLIST. +# Example from bug http://bugs.mysql.com/bug.php?id=40377 +# --- bzr_mysql-6.0-rpl/.../r/log_state.result +# +++ bzr_mysql-6.0-rpl/.../r/log_state.reject +# @@ -25,6 +25,7 @@ +# event_time user_host ... command_type argument +# TIMESTAMP USER_HOST ... Query create table t1(f1 int) +# TIMESTAMP USER_HOST ... Query select * from mysql.general_log +# +TIMESTAMP USER_HOST ... Quit +# .... +# +# What to do? +# ----------- +# +# # Determine initial number of connections (set $count_sessions) +# --source include/count_sessions.inc +# ... +# connect (con1,.....) +# ... +# connection default; +# ... +# disconnect con1; +# ... +# # Wait until we have reached the initial number of connections +# # or more than the sleep time above (10 seconds) has passed. +# # $count_sessions +# --source include/wait_until_count_sessions.inc +# +# +# Important note about tests with unfortunate (= not cooperative +# to successing tests) architecture: +# connection con1; +# send SELECT ..., sleep(10) +# connection default; +# ... +# disconnect con1; +# +# should be fixed by +# connection con1; +# send SELECT ..., sleep(10) +# connection default; +# ... +# connect con1; +# reap; +# connection default; +# disconnect con1; +# +# and not only by appending include/wait_until_count_sessions.inc etc. +# +# +# EXAMPLE +# +# backup.test, grant3.test +# +# +# Created: +# 2009-01-14 mleich +# Modified: +# 2009-02-24 mleich Fix Bug#43114 wait_until_count_sessions too restrictive, +# random PB failures +# + +let $wait_counter= 100; +if ($wait_timeout) +{ + let $wait_counter= `SELECT $wait_timeout * 10`; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; +while ($wait_counter) +{ + let $current_sessions= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); + let $success= `SELECT $current_sessions <= $count_sessions`; + if ($success) + { + let $wait_counter= 0; + } + if (!$success) + { + real_sleep 0.1; + dec $wait_counter; + } +} +if (!$success) +{ + --echo # Timeout in wait_until_count_sessions.inc + --echo # Number of sessions expected: <= $count_sessions found: $current_sessions + SHOW PROCESSLIST; +} + diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 22a9e941241..c31b5ea2189 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1348,12 +1348,12 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*' drop table t1; -CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; SHOW CREATE TABLE t3; Table Create Table t3 CREATE TABLE `t3` ( `f1` int(11) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן' DROP TABLE t3; set sql_mode= 'traditional'; create table t1(col1 tinyint, col2 tinyint unsigned, diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 877da3f2b37..f66c2913ac9 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1204,7 +1204,7 @@ drop table t1; # #60 chars, 120 (+1) bytes (UTF-8 with 2-byte chars) -CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; +CREATE TABLE t3 (f1 INT) COMMENT 'כקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחןכקבהחן'; SHOW CREATE TABLE t3; DROP TABLE t3; From 6d7f876a881f9182d9728c6ac16c1b816255335b Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Sat, 9 May 2009 23:43:48 +0200 Subject: [PATCH 015/188] Use /usr/bin/perl as standard Perl install path (bug#44643) --- scripts/mysql_find_rows.sh | 2 +- scripts/mysql_fix_extensions.sh | 2 +- scripts/mysql_setpermission.sh | 2 +- scripts/mysql_zap.sh | 2 +- scripts/mysqlaccess.sh | 2 +- sql-bench/as3ap.sh | 2 +- sql-bench/bench-count-distinct.sh | 2 +- sql-bench/bench-init.pl.sh | 2 +- sql-bench/compare-results.sh | 2 +- sql-bench/copy-db.sh | 2 +- sql-bench/crash-me.sh | 2 +- sql-bench/innotest1.sh | 2 +- sql-bench/innotest1a.sh | 2 +- sql-bench/innotest1b.sh | 2 +- sql-bench/innotest2.sh | 2 +- sql-bench/innotest2a.sh | 2 +- sql-bench/innotest2b.sh | 2 +- sql-bench/run-all-tests.sh | 2 +- sql-bench/server-cfg.sh | 2 +- sql-bench/test-ATIS.sh | 2 +- sql-bench/test-alter-table.sh | 2 +- sql-bench/test-big-tables.sh | 2 +- sql-bench/test-connect.sh | 2 +- sql-bench/test-create.sh | 2 +- sql-bench/test-insert.sh | 2 +- sql-bench/test-select.sh | 2 +- sql-bench/test-transactions.sh | 2 +- sql-bench/test-wisconsin.sh | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/scripts/mysql_find_rows.sh b/scripts/mysql_find_rows.sh index 77eacc8a9b4..967a8196ebd 100644 --- a/scripts/mysql_find_rows.sh +++ b/scripts/mysql_find_rows.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000, 2004 MySQL AB # # This program is free software; you can redistribute it and/or modify diff --git a/scripts/mysql_fix_extensions.sh b/scripts/mysql_fix_extensions.sh index fbc72406f5e..6d4e017f678 100644 --- a/scripts/mysql_fix_extensions.sh +++ b/scripts/mysql_fix_extensions.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # This is a utility for MySQL. It is not needed by any standard part # of MySQL. diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh index 1f5509f9955..9b49345175a 100644 --- a/scripts/mysql_setpermission.sh +++ b/scripts/mysql_setpermission.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ## Emacs, this is -*- perl -*- mode? :-) ## ## Permission setter for MySQL diff --git a/scripts/mysql_zap.sh b/scripts/mysql_zap.sh index 6c05afb772c..258e60dc356 100644 --- a/scripts/mysql_zap.sh +++ b/scripts/mysql_zap.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2002, 2004 MySQL AB # # This program is free software; you can redistribute it and/or modify diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh index bcaf9f8af8e..0153a3afa7c 100644 --- a/scripts/mysqlaccess.sh +++ b/scripts/mysqlaccess.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # **************************** package MySQLaccess; #use strict; diff --git a/sql-bench/as3ap.sh b/sql-bench/as3ap.sh index d84219a37eb..1c672377fd3 100644 --- a/sql-bench/as3ap.sh +++ b/sql-bench/as3ap.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/bench-count-distinct.sh b/sql-bench/bench-count-distinct.sh index 31558aa0b2e..5cc9fb555af 100644 --- a/sql-bench/bench-count-distinct.sh +++ b/sql-bench/bench-count-distinct.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh index 399c8cb9879..f16e773722f 100644 --- a/sql-bench/bench-init.pl.sh +++ b/sql-bench/bench-init.pl.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2003, 2005 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/compare-results.sh b/sql-bench/compare-results.sh index 145c4894ca2..fec65497c57 100644 --- a/sql-bench/compare-results.sh +++ b/sql-bench/compare-results.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/copy-db.sh b/sql-bench/copy-db.sh index f74fa68a081..e0c290d2453 100644 --- a/sql-bench/copy-db.sh +++ b/sql-bench/copy-db.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index b28bdba7f9f..cc8659513c2 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # -*- perl -*- # Copyright (C) 2000-2006 MySQL AB # diff --git a/sql-bench/innotest1.sh b/sql-bench/innotest1.sh index 8675de19ae4..1c5450a1d9e 100644 --- a/sql-bench/innotest1.sh +++ b/sql-bench/innotest1.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/InnoDB combined database # (c) 2002 Innobase Oy & MySQL AB diff --git a/sql-bench/innotest1a.sh b/sql-bench/innotest1a.sh index 93f8a2a443b..876100e5de4 100644 --- a/sql-bench/innotest1a.sh +++ b/sql-bench/innotest1a.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/InnoDB combined database # (c) 2002 Innobase Oy & MySQL AB diff --git a/sql-bench/innotest1b.sh b/sql-bench/innotest1b.sh index 48fe96ebe7d..3f6c9f5bd5f 100644 --- a/sql-bench/innotest1b.sh +++ b/sql-bench/innotest1b.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/InnoDB combined database # (c) 2002 Innobase Oy & MySQL AB diff --git a/sql-bench/innotest2.sh b/sql-bench/innotest2.sh index aea44003903..cfeb0527970 100644 --- a/sql-bench/innotest2.sh +++ b/sql-bench/innotest2.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/InnoDB combined database # (c) 2002 Innobase Oy & MySQL AB diff --git a/sql-bench/innotest2a.sh b/sql-bench/innotest2a.sh index 3d4bb9933da..f77ed3ddadd 100644 --- a/sql-bench/innotest2a.sh +++ b/sql-bench/innotest2a.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/Innobase combined database # (c) 2000 Innobase Oy & MySQL AB diff --git a/sql-bench/innotest2b.sh b/sql-bench/innotest2b.sh index 272b6dcffd0..72a71d06c73 100644 --- a/sql-bench/innotest2b.sh +++ b/sql-bench/innotest2b.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl ############################################################################ # Stress test for MySQL/Innobase combined database # (c) 2000 Innobase Oy & MySQL AB diff --git a/sql-bench/run-all-tests.sh b/sql-bench/run-all-tests.sh index 7e607b313e4..3338ea30df5 100644 --- a/sql-bench/run-all-tests.sh +++ b/sql-bench/run-all-tests.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index cd694169aa5..66d1b1591c0 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # -*- perl -*- # Copyright (C) 2000-2006 MySQL AB # diff --git a/sql-bench/test-ATIS.sh b/sql-bench/test-ATIS.sh index 6d102fd3977..79b38a95506 100644 --- a/sql-bench/test-ATIS.sh +++ b/sql-bench/test-ATIS.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-alter-table.sh b/sql-bench/test-alter-table.sh index eb06582dc0b..36db26f4bf3 100644 --- a/sql-bench/test-alter-table.sh +++ b/sql-bench/test-alter-table.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-big-tables.sh b/sql-bench/test-big-tables.sh index 0226967bc54..33694a42e17 100644 --- a/sql-bench/test-big-tables.sh +++ b/sql-bench/test-big-tables.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-connect.sh b/sql-bench/test-connect.sh index 84175c357aa..d0f3f0791a4 100644 --- a/sql-bench/test-connect.sh +++ b/sql-bench/test-connect.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-create.sh b/sql-bench/test-create.sh index bc2f17c1f0a..8c5bb0140fd 100644 --- a/sql-bench/test-create.sh +++ b/sql-bench/test-create.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh index 5189e8851e1..eb1856bda75 100644 --- a/sql-bench/test-insert.sh +++ b/sql-bench/test-insert.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh index 809755ab4d7..41e8205196e 100644 --- a/sql-bench/test-select.sh +++ b/sql-bench/test-select.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-transactions.sh b/sql-bench/test-transactions.sh index 5723c856564..edbfef0e3ce 100644 --- a/sql-bench/test-transactions.sh +++ b/sql-bench/test-transactions.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh index 38ab93e7f4a..1974461a7c4 100644 --- a/sql-bench/test-wisconsin.sh +++ b/sql-bench/test-wisconsin.sh @@ -1,4 +1,4 @@ -#!@PERL@ +#!/usr/bin/perl # Copyright (C) 2000-2001, 2003 MySQL AB # # This library is free software; you can redistribute it and/or From 99794e880121f4babaf33eb5851410a0919eeaa7 Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Tue, 12 May 2009 10:38:14 -0700 Subject: [PATCH 016/188] mysqldump would not dump the INFORMATION_SCHEMA even when it was explicitly requested. (Bug #33762) --- client/mysqldump.c | 18 +++++++++++++----- mysql-test/r/mysqldump.result | 36 ++++++++++++++++++++++++++++++++--- mysql-test/t/mysqldump.test | 10 +++++++--- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 323376dd8bf..efcb1820be4 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3813,6 +3813,10 @@ static int dump_all_databases() return 1; while ((row= mysql_fetch_row(tableres))) { + if (mysql_get_server_version(mysql) >= 50003 && + !my_strcasecmp(&my_charset_latin1, row[0], "information_schema")) + continue; + if (dump_all_tables_in_db(row[0])) result=1; } @@ -3827,6 +3831,10 @@ static int dump_all_databases() } while ((row= mysql_fetch_row(tableres))) { + if (mysql_get_server_version(mysql) >= 50003 && + !my_strcasecmp(&my_charset_latin1, row[0], "information_schema")) + continue; + if (dump_all_views_in_db(row[0])) result=1; } @@ -3933,10 +3941,6 @@ int init_dumping_tables(char *qdatabase) static int init_dumping(char *database, int init_func(char*)) { - if (mysql_get_server_version(mysql) >= 50003 && - !my_strcasecmp(&my_charset_latin1, database, "information_schema")) - return 1; - if (mysql_select_db(mysql, database)) { DB_error(mysql, "when selecting the database"); @@ -3995,6 +3999,7 @@ static int dump_all_tables_in_db(char *database) DBUG_RETURN(1); if (opt_xml) print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS); + if (lock_tables) { DYNAMIC_STRING query; @@ -4228,7 +4233,10 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } end= pos; - if (lock_tables) + /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */ + if (lock_tables && + !(mysql_get_server_version(mysql) >= 50003 && + !my_strcasecmp(&my_charset_latin1, db, "information_schema"))) { if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index c97131563cb..4b658f69371 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3563,9 +3563,6 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; drop table t1; drop user mysqltest_1@localhost; # -# Bug#21527 mysqldump incorrectly tries to LOCK TABLES on the -# information_schema database. -# # Bug#21424 mysqldump failing to export/import views # create database mysqldump_myDB; @@ -3605,6 +3602,39 @@ drop user myDB_User@localhost; drop database mysqldump_myDB; use test; # +# Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the +# information_schema database. +# +# Bug #33762: mysqldump can not dump INFORMATION_SCHEMA +# +DROP TABLE IF EXISTS `TABLES`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TEMPORARY TABLE `TABLES` ( + `TABLE_CATALOG` varchar(512) DEFAULT NULL, + `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '', + `TABLE_NAME` varchar(64) NOT NULL DEFAULT '', + `TABLE_TYPE` varchar(64) NOT NULL DEFAULT '', + `ENGINE` varchar(64) DEFAULT NULL, + `VERSION` bigint(21) unsigned DEFAULT NULL, + `ROW_FORMAT` varchar(10) DEFAULT NULL, + `TABLE_ROWS` bigint(21) unsigned DEFAULT NULL, + `AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL, + `DATA_LENGTH` bigint(21) unsigned DEFAULT NULL, + `MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL, + `INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL, + `DATA_FREE` bigint(21) unsigned DEFAULT NULL, + `AUTO_INCREMENT` bigint(21) unsigned DEFAULT NULL, + `CREATE_TIME` datetime DEFAULT NULL, + `UPDATE_TIME` datetime DEFAULT NULL, + `CHECK_TIME` datetime DEFAULT NULL, + `TABLE_COLLATION` varchar(32) DEFAULT NULL, + `CHECKSUM` bigint(21) unsigned DEFAULT NULL, + `CREATE_OPTIONS` varchar(255) DEFAULT NULL, + `TABLE_COMMENT` varchar(80) NOT NULL DEFAULT '' +) ENGINE=MEMORY DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +# # Bug#19745 mysqldump --xml produces invalid xml # DROP TABLE IF EXISTS t1; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index fe89d7bdafa..34ffbe4372b 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1395,9 +1395,6 @@ drop table t1; drop user mysqltest_1@localhost; ---echo # ---echo # Bug#21527 mysqldump incorrectly tries to LOCK TABLES on the ---echo # information_schema database. --echo # --echo # Bug#21424 mysqldump failing to export/import views --echo # @@ -1464,6 +1461,13 @@ disconnect root; --remove_file $MYSQLTEST_VARDIR/tmp/bug21527.sql use test; +--echo # +--echo # Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the +--echo # information_schema database. +--echo # +--echo # Bug #33762: mysqldump can not dump INFORMATION_SCHEMA +--echo # +--exec $MYSQL_DUMP --compact --opt -d information_schema tables --echo # --echo # Bug#19745 mysqldump --xml produces invalid xml From eae91cc7810c53536423d450b318824e0e96ace0 Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Tue, 12 May 2009 10:45:40 -0700 Subject: [PATCH 017/188] mysqlimport was not always compiled correctly to allow thread support, required for the --use-threads option. (Bug #32991) --- client/Makefile.am | 2 +- mysql-test/r/mysqldump.result | 175 ++++++++++++++++++++++++++++++++++ mysql-test/t/mysqldump.test | 5 - 3 files changed, 176 insertions(+), 6 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index 94db565ba37..ab5bc8d601a 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -71,7 +71,7 @@ mysqldump_SOURCES= mysqldump.c \ $(top_srcdir)/mysys/mf_getdate.c mysqlimport_SOURCES= mysqlimport.c - +mysqlimport_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 4b658f69371..7e987df8166 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4036,6 +4036,181 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +create table t1 (a text , b text); +create table t2 (a text , b text); +insert t1 values ("Duck, Duck", "goose"); +insert t1 values ("Duck, Duck", "pidgeon"); +insert t2 values ("We the people", "in order to perform"); +insert t2 values ("a more perfect", "union"); +select * from t1; +a b +Duck, Duck goose +Duck, Duck pidgeon +select * from t2; +a b +We the people in order to perform +a more perfect union +test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 +test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 +select * from t1; +a b +Duck, Duck goose +Duck, Duck pidgeon +Duck, Duck goose +Duck, Duck pidgeon +select * from t2; +a b +We the people in order to perform +a more perfect union +We the people in order to perform +a more perfect union +create table words(a varchar(255)); +create table words2(b varchar(255)); +select * from t1; +a b +Duck, Duck goose +Duck, Duck pidgeon +Duck, Duck goose +Duck, Duck pidgeon +Duck, Duck goose +Duck, Duck pidgeon +select * from t2; +a b +We the people in order to perform +a more perfect union +We the people in order to perform +a more perfect union +We the people in order to perform +a more perfect union +select * from words; +a +Aarhus +Aaron +Ababa +aback +abaft +abandon +abandoned +abandoning +abandonment +abandons +Aarhus +Aaron +Ababa +aback +abaft +abandon +abandoned +abandoning +abandonment +abandons +abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration +select * from words2; +b +abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration +drop table words; +mysql-import: Error: 1146, Table 'test.words' doesn't exist, when using table: words +drop table t1; +drop table t2; +drop table words2; # # Bug#16853 mysqldump doesn't show events # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 34ffbe4372b..2bc25c4929a 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1703,9 +1703,6 @@ DROP TABLE t1; # Added for use-thread option # -# THIS PART OF THE TEST IS DISABLED UNTIL Bug#32991 IS FIXED -if ($bug32991_fixed) { - create table t1 (a text , b text); create table t2 (a text , b text); insert t1 values ("Duck, Duck", "goose"); @@ -1743,8 +1740,6 @@ drop table t2; drop table words2; -} - --echo # --echo # Bug#16853 mysqldump doesn't show events --echo # From 1e37c919ef557f00476779b660ecf0c309c99457 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 15 May 2009 16:33:08 +0530 Subject: [PATCH 018/188] Fix for BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback. The global variable max_binlog_cache_size cannot be set more than 4GB on 32 bit systems, limiting transactions of all storage engines to 4G of changes. The problem is max_binlog_cache_size is declared as ulong which is 4 bytes on 32 bit and 8 bytes on 64 bit machines. Fixed by using ulonglong for max_binlog_cache_size which is 8bytes on 32 and 64 bit machines.The range for max_binlog_cache_size on 32 bit and 64 bit systems is 4096-18446744073709547520 bytes. mysql-test/r/variables.result: Result file for BUG#10206 mysql-test/t/variables.test: Testcase for BUG#10206 sql/mysql_priv.h: change the extern declaration of max_binlog_cache_size to ulonglong sql/mysqld.cc: change the declaration of max_binlog_cache_size to ulonglong and the option is fixed to extend the range of max_binlog_cache_size sql/set_var.cc: change the variable declaration of max_binlog_cache_size to ulonglong --- mysql-test/r/variables.result | 10 ++++++++++ mysql-test/t/variables.test | 9 +++++++++ sql/mysql_priv.h | 3 ++- sql/mysqld.cc | 5 +++-- sql/set_var.cc | 4 ++-- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f27d0b9fdd5..7c40de04694 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1467,4 +1467,14 @@ SELECT @@GLOBAL.server_id; @@GLOBAL.server_id 0 SET GLOBAL server_id = @old_server_id; +# +# BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback +# +SET @old_max_binlog_cache_size = @@GLOBAL.max_binlog_cache_size; +# Set the max_binlog_cache_size to size more than 4GB. +SET GLOBAL max_binlog_cache_size = 5 * 1024 * 1024 * 1024; +SELECT @@GLOBAL.max_binlog_cache_size; +@@GLOBAL.max_binlog_cache_size +5368709120 +SET GLOBAL max_binlog_cache_size = @old_max_binlog_cache_size; End of 5.1 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 6da20409639..2115627efee 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1201,4 +1201,13 @@ SET GLOBAL server_id = -1; SELECT @@GLOBAL.server_id; SET GLOBAL server_id = @old_server_id; +--echo # +--echo # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback +--echo # + +SET @old_max_binlog_cache_size = @@GLOBAL.max_binlog_cache_size; +--echo # Set the max_binlog_cache_size to size more than 4GB. +SET GLOBAL max_binlog_cache_size = 5 * 1024 * 1024 * 1024; +SELECT @@GLOBAL.max_binlog_cache_size; +SET GLOBAL max_binlog_cache_size = @old_max_binlog_cache_size; --echo End of 5.1 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 69a789284b0..0e5956847ed 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1935,7 +1935,8 @@ extern uint max_user_connections; extern ulong what_to_log,flush_time; extern ulong query_buff_size; extern ulong max_prepared_stmt_count, prepared_stmt_count; -extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit; +extern ulong binlog_cache_size, open_files_limit; +extern ulonglong max_binlog_cache_size; extern ulong max_binlog_size, max_relay_log_size; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size, thread_pool_size; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 080f78993a1..7843bcbfc2a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -507,7 +507,8 @@ ulong slave_net_timeout, slave_trans_retries; ulong slave_exec_mode_options; const char *slave_exec_mode_str= "STRICT"; ulong thread_cache_size=0, thread_pool_size= 0; -ulong binlog_cache_size=0, max_binlog_cache_size=0; +ulong binlog_cache_size=0; +ulonglong max_binlog_cache_size=0; ulong query_cache_size=0; ulong refresh_version; /* Increments on each reload */ query_id_t global_query_id; @@ -6582,7 +6583,7 @@ log and this option does nothing anymore.", {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, "Can be used to restrict the total size used to cache a multi-transaction query.", (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0, - GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0}, + GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULLONG_MAX, 0, IO_SIZE, 0}, {"max_binlog_size", OPT_MAX_BINLOG_SIZE, "Binary log will be rotated automatically when the size exceeds this \ value. Will also apply to relay logs if max_relay_log_size is 0. \ diff --git a/sql/set_var.cc b/sql/set_var.cc index bc8c91342e6..0b89333ce03 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -359,8 +359,8 @@ static sys_var_const sys_lower_case_table_names(&vars, &lower_case_table_names); static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet", &SV::max_allowed_packet); -static sys_var_long_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size", - &max_binlog_cache_size); +static sys_var_ulonglong_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size", + &max_binlog_cache_size); static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size", &max_binlog_size, fix_max_binlog_size); From 68bf2c03fb05eed8d4ec8821bdcb630cf51793c6 Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Fri, 15 May 2009 12:24:45 -0700 Subject: [PATCH 019/188] Fix test case, table name needs to be upper-case. --- mysql-test/t/mysqldump.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 2bc25c4929a..64d1036e264 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1467,7 +1467,7 @@ use test; --echo # --echo # Bug #33762: mysqldump can not dump INFORMATION_SCHEMA --echo # ---exec $MYSQL_DUMP --compact --opt -d information_schema tables +--exec $MYSQL_DUMP --compact --opt -d information_schema TABLES --echo # --echo # Bug#19745 mysqldump --xml produces invalid xml From 261238b9247e6a9c1e258a45fd138c29ed39d5c3 Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Fri, 15 May 2009 13:12:20 -0700 Subject: [PATCH 020/188] Remove out-of-date and unnecessary comment in source code about what versions are supported. (Bug #42021) --- client/mysqlbinlog.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 2c2023ae129..2c74d745f01 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -17,10 +17,8 @@ TODO: print the catalog (some USE catalog.db ????). - Standalone program to read a MySQL binary log (or relay log); - can read files produced by 3.23, 4.x, 5.0 servers. + Standalone program to read a MySQL binary log (or relay log). - Can read binlogs from 3.23/4.x/5.0 and relay logs from 4.x/5.0. Should be able to read any file of these categories, even with --start-position. An important fact: the Format_desc event of the log is at most the 3rd event From 2a4e1220c8a382e4f7d15da714d465558b0de685 Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Fri, 15 May 2009 13:25:22 -0700 Subject: [PATCH 021/188] Add usage for --base64-output=DECODE-ROWS and note that UNSPEC is intentionally unmentioned (it is just a placeholder). (Bug #41403) --- client/mysqlbinlog.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 2c74d745f01..aeaf49b5a15 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -932,10 +932,13 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"base64-output", OPT_BASE64_OUTPUT_MODE, + /* 'unspec' is not mentioned because it is just a placeholder. */ "Determine when the output statements should be base64-encoded BINLOG " "statements: 'never' disables it and works only for binlogs without " "row-based events; 'auto' is the default and prints base64 only when " "necessary (i.e., for row-based events and format description events); " + "'decode-rows' suppresses BINLOG statements for row events, but does " + "not exit as an error if a row event is found, unlike 'never'; " "'always' prints base64 whenever possible. 'always' is for debugging " "only and should not be used in a production system. The default is " "'auto'. --base64-output is a short form for --base64-output=always." From 86a7766bda8e38763300fcbfb0de3bf62f919639 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Tue, 19 May 2009 18:43:50 +0200 Subject: [PATCH 022/188] Fix for Bug#44949 funcs_1: Several tests for embedded server need maintenance Detail: The results for the "normal" server testcase variants were already adjusted to the modified information_schema content. Therefore just do the same for the embedded server variants. --- .../funcs_1/r/is_columns_is_embedded.result | 5 +- .../r/is_columns_myisam_embedded.result | 256 +++++++++--------- .../r/is_columns_mysql_embedded.result | 12 +- 3 files changed, 135 insertions(+), 138 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index d5e1309e39f..59ad695c413 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -166,7 +166,7 @@ NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL utf8 utf NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) -NULL information_schema PROCESSLIST TIME 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(7) +NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL int(7) NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL utf8 utf8_general_ci varchar(16) NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) @@ -340,6 +340,7 @@ ORDER BY CHARACTER_SET_NAME, COLLATION_NAME, COL_CML; COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME NULL bigint NULL NULL NULL datetime NULL NULL +NULL int NULL NULL --> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values --> are 0, which is intended behavior, and the result of 0 / 0 IS NULL SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML, @@ -519,7 +520,7 @@ NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4) 3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PROCESSLIST DB varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PROCESSLIST COMMAND varchar 16 48 utf8 utf8_general_ci varchar(16) -NULL information_schema PROCESSLIST TIME bigint NULL NULL NULL NULL bigint(7) +NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7) 3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result index d22c5cc06f7..2721dcf3c6e 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result @@ -514,7 +514,7 @@ NULL test tb1 f6 6 NULL YES mediumtext 16777215 16777215 NULL NULL latin1 latin1 NULL test tb1 f7 7 NULL YES longtext 4294967295 4294967295 NULL NULL latin1 latin1_swedish_ci longtext NULL test tb1 f8 8 NULL YES tinyblob 255 255 NULL NULL NULL NULL tinyblob NULL test tb1 f9 9 NULL YES blob 65535 65535 NULL NULL NULL NULL blob -NULL test tb2 f100 42 00000000000000000008.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date NULL test tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time NULL test tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime @@ -547,32 +547,32 @@ NULL test tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) u NULL test tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill NULL test tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill NULL test tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double -NULL test tb2 f74 16 NULL YES double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb2 f75 17 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb2 f76 18 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double -NULL test tb2 f78 20 7.7 YES double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb2 f79 21 00000000000000000007.7 YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb2 f80 22 00000000000000000008.8 YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float -NULL test tb2 f82 24 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb2 f83 25 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb2 f84 26 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float NULL test tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float -NULL test tb2 f87 29 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb2 f88 30 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb2 f89 31 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb2 f90 32 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb2 f91 33 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb2 f92 34 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float NULL test tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double -NULL test tb2 f95 37 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb2 f96 38 8.8 NO double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb2 f97 39 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb2 f98 40 00000000000000000008.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb2 f99 41 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test tb3 f118 1 a NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) NULL test tb3 f119 2  NO char 1 1 NULL NULL latin1 latin1_bin char(1) NULL test tb3 f120 3  NO char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) @@ -646,33 +646,33 @@ NULL test tb4 f187 12 000000000000000000000000000000009.000000000000000000000000 NULL test tb4 f188 13 0000000009 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill NULL test tb4 f189 14 000000000000000000000000000000009.000000000000000000000000000000 NO decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill NULL test tb4 f190 15 88.8 NO double NULL NULL 22 NULL NULL NULL double -NULL test tb4 f191 16 88.8 NO double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb4 f192 17 00000000000000000088.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb4 f193 18 00000000000000000088.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f191 16 88.8 NO double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb4 f192 17 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f193 18 00000000000000000088.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb4 f194 19 55.5 NO double NULL NULL 22 NULL NULL NULL double -NULL test tb4 f195 20 55.5 NO double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb4 f196 21 00000000000000000055.5 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb4 f197 22 00000000000000000055.5 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f195 20 55.5 NO double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb4 f196 21 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f197 22 00000000000000000055.5 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb4 f198 23 NULL YES float NULL NULL 12 NULL NULL NULL float -NULL test tb4 f199 24 NULL YES float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb4 f200 25 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f201 26 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f199 24 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb4 f200 25 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f201 26 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test tb4 f202 27 NULL YES float NULL NULL 12 NULL NULL NULL float NULL test tb4 f203 28 NULL YES float NULL NULL 12 NULL NULL NULL float -NULL test tb4 f204 29 NULL YES float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb4 f205 30 NULL YES float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb4 f206 31 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f207 32 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f208 33 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f209 34 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f204 29 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb4 f205 30 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb4 f206 31 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f207 32 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f208 33 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f209 34 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test tb4 f210 35 NULL YES float NULL NULL 12 NULL NULL NULL float NULL test tb4 f211 36 NULL YES double NULL NULL 22 NULL NULL NULL double -NULL test tb4 f212 37 NULL YES float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test tb4 f213 38 NULL YES double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test tb4 f214 39 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f215 40 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test tb4 f216 41 NULL YES float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test tb4 f217 42 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f212 37 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned +NULL test tb4 f213 38 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned +NULL test tb4 f214 39 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f215 40 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test tb4 f216 41 NULL YES float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test tb4 f217 42 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test tb4 f218 43 NULL YES date NULL NULL NULL NULL NULL NULL date NULL test tb4 f219 44 NULL YES time NULL NULL NULL NULL NULL NULL time NULL test tb4 f220 45 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime @@ -698,7 +698,7 @@ NULL test tb4 f239 64 NULL YES varbinary 1000 1000 NULL NULL NULL NULL varbinary NULL test tb4 f240 65 NULL YES varchar 120 120 NULL NULL latin1 latin1_swedish_ci varchar(120) NULL test tb4 f241 66 NULL YES char 100 100 NULL NULL latin1 latin1_swedish_ci char(100) NULL test tb4 f242 67 NULL YES bit NULL NULL 30 NULL NULL NULL bit(30) -NULL test1 tb2 f100 42 00000000000000000008.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f100 42 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test1 tb2 f101 43 2000-01-01 NO date NULL NULL NULL NULL NULL NULL date NULL test1 tb2 f102 44 00:00:20 NO time NULL NULL NULL NULL NULL NULL time NULL test1 tb2 f103 45 0002-02-02 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime @@ -731,32 +731,32 @@ NULL test1 tb2 f70 12 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) NULL test1 tb2 f71 13 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill NULL test1 tb2 f72 14 NULL YES decimal NULL NULL 63 30 NULL NULL decimal(63,30) unsigned zerofill NULL test1 tb2 f73 15 NULL YES double NULL NULL 22 NULL NULL NULL double -NULL test1 tb2 f74 16 NULL YES double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test1 tb2 f75 17 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f76 18 NULL YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f74 16 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned +NULL test1 tb2 f75 17 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f76 18 NULL YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test1 tb2 f77 19 7.7 YES double NULL NULL 22 NULL NULL NULL double -NULL test1 tb2 f78 20 7.7 YES double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test1 tb2 f79 21 00000000000000000007.7 YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f80 22 00000000000000000008.8 YES double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f78 20 7.7 YES double NULL NULL 22 NULL NULL NULL double unsigned +NULL test1 tb2 f79 21 00000000000000000007.7 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f80 22 00000000000000000008.8 YES double NULL NULL 22 NULL NULL NULL double unsigned zerofill NULL test1 tb2 f81 23 8.8 NO float NULL NULL 12 NULL NULL NULL float -NULL test1 tb2 f82 24 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test1 tb2 f83 25 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f84 26 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f82 24 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test1 tb2 f83 25 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f84 26 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test1 tb2 f85 27 8.8 NO float NULL NULL 12 NULL NULL NULL float NULL test1 tb2 f86 28 8.8 NO float NULL NULL 12 NULL NULL NULL float -NULL test1 tb2 f87 29 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test1 tb2 f88 30 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test1 tb2 f89 31 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f90 32 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f91 33 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f92 34 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f87 29 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test1 tb2 f88 30 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test1 tb2 f89 31 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f90 32 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f91 33 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f92 34 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test1 tb2 f93 35 8.8 NO float NULL NULL 12 NULL NULL NULL float NULL test1 tb2 f94 36 8.8 NO double NULL NULL 22 NULL NULL NULL double -NULL test1 tb2 f95 37 8.8 NO float unsigned NULL NULL 12 NULL NULL NULL float unsigned -NULL test1 tb2 f96 38 8.8 NO double unsigned NULL NULL 22 NULL NULL NULL double unsigned -NULL test1 tb2 f97 39 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f98 40 00000000000000000008.8 NO double unsigned zerofill NULL NULL 22 NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f99 41 0000000008.8 NO float unsigned zerofill NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f95 37 8.8 NO float NULL NULL 12 NULL NULL NULL float unsigned +NULL test1 tb2 f96 38 8.8 NO double NULL NULL 22 NULL NULL NULL double unsigned +NULL test1 tb2 f97 39 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f98 40 00000000000000000008.8 NO double NULL NULL 22 NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f99 41 0000000008.8 NO float NULL NULL 12 NULL NULL NULL float unsigned zerofill NULL test4 t6 f1 1 NULL YES char 20 20 NULL NULL latin1 latin1_swedish_ci char(20) NULL test4 t6 f2 2 NULL YES char 25 25 NULL NULL latin1 latin1_swedish_ci char(25) NULL test4 t6 f3 3 NULL YES date NULL NULL NULL NULL NULL NULL date @@ -817,11 +817,7 @@ NULL date NULL NULL NULL datetime NULL NULL NULL decimal NULL NULL NULL double NULL NULL -NULL double unsigned NULL NULL -NULL double unsigned zerofill NULL NULL NULL float NULL NULL -NULL float unsigned NULL NULL -NULL float unsigned zerofill NULL NULL NULL int NULL NULL NULL mediumint NULL NULL NULL smallint NULL NULL @@ -963,33 +959,33 @@ NULL test tb2 f70 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test tb2 f71 decimal NULL NULL NULL NULL decimal(10,0) unsigned zerofill NULL test tb2 f72 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test tb2 f73 double NULL NULL NULL NULL double -NULL test tb2 f74 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb2 f75 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb2 f76 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f74 double NULL NULL NULL NULL double unsigned +NULL test tb2 f75 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f76 double NULL NULL NULL NULL double unsigned zerofill NULL test tb2 f77 double NULL NULL NULL NULL double -NULL test tb2 f78 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb2 f79 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb2 f80 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f78 double NULL NULL NULL NULL double unsigned +NULL test tb2 f79 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f80 double NULL NULL NULL NULL double unsigned zerofill NULL test tb2 f81 float NULL NULL NULL NULL float -NULL test tb2 f82 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb2 f83 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f84 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f82 float NULL NULL NULL NULL float unsigned +NULL test tb2 f83 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f84 float NULL NULL NULL NULL float unsigned zerofill NULL test tb2 f85 float NULL NULL NULL NULL float NULL test tb2 f86 float NULL NULL NULL NULL float -NULL test tb2 f87 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb2 f88 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb2 f89 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f90 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f91 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f92 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f87 float NULL NULL NULL NULL float unsigned +NULL test tb2 f88 float NULL NULL NULL NULL float unsigned +NULL test tb2 f89 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f90 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f91 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f92 float NULL NULL NULL NULL float unsigned zerofill NULL test tb2 f93 float NULL NULL NULL NULL float NULL test tb2 f94 double NULL NULL NULL NULL double -NULL test tb2 f95 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb2 f96 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb2 f97 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f98 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb2 f99 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb2 f100 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f95 float NULL NULL NULL NULL float unsigned +NULL test tb2 f96 double NULL NULL NULL NULL double unsigned +NULL test tb2 f97 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f98 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb2 f99 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb2 f100 double NULL NULL NULL NULL double unsigned zerofill NULL test tb2 f101 date NULL NULL NULL NULL date NULL test tb2 f102 time NULL NULL NULL NULL time NULL test tb2 f103 datetime NULL NULL NULL NULL datetime @@ -1080,33 +1076,33 @@ NULL test tb4 f187 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test tb4 f188 decimal NULL NULL NULL NULL decimal(10,0) unsigned zerofill NULL test tb4 f189 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test tb4 f190 double NULL NULL NULL NULL double -NULL test tb4 f191 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb4 f192 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb4 f193 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f191 double NULL NULL NULL NULL double unsigned +NULL test tb4 f192 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f193 double NULL NULL NULL NULL double unsigned zerofill NULL test tb4 f194 double NULL NULL NULL NULL double -NULL test tb4 f195 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb4 f196 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb4 f197 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f195 double NULL NULL NULL NULL double unsigned +NULL test tb4 f196 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f197 double NULL NULL NULL NULL double unsigned zerofill NULL test tb4 f198 float NULL NULL NULL NULL float -NULL test tb4 f199 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb4 f200 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f201 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f199 float NULL NULL NULL NULL float unsigned +NULL test tb4 f200 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f201 float NULL NULL NULL NULL float unsigned zerofill NULL test tb4 f202 float NULL NULL NULL NULL float NULL test tb4 f203 float NULL NULL NULL NULL float -NULL test tb4 f204 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb4 f205 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb4 f206 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f207 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f208 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f209 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f204 float NULL NULL NULL NULL float unsigned +NULL test tb4 f205 float NULL NULL NULL NULL float unsigned +NULL test tb4 f206 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f207 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f208 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f209 float NULL NULL NULL NULL float unsigned zerofill NULL test tb4 f210 float NULL NULL NULL NULL float NULL test tb4 f211 double NULL NULL NULL NULL double -NULL test tb4 f212 float unsigned NULL NULL NULL NULL float unsigned -NULL test tb4 f213 double unsigned NULL NULL NULL NULL double unsigned -NULL test tb4 f214 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f215 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test tb4 f216 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test tb4 f217 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f212 float NULL NULL NULL NULL float unsigned +NULL test tb4 f213 double NULL NULL NULL NULL double unsigned +NULL test tb4 f214 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f215 double NULL NULL NULL NULL double unsigned zerofill +NULL test tb4 f216 float NULL NULL NULL NULL float unsigned zerofill +NULL test tb4 f217 double NULL NULL NULL NULL double unsigned zerofill NULL test tb4 f218 date NULL NULL NULL NULL date NULL test tb4 f219 time NULL NULL NULL NULL time NULL test tb4 f220 datetime NULL NULL NULL NULL datetime @@ -1147,33 +1143,33 @@ NULL test1 tb2 f70 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test1 tb2 f71 decimal NULL NULL NULL NULL decimal(10,0) unsigned zerofill NULL test1 tb2 f72 decimal NULL NULL NULL NULL decimal(63,30) unsigned zerofill NULL test1 tb2 f73 double NULL NULL NULL NULL double -NULL test1 tb2 f74 double unsigned NULL NULL NULL NULL double unsigned -NULL test1 tb2 f75 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f76 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f74 double NULL NULL NULL NULL double unsigned +NULL test1 tb2 f75 double NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f76 double NULL NULL NULL NULL double unsigned zerofill NULL test1 tb2 f77 double NULL NULL NULL NULL double -NULL test1 tb2 f78 double unsigned NULL NULL NULL NULL double unsigned -NULL test1 tb2 f79 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f80 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f78 double NULL NULL NULL NULL double unsigned +NULL test1 tb2 f79 double NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f80 double NULL NULL NULL NULL double unsigned zerofill NULL test1 tb2 f81 float NULL NULL NULL NULL float -NULL test1 tb2 f82 float unsigned NULL NULL NULL NULL float unsigned -NULL test1 tb2 f83 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f84 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f82 float NULL NULL NULL NULL float unsigned +NULL test1 tb2 f83 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f84 float NULL NULL NULL NULL float unsigned zerofill NULL test1 tb2 f85 float NULL NULL NULL NULL float NULL test1 tb2 f86 float NULL NULL NULL NULL float -NULL test1 tb2 f87 float unsigned NULL NULL NULL NULL float unsigned -NULL test1 tb2 f88 float unsigned NULL NULL NULL NULL float unsigned -NULL test1 tb2 f89 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f90 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f91 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f92 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f87 float NULL NULL NULL NULL float unsigned +NULL test1 tb2 f88 float NULL NULL NULL NULL float unsigned +NULL test1 tb2 f89 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f90 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f91 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f92 float NULL NULL NULL NULL float unsigned zerofill NULL test1 tb2 f93 float NULL NULL NULL NULL float NULL test1 tb2 f94 double NULL NULL NULL NULL double -NULL test1 tb2 f95 float unsigned NULL NULL NULL NULL float unsigned -NULL test1 tb2 f96 double unsigned NULL NULL NULL NULL double unsigned -NULL test1 tb2 f97 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f98 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill -NULL test1 tb2 f99 float unsigned zerofill NULL NULL NULL NULL float unsigned zerofill -NULL test1 tb2 f100 double unsigned zerofill NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f95 float NULL NULL NULL NULL float unsigned +NULL test1 tb2 f96 double NULL NULL NULL NULL double unsigned +NULL test1 tb2 f97 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f98 double NULL NULL NULL NULL double unsigned zerofill +NULL test1 tb2 f99 float NULL NULL NULL NULL float unsigned zerofill +NULL test1 tb2 f100 double NULL NULL NULL NULL double unsigned zerofill NULL test1 tb2 f101 date NULL NULL NULL NULL date NULL test1 tb2 f102 time NULL NULL NULL NULL time NULL test1 tb2 f103 datetime NULL NULL NULL NULL datetime diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result index 1d37a87f868..9c9d3cd26de 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result @@ -48,7 +48,7 @@ NULL mysql event last_executed 10 NULL YES datetime NULL NULL NULL NULL NULL NUL NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL NULL NULL timestamp NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') -NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) +NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') @@ -60,7 +60,7 @@ NULL mysql func type 4 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('fu NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP -NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL int(11) +NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL int(11) NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext NULL mysql help_category help_category_id 1 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(5) unsigned PRI @@ -150,7 +150,7 @@ NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL NULL NULL time NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL NULL NULL time NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL int(11) NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL int(11) -NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL int(11) +NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL utf8 utf8_general_ci mediumtext @@ -329,7 +329,7 @@ NULL mysql event ends datetime NULL NULL NULL NULL datetime 3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE') 3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') 3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64) -NULL mysql event originator int NULL NULL NULL NULL int(10) +NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned 1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64) 3.0000 mysql event character_set_client char 32 96 utf8 utf8_bin char(32) 3.0000 mysql event collation_connection char 32 96 utf8 utf8_bin char(32) @@ -342,7 +342,7 @@ NULL mysql func ret tinyint NULL NULL NULL NULL tinyint(1) NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp 1.0000 mysql general_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext NULL mysql general_log thread_id int NULL NULL NULL NULL int(11) -NULL mysql general_log server_id int NULL NULL NULL NULL int(11) +NULL mysql general_log server_id int NULL NULL NULL NULL int(10) unsigned 3.0000 mysql general_log command_type varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 mysql general_log argument mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext NULL mysql help_category help_category_id smallint NULL NULL NULL NULL smallint(5) unsigned @@ -434,7 +434,7 @@ NULL mysql slow_log rows_examined int NULL NULL NULL NULL int(11) 3.0000 mysql slow_log db varchar 512 1536 utf8 utf8_general_ci varchar(512) NULL mysql slow_log last_insert_id int NULL NULL NULL NULL int(11) NULL mysql slow_log insert_id int NULL NULL NULL NULL int(11) -NULL mysql slow_log server_id int NULL NULL NULL NULL int(11) +NULL mysql slow_log server_id int NULL NULL NULL NULL int(10) unsigned 1.0000 mysql slow_log sql_text mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext 3.0000 mysql tables_priv Host char 60 180 utf8 utf8_bin char(60) 3.0000 mysql tables_priv Db char 64 192 utf8 utf8_bin char(64) From 808bed557ee4175ba22a63341d190c21e487a54e Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 27 May 2009 12:24:25 +0400 Subject: [PATCH 023/188] Bug #44638: mysql_upgrade, mysqlcheck output instance unclear Dump all connection-related arguments when running mysqlcheck from mysql_upgrade. No test case, since the output depends on the test suite configuration and platform. client/mysql_upgrade.c: Dump all connection-related arguments when running mysqlcheck from mysql_upgrade. --- client/mysql_upgrade.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index cbc60d8acad..bbc0e0f57ec 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -39,6 +39,7 @@ static uint my_end_arg= 0; static char *opt_user= (char*)"root"; static DYNAMIC_STRING ds_args; +static DYNAMIC_STRING conn_args; static char *opt_password= 0; static my_bool tty_password= 0; @@ -135,6 +136,7 @@ static void free_used_memory(void) free_defaults(defaults_argv); dynstr_free(&ds_args); + dynstr_free(&conn_args); } @@ -204,7 +206,7 @@ static void add_one_option(DYNAMIC_STRING* ds, } } dynstr_append_os_quoted(ds, "--", opt->name, eq, arg, NullS); - dynstr_append(&ds_args, " "); + dynstr_append(ds, " "); } @@ -256,6 +258,15 @@ get_one_option(int optid, const struct my_option *opt, case 'f': /* --force */ add_option= FALSE; break; + + case 'h': /* --host */ + case 'W': /* --pipe */ + case 'P': /* --port */ + case 'S': /* --socket */ + case OPT_MYSQL_PROTOCOL: /* --protocol */ + case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */ + add_one_option(&conn_args, opt, argument); + break; } if (add_option) @@ -603,6 +614,20 @@ static void create_mysql_upgrade_info_file(void) } +/* + Print connection-related arguments. +*/ + +static void print_conn_args(const char *tool_name) +{ + if (conn_args.str[0]) + verbose("Running '%s' with connection arguments: %s", tool_name, + conn_args.str); + else + verbose("Running '%s with default connection arguments", tool_name); +} + + /* Check and upgrade(if neccessary) all tables in the server using "mysqlcheck --check-upgrade .." @@ -610,7 +635,7 @@ static void create_mysql_upgrade_info_file(void) static int run_mysqlcheck_upgrade(void) { - verbose("Running 'mysqlcheck'..."); + print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ "--no-defaults", @@ -624,7 +649,7 @@ static int run_mysqlcheck_upgrade(void) static int run_mysqlcheck_fixnames(void) { - verbose("Running 'mysqlcheck'..."); + print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ "--no-defaults", @@ -753,7 +778,8 @@ int main(int argc, char **argv) strncpy(self_name, argv[0], FN_REFLEN); } - if (init_dynamic_string(&ds_args, "", 512, 256)) + if (init_dynamic_string(&ds_args, "", 512, 256) || + init_dynamic_string(&conn_args, "", 512, 256)) die("Out of memory"); load_defaults("my", load_default_groups, &argc, &argv); From 1b8322c3c6f406bd119145c6f38ddeb802e1b9fc Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 27 May 2009 14:20:57 +0400 Subject: [PATCH 024/188] Bug #44767: invalid memory reads in password() and old_password() functions The PASSWORD() and OLD_PASSWORD() functions could lead to memory reads outside of an internal buffer when used with BLOB arguments. String::c_ptr() assumes there is at least one extra byte in the internally allocated buffer when adding the trailing '\0'. This, however, may not be the case when a String object was initialized with externally allocated buffer. The bug was fixed by adding an additional "length" argument to make_scrambled_password_323() and make_scrambled_password() in order to avoid String::c_ptr() calls for PASSWORD()/OLD_PASSWORD(). However, since the make_scrambled_password[_323] functions are a part of the client library ABI, the functions with the new interfaces were implemented with the 'my_' prefix in their names, with the old functions changed to be wrappers around the new ones to maintain interface compatibility. mysql-test/r/func_crypt.result: Added a test case for bug #44767. mysql-test/t/func_crypt.test: Added a test case for bug #44767. sql/item_strfunc.cc: Use the new my_make_scrambled_password*() to avoid String::c_ptr(). sql/item_strfunc.h: Changed Item_func[_old]_password::alloc() interfaces so that we can use the new my_make_scrambled_password*() functions. sql/mysql_priv.h: Added declarations for the new my_make_scrambled_password*() functions. sql/password.c: Added new my_make_scrambled_password*() functions with an additional "length" argument. Changed ones to be wrappers around the new ones to maintain interface compatibility. sql/sql_yacc.yy: Utilize the new password hashing functions with additional length argument. --- mysql-test/r/func_crypt.result | 11 +++++++ mysql-test/t/func_crypt.test | 12 ++++++++ sql/item_strfunc.cc | 14 +++++---- sql/item_strfunc.h | 4 +-- sql/mysql_priv.h | 6 ++++ sql/password.c | 55 ++++++++++++++++++++++++++++------ sql/sql_yacc.yy | 11 +++---- 7 files changed, 91 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result index afdec0f4d06..42fa18b17b2 100644 --- a/mysql-test/r/func_crypt.result +++ b/mysql-test/r/func_crypt.result @@ -95,3 +95,14 @@ Note 1003 select password(_latin1'idkfa ') AS `password('idkfa ')`,old_password( select encrypt('1234','_.'); encrypt('1234','_.') # +# +# Bug #44767: invalid memory reads in password() and old_password() +# functions +# +CREATE TABLE t1(c1 MEDIUMBLOB); +INSERT INTO t1 VALUES (REPEAT('a', 1024)); +SELECT OLD_PASSWORD(c1), PASSWORD(c1) FROM t1; +OLD_PASSWORD(c1) PASSWORD(c1) +77023ffe214c04ff *82E58A2C08AAFE72C8EB523069CD8ADB33F78F58 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/func_crypt.test b/mysql-test/t/func_crypt.test index cc3cdb9564d..6dedeaa0fef 100644 --- a/mysql-test/t/func_crypt.test +++ b/mysql-test/t/func_crypt.test @@ -56,3 +56,15 @@ explain extended select password('idkfa '), old_password('idkfa'); select encrypt('1234','_.'); # End of 4.1 tests + +--echo # +--echo # Bug #44767: invalid memory reads in password() and old_password() +--echo # functions +--echo # + +CREATE TABLE t1(c1 MEDIUMBLOB); +INSERT INTO t1 VALUES (REPEAT('a', 1024)); +SELECT OLD_PASSWORD(c1), PASSWORD(c1) FROM t1; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index bc2dcb9c61b..71d3a34cd27 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1554,16 +1554,17 @@ String *Item_func_password::val_str(String *str) return 0; if (res->length() == 0) return &my_empty_string; - make_scrambled_password(tmp_value, res->c_ptr()); + my_make_scrambled_password(tmp_value, res->ptr(), res->length()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset()); return str; } -char *Item_func_password::alloc(THD *thd, const char *password) +char *Item_func_password::alloc(THD *thd, const char *password, + size_t pass_len) { char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); if (buff) - make_scrambled_password(buff, password); + my_make_scrambled_password(buff, password, pass_len); return buff; } @@ -1577,16 +1578,17 @@ String *Item_func_old_password::val_str(String *str) return 0; if (res->length() == 0) return &my_empty_string; - make_scrambled_password_323(tmp_value, res->c_ptr()); + my_make_scrambled_password_323(tmp_value, res->ptr(), res->length()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset()); return str; } -char *Item_func_old_password::alloc(THD *thd, const char *password) +char *Item_func_old_password::alloc(THD *thd, const char *password, + size_t pass_len) { char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); if (buff) - make_scrambled_password_323(buff, password); + my_make_scrambled_password_323(buff, password, pass_len); return buff; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 1c5346ab074..f2cb4d2d32a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -281,7 +281,7 @@ public: String *val_str(String *str); void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; } const char *func_name() const { return "password"; } - static char *alloc(THD *thd, const char *password); + static char *alloc(THD *thd, const char *password, size_t pass_len); }; @@ -300,7 +300,7 @@ public: String *val_str(String *str); void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; } const char *func_name() const { return "old_password"; } - static char *alloc(THD *thd, const char *password); + static char *alloc(THD *thd, const char *password, size_t pass_len); }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9768668f103..55bcd30999d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1677,6 +1677,12 @@ extern void turn_parser_debug_on(); SQL_CRYPT *get_crypt_for_frm(void); #endif +/* password.c */ +extern "C" void my_make_scrambled_password_323(char *to, const char *password, + size_t pass_len); +extern "C" void my_make_scrambled_password(char *to, const char *password, + size_t pass_len); + #include "sql_view.h" /* Some inline functions for more speed */ diff --git a/sql/password.c b/sql/password.c index 57ed3e6ab0f..e12074549a4 100644 --- a/sql/password.c +++ b/sql/password.c @@ -137,16 +137,35 @@ void hash_password(ulong *result, const char *password, uint password_len) Create password to be stored in user database from raw string Used for pre-4.1 password handling SYNOPSIS - make_scrambled_password_323() + my_make_scrambled_password_323() to OUT store scrambled password here password IN user-supplied password + pass_len IN length of password string +*/ + +void my_make_scrambled_password_323(char *to, const char *password, + size_t pass_len) +{ + ulong hash_res[2]; + hash_password(hash_res, password, (uint) pass_len); + sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]); +} + + +/* + Wrapper around my_make_scrambled_password_323() to maintain client lib ABI + compatibility. + In server code usage of my_make_scrambled_password_323() is preferred to + avoid strlen(). + SYNOPSIS + make_scrambled_password_323() + to OUT store scrambled password here + password IN NULL-terminated string with user-supplied password */ void make_scrambled_password_323(char *to, const char *password) { - ulong hash_res[2]; - hash_password(hash_res, password, (uint) strlen(password)); - sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]); + my_make_scrambled_password_323(to, password, strlen(password)); } @@ -383,20 +402,21 @@ my_crypt(char *to, const uchar *s1, const uchar *s2, uint len) The result of this function is used as return value from PASSWORD() and is stored in the database. SYNOPSIS - make_scrambled_password() + my_make_scrambled_password() buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string - password IN NULL-terminated password string + password IN password string + pass_len IN length of password string */ -void -make_scrambled_password(char *to, const char *password) +void my_make_scrambled_password(char *to, const char *password, + size_t pass_len) { SHA1_CONTEXT sha1_context; uint8 hash_stage2[SHA1_HASH_SIZE]; mysql_sha1_reset(&sha1_context); /* stage 1: hash password */ - mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) strlen(password)); + mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) pass_len); mysql_sha1_result(&sha1_context, (uint8 *) to); /* stage 2: hash stage1 output */ mysql_sha1_reset(&sha1_context); @@ -409,6 +429,23 @@ make_scrambled_password(char *to, const char *password) } +/* + Wrapper around my_make_scrambled_password() to maintain client lib ABI + compatibility. + In server code usage of my_make_scrambled_password() is preferred to + avoid strlen(). + SYNOPSIS + make_scrambled_password() + buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string + password IN NULL-terminated password string +*/ + +void make_scrambled_password(char *to, const char *password) +{ + my_make_scrambled_password(to, password, strlen(password)); +} + + /* Produce an obscure octet sequence from password and random string, recieved from the server. This sequence corresponds to the diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 61020a3eed0..b6a215a2306 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10092,15 +10092,16 @@ text_or_password: | PASSWORD '(' TEXT_STRING ')' { $$= $3.length ? YYTHD->variables.old_passwords ? - Item_func_old_password::alloc(YYTHD, $3.str) : - Item_func_password::alloc(YYTHD, $3.str) : + Item_func_old_password::alloc(YYTHD, $3.str, $3.length) : + Item_func_password::alloc(YYTHD, $3.str, $3.length) : $3.str; if ($$ == NULL) MYSQL_YYABORT; } | OLD_PASSWORD '(' TEXT_STRING ')' { - $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str) : + $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str, + $3.length) : $3.str; if ($$ == NULL) MYSQL_YYABORT; @@ -10545,7 +10546,7 @@ grant_user: (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); if (buff == NULL) MYSQL_YYABORT; - make_scrambled_password_323(buff, $4.str); + my_make_scrambled_password_323(buff, $4.str, $4.length); $1->password.str= buff; $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; } @@ -10555,7 +10556,7 @@ grant_user: (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); if (buff == NULL) MYSQL_YYABORT; - make_scrambled_password(buff, $4.str); + my_make_scrambled_password(buff, $4.str, $4.length); $1->password.str= buff; $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; } From 80730df7d634e1a620c864d6665d6e66ccad447a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 27 May 2009 16:05:29 +0300 Subject: [PATCH 025/188] Bug #38159: Function parsing problem generates misleading error message Added a more detailed error message on calling an ambiguous missing function. mysql-test/r/ps.result: Bug #38159: fixed existing tests mysql-test/r/sp-error.result: Bug #38159: test case mysql-test/t/ps.test: Bug #38159: fixed existing tests mysql-test/t/sp-error.test: Bug #38159: test case sql/item_func.cc: Bug #38159: generate more detailed error message sql/share/errmsg.txt: Bug #38159: add a more detailed error message sql/sql_derived.cc: Bug #38159: treat the detailed error message the same way as the generic one sql/sql_lex.cc: Bug #38159: - detect if the token is ambiguous and print the appropriate error. - backport is_lex_native_function() from 5.1 sql/sql_lex.h: Bug #38159: detect if the token is ambiguous and print the appropriate error. sql/sql_yacc.yy: Bug #38159: generate more detailed error message sql/table.cc: Bug #38159: treat the detailed error message the same way as the generic one --- mysql-test/r/ps.result | 4 ++-- mysql-test/r/sp-error.result | 10 ++++++++++ mysql-test/t/ps.test | 4 ++-- mysql-test/t/sp-error.test | 13 +++++++++++++ sql/item_func.cc | 10 +++++++++- sql/share/errmsg.txt | 3 +++ sql/sql_derived.cc | 1 + sql/sql_lex.cc | 16 ++++++++++++++++ sql/sql_lex.h | 2 ++ sql/sql_yacc.yy | 3 +-- sql/table.cc | 1 + 11 files changed, 60 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 43c50998e20..e8e75c82b93 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -502,7 +502,7 @@ deallocate prepare stmt; create table t1 (a varchar(20)); insert into t1 values ('foo'); prepare stmt FROM 'SELECT char_length (a) FROM t1'; -ERROR 42000: FUNCTION test.char_length does not exist +ERROR 42000: FUNCTION test.char_length does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual drop table t1; prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0"; execute stmt; @@ -1147,7 +1147,7 @@ End of 4.1 tests. create table t1 (a varchar(20)); insert into t1 values ('foo'); prepare stmt FROM 'SELECT char_length (a) FROM t1'; -ERROR 42000: FUNCTION test.char_length does not exist +ERROR 42000: FUNCTION test.char_length does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual drop table t1; create table t1 (a char(3) not null, b char(3) not null, c char(3) not null, primary key (a, b, c)); diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index e83e8c2c71d..bf25f93cceb 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1520,3 +1520,13 @@ CALL p1((SELECT * FROM t1))| ERROR 21000: Subquery returns more than 1 row DROP PROCEDURE IF EXISTS p1| DROP TABLE t1| +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (2,2); +SELECT MAX (a) FROM t1 WHERE b = 999999; +ERROR 42000: FUNCTION test.MAX does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT AVG (a) FROM t1 WHERE b = 999999; +AVG (a) +NULL +SELECT non_existent (a) FROM t1 WHERE b = 999999; +ERROR 42000: FUNCTION test.non_existent does not exist +DROP TABLE t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index d9e593fd76f..99bc198259e 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -530,7 +530,7 @@ deallocate prepare stmt; # create table t1 (a varchar(20)); insert into t1 values ('foo'); ---error 1305 +--error ER_FUNC_INEXISTENT_NAME_COLLISION prepare stmt FROM 'SELECT char_length (a) FROM t1'; drop table t1; @@ -1239,7 +1239,7 @@ drop table t1; # create table t1 (a varchar(20)); insert into t1 values ('foo'); ---error 1305 +--error ER_FUNC_INEXISTENT_NAME_COLLISION prepare stmt FROM 'SELECT char_length (a) FROM t1'; drop table t1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index c839b1e4374..8143fd56c6d 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2190,3 +2190,16 @@ delimiter ;| #drop procedure if exists bugNNNN| #--enable_warnings #create procedure bugNNNN... + +# +# Bug #38159: Function parsing problem generates misleading error message +# + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (2,2); +--error ER_FUNC_INEXISTENT_NAME_COLLISION +SELECT MAX (a) FROM t1 WHERE b = 999999; +SELECT AVG (a) FROM t1 WHERE b = 999999; +--error ER_SP_DOES_NOT_EXIST +SELECT non_existent (a) FROM t1 WHERE b = 999999; +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 46e0f30d94e..6737b8cd1b0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5401,6 +5401,14 @@ Item_func_sp::func_name() const } +int my_missing_function_error(const LEX_STRING &token, const char *func_name) +{ + if (token.length && is_lex_native_function (&token)) + return my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name); + else + return my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name); +} + /** @brief Initialize the result field by creating a temporary dummy table @@ -5434,7 +5442,7 @@ Item_func_sp::init_result_field(THD *thd) if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, &thd->sp_func_cache, TRUE))) { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); + my_missing_function_error (m_name->m_name, m_name->m_qname.str); context->process_error(thd); DBUG_RETURN(TRUE); } diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c688ba88b7b..6113b18579f 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5649,3 +5649,6 @@ ER_XA_RBTIMEOUT XA106 eng "XA_RBTIMEOUT: Transaction branch was rolled back: took too long" ER_XA_RBDEADLOCK XA102 eng "XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected" + +ER_FUNC_INEXISTENT_NAME_COLLISION 42000 + eng "FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual" diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 830d1b7c36f..46718f74bd4 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -148,6 +148,7 @@ exit: if (orig_table_list->view) { if (thd->net.last_errno == ER_BAD_FIELD_ERROR || + thd->net.last_errno == ER_FUNC_INEXISTENT_NAME_COLLISION || thd->net.last_errno == ER_SP_DOES_NOT_EXIST) { thd->clear_error(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 436f41dd209..e7c87527d78 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -265,6 +265,22 @@ bool is_keyword(const char *name, uint len) return get_hash_symbol(name,len,0)!=0; } +/** + Check if name is a sql function + + @param name checked name + + @return is this a lex native function or not + @retval 0 name is a function + @retval 1 name isn't a function +*/ + +bool is_lex_native_function(const LEX_STRING *name) +{ + DBUG_ASSERT(name != NULL); + return (get_hash_symbol(name->str, (uint) name->length, 1) != 0); +} + /* make a copy of token before ptr and set yytoklen */ static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5c0367632e1..627003880d9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1390,3 +1390,5 @@ extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end); +extern bool is_lex_native_function(const LEX_STRING *name); +int my_missing_function_error(const LEX_STRING &token, const char *name); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 61020a3eed0..37d2658f46f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5968,8 +5968,7 @@ simple_expr: Reusing ER_SP_DOES_NOT_EXIST have a message consistent with the case when a default database exist, see below. */ - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - "FUNCTION", $1.str); + my_missing_function_error ($1, $1.str); MYSQL_YYABORT; } diff --git a/sql/table.cc b/sql/table.cc index 55a9b50605d..3f34281f746 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2138,6 +2138,7 @@ void TABLE_LIST::hide_view_error(THD *thd) /* Hide "Unknown column" or "Unknown function" error */ if (thd->net.last_errno == ER_BAD_FIELD_ERROR || thd->net.last_errno == ER_SP_DOES_NOT_EXIST || + thd->net.last_errno == ER_FUNC_INEXISTENT_NAME_COLLISION || thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR || thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR || thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR || From 7f50fc02c2893a2ca4751518fccc34357be95821 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Wed, 27 May 2009 15:16:21 +0200 Subject: [PATCH 026/188] Bug#34861: mysqldump with --tab gives weird output for triggers. mysqldump --tab still dumped triggers to stdout rather than to individual tables. We now append triggers to the .sql file for the corresponding table. --events and --routines correspond to a database rather than a table and will still go to stdout with --tab unless redirected with --result-file (-r). client/mysqldump.c: Extend open_sql_file_for_table() so we can open-append. Change dump_triggers_for_table() so it will append its output to the table's .sql-file when --tab is used. mysql-test/r/mysqldump.result: Show that when using --tab, triggers now end up in the .sql file with the corresponding table (after that table), while --routines and --events go to stdout or --result-file. mysql-test/t/mysqldump.test: Show that when using --tab, triggers now end up in the .sql file with the corresponding table (after that table), while --routines and --events go to stdout or --result-file. --- client/mysqldump.c | 48 ++++++++++++++++++------------- mysql-test/r/mysqldump.result | 51 +++++++++++++++++++++++++++++++++ mysql-test/t/mysqldump.test | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 20 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 323376dd8bf..38e37aecba6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1397,18 +1397,19 @@ static char *cover_definer_clause_in_sp(const char *def_str, SYNOPSIS open_sql_file_for_table name name of the table or view + flags flags (as per "man 2 open") RETURN VALUES 0 Failed to open file > 0 Handle of the open file */ -static FILE* open_sql_file_for_table(const char* table) +static FILE* open_sql_file_for_table(const char* table, int flags) { FILE* res; char filename[FN_REFLEN], tmp_path[FN_REFLEN]; convert_dirname(tmp_path,path,NullS); res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), - O_WRONLY, MYF(MY_WME)); + flags, MYF(MY_WME)); return res; } @@ -2290,7 +2291,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (path) { - if (!(sql_file= open_sql_file_for_table(table))) + if (!(sql_file= open_sql_file_for_table(table, O_WRONLY))) DBUG_RETURN(0); write_header(sql_file, db); @@ -2501,7 +2502,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (path) { - if (!(sql_file= open_sql_file_for_table(table))) + if (!(sql_file= open_sql_file_for_table(table, O_WRONLY))) DBUG_RETURN(0); write_header(sql_file, db); } @@ -2725,12 +2726,10 @@ continue_xml: DBUG_RETURN((uint) num_fields); } /* get_table_structure */ -static void dump_trigger_old(MYSQL_RES *show_triggers_rs, +static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs, MYSQL_ROW *show_trigger_row, const char *table_name) { - FILE *sql_file= md_result_file; - char quoted_table_name_buf[NAME_LEN * 2 + 3]; char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1); @@ -2796,11 +2795,10 @@ static void dump_trigger_old(MYSQL_RES *show_triggers_rs, DBUG_VOID_RETURN; } -static int dump_trigger(MYSQL_RES *show_create_trigger_rs, +static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs, const char *db_name, const char *db_cl_name) { - FILE *sql_file= md_result_file; MYSQL_ROW row; int db_cl_altered= FALSE; @@ -2864,22 +2862,28 @@ static int dump_triggers_for_table(char *table_name, char *db_name) uint old_opt_compatible_mode= opt_compatible_mode; MYSQL_RES *show_triggers_rs; MYSQL_ROW row; + FILE *sql_file= md_result_file; char db_cl_name[MY_CS_NAME_SIZE]; + int ret= TRUE; DBUG_ENTER("dump_triggers_for_table"); DBUG_PRINT("enter", ("db: %s, table_name: %s", db_name, table_name)); + if (path && !(sql_file= open_sql_file_for_table(table_name, + O_WRONLY | O_APPEND))) + DBUG_RETURN(1); + /* Do not use ANSI_QUOTES on triggers in dump */ opt_compatible_mode&= ~MASK_ANSI_QUOTES; /* Get database collation. */ if (switch_character_set_results(mysql, "binary")) - DBUG_RETURN(TRUE); + goto done; if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name))) - DBUG_RETURN(TRUE); + goto done; /* Get list of triggers. */ @@ -2888,7 +2892,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name) quote_for_like(table_name, name_buff)); if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff)) - DBUG_RETURN(TRUE); + goto done; /* Dump triggers. */ @@ -2909,17 +2913,15 @@ static int dump_triggers_for_table(char *table_name, char *db_name) provide all the necessary information to restore trigger properly. */ - dump_trigger_old(show_triggers_rs, &row, table_name); + dump_trigger_old(sql_file, show_triggers_rs, &row, table_name); } else { MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql); if (!show_create_trigger_rs || - dump_trigger(show_create_trigger_rs, db_name, db_cl_name)) - { - DBUG_RETURN(TRUE); - } + dump_trigger(sql_file, show_create_trigger_rs, db_name, db_cl_name)) + goto done; mysql_free_result(show_create_trigger_rs); } @@ -2929,7 +2931,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name) mysql_free_result(show_triggers_rs); if (switch_character_set_results(mysql, default_charset)) - DBUG_RETURN(TRUE); + goto done; /* make sure to set back opt_compatible mode to @@ -2937,7 +2939,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name) */ opt_compatible_mode=old_opt_compatible_mode; - DBUG_RETURN(FALSE); + ret= FALSE; + +done: + if (path) + my_fclose(sql_file, MYF(0)); + + DBUG_RETURN(ret); } static void add_load_option(DYNAMIC_STRING *str, const char *option, @@ -4782,7 +4790,7 @@ static my_bool get_view_structure(char *table, char* db) /* If requested, open separate .sql file for this view */ if (path) { - if (!(sql_file= open_sql_file_for_table(table))) + if (!(sql_file= open_sql_file_for_table(table, O_WRONLY))) DBUG_RETURN(1); write_header(sql_file, db); diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index c97131563cb..1345481d6d8 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4226,6 +4226,57 @@ DROP DATABASE mysqldump_test_db; # -- End of test case for Bug#32538. SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; + +Bug #34861 - mysqldump with --tab gives weird output for triggers. + +CREATE TABLE t1 (f1 INT); +CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW SET @f1 = 1; +CREATE PROCEDURE pr1 () SELECT "Meow"; +CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow"; + +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; +name body +pr1 SELECT "Meow" + +dump table; if anything goes to stdout, it ends up here: --------------- + +drop everything +DROP EVENT ev1; +DROP TRIGGER tr1; +DROP TABLE t1; +DROP PROCEDURE pr1; + +reload table; this should restore table and trigger +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; +name body + +reload db; this should restore routines and events +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; +name body +pr1 SELECT "Meow" + +cleanup +DROP EVENT IF EXISTS ev1; +DROP PROCEDURE IF EXISTS pr1; +DROP TRIGGER IF EXISTS tr1; +DROP TABLE IF EXISTS t1; # # End of 5.1 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 4edf887a6b7..8d30728d24b 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1953,6 +1953,59 @@ DROP DATABASE mysqldump_test_db; SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT; +########################################################################### + +--echo +--echo Bug #34861 - mysqldump with --tab gives weird output for triggers. +--echo + +CREATE TABLE t1 (f1 INT); +CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW SET @f1 = 1; +CREATE PROCEDURE pr1 () SELECT "Meow"; +CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow"; + +--echo +SHOW TRIGGERS; +SHOW EVENTS; +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; + +--echo +--echo dump table; if anything goes to stdout, it ends up here: --------------- +--exec $MYSQL_DUMP --compact --routines --triggers --events --result-file=$MYSQLTEST_VARDIR/tmp/test_34861.sql --tab=$MYSQLTEST_VARDIR/tmp/ test + +--echo +--echo drop everything +DROP EVENT ev1; +DROP TRIGGER tr1; +DROP TABLE t1; +DROP PROCEDURE pr1; + +--echo +--echo reload table; this should restore table and trigger +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/t1.sql +SHOW TRIGGERS; +SHOW EVENTS; +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; + +--echo +--echo reload db; this should restore routines and events +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/test_34861.sql +SHOW TRIGGERS; +SHOW EVENTS; +SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; + +--echo +--echo cleanup +--remove_file $MYSQLTEST_VARDIR/tmp/t1.txt +--remove_file $MYSQLTEST_VARDIR/tmp/t1.sql +--remove_file $MYSQLTEST_VARDIR/tmp/test_34861.sql +--disable_warnings +DROP EVENT IF EXISTS ev1; +DROP PROCEDURE IF EXISTS pr1; +DROP TRIGGER IF EXISTS tr1; +DROP TABLE IF EXISTS t1; +--enable_warnings + ########################################################################### --echo # From 1b91400ac6758e3ce28a4ee18123a5c5117c9f7e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 28 May 2009 13:34:30 +0500 Subject: [PATCH 027/188] Bug#37268 'binary' character set makes CLI-internal commands case sensitive The fix is to use case insensitive collation for mysql client command search. client/mysql.cc: The fix is to use case insensitive collation for mysql client command search. mysql-test/r/mysql.result: test result mysql-test/t/mysql.test: test case --- client/mysql.cc | 4 ++-- mysql-test/r/mysql.result | 1 + mysql-test/t/mysql.test | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 89f1f28bb1b..b7d66071ca5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1949,7 +1949,7 @@ static COMMANDS *find_command(char *name,char cmd_char) */ if (strstr(name, "\\g") || (strstr(name, delimiter) && !(strlen(name) >= 9 && - !my_strnncoll(charset_info, + !my_strnncoll(&my_charset_latin1, (uchar*) name, 9, (const uchar*) "delimiter", 9)))) @@ -1970,7 +1970,7 @@ static COMMANDS *find_command(char *name,char cmd_char) { if (commands[i].func && ((name && - !my_strnncoll(charset_info,(uchar*)name,len, + !my_strnncoll(&my_charset_latin1, (uchar*)name, len, (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 5f315bca9c2..d1e8ba1e253 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -198,4 +198,5 @@ COUNT (*) 1 COUNT (*) 1 +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (1) End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 0425b4b9022..45077b5ef80 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -348,4 +348,11 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; --exec $MYSQL --ignore-spaces -e "SELECT COUNT (*)" --exec $MYSQL -b -i -e "SELECT COUNT (*)" +# +# Bug#37268 'binary' character set makes CLI-internal commands case sensitive +# +--error 1 +--exec $MYSQL --default-character-set=binary test -e "CONNECT test invalid_hostname" 2>&1 +--exec $MYSQL --default-character-set=binary test -e "DELIMITER //" 2>&1 + --echo End of 5.0 tests From 4cfc9d771a606117f37e543c1a117887cc58ec40 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 28 May 2009 16:19:49 +0500 Subject: [PATCH 028/188] test case fix --- mysql-test/r/mysql.result | 2 +- mysql-test/t/mysql.test | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index d1e8ba1e253..4affd884753 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -198,5 +198,5 @@ COUNT (*) 1 COUNT (*) 1 -ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (1) +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 45077b5ef80..b2d7400d156 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -351,6 +351,7 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug31060.sql; # # Bug#37268 'binary' character set makes CLI-internal commands case sensitive # +--replace_regex /\([0-9]*\)/(errno)/ --error 1 --exec $MYSQL --default-character-set=binary test -e "CONNECT test invalid_hostname" 2>&1 --exec $MYSQL --default-character-set=binary test -e "DELIMITER //" 2>&1 From 858e118ab9520dc52882b0b796be5c4e975f4451 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Fri, 29 May 2009 15:01:00 +0530 Subject: [PATCH 029/188] Bug#44811 Tests with utf8 charset fail with ibmdb2i on 64bit MySQL wmemset was being used to fill the row buffers. wmemset was intended to fill the buffer with 16-bit UCS2 pad values. However, the 64-bit version of wmemset uses 32-bit wide characters and thus filled the buffer incorrectly. In some cases, the null byte map would be overwritten, causing ctype_utf8.test and ibmdb2i_rir.test to fail, giving the error message CPF5035. This patch eliminates the use of wmemset to fill the row buffer. wmemset has been replaced with memset16, which always fills memory with 16-bit values. storage/ibmdb2i/db2i_conversion.cc: Bug#44811 Tests with utf8 charset fail with ibmdb2i on 64bit MySQL Eliminate the use of wmemset to fill the row buffer. Replace wmemset with memset16, which always fills memory with 16-bit values. storage/ibmdb2i/db2i_misc.h: Bug#44811 Tests with utf8 charset fail with ibmdb2i on 64bit MySQL Eliminate the use of wmemset to fill the row buffer. Replace wmemset with memset16, which always fills memory with 16-bit values. --- storage/ibmdb2i/db2i_conversion.cc | 4 ++-- storage/ibmdb2i/db2i_misc.h | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/storage/ibmdb2i/db2i_conversion.cc b/storage/ibmdb2i/db2i_conversion.cc index bdb8085d937..0acde10a4cd 100644 --- a/storage/ibmdb2i/db2i_conversion.cc +++ b/storage/ibmdb2i/db2i_conversion.cc @@ -1085,7 +1085,7 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char if (bytesToStore) memcpy(db2Buf, dataToStore, bytesToStore); if (bytesToPad) - wmemset((wchar_t*)(db2Buf + bytesToStore), 0x0020, bytesToPad/2); + memset16((db2Buf + bytesToStore), 0x0020, bytesToPad/2); } else { @@ -1108,7 +1108,7 @@ int32 ha_ibmdb2i::convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char bytesToStore = db2BytesToStore; } if (db2BytesToStore < maxDb2BytesToStore) // If need to pad - wmemset((wchar_t*)(db2Buf + db2BytesToStore), 0x0020, (maxDb2BytesToStore - db2BytesToStore)/2); + memset16((db2Buf + db2BytesToStore), 0x0020, (maxDb2BytesToStore - db2BytesToStore)/2); } if (db2FieldType == QMY_VARGRAPHIC) diff --git a/storage/ibmdb2i/db2i_misc.h b/storage/ibmdb2i/db2i_misc.h index 9e20f01208b..f0b527aaad0 100644 --- a/storage/ibmdb2i/db2i_misc.h +++ b/storage/ibmdb2i/db2i_misc.h @@ -109,5 +109,21 @@ bool isOrdinaryIdentifier(const char* s) } return true; } + +/** + Fill memory with a 16-bit word. + @param p Pointer to space to fill. + @param v Value to fill + @param l Length of space (in 16-bit words) +*/ +void memset16(void* p, uint16 v, size_t l) +{ + uint16* p2=(uint16*)p; + while (l--) + { + *(p2++) = v; + } +} + #endif From 66e0ee6639e068f5f713a639d9001a81a7bd1013 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Fri, 29 May 2009 15:37:54 +0200 Subject: [PATCH 030/188] Bug#44658 Create procedure makes server crash when user does not have ALL privilege MySQL crashes if a user without proper privileges attempts to create a procedure. The crash happens because more than one error state is pushed onto the Diagnostic area. In this particular case the user is denied to implicitly create a new user account with the implicitly granted privileges ALTER- and EXECUTE ROUTINE. The new account is needed if the original user account contained a host mask. A user account with a host mask is a distinct user account in this context. An alternative would be to first get the most permissive user account which include the current user connection and then assign privileges to that account. This behavior change is considered out of scope for this bug patch. The implicit assignment of privileges when a user creates a stored routine is a considered to be a feature for user convenience and as such it is not a critical operation. Any failure to complete this operation is thus considered non-fatal (an error becomes a warning). The patch back ports a stack implementation of the internal error handler interface. This enables the use of multiple error handlers so that it is possible to intercept and cancel errors thrown by lower layers. This is needed as a error handler already is used in the call stack emitting the errors which needs to be converted. mysql-test/r/grant.result: * Added test case for bug44658 mysql-test/t/grant.test: * Added test case for bug44658 sql/sp.cc: * Removed non functional parameter no_error and my_error calls as all errors from this function will be converted to a warning anyway. * Change function return type from int to bool. sql/sp.h: * Removed non functional parameter no_error and my_error calls as all errors from this function will be converted to a warning anyway. * Changed function return value from int to bool sql/sql_acl.cc: * Removed the non functional no_error parameter from the function prototype. The function is called from two places and in one of the places we now ignore errors through error handlers. * Introduced the parameter write_to_binlog * Introduced an error handler to cancel any error state from mysql_routine_grant. * Moved my_ok() signal from mysql_routine_grant to make it easier to avoid setting the wrong state in the Diagnostic area. * Changed the broken error state in sp_grant_privileges() to a warning so that if "CREATE PROCEDURE" fails because "Password hash isn't a hexidecimal number" it is still clear what happened. sql/sql_acl.h: * Removed the non functional no_error parameter from the function prototype. The function is called from two places and in one of the places we now ignore errors through error handlers. * Introduced the parameter write_to_binlog * Changed return type for sp_grant_privileges() from int to bool sql/sql_class.cc: * Back ported implementation of internal error handler from 6.0 branch sql/sql_class.h: * Back ported implementation of internal error handler from 6.0 branch sql/sql_parse.cc: * Moved my_ok() signal from mysql_routine_grant() to make it easier to avoid setting the wrong state in the Diagnostic area. --- mysql-test/r/grant.result | 55 ++++++++++++++++++++++++++ mysql-test/t/grant.test | 54 ++++++++++++++++++++++++++ sql/sp.cc | 28 ++++++------- sql/sp.h | 4 +- sql/sql_acl.cc | 82 ++++++++++++++++++++------------------- sql/sql_acl.h | 4 +- sql/sql_class.cc | 29 +++++++++----- sql/sql_class.h | 30 +++++++++++++- sql/sql_parse.cc | 4 +- 9 files changed, 221 insertions(+), 69 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index de80a83d538..a677d71b266 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1358,3 +1358,58 @@ DROP USER 'userbug33464'@'localhost'; USE test; DROP DATABASE dbbug33464; SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; +CREATE USER user1; +CREATE USER user2; +GRANT CREATE ON db1.* TO 'user1'@'localhost'; +GRANT CREATE ROUTINE ON db1.* TO 'user1'@'localhost'; +GRANT CREATE ON db1.* TO 'user2'@'%'; +GRANT CREATE ROUTINE ON db1.* TO 'user2'@'%'; +FLUSH PRIVILEGES; +SHOW GRANTS FOR 'user1'@'localhost'; +Grants for user1@localhost +GRANT USAGE ON *.* TO 'user1'@'localhost' +GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost' +** Connect as user1 and create a procedure. +** The creation will imply implicitly assigned +** EXECUTE and ALTER ROUTINE privileges to +** the current user user1@localhost. +SELECT @@GLOBAL.sql_mode; +@@GLOBAL.sql_mode + +SELECT @@SESSION.sql_mode; +@@SESSION.sql_mode + +CREATE DATABASE db1; +CREATE PROCEDURE db1.proc1(p1 INT) +BEGIN +SET @x = 0; +REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; +END ;|| +** Connect as user2 and create a procedure. +** Implicitly assignment of privileges will +** fail because the user2@localhost is an +** unknown user. +CREATE PROCEDURE db1.proc2(p1 INT) +BEGIN +SET @x = 0; +REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; +END ;|| +Warnings: +Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges +SHOW GRANTS FOR 'user1'@'localhost'; +Grants for user1@localhost +GRANT USAGE ON *.* TO 'user1'@'localhost' +GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `db1`.`proc1` TO 'user1'@'localhost' +SHOW GRANTS FOR 'user2'; +Grants for user2@% +GRANT USAGE ON *.* TO 'user2'@'%' +GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user2'@'%' +DROP PROCEDURE db1.proc1; +DROP PROCEDURE db1.proc2; +REVOKE ALL ON db1.* FROM 'user1'@'localhost'; +REVOKE ALL ON db1.* FROM 'user2'@'%'; +DROP USER 'user1'; +DROP USER 'user1'@'localhost'; +DROP USER 'user2'; +DROP DATABASE db1; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 2e42bdbf06c..bcd393bd6ab 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1471,5 +1471,59 @@ DROP DATABASE dbbug33464; SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; +# +# Bug#44658 Create procedure makes server crash when user does not have ALL privilege +# +CREATE USER user1; +CREATE USER user2; +GRANT CREATE ON db1.* TO 'user1'@'localhost'; +GRANT CREATE ROUTINE ON db1.* TO 'user1'@'localhost'; +GRANT CREATE ON db1.* TO 'user2'@'%'; +GRANT CREATE ROUTINE ON db1.* TO 'user2'@'%'; +FLUSH PRIVILEGES; +SHOW GRANTS FOR 'user1'@'localhost'; +connect (con1,localhost,user1,,); +--echo ** Connect as user1 and create a procedure. +--echo ** The creation will imply implicitly assigned +--echo ** EXECUTE and ALTER ROUTINE privileges to +--echo ** the current user user1@localhost. +SELECT @@GLOBAL.sql_mode; +SELECT @@SESSION.sql_mode; +CREATE DATABASE db1; +DELIMITER ||; +CREATE PROCEDURE db1.proc1(p1 INT) + BEGIN + SET @x = 0; + REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; + END ;|| +DELIMITER ;|| + +connect (con2,localhost,user2,,); +--echo ** Connect as user2 and create a procedure. +--echo ** Implicitly assignment of privileges will +--echo ** fail because the user2@localhost is an +--echo ** unknown user. +DELIMITER ||; +CREATE PROCEDURE db1.proc2(p1 INT) + BEGIN + SET @x = 0; + REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; + END ;|| +DELIMITER ;|| + +connection default; +SHOW GRANTS FOR 'user1'@'localhost'; +SHOW GRANTS FOR 'user2'; +disconnect con1; +disconnect con2; +DROP PROCEDURE db1.proc1; +DROP PROCEDURE db1.proc2; +REVOKE ALL ON db1.* FROM 'user1'@'localhost'; +REVOKE ALL ON db1.* FROM 'user2'@'%'; +DROP USER 'user1'; +DROP USER 'user1'@'localhost'; +DROP USER 'user2'; +DROP DATABASE db1; + # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/sql/sp.cc b/sql/sp.cc index 8c8149d0afc..069cb722c2d 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1308,13 +1308,20 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, /** This is used by sql_acl.cc:mysql_routine_grant() and is used to find the routines in 'routines'. + + @param thd Thread handler + @param routines List of needles in the hay stack + @param any Any of the needles are good enough + + @return + @retval FALSE Found. + @retval TRUE Not found */ -int -sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error) +bool +sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) { TABLE_LIST *routine; - bool result= 0; bool sp_object_found; DBUG_ENTER("sp_exists_routine"); for (routine= routines; routine; routine= routine->next_global) @@ -1336,21 +1343,16 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error) if (sp_object_found) { if (any) - DBUG_RETURN(1); - result= 1; + break; } else if (!any) { - if (!no_error) - { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE", - routine->table_name); - DBUG_RETURN(-1); - } - DBUG_RETURN(0); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE", + routine->table_name); + DBUG_RETURN(TRUE); } } - DBUG_RETURN(result); + DBUG_RETURN(FALSE); } diff --git a/sql/sp.h b/sql/sp.h index 75088ea0b83..75c6856f64b 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -39,8 +39,8 @@ sp_head * sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, bool cache_only); -int -sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any, bool no_error); +bool +sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any); int sp_routine_exists_in_table(THD *thd, int type, sp_name *name); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b1dbb7031ce..83cf37e32dc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3191,26 +3191,24 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } -/* +/** Store routine level grants in the privilege tables - SYNOPSIS - mysql_routine_grant() - thd Thread handle - table_list List of routines to give grant - is_proc true indicates routine list are procedures - user_list List of users to give grant - rights Table level grant - revoke_grant Set to 1 if this is a REVOKE command + @param thd Thread handle + @param table_list List of routines to give grant + @param is_proc Is this a list of procedures? + @param user_list List of users to give grant + @param rights Table level grant + @param revoke_grant Is this is a REVOKE command? - RETURN - 0 ok - 1 error + @return + @retval FALSE Success. + @retval TRUE An error occurred. */ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, List &user_list, ulong rights, - bool revoke_grant, bool no_error) + bool revoke_grant, bool write_to_binlog) { List_iterator str_list (user_list); LEX_USER *Str, *tmp_Str; @@ -3221,22 +3219,20 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (!initialized) { - if (!no_error) - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), - "--skip-grant-tables"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), + "--skip-grant-tables"); DBUG_RETURN(TRUE); } if (rights & ~PROC_ACLS) { - if (!no_error) - my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), - MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); DBUG_RETURN(TRUE); } if (!revoke_grant) { - if (sp_exist_routines(thd, table_list, is_proc, no_error)<0) + if (sp_exist_routines(thd, table_list, is_proc)) DBUG_RETURN(TRUE); } @@ -3317,9 +3313,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, { if (revoke_grant) { - if (!no_error) - my_error(ER_NONEXISTING_PROC_GRANT, MYF(0), - Str->user.str, Str->host.str, table_name); + my_error(ER_NONEXISTING_PROC_GRANT, MYF(0), + Str->user.str, Str->host.str, table_name); result= TRUE; continue; } @@ -3344,16 +3339,14 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); - if (!result && !no_error) + + if (write_to_binlog) { write_bin_log(thd, TRUE, thd->query, thd->query_length); } rw_unlock(&LOCK_grant); - if (!result && !no_error) - my_ok(thd); - /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -6150,21 +6143,20 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, } -/* +/** Grant EXECUTE,ALTER privilege for a stored procedure - SYNOPSIS - sp_grant_privileges() - thd The current thread. - db DB of the stored procedure - name Name of the stored procedure + @param thd The current thread. + @param sp_db + @param sp_name + @param is_proc - RETURN - 0 OK. - < 0 Error. Error message not yet sent. + @return + @retval FALSE Success + @retval TRUE An error occured. Error message not yet sent. */ -int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, bool is_proc) { Security_context *sctx= thd->security_ctx; @@ -6174,6 +6166,7 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, bool result; ACL_USER *au; char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]; + Dummy_error_handler error_handler; DBUG_ENTER("sp_grant_privileges"); if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) @@ -6224,8 +6217,11 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, } else { - my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); - return -1; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_PASSWD_LENGTH, + ER(ER_PASSWD_LENGTH), + SCRAMBLED_PASSWORD_CHAR_LENGTH); + return TRUE; } combo->password.str= passwd_buff; } @@ -6241,8 +6237,14 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh)); + /* + Only care about whether the operation failed or succeeded + as all errors will be handled later. + */ + thd->push_internal_handler(&error_handler); result= mysql_routine_grant(thd, tables, is_proc, user_list, - DEFAULT_CREATE_PROC_ACLS, 0, 1); + DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE); + thd->pop_internal_handler(); DBUG_RETURN(result); } diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 9ae17a4bf02..a8090fba2e7 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -233,7 +233,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table, List &user_list, bool revoke); bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc, List &user_list, ulong rights, - bool revoke, bool no_error); + bool revoke, bool write_to_binlog); my_bool grant_init(); void grant_free(void); my_bool grant_reload(THD *thd); @@ -264,7 +264,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, bool is_proc); -int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, bool is_proc); bool check_routine_level_acl(THD *thd, const char *db, const char *name, bool is_proc); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cf5fdcf27a7..a853ad103ea 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -674,31 +674,40 @@ THD::THD() void THD::push_internal_handler(Internal_error_handler *handler) { - /* - TODO: The current implementation is limited to 1 handler at a time only. - THD and sp_rcontext need to be modified to use a common handler stack. - */ - DBUG_ASSERT(m_internal_handler == NULL); - m_internal_handler= handler; + if (m_internal_handler) + { + handler->m_prev_internal_handler= m_internal_handler; + m_internal_handler= handler; + } + else + { + m_internal_handler= handler; + } } bool THD::handle_error(uint sql_errno, const char *message, MYSQL_ERROR::enum_warning_level level) { - if (m_internal_handler) + if (!m_internal_handler) + return FALSE; + + for (Internal_error_handler *error_handler= m_internal_handler; + error_handler; + error_handler= m_internal_handler->m_prev_internal_handler) { - return m_internal_handler->handle_error(sql_errno, message, level, this); + if (error_handler->handle_error(sql_errno, message, level, this)) + return TRUE; } - return FALSE; // 'FALSE', as per coding style + return FALSE; } void THD::pop_internal_handler() { DBUG_ASSERT(m_internal_handler != NULL); - m_internal_handler= NULL; + m_internal_handler= m_internal_handler->m_prev_internal_handler; } extern "C" diff --git a/sql/sql_class.h b/sql/sql_class.h index ce4524fb982..4e9322dee05 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1036,7 +1036,10 @@ show_system_thread(enum_thread_type thread) class Internal_error_handler { protected: - Internal_error_handler() {} + Internal_error_handler() : + m_prev_internal_handler(NULL) + {} + virtual ~Internal_error_handler() {} public: @@ -1069,6 +1072,28 @@ public: const char *message, MYSQL_ERROR::enum_warning_level level, THD *thd) = 0; +private: + Internal_error_handler *m_prev_internal_handler; + friend class THD; +}; + + +/** + Implements the trivial error handler which cancels all error states + and prevents an SQLSTATE to be set. +*/ + +class Dummy_error_handler : public Internal_error_handler +{ +public: + bool handle_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) + { + /* Ignore error */ + return TRUE; + } }; @@ -2210,6 +2235,9 @@ public: thd_scheduler scheduler; public: + inline Internal_error_handler *get_internal_handler() + { return m_internal_handler; } + /** Add an internal error handler to the thread execution context. @param handler the exception handler to add diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6dbe4a4fd8d..403e7bca964 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3883,7 +3883,9 @@ end_with_restore_list: res= mysql_routine_grant(thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE, lex->users_list, grants, - lex->sql_command == SQLCOM_REVOKE, 0); + lex->sql_command == SQLCOM_REVOKE, TRUE); + if (!res) + my_ok(thd); } else { From 2ba60c19c34d38a513bda6ee9c3a2bb407e2034c Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Fri, 29 May 2009 16:22:24 +0200 Subject: [PATCH 031/188] Bug#39200: optimize table does not recognize ROW_FORMAT=COMPRESSED When doing ALTER TABLE, we forgot to point out that we actually have ROW_FORMAT information (from the original table), so we dropped to "sensible defaults". This affects both ALTER TABLE and OPTIMIZE TABLE which may fall back on ALTER TABLE for InnoDB. We now flag that we do indeed know the row-type, thereby preserving compression-type etc. No .test in 5.1 since we'd need a reasonable new plugin from InnoDB to show this properly; in higher versions, maria can demonstrate this. sql/sql_table.cc: In mysql_alter_table() flag that we have row-type info from old table. In compare_tables(), we must explicitly check whether row-type has changed (rather than rely on the flag which will always be set at this point now). --- sql/sql_table.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5397128855a..d5317995948 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5314,7 +5314,7 @@ compare_tables(TABLE *table, create_info->used_fields & HA_CREATE_USED_ENGINE || create_info->used_fields & HA_CREATE_USED_CHARSET || create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET || - create_info->used_fields & HA_CREATE_USED_ROW_FORMAT || + (table->s->row_type != create_info->row_type) || create_info->used_fields & HA_CREATE_USED_PACK_KEYS || create_info->used_fields & HA_CREATE_USED_MAX_ROWS || (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) || @@ -6307,7 +6307,10 @@ view_err: } if (create_info->row_type == ROW_TYPE_NOT_USED) + { create_info->row_type= table->s->row_type; + create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT; + } DBUG_PRINT("info", ("old type: %s new type: %s", ha_resolve_storage_engine_name(old_db_type), From 7a06fac510167536063e12c22a0cf13b6da8d3ba Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 May 2009 19:45:32 +0200 Subject: [PATCH 032/188] Raise version number after cloning 5.0.83 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 4d2b683b1e3..4fcb1f13f35 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.83) +AM_INIT_AUTOMAKE(mysql, 5.0.84) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=83 +NDB_VERSION_BUILD=84 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From abf5f8dac2a0840687dc99816cbd68fb8c515e50 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Sat, 30 May 2009 21:32:28 +0800 Subject: [PATCH 033/188] BUG#41948 Query_log_event constructor needlessly contorted Make the caller of Query_log_event, Execute_load_log_event constructors and THD::binlog_query to provide the error code instead of having the constructors to figure out the error code. sql/log_event.cc: Changed constructors of Query_log_event and Execute_load_log_event to accept the error code argument instead of figuring it out by itself sql/log_event.h: Changed constructors of Query_log_event and Execute_load_log_event to accept the error code argument --- sql/ha_ndbcluster_binlog.cc | 4 ++- sql/log.cc | 56 ++++++++++++++++++++++++------------- sql/log.h | 2 ++ sql/log_event.cc | 34 ++++++---------------- sql/log_event.h | 6 ++-- sql/sp.cc | 2 +- sql/sp_head.cc | 3 +- sql/sql_acl.cc | 2 +- sql/sql_base.cc | 5 ++-- sql/sql_class.cc | 4 +-- sql/sql_class.h | 2 +- sql/sql_db.cc | 15 ++++++---- sql/sql_delete.cc | 14 ++++++++-- sql/sql_insert.cc | 30 ++++++++++++++++---- sql/sql_load.cc | 13 +++++---- sql/sql_table.cc | 7 +++-- sql/sql_update.cc | 14 ++++++++-- sql/sql_view.cc | 3 +- 18 files changed, 133 insertions(+), 83 deletions(-) diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index baf86d739eb..a0c74b60f84 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1855,9 +1855,11 @@ static void ndb_binlog_query(THD *thd, Cluster_schema *schema) else thd->server_id= schema->any_value; thd->db= schema->db; + int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED); thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query, schema->query_length, FALSE, - schema->name[0] == 0 || thd->db[0] == 0); + schema->name[0] == 0 || thd->db[0] == 0, + errcode); thd->server_id= thd_server_id_save; thd->db= thd_db_save; } diff --git a/sql/log.cc b/sql/log.cc index ed2eff6625d..43696cca1dc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1502,8 +1502,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) YESNO(thd->transaction.stmt.modified_non_trans_table))); if (!in_transaction || all) { - Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE); - qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) + Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); goto end; } @@ -1557,8 +1556,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) transactional table in that statement as well, which needs to be rolled back on the slave. */ - Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE); - qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) + Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); } else if (all && !thd->transaction.all.modified_non_trans_table || @@ -1606,10 +1604,11 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) binlog_trans_log_savepos(thd, (my_off_t*) sv); /* Write it to the binary log */ - + + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); int const error= thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, TRUE, FALSE); + thd->query, thd->query_length, TRUE, FALSE, errcode); DBUG_RETURN(error); } @@ -1625,9 +1624,10 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) if (unlikely(thd->transaction.all.modified_non_trans_table || (thd->options & OPTION_KEEP_LOG))) { + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); int error= thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query, thd->query_length, TRUE, FALSE); + thd->query, thd->query_length, TRUE, FALSE, errcode); DBUG_RETURN(error); } binlog_trans_log_truncate(thd, *(my_off_t*)sv); @@ -4327,6 +4327,35 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) return 0; // All OK } +/* + Helper function to get the error code of the query to be binlogged. + */ +int query_error_code(THD *thd, bool not_killed) +{ + int error; + + if (not_killed) + { + error= thd->is_error() ? thd->main_da.sql_errno() : 0; + + /* thd->main_da.sql_errno() might be ER_SERVER_SHUTDOWN or + ER_QUERY_INTERRUPTED, So here we need to make sure that error + is not set to these errors when specified not_killed by the + caller. + */ + if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED) + error= 0; + } + else + { + /* killed status for DELAYED INSERT thread should never be used */ + DBUG_ASSERT(!(thd->system_thread & SYSTEM_THREAD_DELAYED_INSERT)); + error= thd->killed_errno(); + } + + return error; +} + /** Write a cached log entry to the binary log. - To support transaction over replication, we wrap the transaction @@ -4370,19 +4399,8 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) transaction is either a BEGIN..COMMIT block or a single statement in autocommit mode. */ - Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE); - /* - Imagine this is rollback due to net timeout, after all - statements of the transaction succeeded. Then we want a - zero-error code in BEGIN. In other words, if there was a - really serious error code it's already in the statement's - events, there is no need to put it also in this internally - generated event, and as this event is generated late it would - lead to false alarms. + Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE, 0); - This is safer than thd->clear_error() against kills at shutdown. - */ - qinfo.error_code= 0; /* Now this Query_log_event has artificial log_pos 0. It must be adjusted to reflect the real position in the log. Not doing it diff --git a/sql/log.h b/sql/log.h index d54df8add3b..d71dcc3173d 100644 --- a/sql/log.h +++ b/sql/log.h @@ -581,4 +581,6 @@ enum enum_binlog_format { }; extern TYPELIB binlog_format_typelib; +int query_error_code(THD *thd, bool not_killed); + #endif /* LOG_H */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 651cd1418e3..3b2ec469a4c 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2316,19 +2316,16 @@ Query_log_event::Query_log_event() query_length - size of the `query_arg' array using_trans - there is a modified transactional table suppress_use - suppress the generation of 'USE' statements - killed_status_arg - an optional with default to THD::KILLED_NO_VALUE - if the value is different from the default, the arg - is set to the current thd->killed value. - A caller might need to masquerade thd->killed with - THD::NOT_KILLED. + errcode - the error code of the query + DESCRIPTION Creates an event for binlogging - The value for local `killed_status' can be supplied by caller. + The value for `errcode' should be supplied by caller. */ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, bool using_trans, - bool suppress_use, - THD::killed_state killed_status_arg) + bool suppress_use, int errcode) + :Log_event(thd_arg, (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) | @@ -2349,22 +2346,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, { time_t end_time; - if (killed_status_arg == THD::KILLED_NO_VALUE) - killed_status_arg= thd_arg->killed; - error_code= - (killed_status_arg == THD::NOT_KILLED) ? - (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) : - ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 : - thd_arg->killed_errno()); - - /* thd_arg->main_da.sql_errno() might be ER_SERVER_SHUTDOWN or - ER_QUERY_INTERRUPTED, So here we need to make sure that - error_code is not set to these errors when specified NOT_KILLED - by the caller - */ - if ((killed_status_arg == THD::NOT_KILLED) && - (error_code == ER_SERVER_SHUTDOWN || error_code == ER_QUERY_INTERRUPTED)) - error_code= 0; + error_code= errcode; time(&end_time); exec_time = (ulong) (end_time - thd_arg->start_time); @@ -6619,9 +6601,9 @@ Execute_load_query_log_event(THD *thd_arg, const char* query_arg, uint fn_pos_end_arg, enum_load_dup_handling dup_handling_arg, bool using_trans, bool suppress_use, - THD::killed_state killed_err_arg): + int errcode): Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, - suppress_use, killed_err_arg), + suppress_use, errcode), file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg), fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg) { diff --git a/sql/log_event.h b/sql/log_event.h index bda53da8ab0..617db8c44fc 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1623,8 +1623,7 @@ public: #ifndef MYSQL_CLIENT Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, - bool using_trans, bool suppress_use, - THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE); + bool using_trans, bool suppress_use, int error); const char* get_db() { return db; } #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); @@ -2875,8 +2874,7 @@ public: uint fn_pos_end_arg, enum_load_dup_handling dup_handling_arg, bool using_trans, bool suppress_use, - THD::killed_state - killed_err_arg= THD::KILLED_NO_VALUE); + int errcode); #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); #endif /* HAVE_REPLICATION */ diff --git a/sql/sp.cc b/sql/sp.cc index 069cb722c2d..29e228f5e45 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -941,7 +941,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) /* Such a statement can always go directly to binlog, no trans cache */ thd->binlog_query(THD::MYSQL_QUERY_TYPE, log_query.c_ptr(), log_query.length(), - FALSE, FALSE, THD::NOT_KILLED); + FALSE, FALSE, 0); thd->variables.sql_mode= 0; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1dba8a45926..8a8a5b06cc1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1779,8 +1779,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, thd->options= binlog_save_options; if (thd->binlog_evt_union.unioned_events) { + int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED); Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(), - thd->binlog_evt_union.unioned_events_trans, FALSE); + thd->binlog_evt_union.unioned_events_trans, FALSE, errcode); if (mysql_bin_log.write(&qinfo) && thd->binlog_evt_union.unioned_events_trans) { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index e6655856969..4481d58d38d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1655,7 +1655,7 @@ bool change_password(THD *thd, const char *host, const char *user, new_password)); thd->clear_error(); thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, - FALSE, FALSE, THD::NOT_KILLED); + FALSE, FALSE, 0); } end: close_thread_tables(thd); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d4d813d0fbd..de93c6609f7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1541,7 +1541,7 @@ void close_temporary_tables(THD *thd) thd->variables.character_set_client= system_charset_info; Query_log_event qinfo(thd, s_query.ptr(), s_query.length() - 1 /* to remove trailing ',' */, - 0, FALSE, THD::NOT_KILLED); + 0, FALSE, 0); thd->variables.character_set_client= cs_save; mysql_bin_log.write(&qinfo); thd->variables.pseudo_thread_id= save_pseudo_thread_id; @@ -4015,9 +4015,10 @@ retry: /* this DELETE FROM is needed even with row-based binlogging */ end = strxmov(strmov(query, "DELETE FROM `"), share->db.str,"`.`",share->table_name.str,"`", NullS); + int errcode= query_error_code(thd, TRUE); thd->binlog_query(THD::STMT_QUERY_TYPE, query, (ulong)(end-query), - FALSE, FALSE, THD::NOT_KILLED); + FALSE, FALSE, errcode); my_free(query, MYF(0)); } else diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a853ad103ea..f881f0a792b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3658,7 +3658,7 @@ show_query_type(THD::enum_binlog_query_type qtype) */ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, ulong query_len, bool is_trans, bool suppress_use, - THD::killed_state killed_status_arg) + int errcode) { DBUG_ENTER("THD::binlog_query"); DBUG_PRINT("enter", ("qtype: %s query: '%s'", @@ -3725,7 +3725,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, */ { Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use, - killed_status_arg); + errcode); qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; /* Binlog table maps will be irrelevant after a Query_log_event diff --git a/sql/sql_class.h b/sql/sql_class.h index 4e9322dee05..f4d55917b48 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1914,7 +1914,7 @@ public: int binlog_query(enum_binlog_query_type qtype, char const *query, ulong query_len, bool is_trans, bool suppress_use, - THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE); + int errcode); #endif /* diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 5a266c3fac9..7f77e60138b 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -181,8 +181,7 @@ uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length, static inline void write_to_binlog(THD *thd, char *query, uint q_len, char *db, uint db_len) { - Query_log_event qinfo(thd, query, q_len, 0, 0, THD::NOT_KILLED); - qinfo.error_code= 0; + Query_log_event qinfo(thd, query, q_len, 0, 0, 0); qinfo.db= db; qinfo.db_len= db_len; mysql_bin_log.write(&qinfo); @@ -723,8 +722,9 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, if (mysql_bin_log.is_open()) { + int errcode= query_error_code(thd, TRUE); Query_log_event qinfo(thd, query, query_length, 0, - /* suppress_use */ TRUE, THD::NOT_KILLED); + /* suppress_use */ TRUE, errcode); /* Write should use the database being created as the "current @@ -811,8 +811,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) if (mysql_bin_log.is_open()) { + int errcode= query_error_code(thd, TRUE); Query_log_event qinfo(thd, thd->query, thd->query_length, 0, - /* suppress_use */ TRUE, THD::NOT_KILLED); + /* suppress_use */ TRUE, errcode); /* Write should use the database being created as the "current @@ -958,8 +959,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } if (mysql_bin_log.is_open()) { + int errcode= query_error_code(thd, TRUE); Query_log_event qinfo(thd, query, query_length, 0, - /* suppress_use */ TRUE, THD::NOT_KILLED); + /* suppress_use */ TRUE, errcode); /* Write should use the database being created as the "current database" and not the threads current database, which is the @@ -1958,8 +1960,9 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) /* Step8: logging */ if (mysql_bin_log.is_open()) { + int errcode= query_error_code(thd, TRUE); Query_log_event qinfo(thd, thd->query, thd->query_length, - 0, TRUE, THD::NOT_KILLED); + 0, TRUE, errcode); thd->clear_error(); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 7b967206305..277269f3b0d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -389,8 +389,12 @@ cleanup: FALSE : transactional_table; + int errcode= 0; if (error < 0) thd->clear_error(); + else + errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); + /* [binlog]: If 'handler::delete_all_rows()' was called and the storage engine does not inject the rows itself, we replicate @@ -402,7 +406,7 @@ cleanup: */ int log_result= thd->binlog_query(query_type, thd->query, thd->query_length, - is_trans, FALSE, killed_status); + is_trans, FALSE, errcode); if (log_result && transactional_table) { @@ -836,9 +840,10 @@ void multi_delete::abort() */ if (mysql_bin_log.is_open()) { + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_tables, FALSE); + transactional_tables, FALSE, errcode); } thd->transaction.all.modified_non_trans_table= true; } @@ -979,11 +984,14 @@ bool multi_delete::send_eof() { if (mysql_bin_log.is_open()) { + int errcode= 0; if (local_error == 0) thd->clear_error(); + else + errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_tables, FALSE, killed_status) && + transactional_tables, FALSE, errcode) && !normal_tables) { local_error=1; // Log write failed: roll back the SQL statement diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6c27766ec86..e14e7216a31 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -863,6 +863,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, { if (mysql_bin_log.is_open()) { + int errcode= 0; if (error <= 0) { /* @@ -877,6 +878,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* todo: consider removing */ thd->clear_error(); } + else + errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); + /* bug#22725: A query which per-row-loop can not be interrupted with @@ -893,7 +897,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, transactional_table, FALSE, - (error>0) ? thd->killed : THD::NOT_KILLED) && + errcode) && transactional_table) { error=1; @@ -2667,6 +2671,12 @@ bool Delayed_insert::handle_inserts(void) thd.variables.time_zone = row->time_zone; } + /* if the delayed insert was killed, the killed status is + ignored while binlogging */ + int errcode= 0; + if (thd.killed == THD::NOT_KILLED) + errcode= query_error_code(&thd, TRUE); + /* If the query has several rows to insert, only the first row will come here. In row-based binlogging, this means that the first row will be @@ -2677,7 +2687,7 @@ bool Delayed_insert::handle_inserts(void) */ thd.binlog_query(THD::ROW_QUERY_TYPE, row->query.str, row->query.length, - FALSE, FALSE); + FALSE, FALSE, errcode); thd.time_zone_used = backup_time_zone_used; thd.variables.time_zone = backup_time_zone; @@ -3194,11 +3204,14 @@ bool select_insert::send_eof() */ if (mysql_bin_log.is_open()) { + int errcode= 0; if (!error) thd->clear_error(); + else + errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - trans_table, FALSE, killed_status); + trans_table, FALSE, errcode); } table->file->ha_release_auto_increment(); @@ -3265,8 +3278,11 @@ void select_insert::abort() { if (thd->transaction.stmt.modified_non_trans_table) { if (mysql_bin_log.is_open()) + { + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_table, FALSE); + transactional_table, FALSE, errcode); + } if (!thd->current_stmt_binlog_row_based && !can_rollback_data()) thd->transaction.all.modified_non_trans_table= TRUE; if (changed) @@ -3658,10 +3674,14 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */ if (mysql_bin_log.is_open()) + { + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); thd->binlog_query(THD::STMT_QUERY_TYPE, query.ptr(), query.length(), /* is_trans */ TRUE, - /* suppress_use */ FALSE); + /* suppress_use */ FALSE, + errcode); + } } void select_create::store_values(List &values) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index d4f499b8d44..babd02c0008 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -86,7 +86,7 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, static bool write_execute_load_query_log_event(THD *thd, bool duplicates, bool ignore, bool transactional_table, - THD::killed_state killed_status); + int errcode); #endif /* EMBEDDED_LIBRARY */ /* @@ -483,10 +483,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, /* If the file was not empty, wrote_create_file is true */ if (lf_info.wrote_create_file) { + int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); + if (thd->transaction.stmt.modified_non_trans_table) write_execute_load_query_log_event(thd, handle_duplicates, ignore, transactional_table, - killed_status); + errcode); else { Delete_file_log_event d(thd, db, transactional_table); @@ -528,8 +530,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, read_info.end_io_cache(); if (lf_info.wrote_create_file) { + int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); write_execute_load_query_log_event(thd, handle_duplicates, ignore, - transactional_table,killed_status); + transactional_table, errcode); } } } @@ -553,7 +556,7 @@ err: static bool write_execute_load_query_log_event(THD *thd, bool duplicates, bool ignore, bool transactional_table, - THD::killed_state killed_err_arg) + int errcode) { Execute_load_query_log_event e(thd, thd->query, thd->query_length, @@ -561,7 +564,7 @@ static bool write_execute_load_query_log_event(THD *thd, (uint) ((char*)thd->lex->fname_end - (char*)thd->query), (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), - transactional_table, FALSE, killed_err_arg); + transactional_table, FALSE, errcode); e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; return mysql_bin_log.write(&e); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d5317995948..3f90a950324 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1460,10 +1460,13 @@ void write_bin_log(THD *thd, bool clear_error, { if (mysql_bin_log.is_open()) { + int errcode= 0; if (clear_error) thd->clear_error(); + else + errcode= query_error_code(thd, TRUE); thd->binlog_query(THD::STMT_QUERY_TYPE, - query, query_length, FALSE, FALSE, THD::NOT_KILLED); + query, query_length, FALSE, FALSE, errcode); } } @@ -6180,7 +6183,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - 0, FALSE, THD::NOT_KILLED); + 0, FALSE, 0); mysql_bin_log.write(&qinfo); } my_ok(thd); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index dcccf7f147f..ab6ba2ba756 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -795,11 +795,15 @@ int mysql_update(THD *thd, { if (mysql_bin_log.is_open()) { + int errcode= 0; if (error < 0) thd->clear_error(); + else + errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); + if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_table, FALSE, killed_status) && + transactional_table, FALSE, errcode) && transactional_table) { error=1; // Rollback update @@ -1847,9 +1851,10 @@ void multi_update::abort() got caught and if happens later the killed error is written into repl event. */ + int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_tables, FALSE); + transactional_tables, FALSE, errcode); } thd->transaction.all.modified_non_trans_table= TRUE; } @@ -2075,11 +2080,14 @@ bool multi_update::send_eof() { if (mysql_bin_log.is_open()) { + int errcode= 0; if (local_error == 0) thd->clear_error(); + else + errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_tables, FALSE, killed_status) && + transactional_tables, FALSE, errcode) && trans_safe) { local_error= 1; // Rollback update diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4f207f78688..c81a3ca9aba 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -661,8 +661,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, buff.append(STRING_WITH_LEN(" AS ")); buff.append(views->source.str, views->source.length); + int errcode= query_error_code(thd, TRUE); thd->binlog_query(THD::STMT_QUERY_TYPE, - buff.ptr(), buff.length(), FALSE, FALSE, THD::NOT_KILLED); + buff.ptr(), buff.length(), FALSE, FALSE, errcode); } VOID(pthread_mutex_unlock(&LOCK_open)); From 92e2fa7f17b97d96106ffb537eedd2e3aef850e4 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 30 May 2009 12:38:36 -0300 Subject: [PATCH 034/188] MySQL 5.0 backport of Chad Miller's patch for Bug#34309: Bug#34309: '_PC' macro redefinition For reasons that are now a mystery, we had defined a CPP symbol to help ancient compilers work better (in some way that's lost to history). This interferes with at least one modern compiler. Now, don't define the _PC symbol. Those other underscore-leading symbols are suspect also, but at least the names aren't inscrutable. Let's leave them for now. --- include/my_global.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/my_global.h b/include/my_global.h index 31bcb771c4d..5c07aa00b32 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -527,7 +527,6 @@ C_MODE_END */ #define _VARARGS(X) X #define _STATIC_VARARGS(X) X -#define _PC(X) X #if defined(DBUG_ON) && defined(DBUG_OFF) #undef DBUG_OFF From 5dd1abae7d2f9e56d1c3f54077057bd92387a600 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Sun, 31 May 2009 11:26:58 +0800 Subject: [PATCH 035/188] BUG#43263 BEGIN skipped in some replicate-do-db cases BEGIN/COMMIT/ROLLBACK was subject to replication db rules, and caused the boundary of a transaction not recognized correctly when these queries were ignored by the rules. Fixed the problem by skipping replication db rules for these statements. sql/log_event.cc: Skip checking replication db rules for BEGIN/COMMIT/ROLLBACK statements --- mysql-test/r/binlog.result | 10 +- mysql-test/r/mix_innodb_myisam_binlog.result | 46 +++---- mysql-test/r/rpl_begin_commit_rollback.result | 109 +++++++++++++++ .../t/rpl_begin_commit_rollback-slave.opt | 1 + mysql-test/t/rpl_begin_commit_rollback.test | 124 ++++++++++++++++++ sql/log.cc | 6 +- sql/log_event.cc | 5 +- 7 files changed, 269 insertions(+), 32 deletions(-) create mode 100644 mysql-test/r/rpl_begin_commit_rollback.result create mode 100644 mysql-test/t/rpl_begin_commit_rollback-slave.opt create mode 100644 mysql-test/t/rpl_begin_commit_rollback.test diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result index baab30ebbdd..c885c4ce130 100644 --- a/mysql-test/r/binlog.result +++ b/mysql-test/r/binlog.result @@ -12,10 +12,10 @@ show binlog events from 98; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=innodb master-bin.000001 # Query 1 # use `test`; create table t2 (a int) engine=innodb -master-bin.000001 # Query 1 # use `test`; BEGIN +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test`; insert t1 values (5) master-bin.000001 # Xid 1 # COMMIT /* XID */ -master-bin.000001 # Query 1 # use `test`; BEGIN +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test`; insert t2 values (5) master-bin.000001 # Xid 1 # COMMIT /* XID */ drop table t1,t2; @@ -27,7 +27,7 @@ drop table t1; show binlog events in 'master-bin.000001' from 98; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1 (n int) engine=innodb -master-bin.000001 # Query 1 # use `test`; BEGIN +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test`; insert into t1 values(100 + 4) master-bin.000001 # Query 1 # use `test`; insert into t1 values(99 + 4) master-bin.000001 # Query 1 # use `test`; insert into t1 values(98 + 4) @@ -147,7 +147,7 @@ show binlog events from 0; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 master-bin.000001 98 Query 1 197 use `test`; create table t1(n int) engine=innodb -master-bin.000001 197 Query 1 265 use `test`; BEGIN +master-bin.000001 197 Query 1 265 BEGIN master-bin.000001 265 Query 1 353 use `test`; insert into t1 values (1) master-bin.000001 353 Query 1 441 use `test`; insert into t1 values (2) master-bin.000001 441 Query 1 529 use `test`; insert into t1 values (3) @@ -161,7 +161,7 @@ show binlog events from 0; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 master-bin.000001 98 Query 1 198 use `test`; create table t1 (a int) engine=innodb -master-bin.000001 198 Query 1 266 use `test`; BEGIN +master-bin.000001 198 Query 1 266 BEGIN master-bin.000001 266 Query 1 357 use `test`; insert into t1 values( 400 ) master-bin.000001 357 Query 1 448 use `test`; insert into t1 values( 399 ) master-bin.000001 448 Query 1 539 use `test`; insert into t1 values( 398 ) diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index eda3ff41c89..fa994363287 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -8,7 +8,7 @@ insert into t2 select * from t1; commit; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(1) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 master-bin.000001 # Xid # # COMMIT /* XID */ @@ -23,10 +23,10 @@ Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(2) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 -master-bin.000001 # Query # # use `test`; ROLLBACK +master-bin.000001 # Query # # ROLLBACK delete from t1; delete from t2; reset master; @@ -41,7 +41,7 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back commit; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(3) master-bin.000001 # Query # # use `test`; savepoint my_savepoint master-bin.000001 # Query # # use `test`; insert into t1 values(4) @@ -67,7 +67,7 @@ a 7 show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(5) master-bin.000001 # Query # # use `test`; savepoint my_savepoint master-bin.000001 # Query # # use `test`; insert into t1 values(6) @@ -89,10 +89,10 @@ get_lock("a",10) 1 show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(8) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 -master-bin.000001 # Query # # use `test`; ROLLBACK +master-bin.000001 # Query # # ROLLBACK delete from t1; delete from t2; reset master; @@ -100,7 +100,7 @@ insert into t1 values(9); insert into t2 select * from t1; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(9) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 @@ -112,7 +112,7 @@ begin; insert into t2 select * from t1; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(10) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 @@ -120,11 +120,11 @@ insert into t1 values(11); commit; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(10) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(11) master-bin.000001 # Xid # # COMMIT /* XID */ alter table t2 engine=INNODB; @@ -137,7 +137,7 @@ insert into t2 select * from t1; commit; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(12) master-bin.000001 # Query # # use `test`; insert into t2 select * from t1 master-bin.000001 # Xid # # COMMIT /* XID */ @@ -162,7 +162,7 @@ rollback to savepoint my_savepoint; commit; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(14) master-bin.000001 # Xid # # COMMIT /* XID */ delete from t1; @@ -182,7 +182,7 @@ a 18 show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(16) master-bin.000001 # Query # # use `test`; insert into t1 values(18) master-bin.000001 # Xid # # COMMIT /* XID */ @@ -234,24 +234,24 @@ get_lock("lock1",60) 1 show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values(16) master-bin.000001 # Query # # use `test`; insert into t1 values(18) master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; delete from t1 master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; delete from t2 master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; alter table t2 type=MyISAM -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into t1 values (1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; insert into t2 values (20) master-bin.000001 # Query # # use `test`; drop table t1,t2 master-bin.000001 # Query # # use `test`; create temporary table ti (a int) engine=innodb -master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert into ti values(1) master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; create temporary table t1 (a int) engine=myisam @@ -310,11 +310,11 @@ File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 507 show binlog events from 98; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query 1 # use `test`; BEGIN +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test`; insert into ti values (1) master-bin.000001 # Query 1 # use `test`; insert into ti values (2) master-bin.000001 # Query 1 # use `test`; insert into tt select * from ti -master-bin.000001 # Query 1 # use `test`; ROLLBACK +master-bin.000001 # Query 1 # ROLLBACK select count(*) from ti /* zero */; count(*) 0 @@ -342,11 +342,11 @@ File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 581 show binlog events from 98; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query 1 # use `test`; BEGIN +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test`; insert into ti values (1) master-bin.000001 # Query 1 # use `test`; insert into ti values (2) /* to make the dup error in the following */ master-bin.000001 # Query 1 # use `test`; insert into tt select * from ti /* one affected and error */ -master-bin.000001 # Query 1 # use `test`; ROLLBACK +master-bin.000001 # Query 1 # ROLLBACK select count(*) from ti /* zero */; count(*) 0 diff --git a/mysql-test/r/rpl_begin_commit_rollback.result b/mysql-test/r/rpl_begin_commit_rollback.result new file mode 100644 index 00000000000..23736804784 --- /dev/null +++ b/mysql-test/r/rpl_begin_commit_rollback.result @@ -0,0 +1,109 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +DROP DATABASE IF EXISTS db1; +CREATE DATABASE db1; +use db1; +CREATE TABLE db1.t1 (a INT) ENGINE=InnoDB; +CREATE TABLE db1.t2 (s CHAR(255)) ENGINE=MyISAM; +include/stop_slave.inc +[on master] +CREATE PROCEDURE db1.p1 () +BEGIN +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +INSERT INTO t1 VALUES (5); +END// +CREATE PROCEDURE db1.p2 () +BEGIN +INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (7); +INSERT INTO t1 VALUES (8); +INSERT INTO t1 VALUES (9); +INSERT INTO t1 VALUES (10); +INSERT INTO t2 VALUES ('executed db1.p2()'); +END// +INSERT INTO db1.t2 VALUES ('before call db1.p1()'); +use test; +BEGIN; +CALL db1.p1(); +COMMIT; +INSERT INTO db1.t2 VALUES ('after call db1.p1()'); +SELECT * FROM db1.t1; +a +1 +2 +3 +4 +5 +SELECT * FROM db1.t2; +s +before call db1.p1() +after call db1.p1() +[on slave] +start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_POS; +# +# If we got non-zero here, then we're suffering BUG#43263 +# +SELECT 0 as 'Must be 0'; +Must be 0 +0 +SELECT * from db1.t1; +a +1 +2 +3 +4 +5 +SELECT * from db1.t2; +s +before call db1.p1() +[on master] +INSERT INTO db1.t2 VALUES ('before call db1.p2()'); +BEGIN; +CALL db1.p2(); +ROLLBACK; +INSERT INTO db1.t2 VALUES ('after call db1.p2()'); +SELECT * FROM db1.t1; +a +1 +2 +3 +4 +5 +SELECT * FROM db1.t2; +s +before call db1.p1() +after call db1.p1() +before call db1.p2() +executed db1.p2() +after call db1.p2() +[on slave] +start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_POS; +# +# If we got non-zero here, then we're suffering BUG#43263 +# +SELECT 0 as 'Must be 0'; +Must be 0 +0 +SELECT * from db1.t1; +a +1 +2 +3 +4 +5 +SELECT * from db1.t2; +s +before call db1.p1() +executed db1.p2() +# +# Clean up +# +DROP DATABASE db1; +DROP DATABASE db1; diff --git a/mysql-test/t/rpl_begin_commit_rollback-slave.opt b/mysql-test/t/rpl_begin_commit_rollback-slave.opt new file mode 100644 index 00000000000..b4abda5893f --- /dev/null +++ b/mysql-test/t/rpl_begin_commit_rollback-slave.opt @@ -0,0 +1 @@ +--innodb --replicate-do-db=db1 diff --git a/mysql-test/t/rpl_begin_commit_rollback.test b/mysql-test/t/rpl_begin_commit_rollback.test new file mode 100644 index 00000000000..060cf3c21fc --- /dev/null +++ b/mysql-test/t/rpl_begin_commit_rollback.test @@ -0,0 +1,124 @@ +source include/master-slave.inc; +source include/have_innodb.inc; + +disable_warnings; +DROP DATABASE IF EXISTS db1; +enable_warnings; + +CREATE DATABASE db1; + +use db1; + +CREATE TABLE db1.t1 (a INT) ENGINE=InnoDB; +CREATE TABLE db1.t2 (s CHAR(255)) ENGINE=MyISAM; + +sync_slave_with_master; +source include/stop_slave.inc; +connection master; +echo [on master]; + +DELIMITER //; +CREATE PROCEDURE db1.p1 () +BEGIN + INSERT INTO t1 VALUES (1); + INSERT INTO t1 VALUES (2); + INSERT INTO t1 VALUES (3); + INSERT INTO t1 VALUES (4); + INSERT INTO t1 VALUES (5); +END// + +CREATE PROCEDURE db1.p2 () +BEGIN + INSERT INTO t1 VALUES (6); + INSERT INTO t1 VALUES (7); + INSERT INTO t1 VALUES (8); + INSERT INTO t1 VALUES (9); + INSERT INTO t1 VALUES (10); + INSERT INTO t2 VALUES ('executed db1.p2()'); +END// +DELIMITER ;// + +INSERT INTO db1.t2 VALUES ('before call db1.p1()'); + +# Note: the master_log_pos is set to be the position of the BEGIN + 1, +# so before fix of BUG#43263 if the BEGIN is ignored, then all the +# INSERTS in p1 will be replicated in AUTOCOMMIT=1 mode and the slave +# SQL thread will stop right before the first INSERT. After fix of +# BUG#43263, BEGIN will not be ignored by the replication db rules, +# and then the whole transaction will be executed before slave SQL +# stop. +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +use test; +BEGIN; +CALL db1.p1(); +COMMIT; + +# The position where the following START SLAVE UNTIL will stop at +let $master_end_trans_pos= query_get_value(SHOW MASTER STATUS, Position, 1); + +INSERT INTO db1.t2 VALUES ('after call db1.p1()'); +SELECT * FROM db1.t1; +SELECT * FROM db1.t2; + +connection slave; +echo [on slave]; + +replace_result $master_pos MASTER_POS; +eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_pos; +source include/wait_for_slave_sql_to_stop.inc; +let $slave_sql_stop_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +let $result= query_get_value(SELECT $slave_sql_stop_pos - $master_end_trans_pos as result, result, 1); + +--echo # +--echo # If we got non-zero here, then we're suffering BUG#43263 +--echo # +eval SELECT $result as 'Must be 0'; +SELECT * from db1.t1; +SELECT * from db1.t2; + +connection master; +echo [on master]; + +INSERT INTO db1.t2 VALUES ('before call db1.p2()'); + +# See comments above. +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +BEGIN; +CALL db1.p2(); +disable_warnings; +ROLLBACK; +enable_warnings; +let $master_end_trans_pos= query_get_value(SHOW MASTER STATUS, Position, 1); + +INSERT INTO db1.t2 VALUES ('after call db1.p2()'); +SELECT * FROM db1.t1; +SELECT * FROM db1.t2; + +connection slave; +echo [on slave]; + +replace_result $master_pos MASTER_POS; +eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_pos; +source include/wait_for_slave_sql_to_stop.inc; + +let $slave_sql_stop_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +let $result= query_get_value(SELECT $slave_sql_stop_pos - $master_end_trans_pos as result, result, 1); + +--echo # +--echo # If we got non-zero here, then we're suffering BUG#43263 +--echo # +eval SELECT $result as 'Must be 0'; +SELECT * from db1.t1; +SELECT * from db1.t2; + +--echo # +--echo # Clean up +--echo # +connection master; +DROP DATABASE db1; +connection slave; +DROP DATABASE db1; diff --git a/sql/log.cc b/sql/log.cc index b16303ee232..ec8f5fe820b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -159,7 +159,7 @@ static int binlog_commit(THD *thd, bool all) if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), - TRUE, FALSE, THD::KILLED_NO_VALUE); + TRUE, TRUE, THD::KILLED_NO_VALUE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev)); } @@ -204,7 +204,7 @@ static int binlog_rollback(THD *thd, bool all) if (unlikely(thd->transaction.all.modified_non_trans_table)) { Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), - TRUE, FALSE, THD::KILLED_NO_VALUE); + TRUE, TRUE, THD::KILLED_NO_VALUE); qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE) error= binlog_end_trans(thd, trans_log, &qev); } @@ -2094,7 +2094,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) statement in autocommit mode. */ Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), - TRUE, FALSE, THD::KILLED_NO_VALUE); + TRUE, TRUE, THD::KILLED_NO_VALUE); /* Imagine this is rollback due to net timeout, after all statements of the transaction succeeded. Then we want a diff --git a/sql/log_event.cc b/sql/log_event.cc index 3912308cafa..a440f010fa5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1953,7 +1953,10 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, ::exec_event(), then the companion SET also have so we don't need to reset_one_shot_variables(). */ - if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) + if (!strncmp(query_arg, "BEGIN", q_len_arg) || + !strncmp(query_arg, "COMMIT", q_len_arg) || + !strncmp(query_arg, "ROLLBACK", q_len_arg) || + db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); thd->query_length= q_len_arg; From 83a11b78dfe1b702a0b5d8f2b142d0f0cc75092f Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Sun, 31 May 2009 20:10:59 +0800 Subject: [PATCH 036/188] post fix of test result --- mysql-test/r/bdb_notembedded.result | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result index 2367e0d3fda..71fe9696662 100644 --- a/mysql-test/r/bdb_notembedded.result +++ b/mysql-test/r/bdb_notembedded.result @@ -24,18 +24,18 @@ show binlog events; Log_name Pos Event_type Server_id End_log_pos Info f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb -f n Query 1 n use `test`; BEGIN +f n Query 1 n BEGIN f n Query 1 n use `test`; insert into bug16206 values(0) -f n Query 1 n use `test`; COMMIT -f n Query 1 n use `test`; BEGIN +f n Query 1 n COMMIT +f n Query 1 n BEGIN f n Query 1 n use `test`; insert into bug16206 values(1) -f n Query 1 n use `test`; COMMIT -f n Query 1 n use `test`; BEGIN +f n Query 1 n COMMIT +f n Query 1 n BEGIN f n Query 1 n use `test`; insert into bug16206 values(2) -f n Query 1 n use `test`; COMMIT -f n Query 1 n use `test`; BEGIN +f n Query 1 n COMMIT +f n Query 1 n BEGIN f n Query 1 n use `test`; insert into bug16206 values(3) -f n Query 1 n use `test`; COMMIT +f n Query 1 n COMMIT drop table bug16206; set autocommit=0; End of 5.0 tests From 094ddf226611d119671cd3ac1af40a732540b989 Mon Sep 17 00:00:00 2001 From: Narayanan V Date: Mon, 1 Jun 2009 12:52:10 +0530 Subject: [PATCH 037/188] Bug#45197 cp1250 character set with IBMDB2I generates 2027 error Running a SELECT query over an IBMDB2I table with a cp1250 character set was producing an error 2027 (ibmdb2i error 2027: Error converting single-byte sort sequence to UCS-2). The QMY_DESCRIBE_RANGE API was returning error 2027 to the storage engine because the CCSID used for a cp1250 column (870) does not match the CCSID used by the DB2 sort sequences associated with cp1250_* collations (1153). This was because the storage engine relies on a set of system APIs to determine which CCSID value most closely matches a particular MySQL character set. However, in the case of cp1250, the system is returning CCSID 870, which does not have a codepoint for the euro symbol, making it an incorrect match. This patch overrides the selection of a compatible CCSID to always return 1153 for cp1250. storage/ibmdb2i/db2i_charsetSupport.cc: Bug#45197 cp1250 character set with IBMDB2I generates 2027 error override the selection of a compatible CCSID to always return 1153 for cp1250. --- storage/ibmdb2i/db2i_charsetSupport.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/storage/ibmdb2i/db2i_charsetSupport.cc b/storage/ibmdb2i/db2i_charsetSupport.cc index 1479776d71a..7ff3a8c98f6 100644 --- a/storage/ibmdb2i/db2i_charsetSupport.cc +++ b/storage/ibmdb2i/db2i_charsetSupport.cc @@ -245,11 +245,16 @@ static int32 getNewTextDesc(const int32 inType, else if ((inType == Qlg_TypeAS400CCSID) && (outType == Qlg_TypeAix41)) { // Override non-standard charsets - if (unlikely(strcmp("1148", in) == 0)) + if (strcmp("1148", in) == 0) { strcpy(out, "IBM-1148"); DBUG_RETURN(0); } + else if (unlikely(strcmp("1153", in) == 0)) + { + strcpy(out, "IBM-1153"); + DBUG_RETURN(0); + } } char argBuf[sizeof(ArgList)+15]; @@ -583,6 +588,11 @@ int32 getAssociatedCCSID(const uint16 inCcsid, const int inEncodingScheme, uint1 *outCcsid = 1148; DBUG_RETURN(0); } + else if ((inCcsid == 1250) && (inEncodingScheme == 0x1100)) + { + *outCcsid = 1153; + DBUG_RETURN(0); + } if (!ptrInited) { From 33734e956fb06435168ad4630515c02358871a0e Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 2 Jun 2009 11:38:13 +0500 Subject: [PATCH 038/188] Bug#45152 crash with round() function on longtext column in a derived table The crash happens due to wrong max_length value which is set on Item_func_round::fix_length_and_dec() stage. The value is set to args[0]->max_length which is too big in case of LONGTEXT(LONGBLOB) fields. The fix is to set max_length using float_length() function. mysql-test/r/func_math.result: test result mysql-test/t/func_math.test: test case sql/item_func.cc: The crash happens due to wrong max_length value which is set on Item_func_round::fix_length_and_dec() stage. The value is set to args[0]->max_length which is too big in case of LONGTEXT(LONGBLOB) fields. The fix is to set max_length using float_length() function. --- mysql-test/r/func_math.result | 7 +++++++ mysql-test/t/func_math.test | 9 +++++++++ sql/item_func.cc | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 87cfb5b86a5..9681a8a4302 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -390,4 +390,11 @@ a ROUND(a) -1e+16 -10000000000000002 1e+16 10000000000000002 DROP TABLE t1; +CREATE TABLE t1(f1 LONGTEXT) engine=myisam; +INSERT INTO t1 VALUES ('a'); +SELECT 1 FROM (SELECT ROUND(f1) AS a FROM t1) AS s WHERE a LIKE 'a'; +1 +SELECT 1 FROM (SELECT ROUND(f1, f1) AS a FROM t1) AS s WHERE a LIKE 'a'; +1 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 593cfe90c1b..2c1094213e4 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -250,4 +250,13 @@ SELECT a, ROUND(a) FROM t1; DROP TABLE t1; +# +# Bug#45152 crash with round() function on longtext column in a derived table +# +CREATE TABLE t1(f1 LONGTEXT) engine=myisam; +INSERT INTO t1 VALUES ('a'); +SELECT 1 FROM (SELECT ROUND(f1) AS a FROM t1) AS s WHERE a LIKE 'a'; +SELECT 1 FROM (SELECT ROUND(f1, f1) AS a FROM t1) AS s WHERE a LIKE 'a'; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 46e0f30d94e..2421f7e0526 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1958,8 +1958,8 @@ void Item_func_round::fix_length_and_dec() unsigned_flag= args[0]->unsigned_flag; if (!args[1]->const_item()) { - max_length= args[0]->max_length; decimals= args[0]->decimals; + max_length= float_length(decimals); if (args[0]->result_type() == DECIMAL_RESULT) { max_length++; @@ -1979,8 +1979,8 @@ void Item_func_round::fix_length_and_dec() if (args[0]->decimals == NOT_FIXED_DEC) { - max_length= args[0]->max_length; decimals= min(decimals_to_set, NOT_FIXED_DEC); + max_length= float_length(decimals); hybrid_type= REAL_RESULT; return; } From 4fb78ee4c36b5c6bdec8f49d879a397aa656e639 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 2 Jun 2009 11:07:17 +0200 Subject: [PATCH 039/188] Bug#32430:'show innodb status' causes errors Invalid (old?) table or database name in logs Problem was that InnoDB used filenam_to_tablename, which do not handle partitions (due to the '#' in the filename). Solution is to add a new function for explaining what the filename means: explain_filename. It expands the database, table, partition and subpartition parts and uses errmsg.txt for localization. It also converts from my_charset_filename to system_charset_info (i.e. human readable form for non ascii characters). http://lists.mysql.com/commits/70370 2773 Mattias Jonsson 2009-03-25 It has three different output styles. NOTE: This is the server side ONLY part (introducing the explain_filename function). There will be a patch for InnoDB using this function to solve the bug. sql/mysql_priv.h: Bug#32430:'show innodb status' causes errors Invalid (old?) table or database name in logs Added EXPLAIN_FILENAME_MAX_EXTRA_LENGTH, enum_explain_filename_mode and explain_filename. sql/share/errmsg.txt: Bug#32430:'show innodb status' causes errors Invalid (old?) table or database name in logs Added localization names for Database, Table, Partition, Subpartition Temporary and Renamed. sql/sql_table.cc: Bug#32430:'show innodb status' causes errors Invalid (old?) table or database name in logs Added explain_filename function for giving better information to the user about a specific table/partitions file. --- sql/mysql_priv.h | 10 ++ sql/share/errmsg.txt | 21 ++++ sql/sql_table.cc | 228 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 69a789284b0..dcd572bc824 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2253,6 +2253,16 @@ char *fn_rext(char *name); #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS uint strconvert(CHARSET_INFO *from_cs, const char *from, CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors); +/* depends on errmsg.txt Database `db`, Table `t` ... */ +#define EXPLAIN_FILENAME_MAX_EXTRA_LENGTH 63 +enum enum_explain_filename_mode +{ + EXPLAIN_ALL_VERBOSE= 0, + EXPLAIN_PARTITIONS_VERBOSE, + EXPLAIN_PARTITIONS_AS_COMMENT +}; +uint explain_filename(const char *from, char *to, uint to_length, + enum_explain_filename_mode explain_mode); uint filename_to_tablename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length); uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 7c92c827c87..42bca02984d 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6180,3 +6180,24 @@ ER_TOO_LONG_FIELD_COMMENT ER_FUNC_INEXISTENT_NAME_COLLISION 42000 eng "FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual" + +# When updating these, please update EXPLAIN_FILENAME_MAX_EXTRA_LENGTH in +# mysql_priv.h with the new maximal additional length for explain_filename. +ER_DATABASE_NAME + eng "Database `%s`" + swe "Databas `%s`" +ER_TABLE_NAME + eng "Table `%s`" + swe "Tabell `%s`" +ER_PARTITION_NAME + eng "Partition `%s`" + swe "Partition `%s`" +ER_SUBPARTITION_NAME + eng "Subpartition `%s`" + swe "Subpartition `%s`" +ER_TEMPORARY_NAME + eng "Temporary" + swe "Temporär" +ER_RENAMED_NAME + eng "Renamed" + swe "Namnändrad" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3f90a950324..0fc1d04a41b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -68,6 +68,234 @@ static void wait_for_kill_signal(THD *thd) #endif +/** + @brief Helper function for explain_filename +*/ +static char* add_identifier(char *to_p, const char * end_p, + const char* name, uint name_len, int errcode) +{ + uint res; + uint errors; + const char *conv_name; + char tmp_name[FN_REFLEN]; + char conv_string[FN_REFLEN]; + + DBUG_ENTER("add_identifier"); + if (!name[name_len]) + conv_name= name; + else + { + strnmov(tmp_name, name, name_len); + tmp_name[name_len]= 0; + conv_name= tmp_name; + } + res= strconvert(&my_charset_filename, conv_name, system_charset_info, + conv_string, FN_REFLEN, &errors); + if (!res || errors) + conv_name= name; + else + { + DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string)); + conv_name= conv_string; + } + + if (errcode) + to_p+= my_snprintf(to_p, end_p - to_p, ER(errcode), conv_name); + else + to_p+= my_snprintf(to_p, end_p - to_p, "`%s`", conv_name); + return to_p; +} + + +/** + @brief Explain a path name by split it to database, table etc. + + @details Break down the path name to its logic parts + (database, table, partition, subpartition). + filename_to_tablename cannot be used on partitions, due to the #P# part. + There can be up to 6 '#', #P# for partition, #SP# for subpartition + and #TMP# or #REN# for temporary or renamed partitions. + This should be used when something should be presented to a user in a + diagnostic, error etc. when it would be useful to know what a particular + file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc. + + @param from Path name in my_charset_filename + Null terminated in my_charset_filename, normalized + to use '/' as directory separation character. + @param to Explained name in system_charset_info + @param to_length Size of to buffer + @param explain_mode Requested output format. + EXPLAIN_ALL_VERBOSE -> + [Database `db`, ]Table `tbl`[,[ Temporary| Renamed] + Partition `p` [, Subpartition `sp`]] + EXPLAIN_PARTITIONS_VERBOSE -> `db`.`tbl` + [[ Temporary| Renamed] Partition `p` + [, Subpartition `sp`]] + EXPLAIN_PARTITIONS_AS_COMMENT -> `db`.`tbl` |* + [,[ Temporary| Renamed] Partition `p` + [, Subpartition `sp`]] *| + (| is really a /, and it is all in one line) + + @retval Length of returned string +*/ + +uint explain_filename(const char *from, + char *to, + uint to_length, + enum_explain_filename_mode explain_mode) +{ + uint res= 0; + char *to_p= to; + char *end_p= to_p + to_length; + const char *db_name= NULL; + int db_name_len= 0; + const char *table_name; + int table_name_len= 0; + const char *part_name= NULL; + int part_name_len= 0; + const char *subpart_name= NULL; + int subpart_name_len= 0; + enum enum_file_name_type {NORMAL, TEMP, RENAMED} name_type= NORMAL; + const char *tmp_p; + DBUG_ENTER("explain_filename"); + DBUG_PRINT("enter", ("from '%s'", from)); + tmp_p= from; + table_name= from; + /* + If '/' then take last directory part as database. + '/' is the directory separator, not FN_LIB_CHAR + */ + while ((tmp_p= strchr(tmp_p, '/'))) + { + db_name= table_name; + /* calculate the length */ + db_name_len= tmp_p - db_name; + tmp_p++; + table_name= tmp_p; + } + tmp_p= table_name; + while (!res && (tmp_p= strchr(tmp_p, '#'))) + { + tmp_p++; + switch (tmp_p[0]) { + case 'P': + case 'p': + if (tmp_p[1] == '#') + part_name= tmp_p + 2; + else + res= 1; + tmp_p+= 2; + break; + case 'S': + case 's': + if ((tmp_p[1] == 'P' || tmp_p[1] == 'p') && tmp_p[2] == '#') + { + part_name_len= tmp_p - part_name - 1; + subpart_name= tmp_p + 3; + } + else + res= 2; + tmp_p+= 3; + break; + case 'T': + case 't': + if ((tmp_p[1] == 'M' || tmp_p[1] == 'm') && + (tmp_p[2] == 'P' || tmp_p[2] == 'p') && + tmp_p[3] == '#' && !tmp_p[4]) + name_type= TEMP; + else + res= 3; + tmp_p+= 4; + break; + case 'R': + case 'r': + if ((tmp_p[1] == 'E' || tmp_p[1] == 'e') && + (tmp_p[2] == 'N' || tmp_p[2] == 'n') && + tmp_p[3] == '#' && !tmp_p[4]) + name_type= RENAMED; + else + res= 4; + tmp_p+= 4; + break; + default: + res= 5; + } + } + if (res) + { + /* Better to give something back if we fail parsing, than nothing at all */ + DBUG_PRINT("info", ("Error in explain_filename: %u", res)); + sql_print_warning("Invalid (old?) table or database name '%s'", from); + DBUG_RETURN(my_snprintf(to, to_length, + "", + res, from)); + } + if (part_name) + { + table_name_len= part_name - table_name - 3; + if (subpart_name) + subpart_name_len= strlen(subpart_name); + else + part_name_len= strlen(part_name); + if (name_type != NORMAL) + { + if (subpart_name) + subpart_name_len-= 5; + else + part_name_len-= 5; + } + } + if (db_name) + { + if (explain_mode == EXPLAIN_ALL_VERBOSE) + { + to_p= add_identifier(to_p, end_p, db_name, db_name_len, + ER_DATABASE_NAME); + to_p= strnmov(to_p, ", ", end_p - to_p); + } + else + { + to_p= add_identifier(to_p, end_p, db_name, db_name_len, 0); + to_p= strnmov(to_p, ".", end_p - to_p); + } + } + if (explain_mode == EXPLAIN_ALL_VERBOSE) + to_p= add_identifier(to_p, end_p, table_name, table_name_len, + ER_TABLE_NAME); + else + to_p= add_identifier(to_p, end_p, table_name, table_name_len, 0); + if (part_name) + { + if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT) + to_p= strnmov(to_p, " /* ", end_p - to_p); + else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE) + to_p= strnmov(to_p, " ", end_p - to_p); + else + to_p= strnmov(to_p, ", ", end_p - to_p); + if (name_type != NORMAL) + { + if (name_type == TEMP) + to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p); + else + to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p); + to_p= strnmov(to_p, " ", end_p - to_p); + } + to_p= add_identifier(to_p, end_p, part_name, part_name_len, + ER_PARTITION_NAME); + if (subpart_name) + { + to_p= strnmov(to_p, ", ", end_p - to_p); + to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len, + ER_SUBPARTITION_NAME); + } + if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT) + to_p= strnmov(to_p, " */", end_p - to_p); + } + DBUG_PRINT("exit", ("to '%s'", to)); + DBUG_RETURN(to_p - to); +} + + /* Translate a file name to a table name (WL #1324). From d93325626a57a5ee38ab89f6583cb9cb162a3993 Mon Sep 17 00:00:00 2001 From: Satya B Date: Tue, 2 Jun 2009 18:07:47 +0530 Subject: [PATCH 040/188] Followup Fix for BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback. There is failure on pushbuild machines which are using old compilers complaining about ULLONG_MAX declaration. Changing this to ULONGLONG_MAX to solve the problem. sql/mysqld.cc: Change ULLONG_MAX to ULONGLONG_MAX for the max_binlog_cache_size option --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7843bcbfc2a..eb94e1a8fab 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6583,7 +6583,7 @@ log and this option does nothing anymore.", {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, "Can be used to restrict the total size used to cache a multi-transaction query.", (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0, - GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULLONG_MAX, 0, IO_SIZE, 0}, + GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0}, {"max_binlog_size", OPT_MAX_BINLOG_SIZE, "Binary log will be rotated automatically when the size exceeds this \ value. Will also apply to relay logs if max_relay_log_size is 0. \ From 744373ecc02462839db2800f17d0f92a6ff57968 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 3 Jun 2009 15:18:12 +0400 Subject: [PATCH 041/188] Fix compilation failures: get rid of C++ specifics in C-code. --- client/mysql_upgrade.c | 2 +- client/mysqlcheck.c | 2 +- client/mysqldump.c | 2 +- client/mysqlimport.c | 2 +- client/mysqlshow.c | 2 +- client/mysqlslap.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index bbc0e0f57ec..641d4a38d16 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -234,7 +234,7 @@ get_one_option(int optid, const struct my_option *opt, case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ tty_password= 1; add_option= FALSE; if (argument) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1bdb28f5a11..c59049d8b72 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -287,7 +287,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ if (argument) { char *start = argument; diff --git a/client/mysqldump.c b/client/mysqldump.c index 38e37aecba6..6b2c2a06834 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -703,7 +703,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ if (argument) { char *start=argument; diff --git a/client/mysqlimport.c b/client/mysqlimport.c index ec418244f3d..57aee7379f2 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -222,7 +222,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ if (argument) { char *start=argument; diff --git a/client/mysqlshow.c b/client/mysqlshow.c index e401d6cad8f..15f791ca8fb 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -282,7 +282,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ if (argument) { char *start=argument; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 4cf8c7204ed..316fb6a9da3 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -713,7 +713,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= (char*) ""; /* Don't require password */ if (argument) { char *start= argument; From 11f1ab1069b63b6b6cc445b538e1daffa848d6d7 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 3 Jun 2009 15:14:18 +0100 Subject: [PATCH 042/188] BUG#44270: RESET SLAVE does not reset Last_IO_Error or Last_IO_Errno The server was not cleaning the last IO error and error number when resetting slave. This patch addresses this issue by backporting into 5.1 part of the patch in BUG 34654. A fix for this issue had already been pushed into 6.0 as part of the aforementioned bug, however the patch also included some refactoring. The fix for 5.1 does not take into account the refactoring part. mysql-test/extra/rpl_tests/rpl_reset_slave.test: Backported the test case and improved with deploying include/start_slave.inc in relevant spots. sql/slave.cc: Backported part of patch from 6.0 that includes cleaning mi->clear_error() at: 1. beginning of handle_slave_io 2. on successful connection Also, backported the assertion added in the original patch. sql/sql_repl.cc: Backported the call to mi->clear_error() on reset_slave(). --- .../extra/rpl_tests/rpl_reset_slave.test | 54 +++++++++++++++++++ .../suite/rpl/r/rpl_row_reset_slave.result | 23 ++++++++ .../suite/rpl/r/rpl_stm_reset_slave.result | 23 ++++++++ sql/slave.cc | 3 ++ sql/sql_repl.cc | 1 + 5 files changed, 104 insertions(+) diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 2cc041a35e1..49a142f10c2 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -41,3 +41,57 @@ reset slave; start slave; sync_with_master; show status like 'slave_open_temp_tables'; + +# +#Bug#34654 RESET SLAVE does not clear LAST_IO_Err* +# + +# clearing the status +stop slave; +reset slave; +let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); +echo *** errno must be zero: $last_io_errno ***; + +# +# verifying start slave resets Last_IO_Error and Last_IO_Errno. +# + +change master to master_user='impossible_user_name'; +start slave; +source include/wait_for_slave_io_to_stop.inc; +let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); +--disable_query_log +eval SELECT $last_io_errno > 0 as ONE; +--enable_query_log + +source include/stop_slave.inc; +change master to master_user='root'; +source include/start_slave.inc; +let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); +let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1); +--echo *** last errno must be zero: $last_io_errno *** +--echo *** last error must be blank: $last_io_error *** + +# +# verifying reset slave resets Last_{IO,SQL}_Err{or,no} +# + +source include/stop_slave.inc; +change master to master_user='impossible_user_name'; +start slave; +source include/wait_for_slave_io_to_stop.inc; +let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); +--disable_query_log +eval SELECT $last_io_errno > 0 as ONE; +--enable_query_log + +source include/stop_slave.inc; +reset slave; +let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); +let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1); +let $last_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +let $last_sql_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +--echo *** io last errno must be zero: $last_io_errno *** +--echo *** io last error must be blank: $last_io_error *** +--echo *** sql last errno must be zero: $last_sql_errno *** +--echo *** sql last error must be blank: $last_sql_error *** diff --git a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result index 6126ec4bacc..fa40d8760a8 100644 --- a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result @@ -174,3 +174,26 @@ start slave; show status like 'slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 0 +stop slave; +reset slave; +*** errno must be zero: 0 *** +change master to master_user='impossible_user_name'; +start slave; +ONE +1 +include/stop_slave.inc +change master to master_user='root'; +include/start_slave.inc +*** last errno must be zero: 0 *** +*** last error must be blank: *** +include/stop_slave.inc +change master to master_user='impossible_user_name'; +start slave; +ONE +1 +include/stop_slave.inc +reset slave; +*** io last errno must be zero: 0 *** +*** io last error must be blank: *** +*** sql last errno must be zero: 0 *** +*** sql last error must be blank: *** diff --git a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result index bb89d150af7..78d9d7c41eb 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result @@ -174,3 +174,26 @@ start slave; show status like 'slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 1 +stop slave; +reset slave; +*** errno must be zero: 0 *** +change master to master_user='impossible_user_name'; +start slave; +ONE +1 +include/stop_slave.inc +change master to master_user='root'; +include/start_slave.inc +*** last errno must be zero: 0 *** +*** last error must be blank: *** +include/stop_slave.inc +change master to master_user='impossible_user_name'; +start slave; +ONE +1 +include/stop_slave.inc +reset slave; +*** io last errno must be zero: 0 *** +*** io last error must be blank: *** +*** sql last errno must be zero: 0 *** +*** sql last error must be blank: *** diff --git a/sql/slave.cc b/sql/slave.cc index c379a67201a..679de890801 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2397,6 +2397,7 @@ pthread_handler_t handle_slave_io(void *arg) pthread_detach_this_thread(); thd->thread_stack= (char*) &thd; // remember where our stack is + mi->clear_error(); if (init_slave_thread(thd, SLAVE_THD_IO)) { pthread_cond_broadcast(&mi->start_cond); @@ -2511,6 +2512,7 @@ requesting master dump") || goto connected; }); + DBUG_ASSERT(mi->last_error().number == 0); while (!io_slave_killed(thd,mi)) { ulong event_len; @@ -3710,6 +3712,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, if (!slave_was_killed) { + mi->clear_error(); // clear possible left over reconnect error if (reconnect) { if (!suppress_warnings && global_system_variables.log_warnings) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 06c6c022780..b34b3aef51f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1043,6 +1043,7 @@ int reset_slave(THD *thd, Master_info* mi) Reset errors (the idea is that we forget about the old master). */ + mi->clear_error(); mi->rli.clear_error(); mi->rli.clear_until_condition(); From 8041311e24441351fbb42b5ef99f9fd703fde5da Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 4 Jun 2009 10:28:45 +0500 Subject: [PATCH 043/188] Bug#44798 MySQL engine crashes when creating stored procedures with execute_priv=N The crash happens because of uninitialized lex->ssl_cipher, lex->x509_subject, lex->x509_issuer variables. The fix is to add initialization of these variables for stored procedures&functions. mysql-test/r/sp_notembedded.result: test result mysql-test/t/sp_notembedded.test: test case sql/sql_acl.cc: The crash happens because of uninitialized lex->ssl_cipher, lex->x509_subject, lex->x509_issuer variables. The fix is to add initialization of these variables for stored procedures&functions. --- mysql-test/r/sp_notembedded.result | 7 +++++++ mysql-test/t/sp_notembedded.test | 17 +++++++++++++++++ sql/sql_acl.cc | 1 + 3 files changed, 25 insertions(+) diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index 60e427e17a5..0311162e76d 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -219,3 +219,10 @@ GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION drop user mysqltest_1@localhost; drop procedure 15298_1; drop procedure 15298_2; +INSERT INTO mysql.user (Host, User, Password, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv, Repl_client_priv, Create_view_priv, Show_view_priv, Create_routine_priv, Alter_routine_priv, Create_user_priv, ssl_type, ssl_cipher, x509_issuer, x509_subject, max_questions, max_updates, max_connections, max_user_connections) +VALUES('%', 'mysqltest_1', password(''), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', '', '', '', '', '0', '0', '0', '0'); +FLUSH PRIVILEGES; +CREATE PROCEDURE p1(i INT) BEGIN END; +DROP PROCEDURE p1; +DELETE FROM mysql.user WHERE User='mysqltest_1'; +FLUSH PRIVILEGES; diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index 0839709bdc8..d539d4bf8ab 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -292,6 +292,23 @@ drop user mysqltest_1@localhost; drop procedure 15298_1; drop procedure 15298_2; +# +# Bug#44798 MySQL engine crashes when creating stored procedures with execute_priv=N +# +INSERT INTO mysql.user (Host, User, Password, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv, Repl_client_priv, Create_view_priv, Show_view_priv, Create_routine_priv, Alter_routine_priv, Create_user_priv, ssl_type, ssl_cipher, x509_issuer, x509_subject, max_questions, max_updates, max_connections, max_user_connections) +VALUES('%', 'mysqltest_1', password(''), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'N', '', '', '', '', '0', '0', '0', '0'); +FLUSH PRIVILEGES; + +connect (con1, localhost, mysqltest_1,,); +connection con1; +CREATE PROCEDURE p1(i INT) BEGIN END; +disconnect con1; +connection default; +DROP PROCEDURE p1; + +DELETE FROM mysql.user WHERE User='mysqltest_1'; +FLUSH PRIVILEGES; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f61304a1e26..d5b79eaca4e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5911,6 +5911,7 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, DBUG_RETURN(TRUE); thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; + thd->lex->ssl_cipher= thd->lex->x509_subject= thd->lex->x509_issuer= 0; bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh)); result= mysql_routine_grant(thd, tables, is_proc, user_list, From d7bfc76deccc60636a4fbb4bebc386b9ec6bb184 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 4 Jun 2009 14:35:29 +0500 Subject: [PATCH 044/188] Bug#43827 Server closes connections and restarts Problem: Crash happened with a user-defined utf8 collation, on attempt to insert a value longer than the column to store. Reason: The "ctype" member was not initialized (NULL) when allocating a user-defined utf8 collation, so an attempt to call my_ctype(cs, *str) to check if we loose any important data when truncating the value made the server crash. Fix: Initializing tge "ctype" member to a proper value. mysql-test/r/ctype_ldml.result Adding tests mysql-test/t/ctype_ldml.test Adding tests strings/ctype-uca.c Adding initialization of "ctype" member. modified: mysql-test/r/ctype_ldml.result mysql-test/t/ctype_ldml.test strings/ctype-uca.c --- mysql-test/r/ctype_ldml.result | 8 ++++++++ mysql-test/t/ctype_ldml.test | 9 +++++++++ strings/ctype-uca.c | 1 + 3 files changed, 18 insertions(+) diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result index 5dc9ea35cc3..711921eb526 100644 --- a/mysql-test/r/ctype_ldml.result +++ b/mysql-test/r/ctype_ldml.result @@ -40,6 +40,14 @@ abcd abcd efgh efgh ijkl ijkl DROP TABLE t1; +# +# Bug#43827 Server closes connections and restarts +# +CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci); +INSERT INTO t1 SELECT REPEAT('a',11); +Warnings: +Warning 1265 Data truncated for column 'c1' at row 1 +DROP TABLE t1; show collation like 'ucs2_vn_ci'; Collation Charset Id Default Compiled Sortlen ucs2_vn_ci ucs2 242 8 diff --git a/mysql-test/t/ctype_ldml.test b/mysql-test/t/ctype_ldml.test index 73a23a751e8..db9461bfbf7 100644 --- a/mysql-test/t/ctype_ldml.test +++ b/mysql-test/t/ctype_ldml.test @@ -37,6 +37,15 @@ UPDATE t1 SET col2=col1; SELECT * FROM t1 WHERE col1=col2 ORDER BY col1; DROP TABLE t1; +--echo # +--echo # Bug#43827 Server closes connections and restarts +--echo # +# Crash happened with a user-defined utf8 collation, +# on attempt to insert a string longer than the column can store. +CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci); +INSERT INTO t1 SELECT REPEAT('a',11); +DROP TABLE t1; + # # Vietnamese experimental collation # diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 1ed758bc105..2ea48ddab2f 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7992,6 +7992,7 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t)) static my_bool my_coll_init_uca(CHARSET_INFO *cs, void *(*alloc)(size_t)) { cs->pad_char= ' '; + cs->ctype= my_charset_utf8_unicode_ci.ctype; return create_tailoring(cs, alloc); } From a037071a75cb388a17083ac0cca74e93b2dfd5d6 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 4 Jun 2009 12:52:40 +0300 Subject: [PATCH 045/188] Bug #36995: valgrind error in remove_const during subquery executions When copying the Item class one must copy its attributes as well. mysql-test/r/innodb_mysql.result: Bug #36995: test case mysql-test/t/innodb_mysql.test: Bug #36995: test case sql/item.cc: Bug #36995: copy attributes in the copy constructor --- mysql-test/r/innodb_mysql.result | 12 ++++++++++++ mysql-test/t/innodb_mysql.test | 10 ++++++++++ sql/item.cc | 3 +++ 3 files changed, 25 insertions(+) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b6fc58be4c2..a51dc978f3e 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1303,4 +1303,16 @@ t1 CREATE TABLE `t1` ( CONSTRAINT `f2_ref` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; +# +# Bug #36995: valgrind error in remove_const during subquery executions +# +create table t1 (a bit(1) not null,b int) engine=myisam; +create table t2 (c int) engine=innodb; +explain +select b from t1 where a not in (select b from t1,t2 group by a) group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1 +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 05be75fc368..3c81a27e9ac 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1063,4 +1063,14 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY COMMENT 'My ID#', f2 INTEGER DEFAULT NUL SHOW CREATE TABLE t1; DROP TABLE t1; +--echo # +--echo # Bug #36995: valgrind error in remove_const during subquery executions +--echo # + +create table t1 (a bit(1) not null,b int) engine=myisam; +create table t2 (c int) engine=innodb; +explain +select b from t1 where a not in (select b from t1,t2 group by a) group by a; +DROP TABLE t1,t2; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 7c4e86d756f..7a81e48fcee 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -409,6 +409,7 @@ Item::Item(THD *thd, Item *item): name(item->name), orig_name(item->orig_name), max_length(item->max_length), + name_length(item->name_length), marker(item->marker), decimals(item->decimals), maybe_null(item->maybe_null), @@ -416,7 +417,9 @@ Item::Item(THD *thd, Item *item): unsigned_flag(item->unsigned_flag), with_sum_func(item->with_sum_func), fixed(item->fixed), + is_autogenerated_name(item->is_autogenerated_name), collation(item->collation), + with_subselect(item->with_subselect), cmp_context(item->cmp_context) { next= thd->free_list; // Put in free list From a3ac1f7e7832b92de2d3c9d05cc4b5046c5264f1 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Thu, 4 Jun 2009 13:38:53 +0200 Subject: [PATCH 046/188] Bug#15866 main.sp-fib split from main.sp --- mysql-test/r/sp-fib.result | 46 +++++++++++++++++++++++++++++ mysql-test/r/sp.result | 46 ----------------------------- mysql-test/t/sp-fib.test | 60 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 55 ---------------------------------- 4 files changed, 106 insertions(+), 101 deletions(-) create mode 100644 mysql-test/r/sp-fib.result create mode 100644 mysql-test/t/sp-fib.test diff --git a/mysql-test/r/sp-fib.result b/mysql-test/r/sp-fib.result new file mode 100644 index 00000000000..c51aa7d7ad1 --- /dev/null +++ b/mysql-test/r/sp-fib.result @@ -0,0 +1,46 @@ +drop table if exists t3; +create table t3 ( f bigint unsigned not null ); +drop procedure if exists fib; +create procedure fib(n int unsigned) +begin +if n > 1 then +begin +declare x, y bigint unsigned; +declare c cursor for select f from t3 order by f desc limit 2; +open c; +fetch c into y; +fetch c into x; +close c; +insert into t3 values (x+y); +call fib(n-1); +end; +end if; +end| +set @@max_sp_recursion_depth= 20| +insert into t3 values (0), (1)| +call fib(3)| +select * from t3 order by f asc| +f +0 +1 +1 +2 +delete from t3| +insert into t3 values (0), (1)| +call fib(10)| +select * from t3 order by f asc| +f +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +drop table t3| +drop procedure fib| +set @@max_sp_recursion_depth= 0| diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 236fa3d8681..f66d31a3295 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1337,52 +1337,6 @@ drop procedure opp| drop procedure ip| show procedure status like '%p%'| Db Name Type Definer Modified Created Security_type Comment -drop table if exists t3| -create table t3 ( f bigint unsigned not null )| -drop procedure if exists fib| -create procedure fib(n int unsigned) -begin -if n > 1 then -begin -declare x, y bigint unsigned; -declare c cursor for select f from t3 order by f desc limit 2; -open c; -fetch c into y; -fetch c into x; -close c; -insert into t3 values (x+y); -call fib(n-1); -end; -end if; -end| -set @@max_sp_recursion_depth= 20| -insert into t3 values (0), (1)| -call fib(3)| -select * from t3 order by f asc| -f -0 -1 -1 -2 -delete from t3| -insert into t3 values (0), (1)| -call fib(10)| -select * from t3 order by f asc| -f -0 -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -drop table t3| -drop procedure fib| -set @@max_sp_recursion_depth= 0| drop procedure if exists bar| create procedure bar(x char(16), y int) comment "111111111111" sql security invoker diff --git a/mysql-test/t/sp-fib.test b/mysql-test/t/sp-fib.test new file mode 100644 index 00000000000..e6682395a2c --- /dev/null +++ b/mysql-test/t/sp-fib.test @@ -0,0 +1,60 @@ +# Fibonacci, for recursion test. (Yet Another Numerical series :) +# Split from main.sp due to problems reported in Bug#15866 + +--disable_warnings +drop table if exists t3; +--enable_warnings +create table t3 ( f bigint unsigned not null ); + +# We deliberately do it the awkward way, fetching the last two +# values from the table, in order to exercise various statements +# and table accesses at each turn. +--disable_warnings +drop procedure if exists fib; +--enable_warnings + +# Now for multiple statements... +delimiter |; + +create procedure fib(n int unsigned) +begin + if n > 1 then + begin + declare x, y bigint unsigned; + declare c cursor for select f from t3 order by f desc limit 2; + + open c; + fetch c into y; + fetch c into x; + close c; + insert into t3 values (x+y); + call fib(n-1); + end; + end if; +end| + +# Enable recursion +set @@max_sp_recursion_depth= 20| + +# Minimum test: recursion of 3 levels + +insert into t3 values (0), (1)| + +call fib(3)| + +select * from t3 order by f asc| + +delete from t3| + +# The original test, 20 levels, ran into memory limits on some machines +# and builds. Try 10 instead... + +insert into t3 values (0), (1)| + +call fib(10)| + +select * from t3 order by f asc| +drop table t3| +drop procedure fib| +set @@max_sp_recursion_depth= 0| + diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index e3d3298cc50..a785aa2334f 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1560,61 +1560,6 @@ drop procedure ip| show procedure status like '%p%'| -# Fibonacci, for recursion test. (Yet Another Numerical series :) -# ---disable_warnings -drop table if exists t3| ---enable_warnings -create table t3 ( f bigint unsigned not null )| - -# We deliberately do it the awkward way, fetching the last two -# values from the table, in order to exercise various statements -# and table accesses at each turn. ---disable_warnings -drop procedure if exists fib| ---enable_warnings -create procedure fib(n int unsigned) -begin - if n > 1 then - begin - declare x, y bigint unsigned; - declare c cursor for select f from t3 order by f desc limit 2; - - open c; - fetch c into y; - fetch c into x; - close c; - insert into t3 values (x+y); - call fib(n-1); - end; - end if; -end| - -# Enable recursion -set @@max_sp_recursion_depth= 20| - -# Minimum test: recursion of 3 levels - -insert into t3 values (0), (1)| - -call fib(3)| - -select * from t3 order by f asc| - -delete from t3| - -# The original test, 20 levels, ran into memory limits on some machines -# and builds. Try 10 instead... - -insert into t3 values (0), (1)| - -call fib(10)| - -select * from t3 order by f asc| -drop table t3| -drop procedure fib| -set @@max_sp_recursion_depth= 0| - # # Comment & suid # From e34085fe13c7572ae355b456e5d9eb751bacdf7f Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Fri, 5 Jun 2009 00:23:08 +0200 Subject: [PATCH 047/188] Bug#32149: Long semaphore wait for adaptive hash latch Holding on to the temporary inno hash index latch is an optimization in many cases, but a pessimization in some others. Release temporary latches for those corner cases we (or rather, or customers, thanks!) have identified, that is, when we are about to do something that might take a really long time, like REPAIR or filesort. sql/ha_myisam.cc: Let go of (inno, for now) latch when doing MyISAM-repair. (optimize passes through repair.) ("Stuck" in "Repair with keycache".) sql/sql_insert.cc: Let go of (inno, for now) latch when doing CREATE...SELECT in select_insert::send_data() -- it might take a while. ("stuck" in "Sending data") sql/sql_select.cc: Release temporary (inno, for now) latch on - free_tmp_table() (this can take surprisingly long, "removing tmp table") - create_myisam_from_heap() (HEAP table overflowing onto disk as MyISAM, "converting HEAP to MyISAM") --- sql/ha_myisam.cc | 3 +++ sql/sql_insert.cc | 3 +++ sql/sql_select.cc | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 95b7b338131..086b1209a7a 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1009,6 +1009,9 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) param.out_flag= 0; strmov(fixed_name,file->filename); + // Release latches since this can take a long time + ha_release_temporary_latches(thd); + // Don't lock tables if we have used LOCK TABLE if (!thd->locked_tables && mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK)) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d9027e3f5b9..6d63a0907df 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2935,6 +2935,9 @@ bool select_insert::send_data(List &values) } } + // Release latches in case bulk insert takes a long time + ha_release_temporary_latches(thd); + error= write_record(thd, table, &info); table->auto_increment_field_not_null= FALSE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 587c0b85ce6..437aca866c6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10226,6 +10226,9 @@ free_tmp_table(THD *thd, TABLE *entry) save_proc_info=thd->proc_info; thd_proc_info(thd, "removing tmp table"); + // Release latches since this can take a long time + ha_release_temporary_latches(thd); + if (entry->file) { if (entry->db_stat) @@ -10274,6 +10277,10 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, table->file->print_error(error,MYF(0)); DBUG_RETURN(1); } + + // Release latches since this can take a long time + ha_release_temporary_latches(thd); + new_table= *table; new_table.s= &new_table.share_not_to_be_used; new_table.s->db_type= DB_TYPE_MYISAM; From 6c999d777a63afb8e3770ca667891d4df790ddbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Fri, 5 Jun 2009 13:11:55 +0200 Subject: [PATCH 048/188] Bug#45326 Linker failure for libmysqld with VC++ 2008 - Rename the functions in mysqld that conflict with the one in the external interface defined by mysql.h --- sql/mysql_priv.h | 10 +++++----- sql/sql_parse.cc | 12 ++++++------ sql/sql_prepare.cc | 44 ++++++++++++++++++++++---------------------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ba9bee6e054..10db8d3bb51 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1408,14 +1408,14 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table); /* sql_prepare.cc */ -void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length); -void mysql_stmt_execute(THD *thd, char *packet, uint packet_length); -void mysql_stmt_close(THD *thd, char *packet); +void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length); +void mysqld_stmt_execute(THD *thd, char *packet, uint packet_length); +void mysqld_stmt_close(THD *thd, char *packet); void mysql_sql_stmt_prepare(THD *thd); void mysql_sql_stmt_execute(THD *thd); void mysql_sql_stmt_close(THD *thd); -void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length); -void mysql_stmt_reset(THD *thd, char *packet); +void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length); +void mysqld_stmt_reset(THD *thd, char *packet); void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); void reinit_stmt_before_use(THD *thd, LEX *lex); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2974dff9ea9..d228e66a0df 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1168,12 +1168,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_STMT_EXECUTE: { - mysql_stmt_execute(thd, packet, packet_length); + mysqld_stmt_execute(thd, packet, packet_length); break; } case COM_STMT_FETCH: { - mysql_stmt_fetch(thd, packet, packet_length); + mysqld_stmt_fetch(thd, packet, packet_length); break; } case COM_STMT_SEND_LONG_DATA: @@ -1183,17 +1183,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_STMT_PREPARE: { - mysql_stmt_prepare(thd, packet, packet_length); + mysqld_stmt_prepare(thd, packet, packet_length); break; } case COM_STMT_CLOSE: { - mysql_stmt_close(thd, packet); + mysqld_stmt_close(thd, packet); break; } case COM_STMT_RESET: { - mysql_stmt_reset(thd, packet); + mysqld_stmt_reset(thd, packet); break; } case COM_QUERY: @@ -5708,7 +5708,7 @@ mysql_new_select(LEX *lex, bool move_down) /* Don't evaluate this subquery during statement prepare even if it's a constant one. The flag is switched off in the end of - mysql_stmt_prepare. + mysqld_stmt_prepare. */ if (thd->stmt_arena->is_stmt_prepare()) select_lex->uncacheable|= UNCACHEABLE_PREPARE; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index cd11b6d4c24..cdc79870632 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -716,9 +716,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, prepared statement, parameter markers are replaced with variable names. Example: @verbatim - mysql_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?") + mysqld_stmt_prepare("UPDATE t1 SET a=a*1.25 WHERE a=?") --> general logs gets [Prepare] UPDATE t1 SET a*1.25 WHERE a=?" - mysql_stmt_execute(stmt); + mysqld_stmt_execute(stmt); --> general and binary logs get [Execute] UPDATE t1 SET a*1.25 WHERE a=1" @endverbatim @@ -2056,11 +2056,11 @@ static bool init_param_array(Prepared_statement *stmt) to the client, otherwise an error message is set in THD. */ -void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length) +void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) { Prepared_statement *stmt; bool error; - DBUG_ENTER("mysql_stmt_prepare"); + DBUG_ENTER("mysqld_stmt_prepare"); DBUG_PRINT("prep_query", ("%s", packet)); @@ -2423,7 +2423,7 @@ static void reset_stmt_params(Prepared_statement *stmt) client, otherwise an error message is set in THD. */ -void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) +void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) { uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround ulong stmt_id= uint4korr(packet); @@ -2433,7 +2433,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) uchar *packet_end= packet + packet_length; Prepared_statement *stmt; bool open_cursor; - DBUG_ENTER("mysql_stmt_execute"); + DBUG_ENTER("mysqld_stmt_execute"); packet+= 9; /* stmt_id + 5 bytes of flags */ @@ -2444,7 +2444,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), - llstr(stmt_id, llbuf), "mysql_stmt_execute"); + llstr(stmt_id, llbuf), "mysqld_stmt_execute"); DBUG_VOID_RETURN; } @@ -2522,7 +2522,7 @@ void mysql_sql_stmt_execute(THD *thd) @param packet_length Length of packet */ -void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) +void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length) { /* assume there is always place for 8-16 bytes */ ulong stmt_id= uint4korr(packet); @@ -2530,7 +2530,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) Prepared_statement *stmt; Statement stmt_backup; Server_side_cursor *cursor; - DBUG_ENTER("mysql_stmt_fetch"); + DBUG_ENTER("mysqld_stmt_fetch"); /* First of all clear possible warnings from the previous command */ mysql_reset_thd_for_next_command(thd); @@ -2539,7 +2539,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), - llstr(stmt_id, llbuf), "mysql_stmt_fetch"); + llstr(stmt_id, llbuf), "mysqld_stmt_fetch"); DBUG_VOID_RETURN; } @@ -2580,9 +2580,9 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) This function resets statement to the state it was right after prepare. It can be used to: - - clear an error happened during mysql_stmt_send_long_data + - clear an error happened during mysqld_stmt_send_long_data - cancel long data stream for all placeholders without - having to call mysql_stmt_execute. + having to call mysqld_stmt_execute. - close an open cursor Sends 'OK' packet in case of success (statement was reset) or 'ERROR' packet (unrecoverable error/statement not found/etc). @@ -2591,12 +2591,12 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) @param packet Packet with stmt id */ -void mysql_stmt_reset(THD *thd, char *packet) +void mysqld_stmt_reset(THD *thd, char *packet) { /* There is always space for 4 bytes in buffer */ ulong stmt_id= uint4korr(packet); Prepared_statement *stmt; - DBUG_ENTER("mysql_stmt_reset"); + DBUG_ENTER("mysqld_stmt_reset"); /* First of all clear possible warnings from the previous command */ mysql_reset_thd_for_next_command(thd); @@ -2606,7 +2606,7 @@ void mysql_stmt_reset(THD *thd, char *packet) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), - llstr(stmt_id, llbuf), "mysql_stmt_reset"); + llstr(stmt_id, llbuf), "mysqld_stmt_reset"); DBUG_VOID_RETURN; } @@ -2614,7 +2614,7 @@ void mysql_stmt_reset(THD *thd, char *packet) /* Clear parameters from data which could be set by - mysql_stmt_send_long_data() call. + mysqld_stmt_send_long_data() call. */ reset_stmt_params(stmt); @@ -2635,12 +2635,12 @@ void mysql_stmt_reset(THD *thd, char *packet) we don't send any reply to this command. */ -void mysql_stmt_close(THD *thd, char *packet) +void mysqld_stmt_close(THD *thd, char *packet) { /* There is always space for 4 bytes in packet buffer */ ulong stmt_id= uint4korr(packet); Prepared_statement *stmt; - DBUG_ENTER("mysql_stmt_close"); + DBUG_ENTER("mysqld_stmt_close"); thd->main_da.disable_status(); @@ -2739,7 +2739,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) stmt->state= Query_arena::ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), - "mysql_stmt_send_long_data"); + "mysqld_stmt_send_long_data"); DBUG_VOID_RETURN; } #endif @@ -3163,7 +3163,7 @@ Prepared_statement::set_parameters(String *expanded_query, if (res) { my_error(ER_WRONG_ARGUMENTS, MYF(0), - is_sql_ps ? "EXECUTE" : "mysql_stmt_execute"); + is_sql_ps ? "EXECUTE" : "mysqld_stmt_execute"); reset_stmt_params(this); } return res; @@ -3618,11 +3618,11 @@ error: } -/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */ +/** Common part of DEALLOCATE PREPARE and mysqld_stmt_close. */ void Prepared_statement::deallocate() { - /* We account deallocate in the same manner as mysql_stmt_close */ + /* We account deallocate in the same manner as mysqld_stmt_close */ status_var_increment(thd->status_var.com_stmt_close); /* Statement map calls delete stmt on erase */ thd->stmt_map.erase(this); From 22454390c0ce1c3f90059811548a71ee18cac4f3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 5 Jun 2009 15:05:26 +0300 Subject: [PATCH 049/188] Bug #45286: compilation warnings on mysql-5.0-bugteam on MacOSX Fixed the 5.0-bugteam MacOSX warnings. client/mysqldump.c: Bug #45286: typecasts cmd-line-utils/readline/bind.c: Bug #45286: use variable of right type cmd-line-utils/readline/display.c: Bug #45286: use variable of right type dbug/user.r: Bug #45286: no warnings in generating man pages strings/ctype.c: Bug #45286: typecasts --- client/mysqldump.c | 4 ++-- cmd-line-utils/readline/bind.c | 4 +++- cmd-line-utils/readline/display.c | 2 +- dbug/user.r | 1 + strings/ctype.c | 5 ++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index a9d2788de05..2fd69a3d8c6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3122,7 +3122,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table((uchar*) hash_key,end - hash_key)) + if (include_table((byte*) hash_key,end - hash_key)) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -3143,7 +3143,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table((uchar*) hash_key, end - hash_key)) + if (include_table((byte*) hash_key, end - hash_key)) get_view_structure(table, database); } if (opt_xml) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index baed1dfad49..9d0a803cc6c 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -699,8 +699,10 @@ rl_function_of_keyseq (keyseq, map, type) for (i = 0; keyseq && keyseq[i]; i++) { - unsigned char ic = keyseq[i]; + unsigned char uc = keyseq[i]; + int ic; + ic= uc; if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index 6f63faa9738..54c56954f43 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -1888,7 +1888,7 @@ rl_character_len (c, pos) uc = (unsigned char)c; - if (META_CHAR (uc)) + if (META_CHAR (c)) return ((_rl_output_meta_chars == 0) ? 4 : 1); if (uc == '\t') diff --git a/dbug/user.r b/dbug/user.r index 19de840d0ad..ef67ef7a7cf 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -32,6 +32,7 @@ .\" === Set line length .\".ll 6.5i .TL +.warn 0 D B U G .P 0 C Program Debugging Package diff --git a/strings/ctype.c b/strings/ctype.c index 548005f8463..8902cf958a0 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -327,7 +327,10 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length) { my_wc_t wc; int chlen; - for (; (chlen= cs->cset->mb_wc(cs, &wc, str, strend)) > 0; str+= chlen) + for (; (chlen= cs->cset->mb_wc(cs, &wc, + (const unsigned char *) str, + (const unsigned char *) strend)) > 0; + str+= chlen) { if (wc > 0x7F) return MY_REPERTOIRE_UNICODE30; From 898443572f721803f46855b127bb3d40c2345ecb Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 5 Jun 2009 16:44:38 +0300 Subject: [PATCH 050/188] Bug #45286: compilation warnings on mysql-5.0-bugteam on MacOSX Merged the 5.0 fix to 5.1 and fixed the 5.1 specific warnings. --- client/mysqldump.c | 4 ++-- include/my_sys.h | 2 +- storage/myisammrg/myrg_create.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index f7b894803bd..6b2c2a06834 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4110,7 +4110,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table((byte*) hash_key,end - hash_key)) + if (include_table((uchar*) hash_key,end - hash_key)) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -4131,7 +4131,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table((byte*) hash_key, end - hash_key)) + if (include_table((uchar*) hash_key, end - hash_key)) get_view_structure(table, database); } if (opt_xml) diff --git a/include/my_sys.h b/include/my_sys.h index 01804cd089f..263b567684d 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -511,7 +511,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); ((info)->write_pos + (Count) <=(info)->write_end ?\ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\ ((info)->write_pos+=(Count)),0) : \ - (*(info)->write_function)((info),(Buffer),(Count))) + (*(info)->write_function)((info),(uchar *)(Buffer),(Count))) #define my_b_get(info) \ ((info)->read_pos != (info)->read_end ?\ diff --git a/storage/myisammrg/myrg_create.c b/storage/myisammrg/myrg_create.c index df81b730bfd..eaed470daec 100644 --- a/storage/myisammrg/myrg_create.c +++ b/storage/myisammrg/myrg_create.c @@ -46,7 +46,7 @@ int myrg_create(const char *name, const char **table_names, fn_same(buff,name,4); *(end=strend(buff))='\n'; end[1]=0; - if (my_write(file,(char*) buff,(uint) (end-buff+1), + if (my_write(file,(uchar*) buff,(uint) (end-buff+1), MYF(MY_WME | MY_NABP))) goto err; } From 9c7d7d4ea22e0f80101ef2d6dfa335f8d5d8ad46 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 5 Jun 2009 17:59:23 +0300 Subject: [PATCH 051/188] Bug #43532 : backport of the 5.1 code to 5.0 mysqltest --- client/mysqltest.c | 101 ++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 2f19fad9ea9..0bde230cfe2 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1340,23 +1340,25 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) not present. */ -int diff_check() +int diff_check(const char *diff_name) { - char buf[512]= {0}; - FILE *res_file; - const char *cmd = "diff -v"; - int have_diff = 0; + char buf[512]= {0}; + FILE *res_file; + char cmd[128]; + my_snprintf (cmd, sizeof(cmd), "%s -v", diff_name); + int have_diff = 0; if (!(res_file= popen(cmd, "r"))) die("popen(\"%s\", \"r\") failed", cmd); -/* if diff is not present, nothing will be in stdout to increment have_diff */ + /* if diff is not present, nothing will be in + * stdout to increment have_diff */ if (fgets(buf, sizeof(buf), res_file)) { have_diff += 1; } - pclose(res_file); - return have_diff; + pclose(res_file); + return have_diff; } /* @@ -1377,28 +1379,33 @@ void show_diff(DYNAMIC_STRING* ds, { DYNAMIC_STRING ds_tmp; - int have_diff = 0; + const char *diff_name = 0; if (init_dynamic_string(&ds_tmp, "", 256, 256)) die("Out of memory"); - + /* determine if we have diff on Windows - needs special processing due to return values - on that OS - This test is only done on Windows since it's only needed there - in order to correctly detect non-availibility of 'diff', and - the way it's implemented does not work with default 'diff' on Solaris. - */ + needs special processing due to return values + on that OS + This test is only done on Windows since it's only needed there + in order to correctly detect non-availibility of 'diff', and + the way it's implemented does not work with default 'diff' on Solaris. + */ #ifdef __WIN__ - have_diff = diff_check(); + if (diff_check("diff")) + diff_name = "diff"; + else if (diff_check("mtrdiff")) + diff_name = "mtrdiff"; + else + diff_name = 0; #else - have_diff = 1; + diff_name = "diff"; // Otherwise always assume it's called diff #endif - if (have_diff) + if (diff_name) { /* First try with unified diff */ - if (run_tool("diff", + if (run_tool(diff_name, &ds_tmp, /* Get output from diff in ds_tmp */ "-u", filename1, @@ -1409,7 +1416,7 @@ void show_diff(DYNAMIC_STRING* ds, dynstr_set(&ds_tmp, ""); /* Fallback to context diff with "diff -c" */ - if (run_tool("diff", + if (run_tool(diff_name, &ds_tmp, /* Get output from diff in ds_tmp */ "-c", filename1, @@ -1417,42 +1424,42 @@ void show_diff(DYNAMIC_STRING* ds, "2>&1", NULL) > 1) /* Most "diff" tools return >1 if error */ { - have_diff= 0; - } + diff_name= 0; + } } } -if (!(have_diff)) + if (!(diff_name)) { /* Fallback to dump both files to result file and inform about installing "diff" - */ - - dynstr_set(&ds_tmp, ""); + */ - dynstr_append(&ds_tmp, -"\n" -"The two files differ but it was not possible to execute 'diff' in\n" -"order to show only the difference, tried both 'diff -u' or 'diff -c'.\n" -"Instead the whole content of the two files was shown for you to diff manually. ;)\n\n" -"To get a better report you should install 'diff' on your system, which you\n" -"for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n" + dynstr_set(&ds_tmp, ""); + + dynstr_append(&ds_tmp, + "\n" + "The two files differ but it was not possible to execute 'diff' in\n" + "order to show only the difference, tried both 'diff -u' or 'diff -c'.\n" + "Instead the whole content of the two files was shown for you to diff manually. ;)\n\n" + "To get a better report you should install 'diff' on your system, which you\n" + "for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n" #ifdef __WIN__ -"or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" + "or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" #endif -"\n"); + "\n"); - dynstr_append(&ds_tmp, " --- "); - dynstr_append(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); - cat_file(&ds_tmp, filename1); - dynstr_append(&ds_tmp, "<<<\n --- "); - dynstr_append(&ds_tmp, filename1); - dynstr_append(&ds_tmp, " >>>\n"); - cat_file(&ds_tmp, filename2); - dynstr_append(&ds_tmp, "<<<<\n"); - } + dynstr_append(&ds_tmp, " --- "); + dynstr_append(&ds_tmp, filename1); + dynstr_append(&ds_tmp, " >>>\n"); + cat_file(&ds_tmp, filename1); + dynstr_append(&ds_tmp, "<<<\n --- "); + dynstr_append(&ds_tmp, filename1); + dynstr_append(&ds_tmp, " >>>\n"); + cat_file(&ds_tmp, filename2); + dynstr_append(&ds_tmp, "<<<<\n"); + } if (ds) { @@ -1464,7 +1471,7 @@ if (!(have_diff)) /* Print diff directly to stdout */ fprintf(stderr, "%s\n", ds_tmp.str); } - + dynstr_free(&ds_tmp); } From dd570869f483e5ce6dcd45f3b77e69df585c814a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 5 Jun 2009 18:14:56 +0300 Subject: [PATCH 052/188] Bug #45286: compilation warnings on mysql-5.0-bugteam on MacOSX Implemented a way to circumvent the always true comparison by having nested macros (as suggested on review). --- cmd-line-utils/readline/chardefs.h | 3 ++- cmd-line-utils/readline/display.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd-line-utils/readline/chardefs.h b/cmd-line-utils/readline/chardefs.h index def3a111bd3..36fe7fdd7ac 100644 --- a/cmd-line-utils/readline/chardefs.h +++ b/cmd-line-utils/readline/chardefs.h @@ -59,7 +59,8 @@ #define largest_char 255 /* Largest character value. */ #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) -#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) +#define META_BYTE(c) ((c) > meta_character_threshold) +#define META_CHAR(c) (META_BYTE(c) && (c) <= largest_char) #define CTRL(c) ((c) & control_character_mask) #define META(c) ((c) | meta_character_bit) diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index 54c56954f43..842a586b76b 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -1888,7 +1888,7 @@ rl_character_len (c, pos) uc = (unsigned char)c; - if (META_CHAR (c)) + if (META_BYTE (uc)) return ((_rl_output_meta_chars == 0) ? 4 : 1); if (uc == '\t') From 07f33a21d7f2d5378e5ce419c6951c9b9c8eb2b9 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 5 Jun 2009 19:23:44 +0300 Subject: [PATCH 053/188] Addendum to Bug #45286 : implement reviewer's remarks. --- client/mysqldump.c | 4 ++-- cmd-line-utils/readline/bind.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 2fd69a3d8c6..fa6c21ed273 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3122,7 +3122,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table((byte*) hash_key,end - hash_key)) + if (include_table(hash_key,end - hash_key)) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -3143,7 +3143,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table((byte*) hash_key, end - hash_key)) + if (include_table(hash_key, end - hash_key)) get_view_structure(table, database); } if (opt_xml) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index 9d0a803cc6c..fc7bebfd813 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -699,11 +699,9 @@ rl_function_of_keyseq (keyseq, map, type) for (i = 0; keyseq && keyseq[i]; i++) { - unsigned char uc = keyseq[i]; - int ic; + unsigned char ic = keyseq[i]; - ic= uc; - if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + if (META_BYTE (ic) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) { From 46a4685cdb29ea885ddbec6d500b6c64180706e9 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 5 Jun 2009 13:55:09 -0300 Subject: [PATCH 054/188] The valgrind suppression file (valgrind.supp) must be added to a binary distribution of the server as the MTR valgrind option relies on it to silence unmeaningful warnings. mysql-test/Makefile.am: Install valgrind.supp as part of the test suite. Remove reference to inexistent directory. --- mysql-test/Makefile.am | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 5e3582d5e16..7a56584190d 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -25,6 +25,7 @@ test_SCRIPTS = mtr \ mysql-stress-test.pl nobase_test_DATA = \ + valgrind.supp \ lib/v1/mysql-test-run.pl \ lib/v1/mtr_cases.pl \ lib/v1/mtr_io.pl \ @@ -41,7 +42,6 @@ nobase_test_DATA = \ lib/v1/mtr_im.pl \ lib/v1/mtr_process.pl \ lib/v1/mtr_unique.pl \ -\ lib/mtr_cases.pm \ lib/mtr_gcov.pl \ lib/mtr_gprof.pl \ @@ -69,9 +69,8 @@ nobase_test_DATA = \ SUBDIRS = lib/My/SafeProcess EXTRA_DIST = README \ - valgrind.supp \ $(test_SCRIPTS) \ - $(nobase_test_DATA) + $(nobase_test_DATA) # List of directories containing test + result files and the # related test data files that should be copied @@ -93,7 +92,7 @@ TEST_DIRS = t r include std_data std_data/parts collections \ suite/jp suite/jp/t suite/jp/r suite/jp/std_data suite/jp/include \ suite/manual/t suite/manual/r \ suite/ndb_team suite/ndb_team/t suite/ndb_team/r \ - suite/rpl suite/rpl/data suite/rpl/include suite/rpl/r \ + suite/rpl suite/rpl/include suite/rpl/r \ suite/rpl/t \ suite/stress/include suite/stress/t suite/stress/r \ suite/ndb suite/ndb/t suite/ndb/r \ From 12f91b1d8c45bb84ee5bc7ee4b0b455fbb0e2a90 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 5 Jun 2009 19:16:54 -0300 Subject: [PATCH 055/188] Bug#44672: Assertion failed: thd->transaction.xid_state.xid.is_null() The problem is that when a optimization of read-only transactions (bypass 2-phase commit) was implemented, it removed the code that reseted the XID once a transaction wasn't active anymore: sql/sql_parse.cc: - bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt)); - if (!thd->active_transaction()) - thd->transaction.xid_state.xid.null(); + thd->transaction.stmt.reset(); This mostly worked fine as the transaction commit and rollback functions (in handler.cc) reset the XID once the transaction is ended. But those functions wouldn't reset the XID in case of a empty transaction, leading to a assertion when a new starting a new XA transaction. The solution is to ensure that the XID state is reset when empty transactions are ended (by either commit or rollback). This is achieved by reorganizing the code so that the transaction cleanup routine is invoked whenever a transaction is ended. mysql-test/r/xa.result: Add test case result for Bug#44672 mysql-test/t/xa.test: Add test case for Bug#44672 sql/handler.cc: Invoke transaction cleanup function whenever a transaction is ended. Move XID state reset logic to the transaction cleanup function. sql/sql_class.h: Add XID state reset logic. --- mysql-test/r/xa.result | 6 ++++++ mysql-test/t/xa.test | 11 ++++++++++ sql/handler.cc | 48 ++++++++++++++++++++++++------------------ sql/sql_class.h | 8 +++++++ 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 592cf07522b..92f52b402ec 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -75,3 +75,9 @@ xa rollback 'a','c'; xa start 'a','c'; drop table t1; End of 5.0 tests +xa start 'a'; +xa end 'a'; +xa rollback 'a'; +xa start 'a'; +xa end 'a'; +xa rollback 'a'; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 04ecf518577..a0d5aa60641 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -124,6 +124,17 @@ drop table t1; --echo End of 5.0 tests +# +# Bug#44672: Assertion failed: thd->transaction.xid_state.xid.is_null() +# + +xa start 'a'; +xa end 'a'; +xa rollback 'a'; +xa start 'a'; +xa end 'a'; +xa rollback 'a'; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/handler.cc b/sql/handler.cc index d22ee220dc1..9246c04ce7d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1073,6 +1073,13 @@ int ha_commit_trans(THD *thd, bool all) user, or an implicit commit issued by a DDL. */ THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans= all || thd->transaction.all.ha_list == 0; Ha_trx_info *ha_info= trans->ha_list; my_xid xid= thd->transaction.xid_state.xid.get_my_xid(); @@ -1184,16 +1191,9 @@ end: if (rw_trans) start_waiting_global_read_lock(thd); } - else if (all) - { - /* - A COMMIT of an empty transaction. There may be savepoints. - Destroy them. If the transaction is not empty - savepoints are cleared in ha_commit_one_phase() - or ha_rollback_trans(). - */ + /* Free resources and perform other cleanup even for 'empty' transactions. */ + else if (is_real_trans) thd->transaction.cleanup(); - } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); } @@ -1206,6 +1206,13 @@ int ha_commit_one_phase(THD *thd, bool all) { int error=0; THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans=all || thd->transaction.all.ha_list == 0; Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; DBUG_ENTER("ha_commit_one_phase"); @@ -1227,8 +1234,6 @@ int ha_commit_one_phase(THD *thd, bool all) } trans->ha_list= 0; trans->no_2pc=0; - if (is_real_trans) - thd->transaction.xid_state.xid.null(); if (all) { #ifdef HAVE_QUERY_CACHE @@ -1236,8 +1241,9 @@ int ha_commit_one_phase(THD *thd, bool all) query_cache.invalidate(thd->transaction.changed_tables); #endif thd->variables.tx_isolation=thd->session_tx_isolation; - thd->transaction.cleanup(); } + if (is_real_trans) + thd->transaction.cleanup(); } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); @@ -1249,6 +1255,13 @@ int ha_rollback_trans(THD *thd, bool all) int error=0; THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans=all || thd->transaction.all.ha_list == 0; DBUG_ENTER("ha_rollback_trans"); @@ -1294,18 +1307,13 @@ int ha_rollback_trans(THD *thd, bool all) } trans->ha_list= 0; trans->no_2pc=0; - if (is_real_trans) - { - if (thd->transaction_rollback_request) - thd->transaction.xid_state.rm_error= thd->main_da.sql_errno(); - else - thd->transaction.xid_state.xid.null(); - } + if (is_real_trans && thd->transaction_rollback_request) + thd->transaction.xid_state.rm_error= thd->main_da.sql_errno(); if (all) thd->variables.tx_isolation=thd->session_tx_isolation; } /* Always cleanup. Even if there nht==0. There may be savepoints. */ - if (all) + if (is_real_trans) thd->transaction.cleanup(); #endif /* USING_TRANSACTIONS */ if (all) diff --git a/sql/sql_class.h b/sql/sql_class.h index f4d55917b48..ae7f2a51428 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1464,6 +1464,14 @@ public: { changed_tables= 0; savepoints= 0; + /* + If rm_error is raised, it means that this piece of a distributed + transaction has failed and must be rolled back. But the user must + rollback it explicitly, so don't start a new distributed XA until + then. + */ + if (!xid_state.rm_error) + xid_state.xid.null(); #ifdef USING_TRANSACTIONS free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); #endif From 6e422ce034e5e4a1775c8b28abb8f5deca3f1bd9 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Sat, 6 Jun 2009 15:05:44 +0200 Subject: [PATCH 056/188] Addendum to Bug #45286: backport macro name form other tree use same (slightly unwieldy) name in all trees; fix before this version goes "public". bless ctype to avoid upmerge conflict, le sigh. --- cmd-line-utils/readline/bind.c | 2 +- cmd-line-utils/readline/chardefs.h | 4 ++-- cmd-line-utils/readline/display.c | 2 +- strings/ctype.c | 5 ++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index fc7bebfd813..2338f73f6c9 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -701,7 +701,7 @@ rl_function_of_keyseq (keyseq, map, type) { unsigned char ic = keyseq[i]; - if (META_BYTE (ic) && _rl_convert_meta_chars_to_ascii) + if (META_CHAR_FOR_UCHAR (ic) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) { diff --git a/cmd-line-utils/readline/chardefs.h b/cmd-line-utils/readline/chardefs.h index 36fe7fdd7ac..0787d9943bb 100644 --- a/cmd-line-utils/readline/chardefs.h +++ b/cmd-line-utils/readline/chardefs.h @@ -59,8 +59,8 @@ #define largest_char 255 /* Largest character value. */ #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) -#define META_BYTE(c) ((c) > meta_character_threshold) -#define META_CHAR(c) (META_BYTE(c) && (c) <= largest_char) +#define META_CHAR_FOR_UCHAR(c) ((c) > meta_character_threshold) +#define META_CHAR(c) (META_CHAR_FOR_UCHAR(c) && (c) <= largest_char) #define CTRL(c) ((c) & control_character_mask) #define META(c) ((c) | meta_character_bit) diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index 842a586b76b..a68ddff8c88 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -1888,7 +1888,7 @@ rl_character_len (c, pos) uc = (unsigned char)c; - if (META_BYTE (uc)) + if (META_CHAR_FOR_UCHAR (uc)) return ((_rl_output_meta_chars == 0) ? 4 : 1); if (uc == '\t') diff --git a/strings/ctype.c b/strings/ctype.c index 4a54d898337..17ad1256e74 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -328,9 +328,8 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length) { my_wc_t wc; int chlen; - for (; (chlen= cs->cset->mb_wc(cs, &wc, - (const unsigned char *) str, - (const unsigned char *) strend)) > 0; + for (; + (chlen= cs->cset->mb_wc(cs, &wc, (uchar*) str, (uchar*) strend)) > 0; str+= chlen) { if (wc > 0x7F) From 07547c7d4a7e653b9ef2db53ecaae56c392b8e6a Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 6 Jun 2009 12:26:39 -0300 Subject: [PATCH 057/188] Don't mix declarations and code (not widely portable). client/mysqltest.c: Don't mix declarations and code. Tid up function code. --- client/mysqltest.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 0bde230cfe2..f81968ee5a2 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1329,38 +1329,43 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) DBUG_RETURN(ret); } + /* Test if diff is present. This is needed on Windows systems as the OS returns 1 whether diff is successful or if it is not present. - + We run diff -v and look for output in stdout. We don't redirect stderr to stdout to make for a simplified check Windows will output '"diff"' is not recognized... to stderr if it is not present. */ -int diff_check(const char *diff_name) +#ifdef __WIN__ + +static int diff_check(const char *diff_name) { - char buf[512]= {0}; FILE *res_file; - char cmd[128]; - my_snprintf (cmd, sizeof(cmd), "%s -v", diff_name); - int have_diff = 0; + char buf[128]; + int have_diff= 0; - if (!(res_file= popen(cmd, "r"))) - die("popen(\"%s\", \"r\") failed", cmd); + my_snprintf(buf, sizeof(buf), "%s -v", diff_name); - /* if diff is not present, nothing will be in - * stdout to increment have_diff */ + if (!(res_file= popen(buf, "r"))) + die("popen(\"%s\", \"r\") failed", buf); + + /* if diff is not present, nothing will be in stdout to increment have_diff */ if (fgets(buf, sizeof(buf), res_file)) - { - have_diff += 1; - } + have_diff= 1; + pclose(res_file); + return have_diff; } +#endif + + /* Show the diff of two files using the systems builtin diff command. If no such diff command exist, just dump the content From ed7f0f3023041cc1749077ad45cd5a8bb8fa784e Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Mon, 8 Jun 2009 01:40:53 +0500 Subject: [PATCH 058/188] Bug #44886: SIGSEGV in test_if_skip_sort_order() - uninitialized variable used as subscript Grouping select from a "constant" InnoDB table (a table of a single row) joined with other tables caused a crash. mysql-test/r/innodb_mysql.result: Added test case for bug bug #44886. mysql-test/t/innodb_mysql.test: Added test case for bug bug #44886. sql/sql_select.cc: Bug #44886: SIGSEGV in test_if_skip_sort_order() - uninitialized variable used as subscript 1. The test_if_order_by_key function returned unitialized used_key_parts parameter in case of a "constant" InnoDB table. Calling function uses this parameter values as an array index, thus sometimes it caused a crash. The test_if_order_by_key function has been modified to set used_key_parts to 0 (no need for ordering). 2. The test_if_skip_sort_order function has been modified to accept zero used_key_parts value and to prevent an array access by negative index. --- mysql-test/r/innodb_mysql.result | 17 +++++++++++++++++ mysql-test/t/innodb_mysql.test | 21 +++++++++++++++++++++ sql/sql_select.cc | 6 +++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 7e4359e1f92..272782f6647 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2120,4 +2120,21 @@ a b 4 14 5 5 DROP TABLE t1, t2, t3, t4; +# +# Bug#44886: SIGSEGV in test_if_skip_sort_order() - +# uninitialized variable used as subscript +# +CREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY (b), KEY (a,c)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1,0); +CREATE TABLE t2 (a INT, b INT, e INT, KEY (e)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,2); +CREATE TABLE t3 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1, 1); +SELECT * FROM t1, t2, t3 +WHERE t1.a = t3.a AND (t1.b = t3.b OR t1.d) AND t2.b = t1.b AND t2.e = 2 +GROUP BY t1.b; +a b c d a b e a b +1 1 1 0 1 1 2 1 1 +DROP TABLE t1, t2, t3; End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 1b2b861dffb..3e1968b8007 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -359,4 +359,25 @@ SELECT * FROM t4; DROP TABLE t1, t2, t3, t4; +--echo # +--echo # Bug#44886: SIGSEGV in test_if_skip_sort_order() - +--echo # uninitialized variable used as subscript +--echo # + +CREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY (b), KEY (a,c)) + ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1,0); + +CREATE TABLE t2 (a INT, b INT, e INT, KEY (e)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,2); + +CREATE TABLE t3 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1, 1); + +SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND (t1.b = t3.b OR t1.d) AND t2.b = t1.b AND t2.e = 2 + GROUP BY t1.b; + +DROP TABLE t1, t2, t3; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 06776f5f7b3..526b926d66d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12658,7 +12658,10 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, one row). The sorting doesn't matter. */ if (key_part == key_part_end && reverse == 0) + { + *used_key_parts= 0; DBUG_RETURN(1); + } } else DBUG_RETURN(0); @@ -13155,7 +13158,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, select_limit= table_records; if (group) { - rec_per_key= keyinfo->rec_per_key[used_key_parts-1]; + rec_per_key= used_key_parts ? keyinfo->rec_per_key[used_key_parts-1] + : 1; set_if_bigger(rec_per_key, 1); /* With a grouping query each group containing on average From 1b1ca7fe38bdabed77f3009d818f2499f72f8d96 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 7 Jun 2009 23:28:08 +0100 Subject: [PATCH 059/188] BUG#42941: --database paramater to mysqlbinlog fails with RBR mysqlbinlog --database parameter was being ignored when processing row events. As such no event filtering would take place. This patch addresses this by deploying a call to shall_skip_database when table_map_events are handled (as these contain also the name of the database). All other rows events referencing the table id for the filtered map event, will also be skipped. client/mysqlbinlog.cc: Added shall_skip_database call to the part of the code that handles Table_map_log_events. It inspects the database name and decides whether to filter the event or not. Furthermore, if table map event is filtered next events referencing the table id in the table map event, will also be filtered. mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test: Test case that checks if row events are actually filtered out. sql/log_event.h: Added a map for holding the currently ignored table map events. Table map events are inserted when they shall be skipped and removed once the last row event in the statement is processed. --- client/mysqlbinlog.cc | 56 ++++++- .../r/binlog_row_mysqlbinlog_db_filter.result | 43 ++++++ .../t/binlog_row_mysqlbinlog_db_filter.test | 143 ++++++++++++++++++ sql/log_event.h | 1 + 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result create mode 100644 mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 1864786e3c6..042a7957956 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -681,6 +681,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, { char ll_buff[21]; Log_event_type ev_type= ev->get_type_code(); + my_bool destroy_evt= TRUE; DBUG_ENTER("process_event"); print_event_info->short_form= short_form; Exit_status retval= OK_CONTINUE; @@ -871,12 +872,63 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, break; } case TABLE_MAP_EVENT: + { + Table_map_log_event *map= ((Table_map_log_event *)ev); + if (shall_skip_database(map->get_db_name())) + { + print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map); + destroy_evt= FALSE; + goto end; + } + } case WRITE_ROWS_EVENT: case DELETE_ROWS_EVENT: case UPDATE_ROWS_EVENT: case PRE_GA_WRITE_ROWS_EVENT: case PRE_GA_DELETE_ROWS_EVENT: case PRE_GA_UPDATE_ROWS_EVENT: + { + if (ev_type != TABLE_MAP_EVENT) + { + Rows_log_event *e= (Rows_log_event*) ev; + Table_map_log_event *ignored_map= + print_event_info->m_table_map_ignored.get_table(e->get_table_id()); + bool skip_event= (ignored_map != NULL); + + /* + end of statement check: + i) destroy/free ignored maps + ii) if skip event, flush cache now + */ + if (e->get_flags(Rows_log_event::STMT_END_F)) + { + /* + Now is safe to clear ignored map (clear_tables will also + delete original table map events stored in the map). + */ + if (print_event_info->m_table_map_ignored.count() > 0) + print_event_info->m_table_map_ignored.clear_tables(); + + /* + One needs to take into account an event that gets + filtered but was last event in the statement. If this is + the case, previous rows events that were written into + IO_CACHEs still need to be copied from cache to + result_file (as it would happen in ev->print(...) if + event was not skipped). + */ + if (skip_event) + { + if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) || + copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file))) + goto err; + } + } + + /* skip the event check */ + if (skip_event) + goto end; + } /* These events must be printed in base64 format, if printed. base64 format requires a FD event to be safe, so if no FD @@ -900,6 +952,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, goto err; } /* FALL THROUGH */ + } default: ev->print(result_file, print_event_info); } @@ -919,7 +972,8 @@ end: { if (remote_opt) ev->temp_buf= 0; - delete ev; + if (destroy_evt) /* destroy it later if not set (ignored table map) */ + delete ev; } DBUG_RETURN(retval); } diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result new file mode 100644 index 00000000000..354fd832fb3 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result @@ -0,0 +1,43 @@ +RESET MASTER; +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int); +CREATE TABLE t3 (txt TEXT); +CREATE TABLE t4 (a int) ENGINE= InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t1 VALUES (3); +LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3; +INSERT INTO t1 VALUES (4); +CREATE DATABASE b42941; +use b42941; +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int); +CREATE TABLE t3 (txt TEXT); +CREATE TABLE t4 (a int) ENGINE= InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t1 VALUES (3); +LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3; +INSERT INTO t1 VALUES (4); +INSERT INTO test.t1 VALUES (5); +FLUSH LOGS; +UPDATE test.t1 t11, b42941.t1 t12 SET t11.id=10, t12.id=100; +BEGIN; +INSERT INTO test.t4 VALUES (1); +INSERT INTO b42941.t4 VALUES (1); +UPDATE test.t4 tn4, b42941.t4 tt4 SET tn4.a= 10, tt4.a= 100; +COMMIT; +FLUSH LOGS; +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1'); +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2'); +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1'); +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2'); +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1'); +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2'); +DROP DATABASE b42941; +use test; +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test new file mode 100644 index 00000000000..0422c204270 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test @@ -0,0 +1,143 @@ +# BUG#42941: --database parameter to mysqlbinlog fails with RBR +# +# WHAT +# ==== +# +# This test aims at checking whether a rows log event is printed or +# not when --database parameter is used to filter events from one +# given database. +# +# HOW +# === +# +# The test is implemented as follows: +# +# i) Some operations are done in two different databases: +# 'test' and 'b42941'; +# ii) mysqlbinlog is used to dump the contents of the binlog file +# filtering only events from 'b42941'. The result of the dump is +# stored in a temporary file. (This is done with and without +# --verbose/hexdump flag); +# iii) The contents of the dump are loaded into a session variable; +# iv) The variable contents are searched for 'test' and 'b42941'; +# v) Should 'test' be found, an ERROR is reported. Should 'b42941' be +# absent, an ERROR is reported. + +-- source include/have_log_bin.inc +-- source include/have_binlog_format_row.inc +-- source include/have_innodb.inc + +RESET MASTER; +-- let $MYSQLD_DATADIR= `select @@datadir` + +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int); +CREATE TABLE t3 (txt TEXT); +CREATE TABLE t4 (a int) ENGINE= InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t1 VALUES (3); +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3 +INSERT INTO t1 VALUES (4); + +CREATE DATABASE b42941; +use b42941; +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int); +CREATE TABLE t3 (txt TEXT); +CREATE TABLE t4 (a int) ENGINE= InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t1 VALUES (3); +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3 +INSERT INTO t1 VALUES (4); + +INSERT INTO test.t1 VALUES (5); + +FLUSH LOGS; + +UPDATE test.t1 t11, b42941.t1 t12 SET t11.id=10, t12.id=100; + +BEGIN; +INSERT INTO test.t4 VALUES (1); +INSERT INTO b42941.t4 VALUES (1); +UPDATE test.t4 tn4, b42941.t4 tt4 SET tn4.a= 10, tt4.a= 100; +COMMIT; + +FLUSH LOGS; + +-- let $log_file1= $MYSQLD_DATADIR/master-bin.000001 +-- let $log_file2= $MYSQLD_DATADIR/master-bin.000002 +-- let $outfile= $MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog +-- let $cmd= $MYSQL_BINLOG + +let $i= 3; +while($i) +{ + -- let $flags=--database=b42941 + + # construct CLI for mysqlbinlog + if(`SELECT $i=3`) + { + -- let $flags= $flags --verbose --hexdump + } + + if(`SELECT $i=2`) + { + -- let $flags= $flags --verbose + } + +# if(`SELECT $i=1`) +# { + # do nothing $flags is already set as it should be +# } + + # execute mysqlbinlog on the two available master binlog files + -- exec $cmd $flags $log_file1 > $outfile.1 + -- exec $cmd $flags $log_file2 > $outfile.2 + + # load outputs into a variable + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + -- eval SET @b42941_output.1= LOAD_FILE('$outfile.1') + + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + -- eval SET @b42941_output.2= LOAD_FILE('$outfile.2') + + # remove unecessary files + -- remove_file $outfile.1 + -- remove_file $outfile.2 + + # assertion: events for database test are filtered + if (`SELECT INSTR(@b42941_output.1, 'test')`) + { + -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.1). + } + + if (`SELECT INSTR(@b42941_output.2, 'test')`) + { + -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.2). + } + + # assertion: events for database b42941 are not filtered + if (!`SELECT INSTR(@b42941_output.1, 'b42941')`) + { + -- echo **** ERROR **** Database name 'b42941' NOT FOUND in mysqlbinlog output ($flags $outfile.1). + } + + if (!`SELECT INSTR(@b42941_output.2, 'b42941')`) + { + -- echo **** ERROR **** Database name 'b42941' NOT FOUND in mysqlbinlog output ($flags $outfile.2). + } + + dec $i; +} + +DROP DATABASE b42941; +use test; +DROP TABLE t1, t2, t3, t4; diff --git a/sql/log_event.h b/sql/log_event.h index bda53da8ab0..c3cf6cf297a 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -676,6 +676,7 @@ typedef struct st_print_event_info #ifdef MYSQL_CLIENT uint verbose; table_mapping m_table_map; + table_mapping m_table_map_ignored; #endif /* From a7c2707740054204e52f4665c4d81159272d40b7 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 8 Jun 2009 12:51:06 -0300 Subject: [PATCH 060/188] Test is very resource intensive under debug and valgrind runs. Under a debug run, the trace file grows to a few gigabytes. Under valgrind, takes more then 20 minutes due to the high number of insert statements. mysql-test/t/multi_update2.test: Skip under --valgrind and --debug. --- mysql-test/t/multi_update2.test | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/multi_update2.test b/mysql-test/t/multi_update2.test index 47f9bc7bad7..9341d40282b 100644 --- a/mysql-test/t/multi_update2.test +++ b/mysql-test/t/multi_update2.test @@ -2,14 +2,27 @@ # Test of update statement that uses many tables. # +# +# If we are running with +# - Valgrind -> $VALGRIND_TEST <> 0 +# - debug tracing -> @@debug LIKE '%trace%' +# the resource consumtion (storage space needed, runtime) will be extreme. +# Therefore we require that option "big" is set. +# + +if (`SELECT ($VALGRIND_TEST <> 0 OR @@debug LIKE '%trace%') AND '$BIG_TEST' = ''`) +{ + --skip Need "big" when running with Valgrind or debug +} + +# +# Bug#1820 Rows not deleted from second table on multi-table delete +# + --disable_warnings DROP TABLE IF EXISTS t1,t2; --enable_warnings -# -# Bug#1820 Rows not deleted from second table on multi-table delete -# - CREATE TABLE t1 ( a INT NOT NULL, b INT NOT NULL) ; --echo # The protocolling of many inserts into t1 is suppressed. --disable_query_log From 01912b20bc5e1d9bc3ec80289b0de71f9797eaa9 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 8 Jun 2009 19:05:24 -0300 Subject: [PATCH 061/188] Fix for a valgrind warning due to use of a uninitialized variable. The problem was that THD::connect_utime could be used without being initialized when the main thread is used to handle connections (--thread-handling=no-threads). sql/mysqld.cc: Set THD::start_utime even in no-threads handling mode. sql/sql_class.cc: Initialize variable. sql/sql_class.h: Rename connect_utime to prior_thr_create_utime as to better reflect it's use intention. sql/sql_connect.cc: Check only if a thread was actually created. --- sql/mysqld.cc | 7 ++++--- sql/sql_class.cc | 2 +- sql/sql_class.h | 3 ++- sql/sql_connect.cc | 20 ++++++++++++++++---- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index eb94e1a8fab..239fff01071 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4780,8 +4780,9 @@ void handle_connection_in_main_thread(THD *thd) safe_mutex_assert_owner(&LOCK_thread_count); thread_cache_size=0; // Safety threads.append(thd); - (void) pthread_mutex_unlock(&LOCK_thread_count); - handle_one_connection((void*) thd); + pthread_mutex_unlock(&LOCK_thread_count); + thd->start_utime= my_micro_time(); + handle_one_connection(thd); } @@ -4806,7 +4807,7 @@ void create_thread_to_handle_connection(THD *thd) thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->connect_utime= thd->start_utime= my_micro_time(); + thd->prior_thr_create_utime= thd->start_utime= my_micro_time(); if ((error=pthread_create(&thd->real_id,&connection_attrib, handle_one_connection, (void*) thd))) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f881f0a792b..f1ad410b877 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -590,7 +590,7 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; - start_utime= 0L; + start_utime= prior_thr_create_utime= 0L; utime_after_lock= 0L; current_linfo = 0; slave_thread = 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index ae7f2a51428..36e696f2da6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1370,7 +1370,8 @@ public: /* remote (peer) port */ uint16 peer_port; time_t start_time, user_time; - ulonglong connect_utime, thr_create_utime; // track down slow pthread_create + // track down slow pthread_create + ulonglong prior_thr_create_utime, thr_create_utime; ulonglong start_utime, utime_after_lock; thr_lock_type update_lock_default; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index e4d7cf6feb5..98574a07a4e 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1074,8 +1074,8 @@ static void prepare_new_connection_state(THD* thd) pthread_handler_t handle_one_connection(void *arg) { THD *thd= (THD*) arg; - ulong launch_time= (ulong) ((thd->thr_create_utime= my_micro_time()) - - thd->connect_utime); + + thd->thr_create_utime= my_micro_time(); if (thread_scheduler.init_new_connection_thread()) { @@ -1084,8 +1084,20 @@ pthread_handler_t handle_one_connection(void *arg) thread_scheduler.end_thread(thd,0); return 0; } - if (launch_time >= slow_launch_time*1000000L) - statistic_increment(slow_launch_threads,&LOCK_status); + + /* + If a thread was created to handle this connection: + increment slow_launch_threads counter if it took more than + slow_launch_time seconds to create the thread. + */ + if (thd->prior_thr_create_utime) + { + ulong launch_time= (ulong) (thd->thr_create_utime - + thd->prior_thr_create_utime); + if (launch_time >= slow_launch_time*1000000L) + statistic_increment(slow_launch_threads, &LOCK_status); + thd->prior_thr_create_utime= 0; + } /* handle_one_connection() is normally the only way a thread would From 8ad45961508f87db521917a37b4745680b967752 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 8 Jun 2009 19:18:31 -0300 Subject: [PATCH 062/188] Test is very resource intensive under debug and valgrind runs. Under a debug run, the trace file grows to a few gigabytes. Under valgrind, takes more then 20 minutes due to the high number of insert statements. mysql-test/t/multi_update2.test: Skip under --valgrind and --debug. --- mysql-test/t/multi_update2.test | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/multi_update2.test b/mysql-test/t/multi_update2.test index 9341d40282b..a04518f4964 100644 --- a/mysql-test/t/multi_update2.test +++ b/mysql-test/t/multi_update2.test @@ -5,14 +5,33 @@ # # If we are running with # - Valgrind -> $VALGRIND_TEST <> 0 -# - debug tracing -> @@debug LIKE '%trace%' -# the resource consumtion (storage space needed, runtime) will be extreme. -# Therefore we require that option "big" is set. +# - debug tracing -> @@session.debug LIKE '%trace%' +# the resource consumption (storage space needed, runtime) will be extreme. +# Therefore we require that the option "--big-test" is also set. # -if (`SELECT ($VALGRIND_TEST <> 0 OR @@debug LIKE '%trace%') AND '$BIG_TEST' = ''`) +let $need_big= 0; +--disable_query_log +--error 0,ER_UNKNOWN_SYSTEM_VARIABLE +SET @aux = @@session.debug; +if (!$mysql_errno) { - --skip Need "big" when running with Valgrind or debug + # We have returncode 0 = the server system variable @@session.debug exists. + # But we only need "--big-test" in case of tracing. + if (`SELECT @@session.debug LIKE '%trace%'`) + { + let $need_big= 1; + } +} +--enable_query_log +if ($VALGRIND_TEST) +{ + # We are running with Valgrind + inc $need_big; +} +if (`SELECT '$BIG_TEST' = '' AND $need_big = 1`) +{ + --skip Need "--big-test" when running with the option "--debug" or "--valgrind" } # From 9d8c191e9cbb49d1854521fd8193eb099a09fd10 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 8 Jun 2009 20:03:01 -0300 Subject: [PATCH 063/188] Tag count_distinct3.test as a big test. mysql-test/t/count_distinct3.test: Test is resource intensive. --- mysql-test/t/count_distinct3.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/count_distinct3.test b/mysql-test/t/count_distinct3.test index 2f7cf7e5260..ad2bbee95a3 100644 --- a/mysql-test/t/count_distinct3.test +++ b/mysql-test/t/count_distinct3.test @@ -3,6 +3,8 @@ # mysql-4.1 # +--source include/big_test.inc + --disable_warnings DROP TABLE IF EXISTS t1, t2; --enable_warnings From a092ed1afe3c3c7889810f45d591cfb2633c87f9 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Tue, 9 Jun 2009 14:55:30 +0200 Subject: [PATCH 064/188] Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 Compiling MySQL with gcc 4.3.2 and later produces a number of warnings, many of which are new with the recent compiler versions. This bug will be resolved in more than one patch to limit the size of changesets. This is the first patch, fixing a number of the warnings, predominantly "suggest using parentheses around && in ||", and empty for and while bodies. --- sql/field.cc | 44 +++++++++++++++++++++++++------------------ sql/field.h | 2 +- sql/field_conv.cc | 8 ++++---- sql/gstream.cc | 2 +- sql/handler.cc | 4 ++-- sql/item.cc | 8 ++++---- sql/item_cmpfunc.cc | 8 ++++---- sql/item_func.cc | 4 ++-- sql/item_subselect.cc | 8 ++++---- sql/item_sum.cc | 12 ++++++------ sql/item_timefunc.cc | 8 ++++---- sql/log_event.cc | 3 ++- sql/opt_range.cc | 14 +++++++------- sql/opt_sum.cc | 4 ++-- sql/slave.cc | 3 ++- 15 files changed, 71 insertions(+), 61 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index c7dd2afd934..fc54c9ab4c0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1157,7 +1157,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len, if (unsigned_flag) { - if (((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max) || + if ((((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max)) || error == MY_ERRNO_ERANGE) { goto out_of_range; @@ -1324,7 +1324,7 @@ void Field::copy_from_tmp(int row_offset) if (null_ptr) { *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) | - null_ptr[row_offset] & (uchar) null_bit); + (null_ptr[row_offset] & (uchar) null_bit)); } } @@ -3674,8 +3674,8 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int error; char *end; double nr= my_strntod(cs,(char*) from,len,&end,&error); - if (error || (!len || (uint) (end-from) != len && - table->in_use->count_cuted_fields)) + if (error || (!len || ((uint) (end-from) != len && + table->in_use->count_cuted_fields))) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); @@ -3915,8 +3915,8 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int error; char *end; double nr= my_strntod(cs,(char*) from, len, &end, &error); - if (error || (!len || (uint) (end-from) != len && - table->in_use->count_cuted_fields)) + if (error || (!len || ((uint) (end-from) != len && + table->in_use->count_cuted_fields))) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); @@ -4771,7 +4771,7 @@ int Field_time::store(longlong nr, bool unsigned_val) MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr > (longlong) TIME_MAX_VALUE || nr < 0 && unsigned_val) + else if (nr > (longlong) TIME_MAX_VALUE || (nr < 0 && unsigned_val)) { tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -4930,7 +4930,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) int error; longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || + if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155 || error == MY_ERRNO_ERANGE) { *ptr=0; @@ -4973,7 +4973,7 @@ int Field_year::store(double nr) int Field_year::store(longlong nr, bool unsigned_val) { - if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) + if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155) { *ptr= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -5968,16 +5968,22 @@ int Field_str::store(double nr) /* Calculate the exponent from the 'e'-format conversion */ if (anr < 1.0 && anr > 0) { - for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100); - for (; anr < 1e-10; exp-= 10, anr*= 1e10); - for (i= 1; anr < 1 / log_10[i]; exp--, i++); + for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100) + {} + for (; anr < 1e-10; exp-= 10, anr*= 1e10) + {} + for (i= 1; anr < 1 / log_10[i]; exp--, i++) + {} exp--; } else { - for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100); - for (; anr > 1e10; exp+= 10, anr/= 1e10); - for (i= 1; anr > log_10[i]; exp++, i++); + for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100) + {} + for (; anr > 1e10; exp+= 10, anr/= 1e10) + {} + for (i= 1; anr > log_10[i]; exp++, i++) + {} } max_length= local_char_length - neg; @@ -7986,7 +7992,7 @@ bool Field_num::eq_def(Field *field) Field_num *from_num= (Field_num*) field; if (unsigned_flag != from_num->unsigned_flag || - zerofill && !from_num->zerofill && !zero_pack() || + (zerofill && !from_num->zerofill && !zero_pack()) || dec != from_num->dec) return 0; return 1; @@ -8065,7 +8071,8 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) { int delta; - for (; length && !*from; from++, length--); // skip left 0's + for (; length && !*from; from++, length--) // skip left 0's + {} delta= bytes_in_rec - length; if (delta < -1 || @@ -8284,7 +8291,8 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) int delta; uchar bits= (uchar) (field_length & 7); - for (; length && !*from; from++, length--); // skip left 0's + for (; length && !*from; from++, length--) // skip left 0's + {} delta= bytes_in_rec - length; if (delta < 0 || diff --git a/sql/field.h b/sql/field.h index 2975719a591..eef3618a142 100644 --- a/sql/field.h +++ b/sql/field.h @@ -170,7 +170,7 @@ public: memcpy(ptr, ptr + l_offset, pack_length()); if (null_ptr) *null_ptr= ((*null_ptr & (uchar) ~null_bit) | - null_ptr[l_offset] & null_bit); + (null_ptr[l_offset] & null_bit)); } virtual bool binary() const { return 1; } virtual bool zero_pack() const { return 1; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 2705d4f617b..7beb41b8ff1 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -95,7 +95,7 @@ static void do_field_to_null_str(Copy_field *copy) static void do_outer_field_to_null_str(Copy_field *copy) { if (*copy->null_row || - copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)) + (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit))) { bzero(copy->to_ptr,copy->from_length); copy->to_null_ptr[0]=1; // Always bit 1 @@ -209,7 +209,7 @@ static void do_copy_null(Copy_field *copy) static void do_outer_field_null(Copy_field *copy) { if (*copy->null_row || - copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)) + (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit))) { *copy->to_null_ptr|=copy->to_bit; copy->to_field->reset(); @@ -656,9 +656,9 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) */ if (to->real_type() != from->real_type() || !compatible_db_low_byte_first || - ((to->table->in_use->variables.sql_mode & + (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && - to->type() == FIELD_TYPE_DATE || + to->type() == FIELD_TYPE_DATE) || to->type() == FIELD_TYPE_DATETIME)) { if (from->real_type() == FIELD_TYPE_ENUM || diff --git a/sql/gstream.cc b/sql/gstream.cc index 0c8011549f3..e2bb41b8541 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -75,7 +75,7 @@ bool Gis_read_stream::get_next_number(double *d) skip_space(); if ((m_cur >= m_limit) || - (*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+') + ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')) { set_error_msg("Numeric constant expected"); return 1; diff --git a/sql/handler.cc b/sql/handler.cc index 63f652fc2b4..2840037024b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1642,8 +1642,8 @@ int handler::update_auto_increment() thd->prev_insert_id= thd->next_insert_id; if ((nr= table->next_number_field->val_int()) != 0 || - table->auto_increment_field_not_null && - thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) + (table->auto_increment_field_not_null && + thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { /* Mark that we didn't generate a new value **/ auto_increment_column_changed=0; diff --git a/sql/item.cc b/sql/item.cc index 7a81e48fcee..007af8fa522 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1478,7 +1478,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) set(dt); } else - ; // Do nothing + {} // Do nothing } else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && left_is_superset(this, &dt)) @@ -2587,7 +2587,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, if (value.time.year > 9999 || value.time.month > 12 || value.time.day > 31 || - time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23 || + (time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) || value.time.minute > 59 || value.time.second > 59) { char buff[MAX_DATE_STRING_REP_LENGTH]; @@ -4728,8 +4728,8 @@ int Item::save_in_field(Field *field, bool no_conversions) { int error; if (result_type() == STRING_RESULT || - result_type() == REAL_RESULT && - field->result_type() == STRING_RESULT) + (result_type() == REAL_RESULT && + field->result_type() == STRING_RESULT)) { String *result; CHARSET_INFO *cs= collation.collation; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 01d3e9bed52..c940c4ab3c0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1419,8 +1419,8 @@ longlong Item_func_truth::val_int() bool Item_in_optimizer::fix_left(THD *thd, Item **ref) { - if (!args[0]->fixed && args[0]->fix_fields(thd, args) || - !cache && !(cache= Item_cache::get_cache(args[0]))) + if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) || + (!cache && !(cache= Item_cache::get_cache(args[0])))) return 1; cache->setup(args[0]); @@ -2934,8 +2934,8 @@ int cmp_longlong(void *cmp_arg, One of the args is unsigned and is too big to fit into the positive signed range. Report no match. */ - if (a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX || - b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX) + if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) || + (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX)) return a->unsigned_flag ? 1 : -1; /* Although the signedness differs both args can fit into the signed diff --git a/sql/item_func.cc b/sql/item_func.cc index 2421f7e0526..6193ab285f2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4427,8 +4427,8 @@ int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions, update(); if (result_type() == STRING_RESULT || - result_type() == REAL_RESULT && - field->result_type() == STRING_RESULT) + (result_type() == REAL_RESULT && + field->result_type() == STRING_RESULT)) { String *result; CHARSET_INFO *cs= collation.collation; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 401751660fd..13eeba3ea27 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1232,8 +1232,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) Item *item_having_part2= 0; for (uint i= 0; i < cols_num; i++) { - DBUG_ASSERT(left_expr->fixed && - select_lex->ref_pointer_array[i]->fixed || + DBUG_ASSERT((left_expr->fixed && + select_lex->ref_pointer_array[i]->fixed) || (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); @@ -1310,8 +1310,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) for (uint i= 0; i < cols_num; i++) { Item *item, *item_isnull; - DBUG_ASSERT(left_expr->fixed && - select_lex->ref_pointer_array[i]->fixed || + DBUG_ASSERT((left_expr->fixed && + select_lex->ref_pointer_array[i]->fixed) || (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 57045f52825..a381361e8a2 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -652,8 +652,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) return TRUE; // 'item' can be changed during fix_fields - if (!item->fixed && - item->fix_fields(thd, args) || + if ((!item->fixed && + item->fix_fields(thd, args)) || (item= args[0])->check_cols(1)) return TRUE; decimals=item->decimals; @@ -969,8 +969,8 @@ void Item_sum_distinct::fix_length_and_dec() integers each <= 2^32. */ if (table_field_type == MYSQL_TYPE_INT24 || - table_field_type >= MYSQL_TYPE_TINY && - table_field_type <= MYSQL_TYPE_LONG) + (table_field_type >= MYSQL_TYPE_TINY && + table_field_type <= MYSQL_TYPE_LONG)) { val.traits= Hybrid_type_traits_fast_decimal::instance(); break; @@ -2608,8 +2608,8 @@ bool Item_sum_count_distinct::setup(THD *thd) enum enum_field_types f_type= f->type(); tree_key_length+= f->pack_length(); if ((f_type == MYSQL_TYPE_VARCHAR) || - !f->binary() && (f_type == MYSQL_TYPE_STRING || - f_type == MYSQL_TYPE_VAR_STRING)) + (!f->binary() && (f_type == MYSQL_TYPE_STRING || + f_type == MYSQL_TYPE_VAR_STRING))) { all_binary= FALSE; break; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 22ca8a925db..39f869106b6 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -439,7 +439,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, strict_week_number= (*ptr=='V' || *ptr=='v'); tmp= (char*) val + min(val_len, 2); if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 || - strict_week_number && !week_number || + (strict_week_number && !week_number) || week_number > 53) goto err; val= tmp; @@ -535,10 +535,10 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, %V,%v require %X,%x resprectively, %U,%u should be used with %Y and not %X or %x */ - if (strict_week_number && + if ((strict_week_number && (strict_week_number_year < 0 || - strict_week_number_year_type != sunday_first_n_first_week_non_iso) || - !strict_week_number && strict_week_number_year >= 0) + strict_week_number_year_type != sunday_first_n_first_week_non_iso)) || + (!strict_week_number && strict_week_number_year >= 0)) goto err; /* Number of days since year 0 till 1st Jan of this year */ diff --git a/sql/log_event.cc b/sql/log_event.cc index a440f010fa5..3a6daadd11a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1733,7 +1733,8 @@ void Query_log_event::print_query_header(FILE* file, if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db) { - if (different_db= memcmp(print_event_info->db, db, db_len + 1)) + different_db= memcmp(print_event_info->db, db, db_len + 1); + if (different_db) memcpy(print_event_info->db, db, db_len + 1); if (db[0] && different_db) fprintf(file, "use %s%s\n", db, print_event_info->delimiter); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c3a43776429..d52db41d64c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2032,7 +2032,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, quick=0; needed_reg.clear_all(); quick_keys.clear_all(); - if ((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range || + if (((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range) || !limit) DBUG_RETURN(0); /* purecov: inspected */ if (keys_to_use.is_clear_all()) @@ -2462,8 +2462,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost)); if (imerge_too_expensive || (imerge_cost > read_time) || - (non_cpk_scan_records+cpk_scan_records >= param->table->file->records) && - read_time != DBL_MAX) + ((non_cpk_scan_records+cpk_scan_records >= param->table->file->records) && + read_time != DBL_MAX)) { /* Bail out if it is obvious that both index_merge and ROR-union will be @@ -6490,7 +6490,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, goto err; quick->records= records; - if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error || + if ((cp_buffer_from_ref(thd,ref) && thd->is_fatal_error) || !(range= new(alloc) QUICK_RANGE())) goto err; // out of memory @@ -7342,7 +7342,7 @@ int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg) cmp= key_cmp(key_part_info, (byte*) range_arg->min_key, range_arg->min_length); - if (cmp > 0 || cmp == 0 && !(range_arg->flag & NEAR_MIN)) + if (cmp > 0 || (cmp == 0 && !(range_arg->flag & NEAR_MIN))) return 0; return 1; // outside of range } @@ -9395,7 +9395,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* Compare the found key with max_key. */ int cmp_res= key_cmp(index_info->key_part, max_key, real_prefix_len + min_max_arg_len); - if (!((cur_range->flag & NEAR_MAX) && (cmp_res == -1) || + if (!(((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) || (cmp_res <= 0))) { result = HA_ERR_KEY_NOT_FOUND; @@ -9511,7 +9511,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* Compare the found key with min_key. */ int cmp_res= key_cmp(index_info->key_part, min_key, real_prefix_len + min_max_arg_len); - if (!((cur_range->flag & NEAR_MIN) && (cmp_res == 1) || + if (!(((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) || (cmp_res >= 0))) continue; } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index f8603f06fa0..66aa29c6680 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -690,8 +690,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, } else if (eq_type) { - if (!is_null && !cond->val_int() || - is_null && !test(part->field->is_null())) + if ((!is_null && !cond->val_int()) || + (is_null && !test(part->field->is_null()))) return 0; // Impossible test } else if (is_field_part) diff --git a/sql/slave.cc b/sql/slave.cc index 88c19a04602..d90eb9d520c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1334,7 +1334,8 @@ static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, up to and including newline. */ int c; - while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)); + while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) + {} } return 0; } From e66c574df9fb554880217dcbf3a2fbf7e88e1d98 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Jun 2009 11:36:14 -0300 Subject: [PATCH 065/188] Don't run funcs_1/myisam_views test case under valgrind, unless the --big-test flag is supplied. Test is too resource intensive under normal valgrind runs (takes more than 30min on powerful hardware). mysql-test/include/no_valgrind_without_big.inc: Add MTR prerequisite file by Matthias Leich. mysql-test/suite/funcs_1/t/myisam_views.test: Test is too resource intensive under "Valgrind". --- mysql-test/include/no_valgrind_without_big.inc | 12 ++++++++++++ mysql-test/suite/funcs_1/t/myisam_views.test | 2 ++ 2 files changed, 14 insertions(+) create mode 100644 mysql-test/include/no_valgrind_without_big.inc diff --git a/mysql-test/include/no_valgrind_without_big.inc b/mysql-test/include/no_valgrind_without_big.inc new file mode 100644 index 00000000000..743e974daec --- /dev/null +++ b/mysql-test/include/no_valgrind_without_big.inc @@ -0,0 +1,12 @@ +# include/no_valgrind_without_big.inc +# +# If we are running with Valgrind ($VALGRIND_TEST <> 0) than the resource +# consumption (storage space needed, runtime ...) will be extreme. +# Therefore we require that the option "--big-test" is also set. +# + +if (`SELECT $VALGRIND_TEST <> 0 AND '$BIG_TEST' = ''`) +{ + --skip Need "--big-test" when running with Valgrind +} + diff --git a/mysql-test/suite/funcs_1/t/myisam_views.test b/mysql-test/suite/funcs_1/t/myisam_views.test index 461bc0e3549..fe72843cfaf 100644 --- a/mysql-test/suite/funcs_1/t/myisam_views.test +++ b/mysql-test/suite/funcs_1/t/myisam_views.test @@ -1,5 +1,7 @@ #### suite/funcs_1/t/myisam_views.test +--source include/no_valgrind_without_big.inc + # MyISAM tables should be used # # Set $engine_type From cb26bb932c385a41706fb0d423da614958fdaeb5 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Jun 2009 13:09:16 -0300 Subject: [PATCH 066/188] Remove assignments of the $MASTER_MYSOCK variable. This variable is defined by default and one should not do it directly as the socket variable is not available on Windows. --- mysql-test/suite/funcs_1/datadict/charset_collation.inc | 1 - mysql-test/suite/funcs_1/datadict/is_key_column_usage.inc | 1 - mysql-test/suite/funcs_1/datadict/is_routines.inc | 1 - mysql-test/suite/funcs_1/datadict/is_schemata.inc | 1 - mysql-test/suite/funcs_1/datadict/is_tables.inc | 1 - mysql-test/suite/funcs_1/datadict/is_triggers.inc | 1 - mysql-test/suite/funcs_1/datadict/is_views.inc | 1 - mysql-test/suite/funcs_1/datadict/statistics.inc | 1 - mysql-test/suite/funcs_1/datadict/table_constraints.inc | 1 - mysql-test/suite/funcs_1/datadict/tables.inc | 1 - mysql-test/suite/funcs_1/datadict/tables1.inc | 1 - mysql-test/suite/funcs_1/storedproc/storedproc_06.inc | 1 - mysql-test/suite/funcs_1/storedproc/storedproc_10.inc | 1 - mysql-test/suite/funcs_1/t/is_basics_mixed.test | 1 - mysql-test/suite/funcs_1/t/is_column_privileges.test | 1 - .../suite/funcs_1/t/is_column_privileges_is_mysql_test.test | 1 - mysql-test/suite/funcs_1/t/is_columns.test | 1 - mysql-test/suite/funcs_1/t/is_schema_privileges.test | 1 - .../suite/funcs_1/t/is_schema_privileges_is_mysql_test.test | 1 - mysql-test/suite/funcs_1/t/is_schemata_is_mysql_test.test | 1 - mysql-test/suite/funcs_1/t/is_statistics.test | 1 - mysql-test/suite/funcs_1/t/is_table_constraints.test | 1 - mysql-test/suite/funcs_1/t/is_table_privileges.test | 1 - mysql-test/suite/funcs_1/t/is_user_privileges.test | 1 - mysql-test/suite/funcs_1/t/storedproc.test | 1 - mysql-test/suite/funcs_1/triggers/triggers_03.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_0407.inc | 1 - mysql-test/suite/funcs_1/triggers/triggers_08.inc | 1 - 36 files changed, 36 deletions(-) diff --git a/mysql-test/suite/funcs_1/datadict/charset_collation.inc b/mysql-test/suite/funcs_1/datadict/charset_collation.inc index a1991346cfc..ae03996b073 100644 --- a/mysql-test/suite/funcs_1/datadict/charset_collation.inc +++ b/mysql-test/suite/funcs_1/datadict/charset_collation.inc @@ -61,7 +61,6 @@ DROP USER dbdict_test@localhost; CREATE USER dbdict_test@localhost; --echo # Establish connection con (user=dbdict_test) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (con,localhost,dbdict_test,,); ################################################################################ diff --git a/mysql-test/suite/funcs_1/datadict/is_key_column_usage.inc b/mysql-test/suite/funcs_1/datadict/is_key_column_usage.inc index c8e8a186673..098b8c6eca2 100644 --- a/mysql-test/suite/funcs_1/datadict/is_key_column_usage.inc +++ b/mysql-test/suite/funcs_1/datadict/is_key_column_usage.inc @@ -126,7 +126,6 @@ ORDER BY constraint_catalog, constraint_schema, constraint_name, eval $select; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $select; diff --git a/mysql-test/suite/funcs_1/datadict/is_routines.inc b/mysql-test/suite/funcs_1/datadict/is_routines.inc index 19f7ed5d230..c2b547e600f 100644 --- a/mysql-test/suite/funcs_1/datadict/is_routines.inc +++ b/mysql-test/suite/funcs_1/datadict/is_routines.inc @@ -179,7 +179,6 @@ GRANT EXECUTE ON db_datadict_2.* TO 'testuser2'@'localhost'; FLUSH PRIVILEGES; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); --replace_column 16 "YYYY-MM-DD hh:mm:ss" 17 "YYYY-MM-DD hh:mm:ss" diff --git a/mysql-test/suite/funcs_1/datadict/is_schemata.inc b/mysql-test/suite/funcs_1/datadict/is_schemata.inc index 96061d541b7..29e1f6af4ef 100644 --- a/mysql-test/suite/funcs_1/datadict/is_schemata.inc +++ b/mysql-test/suite/funcs_1/datadict/is_schemata.inc @@ -104,7 +104,6 @@ eval $my_select; eval $my_show; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict_1); # Shows db_datadict_1 diff --git a/mysql-test/suite/funcs_1/datadict/is_tables.inc b/mysql-test/suite/funcs_1/datadict/is_tables.inc index 4f608eb02ea..d1e4608a572 100644 --- a/mysql-test/suite/funcs_1/datadict/is_tables.inc +++ b/mysql-test/suite/funcs_1/datadict/is_tables.inc @@ -130,7 +130,6 @@ WHERE table_schema = 'db_datadict' ORDER BY table_name; let $my_show = SHOW TABLES FROM db_datadict; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); # tb2 is not granted to anyone diff --git a/mysql-test/suite/funcs_1/datadict/is_triggers.inc b/mysql-test/suite/funcs_1/datadict/is_triggers.inc index 70d5540e163..3b83a75295b 100644 --- a/mysql-test/suite/funcs_1/datadict/is_triggers.inc +++ b/mysql-test/suite/funcs_1/datadict/is_triggers.inc @@ -122,7 +122,6 @@ let $my_select = SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; let $my_show = SHOW TRIGGERS FROM db_datadict; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); --replace_result $engine_type diff --git a/mysql-test/suite/funcs_1/datadict/is_views.inc b/mysql-test/suite/funcs_1/datadict/is_views.inc index 542dab05a8e..32e66e4f684 100644 --- a/mysql-test/suite/funcs_1/datadict/is_views.inc +++ b/mysql-test/suite/funcs_1/datadict/is_views.inc @@ -108,7 +108,6 @@ WHERE table_schema = 'db_datadict' ORDER BY table_name; eval $select; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , test); eval $select; diff --git a/mysql-test/suite/funcs_1/datadict/statistics.inc b/mysql-test/suite/funcs_1/datadict/statistics.inc index 6f24f422b5e..00fd7a1b06b 100644 --- a/mysql-test/suite/funcs_1/datadict/statistics.inc +++ b/mysql-test/suite/funcs_1/datadict/statistics.inc @@ -42,7 +42,6 @@ ORDER BY table_schema, table_name, index_name, seq_in_index, column_name; eval $my_select; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1,localhost,testuser1,,db_datadict); --replace_column 10 #CARD# diff --git a/mysql-test/suite/funcs_1/datadict/table_constraints.inc b/mysql-test/suite/funcs_1/datadict/table_constraints.inc index 513057c84a0..9e57976862b 100644 --- a/mysql-test/suite/funcs_1/datadict/table_constraints.inc +++ b/mysql-test/suite/funcs_1/datadict/table_constraints.inc @@ -33,7 +33,6 @@ ORDER BY table_schema,table_name,constraint_name; eval $my_select; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1,localhost,testuser1,,db_datadict); eval $my_select; diff --git a/mysql-test/suite/funcs_1/datadict/tables.inc b/mysql-test/suite/funcs_1/datadict/tables.inc index 8dae7ba0ebc..5aa072d184c 100644 --- a/mysql-test/suite/funcs_1/datadict/tables.inc +++ b/mysql-test/suite/funcs_1/datadict/tables.inc @@ -37,7 +37,6 @@ CREATE USER testuser1@localhost; GRANT SELECT ON test1.* TO testuser1@localhost; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1,localhost,testuser1,,test1); --source suite/funcs_1/datadict/tables2.inc diff --git a/mysql-test/suite/funcs_1/datadict/tables1.inc b/mysql-test/suite/funcs_1/datadict/tables1.inc index 2dff32d81a9..2e054a9dcfb 100644 --- a/mysql-test/suite/funcs_1/datadict/tables1.inc +++ b/mysql-test/suite/funcs_1/datadict/tables1.inc @@ -27,7 +27,6 @@ CREATE USER testuser1@localhost; GRANT SELECT ON test1.* TO testuser1@localhost; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1,localhost,testuser1,,test1); --source suite/funcs_1/datadict/tables2.inc diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc index d0fc6092959..f2df99fb5a3 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_06.inc @@ -53,7 +53,6 @@ flush privileges; DROP PROCEDURE IF EXISTS sp1; --enable_warnings -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user1a, localhost, user_1, , db_storedproc_1); --source suite/funcs_1/include/show_connection.inc diff --git a/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc b/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc index 69378541b51..83f5f2105c5 100644 --- a/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc +++ b/mysql-test/suite/funcs_1/storedproc/storedproc_10.inc @@ -58,7 +58,6 @@ GRANT CREATE ROUTINE ON db_storedproc.* TO 'user_1'@'localhost'; GRANT SELECT ON db_storedproc.* TO 'user_2'@'localhost'; FLUSH PRIVILEGES; -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (user2_1, localhost, user_1, , db_storedproc); --source suite/funcs_1/include/show_connection.inc diff --git a/mysql-test/suite/funcs_1/t/is_basics_mixed.test b/mysql-test/suite/funcs_1/t/is_basics_mixed.test index 7d03dc5f8b0..235b91c67d0 100644 --- a/mysql-test/suite/funcs_1/t/is_basics_mixed.test +++ b/mysql-test/suite/funcs_1/t/is_basics_mixed.test @@ -55,7 +55,6 @@ DROP USER 'testuser1'@'localhost'; CREATE USER 'testuser1'@'localhost'; # Low privileged user --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , test); SELECT DATABASE(); diff --git a/mysql-test/suite/funcs_1/t/is_column_privileges.test b/mysql-test/suite/funcs_1/t/is_column_privileges.test index 925d07b9657..cb8c50c01b7 100644 --- a/mysql-test/suite/funcs_1/t/is_column_privileges.test +++ b/mysql-test/suite/funcs_1/t/is_column_privileges.test @@ -132,7 +132,6 @@ WITH GRANT OPTION; eval $select; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $select; diff --git a/mysql-test/suite/funcs_1/t/is_column_privileges_is_mysql_test.test b/mysql-test/suite/funcs_1/t/is_column_privileges_is_mysql_test.test index 98d01c60838..33269fe929c 100644 --- a/mysql-test/suite/funcs_1/t/is_column_privileges_is_mysql_test.test +++ b/mysql-test/suite/funcs_1/t/is_column_privileges_is_mysql_test.test @@ -46,7 +46,6 @@ eval $my_show2; eval $my_show3; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $my_select; diff --git a/mysql-test/suite/funcs_1/t/is_columns.test b/mysql-test/suite/funcs_1/t/is_columns.test index 20b832ca5c3..efb52acd48c 100644 --- a/mysql-test/suite/funcs_1/t/is_columns.test +++ b/mysql-test/suite/funcs_1/t/is_columns.test @@ -148,7 +148,6 @@ eval $my_show2; eval $my_show3; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); --source suite/funcs_1/datadict/datadict_bug_12777.inc diff --git a/mysql-test/suite/funcs_1/t/is_schema_privileges.test b/mysql-test/suite/funcs_1/t/is_schema_privileges.test index c1fc70b03f7..1f408d71b39 100644 --- a/mysql-test/suite/funcs_1/t/is_schema_privileges.test +++ b/mysql-test/suite/funcs_1/t/is_schema_privileges.test @@ -116,7 +116,6 @@ let $show_testuser1 = SHOW GRANTS FOR 'testuser1'@'localhost'; let $show_testuser2 = SHOW GRANTS FOR 'testuser2'@'localhost'; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , test); GRANT SELECT ON db_datadict_4.* TO 'testuser2'@'localhost'; diff --git a/mysql-test/suite/funcs_1/t/is_schema_privileges_is_mysql_test.test b/mysql-test/suite/funcs_1/t/is_schema_privileges_is_mysql_test.test index d7b703ed04a..3f60f71fe9a 100644 --- a/mysql-test/suite/funcs_1/t/is_schema_privileges_is_mysql_test.test +++ b/mysql-test/suite/funcs_1/t/is_schema_privileges_is_mysql_test.test @@ -46,7 +46,6 @@ eval $my_show2; eval $my_show3; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $my_select; diff --git a/mysql-test/suite/funcs_1/t/is_schemata_is_mysql_test.test b/mysql-test/suite/funcs_1/t/is_schemata_is_mysql_test.test index b5f13ab323c..9bfbf0cf335 100644 --- a/mysql-test/suite/funcs_1/t/is_schemata_is_mysql_test.test +++ b/mysql-test/suite/funcs_1/t/is_schemata_is_mysql_test.test @@ -46,7 +46,6 @@ eval $my_show2; eval $my_show3; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $my_select; diff --git a/mysql-test/suite/funcs_1/t/is_statistics.test b/mysql-test/suite/funcs_1/t/is_statistics.test index e202e7392ea..458892a6d91 100644 --- a/mysql-test/suite/funcs_1/t/is_statistics.test +++ b/mysql-test/suite/funcs_1/t/is_statistics.test @@ -140,7 +140,6 @@ eval $my_show1; eval $my_show2; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , test); # nothing visible for testuser1 diff --git a/mysql-test/suite/funcs_1/t/is_table_constraints.test b/mysql-test/suite/funcs_1/t/is_table_constraints.test index 730e805c91e..a64b3bfaa6e 100644 --- a/mysql-test/suite/funcs_1/t/is_table_constraints.test +++ b/mysql-test/suite/funcs_1/t/is_table_constraints.test @@ -132,7 +132,6 @@ eval $my_show1; eval $my_show2; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); SHOW GRANTS FOR 'testuser1'@'localhost'; diff --git a/mysql-test/suite/funcs_1/t/is_table_privileges.test b/mysql-test/suite/funcs_1/t/is_table_privileges.test index 27ce22816a2..5ea0dd7c6a7 100644 --- a/mysql-test/suite/funcs_1/t/is_table_privileges.test +++ b/mysql-test/suite/funcs_1/t/is_table_privileges.test @@ -116,7 +116,6 @@ WHERE table_name LIKE 'tb%' ORDER BY grantee,table_schema,table_name,privilege_type; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); --replace_result $other_engine_type diff --git a/mysql-test/suite/funcs_1/t/is_user_privileges.test b/mysql-test/suite/funcs_1/t/is_user_privileges.test index 5f8c29ca39d..1d0d3e51aae 100644 --- a/mysql-test/suite/funcs_1/t/is_user_privileges.test +++ b/mysql-test/suite/funcs_1/t/is_user_privileges.test @@ -114,7 +114,6 @@ eval $my_select1; eval $my_select2; --echo # Establish connection testuser1 (user=testuser1) -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser1, localhost, testuser1, , db_datadict); eval $my_select1; diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test index 6877b751ed2..dc1177ac8bb 100644 --- a/mysql-test/suite/funcs_1/t/storedproc.test +++ b/mysql-test/suite/funcs_1/t/storedproc.test @@ -817,7 +817,6 @@ CREATE PROCEDURE sp11() insert into mysql.t1 values('a'); --replace_column 13 created 14 modified SELECT security_type from mysql.proc where specific_name='sp11'; -let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (u_1, localhost, user_1, , db_storedproc); --source suite/funcs_1/include/show_connection.inc diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03.inc b/mysql-test/suite/funcs_1/triggers/triggers_03.inc index e5bea5b2005..9ef6a9ac9af 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03.inc @@ -62,7 +62,6 @@ let $message= Testcase 3.5.3.2/6:; grant SELECT on priv_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (no_privs,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc index 60928ba8f35..475063587d4 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_columns.inc @@ -36,7 +36,6 @@ let $message= ####### Testcase for column privileges of triggers: #######; grant SELECT,UPDATE on priv_db.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc index cb9d8ddc78b..e5933eb84a8 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_level.inc @@ -37,7 +37,6 @@ let $message= Testcase for db level:; show grants for test_noprivs@localhost; # no trigger privilege->create trigger must fail: - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); let $message= no trigger privilege on db level for create:; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc index de9cf61f641..82f4a28f664 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc @@ -41,7 +41,6 @@ let $message= ####### Testcase for mix of db and table level: #######; grant SELECT,INSERT on priv2_db.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); use priv1_db; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc index 18c8a3ebcd5..f1efff990f1 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_definer.inc @@ -27,7 +27,6 @@ let $message= ######### Testcase for definer: ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc index cd90d25aefd..b6f4af7e0a7 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc @@ -38,7 +38,6 @@ let $message= #### Testcase for mix of user(global) and db level: ####; grant SELECT,INSERT on *.* to test_noprivs@localhost; show grants for test_noprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc index f1b3bbe2cb4..ea7c385768c 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc @@ -32,7 +32,6 @@ let $message= #### Testcase for trigger privilege on execution time ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; revoke ALL PRIVILEGES, GRANT OPTION FROM test_useprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc index 9cc272c09bc..94f30fe13c2 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc @@ -30,7 +30,6 @@ let $message= ######### Testcase for table level: ########; set password for test_noprivs@localhost = password('PWD'); revoke ALL PRIVILEGES, GRANT OPTION FROM test_noprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc index 53ce49c728c..e43f4ce97a3 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_transaction.inc @@ -27,7 +27,6 @@ let $message= ######### Testcase for transactions: ########; revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); diff --git a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc index af45017ae6a..d68b3d79086 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc @@ -22,7 +22,6 @@ let $message= Testcase: 3.5:; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con1_general,localhost,test_general,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK diff --git a/mysql-test/suite/funcs_1/triggers/triggers_08.inc b/mysql-test/suite/funcs_1/triggers/triggers_08.inc index 4b4050b996d..087f18e8e6b 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_08.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_08.inc @@ -23,7 +23,6 @@ let $message= Testcase: 3.5:; create User test_super@localhost; set password for test_super@localhost = password('PWD'); grant ALL on *.* to test_super@localhost with grant OPTION; - let $MASTER_MYSOCK= query_get_value(SHOW VARIABLES LIKE 'socket', Value, 1); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK connect (con2_general,localhost,test_general,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); --replace_result $MASTER_MYPORT MASTER_MYPORT $MASTER_MYSOCK MASTER_MYSOCK From a073ee45c290d81d365b48b03ef6924e778cd64f Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Tue, 9 Jun 2009 18:11:21 +0200 Subject: [PATCH 067/188] Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 Compiling MySQL with gcc 4.3.2 and later produces a number of warnings, many of which are new with the recent compiler versions. This bug will be resolved in more than one patch to limit the size of changesets. This is the first patch, fixing a number of the warnings, predominantly "suggest using parentheses around && in ||", and empty for and while bodies. --- sql/field.cc | 36 ++++++++++++++++++------------------ sql/field.h | 2 +- sql/field_conv.cc | 8 ++++---- sql/gstream.cc | 2 +- sql/handler.cc | 4 ++-- sql/item.cc | 6 +++--- sql/item_cmpfunc.cc | 8 ++++---- sql/item_func.cc | 4 ++-- sql/item_subselect.cc | 8 ++++---- sql/item_sum.cc | 12 ++++++------ sql/item_timefunc.cc | 8 ++++---- sql/log_event.cc | 3 ++- sql/opt_range.cc | 14 +++++++------- sql/opt_sum.cc | 4 ++-- sql/slave.cc | 2 +- 15 files changed, 61 insertions(+), 60 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index c7dd2afd934..2322c5d7b9d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1157,7 +1157,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len, if (unsigned_flag) { - if (((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max) || + if ((((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max)) || error == MY_ERRNO_ERANGE) { goto out_of_range; @@ -1324,7 +1324,7 @@ void Field::copy_from_tmp(int row_offset) if (null_ptr) { *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) | - null_ptr[row_offset] & (uchar) null_bit); + (null_ptr[row_offset] & (uchar) null_bit)); } } @@ -3674,8 +3674,8 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int error; char *end; double nr= my_strntod(cs,(char*) from,len,&end,&error); - if (error || (!len || (uint) (end-from) != len && - table->in_use->count_cuted_fields)) + if (error || (!len || ((uint) (end-from) != len && + table->in_use->count_cuted_fields))) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); @@ -3915,8 +3915,8 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int error; char *end; double nr= my_strntod(cs,(char*) from, len, &end, &error); - if (error || (!len || (uint) (end-from) != len && - table->in_use->count_cuted_fields)) + if (error || (!len || ((uint) (end-from) != len && + table->in_use->count_cuted_fields))) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, (error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1); @@ -4771,7 +4771,7 @@ int Field_time::store(longlong nr, bool unsigned_val) MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr > (longlong) TIME_MAX_VALUE || nr < 0 && unsigned_val) + else if (nr > (longlong) TIME_MAX_VALUE || (nr < 0 && unsigned_val)) { tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -4930,7 +4930,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) int error; longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || + if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155 || error == MY_ERRNO_ERANGE) { *ptr=0; @@ -4973,7 +4973,7 @@ int Field_year::store(double nr) int Field_year::store(longlong nr, bool unsigned_val) { - if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) + if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155) { *ptr= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -5968,16 +5968,16 @@ int Field_str::store(double nr) /* Calculate the exponent from the 'e'-format conversion */ if (anr < 1.0 && anr > 0) { - for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100); - for (; anr < 1e-10; exp-= 10, anr*= 1e10); - for (i= 1; anr < 1 / log_10[i]; exp--, i++); + for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100) ; + for (; anr < 1e-10; exp-= 10, anr*= 1e10) ; + for (i= 1; anr < 1 / log_10[i]; exp--, i++) ; exp--; } else { - for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100); - for (; anr > 1e10; exp+= 10, anr/= 1e10); - for (i= 1; anr > log_10[i]; exp++, i++); + for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100) ; + for (; anr > 1e10; exp+= 10, anr/= 1e10) ; + for (i= 1; anr > log_10[i]; exp++, i++) ; } max_length= local_char_length - neg; @@ -7986,7 +7986,7 @@ bool Field_num::eq_def(Field *field) Field_num *from_num= (Field_num*) field; if (unsigned_flag != from_num->unsigned_flag || - zerofill && !from_num->zerofill && !zero_pack() || + (zerofill && !from_num->zerofill && !zero_pack()) || dec != from_num->dec) return 0; return 1; @@ -8065,7 +8065,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) { int delta; - for (; length && !*from; from++, length--); // skip left 0's + for (; length && !*from; from++, length--) ; // skip left 0's delta= bytes_in_rec - length; if (delta < -1 || @@ -8284,7 +8284,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) int delta; uchar bits= (uchar) (field_length & 7); - for (; length && !*from; from++, length--); // skip left 0's + for (; length && !*from; from++, length--) ; // skip left 0's delta= bytes_in_rec - length; if (delta < 0 || diff --git a/sql/field.h b/sql/field.h index 2975719a591..eef3618a142 100644 --- a/sql/field.h +++ b/sql/field.h @@ -170,7 +170,7 @@ public: memcpy(ptr, ptr + l_offset, pack_length()); if (null_ptr) *null_ptr= ((*null_ptr & (uchar) ~null_bit) | - null_ptr[l_offset] & null_bit); + (null_ptr[l_offset] & null_bit)); } virtual bool binary() const { return 1; } virtual bool zero_pack() const { return 1; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 2705d4f617b..7beb41b8ff1 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -95,7 +95,7 @@ static void do_field_to_null_str(Copy_field *copy) static void do_outer_field_to_null_str(Copy_field *copy) { if (*copy->null_row || - copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)) + (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit))) { bzero(copy->to_ptr,copy->from_length); copy->to_null_ptr[0]=1; // Always bit 1 @@ -209,7 +209,7 @@ static void do_copy_null(Copy_field *copy) static void do_outer_field_null(Copy_field *copy) { if (*copy->null_row || - copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)) + (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit))) { *copy->to_null_ptr|=copy->to_bit; copy->to_field->reset(); @@ -656,9 +656,9 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) */ if (to->real_type() != from->real_type() || !compatible_db_low_byte_first || - ((to->table->in_use->variables.sql_mode & + (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && - to->type() == FIELD_TYPE_DATE || + to->type() == FIELD_TYPE_DATE) || to->type() == FIELD_TYPE_DATETIME)) { if (from->real_type() == FIELD_TYPE_ENUM || diff --git a/sql/gstream.cc b/sql/gstream.cc index 0c8011549f3..e2bb41b8541 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -75,7 +75,7 @@ bool Gis_read_stream::get_next_number(double *d) skip_space(); if ((m_cur >= m_limit) || - (*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+') + ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')) { set_error_msg("Numeric constant expected"); return 1; diff --git a/sql/handler.cc b/sql/handler.cc index 63f652fc2b4..2840037024b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1642,8 +1642,8 @@ int handler::update_auto_increment() thd->prev_insert_id= thd->next_insert_id; if ((nr= table->next_number_field->val_int()) != 0 || - table->auto_increment_field_not_null && - thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) + (table->auto_increment_field_not_null && + thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { /* Mark that we didn't generate a new value **/ auto_increment_column_changed=0; diff --git a/sql/item.cc b/sql/item.cc index 7a81e48fcee..c20089694db 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2587,7 +2587,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, if (value.time.year > 9999 || value.time.month > 12 || value.time.day > 31 || - time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23 || + (time_type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23) || value.time.minute > 59 || value.time.second > 59) { char buff[MAX_DATE_STRING_REP_LENGTH]; @@ -4728,8 +4728,8 @@ int Item::save_in_field(Field *field, bool no_conversions) { int error; if (result_type() == STRING_RESULT || - result_type() == REAL_RESULT && - field->result_type() == STRING_RESULT) + (result_type() == REAL_RESULT && + field->result_type() == STRING_RESULT)) { String *result; CHARSET_INFO *cs= collation.collation; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 01d3e9bed52..c940c4ab3c0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1419,8 +1419,8 @@ longlong Item_func_truth::val_int() bool Item_in_optimizer::fix_left(THD *thd, Item **ref) { - if (!args[0]->fixed && args[0]->fix_fields(thd, args) || - !cache && !(cache= Item_cache::get_cache(args[0]))) + if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) || + (!cache && !(cache= Item_cache::get_cache(args[0])))) return 1; cache->setup(args[0]); @@ -2934,8 +2934,8 @@ int cmp_longlong(void *cmp_arg, One of the args is unsigned and is too big to fit into the positive signed range. Report no match. */ - if (a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX || - b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX) + if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) || + (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX)) return a->unsigned_flag ? 1 : -1; /* Although the signedness differs both args can fit into the signed diff --git a/sql/item_func.cc b/sql/item_func.cc index 2421f7e0526..6193ab285f2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4427,8 +4427,8 @@ int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions, update(); if (result_type() == STRING_RESULT || - result_type() == REAL_RESULT && - field->result_type() == STRING_RESULT) + (result_type() == REAL_RESULT && + field->result_type() == STRING_RESULT)) { String *result; CHARSET_INFO *cs= collation.collation; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 401751660fd..13eeba3ea27 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1232,8 +1232,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) Item *item_having_part2= 0; for (uint i= 0; i < cols_num; i++) { - DBUG_ASSERT(left_expr->fixed && - select_lex->ref_pointer_array[i]->fixed || + DBUG_ASSERT((left_expr->fixed && + select_lex->ref_pointer_array[i]->fixed) || (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); @@ -1310,8 +1310,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) for (uint i= 0; i < cols_num; i++) { Item *item, *item_isnull; - DBUG_ASSERT(left_expr->fixed && - select_lex->ref_pointer_array[i]->fixed || + DBUG_ASSERT((left_expr->fixed && + select_lex->ref_pointer_array[i]->fixed) || (select_lex->ref_pointer_array[i]->type() == REF_ITEM && ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() == Item_ref::OUTER_REF)); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 57045f52825..a381361e8a2 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -652,8 +652,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) return TRUE; // 'item' can be changed during fix_fields - if (!item->fixed && - item->fix_fields(thd, args) || + if ((!item->fixed && + item->fix_fields(thd, args)) || (item= args[0])->check_cols(1)) return TRUE; decimals=item->decimals; @@ -969,8 +969,8 @@ void Item_sum_distinct::fix_length_and_dec() integers each <= 2^32. */ if (table_field_type == MYSQL_TYPE_INT24 || - table_field_type >= MYSQL_TYPE_TINY && - table_field_type <= MYSQL_TYPE_LONG) + (table_field_type >= MYSQL_TYPE_TINY && + table_field_type <= MYSQL_TYPE_LONG)) { val.traits= Hybrid_type_traits_fast_decimal::instance(); break; @@ -2608,8 +2608,8 @@ bool Item_sum_count_distinct::setup(THD *thd) enum enum_field_types f_type= f->type(); tree_key_length+= f->pack_length(); if ((f_type == MYSQL_TYPE_VARCHAR) || - !f->binary() && (f_type == MYSQL_TYPE_STRING || - f_type == MYSQL_TYPE_VAR_STRING)) + (!f->binary() && (f_type == MYSQL_TYPE_STRING || + f_type == MYSQL_TYPE_VAR_STRING))) { all_binary= FALSE; break; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 22ca8a925db..39f869106b6 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -439,7 +439,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, strict_week_number= (*ptr=='V' || *ptr=='v'); tmp= (char*) val + min(val_len, 2); if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 || - strict_week_number && !week_number || + (strict_week_number && !week_number) || week_number > 53) goto err; val= tmp; @@ -535,10 +535,10 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, %V,%v require %X,%x resprectively, %U,%u should be used with %Y and not %X or %x */ - if (strict_week_number && + if ((strict_week_number && (strict_week_number_year < 0 || - strict_week_number_year_type != sunday_first_n_first_week_non_iso) || - !strict_week_number && strict_week_number_year >= 0) + strict_week_number_year_type != sunday_first_n_first_week_non_iso)) || + (!strict_week_number && strict_week_number_year >= 0)) goto err; /* Number of days since year 0 till 1st Jan of this year */ diff --git a/sql/log_event.cc b/sql/log_event.cc index a440f010fa5..3a6daadd11a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1733,7 +1733,8 @@ void Query_log_event::print_query_header(FILE* file, if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db) { - if (different_db= memcmp(print_event_info->db, db, db_len + 1)) + different_db= memcmp(print_event_info->db, db, db_len + 1); + if (different_db) memcpy(print_event_info->db, db, db_len + 1); if (db[0] && different_db) fprintf(file, "use %s%s\n", db, print_event_info->delimiter); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c3a43776429..d52db41d64c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2032,7 +2032,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, quick=0; needed_reg.clear_all(); quick_keys.clear_all(); - if ((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range || + if (((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range) || !limit) DBUG_RETURN(0); /* purecov: inspected */ if (keys_to_use.is_clear_all()) @@ -2462,8 +2462,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost)); if (imerge_too_expensive || (imerge_cost > read_time) || - (non_cpk_scan_records+cpk_scan_records >= param->table->file->records) && - read_time != DBL_MAX) + ((non_cpk_scan_records+cpk_scan_records >= param->table->file->records) && + read_time != DBL_MAX)) { /* Bail out if it is obvious that both index_merge and ROR-union will be @@ -6490,7 +6490,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, goto err; quick->records= records; - if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error || + if ((cp_buffer_from_ref(thd,ref) && thd->is_fatal_error) || !(range= new(alloc) QUICK_RANGE())) goto err; // out of memory @@ -7342,7 +7342,7 @@ int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg) cmp= key_cmp(key_part_info, (byte*) range_arg->min_key, range_arg->min_length); - if (cmp > 0 || cmp == 0 && !(range_arg->flag & NEAR_MIN)) + if (cmp > 0 || (cmp == 0 && !(range_arg->flag & NEAR_MIN))) return 0; return 1; // outside of range } @@ -9395,7 +9395,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* Compare the found key with max_key. */ int cmp_res= key_cmp(index_info->key_part, max_key, real_prefix_len + min_max_arg_len); - if (!((cur_range->flag & NEAR_MAX) && (cmp_res == -1) || + if (!(((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) || (cmp_res <= 0))) { result = HA_ERR_KEY_NOT_FOUND; @@ -9511,7 +9511,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* Compare the found key with min_key. */ int cmp_res= key_cmp(index_info->key_part, min_key, real_prefix_len + min_max_arg_len); - if (!((cur_range->flag & NEAR_MIN) && (cmp_res == 1) || + if (!(((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) || (cmp_res >= 0))) continue; } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index f8603f06fa0..66aa29c6680 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -690,8 +690,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, } else if (eq_type) { - if (!is_null && !cond->val_int() || - is_null && !test(part->field->is_null())) + if ((!is_null && !cond->val_int()) || + (is_null && !test(part->field->is_null()))) return 0; // Impossible test } else if (is_field_part) diff --git a/sql/slave.cc b/sql/slave.cc index 88c19a04602..dd80b13ed46 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1334,7 +1334,7 @@ static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, up to and including newline. */ int c; - while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)); + while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ; } return 0; } From 403b08342da4905fe0f2be29495ce1d134504038 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Jun 2009 19:32:32 -0300 Subject: [PATCH 068/188] Define MASTER_MYSOCK for ndb tests. Needed for substitution in some tests. mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes: Remove unused file. mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes: Remove unused file. mysql-test/suite/ndb/my.cnf: Export the socket path. --- mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes | 9 --------- mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes | 9 --------- mysql-test/suite/ndb/my.cnf | 1 + 3 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes delete mode 100644 mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes diff --git a/mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes b/mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes deleted file mode 100644 index ce061da2299..00000000000 --- a/mysql-test/suite/funcs_1/t/ndb_storedproc_06.tes +++ /dev/null @@ -1,9 +0,0 @@ -#### suite/funcs_1/t/innodb_storedproc_06.test -# -# 1. Check if InnoDB is available ---source include/have_innodb.inc - -# 2. Set $engine_type -let $engine_type= innodb; - ---source suite/funcs_1/storedproc/storedproc_06.inc diff --git a/mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes b/mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes deleted file mode 100644 index c8c289c5f49..00000000000 --- a/mysql-test/suite/funcs_1/t/ndb_storedproc_08.tes +++ /dev/null @@ -1,9 +0,0 @@ -#### suite/funcs_1/t/innodb_storedproc_08.test -# -# 1. Check if InnoDB is available ---source include/have_innodb.inc - -# 2. Set $engine_type -let $engine_type= innodb; - ---source suite/funcs_1/storedproc/storedproc_08.inc diff --git a/mysql-test/suite/ndb/my.cnf b/mysql-test/suite/ndb/my.cnf index 60769272ada..a19fdeee302 100644 --- a/mysql-test/suite/ndb/my.cnf +++ b/mysql-test/suite/ndb/my.cnf @@ -13,6 +13,7 @@ ndbcluster [ENV] NDB_CONNECTSTRING= @mysql_cluster.1.ndb_connectstring +MASTER_MYSOCK= @mysqld.1.1.socket MASTER_MYPORT= @mysqld.1.1.port MASTER_MYPORT1= @mysqld.2.1.port From 897a1b56d87c75261de556aefb718467408a34eb Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 10 Jun 2009 11:24:47 +0400 Subject: [PATCH 069/188] Bug #45236: large blob inserts from mysqldump fail, possible memory issue ? The mysql command line client could misinterpret some character sequences as commands under some circumstances. The upper limit for internal readline buffer was raised to 1 GB (the same as for server's max_allowed_packet) so that any input line is processed by add_line() as a whole rather than in chunks. client/mysql.cc: The upper limit for internal readline buffer was raised to 1 GB (the same as for server's max_allowed_packet) so that any input line is processed by add_line() as a whole rather than in chunks. mysql-test/r/mysql-bug45236.result: Added a test case for bug #45236. mysql-test/t/mysql-bug45236.test: Added a test case for bug #45236. --- client/mysql.cc | 2 +- mysql-test/r/mysql-bug45236.result | 8 ++++++ mysql-test/t/mysql-bug45236.test | 43 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/mysql-bug45236.result create mode 100644 mysql-test/t/mysql-bug45236.test diff --git a/client/mysql.cc b/client/mysql.cc index b7d66071ca5..216a8f87c27 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -112,7 +112,7 @@ extern "C" { #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" -#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L) +#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L * 1024L) typedef struct st_status { diff --git a/mysql-test/r/mysql-bug45236.result b/mysql-test/r/mysql-bug45236.result new file mode 100644 index 00000000000..cefcb1d314c --- /dev/null +++ b/mysql-test/r/mysql-bug45236.result @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS t1; +SET @old_max_allowed_packet= @@global.max_allowed_packet; +SET @@global.max_allowed_packet = 1024 * 1024 + 1024; +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT CONCAT(REPEAT('1', 1024*1024 - 27), +"\'\r dummydb dummyhost"); +DROP TABLE t1; +SET @@global.max_allowed_packet = @old_max_allowed_packet; diff --git a/mysql-test/t/mysql-bug45236.test b/mysql-test/t/mysql-bug45236.test new file mode 100644 index 00000000000..30cef1ab49c --- /dev/null +++ b/mysql-test/t/mysql-bug45236.test @@ -0,0 +1,43 @@ +# +# Bug #45236: large blob inserts from mysqldump fail, possible memory issue ? +# +# This test consumes a significant amount of resources. +# Therefore it should be kept separated from other tests. +# Otherwise we might suffer from problems like +# Bug#43801 mysql.test takes too long, fails due to expired timeout +# on debx86-b in PB +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +# Have to change the global variable as the session variable is +# read-only. +SET @old_max_allowed_packet= @@global.max_allowed_packet; +# ~1 MB blob length + some space for the rest of INSERT query +SET @@global.max_allowed_packet = 1024 * 1024 + 1024; + +# Create a new connection since the global max_allowed_packet +# has no effect onr the current one +connect (con1, localhost, root,,); + +CREATE TABLE t1(data LONGBLOB); +INSERT INTO t1 SELECT CONCAT(REPEAT('1', 1024*1024 - 27), + "\'\r dummydb dummyhost"); + +let $outfile= $MYSQLTEST_VARDIR/tmp/bug41486.sql; +--error 0,1 +remove_file $outfile; +--exec $MYSQL_DUMP --compact -t test t1 > $outfile +# Check that the mysql client does not interpret the "\r" sequence as a command +--exec $MYSQL --max_allowed_packet=1M test < $outfile 2>&1 + +DROP TABLE t1; + +# Cleanup +disconnect con1; +--source include/wait_until_disconnected.inc +remove_file $outfile; +connection default; +SET @@global.max_allowed_packet = @old_max_allowed_packet; From d98dee2c3b79d6a98978a732b29c2726474e325e Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 10 Jun 2009 11:58:36 +0300 Subject: [PATCH 070/188] Bug #29971 status.test fails This test uses SHOW STATUS and the like, which may be unstable in the face of logging to table, since the CSV handler is actively executing operations and thus incrementing the counters. Fixed by disabling logging to table for the duration of the test and restoring it afterwards. This causes various counters to properly start counting from zero and never advance due to CSV operations. --- mysql-test/r/status.result | 11 +++++++---- mysql-test/t/status.test | 7 +++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index ca815540c29..ce3acba9b8a 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -1,13 +1,15 @@ set @old_concurrent_insert= @@global.concurrent_insert; set @@global.concurrent_insert= 0; +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; flush status; show status like 'Table_lock%'; Variable_name Value -Table_locks_immediate 1 +Table_locks_immediate 0 Table_locks_waited 0 select * from information_schema.session_status where variable_name like 'Table_lock%'; VARIABLE_NAME VARIABLE_VALUE -TABLE_LOCKS_IMMEDIATE 2 +TABLE_LOCKS_IMMEDIATE 0 TABLE_LOCKS_WAITED 0 # Switched to connection: con1 set sql_log_bin=0; @@ -154,7 +156,7 @@ Variable_name Value Com_show_status 3 show status like 'hand%write%'; Variable_name Value -Handler_write 5 +Handler_write 0 show status like '%tmp%'; Variable_name Value Created_tmp_disk_tables 0 @@ -162,7 +164,7 @@ Created_tmp_files 0 Created_tmp_tables 0 show status like 'hand%write%'; Variable_name Value -Handler_write 7 +Handler_write 0 show status like '%tmp%'; Variable_name Value Created_tmp_disk_tables 0 @@ -237,3 +239,4 @@ SELECT 9; DROP PROCEDURE p1; DROP FUNCTION f1; set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 5842f59af5c..5da210f5a69 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -12,6 +12,12 @@ set @old_concurrent_insert= @@global.concurrent_insert; set @@global.concurrent_insert= 0; +# Disable logging to table, since this will also cause table locking and unlocking, which will +# show up in SHOW STATUS and may cause sporadic failures + +SET @old_log_output = @@global.log_output; +SET GLOBAL LOG_OUTPUT = 'FILE'; + # PS causes different statistics --disable_ps_protocol @@ -350,6 +356,7 @@ DROP FUNCTION f1; # Restore global concurrent_insert value. Keep in the end of the test file. --connection default set @@global.concurrent_insert= @old_concurrent_insert; +SET GLOBAL log_output = @old_log_output; # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc From f2448c93d6fc159d8e450539e120066396c44596 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Wed, 10 Jun 2009 11:56:00 +0200 Subject: [PATCH 071/188] Bug#44821: select distinct on partitioned table returns wrong results Range analysis did not request sorted output from the storage engine, which cause partitioned handlers to process one partition at a time while reading key prefixes in ascending order, causing values to be missed. Fixed by always requesting sorted order during range analysis. This fix is introduced in 6.0 by the fix for bug no 41136. mysql-test/r/group_min_max.result: Bug#44821: Test result. mysql-test/t/group_min_max.test: Bug#44821: Test case sql/opt_range.cc: Bug#44821: Fix. --- mysql-test/r/group_min_max.result | 58 +++++++++++++++++++++++++++++++ mysql-test/t/group_min_max.test | 40 +++++++++++++++++++++ sql/opt_range.cc | 2 +- 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index b17884c4f7a..37b84bf8cd8 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2463,3 +2463,61 @@ c 2 DROP TABLE t1; End of 5.0 tests +CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) +PARTITION BY KEY (a, b) PARTITIONS 3 +; +INSERT INTO t1 VALUES +(17, 1, -8), +(3, 1, -7), +(23, 1, -6), +(22, 1, -5), +(11, 1, -4), +(21, 1, -3), +(19, 1, -2), +(30, 1, -1), +(20, 1, 1), +(16, 1, 2), +(18, 1, 3), +(9, 1, 4), +(15, 1, 5), +(28, 1, 6), +(29, 1, 7), +(25, 1, 8), +(10, 1, 9), +(13, 1, 10), +(27, 1, 11), +(24, 1, 12), +(12, 1, 13), +(26, 1, 14), +(14, 1, 15) +; +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; +b c +1 -8 +1 -7 +1 -6 +1 -5 +1 -4 +1 -3 +1 -2 +1 -1 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 +1 9 +1 10 +1 11 +1 12 +1 13 +1 14 +1 15 +EXPLAIN +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range bc bc 10 NULL 7 Using where; Using index for group-by +DROP TABLE t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index adfa77c881c..6fd39beab03 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -983,3 +983,43 @@ SELECT DISTINCT c FROM t1 WHERE d=4; DROP TABLE t1; --echo End of 5.0 tests +# +# Bug#44821: select distinct on partitioned table returns wrong results +# +CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) +PARTITION BY KEY (a, b) PARTITIONS 3 +; + +INSERT INTO t1 VALUES +(17, 1, -8), +(3, 1, -7), +(23, 1, -6), +(22, 1, -5), +(11, 1, -4), +(21, 1, -3), +(19, 1, -2), +(30, 1, -1), + +(20, 1, 1), +(16, 1, 2), +(18, 1, 3), +(9, 1, 4), +(15, 1, 5), +(28, 1, 6), +(29, 1, 7), +(25, 1, 8), +(10, 1, 9), +(13, 1, 10), +(27, 1, 11), +(24, 1, 12), +(12, 1, 13), +(26, 1, 14), +(14, 1, 15) +; + +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; + +EXPLAIN +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; + +DROP TABLE t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 147874611ce..2a46638330c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8556,7 +8556,7 @@ int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length, result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0, last_range->max_keypart_map ? &end_key : 0, test(last_range->flag & EQ_RANGE), - sorted); + TRUE); if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE)) last_range= 0; // Stop searching From afacea4d602bd2230791bd7a91f51e380e00f5d0 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 10 Jun 2009 10:59:59 -0300 Subject: [PATCH 072/188] Bug#41190: shared memory connections do not work in Vista, if server started from cmdline Backport to MySQL 5.0/1 fix by Vladislav Vaintroub: In Vista and later and also in when using terminal services, when server is started from command line, client cannot connect to it via shared memory protocol. This is a regression introduced when Bug#24731 was fixed. The reason is that client is trying to attach to shared memory using global kernel object namespace (all kernel objects are prefixed with Global\). However, server started from the command line in Vista and later will create shared memory and events using current session namespace. Thus, client is unable to find the server and connection fails. The fix for the client is to first try to find server using "local" names (omitting Global\ prefix) and only if server is not found, trying global namespace. --- sql-common/client.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 27cc110401c..5475d5d5160 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -412,6 +412,9 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) DWORD error_code = 0; DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE; char *shared_memory_base_name = mysql->options.shared_memory_base_name; + static const char *name_prefixes[] = {"","Global\\"}; + const char *prefix; + int i; /* get enough space base-name + '_' + longest suffix we might ever send @@ -426,9 +429,18 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) shared_memory_base_name is unique value for each server unique_part is uniquel value for each object (events and file-mapping) */ - suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS); - strmov(suffix_pos, "CONNECT_REQUEST"); - if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp))) + for (i = 0; i< array_elements(name_prefixes); i++) + { + prefix= name_prefixes[i]; + suffix_pos = strxmov(tmp, prefix , shared_memory_base_name, "_", NullS); + strmov(suffix_pos, "CONNECT_REQUEST"); + event_connect_request= OpenEvent(event_access_rights, FALSE, tmp); + if (event_connect_request) + { + break; + } + } + if (!event_connect_request) { error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR; goto err; @@ -480,7 +492,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) unique_part is uniquel value for each object (events and file-mapping) number_of_connection is number of connection between server and client */ - suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char, + suffix_pos = strxmov(tmp, prefix , shared_memory_base_name, "_", connect_number_char, "_", NullS); strmov(suffix_pos, "DATA"); if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL) From a10350978814ec7f7ba7e64f6615847e0311cc69 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 10 Jun 2009 16:04:07 +0200 Subject: [PATCH 073/188] Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 Compiling MySQL with gcc 4.3.2 and later produces a number of warnings, many of which are new with the recent compiler versions. This bug will be resolved in more than one patch to limit the size of changesets. This is the second patch, fixing more of the warnings. --- sql/examples/ha_tina.h | 2 +- sql/field_conv.cc | 4 ++-- sql/item.cc | 2 +- sql/spatial.h | 10 ++++---- sql/sql_acl.cc | 34 +++++++++++++-------------- sql/sql_analyse.cc | 2 +- sql/sql_base.cc | 38 +++++++++++++++--------------- sql/sql_delete.cc | 2 +- sql/sql_help.cc | 2 +- sql/sql_insert.cc | 9 ++++---- sql/sql_lex.cc | 34 +++++++++++++-------------- sql/sql_load.cc | 8 +++---- sql/sql_parse.cc | 28 +++++++++++------------ sql/sql_prepare.cc | 4 ++-- sql/sql_select.cc | 52 ++++++++++++++++++++++-------------------- sql/sql_show.cc | 8 +++---- sql/sql_table.cc | 10 ++++---- sql/sql_trigger.cc | 2 +- sql/sql_update.cc | 2 +- sql/sql_view.cc | 6 ++--- sql/sql_yacc.yy | 6 ++--- sql/table.cc | 8 +++---- sql/table.h | 2 +- sql/time.cc | 8 +++---- sql/tztime.cc | 4 ++-- sql/uniques.cc | 4 ++-- 26 files changed, 147 insertions(+), 144 deletions(-) diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h index 98cba8bf4cd..a00e8887c7e 100644 --- a/sql/examples/ha_tina.h +++ b/sql/examples/ha_tina.h @@ -29,7 +29,7 @@ typedef struct st_tina_share { THR_LOCK lock; } TINA_SHARE; -typedef struct tina_set { +struct tina_set { off_t begin; off_t end; }; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 7beb41b8ff1..630372dfac1 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -761,8 +761,8 @@ int field_conv(Field *to,Field *from) to->table->s->db_low_byte_first == from->table->s->db_low_byte_first && (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || - to->type() != FIELD_TYPE_DATE && - to->type() != FIELD_TYPE_DATETIME) && + (to->type() != FIELD_TYPE_DATE && + to->type() != FIELD_TYPE_DATETIME)) && (from->real_type() != MYSQL_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes)) diff --git a/sql/item.cc b/sql/item.cc index c20089694db..007af8fa522 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1478,7 +1478,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) set(dt); } else - ; // Do nothing + {} // Do nothing } else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && left_is_superset(this, &dt)) diff --git a/sql/spatial.h b/sql/spatial.h index 837ae153310..309789d43e5 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -116,12 +116,12 @@ struct MBR int touches(const MBR *mbr) { /* The following should be safe, even if we compare doubles */ - return ((((mbr->xmin == xmax) || (mbr->xmax == xmin)) && - ((mbr->ymin >= ymin) && (mbr->ymin <= ymax) || - (mbr->ymax >= ymin) && (mbr->ymax <= ymax))) || + return ((((mbr->xmin == xmax) || (mbr->xmax == xmin)) && + (((mbr->ymin >= ymin) && (mbr->ymin <= ymax)) || + ((mbr->ymax >= ymin) && (mbr->ymax <= ymax)))) || (((mbr->ymin == ymax) || (mbr->ymax == ymin)) && - ((mbr->xmin >= xmin) && (mbr->xmin <= xmax) || - (mbr->xmax >= xmin) && (mbr->xmax <= xmax)))); + (((mbr->xmin >= xmin) && (mbr->xmin <= xmax)) || + ((mbr->xmax >= xmin) && (mbr->xmax <= xmax))))); } int within(const MBR *mbr) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d5b79eaca4e..34d7e773ca2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1046,12 +1046,12 @@ static void acl_update_user(const char *user, const char *host, for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); - if (!acl_user->user && !user[0] || - acl_user->user && !strcmp(user,acl_user->user)) + if ((!acl_user->user && !user[0]) || + (acl_user->user && !strcmp(user,acl_user->user))) { - if (!acl_user->host.hostname && !host[0] || - acl_user->host.hostname && - !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) + if ((!acl_user->host.hostname && !host[0]) || + (acl_user->host.hostname && + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname))) { acl_user->access=privileges; if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) @@ -1129,16 +1129,16 @@ static void acl_update_db(const char *user, const char *host, const char *db, for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); - if (!acl_db->user && !user[0] || - acl_db->user && - !strcmp(user,acl_db->user)) + if ((!acl_db->user && !user[0]) || + (acl_db->user && + !strcmp(user,acl_db->user))) { - if (!acl_db->host.hostname && !host[0] || - acl_db->host.hostname && - !strcmp(host, acl_db->host.hostname)) + if ((!acl_db->host.hostname && !host[0]) || + (acl_db->host.hostname && + !strcmp(host, acl_db->host.hostname))) { - if (!acl_db->db && !db[0] || - acl_db->db && !strcmp(db,acl_db->db)) + if ((!acl_db->db && !db[0]) || + (acl_db->db && !strcmp(db,acl_db->db))) { if (privileges) acl_db->access=privileges; @@ -1345,8 +1345,8 @@ bool acl_check_host(const char *host, const char *ip) return 0; VOID(pthread_mutex_lock(&acl_cache->lock)); - if (host && hash_search(&acl_check_hosts,(byte*) host,(uint) strlen(host)) || - ip && hash_search(&acl_check_hosts,(byte*) ip,(uint) strlen(ip))) + if ((host && hash_search(&acl_check_hosts,(byte*) host,(uint) strlen(host))) || + (ip && hash_search(&acl_check_hosts,(byte*) ip,(uint) strlen(ip)))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); return 0; // Found host @@ -1564,8 +1564,8 @@ find_acl_user(const char *host, const char *user, my_bool exact) host, acl_user->host.hostname ? acl_user->host.hostname : "")); - if (!acl_user->user && !user[0] || - acl_user->user && !strcmp(user,acl_user->user)) + if ((!acl_user->user && !user[0]) || + (acl_user->user && !strcmp(user,acl_user->user))) { if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 4b3264069b5..7de395d8d91 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -247,7 +247,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) } DBUG_RETURN(0); } - for (str++; *(end - 1) == '0'; end--); // jump over zeros at the end + for (str++; *(end - 1) == '0'; end--) ; // jump over zeros at the end if (str == end) // number was something like '123.000' { char *endpos= (char*) str; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 854e603d21a..0f86a3dd311 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1556,7 +1556,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, it can not be cloned. Emit an error for an unsupported behaviour. */ if (table->query_id == thd->query_id || - thd->prelocked_mode && table->query_id) + (thd->prelocked_mode && table->query_id)) { my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); DBUG_RETURN(0); @@ -1610,8 +1610,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, distance > 0 - we have lock mode higher then we require distance == 0 - we have lock mode exactly which we need */ - if (best_distance < 0 && distance > best_distance || - distance >= 0 && distance < best_distance) + if ((best_distance < 0 && distance > best_distance) || + (distance >= 0 && distance < best_distance)) { best_distance= distance; best_table= table; @@ -2298,8 +2298,8 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) search= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, &state)) { - if (search->locked_by_name && wait_for_name_lock || - search->is_name_opened() && search->needs_reopen_or_name_lock()) + if ((search->locked_by_name && wait_for_name_lock) || + (search->is_name_opened() && search->needs_reopen_or_name_lock())) return 1; // Table is used } } while ((table=table->next)); @@ -5142,7 +5142,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, thd->lex->current_select->cur_pos_in_select_list= 0; while ((item= it++)) { - if (!item->fixed && item->fix_fields(thd, it.ref()) || + if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1)) { thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; @@ -5476,16 +5476,16 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, DBUG_ASSERT(tables->is_leaf_for_name_resolution()); - if (table_name && my_strcasecmp(table_alias_charset, table_name, - tables->alias) || + if ((table_name && my_strcasecmp(table_alias_charset, table_name, + tables->alias)) || (db_name && strcmp(tables->db,db_name))) continue; #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Ensure that we have access rights to all fields to be inserted. */ - if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL) || - tables->view && (tables->grant.privilege & SELECT_ACL))) && - !any_privileges) + if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL)) || + (tables->view && (tables->grant.privilege & SELECT_ACL))) && + !any_privileges) { field_iterator.set(tables); if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator)) @@ -5539,7 +5539,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, */ if (any_privileges) { - DBUG_ASSERT(tables->field_translation == NULL && table || + DBUG_ASSERT((tables->field_translation == NULL && table) || tables->is_natural_join); DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *fld= (Item_field*) item; @@ -5684,7 +5684,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, if (*conds) { thd->where="where clause"; - if (!(*conds)->fixed && (*conds)->fix_fields(thd, conds) || + if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) || (*conds)->check_cols(1)) goto err_no_arena; } @@ -5704,8 +5704,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, { /* Make a join an a expression */ thd->where="on clause"; - if (!embedded->on_expr->fixed && - embedded->on_expr->fix_fields(thd, &embedded->on_expr) || + if ((!embedded->on_expr->fixed && + embedded->on_expr->fix_fields(thd, &embedded->on_expr)) || embedded->on_expr->check_cols(1)) goto err_no_arena; select_lex->cond_count++; @@ -5860,8 +5860,8 @@ fill_record_n_invoke_before_triggers(THD *thd, List &fields, enum trg_event_type event) { return (fill_record(thd, fields, values, ignore_errors) || - triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE)); + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); } @@ -5955,8 +5955,8 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr, enum trg_event_type event) { return (fill_record(thd, ptr, values, ignore_errors) || - triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE)); + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 79fc4872f05..30b14209a7c 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -711,7 +711,7 @@ void multi_delete::send_error(uint errcode,const char *err) /* the error was handled or nothing deleted and no side effects return */ if (error_handled || - !thd->transaction.stmt.modified_non_trans_table && !deleted) + (!thd->transaction.stmt.modified_non_trans_table && !deleted)) DBUG_VOID_RETURN; /* Something already deleted so we have to invalidate cache */ diff --git a/sql/sql_help.cc b/sql/sql_help.cc index e369a72fa9f..93610ea22b7 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -522,7 +522,7 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol, String **end= pointers + names->elements; List_iterator it(*names); - for (pos= pointers; pos!=end; (*pos++= it++)); + for (pos= pointers; pos!=end; (*pos++= it++)) ; my_qsort(pointers,names->elements,sizeof(String*),string_ptr_cmp); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6d63a0907df..28b8bcd320d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -413,7 +413,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, bool is_multi_insert) { if (duplic == DUP_UPDATE || - duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) + (duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT)) { *lock_type= TL_WRITE_DEFAULT; return; @@ -887,7 +887,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (changed) query_cache_invalidate3(thd, table_list, 1); } - if (changed && error <= 0 || thd->transaction.stmt.modified_non_trans_table + if ((changed && error <= 0) + || thd->transaction.stmt.modified_non_trans_table || was_insert_delayed) { if (mysql_bin_log.is_open()) @@ -3016,8 +3017,8 @@ bool select_insert::send_eof() We must invalidate the table in the query cache before binlog writing and ha_autocommit_or_rollback */ - - if (changed= (info.copied || info.deleted || info.updated)) + changed= (info.copied || info.deleted || info.updated); + if (changed) { query_cache_invalidate3(thd, table, 1); if (thd->transaction.stmt.modified_non_trans_table) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 436f41dd209..2542207e9b3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -594,7 +594,7 @@ int MYSQLlex(void *arg, void *yythd) its value in a query for the binlog, the query must stay grammatically correct. */ - else if (c == '?' && lip->stmt_prepare_mode && !ident_map[yyPeek()]) + else if (c == '?' && lip->stmt_prepare_mode && !ident_map[(int)yyPeek()]) return(PARAM_MARKER); return((int) c); @@ -661,7 +661,7 @@ int MYSQLlex(void *arg, void *yythd) else #endif { - for (result_state= c; ident_map[c= yyGet()]; result_state|= c); + for (result_state= c; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; } @@ -673,9 +673,9 @@ int MYSQLlex(void *arg, void *yythd) If we find a space then this can't be an identifier. We notice this below by checking start != lex->ptr. */ - for (; state_map[c] == MY_LEX_SKIP ; c= yyGet()); + for (; state_map[c] == MY_LEX_SKIP ; c= yyGet()) ; } - if (start == lip->ptr && c == '.' && ident_map[yyPeek()]) + if (start == lip->ptr && c == '.' && ident_map[(int)yyPeek()]) lip->next_state=MY_LEX_IDENT_SEP; else { // '(' must follow directly if function @@ -708,7 +708,7 @@ int MYSQLlex(void *arg, void *yythd) yylval->lex_str.length=1; c=yyGet(); // should be '.' lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword) - if (!ident_map[yyPeek()]) // Probably ` or " + if (!ident_map[(int)yyPeek()]) // Probably ` or " lip->next_state= MY_LEX_START; return((int) c); @@ -782,11 +782,11 @@ int MYSQLlex(void *arg, void *yythd) else #endif { - for (result_state=0; ident_map[c= yyGet()]; result_state|= c); + for (result_state=0; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; } - if (c == '.' && ident_map[yyPeek()]) + if (c == '.' && ident_map[(int)yyPeek()]) lip->next_state=MY_LEX_IDENT_SEP;// Next is '.' yylval->lex_str= get_token(lip, 0, yyLength()); @@ -872,7 +872,7 @@ int MYSQLlex(void *arg, void *yythd) case MY_LEX_BIN_NUMBER: // Found b'bin-string' yyGet(); // Skip ' - while ((c= yyGet()) == '0' || c == '1'); + while ((c= yyGet()) == '0' || c == '1') ; length= (uint) (lip->ptr - lip->tok_start); // Length of bin-num + 3 if (c != '\'') return(ABORT_SYM); // Illegal hex constant @@ -883,8 +883,8 @@ int MYSQLlex(void *arg, void *yythd) return (BIN_NUM); case MY_LEX_CMP_OP: // Incomplete comparison operator - if (state_map[yyPeek()] == MY_LEX_CMP_OP || - state_map[yyPeek()] == MY_LEX_LONG_CMP_OP) + if (state_map[(int)yyPeek()] == MY_LEX_CMP_OP || + state_map[(int)yyPeek()] == MY_LEX_LONG_CMP_OP) yySkip(); if ((tokval = find_keyword(lip,(uint) (lip->ptr - lip->tok_start),0))) { @@ -895,11 +895,11 @@ int MYSQLlex(void *arg, void *yythd) break; case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator - if (state_map[yyPeek()] == MY_LEX_CMP_OP || - state_map[yyPeek()] == MY_LEX_LONG_CMP_OP) + if (state_map[(int)yyPeek()] == MY_LEX_CMP_OP || + state_map[(int)yyPeek()] == MY_LEX_LONG_CMP_OP) { yySkip(); - if (state_map[yyPeek()] == MY_LEX_CMP_OP) + if (state_map[(int)yyPeek()] == MY_LEX_CMP_OP) yySkip(); } if ((tokval = find_keyword(lip,(uint) (lip->ptr - lip->tok_start),0))) @@ -1043,7 +1043,7 @@ int MYSQLlex(void *arg, void *yythd) } break; case MY_LEX_USER_END: // end '@' of user@hostname - switch (state_map[yyPeek()]) { + switch (state_map[(int)yyPeek()]) { case MY_LEX_STRING: case MY_LEX_USER_VARIABLE_DELIMITER: case MY_LEX_STRING_OR_DELIMITER: @@ -1068,7 +1068,7 @@ int MYSQLlex(void *arg, void *yythd) yylval->lex_str.str=(char*) lip->ptr; yylval->lex_str.length=1; yySkip(); // Skip '@' - lip->next_state= (state_map[yyPeek()] == + lip->next_state= (state_map[(int)yyPeek()] == MY_LEX_USER_VARIABLE_DELIMITER ? MY_LEX_OPERATOR_OR_IDENT : MY_LEX_IDENT_OR_KEYWORD); @@ -1080,7 +1080,7 @@ int MYSQLlex(void *arg, void *yythd) [(global | local | session) .]variable_name */ - for (result_state= 0; ident_map[c= yyGet()]; result_state|= c); + for (result_state= 0; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; @@ -1670,7 +1670,7 @@ void st_select_lex::print_limit(THD *thd, String *str) item->substype() == Item_subselect::ALL_SUBS)) { DBUG_ASSERT(!item->fixed || - select_limit->val_int() == LL(1) && offset_limit == 0); + (select_limit->val_int() == LL(1) && offset_limit == 0)); return; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 5b9f8ea441d..83af6d477db 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -723,9 +723,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, real_item= item->real_item(); - if (!read_info.enclosed && + if ((!read_info.enclosed && (enclosed_length && length == 4 && - !memcmp(pos, STRING_WITH_LEN("NULL"))) || + !memcmp(pos, STRING_WITH_LEN("NULL")))) || (length == 1 && read_info.found_null)) { @@ -1132,8 +1132,8 @@ int READ_INFO::read_field() } // End of enclosed field if followed by field_term or line_term if (chr == my_b_EOF || - chr == line_term_char && terminator(line_term_ptr, - line_term_length)) + (chr == line_term_char && terminator(line_term_ptr, + line_term_length))) { // Maybe unexpected linefeed enclosed=1; found_end_of_line=1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 507805ec0c4..79b9b479a0c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1238,7 +1238,7 @@ pthread_handler_t handle_one_connection(void *arg) decrease_user_connections(thd->user_connect); if (thd->killed || - net->vio && net->error && net->report_error) + (net->vio && net->error && net->report_error)) { statistic_increment(aborted_threads, &LOCK_status); } @@ -2366,11 +2366,11 @@ void log_slow_statement(THD *thd) if ((thd->start_time > thd->time_after_lock && (ulong) (thd->start_time - thd->time_after_lock) > thd->variables.long_query_time) || - (thd->server_status & + ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && opt_log_queries_not_using_indexes && /* == SQLCOM_END unless this is a SHOW command */ - thd->lex->orig_sql_command == SQLCOM_END) + thd->lex->orig_sql_command == SQLCOM_END)) { thd_proc_info(thd, "logging slow query"); thd->status_var.long_query_count++; @@ -2676,8 +2676,8 @@ mysql_execute_command(THD *thd) variables, but for now this is probably good enough. Don't reset warnings when executing a stored routine. */ - if ((all_tables || &lex->select_lex != lex->all_selects_list || - lex->sroutines.records) && !thd->spcont || + if (((all_tables || &lex->select_lex != lex->all_selects_list || + lex->sroutines.records) && !thd->spcont) || lex->time_zone_tables_used) mysql_reset_errors(thd, 0); @@ -5641,7 +5641,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (schema_db) { - if (!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL) || + if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) || (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) { if (!no_errors) @@ -5678,7 +5678,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(FALSE); } if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) || - ! db && dont_check_global_grants) + (! db && dont_check_global_grants)) { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) @@ -6029,10 +6029,10 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) { if (access & want_access) { - if (!check_access(thd, access, table->db, + if ((!check_access(thd, access, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) && - !grant_option || !check_grant(thd, access, table, 0, 1, 1)) + !grant_option) || !check_grant(thd, access, table, 0, 1, 1)) DBUG_RETURN(0); } } @@ -7710,12 +7710,12 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) else if ((check_access(thd, UPDATE_ACL, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) || - grant_option && - check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && + (grant_option && + check_grant(thd, UPDATE_ACL, table, 0, 1, 1))) && (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) + (grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)))) DBUG_RETURN(TRUE); table->table_in_first_from_clause= 1; @@ -7735,7 +7735,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)) + (grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) DBUG_RETURN(TRUE); } } @@ -7961,7 +7961,7 @@ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table) return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); + (grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0)); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a20f61436a7..d14f14b526e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1367,7 +1367,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, THD *thd= stmt->thd; set_var_base *var; - if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || + if ((tables && check_table_access(thd, SELECT_ACL, tables, 0)) || open_and_lock_tables(thd, tables)) goto error; @@ -2714,7 +2714,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg) void Prepared_statement::setup_set_params() { /* Setup binary logging */ - if (mysql_bin_log.is_open() && is_update_query(lex->sql_command) || + if ((mysql_bin_log.is_open() && is_update_query(lex->sql_command)) || mysql_log.is_open() || mysql_slow_log.is_open()) { set_params_from_vars= insert_params_from_vars_with_log; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 437aca866c6..611197e6718 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1305,7 +1305,7 @@ JOIN::optimize() join_tab[const_tables].type != JT_ALL && join_tab[const_tables].type != JT_FT && join_tab[const_tables].type != JT_REF_OR_NULL && - (order && simple_order || group_list && simple_group)) + ((order && simple_order) || (group_list && simple_group))) { if (add_ref_to_table_cond(thd,&join_tab[const_tables])) { DBUG_RETURN(1); @@ -1809,9 +1809,9 @@ JOIN::exec() like SEC_TO_TIME(SUM(...)). */ - if (curr_join->group_list && (!test_if_subpart(curr_join->group_list, + if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list, curr_join->order) || - curr_join->select_distinct) || + curr_join->select_distinct)) || (curr_join->select_distinct && curr_join->tmp_table_param.using_indirect_summary_function)) { /* Must copy to another table */ @@ -2269,9 +2269,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, } else { - if (err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, proc_param, - select_lex, unit)) + err= join->prepare(rref_pointer_array, tables, wild_num, + conds, og_num, order, group, having, proc_param, + select_lex, unit); + if (err) { goto err; } @@ -2286,9 +2287,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, DBUG_RETURN(TRUE); thd_proc_info(thd, "init"); thd->used_tables=0; // Updated by setup_fields - if (err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, proc_param, - select_lex, unit)) + err= join->prepare(rref_pointer_array, tables, wild_num, + conds, og_num, order, group, having, proc_param, + select_lex, unit); + if (err) { goto err; } @@ -3744,7 +3746,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, if (use->key == prev->key && use->table == prev->table) { if (prev->keypart+1 < use->keypart || - prev->keypart == use->keypart && found_eq_constant) + (prev->keypart == use->keypart && found_eq_constant)) continue; /* remove */ } else if (use->keypart != 0) // First found must be 0 @@ -4984,8 +4986,8 @@ best_extension_by_limited_search(JOIN *join, { if (best_record_count > current_record_count || best_read_time > current_read_time || - idx == join->const_tables && // 's' is the first table in the QEP - s->table == join->sort_by_table) + (idx == join->const_tables && // 's' is the first table in the QEP + s->table == join->sort_by_table)) { if (best_record_count >= current_record_count && best_read_time >= current_read_time && @@ -5110,7 +5112,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, double current_read_time=read_time+best; if (best_record_count > current_record_count || best_read_time > current_read_time || - idx == join->const_tables && s->table == join->sort_by_table) + (idx == join->const_tables && s->table == join->sort_by_table)) { if (best_record_count >= current_record_count && best_read_time >= current_read_time && @@ -5955,8 +5957,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) the index if we are using limit and this is the first table */ - if (cond && - (!tab->keys.is_subset(tab->const_keys) && i > 0) || + if ((cond && + (!tab->keys.is_subset(tab->const_keys) && i > 0)) || (!tab->const_keys.is_clear_all() && i == join->const_tables && join->unit->select_limit_cnt < join->best_positions[i].records_read && @@ -7081,7 +7083,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, left_item_equal->merge(right_item_equal); /* Remove the merged multiple equality from the list */ List_iterator li(cond_equal->current_level); - while ((li++) != right_item_equal); + while ((li++) != right_item_equal) ; li.remove(); } } @@ -9663,9 +9665,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, reclength=1; // Dummy select /* Use packed rows if there is blobs or a lot of space to gain */ if (blob_count || - string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && + (string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || - string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)) + string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS))) use_packed_rows= 1; table->s->fields= field_count; @@ -10329,8 +10331,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, /* copy row that filled HEAP table */ if ((write_err=new_table.file->write_row(table->record[0]))) { - if (write_err != HA_ERR_FOUND_DUPP_KEY && - write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error) + if ((write_err != HA_ERR_FOUND_DUPP_KEY && + write_err != HA_ERR_FOUND_DUPP_UNIQUE) || !ignore_last_dupp_key_error) goto err; } @@ -12812,8 +12814,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, */ if ((order != join->group_list || !(join->select_options & SELECT_BIG_RESULT) || - select && select->quick && - select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) && + (select && select->quick && + select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) && test_if_skip_sort_order(tab,order,select_limit,0)) DBUG_RETURN(0); for (ORDER *ord= join->order; ord; ord= ord->next) @@ -13626,8 +13628,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, /* Lookup the current GROUP field in the FROM clause. */ order_item_type= order_item->type(); from_field= (Field*) not_found_field; - if (is_group_field && - order_item_type == Item::FIELD_ITEM || + if ((is_group_field && + order_item_type == Item::FIELD_ITEM) || order_item_type == Item::REF_ITEM) { from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables, @@ -14053,7 +14055,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables) if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); - for (; !(map & tables->table->map); tables= tables->next_leaf); + for (; !(map & tables->table->map); tables= tables->next_leaf) ; if (map != tables->table->map) DBUG_RETURN(0); // More than one table DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 59679c96120..8387c087836 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2987,10 +2987,10 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, TYPE_ENUM_PROCEDURE)) return 0; - if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && - proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE || - lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && - proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION || + if ((lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && + proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) || + (lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && + proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) || lex->orig_sql_command == SQLCOM_END) { restore_record(table, s->default_values); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9952fca6bcb..c4360c8d52e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -982,8 +982,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } /* Don't pack rows in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || - sql_field->sql_type == MYSQL_TYPE_VARCHAR && - create_info->row_type != ROW_TYPE_FIXED) + (sql_field->sql_type == MYSQL_TYPE_VARCHAR && + create_info->row_type != ROW_TYPE_FIXED)) (*db_options)|= HA_OPTION_PACK_RECORD; it2.rewind(); } @@ -1422,7 +1422,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->sql_type == MYSQL_TYPE_VARCHAR || sql_field->pack_flag & FIELDFLAG_BLOB))) { - if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB) || + if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) || sql_field->sql_type == MYSQL_TYPE_VARCHAR) key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; else @@ -3954,9 +3954,9 @@ view_err: } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, new_alias) || - (new_name != table_name || new_db != db) && // we also do rename + ((new_name != table_name || new_db != db) && // we also do rename Table_triggers_list::change_table_name(thd, db, table_name, - new_db, new_alias)) + new_db, new_alias))) { // Try to get everything back error=1; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index d2ae494d4eb..1fa8b83f300 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -179,7 +179,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) need second part of condition below, since check_access() function also checks that db is specified. */ - if (!thd->lex->spname->m_db.length || create && !tables->db_length) + if (!thd->lex->spname->m_db.length || (create && !tables->db_length)) { my_error(ER_NO_DB_ERROR, MYF(0)); DBUG_RETURN(TRUE); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 69f876ace39..481fe30c6e7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1532,7 +1532,7 @@ void multi_update::send_error(uint errcode,const char *err) /* the error was handled or nothing deleted and no side effects return */ if (error_handled || - !thd->transaction.stmt.modified_non_trans_table && !updated) + (!thd->transaction.stmt.modified_non_trans_table && !updated)) return; /* Something already updated so we have to invalidate cache */ diff --git a/sql/sql_view.cc b/sql/sql_view.cc index d1d84e76811..96077aeeb12 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -268,11 +268,11 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, */ if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || + (grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))) || (mode != VIEW_CREATE_NEW && (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0)))) + (grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0))))) goto err; for (sl= select_lex; sl; sl= sl->next_select()) @@ -322,7 +322,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, { if (check_access(thd, SELECT_ACL, tbl->db, &tbl->grant.privilege, 0, 0, test(tbl->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) + (grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))) goto err; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b6a215a2306..49b7fafcc0b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3943,7 +3943,7 @@ alter_list_item: MYSQL_YYABORT; } if (check_table_name($3->table.str,$3->table.length) || - $3->db.str && check_db_name($3->db.str)) + ($3->db.str && check_db_name($3->db.str))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); MYSQL_YYABORT; @@ -4094,8 +4094,8 @@ slave_until: | UNTIL_SYM slave_until_opts { LEX *lex=Lex; - if ((lex->mi.log_file_name || lex->mi.pos) && - (lex->mi.relay_log_name || lex->mi.relay_log_pos) || + if (((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || !((lex->mi.log_file_name && lex->mi.pos) || (lex->mi.relay_log_name && lex->mi.relay_log_pos))) { diff --git a/sql/table.cc b/sql/table.cc index 55a9b50605d..84b1099d5a2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2112,8 +2112,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type) { const char *save_where= thd->where; thd->where= "check option"; - if (!check_option->fixed && - check_option->fix_fields(thd, &check_option) || + if ((!check_option->fixed && + check_option->fix_fields(thd, &check_option)) || check_option->check_cols(1)) { DBUG_RETURN(TRUE); @@ -2827,7 +2827,7 @@ void Field_iterator_table_ref::set_field_iterator() /* Necesary, but insufficient conditions. */ DBUG_ASSERT(table_ref->is_natural_join || table_ref->nested_join || - table_ref->join_columns && + (table_ref->join_columns && /* This is a merge view. */ ((table_ref->field_translation && table_ref->join_columns->elements == @@ -2836,7 +2836,7 @@ void Field_iterator_table_ref::set_field_iterator() /* This is stored table or a tmptable view. */ (!table_ref->field_translation && table_ref->join_columns->elements == - table_ref->table->s->fields))); + table_ref->table->s->fields)))); field_it= &natural_join_it; DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join", table_ref->alias)); diff --git a/sql/table.h b/sql/table.h index ad578044371..db996d45320 100644 --- a/sql/table.h +++ b/sql/table.h @@ -729,7 +729,7 @@ struct TABLE_LIST void cleanup_items(); bool placeholder() { - return derived || view || schema_table || create && !table->db_stat || + return derived || view || schema_table || (create && !table->db_stat) || !table; } void print(THD *thd, String *str); diff --git a/sql/time.cc b/sql/time.cc index fb8a51fd0eb..b9cee5a986a 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -76,8 +76,8 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) if (l_time->month == 1 && l_time->day <= 7-weekday) { if (!week_year && - (first_weekday && weekday != 0 || - !first_weekday && weekday >= 4)) + ((first_weekday && weekday != 0) || + (!first_weekday && weekday >= 4))) return 0; week_year= 1; (*year)--; @@ -94,8 +94,8 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) if (week_year && days >= 52*7) { weekday= (weekday + calc_days_in_year(*year)) % 7; - if (!first_weekday && weekday < 4 || - first_weekday && weekday == 0) + if ((!first_weekday && weekday < 4) || + (first_weekday && weekday == 0)) { (*year)++; return 1; diff --git a/sql/tztime.cc b/sql/tztime.cc index d73a1ca0111..73e68ee2b29 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -447,8 +447,8 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage) } if (end_t == MY_TIME_T_MAX || - (cur_off_and_corr > 0) && - (end_t >= MY_TIME_T_MAX - cur_off_and_corr)) + ((cur_off_and_corr > 0) && + (end_t >= MY_TIME_T_MAX - cur_off_and_corr))) /* end of t space */ break; diff --git a/sql/uniques.cc b/sql/uniques.cc index a0d1beaf0f9..86223151d72 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -604,9 +604,9 @@ bool Unique::get(TABLE *table) outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), MYF(MY_ZEROFILL)); - if (!outfile || ! my_b_inited(outfile) && + if (!outfile || (! my_b_inited(outfile) && open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, - MYF(MY_WME))) + MYF(MY_WME)))) return 1; reinit_io_cache(outfile,WRITE_CACHE,0L,0,0); From dd59815f59be26b998d52b82a8c5f3e53e637c99 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 11 Jun 2009 02:08:40 +0100 Subject: [PATCH 074/188] BUG#34687 Error in bin-log after shutdown restart binlog was not closed properly While reading a binary log that is being used by a master or was not properly closed, most likely due to a crash, the following warning message is being printed out: "Warning: this binlog was not closed properly. Most probably mysqld crashed writing it.". This was scaring our users as the message was not taking into account the possibility of the file is being just used by the master. To avoid unnecessarily scaring our users, we replace the original message by the following one: Warning: "this binlog is either is use or was not closed properly.". --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 3a6daadd11a..c6c7bea651a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2257,8 +2257,8 @@ void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info) fprintf(file," at startup"); fputc('\n', file); if (flags & LOG_EVENT_BINLOG_IN_USE_F) - fprintf(file, "# Warning: this binlog was not closed properly. " - "Most probably mysqld crashed writing it.\n"); + fprintf(file, "# Warning: this binlog is either in use or was not " + "closed properly.\n"); } if (!artificial_event && created) { From afa76a9d7ad13d0995a4b27b9c2de5a9edbc7af2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 11 Jun 2009 18:21:54 +0530 Subject: [PATCH 075/188] Applying InnoDB snashot 5.1-ss5282, PRE-Fix for BUG#45097 BUG#45097 - Hang during recovery, redo logs for doublewrite buffer pages Detailed revision comments: r5126 | vasil | 2009-05-26 16:57:12 +0300 (Tue, 26 May 2009) | 9 lines branches/5.1: Preparation for the fix of Bug#45097 Hang during recovery, redo logs for doublewrite buffer pages Non-functional change: move FSP_* macros from fsp0fsp.h to a new file fsp0types.h. This is needed in order to be able to use FSP_EXTENT_SIZE in mtr0log.ic. r5127 | vasil | 2009-05-26 17:05:43 +0300 (Tue, 26 May 2009) | 9 lines branches/5.1: Preparation for the fix of Bug#45097 Hang during recovery, redo logs for doublewrite buffer pages Do not include unnecessary headers mtr0log.h and fut0lst.h in trx0sys.h and include fsp0fsp.h just before it is needed. This is needed in order to be able to use TRX_SYS_SPACE in mtr0log.ic. --- storage/innobase/include/fsp0fsp.h | 58 +----------------- storage/innobase/include/fsp0types.h | 89 ++++++++++++++++++++++++++++ storage/innobase/include/trx0sys.h | 4 +- 3 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 storage/innobase/include/fsp0types.h diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 82e95a2e920..17bfbeec2c1 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -15,29 +15,7 @@ Created 12/18/1995 Heikki Tuuri #include "fut0lst.h" #include "ut0byte.h" #include "page0types.h" - -/* If records are inserted in order, there are the following -flags to tell this (their type is made byte for the compiler -to warn if direction and hint parameters are switched in -fseg_alloc_free_page): */ -#define FSP_UP ((byte)111) /* alphabetically upwards */ -#define FSP_DOWN ((byte)112) /* alphabetically downwards */ -#define FSP_NO_DIR ((byte)113) /* no order */ - -/* File space extent size in pages */ -#define FSP_EXTENT_SIZE 64 - -/* On a page of any file segment, data may be put starting from this offset: */ -#define FSEG_PAGE_DATA FIL_PAGE_DATA - -/* File segment header which points to the inode describing the file segment */ -typedef byte fseg_header_t; - -#define FSEG_HDR_SPACE 0 /* space id of the inode */ -#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */ -#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */ - -#define FSEG_HEADER_SIZE 10 +#include "fsp0types.h" /************************************************************************** Initializes the file space system. */ @@ -350,40 +328,6 @@ fseg_print( fseg_header_t* header, /* in: segment header */ mtr_t* mtr); /* in: mtr */ -/* Flags for fsp_reserve_free_extents */ -#define FSP_NORMAL 1000000 -#define FSP_UNDO 2000000 -#define FSP_CLEANING 3000000 - -/* Number of pages described in a single descriptor page: currently each page -description takes less than 1 byte; a descriptor page is repeated every -this many file pages */ -#define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE - -/* The space low address page map */ -/*--------------------------------------*/ - /* The following two pages are repeated - every XDES_DESCRIBED_PER_PAGE pages in - every tablespace. */ -#define FSP_XDES_OFFSET 0 /* extent descriptor */ -#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */ - /* The ibuf bitmap pages are the ones whose - page number is the number above plus a - multiple of XDES_DESCRIBED_PER_PAGE */ - -#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */ - /* The following pages exist - in the system tablespace (space 0). */ -#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */ -#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */ - /* The ibuf tree root page number in - tablespace 0; its fseg inode is on the page - number FSP_FIRST_INODE_PAGE_NO */ -#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */ -#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */ -#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */ -/*--------------------------------------*/ - #ifndef UNIV_NONINL #include "fsp0fsp.ic" #endif diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h new file mode 100644 index 00000000000..6756d9d285c --- /dev/null +++ b/storage/innobase/include/fsp0types.h @@ -0,0 +1,89 @@ +/***************************************************************************** + +Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/****************************************************** +File space management types + +Created May 26, 2009 Vasil Dimov +*******************************************************/ + +#ifndef fsp0types_h +#define fsp0types_h + +#include "univ.i" + +#include "fil0fil.h" /* for FIL_PAGE_DATA */ + +/* If records are inserted in order, there are the following +flags to tell this (their type is made byte for the compiler +to warn if direction and hint parameters are switched in +fseg_alloc_free_page): */ +#define FSP_UP ((byte)111) /* alphabetically upwards */ +#define FSP_DOWN ((byte)112) /* alphabetically downwards */ +#define FSP_NO_DIR ((byte)113) /* no order */ + +/* File space extent size in pages */ +#define FSP_EXTENT_SIZE 64 + +/* On a page of any file segment, data may be put starting from this offset: */ +#define FSEG_PAGE_DATA FIL_PAGE_DATA + +/* File segment header which points to the inode describing the file segment */ +typedef byte fseg_header_t; + +#define FSEG_HDR_SPACE 0 /* space id of the inode */ +#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */ +#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */ + +#define FSEG_HEADER_SIZE 10 + +/* Flags for fsp_reserve_free_extents */ +#define FSP_NORMAL 1000000 +#define FSP_UNDO 2000000 +#define FSP_CLEANING 3000000 + +/* Number of pages described in a single descriptor page: currently each page +description takes less than 1 byte; a descriptor page is repeated every +this many file pages */ +#define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE + +/* The space low address page map */ +/*--------------------------------------*/ + /* The following two pages are repeated + every XDES_DESCRIBED_PER_PAGE pages in + every tablespace. */ +#define FSP_XDES_OFFSET 0 /* extent descriptor */ +#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */ + /* The ibuf bitmap pages are the ones whose + page number is the number above plus a + multiple of XDES_DESCRIBED_PER_PAGE */ + +#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */ + /* The following pages exist + in the system tablespace (space 0). */ +#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */ +#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */ + /* The ibuf tree root page number in + tablespace 0; its fseg inode is on the page + number FSP_FIRST_INODE_PAGE_NO */ +#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */ +#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */ +#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */ +/*--------------------------------------*/ + +#endif /* fsp0types_h */ diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index a8da5cd51a3..b57cfcf29d7 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -13,15 +13,12 @@ Created 3/26/1996 Heikki Tuuri #include "trx0types.h" #include "mtr0mtr.h" -#include "mtr0log.h" #include "ut0byte.h" #include "mem0mem.h" #include "sync0sync.h" #include "ut0lst.h" #include "buf0buf.h" #include "fil0fil.h" -#include "fut0lst.h" -#include "fsp0fsp.h" #include "read0types.h" /* In a MySQL replication slave, in crash recovery we store the master log @@ -302,6 +299,7 @@ trx_sys_print_mysql_master_log_pos(void); /* Space id and page no where the trx system file copy resides */ #define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */ +#include "fsp0fsp.h" #define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO /* The offset of the transaction system header on the page */ From 03bd6f025bbecd8f1694dd090d0eb68ef10d28e2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 11 Jun 2009 18:35:12 +0530 Subject: [PATCH 076/188] Applying InnoDB snashot 5.1-ss5282, Fix for BUG#45097 BUG#45097 - Hang during recovery, redo logs for doublewrite buffer pages Detailed revision comments: r5128 | vasil | 2009-05-26 17:26:37 +0300 (Tue, 26 May 2009) | 7 lines branches/5.1: Fix Bug#45097 Hang during recovery, redo logs for doublewrite buffer pages Do not write redo log for the pages in the doublewrite buffer. Also, do not make a dummy change to the page because this is not needed. r5150 | vasil | 2009-05-27 18:56:03 +0300 (Wed, 27 May 2009) | 4 lines branches/5.1: Whitespace fixup. --- storage/innobase/include/mtr0log.ic | 24 ++++++++++++++++++++++++ storage/innobase/include/trx0sys.h | 2 ++ storage/innobase/trx/trx0sys.c | 12 +++++------- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index 5b1d1ed34d9..1626f1e77e5 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -9,6 +9,8 @@ Created 12/7/1995 Heikki Tuuri #include "mach0data.h" #include "ut0lst.h" #include "buf0buf.h" +#include "fsp0types.h" +#include "trx0sys.h" /************************************************************ Opens a buffer to mlog. It must be closed with mlog_close. */ @@ -174,6 +176,28 @@ mlog_write_initial_log_record_fast( space = buf_block_get_space(block); offset = buf_block_get_page_no(block); + /* check whether the page is in the doublewrite buffer; + the doublewrite buffer is located in pages + FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the + system tablespace */ + if (space == TRX_SYS_SPACE + && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) { + if (trx_doublewrite_buf_is_being_created) { + /* Do nothing: we only come to this branch in an + InnoDB database creation. We do not redo log + anything for the doublewrite buffer pages. */ + return(log_ptr); + } else { + fprintf(stderr, + "Error: trying to redo log a record of type " + "%d on page %lu of space %lu in the " + "doublewrite buffer, continuing anyway.\n" + "Please post a bug report to " + "bugs.mysql.com.\n", + type, offset, space); + } + } + mach_write_to_1(log_ptr, type); log_ptr++; log_ptr += mach_write_compressed(log_ptr, space); diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index b57cfcf29d7..bad3c9d570c 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -42,6 +42,8 @@ extern trx_sys_t* trx_sys; /* Doublewrite system */ extern trx_doublewrite_t* trx_doublewrite; +/* Set to TRUE when the doublewrite buffer is being created */ +extern ibool trx_doublewrite_buf_is_being_created; extern ibool trx_doublewrite_must_reset_space_ids; extern ibool trx_sys_multiple_tablespace_format; diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 40348dd4199..7975950e912 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri /* The transaction system */ trx_sys_t* trx_sys = NULL; trx_doublewrite_t* trx_doublewrite = NULL; +ibool trx_doublewrite_buf_is_being_created = FALSE; /* The following is set to TRUE when we are upgrading from the old format data files to the new >= 4.1.x format multiple tablespaces format data files */ @@ -180,6 +181,7 @@ trx_sys_create_doublewrite_buf(void) start_again: mtr_start(&mtr); + trx_doublewrite_buf_is_being_created = TRUE; page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG @@ -196,6 +198,7 @@ start_again: trx_doublewrite_init(doublewrite); mtr_commit(&mtr); + trx_doublewrite_buf_is_being_created = FALSE; } else { fprintf(stderr, "InnoDB: Doublewrite buffer not found:" @@ -274,14 +277,8 @@ start_again: buf_page_dbg_add_level(new_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ - /* Make a dummy change to the page to ensure it will - be written to disk in a flush */ - - mlog_write_ulint(new_page + FIL_PAGE_DATA, - TRX_SYS_DOUBLEWRITE_MAGIC_N, - MLOG_4BYTES, &mtr); - if (i == FSP_EXTENT_SIZE / 2) { + ut_a(page_no == FSP_EXTENT_SIZE); mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1, page_no, MLOG_4BYTES, &mtr); @@ -291,6 +288,7 @@ start_again: page_no, MLOG_4BYTES, &mtr); } else if (i == FSP_EXTENT_SIZE / 2 + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { + ut_a(page_no == 2 * FSP_EXTENT_SIZE); mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2, page_no, MLOG_4BYTES, &mtr); From 92ffd7e025105798886932c41e2496844f0dcb77 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 11 Jun 2009 18:42:25 +0530 Subject: [PATCH 077/188] Applying InnoDB snashot 5.1-ss5282, Add TestCase for BUG#40565 Merge the test case from 5.0 to 5.1 for BUG#40565 Detailed revision comments: r5233 | marko | 2009-06-03 15:12:44 +0300 (Wed, 03 Jun 2009) | 11 lines branches/5.1: Merge the test case from r5232 from branches/5.0: ------------------------------------------------------------------------ r5232 | marko | 2009-06-03 14:31:04 +0300 (Wed, 03 Jun 2009) | 21 lines branches/5.0: Merge r3590 from branches/5.1 in order to fix Bug #40565 (Update Query Results in "1 Row Affected" But Should Be "Zero Rows"). Also, add a test case for Bug #40565. rb://128 approved by Heikki Tuuri ------------------------------------------------------------------------ --- mysql-test/r/innodb_bug40565.result | 9 +++++++++ mysql-test/t/innodb_bug40565.test | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 mysql-test/r/innodb_bug40565.result create mode 100644 mysql-test/t/innodb_bug40565.test diff --git a/mysql-test/r/innodb_bug40565.result b/mysql-test/r/innodb_bug40565.result new file mode 100644 index 00000000000..21e923d9336 --- /dev/null +++ b/mysql-test/r/innodb_bug40565.result @@ -0,0 +1,9 @@ +create table bug40565(value decimal(4,2)) engine=innodb; +insert into bug40565 values (1), (null); +update bug40565 set value=NULL; +affected rows: 1 +info: Rows matched: 2 Changed: 1 Warnings: 0 +update bug40565 set value=NULL; +affected rows: 0 +info: Rows matched: 2 Changed: 0 Warnings: 0 +drop table bug40565; diff --git a/mysql-test/t/innodb_bug40565.test b/mysql-test/t/innodb_bug40565.test new file mode 100644 index 00000000000..d7aa0fd514a --- /dev/null +++ b/mysql-test/t/innodb_bug40565.test @@ -0,0 +1,10 @@ +# Bug #40565 Update Query Results in "1 Row Affected" But Should Be "Zero Rows" +-- source include/have_innodb.inc + +create table bug40565(value decimal(4,2)) engine=innodb; +insert into bug40565 values (1), (null); +--enable_info +update bug40565 set value=NULL; +update bug40565 set value=NULL; +--disable_info +drop table bug40565; From 3e82a86ed2dea416c3262a912fb2f323b35a3dc4 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 12 Jun 2009 15:38:55 +0300 Subject: [PATCH 078/188] Bug #45386: Wrong query result with MIN function in field list, WHERE and GROUP BY clause Loose index scan may use range conditions on the argument of the MIN/MAX aggregate functions to find the beginning/end of the interval that satisfies the range conditions in a single go. These range conditions may have open or closed minimum/maximum values. When the comparison returns 0 (equal) the code should check the type of the min/max values of the current interval and accept or reject the row based on whether the limit is open or not. There was a wrong composite condition on checking this and it was not working in all cases. Fixed by simplifying the conditions and reversing the logic. mysql-test/r/group_min_max.result: Bug #45386: test case mysql-test/t/group_min_max.test: Bug #45386: test case sql/opt_range.cc: Bug #45386: fix the check whether to use the value if on the interval boundry --- mysql-test/r/group_min_max.result | 39 +++++++++++++++++++++++++++++++ mysql-test/t/group_min_max.test | 35 +++++++++++++++++++++++++++ sql/opt_range.cc | 20 ++++++++++++---- 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 58be2af1bb8..1138a5e1d88 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2443,4 +2443,43 @@ c 1 2 DROP TABLE t1; +# +# Bug #45386: Wrong query result with MIN function in field list, +# WHERE and GROUP BY clause +# +CREATE TABLE t (a INT, b INT, INDEX (a,b)); +INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); +INSERT INTO t SELECT * FROM t; +# test MIN +#should use range with index for group by +EXPLAIN +SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +#should return 1 row +SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; +a MIN(b) +2 1 +# test MAX +#should use range with index for group by +EXPLAIN +SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +#should return 1 row +SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; +a MAX(b) +2 0 +# test 3 ranges and use the middle one +INSERT INTO t SELECT a, 2 FROM t; +#should use range with index for group by +EXPLAIN +SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t range NULL a 10 NULL 9 Using where; Using index for group-by +#should return 1 row +SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; +a MAX(b) +2 1 +DROP TABLE t; End of 5.0 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index e124bf9e786..163c170eaa0 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -957,4 +957,39 @@ SELECT DISTINCT c FROM t1 WHERE d=4; DROP TABLE t1; +--echo # +--echo # Bug #45386: Wrong query result with MIN function in field list, +--echo # WHERE and GROUP BY clause +--echo # + +CREATE TABLE t (a INT, b INT, INDEX (a,b)); +INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); +INSERT INTO t SELECT * FROM t; + +--echo # test MIN +--echo #should use range with index for group by +EXPLAIN +SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; +--echo #should return 1 row +SELECT a, MIN(b) FROM t WHERE b <> 0 GROUP BY a; + +--echo # test MAX +--echo #should use range with index for group by +EXPLAIN +SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; +--echo #should return 1 row +SELECT a, MAX(b) FROM t WHERE b <> 1 GROUP BY a; + +--echo # test 3 ranges and use the middle one +INSERT INTO t SELECT a, 2 FROM t; + +--echo #should use range with index for group by +EXPLAIN +SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; +--echo #should return 1 row +SELECT a, MAX(b) FROM t WHERE b > 0 AND b < 2 GROUP BY a; + +DROP TABLE t; + + --echo End of 5.0 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d52db41d64c..571a342fa17 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9395,8 +9395,14 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* Compare the found key with max_key. */ int cmp_res= key_cmp(index_info->key_part, max_key, real_prefix_len + min_max_arg_len); - if (!(((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) || - (cmp_res <= 0))) + /* + The key is outside of the range if: + the interval is open and the key is equal to the maximum boundry + or + the key is greater than the maximum + */ + if (((cur_range->flag & NEAR_MAX) && cmp_res == 0) || + cmp_res > 0) { result = HA_ERR_KEY_NOT_FOUND; continue; @@ -9511,8 +9517,14 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* Compare the found key with min_key. */ int cmp_res= key_cmp(index_info->key_part, min_key, real_prefix_len + min_max_arg_len); - if (!(((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) || - (cmp_res >= 0))) + /* + The key is outside of the range if: + the interval is open and the key is equal to the minimum boundry + or + the key is less than the minimum + */ + if (((cur_range->flag & NEAR_MIN) && cmp_res == 0) || + cmp_res < 0) continue; } /* If we got to this point, the current key qualifies as MAX. */ From 62a32540fc8ff953ff0bbf360ffa273d0d2e28c4 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Fri, 12 Jun 2009 14:40:02 +0100 Subject: [PATCH 079/188] Bug#44920: MTR2 is not processing master.opt input properly on Windows Re-enabled tests main.init_connect and rpl.rpl_init_slave.test for non-Windows platforms. Please remove this code upon fixing the bug. --- mysql-test/suite/rpl/t/disabled.def | 1 - mysql-test/suite/rpl/t/rpl_init_slave.test | 6 ++++++ mysql-test/t/disabled.def | 1 - mysql-test/t/init_connect.test | 5 +++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index fcc3d56a9f5..38fc9e21322 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,4 +11,3 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx -rpl_init_slave : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows diff --git a/mysql-test/suite/rpl/t/rpl_init_slave.test b/mysql-test/suite/rpl/t/rpl_init_slave.test index 58d1f6bdc01..dd58b973fca 100644 --- a/mysql-test/suite/rpl/t/rpl_init_slave.test +++ b/mysql-test/suite/rpl/t/rpl_init_slave.test @@ -1,3 +1,9 @@ +if(`SELECT CONVERT(@@version_compile_os using latin1) IN ("Win32", "Win64", "Windows")`) +{ +--skip Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows +} + + source include/master-slave.inc; # diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index af4eb44b464..6d8f0af0c28 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,4 +12,3 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically -init_connect : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index b6bac5f65fa..1e93d0d671f 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -2,6 +2,11 @@ # Test of init_connect variable # +if(`SELECT CONVERT(@@version_compile_os using latin1) IN ("Win32", "Win64", "Windows")`) +{ +--skip Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows +} + # should work with embedded server after mysqltest is fixed --source include/not_embedded.inc From dfb06c38c94c63b8756b12cc073df0a663086193 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 12 Jun 2009 17:06:59 +0300 Subject: [PATCH 080/188] fixed the build-tags command --- support-files/build-tags | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/build-tags b/support-files/build-tags index 6c80d2638e9..b5386dc79c3 100755 --- a/support-files/build-tags +++ b/support-files/build-tags @@ -4,7 +4,7 @@ rm -f TAGS filter='\.cc$\|\.c$\|\.h$\|\.yy$' list="find . -type f" -bzr root >/dev/null 2>/dev/null && list="bzr ls --kind=file --versioned" +bzr root >/dev/null 2>/dev/null && list="bzr ls --from-root -R --kind=file --versioned" $list |grep $filter |while read f; do From 35cf66325047934176fa5bd91c22d99f555cdea7 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Fri, 12 Jun 2009 16:28:10 +0200 Subject: [PATCH 081/188] Bug #45387 Information about statement id for prepared statements missed from general log A refinement of the test in the previous patch to avoid using sleep as a means to ensure that timestamps are added to the log entries. mysql-test/t/log_tables_debug.test: New test file. A debug feature is used to ensure that log entries are prefixed with a timestamp. sql/log.cc: A debug feature is implemented to ensure that log entries are prefixed with a timestamp. --- mysql-test/r/log_tables_debug.result | 23 ++++++++ mysql-test/t/log_tables_debug.test | 88 ++++++++++++++++++++++++++++ sql/log.cc | 5 +- 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/log_tables_debug.result create mode 100644 mysql-test/t/log_tables_debug.test diff --git a/mysql-test/r/log_tables_debug.result b/mysql-test/r/log_tables_debug.result new file mode 100644 index 00000000000..7255c0d38a3 --- /dev/null +++ b/mysql-test/r/log_tables_debug.result @@ -0,0 +1,23 @@ +SET @old_general_log= @@global.general_log; +SET @old_general_log_file= @@global.general_log_file; +SET @old_slow_query_log= @@global.slow_query_log; +SET @old_slow_query_log_file= @@global.slow_query_log_file; +# +# Bug#45387 Information about statement id for prepared +# statements missed from general log +# +SET @@global.general_log = ON; +SET @@global.general_log_file = 'bug45387_general.log'; +SET SESSION debug='+d,reset_log_last_time'; +SET @@global.general_log = @old_general_log; +SET @@global.general_log_file = @old_general_log_file; +SET SESSION debug=''; +Bug#45387: ID match. +End of 5.1 tests +# +# Cleanup +# +SET global general_log = @old_general_log; +SET global general_log_file = @old_general_log_file; +SET global slow_query_log = @old_slow_query_log; +SET global slow_query_log_file = @old_slow_query_log_file; diff --git a/mysql-test/t/log_tables_debug.test b/mysql-test/t/log_tables_debug.test new file mode 100644 index 00000000000..86af7322505 --- /dev/null +++ b/mysql-test/t/log_tables_debug.test @@ -0,0 +1,88 @@ +### t/log_tables_debug.test +# +# Log-related tests requiring a debug-build server. +# + +# extra clean-up required due to Bug#38124, set to 1 when behavior has +# changed (see explanation in log_state.test) +let $fixed_bug38124 = 0; + +--source include/have_debug.inc + +# Several subtests modify global variables. Save the initial values only here, +# but reset to the initial values per subtest. +SET @old_general_log= @@global.general_log; +SET @old_general_log_file= @@global.general_log_file; +SET @old_slow_query_log= @@global.slow_query_log; +SET @old_slow_query_log_file= @@global.slow_query_log_file; + + +--echo # +--echo # Bug#45387 Information about statement id for prepared +--echo # statements missed from general log +--echo # + +let MYSQLD_DATADIR= `SELECT @@datadir`; + +# set logging to our specific bug log to control the entries added +SET @@global.general_log = ON; +SET @@global.general_log_file = 'bug45387_general.log'; + +# turn on output of timestamps on all log file entries, +SET SESSION debug='+d,reset_log_last_time'; + +let CONN_ID= `SELECT CONNECTION_ID()`; + +# reset log settings +SET @@global.general_log = @old_general_log; +SET @@global.general_log_file = @old_general_log_file; +SET SESSION debug=''; + +perl; + # get the relevant info from the surrounding perl invocation + $datadir= $ENV{'MYSQLD_DATADIR'}; + $conn_id= $ENV{'CONN_ID'}; + + # loop through the log file looking for the stmt querying for conn id + open(FILE, "$datadir/bug45387_general.log") or + die("Unable to read log file $datadir/bug45387_general.log: $!\n"); + while() { + if (/\d{6} \d\d:\d\d:\d\d[ \t]+(\d+)[ \t]+Query[ \t]+SELECT CONNECTION_ID/) { + $found= $1; + break; + } + } + close(FILE); + + # print the result + if ($found == $conn_id) { + print "Bug#45387: ID match.\n"; + } else { + print "Bug#45387: Expected ID '$conn_id', found '$found' in log file.\n"; + } +EOF + +--remove_file $MYSQLD_DATADIR/bug45387_general.log + +--echo End of 5.1 tests + + +--echo # +--echo # Cleanup +--echo # + +# Reset global system variables to initial values if forgotten somewhere above. +SET global general_log = @old_general_log; +SET global general_log_file = @old_general_log_file; +SET global slow_query_log = @old_slow_query_log; +SET global slow_query_log_file = @old_slow_query_log_file; +if(!$fixed_bug38124) +{ + --disable_query_log + let $my_var = `SELECT @old_general_log_file`; + eval SET @@global.general_log_file = '$my_var'; + let $my_var = `SELECT @old_slow_query_log_file`; + eval SET @@global.slow_query_log_file = '$my_var'; + --enable_query_log +} + diff --git a/sql/log.cc b/sql/log.cc index b6b92bf1950..ee7ee48b42c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2065,6 +2065,9 @@ bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host, /* Test if someone closed between the is_open test and lock */ if (is_open()) { + /* for testing output of timestamp and thread id */ + DBUG_EXECUTE_IF("reset_log_last_time", last_time= 0;); + /* Note that my_b_write() assumes it knows the length for this */ if (event_time != last_time) { @@ -2073,7 +2076,7 @@ bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host, localtime_r(&event_time, &start); time_buff_len= my_snprintf(local_time_buff, MAX_TIME_SIZE, - "%02d%02d%02d %2d:%02d:%02d", + "%02d%02d%02d %2d:%02d:%02d\t", start.tm_year % 100, start.tm_mon + 1, start.tm_mday, start.tm_hour, start.tm_min, start.tm_sec); From 66398a877a19b56496f706fd131046a5ad257ce8 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 12 Jun 2009 18:11:19 -0300 Subject: [PATCH 082/188] Bug#45100: Incomplete DROP USER in case of SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH' The SQL-mode PAD_CHAR_TO_FULL_LENGTH could prevent a DROP USER statement from privileges associated with the user being dropped. What ocurred was that reading from the User and Host fields of the tables tables_priv or columns_priv would yield values padded with spaces, causing a failure to match a specified user or host ('user' != 'user '); The solution is to disregard the PAD_CHAR_TO_FULL_LENGTH mode when iterating over and matching values in the privileges tables for a DROP USER statement. mysql-test/r/sql_mode.result: Add test case result for Bug#45100. mysql-test/t/sql_mode.test: Add test case for Bug#45100. sql/sql_acl.cc: Clear MODE_PAD_CHAR_TO_FULL_LENGTH before dropping privileges. --- mysql-test/r/sql_mode.result | 21 +++++++++++++++++++++ mysql-test/t/sql_mode.test | 36 ++++++++++++++++++++++++++++++++++++ sql/sql_acl.cc | 4 ++++ 3 files changed, 61 insertions(+) diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 401340f204c..0b0d5a38d0b 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -506,3 +506,24 @@ mysqltest_32753@localhost set session sql_mode=@OLD_SQL_MODE; flush privileges; drop user mysqltest_32753@localhost; +DROP TABLE IF EXISTS t1,t2; +CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'; +CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'; +CREATE TABLE t1 (f1 BIGINT); +CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20)); +GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +SET @OLD_SQL_MODE = @@SESSION.SQL_MODE; +SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'; +DROP USER 'user_PCTFL'@'localhost'; +SET SESSION SQL_MODE = @OLD_SQL_MODE; +DROP USER 'user_no_PCTFL'@'localhost'; +FLUSH PRIVILEGES; +SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv +SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Table_name Column_name Timestamp Column_priv +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index acc9cc7979e..4a9f34443cb 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -308,3 +308,39 @@ flush privileges; --connection default drop user mysqltest_32753@localhost; + +# +# Bug#45100: Incomplete DROP USER in case of SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH' +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings + +# Generate some prerequisites +CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'; +CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'; + +CREATE TABLE t1 (f1 BIGINT); +CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20)); + +# Grant privilege on a TABLE +GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +# Grant privilege on some COLUMN of a table +GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; + +SET @OLD_SQL_MODE = @@SESSION.SQL_MODE; +SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'; +DROP USER 'user_PCTFL'@'localhost'; +SET SESSION SQL_MODE = @OLD_SQL_MODE; +DROP USER 'user_no_PCTFL'@'localhost'; + +FLUSH PRIVILEGES; + +SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; + +# Cleanup +DROP TABLE t1; +DROP TABLE t2; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index be52fae2007..79fc5d816fd 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5696,6 +5696,7 @@ bool mysql_drop_user(THD *thd, List &list) List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_deleted= FALSE; + ulong old_sql_mode= thd->variables.sql_mode; DBUG_ENTER("mysql_drop_user"); /* @@ -5709,6 +5710,8 @@ bool mysql_drop_user(THD *thd, List &list) if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -5741,6 +5744,7 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); + thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(result); } From 6df6c8ee95976a53c0c054c86ad38dfa710c4ab5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 15 Jun 2009 16:38:15 +0300 Subject: [PATCH 083/188] Bug #44810: index merge and order by with low sort_buffer_size crashes server! The problem affects the scenario when index merge is followed by a filesort and the sort buffer is not big enough for all the sort keys. In this case the filesort function will read the data to the end through the index merge quick access method (and thus closing the cursor etc), but will leave the pointer to the quick select method in place. It will then create a temporary file to hold the results of the filesort and will add it as a sort output file (in sort.io_cache). Note that filesort will copy the original 'sort' structure in an automatic variable and restore it after it's done. As a result at exiting filesort() we have a sort.io_cache filled in and nothing else (as a result of close of the cursors at end of reading data through index merge). Now create_sort_index() will note that there is a select and will clean it up (as it's been used already by filesort() reading the data in). While doing that a special case in the index merge destructor will clean up the sort.io_cache, assuming it's an output of the index merge method and is not needed anymore. As a result the code that tries to read the data back from the filesort output will get no data in both memory and disk and will crash. Fixed similarly to how filesort() does it : by copying the sort.io_cache structure to a local variable, removing the pointer to the io_cache (so that it's not freed by QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT) and restoring the original structure (together with the valid pointer) after the cleanup is done. This is a safe thing to do because all the structures are already cleaned up by hitting the end of the index merge's read method (QUICK_INDEX_MERGE_SELECT::get_next()) and the cleanup code being written in a way that tolerates repeating cleanups. mysql-test/r/index_merge.result: Bug #44810: test case mysql-test/t/index_merge.test: Bug #44810: test case sql/sql_select.cc: Bug #44810: preserve the io_cache produced by filesort while cleaning up the index merge quick access method (QUICK_INDEX_MERGE_SELECT). --- mysql-test/r/index_merge.result | 24 ++++++++++++++++++++++++ mysql-test/t/index_merge.test | 26 ++++++++++++++++++++++++++ sql/sql_select.cc | 15 +++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result index f3fce29c910..4b3b0fb54fc 100644 --- a/mysql-test/r/index_merge.result +++ b/mysql-test/r/index_merge.result @@ -555,4 +555,28 @@ a 1 2 drop table t0, t1, t2, t3; +# +# BUG#44810: index merge and order by with low sort_buffer_size +# crashes server! +# +CREATE TABLE t1(a VARCHAR(128),b VARCHAR(128),KEY(A),KEY(B)); +INSERT INTO t1 VALUES (REPEAT('a',128),REPEAT('b',128)); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +SET SESSION sort_buffer_size=1; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '1' +EXPLAIN +SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' +ORDER BY a,b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge a,b a,b 131,131 NULL 64 Using sort_union(a,b); Using where; Using filesort +SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' +ORDER BY a,b; +SET SESSION sort_buffer_size=DEFAULT; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/index_merge.test b/mysql-test/t/index_merge.test index 7f176a4cd11..ebe0fa42fcd 100644 --- a/mysql-test/t/index_merge.test +++ b/mysql-test/t/index_merge.test @@ -503,4 +503,30 @@ where exists (select 1 from t2, t3 drop table t0, t1, t2, t3; +--echo # +--echo # BUG#44810: index merge and order by with low sort_buffer_size +--echo # crashes server! +--echo # +CREATE TABLE t1(a VARCHAR(128),b VARCHAR(128),KEY(A),KEY(B)); +INSERT INTO t1 VALUES (REPEAT('a',128),REPEAT('b',128)); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +SET SESSION sort_buffer_size=1; +EXPLAIN +SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' + ORDER BY a,b; +# we don't actually care about the result : we're checking if it crashes +--disable_result_log +SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' + ORDER BY a,b; +--enable_result_log + +SET SESSION sort_buffer_size=DEFAULT; +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 437aca866c6..0417460fe4f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12872,8 +12872,23 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, tab->records= table->sort.found_records; // For SQL_CALC_ROWS if (select) { + /* + We need to preserve tablesort's output resultset here, because + QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT (called by + SQL_SELECT::cleanup()) may free it assuming it's the result of the quick + select operation that we no longer need. Note that all the other parts of + this data structure are cleaned up when + QUICK_INDEX_MERGE_SELECT::get_next encounters end of data, so the next + SQL_SELECT::cleanup() call changes sort.io_cache alone. + */ + IO_CACHE *tablesort_result_cache; + + tablesort_result_cache= table->sort.io_cache; + table->sort.io_cache= NULL; + select->cleanup(); // filesort did select tab->select= 0; + table->sort.io_cache= tablesort_result_cache; } tab->select_cond=0; tab->last_inner= 0; From d6a9e61c4507fa4ff207f04ac0b3e649a85889e1 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Mon, 15 Jun 2009 17:14:00 +0200 Subject: [PATCH 084/188] Bug#32357 Prepared for push on 5.0-bugteam branch --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index e9de29e2c27..da7b4f70a46 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,6 +16,5 @@ im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly im_options_set : Bug#20294: Instance manager tests fail randomly im_options_unset : Bug#20294: Instance manager tests fail randomly im_utils : Bug#20294: Instance manager tests fail randomly -ndb_backup_print : Bug#32357: ndb_backup_print test fails sometimes in pushbuild rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes kill : Bug#29149 Test "kill" fails on Windows From 37a5f2d42168d68d8bfb6bdbf4ed90291af49f2a Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Mon, 15 Jun 2009 18:03:25 +0200 Subject: [PATCH 085/188] Bug #45387 Information about statement id for prepared statements missed from general log A FLUSH LOGS is added to ensure that the log info hits the file before attempting to process. mysql-test/t/log_tables_debug.test: A FLUSH LOGS is added, and in the event that a match is not found, is reset and the contents of the log file is dumped for debugging purposes. --- mysql-test/r/log_tables_debug.result | 3 ++- mysql-test/t/log_tables_debug.test | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/log_tables_debug.result b/mysql-test/r/log_tables_debug.result index 7255c0d38a3..16d8eed136f 100644 --- a/mysql-test/r/log_tables_debug.result +++ b/mysql-test/r/log_tables_debug.result @@ -9,9 +9,10 @@ SET @old_slow_query_log_file= @@global.slow_query_log_file; SET @@global.general_log = ON; SET @@global.general_log_file = 'bug45387_general.log'; SET SESSION debug='+d,reset_log_last_time'; +FLUSH LOGS; SET @@global.general_log = @old_general_log; SET @@global.general_log_file = @old_general_log_file; -SET SESSION debug=''; +SET SESSION debug='-d,reset_log_last_time'; Bug#45387: ID match. End of 5.1 tests # diff --git a/mysql-test/t/log_tables_debug.test b/mysql-test/t/log_tables_debug.test index 86af7322505..cc0210fe607 100644 --- a/mysql-test/t/log_tables_debug.test +++ b/mysql-test/t/log_tables_debug.test @@ -32,11 +32,12 @@ SET @@global.general_log_file = 'bug45387_general.log'; SET SESSION debug='+d,reset_log_last_time'; let CONN_ID= `SELECT CONNECTION_ID()`; +FLUSH LOGS; # reset log settings SET @@global.general_log = @old_general_log; SET @@global.general_log_file = @old_general_log_file; -SET SESSION debug=''; +SET SESSION debug='-d,reset_log_last_time'; perl; # get the relevant info from the surrounding perl invocation @@ -52,14 +53,20 @@ perl; break; } } - close(FILE); # print the result if ($found == $conn_id) { print "Bug#45387: ID match.\n"; } else { print "Bug#45387: Expected ID '$conn_id', found '$found' in log file.\n"; - } + print "Contents of log file:\n"; + seek(FILE, 0, 0); + while($line= ) { + print $line; + } + } + + close(FILE); EOF --remove_file $MYSQLD_DATADIR/bug45387_general.log From cebad07c5d1c0367b2e405f55baeb9e62422d095 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 15 Jun 2009 20:02:25 -0300 Subject: [PATCH 086/188] Disable session debugging after its not necessary anymore. mysql-test/t/log_tables_debug.test: Remove spurious spaces and disable session debugging. --- mysql-test/t/log_tables_debug.test | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mysql-test/t/log_tables_debug.test b/mysql-test/t/log_tables_debug.test index cc0210fe607..09b024643da 100644 --- a/mysql-test/t/log_tables_debug.test +++ b/mysql-test/t/log_tables_debug.test @@ -18,7 +18,7 @@ SET @old_slow_query_log_file= @@global.slow_query_log_file; --echo # ---echo # Bug#45387 Information about statement id for prepared +--echo # Bug#45387 Information about statement id for prepared --echo # statements missed from general log --echo # @@ -28,7 +28,7 @@ let MYSQLD_DATADIR= `SELECT @@datadir`; SET @@global.general_log = ON; SET @@global.general_log_file = 'bug45387_general.log'; -# turn on output of timestamps on all log file entries, +# turn on output of timestamps on all log file entries SET SESSION debug='+d,reset_log_last_time'; let CONN_ID= `SELECT CONNECTION_ID()`; @@ -37,7 +37,7 @@ FLUSH LOGS; # reset log settings SET @@global.general_log = @old_general_log; SET @@global.general_log_file = @old_general_log_file; -SET SESSION debug='-d,reset_log_last_time'; +SET SESSION debug='-d'; perl; # get the relevant info from the surrounding perl invocation @@ -45,7 +45,7 @@ perl; $conn_id= $ENV{'CONN_ID'}; # loop through the log file looking for the stmt querying for conn id - open(FILE, "$datadir/bug45387_general.log") or + open(FILE, "$datadir/bug45387_general.log") or die("Unable to read log file $datadir/bug45387_general.log: $!\n"); while() { if (/\d{6} \d\d:\d\d:\d\d[ \t]+(\d+)[ \t]+Query[ \t]+SELECT CONNECTION_ID/) { @@ -64,7 +64,7 @@ perl; while($line= ) { print $line; } - } + } close(FILE); EOF @@ -92,4 +92,3 @@ if(!$fixed_bug38124) eval SET @@global.slow_query_log_file = '$my_var'; --enable_query_log } - From 3cc3aa7d70ccffe701f378a6a9f21b1ee02dabc2 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 15 Jun 2009 20:27:27 -0300 Subject: [PATCH 087/188] Post-merge fix: modify regular expression to better handle 24 hour times (ie: 2:16:20). mysql-test/r/log_tables_debug.result: Update test case result. mysql-test/t/log_tables_debug.test: Skip spaces and handle case when a leading zero is not printed. --- mysql-test/r/log_tables_debug.result | 4 ++-- mysql-test/t/log_tables_debug.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/log_tables_debug.result b/mysql-test/r/log_tables_debug.result index 16d8eed136f..daedb8c103a 100644 --- a/mysql-test/r/log_tables_debug.result +++ b/mysql-test/r/log_tables_debug.result @@ -3,7 +3,7 @@ SET @old_general_log_file= @@global.general_log_file; SET @old_slow_query_log= @@global.slow_query_log; SET @old_slow_query_log_file= @@global.slow_query_log_file; # -# Bug#45387 Information about statement id for prepared +# Bug#45387 Information about statement id for prepared # statements missed from general log # SET @@global.general_log = ON; @@ -12,7 +12,7 @@ SET SESSION debug='+d,reset_log_last_time'; FLUSH LOGS; SET @@global.general_log = @old_general_log; SET @@global.general_log_file = @old_general_log_file; -SET SESSION debug='-d,reset_log_last_time'; +SET SESSION debug='-d'; Bug#45387: ID match. End of 5.1 tests # diff --git a/mysql-test/t/log_tables_debug.test b/mysql-test/t/log_tables_debug.test index 09b024643da..19a62614608 100644 --- a/mysql-test/t/log_tables_debug.test +++ b/mysql-test/t/log_tables_debug.test @@ -48,7 +48,7 @@ perl; open(FILE, "$datadir/bug45387_general.log") or die("Unable to read log file $datadir/bug45387_general.log: $!\n"); while() { - if (/\d{6} \d\d:\d\d:\d\d[ \t]+(\d+)[ \t]+Query[ \t]+SELECT CONNECTION_ID/) { + if (/\d{6}\s+\d+:\d+:\d+[ \t]+(\d+)[ \t]+Query[ \t]+SELECT CONNECTION_ID/) { $found= $1; break; } From 46f95f0b8283999574b37438626d09e86fafa077 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 16 Jun 2009 10:27:53 +0200 Subject: [PATCH 088/188] fixed version --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 02e5ad98817136d97374b4cc8d05083cd2ea6f8a Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Tue, 16 Jun 2009 10:34:47 +0200 Subject: [PATCH 089/188] Bug#43758 Query cache can lock up threads in 'freeing items' state Early patch submitted for discussion. It is possible for more than one thread to enter the condition in query_cache_insert(), but the condition predicate is to signal one thread each time the cache status changes between the following states: {NO_FLUSH_IN_PROGRESS,FLUSH_IN_PROGRESS, TABLE_FLUSH_IN_PROGRESS} Consider three threads THD1, THD2, THD3 THD2: select ... => Got a writer in ::store_query THD3: select ... => Got a writer in ::store_query THD1: flush tables => qc status= FLUSH_IN_PROGRESS; new writers are blocked. THD2: select ... => Still got a writer and enters cond in query_cache_insert THD3: select ... => Still got a writer and enters cond in query_cache_insert THD1: flush tables => finished and signal status change. THD2: select ... => Wakes up and completes the insert. THD3: select ... => Happily waiting for better times. Why hurry? This patch is a refactoring of this lock system. It introduces four new methods: Query_cache::try_lock() Query_cache::lock() Query_cache::lock_and_suspend() Query_cache::unlock() This change also deprecates wait_while_table_flush_is_in_progress(). All threads are queued and put on a conditional wait. On each unlock the queue is signalled. This resolve the issues with left over threads. To assure that no threads are spending unnecessary time waiting a signal broadcast is issued every time a lock is taken before a full cache flush. mysql-test/r/query_cache_debug.result: * Added test case for bug43758 mysql-test/t/query_cache_debug.test: * Added test case for bug43758 sql/sql_cache.cc: * Replaced calls to wait_while_table_flush_is_in_progress() with calls to try_lock(), lock_and_suspend() and unlock(). * Renamed enumeration Cache_status to Cache_lock_status. * Renamed enumeration items to UNLOCKED, LOCKED_NO_WAIT and LOCKED. If the LOCKED_NO_WAIT lock type is used to lock the query cache, other threads using try_lock() will fail to acquire the lock. This is useful if the query cache is temporary disabled due to a full table flush. sql/sql_cache.h: * Replaced calls to wait_while_table_flush_is_in_progress() with calls to try_lock(), lock_and_suspend() and unlock(). * Renamed enumeration Cache_status to Cache_lock_status. * Renamed enumeration items to UNLOCKED, LOCKED_NO_WAIT and LOCKED. If the LOCKED_NO_WAIT lock type is used to lock the query cache, other threads using try_lock() will fail to acquire the lock. This is useful if the query cache is temporary disabled due to a full table flush. --- mysql-test/r/query_cache_debug.result | 108 +++++++ mysql-test/t/query_cache_debug.test | 144 +++++++++ sql/sql_cache.cc | 412 +++++++++++++------------- sql/sql_cache.h | 22 +- 4 files changed, 472 insertions(+), 214 deletions(-) diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index b03a71d3fec..b83bccef39c 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -71,3 +71,111 @@ DROP TABLE t1,t2; SET GLOBAL concurrent_insert= DEFAULT; SET GLOBAL query_cache_size= DEFAULT; SET GLOBAL query_cache_type= DEFAULT; +# +# Bug43758 Query cache can lock up threads in 'freeing items' state +# +FLUSH STATUS; +SET GLOBAL query_cache_type=DEMAND; +SET GLOBAL query_cache_size= 1024*768; +DROP TABLE IF EXISTS t1,t2,t3,t4,t5; +CREATE TABLE t1 (a VARCHAR(100)); +CREATE TABLE t2 (a VARCHAR(100)); +CREATE TABLE t3 (a VARCHAR(100)); +CREATE TABLE t4 (a VARCHAR(100)); +CREATE TABLE t5 (a VARCHAR(100)); +INSERT INTO t1 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t2 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t3 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t4 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t5 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +=================================== Connection thd1 +** +** Load Query Cache with a result set and one table. +** +SELECT SQL_CACHE * FROM t1; +a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +************************************************************************* +** We want to accomplish the following state: +** - Query cache status: TABLE_FLUSH_IN_PROGRESS +** - THD1: invalidate_table_internal (iterating query blocks) +** - THD2: query_cache_insert (cond_wait) +** - THD3: query_cache_insert (cond_wait) +** - No thread should be holding the structure_guard_mutex. +** +** First step is to place a DELETE-statement on the debug hook just +** before the mutex lock in invalidate_table_internal. +** This will allow new result sets to be written into the QC. +** +SET SESSION debug='+d,wait_in_query_cache_invalidate1'; +SET SESSION debug='+d,wait_in_query_cache_invalidate2'; +DELETE FROM t1 WHERE a like '%a%';; +=================================== Connection default +** Assert that the expect process status is obtained. +** +=================================== Connection thd2 +** On THD2: Insert a result into the cache. This attempt will be blocked +** because of a debug hook placed just before the mutex lock after which +** the first part of the result set is written. +SET SESSION debug='+d,wait_in_query_cache_insert'; +SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3; +=================================== Connection thd3 +** On THD3: Insert another result into the cache and block on the same +** debug hook. +SET SESSION debug='+d,wait_in_query_cache_insert'; +SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; +=================================== Connection default +** Assert that the two SELECT-stmt threads to reach the hook. +** +** +** Signal the DELETE thread, THD1, to continue. It will enter the mutex +** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then +** unlock the mutex before stopping on the next debug hook. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate1' LIMIT 1 INTO @flush_thread_id; +KILL QUERY @flush_thread_id; +** Assert that we reach the next debug hook. +** +** Signal the remaining debug hooks blocking THD2 and THD3. +** The threads will grab the guard mutex enter the wait condition and +** and finally release the mutex. The threads will continue to wait +** until a broadcast signal reaches them causing both threads to +** come alive and check the condition. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +KILL QUERY @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +KILL QUERY @thread_id; +** +** Finally signal the DELETE statement on THD1 one last time. +** The stmt will complete the query cache invalidation and return +** cache status to NO_FLUSH_IN_PROGRESS. On the status change +** One signal will be sent to the thread group waiting for executing +** invalidations and a broadcast signal will be sent to the thread +** group holding result set writers. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2' LIMIT 1 INTO @flush_thread_id; +KILL QUERY @flush_thread_id; +** +************************************************************************* +** No tables should be locked +=================================== Connection thd2 +a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t3; +=================================== Connection thd3 +a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +DELETE FROM t4; +DELETE FROM t5; +=================================== Connection thd1 +** Done. +SET GLOBAL query_cache_size= 0; +# Restore defaults +RESET QUERY CACHE; +FLUSH STATUS; +DROP TABLE t1,t2,t3,t4,t5; +SET GLOBAL query_cache_size= DEFAULT; +SET GLOBAL query_cache_type= DEFAULT; diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index 8cf5e9d4b16..f54e7105807 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -112,3 +112,147 @@ DROP TABLE t1,t2; SET GLOBAL concurrent_insert= DEFAULT; SET GLOBAL query_cache_size= DEFAULT; SET GLOBAL query_cache_type= DEFAULT; + + +--echo # +--echo # Bug43758 Query cache can lock up threads in 'freeing items' state +--echo # +FLUSH STATUS; +SET GLOBAL query_cache_type=DEMAND; +SET GLOBAL query_cache_size= 1024*768; +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4,t5; +--enable_warnings +CREATE TABLE t1 (a VARCHAR(100)); +CREATE TABLE t2 (a VARCHAR(100)); +CREATE TABLE t3 (a VARCHAR(100)); +CREATE TABLE t4 (a VARCHAR(100)); +CREATE TABLE t5 (a VARCHAR(100)); + +INSERT INTO t1 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t2 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t3 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t4 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t5 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); + +connect (thd2, localhost, root, ,test); +connect (thd3, localhost, root, ,test); +connect (thd1, localhost, root, ,test); + +connection thd1; +--echo =================================== Connection thd1 +--echo ** +--echo ** Load Query Cache with a result set and one table. +--echo ** +SELECT SQL_CACHE * FROM t1; +--echo ************************************************************************* +--echo ** We want to accomplish the following state: +--echo ** - Query cache status: TABLE_FLUSH_IN_PROGRESS +--echo ** - THD1: invalidate_table_internal (iterating query blocks) +--echo ** - THD2: query_cache_insert (cond_wait) +--echo ** - THD3: query_cache_insert (cond_wait) +--echo ** - No thread should be holding the structure_guard_mutex. +--echo ** +--echo ** First step is to place a DELETE-statement on the debug hook just +--echo ** before the mutex lock in invalidate_table_internal. +--echo ** This will allow new result sets to be written into the QC. +--echo ** +SET SESSION debug='+d,wait_in_query_cache_invalidate1'; +SET SESSION debug='+d,wait_in_query_cache_invalidate2'; +--send DELETE FROM t1 WHERE a like '%a%'; + +connection default; +--echo =================================== Connection default +--echo ** Assert that the expect process status is obtained. +LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.processlist WHERE state= 'wait_in_query_cache_invalidate1'; +--source include/wait_condition.inc +-- echo ** + +connection thd2; +--echo =================================== Connection thd2 +--echo ** On THD2: Insert a result into the cache. This attempt will be blocked +--echo ** because of a debug hook placed just before the mutex lock after which +--echo ** the first part of the result set is written. +SET SESSION debug='+d,wait_in_query_cache_insert'; +--send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 + +connection thd3; +--echo =================================== Connection thd3 +--echo ** On THD3: Insert another result into the cache and block on the same +--echo ** debug hook. +SET SESSION debug='+d,wait_in_query_cache_insert'; +--send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; + +connection default; +--echo =================================== Connection default +--echo ** Assert that the two SELECT-stmt threads to reach the hook. +LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 2 FROM information_schema.processlist WHERE state='wait_in_query_cache_insert'; +--source include/wait_condition.inc +--echo ** +--echo ** + +--echo ** Signal the DELETE thread, THD1, to continue. It will enter the mutex +--echo ** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then +--echo ** unlock the mutex before stopping on the next debug hook. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate1' LIMIT 1 INTO @flush_thread_id; +KILL QUERY @flush_thread_id; +--echo ** Assert that we reach the next debug hook. +LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2'; +--source include/wait_condition.inc + +--echo ** +--echo ** Signal the remaining debug hooks blocking THD2 and THD3. +--echo ** The threads will grab the guard mutex enter the wait condition and +--echo ** and finally release the mutex. The threads will continue to wait +--echo ** until a broadcast signal reaches them causing both threads to +--echo ** come alive and check the condition. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +KILL QUERY @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +KILL QUERY @thread_id; +--echo ** +--echo ** Finally signal the DELETE statement on THD1 one last time. +--echo ** The stmt will complete the query cache invalidation and return +--echo ** cache status to NO_FLUSH_IN_PROGRESS. On the status change +--echo ** One signal will be sent to the thread group waiting for executing +--echo ** invalidations and a broadcast signal will be sent to the thread +--echo ** group holding result set writers. +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2' LIMIT 1 INTO @flush_thread_id; +KILL QUERY @flush_thread_id; + +--echo ** +--echo ************************************************************************* +--echo ** No tables should be locked +connection thd2; +--echo =================================== Connection thd2 +reap; +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t3; + +connection thd3; +--echo =================================== Connection thd3 +reap; +DELETE FROM t4; +DELETE FROM t5; + +connection thd1; +--echo =================================== Connection thd1 +reap; + +--echo ** Done. + +connection default; +disconnect thd1; +disconnect thd2; +disconnect thd3; +SET GLOBAL query_cache_size= 0; + +connection default; +--echo # Restore defaults +RESET QUERY CACHE; +FLUSH STATUS; +DROP TABLE t1,t2,t3,t4,t5; +SET GLOBAL query_cache_size= DEFAULT; +SET GLOBAL query_cache_type= DEFAULT; +exit; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 32faeae9dcc..df19fd05417 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -352,11 +352,6 @@ TODO list: #define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock 0x%lx",(ulong)(M))); \ if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")); \ else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); } -#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \ - pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));} -#define STRUCT_UNLOCK(M) { \ - DBUG_PRINT("lock", ("%d struct unlock...",__LINE__)); \ - pthread_mutex_unlock(M);DBUG_PRINT("lock", ("struct unlock OK"));} #define BLOCK_LOCK_WR(B) {DBUG_PRINT("lock", ("%d LOCK_WR 0x%lx",\ __LINE__,(ulong)(B))); \ B->query()->lock_writing();} @@ -403,8 +398,6 @@ static void debug_wait_for_kill(const char *info) #define RW_WLOCK(M) rw_wrlock(M) #define RW_RLOCK(M) rw_rdlock(M) #define RW_UNLOCK(M) rw_unlock(M) -#define STRUCT_LOCK(M) pthread_mutex_lock(M) -#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M) #define BLOCK_LOCK_WR(B) B->query()->lock_writing() #define BLOCK_LOCK_RD(B) B->query()->lock_reading() #define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing() @@ -419,6 +412,140 @@ TYPELIB query_cache_type_typelib= }; +/** + Serialize access to the query cache. + If the lock cannot be granted the thread hangs in a conditional wait which + is signalled on each unlock. + + The lock attempt will also fail without wait if lock_and_suspend() is in + effect by another thread. This enables a quick path in execution to skip waits + when the outcome is known. + + @return + @retval FALSE An exclusive lock was taken + @retval TRUE The locking attempt failed +*/ + +bool Query_cache::try_lock(void) +{ + bool interrupt= FALSE; + DBUG_ENTER("Query_cache::try_lock"); + + pthread_mutex_lock(&structure_guard_mutex); + while (1) + { + if (m_cache_lock_status == Query_cache::UNLOCKED) + { + m_cache_lock_status= Query_cache::LOCKED; +#ifndef DBUG_OFF + THD *thd= current_thd; + if (thd) + m_cache_lock_thread_id= thd->thread_id; +#endif + break; + } + else if (m_cache_lock_status == Query_cache::LOCKED_NO_WAIT) + { + /* + If query cache is protected by a LOCKED_NO_WAIT lock this thread + should avoid using the query cache as it is being evicted. + */ + interrupt= TRUE; + break; + } + else + { + DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED); + pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); + } + } + pthread_mutex_unlock(&structure_guard_mutex); + + DBUG_RETURN(interrupt); +} + + +/** + Serialize access to the query cache. + If the lock cannot be granted the thread hangs in a conditional wait which + is signalled on each unlock. + + This method also suspends the query cache so that other threads attempting to + lock the cache with try_lock() will fail directly without waiting. + + It is used by all methods which flushes or destroys the whole cache. + */ + +void Query_cache::lock_and_suspend(void) +{ + DBUG_ENTER("Query_cache::lock_and_suspend"); + + pthread_mutex_lock(&structure_guard_mutex); + while (m_cache_lock_status != Query_cache::UNLOCKED) + pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); + m_cache_lock_status= Query_cache::LOCKED_NO_WAIT; +#ifndef DBUG_OFF + THD *thd= current_thd; + if (thd) + m_cache_lock_thread_id= thd->thread_id; +#endif + /* Wake up everybody, a whole cache flush is starting! */ + pthread_cond_broadcast(&COND_cache_status_changed); + pthread_mutex_unlock(&structure_guard_mutex); + + DBUG_VOID_RETURN; +} + +/** + Serialize access to the query cache. + If the lock cannot be granted the thread hangs in a conditional wait which + is signalled on each unlock. + + It is used by all methods which invalidates one or more tables. + */ + +void Query_cache::lock(void) +{ + DBUG_ENTER("Query_cache::lock"); + + pthread_mutex_lock(&structure_guard_mutex); + while (m_cache_lock_status != Query_cache::UNLOCKED) + pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); + m_cache_lock_status= Query_cache::LOCKED; +#ifndef DBUG_OFF + THD *thd= current_thd; + if (thd) + m_cache_lock_thread_id= thd->thread_id; +#endif + pthread_mutex_unlock(&structure_guard_mutex); + + DBUG_VOID_RETURN; +} + + +/** + Set the query cache to UNLOCKED and signal waiting threads. +*/ + +void Query_cache::unlock(void) +{ + DBUG_ENTER("Query_cache::unlock"); + pthread_mutex_lock(&structure_guard_mutex); +#ifndef DBUG_OFF + THD *thd= current_thd; + if (thd) + DBUG_ASSERT(m_cache_lock_thread_id == thd->thread_id); +#endif + DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED || + m_cache_lock_status == Query_cache::LOCKED_NO_WAIT); + m_cache_lock_status= Query_cache::UNLOCKED; + DBUG_PRINT("Query_cache",("Sending signal")); + pthread_cond_signal(&COND_cache_status_changed); + pthread_mutex_unlock(&structure_guard_mutex); + DBUG_VOID_RETURN; +} + + /** Helper function for determine if a SELECT statement has a SQL_NO_CACHE directive. @@ -713,14 +840,8 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DBUG_EXECUTE_IF("wait_in_query_cache_insert", debug_wait_for_kill("wait_in_query_cache_insert"); ); - STRUCT_LOCK(&query_cache.structure_guard_mutex); - bool interrupt; - query_cache.wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + if (query_cache.try_lock()) DBUG_VOID_RETURN; - } Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query; if (!query_block) @@ -729,7 +850,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) We lost the writer and the currently processed query has been invalidated; there is nothing left to do. */ - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + query_cache.unlock(); DBUG_VOID_RETURN; } @@ -755,7 +876,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) query_cache.free_query(query_block); query_cache.refused++; // append_result_data no success => we need unlock - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + query_cache.unlock(); DBUG_VOID_RETURN; } @@ -777,14 +898,8 @@ void query_cache_abort(NET *net) if (net->query_cache_query == 0) DBUG_VOID_RETURN; - STRUCT_LOCK(&query_cache.structure_guard_mutex); - bool interrupt; - query_cache.wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + if (query_cache.try_lock()) DBUG_VOID_RETURN; - } /* While we were waiting another thread might have changed the status @@ -803,8 +918,7 @@ void query_cache_abort(NET *net) DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); } - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - + query_cache.unlock(); DBUG_VOID_RETURN; } @@ -832,15 +946,8 @@ void query_cache_end_of_result(THD *thd) emb_count_querycache_size(thd)); #endif - STRUCT_LOCK(&query_cache.structure_guard_mutex); - - bool interrupt; - query_cache.wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + if (query_cache.try_lock()) DBUG_VOID_RETURN; - } query_block= ((Query_cache_block*) thd->net.query_cache_query); if (query_block) @@ -869,10 +976,9 @@ void query_cache_end_of_result(THD *thd) */ DBUG_ASSERT(0); query_cache.free_query(query_block); - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + query_cache.unlock(); DBUG_VOID_RETURN; } - last_result_block= header->result()->prev; allign_size= ALIGN_SIZE(last_result_block->used); len= max(query_cache.min_allocation_unit, allign_size); @@ -885,13 +991,11 @@ void query_cache_end_of_result(THD *thd) /* Drop the writer. */ header->writer(0); thd->net.query_cache_query= 0; - BLOCK_UNLOCK_WR(query_block); DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); } - - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + query_cache.unlock(); DBUG_VOID_RETURN; } @@ -950,11 +1054,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg) query_cache_size_arg)); DBUG_ASSERT(initialized); - STRUCT_LOCK(&structure_guard_mutex); - while (is_flushing()) - pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); - m_cache_status= Query_cache::FLUSH_IN_PROGRESS; - STRUCT_UNLOCK(&structure_guard_mutex); + lock_and_suspend(); /* Wait for all readers and writers to exit. When the list of all queries @@ -986,13 +1086,10 @@ ulong Query_cache::resize(ulong query_cache_size_arg) query_cache_size= query_cache_size_arg; new_query_cache_size= init_cache(); - STRUCT_LOCK(&structure_guard_mutex); - m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; - pthread_cond_signal(&COND_cache_status_changed); if (new_query_cache_size) DBUG_EXECUTE("check_querycache",check_integrity(1);); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_RETURN(new_query_cache_size); } @@ -1089,15 +1186,16 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", */ ha_release_temporary_latches(thd); - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size == 0 || is_flushing()) + /* + A table- or a full flush operation can potentially take a long time to + finish. We choose not to wait for them and skip caching statements + instead. + */ + if (try_lock()) + DBUG_VOID_RETURN; + if (query_cache_size == 0) { - /* - A table- or a full flush operation can potentially take a long time to - finish. We choose not to wait for them and skip caching statements - instead. - */ - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } DUMP(this); @@ -1105,7 +1203,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", if (ask_handler_allowance(thd, tables_used)) { refused++; - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } @@ -1153,7 +1251,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", DBUG_PRINT("qcache", ("insertion in query hash")); header->unlock_n_destroy(); free_memory_block(query_block); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); goto end; } if (!register_all_tables(query_block, tables_used, local_tables)) @@ -1163,7 +1261,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", hash_delete(&queries, (uchar *) query_block); header->unlock_n_destroy(); free_memory_block(query_block); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); goto end; } double_linked_list_simple_include(query_block, &queries_blocks); @@ -1173,7 +1271,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", header->writer(net); header->tables_type(tables_type); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); // init_n_lock make query block locked BLOCK_UNLOCK_WR(query_block); @@ -1182,7 +1280,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", { // We have not enough memory to store query => do nothing refused++; - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_PRINT("warning", ("Can't allocate query")); } } @@ -1190,7 +1288,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", { // Another thread is processing the same query => do nothing refused++; - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_PRINT("qcache", ("Another thread process same query")); } } @@ -1282,18 +1380,17 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) } } - STRUCT_LOCK(&structure_guard_mutex); + /* + Try to obtain an exclusive lock on the query cache. If the cache is + disabled or if a full cache flush is in progress, the attempt to + get the lock is aborted. + */ + if (try_lock()) + goto err; if (query_cache_size == 0) goto err_unlock; - if (is_flushing()) - { - /* Return; Query cache is temporarily disabled while we flush. */ - DBUG_PRINT("qcache",("query cache disabled")); - goto err_unlock; - } - /* Check that we haven't forgot to reset the query cache variables; make sure there are no attached query cache writer to this thread. @@ -1427,7 +1524,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", DBUG_PRINT("qcache", ("Temporary table detected: '%s.%s'", table_list.db, table_list.alias)); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); /* We should not store result of this query because it contain temporary tables => assign following variable to make check @@ -1448,7 +1545,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", DBUG_PRINT("qcache", ("probably no SELECT access to %s.%s => return to normal processing", table_list.db, table_list.alias)); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); thd->lex->safe_to_cache_query=0; // Don't try to cache this BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); // Privilege error @@ -1491,7 +1588,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", } move_to_query_list_end(query_block); hits++; - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); /* Send cached result to client @@ -1530,7 +1627,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", DBUG_RETURN(1); // Result sent to client err_unlock: - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); err: DBUG_RETURN(0); // Query was not cached } @@ -1650,47 +1747,6 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length, } -/** - Synchronize the thread with any flushing operations. - - This helper function is called whenever a thread needs to operate on the - query cache structure (example: during invalidation). If a table flush is in - progress this function will wait for it to stop. If a full flush is in - progress, the function will set the interrupt parameter to indicate that the - current operation is redundant and should be interrupted. - - @param[out] interrupt This out-parameter will be set to TRUE if the calling - function is redundant and should be interrupted. - - @return If the interrupt-parameter is TRUE then m_cache_status is set to - NO_FLUSH_IN_PROGRESS. If the interrupt-parameter is FALSE then - m_cache_status is set to FLUSH_IN_PROGRESS. - The structure_guard_mutex will in any case be locked. -*/ - -void Query_cache::wait_while_table_flush_is_in_progress(bool *interrupt) -{ - while (is_flushing()) - { - /* - If there already is a full flush in progress query cache isn't enabled - and additional flushes are redundant; just return instead. - */ - if (m_cache_status == Query_cache::FLUSH_IN_PROGRESS) - { - *interrupt= TRUE; - return; - } - /* - If a table flush is in progress; wait on cache status to change. - */ - if (m_cache_status == Query_cache::TABLE_FLUSH_IN_PROGRESS) - pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); - } - *interrupt= FALSE; -} - - /** Remove all cached queries that uses the given database. */ @@ -1700,14 +1756,11 @@ void Query_cache::invalidate(char *db) bool restart= FALSE; DBUG_ENTER("Query_cache::invalidate (db)"); - STRUCT_LOCK(&structure_guard_mutex); - bool interrupt; - wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&structure_guard_mutex); - return; - } + /* + Lock the query cache and queue all invalidation attempts to avoid + the risk of a race between invalidation, cache inserts and flushes. + */ + lock(); THD *thd= current_thd; @@ -1763,7 +1816,7 @@ void Query_cache::invalidate(char *db) } while (restart); } // end if( tables_blocks ) } - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } @@ -1787,7 +1840,10 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename) void Query_cache::flush() { DBUG_ENTER("Query_cache::flush"); - STRUCT_LOCK(&structure_guard_mutex); + DBUG_EXECUTE_IF("wait_in_query_cache_flush1", + debug_wait_for_kill("wait_in_query_cache_flush1");); + + lock_and_suspend(); if (query_cache_size > 0) { DUMP(this); @@ -1796,7 +1852,7 @@ void Query_cache::flush() } DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } @@ -1815,18 +1871,16 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit) { DBUG_ENTER("Query_cache::pack"); - bool interrupt; - STRUCT_LOCK(&structure_guard_mutex); - wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&structure_guard_mutex); + /* + If the entire qc is being invalidated we can bail out early + instead of waiting for the lock. + */ + if (try_lock()) DBUG_VOID_RETURN; - } if (query_cache_size == 0) { - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } @@ -1836,7 +1890,7 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit) pack_cache(); } while ((++i < iteration_limit) && join_results(join_limit)); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_VOID_RETURN; } @@ -1851,9 +1905,9 @@ void Query_cache::destroy() else { /* Underlying code expects the lock. */ - STRUCT_LOCK(&structure_guard_mutex); + lock_and_suspend(); free_cache(); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); pthread_cond_destroy(&COND_cache_status_changed); pthread_mutex_destroy(&structure_guard_mutex); @@ -1872,7 +1926,7 @@ void Query_cache::init() DBUG_ENTER("Query_cache::init"); pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_cache_status_changed, NULL); - m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; + m_cache_lock_status= Query_cache::UNLOCKED; initialized = 1; DBUG_VOID_RETURN; } @@ -2112,23 +2166,9 @@ void Query_cache::free_cache() void Query_cache::flush_cache() { - /* - If there is flush in progress, wait for it to finish, and then do - our flush. This is necessary because something could be added to - the cache before we acquire the lock again, and some code (like - Query_cache::free_cache()) depends on the fact that after the - flush the cache is empty. - */ - while (is_flushing()) - pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex); - - /* - Setting 'FLUSH_IN_PROGRESS' will prevent other threads from using - the cache while we are in the middle of the flush, and we release - the lock so that other threads won't block. - */ - m_cache_status= Query_cache::FLUSH_IN_PROGRESS; - STRUCT_UNLOCK(&structure_guard_mutex); + + DBUG_EXECUTE_IF("wait_in_query_cache_flush2", + debug_wait_for_kill("wait_in_query_cache_flush2");); my_hash_reset(&queries); while (queries_blocks != 0) @@ -2136,10 +2176,6 @@ void Query_cache::flush_cache() BLOCK_LOCK_WR(queries_blocks); free_query_internal(queries_blocks); } - - STRUCT_LOCK(&structure_guard_mutex); - m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; - pthread_cond_signal(&COND_cache_status_changed); } /* @@ -2319,10 +2355,6 @@ Query_cache::write_block_data(ulong data_len, uchar* data, } -/* - On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be done. -*/ - my_bool Query_cache::append_result_data(Query_cache_block **current_block, ulong data_len, uchar* data, @@ -2342,10 +2374,6 @@ Query_cache::append_result_data(Query_cache_block **current_block, if (*current_block == 0) { DBUG_PRINT("qcache", ("allocated first result data block %lu", data_len)); - /* - STRUCT_UNLOCK(&structure_guard_mutex) Will be done by - write_result_data if success; - */ DBUG_RETURN(write_result_data(current_block, data_len, data, query_block, Query_cache_block::RES_BEG)); } @@ -2376,10 +2404,6 @@ Query_cache::append_result_data(Query_cache_block **current_block, DBUG_PRINT("qcache", ("allocate new block for %lu bytes", data_len-last_block_free_space)); Query_cache_block *new_block = 0; - /* - On success STRUCT_UNLOCK(&structure_guard_mutex) will be done - by the next call - */ success = write_result_data(&new_block, data_len-last_block_free_space, (uchar*)(((uchar*)data)+last_block_free_space), query_block, @@ -2394,7 +2418,7 @@ Query_cache::append_result_data(Query_cache_block **current_block, else { // It is success (nobody can prevent us write data) - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); } // Now finally write data to the last block @@ -2432,7 +2456,7 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, if (success) { // It is success (nobody can prevent us write data) - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + ALIGN_SIZE(sizeof(Query_cache_result))); #ifndef EMBEDDED_LIBRARY @@ -2590,36 +2614,23 @@ void Query_cache::invalidate_table(THD *thd, TABLE *table) void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length) { - bool interrupt; - STRUCT_LOCK(&structure_guard_mutex); - wait_while_table_flush_is_in_progress(&interrupt); - if (interrupt) - { - STRUCT_UNLOCK(&structure_guard_mutex); - return; - } + DBUG_EXECUTE_IF("wait_in_query_cache_invalidate1", + debug_wait_for_kill("wait_in_query_cache_invalidate1"); ); /* - Setting 'TABLE_FLUSH_IN_PROGRESS' will temporarily disable the cache - so that structural changes to cache won't block the entire server. - However, threads requesting to change the query cache will still have - to wait for the flush to finish. + Lock the query cache and queue all invalidation attempts to avoid + the risk of a race between invalidation, cache inserts and flushes. */ - m_cache_status= Query_cache::TABLE_FLUSH_IN_PROGRESS; - STRUCT_UNLOCK(&structure_guard_mutex); + lock(); + + DBUG_EXECUTE_IF("wait_in_query_cache_invalidate2", + debug_wait_for_kill("wait_in_query_cache_invalidate2"); ); + if (query_cache_size > 0) invalidate_table_internal(thd, key, key_length); - STRUCT_LOCK(&structure_guard_mutex); - m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; - - /* - net_real_write might be waiting on a change on the m_cache_status - variable. - */ - pthread_cond_signal(&COND_cache_status_changed); - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); } @@ -2628,7 +2639,7 @@ void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length) The caller must ensure that no other thread is trying to work with the query cache when this function is executed. - @pre structure_guard_mutex is acquired or TABLE_FLUSH_IN_PROGRESS is set. + @pre structure_guard_mutex is acquired or LOCKED is set. */ void @@ -2646,7 +2657,7 @@ Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length) /** Invalidate a linked list of query cache blocks. - Each block tries to aquire a block level lock before + Each block tries to acquire a block level lock before free_query is a called. This function will in turn affect related table- and result-blocks. @@ -4170,10 +4181,7 @@ my_bool Query_cache::check_integrity(bool locked) DBUG_ENTER("check_integrity"); if (!locked) - STRUCT_LOCK(&structure_guard_mutex); - - while (is_flushing()) - pthread_cond_wait(&COND_cache_status_changed,&structure_guard_mutex); + lock_and_suspend(); if (hash_check(&queries)) { @@ -4422,7 +4430,7 @@ my_bool Query_cache::check_integrity(bool locked) } DBUG_ASSERT(result == 0); if (!locked) - STRUCT_UNLOCK(&structure_guard_mutex); + unlock(); DBUG_RETURN(result); } diff --git a/sql/sql_cache.h b/sql/sql_cache.h index f2c33eff614..777ddd39280 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -272,12 +272,12 @@ public: private: +#ifndef DBUG_OFF + my_thread_id m_cache_lock_thread_id; +#endif pthread_cond_t COND_cache_status_changed; - - enum Cache_status { NO_FLUSH_IN_PROGRESS, FLUSH_IN_PROGRESS, - TABLE_FLUSH_IN_PROGRESS }; - - Cache_status m_cache_status; + enum Cache_lock_status { UNLOCKED, LOCKED_NO_WAIT, LOCKED }; + Cache_lock_status m_cache_lock_status; void free_query_internal(Query_cache_block *point); void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length); @@ -380,8 +380,6 @@ protected: Query_cache_block *pprev); my_bool join_results(ulong join_limit); - void wait_while_table_flush_is_in_progress(bool *interrupt); - /* Following function control structure_guard_mutex by themself or don't need structure_guard_mutex @@ -469,11 +467,6 @@ protected: friend void query_cache_end_of_result(THD *thd); friend void query_cache_abort(NET *net); - bool is_flushing(void) - { - return (m_cache_status != Query_cache::NO_FLUSH_IN_PROGRESS); - } - /* The following functions are only used when debugging We don't protect these with ifndef DBUG_OFF to not have to recompile @@ -491,6 +484,11 @@ protected: Query_cache_block_table * point, const char *name); my_bool in_blocks(Query_cache_block * point); + + bool try_lock(void); + void lock(void); + void lock_and_suspend(void); + void unlock(void); }; extern Query_cache query_cache; From 48d911e70834af190a0650e77584f644525af538 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 16 Jun 2009 12:59:57 +0300 Subject: [PATCH 090/188] Addendum to the fix for bug #44821: move partition dependent test to a test file that guarantees the presence of partition code --- mysql-test/r/group_min_max.result | 58 ------------------------------- mysql-test/r/partition.result | 58 +++++++++++++++++++++++++++++++ mysql-test/t/group_min_max.test | 40 --------------------- mysql-test/t/partition.test | 42 +++++++++++++++++++++- 4 files changed, 99 insertions(+), 99 deletions(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 1324b2d93ca..27448d3e949 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2502,61 +2502,3 @@ a MAX(b) 2 1 DROP TABLE t; End of 5.0 tests -CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) -PARTITION BY KEY (a, b) PARTITIONS 3 -; -INSERT INTO t1 VALUES -(17, 1, -8), -(3, 1, -7), -(23, 1, -6), -(22, 1, -5), -(11, 1, -4), -(21, 1, -3), -(19, 1, -2), -(30, 1, -1), -(20, 1, 1), -(16, 1, 2), -(18, 1, 3), -(9, 1, 4), -(15, 1, 5), -(28, 1, 6), -(29, 1, 7), -(25, 1, 8), -(10, 1, 9), -(13, 1, 10), -(27, 1, 11), -(24, 1, 12), -(12, 1, 13), -(26, 1, 14), -(14, 1, 15) -; -SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; -b c -1 -8 -1 -7 -1 -6 -1 -5 -1 -4 -1 -3 -1 -2 -1 -1 -1 1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -EXPLAIN -SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range bc bc 10 NULL 7 Using where; Using index for group-by -DROP TABLE t1; diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index f69ba522a9c..20853da1af0 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1924,5 +1924,63 @@ EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a>=200; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p2,p3 ALL NULL NULL NULL NULL 3 Using where DROP TABLE t1; +CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) +PARTITION BY KEY (a, b) PARTITIONS 3 +; +INSERT INTO t1 VALUES +(17, 1, -8), +(3, 1, -7), +(23, 1, -6), +(22, 1, -5), +(11, 1, -4), +(21, 1, -3), +(19, 1, -2), +(30, 1, -1), +(20, 1, 1), +(16, 1, 2), +(18, 1, 3), +(9, 1, 4), +(15, 1, 5), +(28, 1, 6), +(29, 1, 7), +(25, 1, 8), +(10, 1, 9), +(13, 1, 10), +(27, 1, 11), +(24, 1, 12), +(12, 1, 13), +(26, 1, 14), +(14, 1, 15) +; +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; +b c +1 -8 +1 -7 +1 -6 +1 -5 +1 -4 +1 -3 +1 -2 +1 -1 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +1 8 +1 9 +1 10 +1 11 +1 12 +1 13 +1 14 +1 15 +EXPLAIN +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range bc bc 10 NULL 7 Using where; Using index for group-by +DROP TABLE t1; End of 5.1 tests SET @@global.general_log= @old_general_log; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 42a37294f1b..981be3efece 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -1018,43 +1018,3 @@ DROP TABLE t; --echo End of 5.0 tests -# -# Bug#44821: select distinct on partitioned table returns wrong results -# -CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) -PARTITION BY KEY (a, b) PARTITIONS 3 -; - -INSERT INTO t1 VALUES -(17, 1, -8), -(3, 1, -7), -(23, 1, -6), -(22, 1, -5), -(11, 1, -4), -(21, 1, -3), -(19, 1, -2), -(30, 1, -1), - -(20, 1, 1), -(16, 1, 2), -(18, 1, 3), -(9, 1, 4), -(15, 1, 5), -(28, 1, 6), -(29, 1, 7), -(25, 1, 8), -(10, 1, 9), -(13, 1, 10), -(27, 1, 11), -(24, 1, 12), -(12, 1, 13), -(26, 1, 14), -(14, 1, 15) -; - -SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; - -EXPLAIN -SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; - -DROP TABLE t1; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index ce89609de39..8535e1bc5c2 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1935,7 +1935,47 @@ INSERT INTO t1 VALUES (10), (100), (200), (300), (400); EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a>=200; DROP TABLE t1; +# +# Bug#44821: select distinct on partitioned table returns wrong results +# +CREATE TABLE t1 ( a INT, b INT, c INT, KEY bc(b, c) ) +PARTITION BY KEY (a, b) PARTITIONS 3 +; + +INSERT INTO t1 VALUES +(17, 1, -8), +(3, 1, -7), +(23, 1, -6), +(22, 1, -5), +(11, 1, -4), +(21, 1, -3), +(19, 1, -2), +(30, 1, -1), + +(20, 1, 1), +(16, 1, 2), +(18, 1, 3), +(9, 1, 4), +(15, 1, 5), +(28, 1, 6), +(29, 1, 7), +(25, 1, 8), +(10, 1, 9), +(13, 1, 10), +(27, 1, 11), +(24, 1, 12), +(12, 1, 13), +(26, 1, 14), +(14, 1, 15) +; + +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; + +EXPLAIN +SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; + +DROP TABLE t1; + --echo End of 5.1 tests - SET @@global.general_log= @old_general_log; From a0fcfc0c122039352b4cc3b4542521ecc6882b02 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 16 Jun 2009 14:00:04 +0200 Subject: [PATCH 091/188] Raise version number after cloning 5.1.36 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index d323ce9f726..6867ea8bd92 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.36) +AM_INIT_AUTOMAKE(mysql, 5.1.37) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From aa8677bc32fd80ee9ab08717369d23a4ef011717 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 16 Jun 2009 16:36:15 +0200 Subject: [PATCH 092/188] Bug#45168: assertion with convert() and empty set value The assertion in String::copy was added in order to avoid valgrind errors when the destination was the same as the source. Eased restriction to allow for the case when str == NULL. mysql-test/r/func_set.result: Bug#45168: Test result mysql-test/t/func_set.test: Bug#45168: Test case sql/item_strfunc.cc: Bug#45168: Code cleanup and grammar correction in comment sql/sql_string.cc: Bug#45168: Fix --- mysql-test/r/func_set.result | 13 +++++++++++++ mysql-test/t/func_set.test | 13 +++++++++++++ sql/item_strfunc.cc | 5 ++--- sql/sql_string.cc | 15 ++++++++++++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index ecdc35ac4cd..14ebc8203ec 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -146,3 +146,16 @@ NULL 0 0 drop table t1; +CREATE TABLE t1( a SET('a', 'b', 'c') ); +CREATE TABLE t2( a SET('a', 'b', 'c') ); +INSERT INTO t1 VALUES ('d'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +INSERT INTO t2 VALUES (''); +SELECT CONVERT( a USING latin1 ) FROM t1; +CONVERT( a USING latin1 ) + +SELECT CONVERT( a USING latin1 ) FROM t2; +CONVERT( a USING latin1 ) + +DROP TABLE t1, t2; diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index 5f37cd2a13e..294efa8caf1 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -84,3 +84,16 @@ engine=myisam default charset=latin1; insert into t1 values (''),(null),(null),(''),(''),(''); select find_in_set(f1,f1) as a from t1,(select find_in_set(f1,f1) as b from t1) a; drop table t1; +# +# Bug#45168: assertion with convert() and empty set value +# +CREATE TABLE t1( a SET('a', 'b', 'c') ); +CREATE TABLE t2( a SET('a', 'b', 'c') ); + +INSERT INTO t1 VALUES ('d'); +INSERT INTO t2 VALUES (''); + +SELECT CONVERT( a USING latin1 ) FROM t1; +SELECT CONVERT( a USING latin1 ) FROM t2; + +DROP TABLE t1, t2; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2d580e4d9a8..be94f19f597 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2710,13 +2710,12 @@ String *Item_func_conv_charset::val_str(String *str) return null_value ? 0 : &str_value; /* Here we don't pass 'str' as a parameter to args[0]->val_str() - as 'str' may points to 'str_value' (e.g. see Item::save_in_field()), + as 'str' may point to 'str_value' (e.g. see Item::save_in_field()), which we use below to convert string. Use argument's 'str_value' instead. */ - String *arg= args[0]->val_str(&args[0]->str_value);; + String *arg= args[0]->val_str(&args[0]->str_value); uint dummy_errors; - arg= args[0]->val_str(&args[0]->str_value); if (!arg) { null_value=1; diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 61731f3b984..7759985ba85 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -322,14 +322,23 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, return copy_aligned(str, arg_length, offset, cs); } - /* Copy with charset conversion */ + +/** + Copies the character data into this String, with optional character set + conversion. + + @return + FALSE ok + TRUE Could not allocate result buffer + +*/ bool String::copy(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors) { uint32 offset; - - DBUG_ASSERT(str != Ptr); + + DBUG_ASSERT(!str || str != Ptr); if (!needs_conversion(arg_length, from_cs, to_cs, &offset)) { From 4cb4593bdea737037c4d01bd3fbd7faa2bde5d22 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Tue, 16 Jun 2009 16:04:30 +0100 Subject: [PATCH 093/188] BUG#45511 rpl.rpl_binlog_corruption fails with warning messages in Valgrind This is a backport of BUG#43076. --- sql/rpl_reporting.cc | 7 +++++++ sql/rpl_reporting.h | 10 ++++++++++ sql/slave.cc | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/sql/rpl_reporting.cc b/sql/rpl_reporting.cc index 28f257790c7..a09140de3c4 100644 --- a/sql/rpl_reporting.cc +++ b/sql/rpl_reporting.cc @@ -13,6 +13,7 @@ Slave_reporting_capability::report(loglevel level, int err_code, va_list args; va_start(args, msg); + pthread_mutex_lock(&err_lock); switch (level) { case ERROR_LEVEL: @@ -38,6 +39,7 @@ Slave_reporting_capability::report(loglevel level, int err_code, my_vsnprintf(pbuff, pbuffsize, msg, args); + pthread_mutex_unlock(&err_lock); va_end(args); /* If the msg string ends with '.', do not add a ',' it would be ugly */ @@ -46,3 +48,8 @@ Slave_reporting_capability::report(loglevel level, int err_code, (pbuff[0] && *(strend(pbuff)-1) == '.') ? "" : ",", err_code); } + +Slave_reporting_capability::~Slave_reporting_capability() +{ + pthread_mutex_destroy(&err_lock); +} diff --git a/sql/rpl_reporting.h b/sql/rpl_reporting.h index 2e3fa3cea83..ce33407e516 100644 --- a/sql/rpl_reporting.h +++ b/sql/rpl_reporting.h @@ -16,6 +16,8 @@ class Slave_reporting_capability { public: + /** lock used to synchronize m_last_error on 'SHOW SLAVE STATUS' **/ + mutable pthread_mutex_t err_lock; /** Constructor. @@ -24,6 +26,7 @@ public: Slave_reporting_capability(char const *thread_name) : m_thread_name(thread_name) { + pthread_mutex_init(&err_lock, MY_MUTEX_INIT_FAST); } /** @@ -44,7 +47,9 @@ public: STATUS. */ void clear_error() { + pthread_mutex_lock(&err_lock); m_last_error.clear(); + pthread_mutex_unlock(&err_lock); } /** @@ -72,6 +77,7 @@ public: Error const& last_error() const { return m_last_error; } + virtual ~Slave_reporting_capability()= 0; private: /** Last error produced by the I/O or SQL thread respectively. @@ -79,6 +85,10 @@ private: mutable Error m_last_error; char const *const m_thread_name; + + // not implemented + Slave_reporting_capability(const Slave_reporting_capability& rhs); + Slave_reporting_capability& operator=(const Slave_reporting_capability& rhs); }; #endif // RPL_REPORTING_H diff --git a/sql/slave.cc b/sql/slave.cc index ac371baf522..043b0e3fed5 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1493,6 +1493,8 @@ bool show_master_info(THD* thd, Master_info* mi) pthread_mutex_lock(&mi->data_lock); pthread_mutex_lock(&mi->rli.data_lock); + pthread_mutex_lock(&mi->err_lock); + pthread_mutex_lock(&mi->rli.err_lock); protocol->store(mi->host, &my_charset_bin); protocol->store(mi->user, &my_charset_bin); protocol->store((uint32) mi->port); @@ -1592,6 +1594,8 @@ bool show_master_info(THD* thd, Master_info* mi) // Last_SQL_Error protocol->store(mi->rli.last_error().message, &my_charset_bin); + pthread_mutex_unlock(&mi->rli.err_lock); + pthread_mutex_unlock(&mi->err_lock); pthread_mutex_unlock(&mi->rli.data_lock); pthread_mutex_unlock(&mi->data_lock); From 3b0e6e41098557dab9fe7ca5c59f2863fd671b94 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 17 Jun 2009 15:54:01 +0200 Subject: [PATCH 094/188] Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 Compiling MySQL with gcc 4.3.2 and later produces a number of warnings, many of which are new with the recent compiler versions. This bug will be resolved in more than one patch to limit the size of changesets. This is the second patch, fixing more of the warnings. --- sql/examples/ha_tina.h | 2 +- sql/field_conv.cc | 4 ++-- sql/ha_federated.cc | 39 +++++++++++++++---------------- sql/item.cc | 2 -- sql/spatial.h | 12 +++++----- sql/sql_acl.cc | 34 +++++++++++++-------------- sql/sql_analyse.cc | 2 +- sql/sql_base.cc | 38 +++++++++++++++--------------- sql/sql_delete.cc | 2 +- sql/sql_help.cc | 2 +- sql/sql_insert.cc | 9 ++++---- sql/sql_lex.cc | 12 +++++----- sql/sql_load.cc | 8 +++---- sql/sql_parse.cc | 28 +++++++++++------------ sql/sql_prepare.cc | 4 ++-- sql/sql_select.cc | 52 ++++++++++++++++++++++-------------------- sql/sql_show.cc | 8 +++---- sql/sql_table.cc | 10 ++++---- sql/sql_trigger.cc | 2 +- sql/sql_update.cc | 2 +- sql/sql_view.cc | 6 ++--- sql/sql_yacc.yy | 6 ++--- sql/table.cc | 8 +++---- sql/table.h | 2 +- sql/time.cc | 8 +++---- sql/tztime.cc | 4 ++-- sql/uniques.cc | 4 ++-- 27 files changed, 154 insertions(+), 156 deletions(-) diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h index 98cba8bf4cd..a00e8887c7e 100644 --- a/sql/examples/ha_tina.h +++ b/sql/examples/ha_tina.h @@ -29,7 +29,7 @@ typedef struct st_tina_share { THR_LOCK lock; } TINA_SHARE; -typedef struct tina_set { +struct tina_set { off_t begin; off_t end; }; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 7beb41b8ff1..630372dfac1 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -761,8 +761,8 @@ int field_conv(Field *to,Field *from) to->table->s->db_low_byte_first == from->table->s->db_low_byte_first && (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || - to->type() != FIELD_TYPE_DATE && - to->type() != FIELD_TYPE_DATETIME) && + (to->type() != FIELD_TYPE_DATE && + to->type() != FIELD_TYPE_DATETIME)) && (from->real_type() != MYSQL_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes)) diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 6944dc5a030..9c2f73912ea 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -2596,30 +2596,27 @@ int ha_federated::info(uint flag) if (!(row= mysql_fetch_row(result))) goto error; - if (flag & HA_STATUS_VARIABLE | HA_STATUS_CONST) - { - /* - deleted is set in ha_federated::info - */ - /* - need to figure out what this means as far as federated is concerned, - since we don't have a "file" + /* + deleted is set in ha_federated::info + */ + /* + need to figure out what this means as far as federated is concerned, + since we don't have a "file" - data_file_length = ? - index_file_length = ? - delete_length = ? - */ - if (row[4] != NULL) - records= (ha_rows) my_strtoll10(row[4], (char**) 0, &error); + data_file_length = ? + index_file_length = ? + delete_length = ? + */ + if (row[4] != NULL) + records= (ha_rows) my_strtoll10(row[4], (char**) 0, &error); - mean_rec_length= table->s->reclength; - data_file_length= records * mean_rec_length; + mean_rec_length= table->s->reclength; + data_file_length= records * mean_rec_length; - if (row[12] != NULL) - update_time= (time_t) my_strtoll10(row[12], (char**) 0, &error); - if (row[13] != NULL) - check_time= (time_t) my_strtoll10(row[13], (char**) 0, &error); - } + if (row[12] != NULL) + update_time= (time_t) my_strtoll10(row[12], (char**) 0, &error); + if (row[13] != NULL) + check_time= (time_t) my_strtoll10(row[13], (char**) 0, &error); /* size of IO operations (This is based on a good guess, no high science diff --git a/sql/item.cc b/sql/item.cc index c20089694db..1e379527fb7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1477,8 +1477,6 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) { set(dt); } - else - ; // Do nothing } else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && left_is_superset(this, &dt)) diff --git a/sql/spatial.h b/sql/spatial.h index 837ae153310..07aba4f925f 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -116,12 +116,12 @@ struct MBR int touches(const MBR *mbr) { /* The following should be safe, even if we compare doubles */ - return ((((mbr->xmin == xmax) || (mbr->xmax == xmin)) && - ((mbr->ymin >= ymin) && (mbr->ymin <= ymax) || - (mbr->ymax >= ymin) && (mbr->ymax <= ymax))) || - (((mbr->ymin == ymax) || (mbr->ymax == ymin)) && - ((mbr->xmin >= xmin) && (mbr->xmin <= xmax) || - (mbr->xmax >= xmin) && (mbr->xmax <= xmax)))); + return ((mbr->xmin == xmax || mbr->xmax == xmin) && + ((mbr->ymin >= ymin && mbr->ymin <= ymax) || + (mbr->ymax >= ymin && mbr->ymax <= ymax))) || + ((mbr->ymin == ymax || mbr->ymax == ymin) && + ((mbr->xmin >= xmin && mbr->xmin <= xmax) || + (mbr->xmax >= xmin && mbr->xmax <= xmax))); } int within(const MBR *mbr) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d5b79eaca4e..34d7e773ca2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1046,12 +1046,12 @@ static void acl_update_user(const char *user, const char *host, for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); - if (!acl_user->user && !user[0] || - acl_user->user && !strcmp(user,acl_user->user)) + if ((!acl_user->user && !user[0]) || + (acl_user->user && !strcmp(user,acl_user->user))) { - if (!acl_user->host.hostname && !host[0] || - acl_user->host.hostname && - !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) + if ((!acl_user->host.hostname && !host[0]) || + (acl_user->host.hostname && + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname))) { acl_user->access=privileges; if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) @@ -1129,16 +1129,16 @@ static void acl_update_db(const char *user, const char *host, const char *db, for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); - if (!acl_db->user && !user[0] || - acl_db->user && - !strcmp(user,acl_db->user)) + if ((!acl_db->user && !user[0]) || + (acl_db->user && + !strcmp(user,acl_db->user))) { - if (!acl_db->host.hostname && !host[0] || - acl_db->host.hostname && - !strcmp(host, acl_db->host.hostname)) + if ((!acl_db->host.hostname && !host[0]) || + (acl_db->host.hostname && + !strcmp(host, acl_db->host.hostname))) { - if (!acl_db->db && !db[0] || - acl_db->db && !strcmp(db,acl_db->db)) + if ((!acl_db->db && !db[0]) || + (acl_db->db && !strcmp(db,acl_db->db))) { if (privileges) acl_db->access=privileges; @@ -1345,8 +1345,8 @@ bool acl_check_host(const char *host, const char *ip) return 0; VOID(pthread_mutex_lock(&acl_cache->lock)); - if (host && hash_search(&acl_check_hosts,(byte*) host,(uint) strlen(host)) || - ip && hash_search(&acl_check_hosts,(byte*) ip,(uint) strlen(ip))) + if ((host && hash_search(&acl_check_hosts,(byte*) host,(uint) strlen(host))) || + (ip && hash_search(&acl_check_hosts,(byte*) ip,(uint) strlen(ip)))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); return 0; // Found host @@ -1564,8 +1564,8 @@ find_acl_user(const char *host, const char *user, my_bool exact) host, acl_user->host.hostname ? acl_user->host.hostname : "")); - if (!acl_user->user && !user[0] || - acl_user->user && !strcmp(user,acl_user->user)) + if ((!acl_user->user && !user[0]) || + (acl_user->user && !strcmp(user,acl_user->user))) { if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 4b3264069b5..7de395d8d91 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -247,7 +247,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) } DBUG_RETURN(0); } - for (str++; *(end - 1) == '0'; end--); // jump over zeros at the end + for (str++; *(end - 1) == '0'; end--) ; // jump over zeros at the end if (str == end) // number was something like '123.000' { char *endpos= (char*) str; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 854e603d21a..0f86a3dd311 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1556,7 +1556,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, it can not be cloned. Emit an error for an unsupported behaviour. */ if (table->query_id == thd->query_id || - thd->prelocked_mode && table->query_id) + (thd->prelocked_mode && table->query_id)) { my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); DBUG_RETURN(0); @@ -1610,8 +1610,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, distance > 0 - we have lock mode higher then we require distance == 0 - we have lock mode exactly which we need */ - if (best_distance < 0 && distance > best_distance || - distance >= 0 && distance < best_distance) + if ((best_distance < 0 && distance > best_distance) || + (distance >= 0 && distance < best_distance)) { best_distance= distance; best_table= table; @@ -2298,8 +2298,8 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) search= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, &state)) { - if (search->locked_by_name && wait_for_name_lock || - search->is_name_opened() && search->needs_reopen_or_name_lock()) + if ((search->locked_by_name && wait_for_name_lock) || + (search->is_name_opened() && search->needs_reopen_or_name_lock())) return 1; // Table is used } } while ((table=table->next)); @@ -5142,7 +5142,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, thd->lex->current_select->cur_pos_in_select_list= 0; while ((item= it++)) { - if (!item->fixed && item->fix_fields(thd, it.ref()) || + if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1)) { thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; @@ -5476,16 +5476,16 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, DBUG_ASSERT(tables->is_leaf_for_name_resolution()); - if (table_name && my_strcasecmp(table_alias_charset, table_name, - tables->alias) || + if ((table_name && my_strcasecmp(table_alias_charset, table_name, + tables->alias)) || (db_name && strcmp(tables->db,db_name))) continue; #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Ensure that we have access rights to all fields to be inserted. */ - if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL) || - tables->view && (tables->grant.privilege & SELECT_ACL))) && - !any_privileges) + if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL)) || + (tables->view && (tables->grant.privilege & SELECT_ACL))) && + !any_privileges) { field_iterator.set(tables); if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator)) @@ -5539,7 +5539,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, */ if (any_privileges) { - DBUG_ASSERT(tables->field_translation == NULL && table || + DBUG_ASSERT((tables->field_translation == NULL && table) || tables->is_natural_join); DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *fld= (Item_field*) item; @@ -5684,7 +5684,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, if (*conds) { thd->where="where clause"; - if (!(*conds)->fixed && (*conds)->fix_fields(thd, conds) || + if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) || (*conds)->check_cols(1)) goto err_no_arena; } @@ -5704,8 +5704,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, { /* Make a join an a expression */ thd->where="on clause"; - if (!embedded->on_expr->fixed && - embedded->on_expr->fix_fields(thd, &embedded->on_expr) || + if ((!embedded->on_expr->fixed && + embedded->on_expr->fix_fields(thd, &embedded->on_expr)) || embedded->on_expr->check_cols(1)) goto err_no_arena; select_lex->cond_count++; @@ -5860,8 +5860,8 @@ fill_record_n_invoke_before_triggers(THD *thd, List &fields, enum trg_event_type event) { return (fill_record(thd, fields, values, ignore_errors) || - triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE)); + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); } @@ -5955,8 +5955,8 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr, enum trg_event_type event) { return (fill_record(thd, ptr, values, ignore_errors) || - triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE)); + (triggers && triggers->process_triggers(thd, event, + TRG_ACTION_BEFORE, TRUE))); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 79fc4872f05..30b14209a7c 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -711,7 +711,7 @@ void multi_delete::send_error(uint errcode,const char *err) /* the error was handled or nothing deleted and no side effects return */ if (error_handled || - !thd->transaction.stmt.modified_non_trans_table && !deleted) + (!thd->transaction.stmt.modified_non_trans_table && !deleted)) DBUG_VOID_RETURN; /* Something already deleted so we have to invalidate cache */ diff --git a/sql/sql_help.cc b/sql/sql_help.cc index e369a72fa9f..93610ea22b7 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -522,7 +522,7 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol, String **end= pointers + names->elements; List_iterator it(*names); - for (pos= pointers; pos!=end; (*pos++= it++)); + for (pos= pointers; pos!=end; (*pos++= it++)) ; my_qsort(pointers,names->elements,sizeof(String*),string_ptr_cmp); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 6d63a0907df..28b8bcd320d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -413,7 +413,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, bool is_multi_insert) { if (duplic == DUP_UPDATE || - duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) + (duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT)) { *lock_type= TL_WRITE_DEFAULT; return; @@ -887,7 +887,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (changed) query_cache_invalidate3(thd, table_list, 1); } - if (changed && error <= 0 || thd->transaction.stmt.modified_non_trans_table + if ((changed && error <= 0) + || thd->transaction.stmt.modified_non_trans_table || was_insert_delayed) { if (mysql_bin_log.is_open()) @@ -3016,8 +3017,8 @@ bool select_insert::send_eof() We must invalidate the table in the query cache before binlog writing and ha_autocommit_or_rollback */ - - if (changed= (info.copied || info.deleted || info.updated)) + changed= (info.copied || info.deleted || info.updated); + if (changed) { query_cache_invalidate3(thd, table, 1); if (thd->transaction.stmt.modified_non_trans_table) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 436f41dd209..061a20679e7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -661,7 +661,7 @@ int MYSQLlex(void *arg, void *yythd) else #endif { - for (result_state= c; ident_map[c= yyGet()]; result_state|= c); + for (result_state= c; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; } @@ -673,7 +673,7 @@ int MYSQLlex(void *arg, void *yythd) If we find a space then this can't be an identifier. We notice this below by checking start != lex->ptr. */ - for (; state_map[c] == MY_LEX_SKIP ; c= yyGet()); + for (; state_map[c] == MY_LEX_SKIP ; c= yyGet()) ; } if (start == lip->ptr && c == '.' && ident_map[yyPeek()]) lip->next_state=MY_LEX_IDENT_SEP; @@ -782,7 +782,7 @@ int MYSQLlex(void *arg, void *yythd) else #endif { - for (result_state=0; ident_map[c= yyGet()]; result_state|= c); + for (result_state=0; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; } @@ -872,7 +872,7 @@ int MYSQLlex(void *arg, void *yythd) case MY_LEX_BIN_NUMBER: // Found b'bin-string' yyGet(); // Skip ' - while ((c= yyGet()) == '0' || c == '1'); + while ((c= yyGet()) == '0' || c == '1') ; length= (uint) (lip->ptr - lip->tok_start); // Length of bin-num + 3 if (c != '\'') return(ABORT_SYM); // Illegal hex constant @@ -1080,7 +1080,7 @@ int MYSQLlex(void *arg, void *yythd) [(global | local | session) .]variable_name */ - for (result_state= 0; ident_map[c= yyGet()]; result_state|= c); + for (result_state= 0; ident_map[c= yyGet()]; result_state|= c) ; /* If there were non-ASCII characters, mark that we must convert */ result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; @@ -1670,7 +1670,7 @@ void st_select_lex::print_limit(THD *thd, String *str) item->substype() == Item_subselect::ALL_SUBS)) { DBUG_ASSERT(!item->fixed || - select_limit->val_int() == LL(1) && offset_limit == 0); + (select_limit->val_int() == LL(1) && offset_limit == 0)); return; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 5b9f8ea441d..83af6d477db 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -723,9 +723,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, real_item= item->real_item(); - if (!read_info.enclosed && + if ((!read_info.enclosed && (enclosed_length && length == 4 && - !memcmp(pos, STRING_WITH_LEN("NULL"))) || + !memcmp(pos, STRING_WITH_LEN("NULL")))) || (length == 1 && read_info.found_null)) { @@ -1132,8 +1132,8 @@ int READ_INFO::read_field() } // End of enclosed field if followed by field_term or line_term if (chr == my_b_EOF || - chr == line_term_char && terminator(line_term_ptr, - line_term_length)) + (chr == line_term_char && terminator(line_term_ptr, + line_term_length))) { // Maybe unexpected linefeed enclosed=1; found_end_of_line=1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 507805ec0c4..79b9b479a0c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1238,7 +1238,7 @@ pthread_handler_t handle_one_connection(void *arg) decrease_user_connections(thd->user_connect); if (thd->killed || - net->vio && net->error && net->report_error) + (net->vio && net->error && net->report_error)) { statistic_increment(aborted_threads, &LOCK_status); } @@ -2366,11 +2366,11 @@ void log_slow_statement(THD *thd) if ((thd->start_time > thd->time_after_lock && (ulong) (thd->start_time - thd->time_after_lock) > thd->variables.long_query_time) || - (thd->server_status & + ((thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && opt_log_queries_not_using_indexes && /* == SQLCOM_END unless this is a SHOW command */ - thd->lex->orig_sql_command == SQLCOM_END) + thd->lex->orig_sql_command == SQLCOM_END)) { thd_proc_info(thd, "logging slow query"); thd->status_var.long_query_count++; @@ -2676,8 +2676,8 @@ mysql_execute_command(THD *thd) variables, but for now this is probably good enough. Don't reset warnings when executing a stored routine. */ - if ((all_tables || &lex->select_lex != lex->all_selects_list || - lex->sroutines.records) && !thd->spcont || + if (((all_tables || &lex->select_lex != lex->all_selects_list || + lex->sroutines.records) && !thd->spcont) || lex->time_zone_tables_used) mysql_reset_errors(thd, 0); @@ -5641,7 +5641,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (schema_db) { - if (!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL) || + if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) || (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) { if (!no_errors) @@ -5678,7 +5678,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(FALSE); } if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) || - ! db && dont_check_global_grants) + (! db && dont_check_global_grants)) { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) @@ -6029,10 +6029,10 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) { if (access & want_access) { - if (!check_access(thd, access, table->db, + if ((!check_access(thd, access, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) && - !grant_option || !check_grant(thd, access, table, 0, 1, 1)) + !grant_option) || !check_grant(thd, access, table, 0, 1, 1)) DBUG_RETURN(0); } } @@ -7710,12 +7710,12 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) else if ((check_access(thd, UPDATE_ACL, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) || - grant_option && - check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && + (grant_option && + check_grant(thd, UPDATE_ACL, table, 0, 1, 1))) && (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) + (grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)))) DBUG_RETURN(TRUE); table->table_in_first_from_clause= 1; @@ -7735,7 +7735,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)) + (grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) DBUG_RETURN(TRUE); } } @@ -7961,7 +7961,7 @@ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table) return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); + (grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0)); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a20f61436a7..d14f14b526e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1367,7 +1367,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, THD *thd= stmt->thd; set_var_base *var; - if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || + if ((tables && check_table_access(thd, SELECT_ACL, tables, 0)) || open_and_lock_tables(thd, tables)) goto error; @@ -2714,7 +2714,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg) void Prepared_statement::setup_set_params() { /* Setup binary logging */ - if (mysql_bin_log.is_open() && is_update_query(lex->sql_command) || + if ((mysql_bin_log.is_open() && is_update_query(lex->sql_command)) || mysql_log.is_open() || mysql_slow_log.is_open()) { set_params_from_vars= insert_params_from_vars_with_log; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0417460fe4f..672ebaf9259 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1305,7 +1305,7 @@ JOIN::optimize() join_tab[const_tables].type != JT_ALL && join_tab[const_tables].type != JT_FT && join_tab[const_tables].type != JT_REF_OR_NULL && - (order && simple_order || group_list && simple_group)) + ((order && simple_order) || (group_list && simple_group))) { if (add_ref_to_table_cond(thd,&join_tab[const_tables])) { DBUG_RETURN(1); @@ -1809,9 +1809,9 @@ JOIN::exec() like SEC_TO_TIME(SUM(...)). */ - if (curr_join->group_list && (!test_if_subpart(curr_join->group_list, + if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list, curr_join->order) || - curr_join->select_distinct) || + curr_join->select_distinct)) || (curr_join->select_distinct && curr_join->tmp_table_param.using_indirect_summary_function)) { /* Must copy to another table */ @@ -2269,9 +2269,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, } else { - if (err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, proc_param, - select_lex, unit)) + err= join->prepare(rref_pointer_array, tables, wild_num, + conds, og_num, order, group, having, proc_param, + select_lex, unit); + if (err) { goto err; } @@ -2286,9 +2287,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, DBUG_RETURN(TRUE); thd_proc_info(thd, "init"); thd->used_tables=0; // Updated by setup_fields - if (err= join->prepare(rref_pointer_array, tables, wild_num, - conds, og_num, order, group, having, proc_param, - select_lex, unit)) + err= join->prepare(rref_pointer_array, tables, wild_num, + conds, og_num, order, group, having, proc_param, + select_lex, unit); + if (err) { goto err; } @@ -3744,7 +3746,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, if (use->key == prev->key && use->table == prev->table) { if (prev->keypart+1 < use->keypart || - prev->keypart == use->keypart && found_eq_constant) + (prev->keypart == use->keypart && found_eq_constant)) continue; /* remove */ } else if (use->keypart != 0) // First found must be 0 @@ -4984,8 +4986,8 @@ best_extension_by_limited_search(JOIN *join, { if (best_record_count > current_record_count || best_read_time > current_read_time || - idx == join->const_tables && // 's' is the first table in the QEP - s->table == join->sort_by_table) + (idx == join->const_tables && // 's' is the first table in the QEP + s->table == join->sort_by_table)) { if (best_record_count >= current_record_count && best_read_time >= current_read_time && @@ -5110,7 +5112,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, double current_read_time=read_time+best; if (best_record_count > current_record_count || best_read_time > current_read_time || - idx == join->const_tables && s->table == join->sort_by_table) + (idx == join->const_tables && s->table == join->sort_by_table)) { if (best_record_count >= current_record_count && best_read_time >= current_read_time && @@ -5955,8 +5957,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) the index if we are using limit and this is the first table */ - if (cond && - (!tab->keys.is_subset(tab->const_keys) && i > 0) || + if ((cond && + (!tab->keys.is_subset(tab->const_keys) && i > 0)) || (!tab->const_keys.is_clear_all() && i == join->const_tables && join->unit->select_limit_cnt < join->best_positions[i].records_read && @@ -7081,7 +7083,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, left_item_equal->merge(right_item_equal); /* Remove the merged multiple equality from the list */ List_iterator li(cond_equal->current_level); - while ((li++) != right_item_equal); + while ((li++) != right_item_equal) ; li.remove(); } } @@ -9663,9 +9665,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, reclength=1; // Dummy select /* Use packed rows if there is blobs or a lot of space to gain */ if (blob_count || - string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && + (string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || - string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)) + string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS))) use_packed_rows= 1; table->s->fields= field_count; @@ -10329,8 +10331,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, /* copy row that filled HEAP table */ if ((write_err=new_table.file->write_row(table->record[0]))) { - if (write_err != HA_ERR_FOUND_DUPP_KEY && - write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error) + if ((write_err != HA_ERR_FOUND_DUPP_KEY && + write_err != HA_ERR_FOUND_DUPP_UNIQUE) || !ignore_last_dupp_key_error) goto err; } @@ -12812,8 +12814,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, */ if ((order != join->group_list || !(join->select_options & SELECT_BIG_RESULT) || - select && select->quick && - select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) && + (select && select->quick && + select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) && test_if_skip_sort_order(tab,order,select_limit,0)) DBUG_RETURN(0); for (ORDER *ord= join->order; ord; ord= ord->next) @@ -13641,8 +13643,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, /* Lookup the current GROUP field in the FROM clause. */ order_item_type= order_item->type(); from_field= (Field*) not_found_field; - if (is_group_field && - order_item_type == Item::FIELD_ITEM || + if ((is_group_field && + order_item_type == Item::FIELD_ITEM) || order_item_type == Item::REF_ITEM) { from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables, @@ -14068,7 +14070,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables) if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); - for (; !(map & tables->table->map); tables= tables->next_leaf); + for (; !(map & tables->table->map); tables= tables->next_leaf) ; if (map != tables->table->map) DBUG_RETURN(0); // More than one table DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 59679c96120..8387c087836 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2987,10 +2987,10 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, TYPE_ENUM_PROCEDURE)) return 0; - if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && - proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE || - lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && - proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION || + if ((lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && + proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) || + (lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && + proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) || lex->orig_sql_command == SQLCOM_END) { restore_record(table, s->default_values); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9952fca6bcb..c4360c8d52e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -982,8 +982,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } /* Don't pack rows in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || - sql_field->sql_type == MYSQL_TYPE_VARCHAR && - create_info->row_type != ROW_TYPE_FIXED) + (sql_field->sql_type == MYSQL_TYPE_VARCHAR && + create_info->row_type != ROW_TYPE_FIXED)) (*db_options)|= HA_OPTION_PACK_RECORD; it2.rewind(); } @@ -1422,7 +1422,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->sql_type == MYSQL_TYPE_VARCHAR || sql_field->pack_flag & FIELDFLAG_BLOB))) { - if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB) || + if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) || sql_field->sql_type == MYSQL_TYPE_VARCHAR) key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; else @@ -3954,9 +3954,9 @@ view_err: } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, new_alias) || - (new_name != table_name || new_db != db) && // we also do rename + ((new_name != table_name || new_db != db) && // we also do rename Table_triggers_list::change_table_name(thd, db, table_name, - new_db, new_alias)) + new_db, new_alias))) { // Try to get everything back error=1; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index d2ae494d4eb..1fa8b83f300 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -179,7 +179,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) need second part of condition below, since check_access() function also checks that db is specified. */ - if (!thd->lex->spname->m_db.length || create && !tables->db_length) + if (!thd->lex->spname->m_db.length || (create && !tables->db_length)) { my_error(ER_NO_DB_ERROR, MYF(0)); DBUG_RETURN(TRUE); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 69f876ace39..481fe30c6e7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1532,7 +1532,7 @@ void multi_update::send_error(uint errcode,const char *err) /* the error was handled or nothing deleted and no side effects return */ if (error_handled || - !thd->transaction.stmt.modified_non_trans_table && !updated) + (!thd->transaction.stmt.modified_non_trans_table && !updated)) return; /* Something already updated so we have to invalidate cache */ diff --git a/sql/sql_view.cc b/sql/sql_view.cc index d1d84e76811..96077aeeb12 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -268,11 +268,11 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, */ if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || + (grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))) || (mode != VIEW_CREATE_NEW && (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0)))) + (grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0))))) goto err; for (sl= select_lex; sl; sl= sl->next_select()) @@ -322,7 +322,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, { if (check_access(thd, SELECT_ACL, tbl->db, &tbl->grant.privilege, 0, 0, test(tbl->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) + (grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))) goto err; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b6a215a2306..49b7fafcc0b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3943,7 +3943,7 @@ alter_list_item: MYSQL_YYABORT; } if (check_table_name($3->table.str,$3->table.length) || - $3->db.str && check_db_name($3->db.str)) + ($3->db.str && check_db_name($3->db.str))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); MYSQL_YYABORT; @@ -4094,8 +4094,8 @@ slave_until: | UNTIL_SYM slave_until_opts { LEX *lex=Lex; - if ((lex->mi.log_file_name || lex->mi.pos) && - (lex->mi.relay_log_name || lex->mi.relay_log_pos) || + if (((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || !((lex->mi.log_file_name && lex->mi.pos) || (lex->mi.relay_log_name && lex->mi.relay_log_pos))) { diff --git a/sql/table.cc b/sql/table.cc index 55a9b50605d..84b1099d5a2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2112,8 +2112,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type) { const char *save_where= thd->where; thd->where= "check option"; - if (!check_option->fixed && - check_option->fix_fields(thd, &check_option) || + if ((!check_option->fixed && + check_option->fix_fields(thd, &check_option)) || check_option->check_cols(1)) { DBUG_RETURN(TRUE); @@ -2827,7 +2827,7 @@ void Field_iterator_table_ref::set_field_iterator() /* Necesary, but insufficient conditions. */ DBUG_ASSERT(table_ref->is_natural_join || table_ref->nested_join || - table_ref->join_columns && + (table_ref->join_columns && /* This is a merge view. */ ((table_ref->field_translation && table_ref->join_columns->elements == @@ -2836,7 +2836,7 @@ void Field_iterator_table_ref::set_field_iterator() /* This is stored table or a tmptable view. */ (!table_ref->field_translation && table_ref->join_columns->elements == - table_ref->table->s->fields))); + table_ref->table->s->fields)))); field_it= &natural_join_it; DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join", table_ref->alias)); diff --git a/sql/table.h b/sql/table.h index ad578044371..db996d45320 100644 --- a/sql/table.h +++ b/sql/table.h @@ -729,7 +729,7 @@ struct TABLE_LIST void cleanup_items(); bool placeholder() { - return derived || view || schema_table || create && !table->db_stat || + return derived || view || schema_table || (create && !table->db_stat) || !table; } void print(THD *thd, String *str); diff --git a/sql/time.cc b/sql/time.cc index fb8a51fd0eb..b9cee5a986a 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -76,8 +76,8 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) if (l_time->month == 1 && l_time->day <= 7-weekday) { if (!week_year && - (first_weekday && weekday != 0 || - !first_weekday && weekday >= 4)) + ((first_weekday && weekday != 0) || + (!first_weekday && weekday >= 4))) return 0; week_year= 1; (*year)--; @@ -94,8 +94,8 @@ uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year) if (week_year && days >= 52*7) { weekday= (weekday + calc_days_in_year(*year)) % 7; - if (!first_weekday && weekday < 4 || - first_weekday && weekday == 0) + if ((!first_weekday && weekday < 4) || + (first_weekday && weekday == 0)) { (*year)++; return 1; diff --git a/sql/tztime.cc b/sql/tztime.cc index d73a1ca0111..73e68ee2b29 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -447,8 +447,8 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage) } if (end_t == MY_TIME_T_MAX || - (cur_off_and_corr > 0) && - (end_t >= MY_TIME_T_MAX - cur_off_and_corr)) + ((cur_off_and_corr > 0) && + (end_t >= MY_TIME_T_MAX - cur_off_and_corr))) /* end of t space */ break; diff --git a/sql/uniques.cc b/sql/uniques.cc index a0d1beaf0f9..86223151d72 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -604,9 +604,9 @@ bool Unique::get(TABLE *table) outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), MYF(MY_ZEROFILL)); - if (!outfile || ! my_b_inited(outfile) && + if (!outfile || (! my_b_inited(outfile) && open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, - MYF(MY_WME))) + MYF(MY_WME)))) return 1; reinit_io_cache(outfile,WRITE_CACHE,0L,0,0); From 389fba8403df5cb0bbf109245cc9c9c4d39463e7 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Wed, 17 Jun 2009 16:28:11 +0200 Subject: [PATCH 095/188] Bug#43758 Query cache can lock up threads in 'freeing items' state This patch corrects a misstake in the test case for bug patch 43658. There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all. The affected platforms appears to be limited to linux. mysql-test/r/query_cache_debug.result: There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all. mysql-test/t/query_cache_debug.test: There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all. --- mysql-test/r/query_cache_debug.result | 4 ++-- mysql-test/t/query_cache_debug.test | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result index b83bccef39c..eb59e62c8ba 100644 --- a/mysql-test/r/query_cache_debug.result +++ b/mysql-test/r/query_cache_debug.result @@ -141,9 +141,9 @@ KILL QUERY @flush_thread_id; ** and finally release the mutex. The threads will continue to wait ** until a broadcast signal reaches them causing both threads to ** come alive and check the condition. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id ASC LIMIT 1 INTO @thread_id; KILL QUERY @thread_id; -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id DESC LIMIT 1 INTO @thread_id; KILL QUERY @thread_id; ** ** Finally signal the DELETE statement on THD1 one last time. diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index f54e7105807..d30cd458e99 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -206,10 +206,11 @@ LET $wait_condition= SELECT SQL_NO_CACHE COUNT(*)= 1 FROM information_schema.pro --echo ** and finally release the mutex. The threads will continue to wait --echo ** until a broadcast signal reaches them causing both threads to --echo ** come alive and check the condition. -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id ASC LIMIT 1 INTO @thread_id; KILL QUERY @thread_id; -SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' LIMIT 1 INTO @thread_id; +SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id DESC LIMIT 1 INTO @thread_id; KILL QUERY @thread_id; + --echo ** --echo ** Finally signal the DELETE statement on THD1 one last time. --echo ** The stmt will complete the query cache invalidation and return From 0d460bcd65f484c1c2e415795f29b8d1949faacf Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Wed, 17 Jun 2009 16:58:33 +0200 Subject: [PATCH 096/188] Bug#44684: valgrind reports invalid reads in Item_func_spatial_collection::val_str When the concatenation function for geometry data collections reads the binary data it was not rigorous in checking that there is data available, leading to invalid reads and crashes. Fixed by making checking stricter. mysql-test/r/gis.result: Bug#44684: Test result mysql-test/t/gis.test: Bug#44684: Test case sql/item_geofunc.cc: Bug#44684: fix(es) - Check that there are 4 bytes available for type code. - Check that there is at least one point available for linestring. - Check that there are at least 2 points in a polygon and data for all the points. --- mysql-test/r/gis.result | 48 +++++++++++++++++++++++++++++++++++++++++ mysql-test/t/gis.test | 24 +++++++++++++++++++++ sql/item_geofunc.cc | 13 ++++++++--- 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 494b7a36532..a3708d06a1c 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -984,4 +984,52 @@ f4 geometry YES NULL f5 datetime YES NULL drop view v1; drop table t1; +SELECT MultiPoint(12345,''); +MultiPoint(12345,'') +NULL +SELECT MultiPoint(123451,''); +MultiPoint(123451,'') +NULL +SELECT MultiPoint(1234512,''); +MultiPoint(1234512,'') +NULL +SELECT MultiPoint(12345123,''); +MultiPoint(12345123,'') +NULL +SELECT MultiLineString(12345,''); +MultiLineString(12345,'') +NULL +SELECT MultiLineString(123451,''); +MultiLineString(123451,'') +NULL +SELECT MultiLineString(1234512,''); +MultiLineString(1234512,'') +NULL +SELECT MultiLineString(12345123,''); +MultiLineString(12345123,'') +NULL +SELECT LineString(12345,''); +LineString(12345,'') +NULL +SELECT LineString(123451,''); +LineString(123451,'') +NULL +SELECT LineString(1234512,''); +LineString(1234512,'') +NULL +SELECT LineString(12345123,''); +LineString(12345123,'') +NULL +SELECT Polygon(12345,''); +Polygon(12345,'') +NULL +SELECT Polygon(123451,''); +Polygon(123451,'') +NULL +SELECT Polygon(1234512,''); +Polygon(1234512,'') +NULL +SELECT Polygon(12345123,''); +Polygon(12345123,'') +NULL End of 5.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 0dae4509518..4a60e777cc7 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -667,4 +667,28 @@ desc v1; drop view v1; drop table t1; +# +# Bug#44684: valgrind reports invalid reads in +# Item_func_spatial_collection::val_str +# +SELECT MultiPoint(12345,''); +SELECT MultiPoint(123451,''); +SELECT MultiPoint(1234512,''); +SELECT MultiPoint(12345123,''); + +SELECT MultiLineString(12345,''); +SELECT MultiLineString(123451,''); +SELECT MultiLineString(1234512,''); +SELECT MultiLineString(12345123,''); + +SELECT LineString(12345,''); +SELECT LineString(123451,''); +SELECT LineString(1234512,''); +SELECT LineString(12345123,''); + +SELECT Polygon(12345,''); +SELECT Polygon(123451,''); +SELECT Polygon(1234512,''); +SELECT Polygon(12345123,''); + --echo End of 5.1 tests diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 24a92c78e9c..a34204b7181 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -416,7 +416,10 @@ String *Item_func_spatial_collection::val_str(String *str) else { enum Geometry::wkbType wkb_type; - const char *data= res->ptr() + 4/*SRID*/ + 1; + const uint data_offset= 4/*SRID*/ + 1; + if (res->length() < data_offset + sizeof(uint32)) + goto err; + const char *data= res->ptr() + data_offset; /* In the case of named collection we must check that items @@ -439,7 +442,7 @@ String *Item_func_spatial_collection::val_str(String *str) break; case Geometry::wkb_linestring: - if (str->append(data, POINT_DATA_SIZE, 512)) + if (len < POINT_DATA_SIZE || str->append(data, POINT_DATA_SIZE, 512)) goto err; break; case Geometry::wkb_polygon: @@ -448,11 +451,15 @@ String *Item_func_spatial_collection::val_str(String *str) double x1, y1, x2, y2; const char *org_data= data; - if (len < 4 + 2 * POINT_DATA_SIZE) + if (len < 4) goto err; n_points= uint4korr(data); data+= 4; + + if (n_points < 2 || len < 4 + n_points * POINT_DATA_SIZE) + goto err; + float8get(x1, data); data+= SIZEOF_STORED_DOUBLE; float8get(y1, data); From 5814263583577a10c139461e95e0b4433d575c57 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 17 Jun 2009 20:10:48 +0400 Subject: [PATCH 097/188] Disabled embedded server for the test case for bug #45236. --- mysql-test/t/mysql-bug45236.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/mysql-bug45236.test b/mysql-test/t/mysql-bug45236.test index 30cef1ab49c..efc10ed19ea 100644 --- a/mysql-test/t/mysql-bug45236.test +++ b/mysql-test/t/mysql-bug45236.test @@ -8,6 +8,8 @@ # on debx86-b in PB # +-- source include/not_embedded.inc + --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings From e544285dc2182eb9f6da7a77d2730747a87a2e69 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 18 Jun 2009 17:11:47 +0400 Subject: [PATCH 098/188] Bug #41710: MySQL 5.1.30 crashes on the latest OpenSolaris 10 Change the default optimization level for Sun Studio to "-O1". This is a workaround for a Sun Studio bug (see bug #41710 comments for details): 1. Use $GCC instead of $ac_cv_prog_gcc to check for gcc, since the first one is the only documented way to do it. 2. Use $GXX instead of $ac_cv_prog_cxx_g to check for g++, since the latter is set to "yes" when the C++ compiler accepts "-g" which is the case for both g++ and CC. 3. When building with Sun Studio, set the default values for CFLAGS/CXXFLAGS to "-O1", since unlike GCC, Sun Studio interprets "-O" as "-xO3" (see the manual pages for cc and CC). configure.in: 1. Use $GCC instead of $ac_cv_prog_gcc to check for gcc, since the first one is the only documented way to do it. 2. Use $GXX instead of $ac_cv_prog_cxx_g to check for g++, since the latter is set to "yes" when the C++ compiler accepts "-g" which is the case for both g++ and CC. 3. When building with Sun Studio, set the default values for CFLAGS/CXXFLAGS to "-O1", since unlike GCC, Sun Studio interprets "-O" as "-xO3" (see the manual pages for cc and CC). --- configure.in | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index 4fcb1f13f35..ec432e19ce3 100644 --- a/configure.in +++ b/configure.in @@ -1756,7 +1756,7 @@ esac # Build optimized or debug version ? # First check for gcc and g++ -if test "$ac_cv_prog_gcc" = "yes" +if test "$GCC" = "yes" then DEBUG_CFLAGS="-g" DEBUG_OPTIMIZE_CC="-O" @@ -1764,9 +1764,16 @@ then else DEBUG_CFLAGS="-g" DEBUG_OPTIMIZE_CC="" - OPTIMIZE_CFLAGS="-O" + case $SYSTEM_TYPE in + *solaris*) + OPTIMIZE_CFLAGS="-O1" + ;; + *) + OPTIMIZE_CFLAGS="-O" + ;; + esac fi -if test "$ac_cv_prog_cxx_g" = "yes" +if test "$GXX" = "yes" then DEBUG_CXXFLAGS="-g" DEBUG_OPTIMIZE_CXX="-O" @@ -1774,7 +1781,14 @@ then else DEBUG_CXXFLAGS="-g" DEBUG_OPTIMIZE_CXX="" - OPTIMIZE_CXXFLAGS="-O" + case $SYSTEM_TYPE in + *solaris*) + OPTIMIZE_CXXFLAGS="-O1" + ;; + *) + OPTIMIZE_CXXFLAGS="-O" + ;; + esac fi if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then From 3cf052b76cb62a3efbb29d4086a893f7f0d37d94 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 18 Jun 2009 14:52:46 +0100 Subject: [PATCH 099/188] BUG#43929 binlog corruption when max_binlog_cache_size is exceeded Large transactions and statements may corrupt the binary log if the size of the cache, which is set by the max_binlog_cache_size, is not enough to store the the changes. In a nutshell, to fix the bug, we save the position of the next character in the cache before starting processing a statement. If there is a problem, we simply restore the position thus removing any effect of the statement from the cache. Unfortunately, to avoid corrupting the binary log, we may end up loosing changes on non-transactional tables if they do not fit in the cache. In such cases, we store an Incident_log_event in order to stop the slave and alert users that some changes were not logged. Precisely, for every non-transactional changes that do not fit into the cache, we do the following: a) the statement is *not* logged b) an incident event is logged after committing/rolling back the transaction, if any. Note that if a failure happens before writing the incident event to the binary log, the slave will not stop and the master will not have reported any error. c) its respective statement gives an error For transactional changes that do not fit into the cache, we do the following: a) the statement is *not* logged b) its respective statement gives an error To work properly, this patch requires two additional things. Firstly, callers to MYSQL_BIN_LOG::write and THD::binlog_query must handle any error returned and take the appropriate actions such as undoing the effects of a statement. We already changed some calls in the sql_insert.cc, sql_update.cc and sql_insert.cc modules but the remaining calls spread all over the code should be handled in BUG#37148. Secondly, statements must be either classified as DDL or DML because DDLs that do not get into the cache must generate an incident event since they cannot be rolled back. --- mysql-test/include/commit.inc | 8 +- mysql-test/r/commit_1innodb.result | 8 +- .../rpl/r/rpl_binlog_max_cache_size.result | 135 ++++++ .../t/rpl_binlog_max_cache_size-master.opt | 1 + .../rpl/t/rpl_binlog_max_cache_size.test | 395 ++++++++++++++++++ sql/log.cc | 141 ++++++- sql/log.h | 5 +- sql/sql_delete.cc | 2 +- sql/sql_insert.cc | 3 +- sql/sql_update.cc | 6 +- 10 files changed, 661 insertions(+), 43 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index a4e7d9ae601..5ff9d409e27 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -669,13 +669,9 @@ call p_verify_status_increment(1, 0, 1, 0); insert t1 set a=3; call p_verify_status_increment(2, 2, 2, 2); savepoint a; -call p_verify_status_increment(0, 0, 0, 0); +call p_verify_status_increment(1, 0, 0, 0); insert t1 set a=4; ---echo # Binlog does not register itself this time for other than the 1st ---echo # statement of the transaction with MIXED/STATEMENT binlog_format. ---echo # It needs registering with the ROW format. Therefore 1,0,2,2 are ---echo # the correct arguments to this test after bug#40221 fixed. -call p_verify_status_increment(1, 0, 2, 2); +call p_verify_status_increment(2, 2, 2, 2); release savepoint a; rollback; call p_verify_status_increment(0, 0, 0, 0); diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index de80dba47c1..5f300468499 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -766,15 +766,11 @@ call p_verify_status_increment(2, 2, 2, 2); SUCCESS savepoint a; -call p_verify_status_increment(0, 0, 0, 0); +call p_verify_status_increment(1, 0, 0, 0); SUCCESS insert t1 set a=4; -# Binlog does not register itself this time for other than the 1st -# statement of the transaction with MIXED/STATEMENT binlog_format. -# It needs registering with the ROW format. Therefore 1,0,2,2 are -# the correct arguments to this test after bug#40221 fixed. -call p_verify_status_increment(1, 0, 2, 2); +call p_verify_status_increment(2, 2, 2, 2); SUCCESS release savepoint a; diff --git a/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result b/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result new file mode 100644 index 00000000000..0e3f83d0aa5 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_binlog_max_cache_size.result @@ -0,0 +1,135 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; +CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +######################################################################################## +# 1 - SINGLE STATEMENT +######################################################################################## +*** Single statement on transactional table *** +Got one of the listed errors +*** Single statement on non-transactional table *** +*** After WL#2687 the difference between STATEMENT/MIXED and ROW will not exist. *** +Got one of the listed errors +*** Single statement on both transactional and non-transactional tables. *** +*** After WL#2687 we will be able to change the order of the tables. *** +Got one of the listed errors +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE SQL_THREAD; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +BEGIN; +Got one of the listed errors +Got one of the listed errors +source include/diff_master_slave.inc; +######################################################################################## +# 3 - BEGIN - COMMIT +######################################################################################## +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +COMMIT; +source include/diff_master_slave.inc; +######################################################################################## +# 4 - BEGIN - ROLLBACK +######################################################################################## +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +source include/diff_master_slave.inc; +######################################################################################## +# 5 - PROCEDURE +######################################################################################## +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +CREATE PROCEDURE p1(pd VARCHAR(30000)) +BEGIN +INSERT INTO t1 (a, data) VALUES (1, pd); +INSERT INTO t1 (a, data) VALUES (2, pd); +INSERT INTO t1 (a, data) VALUES (3, pd); +INSERT INTO t1 (a, data) VALUES (4, pd); +INSERT INTO t1 (a, data) VALUES (5, 's'); +END// +TRUNCATE TABLE t1; +TRUNCATE TABLE t1; +BEGIN; +Got one of the listed errors +COMMIT; +TRUNCATE TABLE t1; +BEGIN; +Got one of the listed errors +ROLLBACK; +source include/diff_master_slave.inc; +######################################################################################## +# 6 - XID +######################################################################################## +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +ROLLBACK TO sv; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +COMMIT; +source include/diff_master_slave.inc; +######################################################################################## +# 7 - NON-TRANS TABLE +######################################################################################## +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +COMMIT; +BEGIN; +Got one of the listed errors +COMMIT; +######################################################################################## +# CLEAN +######################################################################################## +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE IF EXISTS t4; +DROP TABLE IF EXISTS t5; +DROP TABLE IF EXISTS t6; +DROP PROCEDURE p1; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE IF EXISTS t4; +DROP TABLE IF EXISTS t5; +DROP TABLE IF EXISTS t6; +DROP PROCEDURE p1; diff --git a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt new file mode 100644 index 00000000000..45631525481 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size-master.opt @@ -0,0 +1 @@ +--binlog_cache_size=4096 --max_binlog_cache_size=7680 diff --git a/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test new file mode 100644 index 00000000000..e1f1f8c54bb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_max_cache_size.test @@ -0,0 +1,395 @@ +######################################################################################## +# This test verifies if the binlog is not corrupted when the cache buffer is not +# big enough to accommodate the changes and is divided in five steps: +# +# 1 - Single Statements: +# 1.1 - Single statement on transactional table. +# 1.2 - Single statement on non-transactional table. +# 1.3 - Single statement on both transactional and non-transactional tables. +# In both 1.2 and 1.3, an incident event is logged to notify the user that the +# master and slave are diverging. +# +# 2 - Transactions ended by an implicit commit. +# +# 3 - Transactions ended by a COMMIT. +# +# 4 - Transactions ended by a ROLLBACK. +# +# 5 - Transactions with a failing statement that updates a non-transactional +# table. In this case, a failure means that the statement does not get into +# the cache and an incident event is logged to notify the user that the master +# and slave are diverging. +# +######################################################################################## + +######################################################################################## +# Configuring the environment +######################################################################################## +--source include/have_innodb.inc +--source include/master-slave.inc +--source include/not_embedded.inc +--source include/not_windows.inc + +CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; +CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; + +let $data = `select concat('"', repeat('a',2000), '"')`; + +--echo ######################################################################################## +--echo # 1 - SINGLE STATEMENT +--echo ######################################################################################## + +connection master; + +--echo *** Single statement on transactional table *** +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +eval INSERT INTO t1 (a, data) VALUES (1, + CONCAT($data, $data, $data, $data, $data)); +--enable_query_log + +--echo *** Single statement on non-transactional table *** +--echo *** After WL#2687 the difference between STATEMENT/MIXED and ROW will not exist. *** +--disable_query_log +--disable_warnings +if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) +{ + eval INSERT INTO t2 (a, data) VALUES (2, + CONCAT($data, $data, $data, $data, $data, $data)); + --echo Got one of the listed errors +} +if (`SELECT @@binlog_format = 'ROW'`) +{ + --error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE + eval INSERT INTO t2 (a, data) VALUES (2, + CONCAT($data, $data, $data, $data, $data, $data)); + + connection slave; + --source include/wait_for_slave_sql_to_stop.inc + SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; + START SLAVE SQL_THREAD; + --source include/wait_for_slave_sql_to_start.inc +} +--enable_warnings +--enable_query_log + +connection master; + +--disable_query_log +eval INSERT INTO t1 (a, data) VALUES (3, $data); +eval INSERT INTO t1 (a, data) VALUES (4, $data); +eval INSERT INTO t1 (a, data) VALUES (5, $data); +eval INSERT INTO t2 (a, data) VALUES (3, $data); +eval INSERT INTO t2 (a, data) VALUES (4, $data); +eval INSERT INTO t2 (a, data) VALUES (5, $data); +--enable_query_log + +--echo *** Single statement on both transactional and non-transactional tables. *** +--echo *** After WL#2687 we will be able to change the order of the tables. *** +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data), + t1.data = CONCAT($data, $data, $data, $data); +--enable_query_log + +connection slave; +--source include/wait_for_slave_sql_to_stop.inc +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_to_start.inc + +#--echo ######################################################################################## +#--echo # 2 - BEGIN - IMPLICIT COMMIT by DDL +#--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log + +--disable_query_log +ALTER TABLE t3 ADD COLUMN d int; +--enable_query_log + +--disable_query_log +--eval INSERT INTO t2 (a, data) VALUES (10, $data); +--eval INSERT INTO t2 (a, data) VALUES (11, $data); +--eval INSERT INTO t2 (a, data) VALUES (12, $data); +--eval INSERT INTO t2 (a, data) VALUES (13, $data); +--enable_query_log + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (14, $data); +--eval INSERT INTO t1 (a, data) VALUES (15, $data); +--eval INSERT INTO t1 (a, data) VALUES (16, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (17, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (18, $data); +--eval INSERT INTO t1 (a, data) VALUES (19, 's'); +--eval INSERT INTO t2 (a, data) VALUES (20, 's'); +--eval INSERT INTO t1 (a, data) VALUES (21, 's'); +--enable_query_log + +if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) +{ + --disable_query_log + CREATE TABLE t4 SELECT * FROM t1; + --enable_query_log + --echo Got one of the listed errors +} +if (`SELECT @@binlog_format = 'ROW'`) +{ + --disable_query_log + --error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE + CREATE TABLE t4 SELECT * FROM t1; + --enable_query_log +} + +--disable_query_log +--eval INSERT INTO t2 (a, data) VALUES (15, $data); +--enable_query_log + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (22, $data); +--eval INSERT INTO t1 (a, data) VALUES (23, $data); +--eval INSERT INTO t1 (a, data) VALUES (24, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (25, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (26, $data); +--eval INSERT INTO t1 (a, data) VALUES (27, 's'); +--eval INSERT INTO t2 (a, data) VALUES (28, 's'); +--eval INSERT INTO t1 (a, data) VALUES (29, 's'); +--enable_query_log + +--disable_query_log +CREATE TABLE t5 (a int); +--enable_query_log + +let $diff_statement= SELECT * FROM t1; +--source include/diff_master_slave.inc + +--echo ######################################################################################## +--echo # 3 - BEGIN - COMMIT +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log +COMMIT; + +let $diff_statement= SELECT * FROM t1; +--source include/diff_master_slave.inc + +--echo ######################################################################################## +--echo # 4 - BEGIN - ROLLBACK +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log +ROLLBACK; + +let $diff_statement= SELECT * FROM t1; +--source include/diff_master_slave.inc + +--echo ######################################################################################## +--echo # 5 - PROCEDURE +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +DELIMITER //; + +CREATE PROCEDURE p1(pd VARCHAR(30000)) +BEGIN + INSERT INTO t1 (a, data) VALUES (1, pd); + INSERT INTO t1 (a, data) VALUES (2, pd); + INSERT INTO t1 (a, data) VALUES (3, pd); + INSERT INTO t1 (a, data) VALUES (4, pd); + INSERT INTO t1 (a, data) VALUES (5, 's'); +END// + +DELIMITER ;// + +TRUNCATE TABLE t1; + +--disable_query_log +eval CALL p1($data); +--enable_query_log + +TRUNCATE TABLE t1; + +BEGIN; +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +eval CALL p1($data); +--enable_query_log +COMMIT; + +TRUNCATE TABLE t1; + +BEGIN; +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +eval CALL p1($data); +--enable_query_log +ROLLBACK; + +let $diff_statement= SELECT * FROM t1; +--source include/diff_master_slave.inc + +--echo ######################################################################################## +--echo # 6 - XID +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +SAVEPOINT sv; +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log +ROLLBACK TO sv; +COMMIT; + +let $diff_statement= SELECT * FROM t1; +--source include/diff_master_slave.inc + +--echo ######################################################################################## +--echo # 7 - NON-TRANS TABLE +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t2 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (7, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval UPDATE t2 SET data= CONCAT($data, $data); +--eval INSERT INTO t1 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--eval INSERT INTO t2 (a, data) VALUES (10, 's'); +--eval INSERT INTO t1 (a, data) VALUES (11, 's'); +--enable_query_log +COMMIT; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (15, $data); +--eval INSERT INTO t1 (a, data) VALUES (16, $data); +--eval INSERT INTO t2 (a, data) VALUES (17, $data); +--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (18, $data); +--enable_query_log +COMMIT; + +connection slave; +--source include/wait_for_slave_sql_to_stop.inc + +--echo ######################################################################################## +--echo # CLEAN +--echo ######################################################################################## + +--disable_warnings +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE IF EXISTS t4; +DROP TABLE IF EXISTS t5; +DROP TABLE IF EXISTS t6; +DROP PROCEDURE p1; +connection slave; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE IF EXISTS t4; +DROP TABLE IF EXISTS t5; +DROP TABLE IF EXISTS t6; +DROP PROCEDURE p1; +--enable_warnings diff --git a/sql/log.cc b/sql/log.cc index ee7ee48b42c..1ed3b35a8a9 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -153,7 +153,8 @@ private: class binlog_trx_data { public: binlog_trx_data() - : at_least_one_stmt(0), m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF) + : at_least_one_stmt(0), incident(FALSE), m_pending(0), + before_stmt_pos(MY_OFF_T_UNDEF) { trans_log.end_of_file= max_binlog_cache_size; } @@ -184,6 +185,7 @@ public: delete pending(); set_pending(0); reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0); + trans_log.end_of_file= max_binlog_cache_size; if (pos < before_stmt_pos) before_stmt_pos= MY_OFF_T_UNDEF; @@ -206,6 +208,7 @@ public: if (!empty()) truncate(0); before_stmt_pos= MY_OFF_T_UNDEF; + incident= FALSE; trans_log.end_of_file= max_binlog_cache_size; DBUG_ASSERT(empty()); } @@ -222,11 +225,22 @@ public: IO_CACHE trans_log; // The transaction cache + void set_incident(void) + { + incident= TRUE; + } + + bool has_incident(void) + { + return(incident); + } + /** Boolean that is true if there is at least one statement in the transaction cache. */ bool at_least_one_stmt; + bool incident; private: /* @@ -1391,7 +1405,8 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, */ if (end_ev != NULL) { - thd->binlog_flush_pending_rows_event(TRUE); + if (thd->binlog_flush_pending_rows_event(TRUE)) + DBUG_RETURN(1); /* Doing a commit or a rollback including non-transactional tables, i.e., ending a transaction where we might write the transaction @@ -1402,7 +1417,8 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, were, we would have to ensure that we're not ending a statement inside a stored function. */ - error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev); + error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev, + trx_data->has_incident()); trx_data->reset(); /* @@ -1428,7 +1444,11 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, */ thd->binlog_remove_pending_rows_event(TRUE); if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) + { + if (trx_data->has_incident()) + mysql_bin_log.write_incident(thd, TRUE); trx_data->reset(); + } else // ...statement trx_data->truncate(trx_data->before_stmt_pos); @@ -1544,9 +1564,11 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) YESNO(all), YESNO(thd->transaction.all.modified_non_trans_table), YESNO(thd->transaction.stmt.modified_non_trans_table))); - if (all && thd->transaction.all.modified_non_trans_table || - !all && thd->transaction.stmt.modified_non_trans_table || - (thd->options & OPTION_KEEP_LOG)) + if ((all && thd->transaction.all.modified_non_trans_table) || + (!all && thd->transaction.stmt.modified_non_trans_table && + !mysql_bin_log.check_write_error(thd)) || + ((thd->options & OPTION_KEEP_LOG) && + !mysql_bin_log.check_write_error(thd))) { /* We write the transaction cache with a rollback last if we have @@ -1559,14 +1581,22 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); } - else if (all && !thd->transaction.all.modified_non_trans_table || - !all && !thd->transaction.stmt.modified_non_trans_table) + else { /* - If we have modified only transactional tables, we can truncate - the transaction cache without writing anything to the binary - log. + We reach this point if either only transactional tables were modified or + the effect of a statement that did not get into the binlog needs to be + rolled back. In the latter case, if a statement changed non-transactional + tables or had the OPTION_KEEP_LOG associated, we write an incident event + to the binlog in order to stop slaves and notify users that some changes + on the master did not get into the binlog and slaves will be inconsistent. + On the other hand, if a statement is transactional, we just safely roll it + back. */ + if ((thd->transaction.stmt.modified_non_trans_table || + (thd->options & OPTION_KEEP_LOG)) && + mysql_bin_log.check_write_error(thd)) + trx_data->set_incident(); error= binlog_end_trans(thd, trx_data, 0, all); } if (!all) @@ -1574,6 +1604,44 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) DBUG_RETURN(error); } +void MYSQL_BIN_LOG::set_write_error(THD *thd) +{ + DBUG_ENTER("MYSQL_BIN_LOG::set_write_error"); + + write_error= 1; + + if (check_write_error(thd)) + DBUG_VOID_RETURN; + + if (my_errno == EFBIG) + my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(MY_WME)); + else + my_error(ER_ERROR_ON_WRITE, MYF(MY_WME), name, errno); + + DBUG_VOID_RETURN; +} + +bool MYSQL_BIN_LOG::check_write_error(THD *thd) +{ + DBUG_ENTER("MYSQL_BIN_LOG::check_write_error"); + + bool checked= FALSE; + + if (!thd->is_error()) + DBUG_RETURN(checked); + + switch (thd->main_da.sql_errno()) + { + case ER_TRANS_CACHE_FULL: + case ER_ERROR_ON_WRITE: + case ER_BINLOG_LOGGING_IMPOSSIBLE: + checked= TRUE; + break; + } + + DBUG_RETURN(checked); +} + /** @note How do we handle this (unlikely but legal) case: @@ -3854,6 +3922,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, if (pending->write(file)) { pthread_mutex_unlock(&LOCK_log); + set_write_error(thd); DBUG_RETURN(1); } @@ -3928,7 +3997,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) */ bool const end_stmt= thd->prelocked_mode && thd->lex->requires_prelocking(); - thd->binlog_flush_pending_rows_event(end_stmt); + if (thd->binlog_flush_pending_rows_event(end_stmt)) + DBUG_RETURN(error); pthread_mutex_lock(&LOCK_log); @@ -3979,8 +4049,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu", event_info->get_cache_stmt(), (ulong) trans_log_pos)); - if (trans_log_pos == 0) - thd->binlog_start_trans_and_stmt(); + thd->binlog_start_trans_and_stmt(); file= trans_log; } /* @@ -4058,7 +4127,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) Write the SQL command */ - if (event_info->write(file)) + if (event_info->write(file) || + DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0)) goto err; if (file == &log_file) // we are writing to the real log (disk) @@ -4072,13 +4142,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) err: if (error) - { - if (my_errno == EFBIG) - my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(0)); - else - my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno); - write_error=1; - } + set_write_error(thd); } if (event_info->flags & LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F) @@ -4359,6 +4423,29 @@ int query_error_code(THD *thd, bool not_killed) return error; } +bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) +{ + uint error= 0; + DBUG_ENTER("MYSQL_BIN_LOG::write_incident"); + LEX_STRING const write_error_msg= + { C_STRING_WITH_LEN("error writing to the binary log") }; + Incident incident= INCIDENT_LOST_EVENTS; + Incident_log_event ev(thd, incident, write_error_msg); + if (lock) + pthread_mutex_lock(&LOCK_log); + ev.write(&log_file); + if (lock) + { + if (!error && !(error= flush_and_sync())) + { + signal_update(); + rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); + } + pthread_mutex_unlock(&LOCK_log); + } + DBUG_RETURN(error); +} + /** Write a cached log entry to the binary log. - To support transaction over replication, we wrap the transaction @@ -4371,6 +4458,9 @@ int query_error_code(THD *thd, bool not_killed) @param cache The cache to copy to the binlog @param commit_event The commit event to print after writing the contents of the cache. + @param incident Defines if an incident event should be created to + notify that some non-transactional changes did + not get into the binlog. @note We only come here if there is something in the cache. @@ -4380,7 +4470,8 @@ int query_error_code(THD *thd, bool not_killed) 'cache' needs to be reinitialized after this functions returns. */ -bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) +bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, + bool incident) { DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)"); VOID(pthread_mutex_lock(&LOCK_log)); @@ -4429,6 +4520,10 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) if (commit_event && commit_event->write(&log_file)) goto err; + + if (incident && write_incident(thd, FALSE)) + goto err; + if (flush_and_sync()) goto err; DBUG_EXECUTE_IF("half_binlogged_transaction", abort();); diff --git a/sql/log.h b/sql/log.h index d71dcc3173d..d306d6f7182 100644 --- a/sql/log.h +++ b/sql/log.h @@ -356,9 +356,12 @@ public: void new_file(); bool write(Log_event* event_info); // binary log write - bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event); + bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident); + bool write_incident(THD *thd, bool lock); int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync); + void set_write_error(THD *thd); + bool check_write_error(THD *thd); void start_union_events(THD *thd, query_id_t query_id_param); void stop_union_events(THD *thd); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 277269f3b0d..f9de43347bc 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -408,7 +408,7 @@ cleanup: thd->query, thd->query_length, is_trans, FALSE, errcode); - if (log_result && transactional_table) + if (log_result) { error=1; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9de27868d74..3f57a40eaf2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -897,8 +897,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, transactional_table, FALSE, - errcode) && - transactional_table) + errcode)) { error=1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ab6ba2ba756..4d5613a684a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -803,8 +803,7 @@ int mysql_update(THD *thd, if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_table, FALSE, errcode) && - transactional_table) + transactional_table, FALSE, errcode)) { error=1; // Rollback update } @@ -2087,8 +2086,7 @@ bool multi_update::send_eof() errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length, - transactional_tables, FALSE, errcode) && - trans_safe) + transactional_tables, FALSE, errcode)) { local_error= 1; // Rollback update } From 4de6d1a80f97dbb4a66b76ed44f0c026d0146cb4 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 18 Jun 2009 20:21:47 -0300 Subject: [PATCH 100/188] Bug#42599: error: `pthread_setschedprio' was not declared in this scope The problem was that a pthread.h header used by gcc did not declare the pthread_setscheprio, yet the function is implemented by the function is implemented, causing a autoconf check to pass and compilation with C++ to fail. The solution is to add a autoconf check to ensure that the function is properly declared. configure.in: Check that the pthread_setschedprio is declared. --- configure.in | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configure.in b/configure.in index d323ce9f726..bd26e584bfe 100644 --- a/configure.in +++ b/configure.in @@ -2076,6 +2076,25 @@ case "$mysql_cv_sys_os" in # unsupported priority values are passed to pthread_setschedprio. # Since the only supported value is 1, treat it as inexistent. ;; + SunOS) # Bug#42599 error: `pthread_setschedprio' was not declared in this scope + # In some installations, the pthread.h header used by GCC does not + # declare the pthread_setscheprio prototype, but the function is + # implemented. Since the function is used in C++ code, ensure that + # the function prototype is present. + AC_MSG_CHECKING([whether pthread_setschedprio is declared]) + AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([#include ], + [(void)(pthread_setschedprio);])], + [ac_cv_func_pthread_setschedprio=yes], + [ac_cv_func_pthread_setschedprio=no]) + AC_LANG_POP([C++]) + AC_MSG_RESULT([$ac_cv_func_pthread_setschedprio]) + if test "$ac_cv_func_pthread_setschedprio" = yes; then + AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, + [Define to 1 if you have the `pthread_setschedprio' function.]) + fi + ;; *) AC_CHECK_FUNCS(pthread_setschedprio) ;; esac From 9347649c16c176605aac1e36275fa89a6b21f9fc Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 19 Jun 2009 13:24:43 +0500 Subject: [PATCH 101/188] Bug#44834 strxnmov is expected to behave as you'd expect The problem: described in the bug report. The fix: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used client/mysql.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/ha_ndbcluster.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/ha_ndbcluster_binlog.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/handler.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/log.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/mysqld.cc: removed unnecessary line sql/parse_file.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_acl.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_base.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_db.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_delete.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_partition.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_rename.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_show.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_table.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function sql/sql_view.cc: --increase buffers where it's necessary (buffers which are used in stxnmov) --decrease buffer lengths which are used as argument for strxnmov function --- client/mysql.cc | 2 +- sql/ha_ndbcluster.cc | 46 +++++++++++++++-------------- sql/ha_ndbcluster_binlog.cc | 32 ++++++++++---------- sql/handler.cc | 8 ++--- sql/log.cc | 4 +-- sql/mysqld.cc | 1 - sql/parse_file.cc | 4 +-- sql/sql_acl.cc | 4 +-- sql/sql_base.cc | 6 ++-- sql/sql_db.cc | 18 ++++++------ sql/sql_delete.cc | 4 +-- sql/sql_partition.cc | 42 +++++++++++++-------------- sql/sql_rename.cc | 6 ++-- sql/sql_show.cc | 10 +++---- sql/sql_table.cc | 58 +++++++++++++++++++------------------ sql/sql_view.cc | 14 ++++----- 16 files changed, 132 insertions(+), 127 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 732e38cd74d..4ab46ed1e7d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2732,7 +2732,7 @@ static int com_server_help(String *buffer __attribute__((unused)), { MYSQL_ROW cur; const char *server_cmd= buffer->ptr(); - char cmd_buf[100]; + char cmd_buf[100 + 1]; MYSQL_RES *result; int error; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 3454f3558e8..ddb90427fdc 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1247,7 +1247,7 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info, } if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX) { - char unique_index_name[FN_LEN]; + char unique_index_name[FN_LEN + 1]; static const char* unique_suffix= "$unique"; m_has_unique_index= TRUE; strxnmov(unique_index_name, FN_LEN, index_name, unique_suffix, NullS); @@ -5150,7 +5150,7 @@ int ha_ndbcluster::create(const char *name, uchar *data= NULL, *pack_data= NULL; bool create_from_engine= (create_info->table_options & HA_OPTION_CREATE_FROM_ENGINE); bool is_truncate= (thd->lex->sql_command == SQLCOM_TRUNCATE); - char tablespace[FN_LEN]; + char tablespace[FN_LEN + 1]; NdbDictionary::Table::SingleUserMode single_user_mode= NdbDictionary::Table::SingleUserModeLocked; DBUG_ENTER("ha_ndbcluster::create"); @@ -5613,7 +5613,7 @@ int ha_ndbcluster::create_index(const char *name, KEY *key_info, NDB_INDEX_TYPE idx_type, uint idx_no) { int error= 0; - char unique_name[FN_LEN]; + char unique_name[FN_LEN + 1]; static const char* unique_suffix= "$unique"; DBUG_ENTER("ha_ndbcluster::create_ordered_index"); DBUG_PRINT("info", ("Creating index %u: %s", idx_no, name)); @@ -6661,7 +6661,7 @@ int ndbcluster_discover(handlerton *hton, THD* thd, const char *db, size_t len; uchar* data= NULL; Ndb* ndb; - char key[FN_REFLEN]; + char key[FN_REFLEN + 1]; DBUG_ENTER("ndbcluster_discover"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); @@ -6672,7 +6672,7 @@ int ndbcluster_discover(handlerton *hton, THD* thd, const char *db, ERR_RETURN(ndb->getNdbError()); } NDBDICT* dict= ndb->getDictionary(); - build_table_filename(key, sizeof(key), db, name, "", 0); + build_table_filename(key, sizeof(key) - 1, db, name, "", 0); /* ndb_share reference temporary */ NDB_SHARE *share= get_share(key, 0, FALSE); if (share) @@ -6837,9 +6837,9 @@ int ndbcluster_drop_database_impl(const char *path) drop_list.push_back(thd->strdup(elmt.name)); } // Drop any tables belonging to database - char full_path[FN_REFLEN]; + char full_path[FN_REFLEN + 1]; char *tmp= full_path + - build_table_filename(full_path, sizeof(full_path), dbname, "", "", 0); + build_table_filename(full_path, sizeof(full_path) - 1, dbname, "", "", 0); if (ndb->setDatabaseName(dbname)) { ERR_RETURN(ndb->getNdbError()); @@ -6908,7 +6908,7 @@ int ndb_create_table_from_engine(THD *thd, const char *db, int ndbcluster_find_all_files(THD *thd) { Ndb* ndb; - char key[FN_REFLEN]; + char key[FN_REFLEN + 1]; NDBDICT *dict; int unhandled, retries= 5, skipped; DBUG_ENTER("ndbcluster_find_all_files"); @@ -6966,7 +6966,7 @@ int ndbcluster_find_all_files(THD *thd) /* check if database exists */ char *end= key + - build_table_filename(key, sizeof(key), elmt.database, "", "", 0); + build_table_filename(key, sizeof(key) - 1, elmt.database, "", "", 0); if (my_access(key, F_OK)) { /* no such database defined, skip table */ @@ -7047,7 +7047,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, { // extra bracket to avoid gcc 2.95.3 warning uint i; Ndb* ndb; - char name[FN_REFLEN]; + char name[FN_REFLEN + 1]; HASH ndb_tables, ok_tables; NDBDICT::List list; @@ -7117,7 +7117,8 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, DBUG_PRINT("info", ("%s", file_name->str)); if (hash_search(&ndb_tables, (uchar*) file_name->str, file_name->length)) { - build_table_filename(name, sizeof(name), db, file_name->str, reg_ext, 0); + build_table_filename(name, sizeof(name) - 1, db, + file_name->str, reg_ext, 0); if (my_access(name, F_OK)) { pthread_mutex_lock(&LOCK_open); @@ -7139,7 +7140,8 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, } // Check for .ndb file with this name - build_table_filename(name, sizeof(name), db, file_name->str, ha_ndb_ext, 0); + build_table_filename(name, sizeof(name) - 1, db, + file_name->str, ha_ndb_ext, 0); DBUG_PRINT("info", ("Check access for %s", name)); if (my_access(name, F_OK)) { @@ -7182,7 +7184,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, /* setup logging to binlog for all discovered tables */ { char *end, *end1= name + - build_table_filename(name, sizeof(name), db, "", "", 0); + build_table_filename(name, sizeof(name) - 1, db, "", "", 0); for (i= 0; i < ok_tables.records; i++) { file_name_str= (char*)hash_element(&ok_tables, i); @@ -7204,7 +7206,8 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, file_name_str= (char*) hash_element(&ndb_tables, i); if (!hash_search(&ok_tables, (uchar*) file_name_str, strlen(file_name_str))) { - build_table_filename(name, sizeof(name), db, file_name_str, reg_ext, 0); + build_table_filename(name, sizeof(name) - 1, + db, file_name_str, reg_ext, 0); if (my_access(name, F_OK)) { DBUG_PRINT("info", ("%s must be discovered", file_name_str)); @@ -7584,7 +7587,7 @@ void ndbcluster_print_error(int error, const NdbOperation *error_op) void ha_ndbcluster::set_dbname(const char *path_name, char *dbname) { char *end, *ptr, *tmp_name; - char tmp_buff[FN_REFLEN]; + char tmp_buff[FN_REFLEN + 1]; tmp_name= tmp_buff; /* Scan name from the end */ @@ -7610,7 +7613,7 @@ void ha_ndbcluster::set_dbname(const char *path_name, char *dbname) ptr++; } #endif - filename_to_tablename(tmp_name, dbname, FN_REFLEN); + filename_to_tablename(tmp_name, dbname, sizeof(tmp_buff) - 1); } /** @@ -7630,7 +7633,7 @@ void ha_ndbcluster::set_tabname(const char *path_name, char * tabname) { char *end, *ptr, *tmp_name; - char tmp_buff[FN_REFLEN]; + char tmp_buff[FN_REFLEN + 1]; tmp_name= tmp_buff; /* Scan name from the end */ @@ -7651,7 +7654,7 @@ ha_ndbcluster::set_tabname(const char *path_name, char * tabname) ptr++; } #endif - filename_to_tablename(tmp_name, tabname, FN_REFLEN); + filename_to_tablename(tmp_name, tabname, sizeof(tmp_buff) - 1); } /** @@ -7837,11 +7840,12 @@ uint8 ha_ndbcluster::table_cache_type() uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname, Uint64 *commit_count) { - char name[FN_REFLEN]; + char name[FN_REFLEN + 1]; NDB_SHARE *share; DBUG_ENTER("ndb_get_commitcount"); - build_table_filename(name, sizeof(name), dbname, tabname, "", 0); + build_table_filename(name, sizeof(name) - 1, + dbname, tabname, "", 0); DBUG_PRINT("enter", ("name: %s", name)); pthread_mutex_lock(&ndbcluster_mutex); if (!(share=(NDB_SHARE*) hash_search(&ndbcluster_open_tables, @@ -9945,7 +9949,7 @@ bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *create_info, ai=1; } - char tablespace_name[FN_LEN]; + char tablespace_name[FN_LEN + 1]; if (get_tablespace_name(current_thd, tablespace_name, FN_LEN)) { if (create_info->tablespace) diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index a0c74b60f84..f705af8bf47 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -788,7 +788,7 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd) if (g_ndb_cluster_connection->get_no_ready() <= 0) DBUG_RETURN(0); - char buf[1024], *end; + char buf[1024 + 1], *end; if (ndb_extra_logging) sql_print_information("NDB: Creating " NDB_REP_DB "." NDB_APPLY_TABLE); @@ -798,7 +798,7 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd) if so, remove it since there is none in Ndb */ { - build_table_filename(buf, sizeof(buf), + build_table_filename(buf, sizeof(buf) - 1, NDB_REP_DB, NDB_APPLY_TABLE, reg_ext, 0); my_delete(buf, MYF(0)); } @@ -846,7 +846,7 @@ static int ndbcluster_create_schema_table(THD *thd) if (g_ndb_cluster_connection->get_no_ready() <= 0) DBUG_RETURN(0); - char buf[1024], *end; + char buf[1024 + 1], *end; if (ndb_extra_logging) sql_print_information("NDB: Creating " NDB_REP_DB "." NDB_SCHEMA_TABLE); @@ -856,7 +856,7 @@ static int ndbcluster_create_schema_table(THD *thd) if so, remove it since there is none in Ndb */ { - build_table_filename(buf, sizeof(buf), + build_table_filename(buf, sizeof(buf) - 1, NDB_REP_DB, NDB_SCHEMA_TABLE, reg_ext, 0); my_delete(buf, MYF(0)); } @@ -1321,8 +1321,8 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share, NDB_SCHEMA_OBJECT *ndb_schema_object; { - char key[FN_REFLEN]; - build_table_filename(key, sizeof(key), db, table_name, "", 0); + char key[FN_REFLEN + 1]; + build_table_filename(key, sizeof(key) - 1, db, table_name, "", 0); ndb_schema_object= ndb_get_schema_object(key, TRUE, FALSE); } @@ -1674,7 +1674,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, if (is_remote_change && is_online_alter_table) { const char *tabname= table_share->table_name.str; - char key[FN_REFLEN]; + char key[FN_REFLEN + 1]; uchar *data= 0, *pack_data= 0; size_t length, pack_length; int error; @@ -1683,7 +1683,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, DBUG_PRINT("info", ("Detected frm change of table %s.%s", dbname, tabname)); - build_table_filename(key, FN_LEN-1, dbname, tabname, NullS, 0); + build_table_filename(key, FN_LEN - 1, dbname, tabname, NullS, 0); /* If the there is no local table shadowing the altered table and it has an frm that is different than the one on disk then @@ -1926,8 +1926,8 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb, break; case SOT_TRUNCATE_TABLE: { - char key[FN_REFLEN]; - build_table_filename(key, sizeof(key), + char key[FN_REFLEN + 1]; + build_table_filename(key, sizeof(key) - 1, schema->db, schema->name, "", 0); /* ndb_share reference temporary, free below */ NDB_SHARE *share= get_share(key, 0, FALSE, FALSE); @@ -2173,8 +2173,8 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd, int log_query= 0; { enum SCHEMA_OP_TYPE schema_type= (enum SCHEMA_OP_TYPE)schema->type; - char key[FN_REFLEN]; - build_table_filename(key, sizeof(key), schema->db, schema->name, "", 0); + char key[FN_REFLEN + 1]; + build_table_filename(key, sizeof(key) - 1, schema->db, schema->name, "", 0); if (schema_type == SOT_CLEAR_SLOCK) { pthread_mutex_lock(&ndbcluster_mutex); @@ -2508,8 +2508,8 @@ ndb_rep_event_name(String *event_name,const char *db, const char *tbl) bool ndbcluster_check_if_local_table(const char *dbname, const char *tabname) { - char key[FN_REFLEN]; - char ndb_file[FN_REFLEN]; + char key[FN_REFLEN + 1]; + char ndb_file[FN_REFLEN + 1]; DBUG_ENTER("ndbcluster_check_if_local_table"); build_table_filename(key, FN_LEN-1, dbname, tabname, reg_ext, 0); @@ -2534,9 +2534,9 @@ ndbcluster_check_if_local_tables_in_db(THD *thd, const char *dbname) DBUG_PRINT("info", ("Looking for files in directory %s", dbname)); LEX_STRING *tabname; List files; - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; - build_table_filename(path, sizeof(path), dbname, "", "", 0); + build_table_filename(path, sizeof(path) - 1, dbname, "", "", 0); if (find_files(thd, &files, dbname, path, NullS, 0) != FIND_FILES_OK) { DBUG_PRINT("info", ("Failed to find files")); diff --git a/sql/handler.cc b/sql/handler.cc index 058a43eed8d..7e584b8fcf3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3582,7 +3582,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) int error; uchar *frmblob; size_t frmlen; - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; HA_CREATE_INFO create_info; TABLE table; TABLE_SHARE share; @@ -3601,7 +3601,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) frmblob and frmlen are set, write the frm to disk */ - build_table_filename(path, FN_REFLEN-1, db, name, "", 0); + build_table_filename(path, sizeof(path) - 1, db, name, "", 0); // Save the frm file error= writefrm(path, frmblob, frmlen); my_free(frmblob, MYF(0)); @@ -4778,7 +4778,7 @@ fl_log_iterator_buffer_init(struct handler_iterator *iterator) if ((ptr= (uchar*)my_malloc(ALIGN_SIZE(sizeof(fl_buff)) + ((ALIGN_SIZE(sizeof(LEX_STRING)) + sizeof(enum log_status) + - + FN_REFLEN) * + + FN_REFLEN + 1) * (uint) dirp->number_off_files), MYF(0))) == 0) { @@ -4806,7 +4806,7 @@ fl_log_iterator_buffer_init(struct handler_iterator *iterator) name_ptr= strxnmov(buff->names[buff->entries].str= name_ptr, FN_REFLEN, fl_dir, file->name, NullS); buff->names[buff->entries].length= (name_ptr - - buff->names[buff->entries].str) - 1; + buff->names[buff->entries].str); buff->statuses[buff->entries]= st; buff->entries++; } diff --git a/sql/log.cc b/sql/log.cc index 1ed3b35a8a9..8bb6ba8e9c6 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -956,7 +956,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, bool error= FALSE; Log_event_handler **current_handler; bool is_command= FALSE; - char user_host_buff[MAX_USER_HOST_SIZE]; + char user_host_buff[MAX_USER_HOST_SIZE + 1]; Security_context *sctx= thd->security_ctx; uint user_host_len= 0; ulonglong query_utime, lock_utime; @@ -1022,7 +1022,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, { bool error= FALSE; Log_event_handler **current_handler= general_log_handler_list; - char user_host_buff[MAX_USER_HOST_SIZE]; + char user_host_buff[MAX_USER_HOST_SIZE + 1]; Security_context *sctx= thd->security_ctx; ulong id; uint user_host_len= 0; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 239fff01071..1d18226ab45 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1664,7 +1664,6 @@ static void network_init(void) opt_enable_named_pipe) { - pipe_name[sizeof(pipe_name)-1]= 0; /* Safety if too long string */ strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", mysqld_unix_port, NullS); bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity)); diff --git a/sql/parse_file.cc b/sql/parse_file.cc index f2dbeba1bbf..3d65fa1de31 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -231,7 +231,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, including dir name, file name itself, and an extension, and with unpack_filename() executed over it. */ - path_end= strxnmov(path, FN_REFLEN, file_name->str, NullS) - path; + path_end= strxnmov(path, sizeof(path) - 1, file_name->str, NullS) - path; } // temporary file name @@ -314,7 +314,7 @@ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, const char *new_db, const char *new_name) { - char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; + char old_path[FN_REFLEN + 1], new_path[FN_REFLEN + 1], arc_path[FN_REFLEN + 1]; build_table_filename(old_path, sizeof(old_path) - 1, schema, old_name, reg_ext, 0); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a1164ec6448..ab18a2d1d04 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2995,8 +2995,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { if (!(rights & CREATE_ACL)) { - char buf[FN_REFLEN]; - build_table_filename(buf, sizeof(buf), table_list->db, + char buf[FN_REFLEN + 1]; + build_table_filename(buf, sizeof(buf) - 1, table_list->db, table_list->table_name, reg_ext, 0); fn_format(buf, buf, "", "", MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS | MY_RETURN_REAL_PATH | MY_APPEND_EXT); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6b3f75376a3..134b45a9100 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2432,7 +2432,7 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db, bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; int rc; DBUG_ENTER("check_if_table_exists"); @@ -2649,7 +2649,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, real fix will be made after definition cache will be made) */ { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; enum legacy_db_type not_used; build_table_filename(path, sizeof(path) - 1, table_list->db, table_list->table_name, reg_ext, 0); @@ -6340,7 +6340,7 @@ find_field_in_tables(THD *thd, Item_ident *item, (report_error == REPORT_ALL_ERRORS || report_error == REPORT_EXCEPT_NON_UNIQUE)) { - char buff[NAME_LEN*2+1]; + char buff[NAME_LEN*2 + 2]; if (db && db[0]) { strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7f77e60138b..98d17fdd318 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -537,13 +537,13 @@ err1: bool load_db_opt_by_name(THD *thd, const char *db_name, HA_CREATE_INFO *db_create_info) { - char db_opt_path[FN_REFLEN]; + char db_opt_path[FN_REFLEN + 1]; /* Pass an empty file name, and the database options file name as extension to avoid table name to file name encoding. */ - (void) build_table_filename(db_opt_path, sizeof(db_opt_path), + (void) build_table_filename(db_opt_path, sizeof(db_opt_path) - 1, db_name, "", MY_DB_OPT_FILE, 0); return load_db_opt(thd, db_opt_path, db_create_info); @@ -645,7 +645,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /* Check directory */ - path_len= build_table_filename(path, sizeof(path), db, "", "", 0); + path_len= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); path[path_len-1]= 0; // Remove last '/' from path if (my_stat(path,&stat_info,MYF(0))) @@ -791,7 +791,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) We pass MY_DB_OPT_FILE as "extension" to avoid "table name to file name" encoding. */ - build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0); + build_table_filename(path, sizeof(path) - 1, db, "", MY_DB_OPT_FILE, 0); if ((error=write_db_opt(thd, path, create_info))) goto exit; @@ -884,7 +884,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); - length= build_table_filename(path, sizeof(path), db, "", "", 0); + length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); strmov(path+length, MY_DB_OPT_FILE); // Append db option file name del_dbopt(path); // Remove dboption hash entry path[length]= '\0'; // Remove file name @@ -1841,7 +1841,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++) { FILEINFO *file= dirp->dir_entry + idx; - char *extension, tname[FN_REFLEN]; + char *extension, tname[FN_REFLEN + 1]; LEX_STRING table_str; DBUG_PRINT("info",("Examining: %s", file->name)); @@ -1930,7 +1930,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) for (uint idx=0 ; idx < nfiles ; idx++) { FILEINFO *file= dirp->dir_entry + idx; - char oldname[FN_REFLEN], newname[FN_REFLEN]; + char oldname[FN_REFLEN + 1], newname[FN_REFLEN + 1]; DBUG_PRINT("info",("Examining: %s", file->name)); /* skiping . and .. and MY_DB_OPT_FILE */ @@ -2000,10 +2000,10 @@ exit: bool check_db_dir_existence(const char *db_name) { - char db_dir_path[FN_REFLEN]; + char db_dir_path[FN_REFLEN + 1]; uint db_dir_path_len; - db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path), + db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path) - 1, db_name, "", "", 0); if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b20ff78b9ba..677098d275a 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1051,7 +1051,7 @@ static bool mysql_truncate_by_delete(THD *thd, TABLE_LIST *table_list) bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) { HA_CREATE_INFO create_info; - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; TABLE *table; bool error; uint path_length; @@ -1088,7 +1088,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) goto end; } - path_length= build_table_filename(path, sizeof(path), table_list->db, + path_length= build_table_filename(path, sizeof(path) - 1, table_list->db, table_list->table_name, reg_ext, 0); if (!dont_send_ok) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 4a50650b6f4..3713a10997d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5090,7 +5090,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) handler *file= lpt->table->file; DBUG_ENTER("mysql_change_partitions"); - build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied, &lpt->deleted, lpt->pack_frm_data, lpt->pack_frm_len))) @@ -5130,7 +5130,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) int error; DBUG_ENTER("mysql_rename_partitions"); - build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); if ((error= lpt->table->file->ha_rename_partitions(path))) { if (error != 1) @@ -5171,7 +5171,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) int error; DBUG_ENTER("mysql_drop_partitions"); - build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); if ((error= lpt->table->file->ha_drop_partitions(path))) { lpt->table->file->print_error(error, MYF(0)); @@ -5516,10 +5516,10 @@ static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL; - char shadow_path[FN_REFLEN]; + char shadow_path[FN_REFLEN + 1]; DBUG_ENTER("write_log_drop_shadow_frm"); - build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); + build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_replace_delete_frm(lpt, 0UL, NULL, (const char*)shadow_path, FALSE)) @@ -5559,15 +5559,15 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt) partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; - char path[FN_REFLEN]; - char shadow_path[FN_REFLEN]; + char path[FN_REFLEN + 1]; + char shadow_path[FN_REFLEN + 1]; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; DBUG_ENTER("write_log_rename_frm"); part_info->first_log_entry= NULL; - build_table_filename(path, sizeof(path), lpt->db, + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); + build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE)) goto error; @@ -5610,16 +5610,16 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; - char tmp_path[FN_REFLEN]; - char path[FN_REFLEN]; + char tmp_path[FN_REFLEN + 1]; + char path[FN_REFLEN + 1]; uint next_entry= 0; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; DBUG_ENTER("write_log_drop_partition"); part_info->first_log_entry= NULL; - build_table_filename(path, sizeof(path), lpt->db, + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, + build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db, lpt->table_name, "#", 0); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, @@ -5669,14 +5669,14 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL; - char tmp_path[FN_REFLEN]; - char path[FN_REFLEN]; + char tmp_path[FN_REFLEN + 1]; + char path[FN_REFLEN + 1]; uint next_entry= 0; DBUG_ENTER("write_log_add_change_partition"); - build_table_filename(path, sizeof(path), lpt->db, + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, + build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db, lpt->table_name, "#", 0); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, @@ -5723,16 +5723,16 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; - char path[FN_REFLEN]; - char shadow_path[FN_REFLEN]; + char path[FN_REFLEN + 1]; + char shadow_path[FN_REFLEN + 1]; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; uint next_entry= 0; DBUG_ENTER("write_log_final_change_partition"); part_info->first_log_entry= NULL; - build_table_filename(path, sizeof(path), lpt->db, + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); + build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, lpt->alter_info->flags & ALTER_REORGANIZE_PARTITION)) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 7cc9130cc4a..0e0b8eb60b9 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -244,7 +244,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, char *new_table_alias, bool skip_error) { int rc= 1; - char name[FN_REFLEN]; + char name[FN_REFLEN + 1]; const char *new_alias, *old_alias; frm_type_enum frm_type; enum legacy_db_type table_type; @@ -263,14 +263,14 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } DBUG_ASSERT(new_alias); - build_table_filename(name, sizeof(name), + build_table_filename(name, sizeof(name) - 1, new_db, new_alias, reg_ext, 0); if (!access(name,F_OK)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(1); // This can't be skipped } - build_table_filename(name, sizeof(name), + build_table_filename(name, sizeof(name) - 1, ren_table->db, old_alias, reg_ext, 0); frm_type= mysql_frm_type(thd, name, &table_type); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a4fc10002dd..3964e38db5e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2819,8 +2819,8 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals, bool with_i_schema, LEX_STRING *db_name) { - char path[FN_REFLEN]; - build_table_filename(path, sizeof(path), db_name->str, "", "", 0); + char path[FN_REFLEN + 1]; + build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0); if (!lookup_field_vals->wild_table_value && lookup_field_vals->table_value.str) { @@ -2982,8 +2982,8 @@ static int fill_schema_table_names(THD *thd, TABLE *table, else { enum legacy_db_type not_used; - char path[FN_REFLEN]; - (void) build_table_filename(path, sizeof(path), db_name->str, + char path[FN_REFLEN + 1]; + (void) build_table_filename(path, sizeof(path) - 1, db_name->str, table_name->str, reg_ext, 0); switch (mysql_frm_type(thd, path, ¬_used)) { case FRMTYPE_ERROR: @@ -3470,7 +3470,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) MY_STAT stat_info; if (!lookup_field_vals.db_value.str[0]) DBUG_RETURN(0); - path_len= build_table_filename(path, sizeof(path), + path_len= build_table_filename(path, sizeof(path) - 1, lookup_field_vals.db_value.str, "", "", 0); path[path_len-1]= 0; if (!my_stat(path,&stat_info,MYF(0))) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f768659de0e..1c88bef7c5a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1515,7 +1515,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) /* Build shadow frm file name */ - build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); + build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); strxmov(shadow_frm_name, shadow_path, reg_ext, NullS); if (flags & WFRM_WRITE_SHADOW) { @@ -1590,7 +1590,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) /* Build frm file name */ - build_table_filename(path, sizeof(path), lpt->db, + build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); strxmov(frm_name, path, reg_ext, NullS); /* @@ -1792,7 +1792,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN], *alias; + char path[FN_REFLEN + 1], *alias; uint path_length; String wrong_tables; int error= 0; @@ -1922,7 +1922,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, } alias= (lower_case_table_names == 2) ? table->alias : table->table_name; /* remove .frm file and engine files */ - path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext, + path_length= build_table_filename(path, sizeof(path) - 1, db, alias, + reg_ext, table->internal_tmp_table ? FN_IS_TMP : 0); } @@ -2078,11 +2079,11 @@ err_with_placeholders: bool quick_rm_table(handlerton *base,const char *db, const char *table_name, uint flags) { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; bool error= 0; DBUG_ENTER("quick_rm_table"); - uint path_length= build_table_filename(path, sizeof(path), + uint path_length= build_table_filename(path, sizeof(path) - 1, db, table_name, reg_ext, flags); if (my_delete(path,MYF(0))) error= 1; /* purecov: inspected */ @@ -3471,7 +3472,7 @@ bool mysql_create_table_no_lock(THD *thd, bool internal_tmp_table, uint select_field_count) { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; uint path_length; const char *alias; uint db_options, key_count; @@ -3679,7 +3680,7 @@ bool mysql_create_table_no_lock(THD *thd, } else { - path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext, + path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext, internal_tmp_table ? FN_IS_TMP : 0); } @@ -3993,7 +3994,8 @@ mysql_rename_table(handlerton *base, const char *old_db, const char *new_name, uint flags) { THD *thd= current_thd; - char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN]; + char from[FN_REFLEN + 1], to[FN_REFLEN + 1], + lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1]; char *from_base= from, *to_base= to; char tmp_name[NAME_LEN+1]; handler *file; @@ -4005,9 +4007,9 @@ mysql_rename_table(handlerton *base, const char *old_db, file= (base == NULL ? 0 : get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base)); - build_table_filename(from, sizeof(from), old_db, old_name, "", + build_table_filename(from, sizeof(from) - 1, old_db, old_name, "", flags & FN_FROM_IS_TMP); - build_table_filename(to, sizeof(to), new_db, new_name, "", + build_table_filename(to, sizeof(to) - 1, new_db, new_name, "", flags & FN_TO_IS_TMP); /* @@ -4020,13 +4022,13 @@ mysql_rename_table(handlerton *base, const char *old_db, { strmov(tmp_name, old_name); my_casedn_str(files_charset_info, tmp_name); - build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "", + build_table_filename(lc_from, sizeof(lc_from) - 1, old_db, tmp_name, "", flags & FN_FROM_IS_TMP); from_base= lc_from; strmov(tmp_name, new_name); my_casedn_str(files_charset_info, tmp_name); - build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "", + build_table_filename(lc_to, sizeof(lc_to) - 1, new_db, tmp_name, "", flags & FN_TO_IS_TMP); to_base= lc_to; } @@ -4157,16 +4159,16 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, else { char* backup_dir= thd->lex->backup_dir; - char src_path[FN_REFLEN], dst_path[FN_REFLEN], uname[FN_REFLEN]; + char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1], uname[FN_REFLEN]; char* table_name= table->table_name; char* db= table->db; - VOID(tablename_to_filename(table->table_name, uname, sizeof(uname))); + VOID(tablename_to_filename(table->table_name, uname, sizeof(uname) - 1)); if (fn_format_relative_to_data_home(src_path, uname, backup_dir, reg_ext)) DBUG_RETURN(-1); // protect buffer overflow - build_table_filename(dst_path, sizeof(dst_path), + build_table_filename(dst_path, sizeof(dst_path) - 1, db, table_name, reg_ext, 0); if (lock_and_wait_for_table_name(thd,table)) @@ -5088,7 +5090,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, HA_CREATE_INFO *create_info) { TABLE *name_lock= 0; - char src_path[FN_REFLEN], dst_path[FN_REFLEN]; + char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1]; uint dst_path_length; char *db= table->db; char *table_name= table->table_name; @@ -5098,7 +5100,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, #ifdef WITH_PARTITION_STORAGE_ENGINE char tmp_path[FN_REFLEN]; #endif - char ts_name[FN_LEN]; + char ts_name[FN_LEN + 1]; DBUG_ENTER("mysql_create_like_table"); @@ -5147,7 +5149,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, goto err; if (!name_lock) goto table_exists; - dst_path_length= build_table_filename(dst_path, sizeof(dst_path), + dst_path_length= build_table_filename(dst_path, sizeof(dst_path) - 1, db, table_name, reg_ext, 0); if (!access(dst_path, F_OK)) goto table_exists; @@ -5888,7 +5890,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY) { - char *tablespace= static_cast(thd->alloc(FN_LEN)); + char *tablespace= static_cast(thd->alloc(FN_LEN + 1)); /* Regular alter table of disk stored table (no tablespace/storage change) Copy tablespace name @@ -6255,10 +6257,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { TABLE *table, *new_table= 0, *name_lock= 0; int error= 0; - char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; + char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; handlerton *old_db_type, *new_db_type, *save_old_db_type; @@ -6333,8 +6335,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, db=table_list->db; if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) new_db= db; - build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0); - build_table_filename(path, sizeof(path), db, table_name, "", 0); + build_table_filename(reg_path, sizeof(reg_path) - 1, db, table_name, reg_ext, 0); + build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); mysql_ha_rm_tables(thd, table_list, FALSE); @@ -6481,7 +6483,7 @@ view_err: DBUG_RETURN(TRUE); } - build_table_filename(new_name_buff, sizeof(new_name_buff), + build_table_filename(new_name_buff, sizeof(new_name_buff) - 1, new_db, new_name_buff, reg_ext, 0); if (!access(new_name_buff, F_OK)) { @@ -6982,9 +6984,9 @@ view_err: } else { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; /* table is a normal table: Create temporary table in same directory */ - build_table_filename(path, sizeof(path), new_db, tmp_name, "", + build_table_filename(path, sizeof(path) - 1, new_db, tmp_name, "", FN_IS_TMP); /* Open our intermediate table */ new_table=open_temporary_table(thd, path, new_db, tmp_name,0); @@ -7312,7 +7314,7 @@ view_err: */ char path[FN_REFLEN]; TABLE *t_table; - build_table_filename(path, sizeof(path), new_db, table_name, "", 0); + build_table_filename(path + 1, sizeof(path) - 1, new_db, table_name, "", 0); t_table= open_temporary_table(thd, path, new_db, tmp_name, 0); if (t_table) { diff --git a/sql/sql_view.cc b/sql/sql_view.cc index c81a3ca9aba..2a4c5c950fe 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -801,7 +801,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, char md5[MD5_BUFF_LENGTH]; bool can_be_merged; - char dir_buff[FN_REFLEN], path_buff[FN_REFLEN]; + char dir_buff[FN_REFLEN + 1], path_buff[FN_REFLEN + 1]; LEX_STRING dir, file, path; int error= 0; DBUG_ENTER("mysql_register_view"); @@ -878,11 +878,11 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, } loop_out: /* print file name */ - dir.length= build_table_filename(dir_buff, sizeof(dir_buff), + dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1, view->db, "", "", 0); dir.str= dir_buff; - path.length= build_table_filename(path_buff, sizeof(path_buff), + path.length= build_table_filename(path_buff, sizeof(path_buff) - 1, view->db, view->table_name, reg_ext, 0); path.str= path_buff; @@ -1569,7 +1569,7 @@ err: bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { - char path[FN_REFLEN]; + char path[FN_REFLEN + 1]; TABLE_LIST *view; String non_existant_views; char *wrong_object_db= NULL, *wrong_object_name= NULL; @@ -1584,7 +1584,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { TABLE_SHARE *share; frm_type_enum type= FRMTYPE_ERROR; - build_table_filename(path, sizeof(path), + build_table_filename(path, sizeof(path) - 1, view->db, view->table_name, reg_ext, 0); if (access(path, F_OK) || @@ -1929,7 +1929,7 @@ mysql_rename_view(THD *thd, { LEX_STRING pathstr; File_parser *parser; - char path_buff[FN_REFLEN]; + char path_buff[FN_REFLEN + 1]; bool error= TRUE; DBUG_ENTER("mysql_rename_view"); @@ -1942,7 +1942,7 @@ mysql_rename_view(THD *thd, is_equal(&view_type, parser->type())) { TABLE_LIST view_def; - char dir_buff[FN_REFLEN]; + char dir_buff[FN_REFLEN + 1]; LEX_STRING dir, file; /* From 37d2019d1756d630d48ab23ca41f7c595862c7f4 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Fri, 19 Jun 2009 11:27:19 +0200 Subject: [PATCH 102/188] Bug #32223 SETting max_allowed_packet variable Inconsistent behavior of session variable max_allowed_packet (and net_buffer_length); only assignment to the global variable has any effect, without this being obvious to the user. The patch for Bug#22891 is backported to 5.0, making the two session variables read-only. As this is a backport to GA software, the error used when trying to assign to the read- only variable is ER_UNKNOWN_ERROR. The error message is the same as in 5.1+. mysql-test/t/variables.test: Tests are changed to account for the new semantics, and assignment to the read-only variables is added to test the emission of the correct error message. sql/set_var.cc: Both max_allowed_packet and net_buffer_length are changed to be of type sys_var_thd_ulong_session_readonly. ER_UNKNOWN_ERROR is used to indicate an attempt to assign to an instance of a read-only variable. sql/set_var.h: Class sys_var_thd_ulong_session_readonly is added. --- mysql-test/r/func_compress.result | 2 +- mysql-test/r/packet.result | 12 +----------- mysql-test/r/variables.result | 26 ++++++++++++++----------- mysql-test/t/func_compress.test | 4 +++- mysql-test/t/packet.test | 32 ++++++++++++++++--------------- mysql-test/t/variables.test | 21 ++++++++++++-------- sql/set_var.cc | 23 ++++++++++++++++++---- sql/set_var.h | 22 +++++++++++++++++++++ 8 files changed, 91 insertions(+), 51 deletions(-) diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index d8745c38f57..d0689af5bff 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -68,7 +68,7 @@ Warnings: Error 1259 ZLIB: Input data corrupted Error 1256 Uncompressed data size too large; the maximum size is 1048576 (probably, length of uncompressed data was corrupted) drop table t1; -set @@max_allowed_packet=1048576*100; +set @@global.max_allowed_packet=1048576*100; select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null; compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null 0 diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result index 5cc63c4690d..ecbb47d4ee0 100644 --- a/mysql-test/r/packet.result +++ b/mysql-test/r/packet.result @@ -3,32 +3,22 @@ set @net_buffer_length=@@global.net_buffer_length; set global max_allowed_packet=100; Warnings: Warning 1292 Truncated incorrect max_allowed_packet value: '100' -set max_allowed_packet=100; -Warnings: -Warning 1292 Truncated incorrect max_allowed_packet value: '100' set global net_buffer_length=100; Warnings: Warning 1292 Truncated incorrect net_buffer_length value: '100' -set net_buffer_length=100; -Warnings: -Warning 1292 Truncated incorrect net_buffer_length value: '100' SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; len 1024 select repeat('a',2000); repeat('a',2000) -NULL -Warnings: -Warning 1301 Result of repeat() was larger than max_allowed_packet (1024) - truncated +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa select @@net_buffer_length, @@max_allowed_packet; @@net_buffer_length @@max_allowed_packet 1024 1024 SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; ERROR 08S01: Got a packet bigger than 'max_allowed_packet' bytes set global max_allowed_packet=default; -set max_allowed_packet=default; set global net_buffer_length=default; -set net_buffer_length=default; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; len 100 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index fbec38c9a9f..496f0b69fb8 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -187,7 +187,7 @@ Variable_name Value myisam_max_sort_file_size FILE_SIZE set global net_retry_count=10, session net_retry_count=10; set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300; -set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600; +set session net_write_timeout=500, net_read_timeout=600; show global variables like 'net_%'; Variable_name Value net_buffer_length 1024 @@ -196,35 +196,39 @@ net_retry_count 10 net_write_timeout 200 show session variables like 'net_%'; Variable_name Value -net_buffer_length 2048 +net_buffer_length 16384 net_read_timeout 600 net_retry_count 10 net_write_timeout 500 -set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000; +set global net_buffer_length=8000, net_read_timeout=900, net_write_timeout=1000; show global variables like 'net_%'; Variable_name Value -net_buffer_length 1024 +net_buffer_length 7168 net_read_timeout 900 net_retry_count 10 net_write_timeout 1000 show session variables like 'net_%'; Variable_name Value -net_buffer_length 7168 +net_buffer_length 16384 net_read_timeout 600 net_retry_count 10 net_write_timeout 500 -set net_buffer_length=1; +set global net_buffer_length=1; Warnings: Warning 1292 Truncated incorrect net_buffer_length value: '1' -show variables like 'net_buffer_length'; +show global variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1024 -set net_buffer_length=2000000000; +set global net_buffer_length=2000000000; Warnings: Warning 1292 Truncated incorrect net_buffer_length value: '2000000000' -show variables like 'net_buffer_length'; +show global variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1048576 +set session net_buffer_length=1024; +ERROR HY000: SESSION variable net_buffer_length is read-only. Use SET GLOBAL net_buffer_length to assign the value +set session max_allowed_packet=1024; +ERROR HY000: SESSION variable max_allowed_packet is read-only. Use SET GLOBAL max_allowed_packet to assign the value set character set cp1251_koi8; show variables like "character_set_client"; Variable_name Value @@ -393,7 +397,7 @@ set last_insert_id=1; set global local_infile=1; set long_query_time=100; set low_priority_updates=1; -set max_allowed_packet=100; +set global max_allowed_packet=100; Warnings: Warning 1292 Truncated incorrect max_allowed_packet value: '100' set global max_binlog_cache_size=100; @@ -417,7 +421,7 @@ select @@max_user_connections; 100 set global max_write_lock_count=100; set myisam_sort_buffer_size=100; -set net_buffer_length=100; +set global net_buffer_length=100; Warnings: Warning 1292 Truncated incorrect net_buffer_length value: '100' set net_read_timeout=100; diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index c84f22c5595..2ee222c6a10 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -43,8 +43,10 @@ drop table t1; # note that when LOW_MEMORY is set the "test" below is meaningless # -set @@max_allowed_packet=1048576*100; +set @@global.max_allowed_packet=1048576*100; --replace_result "''" XXX "'1'" XXX +# reconnect to make the new max packet size take effect +--connect (newconn, localhost, root,,) eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null; # diff --git a/mysql-test/t/packet.test b/mysql-test/t/packet.test index 6210e9986ad..7e08a0f6c3f 100644 --- a/mysql-test/t/packet.test +++ b/mysql-test/t/packet.test @@ -15,31 +15,33 @@ set @max_allowed_packet=@@global.max_allowed_packet; set @net_buffer_length=@@global.net_buffer_length; + +# setting values below minimum threshold of 1024 will cause truncating +set global max_allowed_packet=100; +set global net_buffer_length=100; + +# is not yet in effect +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +select repeat('a',2000); + +# +# Connection 1 should get error for too big packets +# connect (con1,localhost,root,,); connection con1; -set global max_allowed_packet=100; -set max_allowed_packet=100; -set global net_buffer_length=100; -set net_buffer_length=100; -# Have to be > 1024 as min value of net_buffer_length is 1024 +select @@net_buffer_length, @@max_allowed_packet; +--error ER_NET_PACKET_TOO_LARGE SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; -# Should return NULL as 2000 is bigger than max_allowed_packet -select repeat('a',2000); connection default; disconnect con1; # -# Connection 2 should get error for too big packets +# Reset to default values and reconnect # +set global max_allowed_packet=default; +set global net_buffer_length=default; connect (con2,localhost,root,,); connection con2; -select @@net_buffer_length, @@max_allowed_packet; ---error ER_NET_PACKET_TOO_LARGE -SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; -set global max_allowed_packet=default; -set max_allowed_packet=default; -set global net_buffer_length=default; -set net_buffer_length=default; SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; select length(repeat('a',2000)); connection default; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 424776dfda4..91f75cf6cd4 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -131,17 +131,22 @@ show global variables like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300; -set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600; +set session net_write_timeout=500, net_read_timeout=600; show global variables like 'net_%'; show session variables like 'net_%'; -set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000; +set global net_buffer_length=8000, net_read_timeout=900, net_write_timeout=1000; show global variables like 'net_%'; show session variables like 'net_%'; -set net_buffer_length=1; -show variables like 'net_buffer_length'; +set global net_buffer_length=1; +show global variables like 'net_buffer_length'; #warning 1292 -set net_buffer_length=2000000000; -show variables like 'net_buffer_length'; +set global net_buffer_length=2000000000; +show global variables like 'net_buffer_length'; + +--error ER_UNKNOWN_ERROR +set session net_buffer_length=1024; +--error ER_UNKNOWN_ERROR +set session max_allowed_packet=1024; set character set cp1251_koi8; show variables like "character_set_client"; @@ -272,7 +277,7 @@ set last_insert_id=1; set global local_infile=1; set long_query_time=100; set low_priority_updates=1; -set max_allowed_packet=100; +set global max_allowed_packet=100; set global max_binlog_cache_size=100; set global max_binlog_size=100; set global max_connect_errors=100; @@ -286,7 +291,7 @@ set global max_user_connections=100; select @@max_user_connections; set global max_write_lock_count=100; set myisam_sort_buffer_size=100; -set net_buffer_length=100; +set global net_buffer_length=100; set net_read_timeout=100; set net_write_timeout=100; set global query_cache_limit=100; diff --git a/sql/set_var.cc b/sql/set_var.cc index 7a85c1c0fa3..aebebb3b465 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -228,8 +228,8 @@ sys_var_thd_bool sys_sql_low_priority_updates("sql_low_priority_updates", &SV::low_priority_updates, fix_low_priority_updates); #endif -sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet", - &SV::max_allowed_packet); +sys_var_thd_ulong_session_readonly sys_max_allowed_packet("max_allowed_packet", + &SV::max_allowed_packet); sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size", &max_binlog_cache_size); sys_var_long_ptr sys_max_binlog_size("max_binlog_size", @@ -296,8 +296,8 @@ sys_var_thd_enum sys_myisam_stats_method("myisam_stats_method", &myisam_stats_method_typelib, NULL); -sys_var_thd_ulong sys_net_buffer_length("net_buffer_length", - &SV::net_buffer_length); +sys_var_thd_ulong_session_readonly sys_net_buffer_length("net_buffer_length", + &SV::net_buffer_length); sys_var_thd_ulong sys_net_read_timeout("net_read_timeout", &SV::net_read_timeout, 0, fix_net_read_timeout); @@ -2948,6 +2948,21 @@ byte *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type, } +bool sys_var_thd_ulong_session_readonly::check(THD *thd, set_var *var) +{ + if (var->type != OPT_GLOBAL) + { + /* Due to backporting, this is actually ER_VARIABLE_IS_READONLY in 5.1+ */ + my_printf_error(ER_UNKNOWN_ERROR, + "SESSION variable %s is read-only. Use SET GLOBAL %s " + "to assign the value", MYF(0), name, name); + return TRUE; + } + + return sys_var_thd_ulong::check(thd, var); +} + + bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var) { MY_LOCALE *locale_match; diff --git a/sql/set_var.h b/sql/set_var.h index f43d3b75cee..5fb883e8b86 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -873,6 +873,28 @@ public: byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; + +/** + * @brief This is a specialization of sys_var_thd_ulong that implements a + read-only session variable. The class overrides check() and check_default() + to achieve the read-only property for the session part of the variable. + */ +class sys_var_thd_ulong_session_readonly : public sys_var_thd_ulong +{ +public: + sys_var_thd_ulong_session_readonly(const char *name_arg, ulong SV::*offset_arg, + sys_check_func c_func= NULL, + sys_after_update_func au_func= NULL): + sys_var_thd_ulong(name_arg, offset_arg, c_func, au_func) + { } + bool check(THD *thd, set_var *var); + bool check_default(enum_var_type type) + { + return type != OPT_GLOBAL || !option_limits; + } +}; + + class sys_var_trust_routine_creators :public sys_var_bool_ptr { /* We need a derived class only to have a warn_deprecated() */ From 18bd3cd5f370a8e9579e6947f94922de08b99711 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Fri, 19 Jun 2009 12:27:24 +0100 Subject: [PATCH 103/188] Post-fix for BUG#43929. --- mysql-test/include/commit.inc | 2 +- mysql-test/r/commit_1innodb.result | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index 5ff9d409e27..d412eae8364 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -669,7 +669,7 @@ call p_verify_status_increment(1, 0, 1, 0); insert t1 set a=3; call p_verify_status_increment(2, 2, 2, 2); savepoint a; -call p_verify_status_increment(1, 0, 0, 0); +call p_verify_status_increment(1, 0, 1, 0); insert t1 set a=4; call p_verify_status_increment(2, 2, 2, 2); release savepoint a; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index 5f300468499..cabd4c29c1d 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -766,7 +766,7 @@ call p_verify_status_increment(2, 2, 2, 2); SUCCESS savepoint a; -call p_verify_status_increment(1, 0, 0, 0); +call p_verify_status_increment(1, 0, 1, 0); SUCCESS insert t1 set a=4; From 336c81061872bd5610670edd5595bf7ac1e41fad Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Fri, 19 Jun 2009 17:29:21 +0530 Subject: [PATCH 104/188] Bug#43572 Handle failures from hash_init Failure to allocate memory for the hash->array element, caused hash_init to return without initializing the other members of the hash. Thus although the dynamic array buffer may be allocated at a later point in the code, the incompletely initialized hash caused fatal failures. This patch moves the initialization of the other members of the hash above the array allocation, so that the usage of this hash will not result in fatal failures. include/hash.h: Bug#43572 Handle failures from hash_init hash_inited is used to verify that the hash is valid. After the change induced by the current patch hash->array.buffer !=0 is not a valid check for this condition, since, the dynamic array can be allocated even at a later time. Bootstrap SQL script is setting some variables, which are actually not set due to this hash_inited issue. Thus we get empty grant tables. A better way to check if the hash is valid is to verify that hash->blength is greater than 0. mysys/hash.c: Bug#43572 Handle failures from hash_init Move the initialization of the other members of the hash above the array allocation, so that the usage of this hash will not result in fatal failures. --- include/hash.h | 2 +- mysys/hash.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/include/hash.h b/include/hash.h index 97e947d7c6a..56b54a15a8c 100644 --- a/include/hash.h +++ b/include/hash.h @@ -63,7 +63,7 @@ void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row); my_bool hash_check(HASH *hash); /* Only in debug library */ #define hash_clear(H) bzero((char*) (H),sizeof(*(H))) -#define hash_inited(H) ((H)->array.buffer != 0) +#define hash_inited(H) ((H)->blength != 0) #define hash_init_opt(A,B,C,D,E,F,G,H) \ (!hash_inited(A) && _hash_init(A,B,C,D,E,F,G, H CALLER_INFO)) diff --git a/mysys/hash.c b/mysys/hash.c index 9e8404248eb..4aab75609f4 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -45,6 +45,32 @@ static uint calc_hash(const HASH *hash, const byte *key, uint length) return nr1; } +/** + @brief Initialize the hash + + @details + + Initialize the hash, by defining and giving valid values for + its elements. The failure to allocate memory for the + hash->array element will not result in a fatal failure. The + dynamic array that is part of the hash will allocate memory + as required during insertion. + + @param[in,out] hash The hash that is initialized + @param[in] charset The charater set information + @param[in] size The hash size + @param[in] key_offest The key offset for the hash + @param[in] key_length The length of the key used in + the hash + @param[in] get_key get the key for the hash + @param[in] free_element pointer to the function that + does cleanup + @param[in] CALLER_INFO_PROTO flag that define the behaviour + of the hash + @return inidicates success or failure of initialization + @retval 0 success + @retval 1 failure +*/ my_bool _hash_init(HASH *hash,CHARSET_INFO *charset, uint size,uint key_offset,uint key_length, @@ -55,11 +81,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, DBUG_PRINT("enter",("hash: 0x%lx size: %d", (long) hash, size)); hash->records=0; - if (my_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0)) - { - hash->free=0; /* Allow call to hash_free */ - DBUG_RETURN(1); - } hash->key_offset=key_offset; hash->key_length=key_length; hash->blength=1; @@ -67,7 +88,8 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, hash->free=free_element; hash->flags=flags; hash->charset=charset; - DBUG_RETURN(0); + DBUG_RETURN(my_init_dynamic_array_ci(&hash->array, + sizeof(HASH_LINK), size, 0)); } @@ -113,6 +135,7 @@ void hash_free(HASH *hash) hash_free_elements(hash); hash->free= 0; delete_dynamic(&hash->array); + hash->blength= 0; DBUG_VOID_RETURN; } From 014e28912587d19038549e18097feb0efa4489dc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 19 Jun 2009 15:52:20 +0300 Subject: [PATCH 105/188] Bug #36654: mysqld_multi cannot start instances with different versions occasionally. mysql_multi can call mysqld_safe. In doing this it's not changing the current working directory. This may cause confusion in the case where mysqld_multi is handling instances of servers of different versions and the current working directory is the installation directory of one of these servers. Fixed by enhancing the meaning of basedir in [mysqldN] sections of mysqld_multi. If specified, mysqld_multi will change the current working directory to the basedir directory before starting the server in mysqld_multi ... start ... and then change it back to what it was. scripts/mysqld_multi.sh: Bug #36654: optionally preserve, change and restore the cwd when starting server instances --- scripts/mysqld_multi.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 3cb4665eb1c..a6330055f99 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -1,7 +1,7 @@ #!/usr/bin/perl use Getopt::Long; -use POSIX qw(strftime); +use POSIX qw(strftime getcwd); $|=1; $VER="2.16"; @@ -295,6 +295,7 @@ sub start_mysqlds() { @options = defaults_for_group($groups[$i]); + $basedir_found= 0; # The default $mysqld_found= 1; # The default $mysqld_found= 0 if (!length($mysqld)); $com= "$mysqld"; @@ -310,6 +311,14 @@ sub start_mysqlds() $com= $options[$j]; $mysqld_found= 1; } + elsif ("--basedir=" eq substr($options[$j], 0, 10)) + { + $basedir= $options[$j]; + $basedir =~ s/^--basedir=//; + $basedir_found= 1; + $options[$j]= quote_shell_word($options[$j]); + $tmp.= " $options[$j]"; + } else { $options[$j]= quote_shell_word($options[$j]); @@ -337,7 +346,16 @@ sub start_mysqlds() print "group [$groups[$i]] separately.\n"; exit(1); } + if ($basedir_found) + { + $curdir=getcwd(); + chdir($basedir) or die "Can't change to datadir $basedir"; + } system($com); + if ($basedir_found) + { + chdir($curdir) or die "Can't change back to original dir $curdir"; + } } if (!$i && !$opt_no_log) { From 59730d8fceaede7115bf9e3ac8df5821b8fbffee Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Fri, 19 Jun 2009 17:04:25 +0200 Subject: [PATCH 106/188] Fix for Bug#40545, Bug#40209, Bug#40618, Bug#38346 Details: - Limit the queries to character sets and collations which are most probably available in all build types. But try to preserve the intention of the tests. - Remove the variants adjusted to some build types. Note: 1. The results of the review by Bar are included. 2. I am not able to check the correctness of this patch on any existing build type and any MySQL version. So it could happen that the new test fails somewhere. --- .../suite/funcs_1/r/charset_collation.result | 40 +++ .../funcs_1/r/charset_collation_1.result | 309 ----------------- .../funcs_1/r/charset_collation_2.result | 311 ------------------ .../funcs_1/r/charset_collation_3.result | 309 ----------------- .../charset_collation.test} | 91 ++--- .../suite/funcs_1/t/charset_collation_1.test | 32 -- .../suite/funcs_1/t/charset_collation_2.test | 24 -- .../suite/funcs_1/t/charset_collation_3.test | 25 -- 8 files changed, 72 insertions(+), 1069 deletions(-) create mode 100644 mysql-test/suite/funcs_1/r/charset_collation.result delete mode 100644 mysql-test/suite/funcs_1/r/charset_collation_1.result delete mode 100644 mysql-test/suite/funcs_1/r/charset_collation_2.result delete mode 100644 mysql-test/suite/funcs_1/r/charset_collation_3.result rename mysql-test/suite/funcs_1/{datadict/charset_collation.inc => t/charset_collation.test} (54%) delete mode 100644 mysql-test/suite/funcs_1/t/charset_collation_1.test delete mode 100644 mysql-test/suite/funcs_1/t/charset_collation_2.test delete mode 100644 mysql-test/suite/funcs_1/t/charset_collation_3.test diff --git a/mysql-test/suite/funcs_1/r/charset_collation.result b/mysql-test/suite/funcs_1/r/charset_collation.result new file mode 100644 index 00000000000..b3183ba48e1 --- /dev/null +++ b/mysql-test/suite/funcs_1/r/charset_collation.result @@ -0,0 +1,40 @@ +DROP USER dbdict_test@localhost; +CREATE USER dbdict_test@localhost; +# Establish connection con (user=dbdict_test) + +SELECT * +FROM information_schema.character_sets +WHERE character_set_name IN ('utf8','latin1','binary') +ORDER BY character_set_name; +CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN +binary binary Binary pseudo charset 1 +latin1 latin1_swedish_ci cp1252 West European 1 +utf8 utf8_general_ci UTF-8 Unicode 3 + +SELECT * +FROM information_schema.collations +WHERE character_set_name IN ('utf8','latin1','binary') +AND (collation_name LIKE CONCAT(character_set_name,'_general_ci') +OR +collation_name LIKE CONCAT(character_set_name,'_bin')) +ORDER BY collation_name; +COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN +latin1_bin latin1 47 Yes 1 +latin1_general_ci latin1 48 Yes 1 +utf8_bin utf8 83 Yes 1 +utf8_general_ci utf8 33 Yes Yes 1 + +SELECT * +FROM information_schema.collation_character_set_applicability +WHERE character_set_name IN ('utf8','latin1','binary') +AND (collation_name LIKE CONCAT(character_set_name,'_general_ci') +OR +collation_name LIKE CONCAT(character_set_name,'_bin')) +ORDER BY collation_name, character_set_name; +COLLATION_NAME CHARACTER_SET_NAME +latin1_bin latin1 +latin1_general_ci latin1 +utf8_bin utf8 +utf8_general_ci utf8 +# Switch to connection default + disconnect con +DROP USER dbdict_test@localhost; diff --git a/mysql-test/suite/funcs_1/r/charset_collation_1.result b/mysql-test/suite/funcs_1/r/charset_collation_1.result deleted file mode 100644 index d397c671321..00000000000 --- a/mysql-test/suite/funcs_1/r/charset_collation_1.result +++ /dev/null @@ -1,309 +0,0 @@ -DROP USER dbdict_test@localhost; -CREATE USER dbdict_test@localhost; -# Establish connection con (user=dbdict_test) - -SELECT * -FROM information_schema.character_sets -ORDER BY character_set_name; -CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN -armscii8 armscii8_general_ci ARMSCII-8 Armenian 1 -ascii ascii_general_ci US ASCII 1 -big5 big5_chinese_ci Big5 Traditional Chinese 2 -binary binary Binary pseudo charset 1 -cp1250 cp1250_general_ci Windows Central European 1 -cp1251 cp1251_general_ci Windows Cyrillic 1 -cp1256 cp1256_general_ci Windows Arabic 1 -cp1257 cp1257_general_ci Windows Baltic 1 -cp850 cp850_general_ci DOS West European 1 -cp852 cp852_general_ci DOS Central European 1 -cp866 cp866_general_ci DOS Russian 1 -cp932 cp932_japanese_ci SJIS for Windows Japanese 2 -dec8 dec8_swedish_ci DEC West European 1 -eucjpms eucjpms_japanese_ci UJIS for Windows Japanese 3 -euckr euckr_korean_ci EUC-KR Korean 2 -gb2312 gb2312_chinese_ci GB2312 Simplified Chinese 2 -gbk gbk_chinese_ci GBK Simplified Chinese 2 -geostd8 geostd8_general_ci GEOSTD8 Georgian 1 -greek greek_general_ci ISO 8859-7 Greek 1 -hebrew hebrew_general_ci ISO 8859-8 Hebrew 1 -hp8 hp8_english_ci HP West European 1 -keybcs2 keybcs2_general_ci DOS Kamenicky Czech-Slovak 1 -koi8r koi8r_general_ci KOI8-R Relcom Russian 1 -koi8u koi8u_general_ci KOI8-U Ukrainian 1 -latin1 latin1_swedish_ci cp1252 West European 1 -latin2 latin2_general_ci ISO 8859-2 Central European 1 -latin5 latin5_turkish_ci ISO 8859-9 Turkish 1 -latin7 latin7_general_ci ISO 8859-13 Baltic 1 -macce macce_general_ci Mac Central European 1 -macroman macroman_general_ci Mac West European 1 -sjis sjis_japanese_ci Shift-JIS Japanese 2 -swe7 swe7_swedish_ci 7bit Swedish 1 -tis620 tis620_thai_ci TIS620 Thai 1 -ucs2 ucs2_general_ci UCS-2 Unicode 2 -ujis ujis_japanese_ci EUC-JP Japanese 3 -utf8 utf8_general_ci UTF-8 Unicode 3 - -SELECT * -FROM information_schema.collations -ORDER BY collation_name; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN -armscii8_bin armscii8 64 0 -armscii8_general_ci armscii8 32 Yes 0 -ascii_bin ascii 65 0 -ascii_general_ci ascii 11 Yes 0 -big5_bin big5 84 Yes 1 -big5_chinese_ci big5 1 Yes Yes 1 -binary binary 63 Yes Yes 1 -cp1250_bin cp1250 66 Yes 1 -cp1250_croatian_ci cp1250 44 Yes 1 -cp1250_czech_cs cp1250 34 Yes 2 -cp1250_general_ci cp1250 26 Yes Yes 1 -cp1251_bin cp1251 50 0 -cp1251_bulgarian_ci cp1251 14 0 -cp1251_general_ci cp1251 51 Yes 0 -cp1251_general_cs cp1251 52 0 -cp1251_ukrainian_ci cp1251 23 0 -cp1256_bin cp1256 67 0 -cp1256_general_ci cp1256 57 Yes 0 -cp1257_bin cp1257 58 0 -cp1257_general_ci cp1257 59 Yes 0 -cp1257_lithuanian_ci cp1257 29 0 -cp850_bin cp850 80 0 -cp850_general_ci cp850 4 Yes 0 -cp852_bin cp852 81 0 -cp852_general_ci cp852 40 Yes 0 -cp866_bin cp866 68 0 -cp866_general_ci cp866 36 Yes 0 -cp932_bin cp932 96 Yes 1 -cp932_japanese_ci cp932 95 Yes Yes 1 -dec8_bin dec8 69 0 -dec8_swedish_ci dec8 3 Yes 0 -eucjpms_bin eucjpms 98 Yes 1 -eucjpms_japanese_ci eucjpms 97 Yes Yes 1 -euckr_bin euckr 85 Yes 1 -euckr_korean_ci euckr 19 Yes Yes 1 -gb2312_bin gb2312 86 Yes 1 -gb2312_chinese_ci gb2312 24 Yes Yes 1 -gbk_bin gbk 87 Yes 1 -gbk_chinese_ci gbk 28 Yes Yes 1 -geostd8_bin geostd8 93 0 -geostd8_general_ci geostd8 92 Yes 0 -greek_bin greek 70 0 -greek_general_ci greek 25 Yes 0 -hebrew_bin hebrew 71 0 -hebrew_general_ci hebrew 16 Yes 0 -hp8_bin hp8 72 0 -hp8_english_ci hp8 6 Yes 0 -keybcs2_bin keybcs2 73 0 -keybcs2_general_ci keybcs2 37 Yes 0 -koi8r_bin koi8r 74 0 -koi8r_general_ci koi8r 7 Yes 0 -koi8u_bin koi8u 75 0 -koi8u_general_ci koi8u 22 Yes 0 -latin1_bin latin1 47 Yes 1 -latin1_danish_ci latin1 15 Yes 1 -latin1_general_ci latin1 48 Yes 1 -latin1_general_cs latin1 49 Yes 1 -latin1_german1_ci latin1 5 Yes 1 -latin1_german2_ci latin1 31 Yes 2 -latin1_spanish_ci latin1 94 Yes 1 -latin1_swedish_ci latin1 8 Yes Yes 1 -latin2_bin latin2 77 Yes 1 -latin2_croatian_ci latin2 27 Yes 1 -latin2_czech_cs latin2 2 Yes 4 -latin2_general_ci latin2 9 Yes Yes 1 -latin2_hungarian_ci latin2 21 Yes 1 -latin5_bin latin5 78 0 -latin5_turkish_ci latin5 30 Yes 0 -latin7_bin latin7 79 0 -latin7_estonian_cs latin7 20 0 -latin7_general_ci latin7 41 Yes 0 -latin7_general_cs latin7 42 0 -macce_bin macce 43 0 -macce_general_ci macce 38 Yes 0 -macroman_bin macroman 53 0 -macroman_general_ci macroman 39 Yes 0 -sjis_bin sjis 88 Yes 1 -sjis_japanese_ci sjis 13 Yes Yes 1 -swe7_bin swe7 82 0 -swe7_swedish_ci swe7 10 Yes 0 -tis620_bin tis620 89 Yes 1 -tis620_thai_ci tis620 18 Yes Yes 4 -ucs2_bin ucs2 90 Yes 1 -ucs2_czech_ci ucs2 138 Yes 8 -ucs2_danish_ci ucs2 139 Yes 8 -ucs2_esperanto_ci ucs2 145 Yes 8 -ucs2_estonian_ci ucs2 134 Yes 8 -ucs2_general_ci ucs2 35 Yes Yes 1 -ucs2_hungarian_ci ucs2 146 Yes 8 -ucs2_icelandic_ci ucs2 129 Yes 8 -ucs2_latvian_ci ucs2 130 Yes 8 -ucs2_lithuanian_ci ucs2 140 Yes 8 -ucs2_persian_ci ucs2 144 Yes 8 -ucs2_polish_ci ucs2 133 Yes 8 -ucs2_romanian_ci ucs2 131 Yes 8 -ucs2_roman_ci ucs2 143 Yes 8 -ucs2_slovak_ci ucs2 141 Yes 8 -ucs2_slovenian_ci ucs2 132 Yes 8 -ucs2_spanish2_ci ucs2 142 Yes 8 -ucs2_spanish_ci ucs2 135 Yes 8 -ucs2_swedish_ci ucs2 136 Yes 8 -ucs2_turkish_ci ucs2 137 Yes 8 -ucs2_unicode_ci ucs2 128 Yes 8 -ujis_bin ujis 91 Yes 1 -ujis_japanese_ci ujis 12 Yes Yes 1 -utf8_bin utf8 83 Yes 1 -utf8_czech_ci utf8 202 Yes 8 -utf8_danish_ci utf8 203 Yes 8 -utf8_esperanto_ci utf8 209 Yes 8 -utf8_estonian_ci utf8 198 Yes 8 -utf8_general_ci utf8 33 Yes Yes 1 -utf8_hungarian_ci utf8 210 Yes 8 -utf8_icelandic_ci utf8 193 Yes 8 -utf8_latvian_ci utf8 194 Yes 8 -utf8_lithuanian_ci utf8 204 Yes 8 -utf8_persian_ci utf8 208 Yes 8 -utf8_polish_ci utf8 197 Yes 8 -utf8_romanian_ci utf8 195 Yes 8 -utf8_roman_ci utf8 207 Yes 8 -utf8_slovak_ci utf8 205 Yes 8 -utf8_slovenian_ci utf8 196 Yes 8 -utf8_spanish2_ci utf8 206 Yes 8 -utf8_spanish_ci utf8 199 Yes 8 -utf8_swedish_ci utf8 200 Yes 8 -utf8_turkish_ci utf8 201 Yes 8 -utf8_unicode_ci utf8 192 Yes 8 - - -SELECT * -FROM information_schema.collation_character_set_applicability -ORDER BY collation_name, character_set_name; -COLLATION_NAME CHARACTER_SET_NAME -armscii8_bin armscii8 -armscii8_general_ci armscii8 -ascii_bin ascii -ascii_general_ci ascii -big5_bin big5 -big5_chinese_ci big5 -binary binary -cp1250_bin cp1250 -cp1250_croatian_ci cp1250 -cp1250_czech_cs cp1250 -cp1250_general_ci cp1250 -cp1251_bin cp1251 -cp1251_bulgarian_ci cp1251 -cp1251_general_ci cp1251 -cp1251_general_cs cp1251 -cp1251_ukrainian_ci cp1251 -cp1256_bin cp1256 -cp1256_general_ci cp1256 -cp1257_bin cp1257 -cp1257_general_ci cp1257 -cp1257_lithuanian_ci cp1257 -cp850_bin cp850 -cp850_general_ci cp850 -cp852_bin cp852 -cp852_general_ci cp852 -cp866_bin cp866 -cp866_general_ci cp866 -cp932_bin cp932 -cp932_japanese_ci cp932 -dec8_bin dec8 -dec8_swedish_ci dec8 -eucjpms_bin eucjpms -eucjpms_japanese_ci eucjpms -euckr_bin euckr -euckr_korean_ci euckr -gb2312_bin gb2312 -gb2312_chinese_ci gb2312 -gbk_bin gbk -gbk_chinese_ci gbk -geostd8_bin geostd8 -geostd8_general_ci geostd8 -greek_bin greek -greek_general_ci greek -hebrew_bin hebrew -hebrew_general_ci hebrew -hp8_bin hp8 -hp8_english_ci hp8 -keybcs2_bin keybcs2 -keybcs2_general_ci keybcs2 -koi8r_bin koi8r -koi8r_general_ci koi8r -koi8u_bin koi8u -koi8u_general_ci koi8u -latin1_bin latin1 -latin1_danish_ci latin1 -latin1_general_ci latin1 -latin1_general_cs latin1 -latin1_german1_ci latin1 -latin1_german2_ci latin1 -latin1_spanish_ci latin1 -latin1_swedish_ci latin1 -latin2_bin latin2 -latin2_croatian_ci latin2 -latin2_czech_cs latin2 -latin2_general_ci latin2 -latin2_hungarian_ci latin2 -latin5_bin latin5 -latin5_turkish_ci latin5 -latin7_bin latin7 -latin7_estonian_cs latin7 -latin7_general_ci latin7 -latin7_general_cs latin7 -macce_bin macce -macce_general_ci macce -macroman_bin macroman -macroman_general_ci macroman -sjis_bin sjis -sjis_japanese_ci sjis -swe7_bin swe7 -swe7_swedish_ci swe7 -tis620_bin tis620 -tis620_thai_ci tis620 -ucs2_bin ucs2 -ucs2_czech_ci ucs2 -ucs2_danish_ci ucs2 -ucs2_esperanto_ci ucs2 -ucs2_estonian_ci ucs2 -ucs2_general_ci ucs2 -ucs2_hungarian_ci ucs2 -ucs2_icelandic_ci ucs2 -ucs2_latvian_ci ucs2 -ucs2_lithuanian_ci ucs2 -ucs2_persian_ci ucs2 -ucs2_polish_ci ucs2 -ucs2_romanian_ci ucs2 -ucs2_roman_ci ucs2 -ucs2_slovak_ci ucs2 -ucs2_slovenian_ci ucs2 -ucs2_spanish2_ci ucs2 -ucs2_spanish_ci ucs2 -ucs2_swedish_ci ucs2 -ucs2_turkish_ci ucs2 -ucs2_unicode_ci ucs2 -ujis_bin ujis -ujis_japanese_ci ujis -utf8_bin utf8 -utf8_czech_ci utf8 -utf8_danish_ci utf8 -utf8_esperanto_ci utf8 -utf8_estonian_ci utf8 -utf8_general_ci utf8 -utf8_hungarian_ci utf8 -utf8_icelandic_ci utf8 -utf8_latvian_ci utf8 -utf8_lithuanian_ci utf8 -utf8_persian_ci utf8 -utf8_polish_ci utf8 -utf8_romanian_ci utf8 -utf8_roman_ci utf8 -utf8_slovak_ci utf8 -utf8_slovenian_ci utf8 -utf8_spanish2_ci utf8 -utf8_spanish_ci utf8 -utf8_swedish_ci utf8 -utf8_turkish_ci utf8 -utf8_unicode_ci utf8 -# Switch to connection default + disconnect con -DROP USER dbdict_test@localhost; diff --git a/mysql-test/suite/funcs_1/r/charset_collation_2.result b/mysql-test/suite/funcs_1/r/charset_collation_2.result deleted file mode 100644 index 0035da13c56..00000000000 --- a/mysql-test/suite/funcs_1/r/charset_collation_2.result +++ /dev/null @@ -1,311 +0,0 @@ -DROP USER dbdict_test@localhost; -CREATE USER dbdict_test@localhost; -# Establish connection con (user=dbdict_test) - -SELECT * -FROM information_schema.character_sets -ORDER BY character_set_name; -CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN -armscii8 armscii8_general_ci ARMSCII-8 Armenian 1 -ascii ascii_general_ci US ASCII 1 -big5 big5_chinese_ci Big5 Traditional Chinese 2 -binary binary Binary pseudo charset 1 -cp1250 cp1250_general_ci Windows Central European 1 -cp1251 cp1251_general_ci Windows Cyrillic 1 -cp1256 cp1256_general_ci Windows Arabic 1 -cp1257 cp1257_general_ci Windows Baltic 1 -cp850 cp850_general_ci DOS West European 1 -cp852 cp852_general_ci DOS Central European 1 -cp866 cp866_general_ci DOS Russian 1 -cp932 cp932_japanese_ci SJIS for Windows Japanese 2 -dec8 dec8_swedish_ci DEC West European 1 -eucjpms eucjpms_japanese_ci UJIS for Windows Japanese 3 -euckr euckr_korean_ci EUC-KR Korean 2 -gb2312 gb2312_chinese_ci GB2312 Simplified Chinese 2 -gbk gbk_chinese_ci GBK Simplified Chinese 2 -geostd8 geostd8_general_ci GEOSTD8 Georgian 1 -greek greek_general_ci ISO 8859-7 Greek 1 -hebrew hebrew_general_ci ISO 8859-8 Hebrew 1 -hp8 hp8_english_ci HP West European 1 -keybcs2 keybcs2_general_ci DOS Kamenicky Czech-Slovak 1 -koi8r koi8r_general_ci KOI8-R Relcom Russian 1 -koi8u koi8u_general_ci KOI8-U Ukrainian 1 -latin1 latin1_swedish_ci cp1252 West European 1 -latin2 latin2_general_ci ISO 8859-2 Central European 1 -latin5 latin5_turkish_ci ISO 8859-9 Turkish 1 -latin7 latin7_general_ci ISO 8859-13 Baltic 1 -macce macce_general_ci Mac Central European 1 -macroman macroman_general_ci Mac West European 1 -sjis sjis_japanese_ci Shift-JIS Japanese 2 -swe7 swe7_swedish_ci 7bit Swedish 1 -tis620 tis620_thai_ci TIS620 Thai 1 -ucs2 ucs2_general_ci UCS-2 Unicode 2 -ujis ujis_japanese_ci EUC-JP Japanese 3 -utf8 utf8_general_ci UTF-8 Unicode 3 - -SELECT * -FROM information_schema.collations -ORDER BY collation_name; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN -armscii8_bin armscii8 64 0 -armscii8_general_ci armscii8 32 Yes 0 -ascii_bin ascii 65 0 -ascii_general_ci ascii 11 Yes 0 -big5_bin big5 84 Yes 1 -big5_chinese_ci big5 1 Yes Yes 1 -binary binary 63 Yes Yes 1 -cp1250_bin cp1250 66 Yes 1 -cp1250_croatian_ci cp1250 44 Yes 1 -cp1250_czech_cs cp1250 34 Yes 2 -cp1250_general_ci cp1250 26 Yes Yes 1 -cp1251_bin cp1251 50 0 -cp1251_bulgarian_ci cp1251 14 0 -cp1251_general_ci cp1251 51 Yes 0 -cp1251_general_cs cp1251 52 0 -cp1251_ukrainian_ci cp1251 23 0 -cp1256_bin cp1256 67 0 -cp1256_general_ci cp1256 57 Yes 0 -cp1257_bin cp1257 58 0 -cp1257_general_ci cp1257 59 Yes 0 -cp1257_lithuanian_ci cp1257 29 0 -cp850_bin cp850 80 0 -cp850_general_ci cp850 4 Yes 0 -cp852_bin cp852 81 0 -cp852_general_ci cp852 40 Yes 0 -cp866_bin cp866 68 0 -cp866_general_ci cp866 36 Yes 0 -cp932_bin cp932 96 Yes 1 -cp932_japanese_ci cp932 95 Yes Yes 1 -dec8_bin dec8 69 0 -dec8_swedish_ci dec8 3 Yes 0 -eucjpms_bin eucjpms 98 Yes 1 -eucjpms_japanese_ci eucjpms 97 Yes Yes 1 -euckr_bin euckr 85 Yes 1 -euckr_korean_ci euckr 19 Yes Yes 1 -gb2312_bin gb2312 86 Yes 1 -gb2312_chinese_ci gb2312 24 Yes Yes 1 -gbk_bin gbk 87 Yes 1 -gbk_chinese_ci gbk 28 Yes Yes 1 -geostd8_bin geostd8 93 0 -geostd8_general_ci geostd8 92 Yes 0 -greek_bin greek 70 0 -greek_general_ci greek 25 Yes 0 -hebrew_bin hebrew 71 0 -hebrew_general_ci hebrew 16 Yes 0 -hp8_bin hp8 72 0 -hp8_english_ci hp8 6 Yes 0 -keybcs2_bin keybcs2 73 0 -keybcs2_general_ci keybcs2 37 Yes 0 -koi8r_bin koi8r 74 0 -koi8r_general_ci koi8r 7 Yes 0 -koi8u_bin koi8u 75 0 -koi8u_general_ci koi8u 22 Yes 0 -latin1_bin latin1 47 Yes 1 -latin1_danish_ci latin1 15 Yes 1 -latin1_general_ci latin1 48 Yes 1 -latin1_general_cs latin1 49 Yes 1 -latin1_german1_ci latin1 5 Yes 1 -latin1_german2_ci latin1 31 Yes 2 -latin1_spanish_ci latin1 94 Yes 1 -latin1_swedish_ci latin1 8 Yes Yes 1 -latin2_bin latin2 77 Yes 1 -latin2_croatian_ci latin2 27 Yes 1 -latin2_czech_cs latin2 2 Yes 4 -latin2_general_ci latin2 9 Yes Yes 1 -latin2_hungarian_ci latin2 21 Yes 1 -latin5_bin latin5 78 0 -latin5_turkish_ci latin5 30 Yes 0 -latin7_bin latin7 79 0 -latin7_estonian_cs latin7 20 0 -latin7_general_ci latin7 41 Yes 0 -latin7_general_cs latin7 42 0 -macce_bin macce 43 0 -macce_general_ci macce 38 Yes 0 -macroman_bin macroman 53 0 -macroman_general_ci macroman 39 Yes 0 -sjis_bin sjis 88 Yes 1 -sjis_japanese_ci sjis 13 Yes Yes 1 -swe7_bin swe7 82 0 -swe7_swedish_ci swe7 10 Yes 0 -tis620_bin tis620 89 Yes 1 -tis620_thai_ci tis620 18 Yes Yes 4 -ucs2_bin ucs2 90 Yes 1 -ucs2_czech_ci ucs2 138 Yes 8 -ucs2_danish_ci ucs2 139 Yes 8 -ucs2_esperanto_ci ucs2 145 Yes 8 -ucs2_estonian_ci ucs2 134 Yes 8 -ucs2_general_ci ucs2 35 Yes Yes 1 -ucs2_hungarian_ci ucs2 146 Yes 8 -ucs2_icelandic_ci ucs2 129 Yes 8 -ucs2_latvian_ci ucs2 130 Yes 8 -ucs2_lithuanian_ci ucs2 140 Yes 8 -ucs2_persian_ci ucs2 144 Yes 8 -ucs2_polish_ci ucs2 133 Yes 8 -ucs2_romanian_ci ucs2 131 Yes 8 -ucs2_roman_ci ucs2 143 Yes 8 -ucs2_slovak_ci ucs2 141 Yes 8 -ucs2_slovenian_ci ucs2 132 Yes 8 -ucs2_spanish2_ci ucs2 142 Yes 8 -ucs2_spanish_ci ucs2 135 Yes 8 -ucs2_swedish_ci ucs2 136 Yes 8 -ucs2_turkish_ci ucs2 137 Yes 8 -ucs2_unicode_ci ucs2 128 Yes 8 -ujis_bin ujis 91 Yes 1 -ujis_japanese_ci ujis 12 Yes Yes 1 -utf8_bin utf8 83 Yes 1 -utf8_czech_ci utf8 202 Yes 8 -utf8_danish_ci utf8 203 Yes 8 -utf8_esperanto_ci utf8 209 Yes 8 -utf8_estonian_ci utf8 198 Yes 8 -utf8_general_ci utf8 33 Yes Yes 1 -utf8_general_cs utf8 254 Yes 1 -utf8_hungarian_ci utf8 210 Yes 8 -utf8_icelandic_ci utf8 193 Yes 8 -utf8_latvian_ci utf8 194 Yes 8 -utf8_lithuanian_ci utf8 204 Yes 8 -utf8_persian_ci utf8 208 Yes 8 -utf8_polish_ci utf8 197 Yes 8 -utf8_romanian_ci utf8 195 Yes 8 -utf8_roman_ci utf8 207 Yes 8 -utf8_slovak_ci utf8 205 Yes 8 -utf8_slovenian_ci utf8 196 Yes 8 -utf8_spanish2_ci utf8 206 Yes 8 -utf8_spanish_ci utf8 199 Yes 8 -utf8_swedish_ci utf8 200 Yes 8 -utf8_turkish_ci utf8 201 Yes 8 -utf8_unicode_ci utf8 192 Yes 8 - - -SELECT * -FROM information_schema.collation_character_set_applicability -ORDER BY collation_name, character_set_name; -COLLATION_NAME CHARACTER_SET_NAME -armscii8_bin armscii8 -armscii8_general_ci armscii8 -ascii_bin ascii -ascii_general_ci ascii -big5_bin big5 -big5_chinese_ci big5 -binary binary -cp1250_bin cp1250 -cp1250_croatian_ci cp1250 -cp1250_czech_cs cp1250 -cp1250_general_ci cp1250 -cp1251_bin cp1251 -cp1251_bulgarian_ci cp1251 -cp1251_general_ci cp1251 -cp1251_general_cs cp1251 -cp1251_ukrainian_ci cp1251 -cp1256_bin cp1256 -cp1256_general_ci cp1256 -cp1257_bin cp1257 -cp1257_general_ci cp1257 -cp1257_lithuanian_ci cp1257 -cp850_bin cp850 -cp850_general_ci cp850 -cp852_bin cp852 -cp852_general_ci cp852 -cp866_bin cp866 -cp866_general_ci cp866 -cp932_bin cp932 -cp932_japanese_ci cp932 -dec8_bin dec8 -dec8_swedish_ci dec8 -eucjpms_bin eucjpms -eucjpms_japanese_ci eucjpms -euckr_bin euckr -euckr_korean_ci euckr -gb2312_bin gb2312 -gb2312_chinese_ci gb2312 -gbk_bin gbk -gbk_chinese_ci gbk -geostd8_bin geostd8 -geostd8_general_ci geostd8 -greek_bin greek -greek_general_ci greek -hebrew_bin hebrew -hebrew_general_ci hebrew -hp8_bin hp8 -hp8_english_ci hp8 -keybcs2_bin keybcs2 -keybcs2_general_ci keybcs2 -koi8r_bin koi8r -koi8r_general_ci koi8r -koi8u_bin koi8u -koi8u_general_ci koi8u -latin1_bin latin1 -latin1_danish_ci latin1 -latin1_general_ci latin1 -latin1_general_cs latin1 -latin1_german1_ci latin1 -latin1_german2_ci latin1 -latin1_spanish_ci latin1 -latin1_swedish_ci latin1 -latin2_bin latin2 -latin2_croatian_ci latin2 -latin2_czech_cs latin2 -latin2_general_ci latin2 -latin2_hungarian_ci latin2 -latin5_bin latin5 -latin5_turkish_ci latin5 -latin7_bin latin7 -latin7_estonian_cs latin7 -latin7_general_ci latin7 -latin7_general_cs latin7 -macce_bin macce -macce_general_ci macce -macroman_bin macroman -macroman_general_ci macroman -sjis_bin sjis -sjis_japanese_ci sjis -swe7_bin swe7 -swe7_swedish_ci swe7 -tis620_bin tis620 -tis620_thai_ci tis620 -ucs2_bin ucs2 -ucs2_czech_ci ucs2 -ucs2_danish_ci ucs2 -ucs2_esperanto_ci ucs2 -ucs2_estonian_ci ucs2 -ucs2_general_ci ucs2 -ucs2_hungarian_ci ucs2 -ucs2_icelandic_ci ucs2 -ucs2_latvian_ci ucs2 -ucs2_lithuanian_ci ucs2 -ucs2_persian_ci ucs2 -ucs2_polish_ci ucs2 -ucs2_romanian_ci ucs2 -ucs2_roman_ci ucs2 -ucs2_slovak_ci ucs2 -ucs2_slovenian_ci ucs2 -ucs2_spanish2_ci ucs2 -ucs2_spanish_ci ucs2 -ucs2_swedish_ci ucs2 -ucs2_turkish_ci ucs2 -ucs2_unicode_ci ucs2 -ujis_bin ujis -ujis_japanese_ci ujis -utf8_bin utf8 -utf8_czech_ci utf8 -utf8_danish_ci utf8 -utf8_esperanto_ci utf8 -utf8_estonian_ci utf8 -utf8_general_ci utf8 -utf8_general_cs utf8 -utf8_hungarian_ci utf8 -utf8_icelandic_ci utf8 -utf8_latvian_ci utf8 -utf8_lithuanian_ci utf8 -utf8_persian_ci utf8 -utf8_polish_ci utf8 -utf8_romanian_ci utf8 -utf8_roman_ci utf8 -utf8_slovak_ci utf8 -utf8_slovenian_ci utf8 -utf8_spanish2_ci utf8 -utf8_spanish_ci utf8 -utf8_swedish_ci utf8 -utf8_turkish_ci utf8 -utf8_unicode_ci utf8 -# Switch to connection default + disconnect con -DROP USER dbdict_test@localhost; diff --git a/mysql-test/suite/funcs_1/r/charset_collation_3.result b/mysql-test/suite/funcs_1/r/charset_collation_3.result deleted file mode 100644 index b9a2dbe8a98..00000000000 --- a/mysql-test/suite/funcs_1/r/charset_collation_3.result +++ /dev/null @@ -1,309 +0,0 @@ -DROP USER dbdict_test@localhost; -CREATE USER dbdict_test@localhost; -# Establish connection con (user=dbdict_test) - -SELECT * -FROM information_schema.character_sets -ORDER BY character_set_name; -CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN -armscii8 armscii8_general_ci ARMSCII-8 Armenian 1 -ascii ascii_general_ci US ASCII 1 -big5 big5_chinese_ci Big5 Traditional Chinese 2 -binary binary Binary pseudo charset 1 -cp1250 cp1250_general_ci Windows Central European 1 -cp1251 cp1251_general_ci Windows Cyrillic 1 -cp1256 cp1256_general_ci Windows Arabic 1 -cp1257 cp1257_general_ci Windows Baltic 1 -cp850 cp850_general_ci DOS West European 1 -cp852 cp852_general_ci DOS Central European 1 -cp866 cp866_general_ci DOS Russian 1 -cp932 cp932_japanese_ci SJIS for Windows Japanese 2 -dec8 dec8_swedish_ci DEC West European 1 -eucjpms eucjpms_japanese_ci UJIS for Windows Japanese 3 -euckr euckr_korean_ci EUC-KR Korean 2 -gb2312 gb2312_chinese_ci GB2312 Simplified Chinese 2 -gbk gbk_chinese_ci GBK Simplified Chinese 2 -geostd8 geostd8_general_ci GEOSTD8 Georgian 1 -greek greek_general_ci ISO 8859-7 Greek 1 -hebrew hebrew_general_ci ISO 8859-8 Hebrew 1 -hp8 hp8_english_ci HP West European 1 -keybcs2 keybcs2_general_ci DOS Kamenicky Czech-Slovak 1 -koi8r koi8r_general_ci KOI8-R Relcom Russian 1 -koi8u koi8u_general_ci KOI8-U Ukrainian 1 -latin1 latin1_swedish_ci cp1252 West European 1 -latin2 latin2_general_ci ISO 8859-2 Central European 1 -latin5 latin5_turkish_ci ISO 8859-9 Turkish 1 -latin7 latin7_general_ci ISO 8859-13 Baltic 1 -macce macce_general_ci Mac Central European 1 -macroman macroman_general_ci Mac West European 1 -sjis sjis_japanese_ci Shift-JIS Japanese 2 -swe7 swe7_swedish_ci 7bit Swedish 1 -tis620 tis620_thai_ci TIS620 Thai 1 -ucs2 ucs2_general_ci UCS-2 Unicode 2 -ujis ujis_japanese_ci EUC-JP Japanese 3 -utf8 utf8_general_ci UTF-8 Unicode 3 - -SELECT * -FROM information_schema.collations -ORDER BY collation_name; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN -armscii8_bin armscii8 64 Yes 1 -armscii8_general_ci armscii8 32 Yes Yes 1 -ascii_bin ascii 65 Yes 1 -ascii_general_ci ascii 11 Yes Yes 1 -big5_bin big5 84 Yes 1 -big5_chinese_ci big5 1 Yes Yes 1 -binary binary 63 Yes Yes 1 -cp1250_bin cp1250 66 Yes 1 -cp1250_croatian_ci cp1250 44 Yes 1 -cp1250_czech_cs cp1250 34 Yes 2 -cp1250_general_ci cp1250 26 Yes Yes 1 -cp1251_bin cp1251 50 Yes 1 -cp1251_bulgarian_ci cp1251 14 Yes 1 -cp1251_general_ci cp1251 51 Yes Yes 1 -cp1251_general_cs cp1251 52 Yes 1 -cp1251_ukrainian_ci cp1251 23 Yes 1 -cp1256_bin cp1256 67 Yes 1 -cp1256_general_ci cp1256 57 Yes Yes 1 -cp1257_bin cp1257 58 Yes 1 -cp1257_general_ci cp1257 59 Yes Yes 1 -cp1257_lithuanian_ci cp1257 29 Yes 1 -cp850_bin cp850 80 Yes 1 -cp850_general_ci cp850 4 Yes Yes 1 -cp852_bin cp852 81 Yes 1 -cp852_general_ci cp852 40 Yes Yes 1 -cp866_bin cp866 68 Yes 1 -cp866_general_ci cp866 36 Yes Yes 1 -cp932_bin cp932 96 Yes 1 -cp932_japanese_ci cp932 95 Yes Yes 1 -dec8_bin dec8 69 Yes 1 -dec8_swedish_ci dec8 3 Yes Yes 1 -eucjpms_bin eucjpms 98 Yes 1 -eucjpms_japanese_ci eucjpms 97 Yes Yes 1 -euckr_bin euckr 85 Yes 1 -euckr_korean_ci euckr 19 Yes Yes 1 -gb2312_bin gb2312 86 Yes 1 -gb2312_chinese_ci gb2312 24 Yes Yes 1 -gbk_bin gbk 87 Yes 1 -gbk_chinese_ci gbk 28 Yes Yes 1 -geostd8_bin geostd8 93 Yes 1 -geostd8_general_ci geostd8 92 Yes Yes 1 -greek_bin greek 70 Yes 1 -greek_general_ci greek 25 Yes Yes 1 -hebrew_bin hebrew 71 Yes 1 -hebrew_general_ci hebrew 16 Yes Yes 1 -hp8_bin hp8 72 Yes 1 -hp8_english_ci hp8 6 Yes Yes 1 -keybcs2_bin keybcs2 73 Yes 1 -keybcs2_general_ci keybcs2 37 Yes Yes 1 -koi8r_bin koi8r 74 Yes 1 -koi8r_general_ci koi8r 7 Yes Yes 1 -koi8u_bin koi8u 75 Yes 1 -koi8u_general_ci koi8u 22 Yes Yes 1 -latin1_bin latin1 47 Yes 1 -latin1_danish_ci latin1 15 Yes 1 -latin1_general_ci latin1 48 Yes 1 -latin1_general_cs latin1 49 Yes 1 -latin1_german1_ci latin1 5 Yes 1 -latin1_german2_ci latin1 31 Yes 2 -latin1_spanish_ci latin1 94 Yes 1 -latin1_swedish_ci latin1 8 Yes Yes 1 -latin2_bin latin2 77 Yes 1 -latin2_croatian_ci latin2 27 Yes 1 -latin2_czech_cs latin2 2 Yes 4 -latin2_general_ci latin2 9 Yes Yes 1 -latin2_hungarian_ci latin2 21 Yes 1 -latin5_bin latin5 78 Yes 1 -latin5_turkish_ci latin5 30 Yes Yes 1 -latin7_bin latin7 79 Yes 1 -latin7_estonian_cs latin7 20 Yes 1 -latin7_general_ci latin7 41 Yes Yes 1 -latin7_general_cs latin7 42 Yes 1 -macce_bin macce 43 Yes 1 -macce_general_ci macce 38 Yes Yes 1 -macroman_bin macroman 53 Yes 1 -macroman_general_ci macroman 39 Yes Yes 1 -sjis_bin sjis 88 Yes 1 -sjis_japanese_ci sjis 13 Yes Yes 1 -swe7_bin swe7 82 Yes 1 -swe7_swedish_ci swe7 10 Yes Yes 1 -tis620_bin tis620 89 Yes 1 -tis620_thai_ci tis620 18 Yes Yes 4 -ucs2_bin ucs2 90 Yes 1 -ucs2_czech_ci ucs2 138 Yes 8 -ucs2_danish_ci ucs2 139 Yes 8 -ucs2_esperanto_ci ucs2 145 Yes 8 -ucs2_estonian_ci ucs2 134 Yes 8 -ucs2_general_ci ucs2 35 Yes Yes 1 -ucs2_hungarian_ci ucs2 146 Yes 8 -ucs2_icelandic_ci ucs2 129 Yes 8 -ucs2_latvian_ci ucs2 130 Yes 8 -ucs2_lithuanian_ci ucs2 140 Yes 8 -ucs2_persian_ci ucs2 144 Yes 8 -ucs2_polish_ci ucs2 133 Yes 8 -ucs2_romanian_ci ucs2 131 Yes 8 -ucs2_roman_ci ucs2 143 Yes 8 -ucs2_slovak_ci ucs2 141 Yes 8 -ucs2_slovenian_ci ucs2 132 Yes 8 -ucs2_spanish2_ci ucs2 142 Yes 8 -ucs2_spanish_ci ucs2 135 Yes 8 -ucs2_swedish_ci ucs2 136 Yes 8 -ucs2_turkish_ci ucs2 137 Yes 8 -ucs2_unicode_ci ucs2 128 Yes 8 -ujis_bin ujis 91 Yes 1 -ujis_japanese_ci ujis 12 Yes Yes 1 -utf8_bin utf8 83 Yes 1 -utf8_czech_ci utf8 202 Yes 8 -utf8_danish_ci utf8 203 Yes 8 -utf8_esperanto_ci utf8 209 Yes 8 -utf8_estonian_ci utf8 198 Yes 8 -utf8_general_ci utf8 33 Yes Yes 1 -utf8_hungarian_ci utf8 210 Yes 8 -utf8_icelandic_ci utf8 193 Yes 8 -utf8_latvian_ci utf8 194 Yes 8 -utf8_lithuanian_ci utf8 204 Yes 8 -utf8_persian_ci utf8 208 Yes 8 -utf8_polish_ci utf8 197 Yes 8 -utf8_romanian_ci utf8 195 Yes 8 -utf8_roman_ci utf8 207 Yes 8 -utf8_slovak_ci utf8 205 Yes 8 -utf8_slovenian_ci utf8 196 Yes 8 -utf8_spanish2_ci utf8 206 Yes 8 -utf8_spanish_ci utf8 199 Yes 8 -utf8_swedish_ci utf8 200 Yes 8 -utf8_turkish_ci utf8 201 Yes 8 -utf8_unicode_ci utf8 192 Yes 8 - - -SELECT * -FROM information_schema.collation_character_set_applicability -ORDER BY collation_name, character_set_name; -COLLATION_NAME CHARACTER_SET_NAME -armscii8_bin armscii8 -armscii8_general_ci armscii8 -ascii_bin ascii -ascii_general_ci ascii -big5_bin big5 -big5_chinese_ci big5 -binary binary -cp1250_bin cp1250 -cp1250_croatian_ci cp1250 -cp1250_czech_cs cp1250 -cp1250_general_ci cp1250 -cp1251_bin cp1251 -cp1251_bulgarian_ci cp1251 -cp1251_general_ci cp1251 -cp1251_general_cs cp1251 -cp1251_ukrainian_ci cp1251 -cp1256_bin cp1256 -cp1256_general_ci cp1256 -cp1257_bin cp1257 -cp1257_general_ci cp1257 -cp1257_lithuanian_ci cp1257 -cp850_bin cp850 -cp850_general_ci cp850 -cp852_bin cp852 -cp852_general_ci cp852 -cp866_bin cp866 -cp866_general_ci cp866 -cp932_bin cp932 -cp932_japanese_ci cp932 -dec8_bin dec8 -dec8_swedish_ci dec8 -eucjpms_bin eucjpms -eucjpms_japanese_ci eucjpms -euckr_bin euckr -euckr_korean_ci euckr -gb2312_bin gb2312 -gb2312_chinese_ci gb2312 -gbk_bin gbk -gbk_chinese_ci gbk -geostd8_bin geostd8 -geostd8_general_ci geostd8 -greek_bin greek -greek_general_ci greek -hebrew_bin hebrew -hebrew_general_ci hebrew -hp8_bin hp8 -hp8_english_ci hp8 -keybcs2_bin keybcs2 -keybcs2_general_ci keybcs2 -koi8r_bin koi8r -koi8r_general_ci koi8r -koi8u_bin koi8u -koi8u_general_ci koi8u -latin1_bin latin1 -latin1_danish_ci latin1 -latin1_general_ci latin1 -latin1_general_cs latin1 -latin1_german1_ci latin1 -latin1_german2_ci latin1 -latin1_spanish_ci latin1 -latin1_swedish_ci latin1 -latin2_bin latin2 -latin2_croatian_ci latin2 -latin2_czech_cs latin2 -latin2_general_ci latin2 -latin2_hungarian_ci latin2 -latin5_bin latin5 -latin5_turkish_ci latin5 -latin7_bin latin7 -latin7_estonian_cs latin7 -latin7_general_ci latin7 -latin7_general_cs latin7 -macce_bin macce -macce_general_ci macce -macroman_bin macroman -macroman_general_ci macroman -sjis_bin sjis -sjis_japanese_ci sjis -swe7_bin swe7 -swe7_swedish_ci swe7 -tis620_bin tis620 -tis620_thai_ci tis620 -ucs2_bin ucs2 -ucs2_czech_ci ucs2 -ucs2_danish_ci ucs2 -ucs2_esperanto_ci ucs2 -ucs2_estonian_ci ucs2 -ucs2_general_ci ucs2 -ucs2_hungarian_ci ucs2 -ucs2_icelandic_ci ucs2 -ucs2_latvian_ci ucs2 -ucs2_lithuanian_ci ucs2 -ucs2_persian_ci ucs2 -ucs2_polish_ci ucs2 -ucs2_romanian_ci ucs2 -ucs2_roman_ci ucs2 -ucs2_slovak_ci ucs2 -ucs2_slovenian_ci ucs2 -ucs2_spanish2_ci ucs2 -ucs2_spanish_ci ucs2 -ucs2_swedish_ci ucs2 -ucs2_turkish_ci ucs2 -ucs2_unicode_ci ucs2 -ujis_bin ujis -ujis_japanese_ci ujis -utf8_bin utf8 -utf8_czech_ci utf8 -utf8_danish_ci utf8 -utf8_esperanto_ci utf8 -utf8_estonian_ci utf8 -utf8_general_ci utf8 -utf8_hungarian_ci utf8 -utf8_icelandic_ci utf8 -utf8_latvian_ci utf8 -utf8_lithuanian_ci utf8 -utf8_persian_ci utf8 -utf8_polish_ci utf8 -utf8_romanian_ci utf8 -utf8_roman_ci utf8 -utf8_slovak_ci utf8 -utf8_slovenian_ci utf8 -utf8_spanish2_ci utf8 -utf8_spanish_ci utf8 -utf8_swedish_ci utf8 -utf8_turkish_ci utf8 -utf8_unicode_ci utf8 -# Switch to connection default + disconnect con -DROP USER dbdict_test@localhost; diff --git a/mysql-test/suite/funcs_1/datadict/charset_collation.inc b/mysql-test/suite/funcs_1/t/charset_collation.test similarity index 54% rename from mysql-test/suite/funcs_1/datadict/charset_collation.inc rename to mysql-test/suite/funcs_1/t/charset_collation.test index ae03996b073..186eb1f5b85 100644 --- a/mysql-test/suite/funcs_1/datadict/charset_collation.inc +++ b/mysql-test/suite/funcs_1/t/charset_collation.test @@ -1,58 +1,16 @@ -# suite/funcs_1/datadict/charset_collation.inc +# suite/funcs_1/t/charset_collation.test # # Tests checking the content of the information_schema tables # character_sets # collations # collation_character_set_applicability # -# -# The amount and properties of character_sets/collations depend on the -# build type -# 2007-12 MySQL 5.0, 2008-06 MySQL 5.1 -# --------------------------------------------------------------------- -# -# Variant 1 fits to -# version_comment MySQL Enterprise Server (Commercial) -# version_comment MySQL Enterprise Server (GPL) -# version_comment MySQL Classic Server (Commercial) -# version_comment MySQL Pushbuild Edition, build -# (version_comment Source distribution -# and -# compile was without "max" - > no collation 'utf8_general_ci') -# -# Variant 2 fits to -# version_comment MySQL Enterprise Server (GPL) -# version_comment MySQL Classic Server (Commercial) -# version_comment MySQL Pushbuild Edition, build -# (version_comment Source distribution -# and -# compile was without "max" - > collation 'utf8_general_ci' exists) -# -# Difference between variant 1 and 2 is the collation 'utf8_general_ci'. -# -# Variant 3 fits to -# version_comment MySQL Community Server (GPL) -# version_comment MySQL Cluster Server (Commercial) -# version_comment MySQL Advanced Server (GPL) 5.1 -# version_comment MySQL Advanced Server (Commercial) 5.1 -# -# Difference between variant 3 and 2 is within the collation properties -# IS_COMPILED and SORTLEN. -# -# 2008-06 All time excluded variant is "vanilla". -# How to build "vanilla": -# ./BUILD/autorun.sh -# ./configure -# ./make -# Some properties of "vanilla" -# version_comment Source distribution -# Compared to the variants 1 to 3 a lot of character sets are missing. -# Example: "ucs2_bin" is in variant 1 to 3 but not in "vanilla". -# # Created: -# 2007-12-18 mleich - remove the unstable character_set/collation subtests -# from include/datadict-master.inc -# - create this new test +# 2009-04-28 mleich Replace the charset_collation_* test which failed too often +# because of changes +# - in general available character sets and collations +# - in build types +# (Bug#40545, Bug#40209, Bug#40618, Bug#38346) # # Create a low privileged user. @@ -61,7 +19,6 @@ DROP USER dbdict_test@localhost; CREATE USER dbdict_test@localhost; --echo # Establish connection con (user=dbdict_test) ---replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (con,localhost,dbdict_test,,); ################################################################################ # @@ -97,32 +54,48 @@ connect (con,localhost,dbdict_test,,); # combinations for which the current user and PUBLIC have no # USAGE privilege. # -# Notes (2007-12-19 mleich): +# Notes (2009-04-28 mleich): # - The requirements are outdated because grant/revoke privilege for using a # characterset/collation were never implemented. -# Therefore the tests should simply check the content of these tables. -# +# Therefore the tests focus on the completeness and correctness of the +# content (rows and columns) of these tables. # - The amount of collations/character sets grows with new MySQL releases. -# -# - Even within the same release the amount of records within these tables +# Even within the same release the amount of records within these tables # can differ between different build types (community, enterprise, source,...) -# +# Therefore we limit the queries to character sets and collations which +# - exist in all build types +# - have in all build types the same "state". +# The character set +# - utf8 is used for Metadata +# - ascii is a quite usual +# The collations _general_ci and _bin seem +# to be available all time. # ################################################################################ + +let $char_set_condition= character_set_name IN ('utf8','latin1','binary'); +let $collation_condition= + (collation_name LIKE CONCAT(character_set_name,'_general_ci') + OR + collation_name LIKE CONCAT(character_set_name,'_bin')); --echo -SELECT * +eval SELECT * FROM information_schema.character_sets +WHERE $char_set_condition ORDER BY character_set_name; --echo -SELECT * +eval SELECT * FROM information_schema.collations +WHERE $char_set_condition + AND $collation_condition ORDER BY collation_name; -echo; --echo -SELECT * +eval SELECT * FROM information_schema.collation_character_set_applicability +WHERE $char_set_condition + AND $collation_condition ORDER BY collation_name, character_set_name; diff --git a/mysql-test/suite/funcs_1/t/charset_collation_1.test b/mysql-test/suite/funcs_1/t/charset_collation_1.test deleted file mode 100644 index 15777062a72..00000000000 --- a/mysql-test/suite/funcs_1/t/charset_collation_1.test +++ /dev/null @@ -1,32 +0,0 @@ -# Tests checking the content of the information_schema tables -# character_sets -# collations -# collation_character_set_applicability -# -# Content variant 1 which should fit to -# Enterprise or Classic builds (binaries provided by MySQL) -# Pushbuilds -# Source builds without "max" -# -# Please read suite/funcs_1/datadict/charset_collation.inc for -# additional information. -# -# Created: -# 2007-12-18 mleich - remove the unstable character_set/collation subtests -# from include/datadict-master.inc -# - create this new test -# - -if (`SELECT EXISTS (SELECT 1 FROM information_schema.collations - WHERE collation_name = 'utf8_general_cs') - OR ( @@version_comment NOT LIKE '%Source%' - AND @@version_comment NOT LIKE '%Enterprise%' - AND @@version_comment NOT LIKE '%Classic%' - AND @@version_comment NOT LIKE '%Pushbuild%') - OR (SELECT count(*) = 0 FROM information_schema.collations - WHERE collation_name = 'ucs2_bin')`) -{ - skip Test needs Enterprise, Classic , regular Pushbuild or Source-without-max build; -} - ---source suite/funcs_1/datadict/charset_collation.inc diff --git a/mysql-test/suite/funcs_1/t/charset_collation_2.test b/mysql-test/suite/funcs_1/t/charset_collation_2.test deleted file mode 100644 index d4924953b7d..00000000000 --- a/mysql-test/suite/funcs_1/t/charset_collation_2.test +++ /dev/null @@ -1,24 +0,0 @@ -# Tests checking the content of the information_schema tables -# character_sets -# collations -# collation_character_set_applicability -# -# Content variant 2 (compile from source with "max") -# -# Please read suite/funcs_1/datadict/charset_collation.inc for -# additional information. -# -# Created: -# 2007-12-18 mleich - remove the unstable character_set/collation subtests -# from include/datadict-master.inc -# - create this new test -# - -if (`SELECT @@version_comment NOT LIKE '%Source%' - OR NOT EXISTS (SELECT 1 FROM information_schema.collations - WHERE collation_name = 'utf8_general_cs')`) -{ - skip Test needs Source build with "max"; -} - ---source suite/funcs_1/datadict/charset_collation.inc diff --git a/mysql-test/suite/funcs_1/t/charset_collation_3.test b/mysql-test/suite/funcs_1/t/charset_collation_3.test deleted file mode 100644 index e88b44e4a0f..00000000000 --- a/mysql-test/suite/funcs_1/t/charset_collation_3.test +++ /dev/null @@ -1,25 +0,0 @@ -# Tests checking the content of the information_schema tables -# character_sets -# collations -# collation_character_set_applicability -# -# Content variant 3 which should fit to -# Community and Cluster builds (binaries provided by MySQL) -# -# Please read suite/funcs_1/datadict/charset_collation.inc for -# additional information. -# -# Created: -# 2007-12-18 mleich - remove the unstable character_set/collation subtests -# from include/datadict-master.inc -# - create this new test -# - -if (`SELECT @@version_comment NOT LIKE '%Community%' - AND @@version_comment NOT LIKE '%Cluster%' - AND @@version_comment NOT LIKE '%Advanced%'`) -{ - skip Test needs Community, Cluster or Advanced build; -} - ---source suite/funcs_1/datadict/charset_collation.inc From b0064fa5a96502da95132e5e19660057e260f1b5 Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Mon, 22 Jun 2009 16:40:34 +0530 Subject: [PATCH 107/188] Bug#43572 Handle failures from hash_init The merge from http://lists.mysql.com/commits/76678 caused the growth_size parameter to the my_init_dynamic_array function to be ignored. This patch corrects the problem. mysys/hash.c: Bug#43572 Handle failures from hash_init Replacing the last parameter to my_init_dynamic_array with growth_size. --- mysys/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/hash.c b/mysys/hash.c index 2490a6c2019..63933abb085 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -89,7 +89,7 @@ _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, hash->flags=flags; hash->charset=charset; DBUG_RETURN(my_init_dynamic_array_ci(&hash->array, - sizeof(HASH_LINK), size, 0)); + sizeof(HASH_LINK), size, growth_size)); } From 7d0675f613db96ad38af626d6cd504c04501092d Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 22 Jun 2009 16:58:00 +0530 Subject: [PATCH 108/188] Applying InnoDB snashot 5.1-ss5343, Fixes BUG#45357 1. BUG#45357 - 5.1.35 crashes with Failing assertion: index->type & DICT_CLUSTERED 2. Also fixes the compilation problem when the flag -DUNIV_MUST_NOT_INLINE Detailed revision comments: r5340 | marko | 2009-06-17 12:11:49 +0300 (Wed, 17 Jun 2009) | 4 lines branches/5.1: row_unlock_for_mysql(): When the clustered index is unknown, refuse to unlock the record. (Bug #45357, caused by the fix of Bug #39320). rb://132 approved by Sunny Bains. r5339 | marko | 2009-06-17 11:01:37 +0300 (Wed, 17 Jun 2009) | 2 lines branches/5.1: Add missing #include "mtr0log.h" so that the code compiles with -DUNIV_MUST_NOT_INLINE. --- mysql-test/r/innodb_bug45357.result | 7 +++++++ mysql-test/t/innodb_bug45357.test | 10 ++++++++++ storage/innobase/btr/btr0cur.c | 1 + storage/innobase/include/trx0rseg.ic | 1 + storage/innobase/row/row0mysql.c | 9 +++++++-- storage/innobase/trx/trx0rec.c | 1 + 6 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/innodb_bug45357.result create mode 100644 mysql-test/t/innodb_bug45357.test diff --git a/mysql-test/r/innodb_bug45357.result b/mysql-test/r/innodb_bug45357.result new file mode 100644 index 00000000000..7adeff2062f --- /dev/null +++ b/mysql-test/r/innodb_bug45357.result @@ -0,0 +1,7 @@ +set session transaction isolation level read committed; +create table bug45357(a int, b int,key(b))engine=innodb; +insert into bug45357 values (25170,6122); +update bug45357 set a=1 where b=30131; +delete from bug45357 where b < 20996; +delete from bug45357 where b < 7001; +drop table bug45357; diff --git a/mysql-test/t/innodb_bug45357.test b/mysql-test/t/innodb_bug45357.test new file mode 100644 index 00000000000..81727f352dd --- /dev/null +++ b/mysql-test/t/innodb_bug45357.test @@ -0,0 +1,10 @@ +-- source include/have_innodb.inc + +set session transaction isolation level read committed; + +create table bug45357(a int, b int,key(b))engine=innodb; +insert into bug45357 values (25170,6122); +update bug45357 set a=1 where b=30131; +delete from bug45357 where b < 20996; +delete from bug45357 where b < 7001; +drop table bug45357; diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 54acdf73db6..d2a2e4d2157 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -23,6 +23,7 @@ Created 10/16/1994 Heikki Tuuri #include "btr0cur.ic" #endif +#include "mtr0log.h" #include "page0page.h" #include "rem0rec.h" #include "rem0cmp.h" diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic index eb1893587a6..577cd0dee7b 100644 --- a/storage/innobase/include/trx0rseg.ic +++ b/storage/innobase/include/trx0rseg.ic @@ -7,6 +7,7 @@ Created 3/26/1996 Heikki Tuuri *******************************************************/ #include "srv0srv.h" +#include "mtr0log.h" /********************************************************************** Gets a rollback segment header. */ diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 2d9ed4fc944..6ec466cf995 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1529,9 +1529,14 @@ row_unlock_for_mysql( index = btr_pcur_get_btr_cur(clust_pcur)->index; } + if (UNIV_UNLIKELY(!(index->type & DICT_CLUSTERED))) { + /* This is not a clustered index record. We + do not know how to unlock the record. */ + goto no_unlock; + } + /* If the record has been modified by this transaction, do not unlock it. */ - ut_a(index->type & DICT_CLUSTERED); if (index->trx_id_offset) { rec_trx_id = trx_read_trx_id(rec @@ -1568,7 +1573,7 @@ row_unlock_for_mysql( prebuilt->select_lock_type); } } - +no_unlock: mtr_commit(&mtr); } diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index 50f8b011463..38ad53fcfb0 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -23,6 +23,7 @@ Created 3/26/1996 Heikki Tuuri #include "que0que.h" #include "trx0purge.h" #include "row0row.h" +#include "mtr0log.h" /*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/ From ea963c3693c3afea4024cd3e5803c890afee5b37 Mon Sep 17 00:00:00 2001 From: Christoffer Hall Date: Mon, 22 Jun 2009 14:43:19 +0200 Subject: [PATCH 109/188] BUG#42721 configure.in invokes 'nm' directly A hardcoded use of nm and libc was put into configure.in. This broke cross-compiling and is bad practice. Fitting variables now used. --- configure.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index bd26e584bfe..33ac021ec76 100644 --- a/configure.in +++ b/configure.in @@ -603,10 +603,11 @@ AC_SUBST(NOINST_LDFLAGS) # Check if we are using Linux and a glibc compiled with static nss # (this is true on the MySQL build machines to avoid NSS problems) # +AC_CHECK_TOOL([NM], [nm]) if test "$TARGET_LINUX" = "true" -a "$static_nss" = "" then - tmp=`nm /usr/lib*/libc.a | grep _nss_files_getaliasent_r` + tmp=`$NM ${other_libc_lib:-/usr/lib*}/libc.a | grep _nss_files_getaliasent_r1` if test -n "$tmp" then STATIC_NSS_FLAGS="-lc -lnss_files -lnss_dns -lresolv" From 543885d1b1402bea2475ad76161de5a62929e8c2 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Mon, 22 Jun 2009 14:51:33 +0200 Subject: [PATCH 110/188] Bug#44653: Server crash noticed when executing random queries with partitions. When opening a table, it is imperative that the flag TABLE::auto_increment_field_not_null be false. But if an error occured during the creation of a table (e.g. the table exists already) with an auto_increment column and a BEFORE trigger that used the INSERT ... SELECT construct, the flag was not reset until after error checking. Thus if an error occured, select_insert::send_data() returned immediately and it was not reset (see * in pseudocode below). Crash happened if the table was opened again. Fixed by resetting the flag after error checking. nested-loops_join(): for each row in SELECT table { select_insert::send_data(): if a values is supplied for AUTO_INCREMENT column table->auto_increment_field_not_null= TRUE else table->auto_increment_field_not_null= FALSE if (error) return 1; * if (table->auto_increment_field_not_null == FALSE) ... table->auto_increment_field_not_null == FALSE } <-- table returned to table cache and later retrieved by open_table: open_table(): assert(table->auto_increment_field_not_null) mysql-test/r/trigger.result: Bug#44653: Test result mysql-test/t/trigger.test: Bug#44653: Test case sql/sql_insert.cc: Bug#44653: Fix: Make sure to unset this field before returning in case of error --- mysql-test/r/trigger.result | 14 ++++++++++++++ mysql-test/t/trigger.test | 26 ++++++++++++++++++++++++++ sql/sql_insert.cc | 3 +++ 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 23f15f618f2..4476735735c 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -2073,4 +2073,18 @@ select @a, @b; drop trigger trg1; drop trigger trg2; drop table t1, t2; +CREATE TABLE t1 ( a INT, b INT ); +CREATE TABLE t2 ( a INT AUTO_INCREMENT KEY, b INT ); +INSERT INTO t1 (a) VALUES (1); +CREATE TRIGGER tr1 +BEFORE INSERT ON t2 +FOR EACH ROW +BEGIN +UPDATE a_nonextisting_table SET a = 1; +END// +CREATE TABLE IF NOT EXISTS t2 ( a INT, b INT ) SELECT a, b FROM t1; +ERROR 42S02: Table 'test.a_nonextisting_table' doesn't exist +SELECT * FROM t2; +a b +DROP TABLE t1, t2; End of 5.1 tests. diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 9a5556c518d..1e55f9d5993 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2370,4 +2370,30 @@ drop trigger trg1; drop trigger trg2; drop table t1, t2; +# +# Bug#44653: Server crash noticed when executing random queries with partitions. +# +CREATE TABLE t1 ( a INT, b INT ); +CREATE TABLE t2 ( a INT AUTO_INCREMENT KEY, b INT ); + +INSERT INTO t1 (a) VALUES (1); + +delimiter //; +CREATE TRIGGER tr1 +BEFORE INSERT ON t2 +FOR EACH ROW +BEGIN + UPDATE a_nonextisting_table SET a = 1; +END// +delimiter ;// + +--disable_abort_on_error +CREATE TABLE IF NOT EXISTS t2 ( a INT, b INT ) SELECT a, b FROM t1; +--enable_abort_on_error + +# Caused failed assertion +SELECT * FROM t2; + +DROP TABLE t1, t2; + --echo End of 5.1 tests. diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9de27868d74..633dbf67bbc 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3100,7 +3100,10 @@ bool select_insert::send_data(List &values) store_values(values); thd->count_cuted_fields= CHECK_FIELD_IGNORE; if (thd->is_error()) + { + table->auto_increment_field_not_null= FALSE; DBUG_RETURN(1); + } if (table_list) // Not CREATE ... SELECT { switch (table_list->view_check_option(thd, info.ignore)) { From 73cbaa6d17b508e12af1d71b5d07f80f02acfeed Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Tue, 23 Jun 2009 10:15:27 +0400 Subject: [PATCH 111/188] Bug #45309: InnoDB does not rollback for delete and update queries if query was killed Since we rely on thd->is_error() to decide whether we should COMMIT or ROLLBACK after a query execution, check the query 'killed' state and throw an error before calling ha_autocommit_or_rollback(), not after. The patch was tested manually. For reliable results, the test case would have to KILL QUERY while a DELETE/UPDATE query in another thread is still running. I don't see a way to achieve this kind of synchronization in our test suite (no debug_sync in 5.1). sql/sql_parse.cc: Since we rely on thd->is_error() to decide whether we should COMMIT or ROLLBACK after query execution, check the query 'killed' state and throw an error before calling ha_autocommit_or_rollback(), not after. --- sql/sql_parse.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9c621004cc3..c593f563052 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1560,14 +1560,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } - /* If commit fails, we should be able to reset the OK status. */ - thd->main_da.can_overwrite_status= TRUE; - ha_autocommit_or_rollback(thd, thd->is_error()); - thd->main_da.can_overwrite_status= FALSE; - - thd->transaction.stmt.reset(); - - /* report error issued during command execution */ if (thd->killed_errno()) { @@ -1580,6 +1572,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->mysys_var->abort= 0; } + /* If commit fails, we should be able to reset the OK status. */ + thd->main_da.can_overwrite_status= TRUE; + ha_autocommit_or_rollback(thd, thd->is_error()); + thd->main_da.can_overwrite_status= FALSE; + + thd->transaction.stmt.reset(); + net_end_statement(thd); query_cache_end_of_result(thd); From e2ac8c07bdd2e58f5f7b4919a76a0d1881f3ed5e Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 23 Jun 2009 12:10:04 +0300 Subject: [PATCH 112/188] Bug #38240 Crash in safe_mutex_lock () thr_mutex.c line 97 on rotate_relay_log The reason for the crash was rotate_relay_log (mi=0x0) did not verify the passed value of active_mi. There are more cases where active_mi is supposed to be non-zero e.g change_master(), stop_slave(), and it's reasonable to protect from a similar crash all of them with common fixes. Fixed with spliting end_slave() in slave threads release and slave data clean-up parts (a new close_active_mi()). The new function is invoked at the very end of close_connections() so that all users of active_mi are proven to have left. sql/mysqld.cc: added the 2nd part (data) of the slave's clean up. sql/slave.cc: end_slave() is split in two part to release the slave threads and the remained resources separately. The new close_active_mi() should be called after all possible users ofactive_mi has left, i.e at the very end of close_connections(). sql/slave.h: interface to the new end_active_mi() function is added. --- sql/mysqld.cc | 1 + sql/slave.cc | 25 +++++++++++++++++++++---- sql/slave.h | 3 ++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1d18226ab45..f7ee7b025f9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -983,6 +983,7 @@ static void close_connections(void) } (void) pthread_mutex_unlock(&LOCK_thread_count); + close_active_mi(); DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } diff --git a/sql/slave.cc b/sql/slave.cc index 043b0e3fed5..5570a07c02d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -668,7 +668,7 @@ static int end_slave_on_walk(Master_info* mi, uchar* /*unused*/) /* - Free all resources used by slave + Release slave threads at time of executing shutdown. SYNOPSIS end_slave() @@ -694,14 +694,31 @@ void end_slave() once multi-master code is ready. */ terminate_slave_threads(active_mi,SLAVE_FORCE_ALL); - end_master_info(active_mi); - delete active_mi; - active_mi= 0; } pthread_mutex_unlock(&LOCK_active_mi); DBUG_VOID_RETURN; } +/** + Free all resources used by slave threads at time of executing shutdown. + The routine must be called after all possible users of @c active_mi + have left. + + SYNOPSIS + close_active_mi() + +*/ +void close_active_mi() +{ + pthread_mutex_lock(&LOCK_active_mi); + if (active_mi) + { + end_master_info(active_mi); + delete active_mi; + active_mi= 0; + } + pthread_mutex_unlock(&LOCK_active_mi); +} static bool io_slave_killed(THD* thd, Master_info* mi) { diff --git a/sql/slave.h b/sql/slave.h index abd63315e62..160418955b5 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -174,7 +174,8 @@ const char *print_slave_db_safe(const char *db); int check_expected_error(THD* thd, Relay_log_info const *rli, int error_code); void skip_load_data_infile(NET* net); -void end_slave(); /* clean up */ +void end_slave(); /* release slave threads */ +void close_active_mi(); /* clean up slave threads data */ void clear_until_condition(Relay_log_info* rli); void clear_slave_error(Relay_log_info* rli); void end_relay_log_info(Relay_log_info* rli); From 2a5907a8fdb6a96aa41bc6d5776dbedae5aecf5c Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Tue, 23 Jun 2009 14:32:14 +0200 Subject: [PATCH 113/188] Bug#45293 Supressed some warnings --- mysql-test/suite/funcs_1/r/storedproc.result | 8 -------- mysql-test/suite/funcs_1/t/storedproc.test | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index 7e21ddf1544..3efb361dc82 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -18241,8 +18241,6 @@ END// CALL sp70_n(-1e+40); f1 -10000000000000000000000000000000000000000 -Warnings: -Note 1265 Data truncated for column 'f1' at row 1 CALL sp70_n( -10000000000000000000000000000000000000000 ); f1 -10000000000000000000000000000000000000000 @@ -18255,8 +18253,6 @@ END// CALL sp71_nu(1.00e+40); f1 10000000000000000000000000000000000000000 -Warnings: -Note 1265 Data truncated for column 'f1' at row 1 CALL sp71_nu( 10000000000000000000000000000000000000000 ); f1 10000000000000000000000000000000000000000 @@ -18269,8 +18265,6 @@ END// CALL sp72_nuz(1.00e+40); f1 0000000000000000000000010000000000000000000000000000000000000000 -Warnings: -Note 1265 Data truncated for column 'f1' at row 1 CALL sp72_nuz( 10000000000000000000000000000000000000000 ); f1 0000000000000000000000010000000000000000000000000000000000000000 @@ -18283,8 +18277,6 @@ END// CALL sp73_n_z(1.00e+40); f1 0000000000000000000000010000000000000000000000000000000000000000 -Warnings: -Note 1265 Data truncated for column 'f1' at row 1 CALL sp73_n_z( 10000000000000000000000000000000000000000 ); f1 0000000000000000000000010000000000000000000000000000000000000000 diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test index dc1177ac8bb..67fc33269a3 100644 --- a/mysql-test/suite/funcs_1/t/storedproc.test +++ b/mysql-test/suite/funcs_1/t/storedproc.test @@ -22429,7 +22429,9 @@ BEGIN END// delimiter ;// +--disable_warnings CALL sp70_n(-1e+40); +--enable_warnings eval CALL sp70_n( $minus_40 ); @@ -22445,7 +22447,9 @@ BEGIN END// delimiter ;// +--disable_warnings CALL sp71_nu(1.00e+40); +--enable_warnings eval CALL sp71_nu( $plus_40 ); @@ -22461,7 +22465,9 @@ BEGIN END// delimiter ;// +--disable_warnings CALL sp72_nuz(1.00e+40); +--enable_warnings eval CALL sp72_nuz( $plus_40 ); @@ -22477,7 +22483,9 @@ BEGIN END// delimiter ;// +--disable_warnings CALL sp73_n_z(1.00e+40); +--enable_warnings eval CALL sp73_n_z( $plus_40 ); From f7b9700ad2f887ca07dfcd864b5d2a0c5b2cf284 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:00:58 +0200 Subject: [PATCH 114/188] Backport into mysql-5.1.34sp1-release > ------------------------------------------------------------ > revno: 1810.3885.1 > revision-id: holyfoot@mysql.com-20090428094726-i4j7z985mxr43jym > parent: gshchepa@mysql.com-20090428001913-plzojd1pwplior44 > committer: Alexey Botchkov > branch nick: 50mrg > timestamp: Tue 2009-04-28 14:47:26 +0500 > message: > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > the Point() and Linestring() functions create WKB representation of an > object instead of an real geometry object. > That produced bugs when these were inserted into tables. > > GIS tests fixed accordingly. > > per-file messages: > mysql-test/r/gis-rtree.result > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > test result > mysql-test/r/gis.result > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > test result > mysql-test/t/gis-rtree.test > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > test fixed - GeomFromWKB invocations removed > mysql-test/t/gis.test > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > test fixed - AsWKB invocations added > sql/item_geofunc.cc > Bug#38990 Arbitrary data input plus GIS functions causes mysql server crash > Point() and similar functions to create a proper object --- mysql-test/r/gis-rtree.result | 668 +++++++++++++++++----------------- mysql-test/r/gis.result | 12 +- mysql-test/t/gis-rtree.test | 72 ++-- mysql-test/t/gis.test | 12 +- sql/item_geofunc.cc | 27 +- 5 files changed, 401 insertions(+), 390 deletions(-) diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index f8e0085bf59..b030139e40e 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -186,106 +186,106 @@ CREATE TABLE t2 ( fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, g GEOMETRY NOT NULL ) ENGINE=MyISAM; -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)))); -INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))); +INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))); ALTER TABLE t2 ADD SPATIAL KEY(g); SHOW CREATE TABLE t2; Table Create Table @@ -309,406 +309,406 @@ fid AsText(g) 56 LINESTRING(41 41,50 50) 45 LINESTRING(51 51,60 60) 55 LINESTRING(41 51,50 60) -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))))); +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -99 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -98 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -97 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -96 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -95 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -94 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -93 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -92 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -91 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -90 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -89 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -88 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -87 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -86 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -85 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -84 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -83 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -82 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -81 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -80 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -79 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -78 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -77 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -76 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -75 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -74 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -73 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -72 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -71 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -70 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -69 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -68 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -67 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -66 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -65 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -64 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -63 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -62 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -61 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -60 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -59 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -58 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -57 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -56 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -55 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -54 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -53 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -52 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -51 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -50 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -49 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -48 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -47 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -46 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -45 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -44 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -43 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -42 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -41 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -40 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -39 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -38 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -37 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -36 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -35 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -34 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -33 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -32 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -31 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -30 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -29 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -28 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -27 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -26 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -25 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -24 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -23 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -22 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -21 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -20 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -19 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -18 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -17 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -16 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -15 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -14 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -13 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -12 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -11 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -10 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)))); SELECT count(*) FROM t2; count(*) -9 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)))); SELECT count(*) FROM t2; count(*) -8 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)))); SELECT count(*) FROM t2; count(*) -7 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)))); SELECT count(*) FROM t2; count(*) -6 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)))); SELECT count(*) FROM t2; count(*) -5 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)))); SELECT count(*) FROM t2; count(*) -4 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)))); SELECT count(*) FROM t2; count(*) -3 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)))); SELECT count(*) FROM t2; count(*) -2 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)))); SELECT count(*) FROM t2; count(*) -1 -DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))))); +100 +DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)))); SELECT count(*) FROM t2; count(*) -0 +100 DROP TABLE t2; drop table if exists t1; Warnings: @@ -863,11 +863,11 @@ Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0))); -SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0)); +INSERT INTO t1 (foo) VALUES (POINT(1,1)); +INSERT INTO t1 (foo) VALUES (POINT(1,0)); +INSERT INTO t1 (foo) VALUES (POINT(0,1)); +INSERT INTO t1 (foo) VALUES (POINT(0,0)); +SELECT 1 FROM t1 WHERE foo != POINT(0,0); 1 1 1 @@ -1426,35 +1426,35 @@ Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; create table t1 (a geometry not null, spatial index(a)); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072))); -insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0))); -insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241))); -insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231))); -insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260))); -insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125))); -insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29))); -insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86))); -insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130))); -insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34))); -insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183))); -insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178))); +insert into t1 values (POINT(1.1517219314031e+164, 131072)); +insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284)); +insert into t1 values (POINT(4.7783097267365e-299, -0)); +insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53)); +insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111)); +insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241)); +insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111)); +insert into t1 values (POINT(0, 6.9835074892995e-251)); +insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231)); +insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260)); +insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236)); +insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125)); +insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275)); +insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29)); +insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86)); +insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270)); +insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19)); +insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255)); +insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130)); +insert into t1 values (POINT(0, 5.8774717541114e-39)); +insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159)); +insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270)); +insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82)); +insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34)); +insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53)); +insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183)); +insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192)); +insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159)); +insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178)); drop table t1; CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); INSERT INTO t1(foo) VALUES (NULL); diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 94a5fd83162..494b7a36532 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -47,26 +47,26 @@ INSERT INTO gis_point VALUES INSERT INTO gis_line VALUES (105, LineFromText('LINESTRING(0 0,0 10,10 0)')), (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')), -(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10)))); +(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10))))); INSERT INTO gis_polygon VALUES (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')), (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')), -(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))); +(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))))); INSERT INTO gis_multi_point VALUES (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')), (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')), -(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10)))); +(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10))))); INSERT INTO gis_multi_line VALUES (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')), (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')), -(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))); +(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))))); INSERT INTO gis_multi_polygon VALUES (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), -(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))); +(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))))); INSERT INTO gis_geometrycollection VALUES (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')), -(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))); +(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))); INSERT into gis_geometry SELECT * FROM gis_point; INSERT into gis_geometry SELECT * FROM gis_line; INSERT into gis_geometry SELECT * FROM gis_polygon; diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index dad22f42571..19bbcf19cca 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -41,7 +41,7 @@ while ($1) let $2=10; while ($2) { - eval INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)))); + eval INSERT INTO t2 (g) VALUES (LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))); dec $2; } dec $1; @@ -61,7 +61,7 @@ while ($1) let $2=10; while ($2) { - eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))))); + eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)))); SELECT count(*) FROM t2; dec $2; } @@ -235,11 +235,11 @@ DROP TABLE t1; # Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection # CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) ); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1))); -INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0))); -SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0)); +INSERT INTO t1 (foo) VALUES (POINT(1,1)); +INSERT INTO t1 (foo) VALUES (POINT(1,0)); +INSERT INTO t1 (foo) VALUES (POINT(0,1)); +INSERT INTO t1 (foo) VALUES (POINT(0,0)); +SELECT 1 FROM t1 WHERE foo != POINT(0,0); DROP TABLE t1; # @@ -802,35 +802,35 @@ DROP TABLE t1; # create table t1 (a geometry not null, spatial index(a)); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072))); -insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0))); -insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241))); -insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111))); -insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231))); -insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260))); -insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125))); -insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29))); -insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86))); -insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19))); -insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130))); -insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39))); -insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270))); -insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82))); -insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34))); -insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53))); -insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183))); -insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192))); -insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159))); -insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178))); +insert into t1 values (POINT(1.1517219314031e+164, 131072)); +insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284)); +insert into t1 values (POINT(4.7783097267365e-299, -0)); +insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53)); +insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111)); +insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241)); +insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111)); +insert into t1 values (POINT(0, 6.9835074892995e-251)); +insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231)); +insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260)); +insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236)); +insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125)); +insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275)); +insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29)); +insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86)); +insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270)); +insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19)); +insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255)); +insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130)); +insert into t1 values (POINT(0, 5.8774717541114e-39)); +insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159)); +insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270)); +insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82)); +insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34)); +insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53)); +insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183)); +insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192)); +insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159)); +insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178)); drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index a9c66855f96..0dae4509518 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -37,32 +37,32 @@ INSERT INTO gis_point VALUES INSERT INTO gis_line VALUES (105, LineFromText('LINESTRING(0 0,0 10,10 0)')), (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')), -(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10)))); +(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10))))); INSERT INTO gis_polygon VALUES (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')), (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')), -(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))); +(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))))); INSERT INTO gis_multi_point VALUES (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')), (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')), -(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10)))); +(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10))))); INSERT INTO gis_multi_line VALUES (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')), (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')), -(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))); +(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))))); INSERT INTO gis_multi_polygon VALUES (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), -(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))); +(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))))); INSERT INTO gis_geometrycollection VALUES (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')), -(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))); +(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))); INSERT into gis_geometry SELECT * FROM gis_point; INSERT into gis_geometry SELECT * FROM gis_line; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index ac1b7738a27..24a92c78e9c 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -78,10 +78,17 @@ String *Item_func_geometry_from_wkb::val_str(String *str) { DBUG_ASSERT(fixed == 1); String arg_val; - String *wkb= args[0]->val_str(&arg_val); + String *wkb; Geometry_buffer buffer; uint32 srid= 0; + if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY) + { + return args[0]->val_str(str); + } + + wkb= args[0]->val_str(&arg_val); + if ((arg_count == 2) && !args[1]->null_value) srid= (uint32)args[1]->val_int(); @@ -91,8 +98,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str) str->length(0); str->q_append(srid); if ((null_value= - (args[0]->null_value || - !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str)))) + (args[0]->null_value || + !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str)))) return 0; return str; } @@ -345,14 +352,16 @@ String *Item_func_point::val_str(String *str) DBUG_ASSERT(fixed == 1); double x= args[0]->val_real(); double y= args[1]->val_real(); + uint32 srid= 0; if ((null_value= (args[0]->null_value || args[1]->null_value || - str->realloc(1 + 4 + SIZEOF_STORED_DOUBLE*2)))) + str->realloc(4/*SRID*/ + 1 + 4 + SIZEOF_STORED_DOUBLE*2)))) return 0; str->set_charset(&my_charset_bin); str->length(0); + str->q_append(srid); str->q_append((char)Geometry::wkb_ndr); str->q_append((uint32)Geometry::wkb_point); str->q_append(x); @@ -376,12 +385,14 @@ String *Item_func_spatial_collection::val_str(String *str) DBUG_ASSERT(fixed == 1); String arg_value; uint i; + uint32 srid= 0; str->set_charset(&my_charset_bin); str->length(0); - if (str->reserve(1 + 4 + 4, 512)) + if (str->reserve(4/*SRID*/ + 1 + 4 + 4, 512)) goto err; + str->q_append(srid); str->q_append((char) Geometry::wkb_ndr); str->q_append((uint32) coll_type); str->q_append((uint32) arg_count); @@ -399,13 +410,13 @@ String *Item_func_spatial_collection::val_str(String *str) In the case of GeometryCollection we don't need any checkings for item types, so just copy them into target collection */ - if (str->append(res->ptr(), len, (uint32) 512)) + if (str->append(res->ptr() + 4/*SRID*/, len - 4/*SRID*/, (uint32) 512)) goto err; } else { enum Geometry::wkbType wkb_type; - const char *data= res->ptr() + 1; + const char *data= res->ptr() + 4/*SRID*/ + 1; /* In the case of named collection we must check that items @@ -414,7 +425,7 @@ String *Item_func_spatial_collection::val_str(String *str) wkb_type= (Geometry::wkbType) uint4korr(data); data+= 4; - len-= 5; + len-= 5 + 4/*SRID*/; if (wkb_type != item_type) goto err; From 92c64f157b77db5d47579ead90612638ec002942 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:11:06 +0200 Subject: [PATCH 115/188] Backport into mysql-5.1.34sp1-release > ------------------------------------------------------------ > revno: 2841.1.1 > revision-id: sergey.glukhov@sun.com-20090401084033-161k4f8qucafy6mj > parent: ramil@mysql.com-20090401053459-07x8z2pw2ev94xck > committer: Sergey Glukhov > branch nick: mysql-5.1-bugteam > timestamp: Wed 2009-04-01 13:40:33 +0500 > message: > Bug#43183 ExctractValue() brings result list in missorder > The problem is that XML functions(items) do not reset null_value > before their execution and further item excution may use > null_value value of the previous result. > The fix is to reset null_value. --- mysql-test/r/xml.result | 29 +++++++++++++++++++++++++++++ mysql-test/t/xml.test | 27 +++++++++++++++++++++++++++ sql/item_xmlfunc.cc | 2 ++ 3 files changed, 58 insertions(+) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 404b0dc3789..fad2cab0e57 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -1064,4 +1064,33 @@ select extractvalue('','"b"/a'); ERROR HY000: XPATH syntax error: '/a' select extractvalue('','(1)/a'); ERROR HY000: XPATH syntax error: '/a' +CREATE TABLE IF NOT EXISTS t1 ( +id int(10) unsigned NOT NULL AUTO_INCREMENT, +xml text, +PRIMARY KEY (id) +) ENGINE=MyISAM; +INSERT INTO t1 (id, xml) VALUES +(15, ''), +(14, ''); +SELECT +extractvalue( xml, '/bla/@name' ), +extractvalue( xml, '/bla/@name' ) +FROM t1 ORDER BY t1.id; +extractvalue( xml, '/bla/@name' ) extractvalue( xml, '/bla/@name' ) +NULL NULL +blubb blubb +Warnings: +Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' +Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' +SELECT +UpdateXML(xml, '/bla/@name', 'test'), +UpdateXML(xml, '/bla/@name', 'test') +FROM t1 ORDER BY t1.id; +UpdateXML(xml, '/bla/@name', 'test') UpdateXML(xml, '/bla/@name', 'test') +NULL NULL + +Warnings: +Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' +Warning 1525 Incorrect XML value: 'parse error at line 1 pos 23: unexpected END-OF-INPUT' +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 74bce8dc962..6e7d38cdfca 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -590,4 +590,31 @@ select extractvalue('','"b"/a'); --error ER_UNKNOWN_ERROR select extractvalue('','(1)/a'); +# +# Bug#43183 ExctractValue() brings result list in missorder +# +CREATE TABLE IF NOT EXISTS t1 ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + xml text, + PRIMARY KEY (id) +) ENGINE=MyISAM; + +INSERT INTO t1 (id, xml) VALUES +(15, ''), +(14, ''); + + +SELECT +extractvalue( xml, '/bla/@name' ), +extractvalue( xml, '/bla/@name' ) +FROM t1 ORDER BY t1.id; + + +SELECT +UpdateXML(xml, '/bla/@name', 'test'), +UpdateXML(xml, '/bla/@name', 'test') +FROM t1 ORDER BY t1.id; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 5601a2b18c6..6320873e4d3 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2785,6 +2785,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf) String *Item_func_xml_extractvalue::val_str(String *str) { String *res; + null_value= 0; if (!nodeset_func || !(res= args[0]->val_str(str)) || !parse_xml(res, &pxml)) @@ -2801,6 +2802,7 @@ String *Item_func_xml_update::val_str(String *str) { String *res, *nodeset, *rep; + null_value= 0; if (!nodeset_func || !(res= args[0]->val_str(str)) || !(rep= args[2]->val_str(&tmp_value3)) || From 4ce94d93f94aa03b647aa67a8a395e79e13d6104 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:13:50 +0200 Subject: [PATCH 116/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2852.1.10 > revision-id: sergey.glukhov@sun.com-20090409093850-z3vgmz8fqogv8o1o > parent: v.narayanan@sun.com-20090409081823-zsw611isjcorl63b > parent: sergey.glukhov@sun.com-20090409091931-2zhtgonllfmsxjex > committer: Sergey Glukhov > branch nick: mysql-5.1-bugteam > timestamp: Thu 2009-04-09 14:38:50 +0500 > message: > 5.0-bugteam->5.1-bugteam merge > ------------------------------------------------------------ > revno: 1810.3882.6 > revision-id: sergey.glukhov@sun.com-20090409091931-2zhtgonllfmsxjex > parent: anurag.shekhar@sun.com-20090409080004-xvxy663jan45tb3c > committer: Sergey Glukhov > branch nick: mysql-5.0-bugteam > timestamp: Thu 2009-04-09 14:19:31 +0500 > message: > Bug#43833 Simple INSERT crashes the server > The crash happens due to wrong 'digits' variable value(0), > 'digits' can not be 0, so the fix is use 1 as min allowed value. --- mysql-test/r/insert.result | 5 +++++ mysql-test/t/insert.test | 9 +++++++++ sql/field.cc | 6 +++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 919aff4bfb7..3f91039d592 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -633,4 +633,9 @@ SELECT * FROM t2; c1 15449237462 DROP TABLE t1, t2; +CREATE TABLE t1(f1 FLOAT); +INSERT INTO t1 VALUES (1.23); +CREATE TABLE t2(f1 CHAR(1)); +INSERT INTO t2 SELECT f1 FROM t1; +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index c58fb61ad30..8f9ed6c7d06 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -488,5 +488,14 @@ SELECT * FROM t2; DROP TABLE t1, t2; +# +# Bug#43833 Simple INSERT crashes the server +# +CREATE TABLE t1(f1 FLOAT); +INSERT INTO t1 VALUES (1.23); +CREATE TABLE t2(f1 CHAR(1)); +INSERT INTO t2 SELECT f1 FROM t1; +DROP TABLE t1, t2; + --echo End of 5.0 tests. diff --git a/sql/field.cc b/sql/field.cc index 973170223e4..1eabcaaf5e6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6448,13 +6448,13 @@ int Field_str::store(double nr) calculate the maximum number of significant digits if the 'f'-format would be used (+1 for decimal point if the number has a fractional part). */ - digits= max(0, (int) max_length - fractional); + digits= max(1, (int) max_length - fractional); /* If the exponent is negative, decrease digits by the number of leading zeros after the decimal point that do not count as significant digits. */ if (exp < 0) - digits= max(0, (int) digits + exp); + digits= max(1, (int) digits + exp); /* 'e'-format is used only if the exponent is less than -4 or greater than or equal to the precision. In this case we need to adjust the number of @@ -6462,7 +6462,7 @@ int Field_str::store(double nr) We also have to reserve one additional character if abs(exp) >= 100. */ if (exp >= (int) digits || exp < -4) - digits= max(0, (int) (max_length - 5 - (exp >= 100 || exp <= -100))); + digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100))); /* Limit precision to DBL_DIG to avoid garbage past significant digits */ set_if_smaller(digits, DBL_DIG); From 38094c04d0873f28c2cc34cb49492fae4b592312 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:14:47 +0200 Subject: [PATCH 117/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2852.1.15 > revision-id: davi.arnaut@sun.com-20090409152525-b4vnj9atidmjh0mf > parent: luis.soares@sun.com-20090409113044-2072kufy5efeohpp > committer: Davi Arnaut > branch nick: 43706-5.1 > timestamp: Thu 2009-04-09 12:25:25 -0300 > message: > Bug#43706: libmysqld segfaults when re-intialised > Bug#44091: libmysqld gets stuck waiting on mutex on initialization > > The problem was that libmysqld wasn't enforcing a certain > initialization and deinitialization order for the mysys > library. Another problem was that the global object used > for management of log event handlers (aka LOGGER) wasn't > being prepared for a possible reutilization. > > What leads to the hang/crash reported is that a failure > to load the language file triggers a double call of the > cleanup functions, causing an already destroyed mutex to > be used. > > The solution is enforce a order on the initialization and > deinitialization of the mysys library within the libmysqld > library and to ensure that the global LOGGER object reset > it's internal state during cleanup. --- mysys/my_init.c | 4 ++++ sql/log.cc | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/mysys/my_init.c b/mysys/my_init.c index b330ffac65a..a60927be693 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -136,6 +136,10 @@ void my_end(int infoflag) */ FILE *info_file= DBUG_FILE; my_bool print_info= (info_file != stderr); + + if (!my_init_done) + return; + /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer operational, so we cannot use DBUG_RETURN. diff --git a/sql/log.cc b/sql/log.cc index 44296daa939..ed2eff6625d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -845,6 +845,7 @@ void LOGGER::cleanup_base() { table_log_handler->cleanup(); delete table_log_handler; + table_log_handler= NULL; } if (file_log_handler) file_log_handler->cleanup(); @@ -855,7 +856,11 @@ void LOGGER::cleanup_end() { DBUG_ASSERT(inited == 1); if (file_log_handler) + { delete file_log_handler; + file_log_handler=NULL; + } + inited= 0; } From f5883e8d69135559edbfc4282b08ef569ade16ef Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:15:43 +0200 Subject: [PATCH 118/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2852.12.6 > tags: clone-5.1.35-build, mysql-5.1.35 > revision-id: gshchepa@mysql.com-20090513075139-g50shsfjaf1dstdn > parent: joerg@mysql.com-20090508190407-ymqxmp6daeta6fdj > committer: Gleb Shchepa > branch nick: mysql-5.1 > timestamp: Wed 2009-05-13 12:51:39 +0500 > message: > Bug #44290: explain crashes for subquery with distinct in > SQL_SELECT::test_quick_select > > The crash was caused by an incomplete cleanup of JOIN_TAB::select > during the filesort of rows for GROUP BY clause inside a subquery. > Queries where a quick index access is replaced with filesort was > was affected. For example: > > SELECT 1 FROM > (SELECT COUNT(DISTINCT c1) FROM t1 > WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x > > Quick index access related data in the SQL_SELECT::test_quick_select > function was inconsistent after an incomplete cleanup. > This function has been completed to prevent crashes in the > SQL_SELECT::test_quick_select function. --- mysql-test/include/mix1.inc | 19 +++++++++++++++++++ mysql-test/r/innodb_mysql.result | 19 +++++++++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 39 insertions(+) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index cc9183205be..b29661b85cd 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1475,4 +1475,23 @@ DROP TABLE t1; # DROP TABLE t1; # +--echo # +--echo # Bug #44290: explain crashes for subquery with distinct in +--echo # SQL_SELECT::test_quick_select +--echo # (reproduced only with InnoDB tables) +--echo # + +eval +CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, KEY (c3), KEY (c2, c3)) + ENGINE=$engine_type; +INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); + +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) + FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +EXPLAIN +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) + FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 6fcc9415d12..f2caf7d07ec 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1657,6 +1657,25 @@ vid tid idx name type 3 1 2 c1 NULL 3 1 1 pk NULL DROP TABLE t1; +# +# Bug #44290: explain crashes for subquery with distinct in +# SQL_SELECT::test_quick_select +# (reproduced only with InnoDB tables) +# +CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, KEY (c3), KEY (c2, c3)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +1 +1 +EXPLAIN +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 index c3,c2 c2 10 NULL 5 +DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; create table t1(a int); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0a3238b0185..d5430430ed5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13459,6 +13459,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, { select->cleanup(); // filesort did select tab->select= 0; + table->quick_keys.clear_all(); // as far as we cleanup select->quick } tab->select_cond=0; tab->last_inner= 0; From cf1f35a1e1b5bed3a086dcbcf11112f739d8e7f2 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:16:32 +0200 Subject: [PATCH 119/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2852.2.1 > revision-id: gni@mysql.com-20090403182157-de6ecrtzlgvpl5mk > parent: timothy.smith@sun.com-20090402083720-b7i3jr4dmvwjakcj > committer: Guangbao Ni > branch nick: bugteam-5.1-bug42640 > timestamp: Fri 2009-04-03 18:21:57 +0000 > message: > BUG#42640 mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLESmode) > > Mysql server crashes because unsafe statements warning is wrongly elevated to error, > which is set the error status of Diagnostics_area of the thread in THD::binlog_query(). > Yet the caller believes that binary logging shouldn't touch the status, so it will > set the status also later by my_ok(), my_error() or my_message() seperately > according to the execution result of the statement or transaction. > But the status of Diagnostics_area of the thread is allowed to set only once. > > Fixed to clear the error wrongly set by binary logging, but keep the warning message. --- .../suite/binlog/r/binlog_stm_ps.result | 2 +- .../suite/binlog/r/binlog_unsafe.result | 128 ++++++++++-------- mysql-test/suite/binlog/t/binlog_unsafe.test | 19 +++ mysql-test/suite/rpl/r/rpl_skip_error.result | 2 +- .../suite/rpl/r/rpl_stm_loadfile.result | 4 +- mysql-test/suite/rpl/r/rpl_udf.result | 8 +- sql/sql_class.cc | 6 +- 7 files changed, 105 insertions(+), 64 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_stm_ps.result b/mysql-test/suite/binlog/r/binlog_stm_ps.result index 1cf7429987e..ea7cc6f16df 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_ps.result +++ b/mysql-test/suite/binlog/r/binlog_stm_ps.result @@ -11,7 +11,7 @@ prepare s from "insert into t1 select 100 limit ?"; set @a=100; execute s using @a; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1 (a int) diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index a0809c79fa2..675c327e9e7 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -10,25 +10,25 @@ INSERT DELAYED INTO t1 VALUES (5); ---- Insert directly ---- INSERT INTO t1 VALUES (@@global.sync_binlog); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t1 VALUES (@@session.insert_id); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t1 VALUES (@@global.auto_increment_increment); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 SELECT UUID(); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@session.sql_mode); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@global.init_slave); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. INSERT INTO t2 VALUES (@@hostname); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from stored procedure ---- CREATE PROCEDURE proc() BEGIN @@ -42,13 +42,13 @@ INSERT INTO t2 VALUES (@@hostname); END| CALL proc(); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from stored function ---- CREATE FUNCTION func() RETURNS INT @@ -66,13 +66,13 @@ SELECT func(); func() 0 Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from trigger ---- CREATE TRIGGER trig BEFORE INSERT ON trigger_table @@ -88,14 +88,14 @@ INSERT INTO t2 VALUES (@@hostname); END| INSERT INTO trigger_table VALUES ('bye.'); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from prepared statement ---- PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)'; PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)'; @@ -106,25 +106,25 @@ PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)'; PREPARE p7 FROM 'INSERT INTO t2 VALUES (@@hostname)'; EXECUTE p1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p2; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p3; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p4; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p5; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p6; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. EXECUTE p7; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ---- Insert from nested call of triggers / functions / procedures ---- CREATE PROCEDURE proc1() INSERT INTO trigger_table VALUES ('ha!')| @@ -154,13 +154,13 @@ EXECUTE prep6; func5() 0 Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. ==== Variables that should *not* be unsafe ==== INSERT INTO t1 VALUES (@@session.pseudo_thread_id); INSERT INTO t1 VALUES (@@session.pseudo_thread_id); @@ -195,16 +195,16 @@ DROP TABLE t1, t2, t3, trigger_table, trigger_table2; CREATE TABLE t1(a INT, b INT, KEY(a), PRIMARY KEY(b)); INSERT INTO t1 SELECT * FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. REPLACE INTO t1 SELECT * FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. UPDATE t1 SET a=1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DELETE FROM t1 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. CREATE PROCEDURE p1() BEGIN INSERT INTO t1 SELECT * FROM t1 LIMIT 1; @@ -214,10 +214,10 @@ DELETE FROM t1 LIMIT 1; END| CALL p1(); Warnings: -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DROP PROCEDURE p1; DROP TABLE t1; DROP TABLE IF EXISTS t1; @@ -225,7 +225,7 @@ CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100)); INSERT INTO t1 VALUES ('a','b'); UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. DROP TABLE t1; DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1(i INT PRIMARY KEY); @@ -234,7 +234,7 @@ CREATE TABLE t3(i INT, ch CHAR(50)); "Should issue message Statement is not safe to log in statement format." INSERT INTO t1 SELECT * FROM t2 LIMIT 1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. CREATE FUNCTION func6() RETURNS INT BEGIN @@ -246,7 +246,7 @@ END| "Should issue message Statement is not safe to log in statement format only once" INSERT INTO t3 VALUES(func6(), UUID()); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. "Check whether SET @@SQL_LOG_BIN = 0/1 doesn't work in substatements" CREATE FUNCTION fun_check_log_bin() RETURNS INT BEGIN @@ -259,7 +259,7 @@ SELECT fun_check_log_bin(); fun_check_log_bin() 100 Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. "SQL_LOG_BIN should be ON still" SHOW VARIABLES LIKE "SQL_LOG_BIN"; Variable_name Value @@ -309,4 +309,22 @@ DROP FUNCTION func7; DROP TRIGGER trig; DROP TABLE t1, t2, t3, trigger_table; set @@SESSION.SQL_LOG_BIN = @save_log_bin; +SET @save_sql_mode = @@SESSION.SQL_MODE; +SET @@SESSION.SQL_MODE = STRICT_ALL_TABLES; +CREATE TABLE t1(i INT PRIMARY KEY); +CREATE TABLE t2(i INT PRIMARY KEY); +INSERT INTO t1 SELECT * FROM t2 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +INSERT INTO t1 VALUES(@@global.sync_binlog); +Warnings: +Note 1592 Statement is not safe to log in statement format. +UPDATE t1 SET i = 999 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +DELETE FROM t1 LIMIT 1; +Warnings: +Note 1592 Statement is not safe to log in statement format. +DROP TABLE t1, t2; +SET @@SESSION.SQL_MODE = @save_sql_mode; "End of tests" diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test index 642dc3a46f7..1b0f0a6c30a 100644 --- a/mysql-test/suite/binlog/t/binlog_unsafe.test +++ b/mysql-test/suite/binlog/t/binlog_unsafe.test @@ -46,6 +46,7 @@ # BUG#34732: mysqlbinlog does not print default values for auto_increment variables # BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed # BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0 +# BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) # # ==== Related test cases ==== # @@ -369,4 +370,22 @@ DROP FUNCTION func7; DROP TRIGGER trig; DROP TABLE t1, t2, t3, trigger_table; set @@SESSION.SQL_LOG_BIN = @save_log_bin; + +# +# For BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) +# +SET @save_sql_mode = @@SESSION.SQL_MODE; +SET @@SESSION.SQL_MODE = STRICT_ALL_TABLES; + +CREATE TABLE t1(i INT PRIMARY KEY); +CREATE TABLE t2(i INT PRIMARY KEY); + +INSERT INTO t1 SELECT * FROM t2 LIMIT 1; +INSERT INTO t1 VALUES(@@global.sync_binlog); + +UPDATE t1 SET i = 999 LIMIT 1; +DELETE FROM t1 LIMIT 1; + +DROP TABLE t1, t2; +SET @@SESSION.SQL_MODE = @save_sql_mode; --echo "End of tests" diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index b90d8113e8e..205c7785349 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -76,7 +76,7 @@ create table t1(a int primary key); insert into t1 values (1),(2); delete from t1 where @@server_id=1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. set sql_mode=strict_trans_tables; insert into t1 values (7), (8), (9); [on slave] diff --git a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result index d18befe6e4c..72f58268d5f 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_loadfile.result +++ b/mysql-test/suite/rpl/r/rpl_stm_loadfile.result @@ -10,7 +10,7 @@ CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a)); INSERT INTO test.t1 VALUES(1,'test'); UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1; Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. create procedure test.p1() begin INSERT INTO test.t1 VALUES(2,'test'); @@ -18,7 +18,7 @@ UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2; end| CALL test.p1(); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. SELECT * FROM test.t1 ORDER BY blob_column; a blob_column 1 abase diff --git a/mysql-test/suite/rpl/r/rpl_udf.result b/mysql-test/suite/rpl/r/rpl_udf.result index 79a82b5fbc7..56df5b30d93 100644 --- a/mysql-test/suite/rpl/r/rpl_udf.result +++ b/mysql-test/suite/rpl/r/rpl_udf.result @@ -182,19 +182,19 @@ CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM; affected rows: 0 INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00)); Warnings: -Warning 1592 Statement is not safe to log in statement format. +Note 1592 Statement is not safe to log in statement format. affected rows: 1 SELECT * FROM t1 ORDER BY sum; sum price diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7f15508caa1..b73822f5a48 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3676,7 +3676,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, if (sql_log_bin_toplevel && lex->is_stmt_unsafe() && variables.binlog_format == BINLOG_FORMAT_STMT) { - push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN, + /* + A warning can be elevated a error when STRICT sql mode. + But we don't want to elevate binlog warning to error here. + */ + push_warning(this, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BINLOG_UNSAFE_STATEMENT, ER(ER_BINLOG_UNSAFE_STATEMENT)); if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED)) From 11d2b7fea62a030cf9c959d81a30272ec0210d14 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:17:12 +0200 Subject: [PATCH 120/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2852.2.3 > revision-id: davi.arnaut@sun.com-20090403194600-60ufn0tz1gx1kl0l > parent: gni@mysql.com-20090403184200-vnjtpsv4an79w8bu > parent: davi.arnaut@sun.com-20090403191154-0ho2nai3chjsmpof > committer: Davi Arnaut > branch nick: 43230-5.1 > timestamp: Fri 2009-04-03 16:46:00 -0300 > message: > Merge Bug#43230 into mysql-5.1-bugteam > ------------------------------------------------------------ > revno: 1810.3855.16 > revision-id: davi.arnaut@sun.com-20090403191154-0ho2nai3chjsmpof > parent: chad@mysql.com-20090402152928-3ld60a56h86njcpg > committer: Davi Arnaut > branch nick: 43230-5.0 > timestamp: Fri 2009-04-03 16:11:54 -0300 > message: > Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely > > The problem is that a SELECT .. FOR UPDATE statement might open > a table and later wait for a impeding global read lock without > noticing whether it is holding a table that is being waited upon > the the flush phase of the process that took the global read > lock. > > The same problem also affected the following statements: > > LOCK TABLES .. WRITE > UPDATE .. SET (update and multi-table update) > TRUNCATE TABLE .. > LOAD DATA .. > > The solution is to make the above statements wait for a impending > global read lock before opening the tables. If there is no > impending global read lock, the statement raises a temporary > protection against global read locks and progresses smoothly > towards completion. > > Important notice: the patch does not try to address all possible > cases, only those which are common and can be fixed unintrusively > enough for 5.0. --- mysql-test/r/lock_multi.result | 55 ++++++++++++++ mysql-test/t/lock_multi.test | 128 +++++++++++++++++++++++++++++++++ sql/sql_lex.cc | 1 + sql/sql_lex.h | 16 +++++ sql/sql_parse.cc | 33 ++++++++- sql/sql_yacc.yy | 7 +- 6 files changed, 236 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 35bc7376296..d8768e802ea 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -96,6 +96,61 @@ alter table t1 auto_increment=0; alter table t1 auto_increment=0; unlock tables; drop table t1; +create table t1 (a int); +create table t2 like t1; +# con1 +lock tables t1 write; +# con2 +flush tables with read lock; +# con5 +# global read lock is taken +# con3 +select * from t2 for update; +# waiting for release of read lock +# con4 +# would hang and later cause a deadlock +flush tables t2; +# clean up +unlock tables; +unlock tables; +a +drop table t1,t2; +# +# Lightweight version: +# Ensure that the wait for a GRL is done before opening tables. +# +create table t1 (a int); +create table t2 like t1; +# +# UPDATE +# +# default +flush tables with read lock; +# con1 +update t2 set a = 1; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +# +# LOCK TABLES .. WRITE +# +# default +flush tables with read lock; +# con1 +lock tables t2 write; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +unlock tables; +drop table t1,t2; End of 5.0 tests create table t1 (i int); lock table t1 read; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index e93153f005c..47b5aa0292b 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -317,6 +317,134 @@ reap; connection locker; drop table t1; +# +# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely +# + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connect (con3,localhost,root,,); +connect (con4,localhost,root,,); +connect (con5,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +connection con1; +--echo # con1 +lock tables t1 write; +connection con2; +--echo # con2 +send flush tables with read lock; +connection con5; +--echo # con5 +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Flushing tables'; +--source include/wait_show_condition.inc +--echo # global read lock is taken +connection con3; +--echo # con3 +send select * from t2 for update; +connection con5; +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # waiting for release of read lock +connection con4; +--echo # con4 +--echo # would hang and later cause a deadlock +flush tables t2; +connection con1; +--echo # clean up +unlock tables; +connection con2; +--reap +unlock tables; +connection con3; +--reap +connection default; +disconnect con5; +disconnect con4; +disconnect con3; +disconnect con2; +disconnect con1; + +drop table t1,t2; + +--echo # +--echo # Lightweight version: +--echo # Ensure that the wait for a GRL is done before opening tables. +--echo # + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +--echo # +--echo # UPDATE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send update t2 set a = 1; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap + +--echo # +--echo # LOCK TABLES .. WRITE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send lock tables t2 write; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap +unlock tables; + +connection default; +disconnect con2; +disconnect con1; + +drop table t1,t2; + --echo End of 5.0 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e6eb9a8a44e..69b8c486d5f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -348,6 +348,7 @@ void lex_start(THD *thd) lex->nest_level=0 ; lex->allow_sum_func= 0; lex->in_sum_func= NULL; + lex->protect_against_global_read_lock= FALSE; /* ok, there must be a better solution for this, long-term I tried "bzero" in the sql_yacc.yy code, but that for diff --git a/sql/sql_lex.h b/sql/sql_lex.h index f34a1c7c36f..172940cf9d7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1745,6 +1745,22 @@ typedef struct st_lex : public Query_tables_list bool escape_used; bool is_lex_started; /* If lex_start() did run. For debugging. */ + /* + Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE. + + Protect from a impending GRL as otherwise the thread might deadlock + if it starts waiting for the GRL in mysql_lock_tables. + + The protection is needed because there is a race between setting + the global read lock and waiting for all open tables to be closed. + The problem is a circular wait where a thread holding "old" open + tables will wait for the global read lock to be released while the + thread holding the global read lock will wait for all "old" open + tables to be closed -- the flush part of flush tables with read + lock. + */ + bool protect_against_global_read_lock; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2974dff9ea9..6dbe4a4fd8d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2200,8 +2200,15 @@ mysql_execute_command(THD *thd) res= check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, any_db, 0, 0, 0, 0); - if (!res) - res= execute_sqlcom_select(thd, all_tables); + + if (res) + break; + + if (!thd->locked_tables && lex->protect_against_global_read_lock && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + break; + + res= execute_sqlcom_select(thd, all_tables); break; case SQLCOM_PREPARE: { @@ -3006,6 +3013,9 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (update_precheck(thd, all_tables)) break; + if (!thd->locked_tables && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; DBUG_ASSERT(select_lex->offset_limit == 0); unit->set_limit(select_lex); res= (up_result= mysql_update(thd, all_tables, @@ -3032,6 +3042,15 @@ end_with_restore_list: else res= 0; + /* + Protection might have already been risen if its a fall through + from the SQLCOM_UPDATE case above. + */ + if (!thd->locked_tables && + lex->sql_command == SQLCOM_UPDATE_MULTI && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; + res= mysql_multi_update_prepare(thd); #ifdef HAVE_REPLICATION @@ -3229,7 +3248,8 @@ end_with_restore_list: ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } - + if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; res= mysql_truncate(thd, first_table, 0); break; case SQLCOM_DELETE: @@ -3402,6 +3422,10 @@ end_with_restore_list: if (check_one_table_access(thd, privilege, all_tables)) goto error; + if (!thd->locked_tables && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; + res= mysql_load(thd, lex->exchange, first_table, lex->field_list, lex->update_list, lex->value_list, lex->duplicates, lex->ignore, (bool) lex->local_file); @@ -3472,6 +3496,9 @@ end_with_restore_list: if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, UINT_MAX, FALSE)) goto error; + if (lex->protect_against_global_read_lock && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) + goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e56ff7c6ad7..7752ccce73d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6538,6 +6538,7 @@ select_lock_type: lex->current_select->set_lock_for_tables(TL_WRITE); lex->current_select->lock_option= TL_WRITE; lex->safe_to_cache_query=0; + lex->protect_against_global_read_lock= TRUE; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { @@ -12182,8 +12183,12 @@ table_lock_list: table_lock: table_ident opt_table_alias lock_option { - if (!Select->add_table_to_list(YYTHD, $1, $2, 0, (thr_lock_type) $3)) + thr_lock_type lock_type= (thr_lock_type) $3; + if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type)) MYSQL_YYABORT; + /* If table is to be write locked, protect from a impending GRL. */ + if (lock_type >= TL_WRITE_ALLOW_WRITE) + Lex->protect_against_global_read_lock= TRUE; } ; From 579f83859f5a97d653171a4493ef27b43e148617 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:19:45 +0200 Subject: [PATCH 121/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2857.1.1 > revision-id: satya.bn@sun.com-20090415114608-26b21dtx3doeidcc > parent: davi.arnaut@sun.com-20090414120532-9a34lwlk105z8log > committer: Satya B > branch nick: mysql-5.1-bugteam-innodb > timestamp: Wed 2009-04-15 17:16:08 +0530 > message: > Applying InnoDB snashot 5.1-ss4699, part 1. Fixes BUG#39320 and other > problems > > 1) BUG#39320 - innodb crash in file btr/btr0pcur.c line 217 with > innodb_locks_unsafe_for_binlog > > 2) Fixes bug in multi-table semi consistent reads. > > 3) Fixes email address from dev@innodb.com to innodb_dev_ww@oracle.com > > 4) Fixes warning message generated by main.innodb test > > > Detailed revision comments: > > r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 5 lines > branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position > also for unlock_row(). (Bug #39320) > > rb://96 approved by Heikki Tuuri. > > r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 8 lines > branches/5.1: Fix a bug in multi-table semi-consistent reads. > Remember the acquired record locks per table handle (row_prebuilt_t) > rather than per transaction (trx_t), so that unlock_row should successfully > unlock all non-matching rows in multi-table operations. > This deficiency was found while investigating Bug #39320. > > rb://94 approved by Heikki Tuuri. > > r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines > branches/5.1: row_unlock_for_mysql(): Do not unlock records that were > modified by the current transaction. This bug was introduced or unmasked > in r4400. > > rb://97 approved by Heikki Tuuri > > r4573 | vasil | 2009-03-30 14:17:13 +0300 (Mon, 30 Mar 2009) | 4 lines > branches/5.1: > > Fix email address from dev@innodb.com to innodb_dev_ww@oracle.com > > r4574 | vasil | 2009-03-30 14:27:08 +0300 (Mon, 30 Mar 2009) | 38 lines > branches/5.1: > > Restore the state of INNODB_THREAD_CONCURRENCY to silence this warning: > > TEST RESULT TIME (ms) > ------------------------------------------------------------ > > worker[1] Using MTR_BUILD_THREAD 250, with reserved ports 12500..12509 > main.innodb [ pass ] 8803 > > MTR's internal check of the test case 'main.innodb' failed. > This means that the test case does not preserve the state that existed > before the test case was executed. Most likely the test case did not > do a proper clean-up. > This is the diff of the states of the servers before and after the > test case was executed: > mysqltest: Logging to '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.log'. > mysqltest: Results saved in '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result'. > mysqltest: Connecting to server localhost:12500 (socket /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/mysqld.1.sock) as 'root', connection 'default', attempt 0 ... > mysqltest: ... Connected. > mysqltest: Start processing test commands from './include/check-testcase.test' ... > mysqltest: ... Done processing test commands. > --- /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result 2009-03-30 14:12:31.000000000 +0300 > +++ /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.reject 2009-03-30 14:12:41.000000000 +0300 > @@ -99,7 +99,7 @@ > INNODB_SUPPORT_XA ON > INNODB_SYNC_SPIN_LOOPS 20 > INNODB_TABLE_LOCKS ON > -INNODB_THREAD_CONCURRENCY 8 > +INNODB_THREAD_CONCURRENCY 16 > INNODB_THREAD_SLEEP_DELAY 10000 > INSERT_ID 0 > INTERACTIVE_TIMEOUT 28800 > > mysqltest: Result content mismatch > > not ok > > r4576 | vasil | 2009-03-30 16:25:10 +0300 (Mon, 30 Mar 2009) | 4 lines > branches/5.1: > > Revert a change to Makefile.am that I committed accidentally in c4574. --- mysql-test/r/innodb-semi-consistent.result | 7 ++ mysql-test/t/innodb-semi-consistent.test | 13 ++++ mysql-test/t/innodb.test | 14 +++- storage/innobase/include/row0mysql.h | 15 ++++ storage/innobase/include/trx0trx.h | 42 ----------- storage/innobase/include/trx0trx.ic | 58 --------------- storage/innobase/lock/lock0lock.c | 21 ------ storage/innobase/row/row0mysql.c | 85 ++++++++++++++-------- storage/innobase/row/row0sel.c | 43 ++++++----- storage/innobase/trx/trx0trx.c | 2 - 10 files changed, 125 insertions(+), 175 deletions(-) diff --git a/mysql-test/r/innodb-semi-consistent.result b/mysql-test/r/innodb-semi-consistent.result index 55e3cb5c7b4..ca0e362ef80 100644 --- a/mysql-test/r/innodb-semi-consistent.result +++ b/mysql-test/r/innodb-semi-consistent.result @@ -38,3 +38,10 @@ a 11 7 drop table t1; +create table t1 (a int, b int) engine=myisam; +create table t2 (c int, d int, key (c)) engine=innodb; +insert into t1 values (1,1); +insert into t2 values (1,2); +set session transaction isolation level read committed; +delete from t1 using t1 join t2 on t1.a = t2.c where t2.d in (1); +drop table t1, t2; diff --git a/mysql-test/t/innodb-semi-consistent.test b/mysql-test/t/innodb-semi-consistent.test index 6d3020bb560..61ad7815ca9 100644 --- a/mysql-test/t/innodb-semi-consistent.test +++ b/mysql-test/t/innodb-semi-consistent.test @@ -53,3 +53,16 @@ drop table t1; connection default; disconnect a; disconnect b; + +# Bug 39320 +create table t1 (a int, b int) engine=myisam; +create table t2 (c int, d int, key (c)) engine=innodb; +insert into t1 values (1,1); +insert into t2 values (1,2); +connect (a,localhost,root,,); +connection a; +set session transaction isolation level read committed; +delete from t1 using t1 join t2 on t1.a = t2.c where t2.d in (1); +connection default; +disconnect a; +drop table t1, t2; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index b0353ed5268..9221e389f97 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -6,7 +6,9 @@ # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### @@ -17,6 +19,10 @@ # Small basic test with ignore # +-- disable_query_log +SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency; +-- enable_query_log + --disable_warnings drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; @@ -2524,6 +2530,8 @@ DROP TABLE bug35537; DISCONNECT c1; CONNECTION default; +SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # @@ -2532,7 +2540,9 @@ CONNECTION default; # Use innodb_mysql.[test|result] files instead. # # # # If nevertheless you need to make some changes here, please, forward # -# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com # +# your commit message # +# To: innodb_dev_ww@oracle.com # +# Cc: dev-innodb@mysql.com # # (otherwise your changes may be erased). # # # ####################################################################### diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 9b2f3250486..5430190fa51 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -656,6 +656,21 @@ struct row_prebuilt_struct { This eliminates lock waits in some cases; note that this breaks serializability. */ + ulint new_rec_locks; /* normally 0; if + srv_locks_unsafe_for_binlog is + TRUE or session is using READ + COMMITTED isolation level, in a + cursor search, if we set a new + record lock on an index, this is + incremented; this is used in + releasing the locks under the + cursors if we are performing an + UPDATE and we determine after + retrieving the row that it does + not need to be locked; thus, + these can be used to implement a + 'mini-rollback' that releases + the latest record locks */ ulint mysql_prefix_len;/* byte offset of the end of the last requested column */ ulint mysql_row_len; /* length in bytes of a row in the diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 5017c15aaf0..f0833bc6f21 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -21,34 +21,6 @@ Created 3/26/1996 Heikki Tuuri extern ulint trx_n_mysql_transactions; -/***************************************************************** -Resets the new record lock info in a transaction struct. */ -UNIV_INLINE -void -trx_reset_new_rec_lock_info( -/*========================*/ - trx_t* trx); /* in: transaction struct */ -/***************************************************************** -Registers that we have set a new record lock on an index. We only have space -to store 2 indexes! If this is called to store more than 2 indexes after -trx_reset_new_rec_lock_info(), then this function does nothing. */ -UNIV_INLINE -void -trx_register_new_rec_lock( -/*======================*/ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index); /* in: trx sets a new record lock on this - index */ -/***************************************************************** -Checks if trx has set a new record lock on an index. */ -UNIV_INLINE -ibool -trx_new_rec_locks_contain( -/*======================*/ - /* out: TRUE if trx has set a new record lock - on index */ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index); /* in: index */ /************************************************************************ Releases the search latch if trx has reserved it. */ @@ -527,20 +499,6 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ - dict_index_t* new_rec_locks[2];/* these are normally NULL; if - srv_locks_unsafe_for_binlog is TRUE - or session is using READ COMMITTED - isolation level, - in a cursor search, if we set a new - record lock on an index, this is set - to point to the index; this is - used in releasing the locks under the - cursors if we are performing an UPDATE - and we determine after retrieving - the row that it does not need to be - locked; thus, these can be used to - implement a 'mini-rollback' that - releases the latest record locks */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index d562db233e9..09b2f822ff7 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -38,61 +38,3 @@ trx_start_if_not_started_low( trx_start_low(trx, ULINT_UNDEFINED); } } - -/***************************************************************** -Resets the new record lock info in a transaction struct. */ -UNIV_INLINE -void -trx_reset_new_rec_lock_info( -/*========================*/ - trx_t* trx) /* in: transaction struct */ -{ - trx->new_rec_locks[0] = NULL; - trx->new_rec_locks[1] = NULL; -} - -/***************************************************************** -Registers that we have set a new record lock on an index. We only have space -to store 2 indexes! If this is called to store more than 2 indexes after -trx_reset_new_rec_lock_info(), then this function does nothing. */ -UNIV_INLINE -void -trx_register_new_rec_lock( -/*======================*/ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index) /* in: trx sets a new record lock on this - index */ -{ - if (trx->new_rec_locks[0] == NULL) { - trx->new_rec_locks[0] = index; - - return; - } - - if (trx->new_rec_locks[0] == index) { - - return; - } - - if (trx->new_rec_locks[1] != NULL) { - - return; - } - - trx->new_rec_locks[1] = index; -} - -/***************************************************************** -Checks if trx has set a new record lock on an index. */ -UNIV_INLINE -ibool -trx_new_rec_locks_contain( -/*======================*/ - /* out: TRUE if trx has set a new record lock - on index */ - trx_t* trx, /* in: transaction struct */ - dict_index_t* index) /* in: index */ -{ - return(trx->new_rec_locks[0] == index - || trx->new_rec_locks[1] == index); -} diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index d9bc8ba09e4..5afd19aa7e7 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1970,12 +1970,6 @@ lock_rec_lock_fast( if (lock == NULL) { if (!impl) { lock_rec_create(mode, rec, index, trx); - - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } return(TRUE); @@ -1999,11 +1993,6 @@ lock_rec_lock_fast( if (!lock_rec_get_nth_bit(lock, heap_no)) { lock_rec_set_nth_bit(lock, heap_no); - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } } @@ -2058,22 +2047,12 @@ lock_rec_lock_slow( enough already granted on the record, we have to wait. */ err = lock_rec_enqueue_waiting(mode, rec, index, thr); - - if (srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } else { if (!impl) { /* Set the requested lock on the record */ lock_rec_add_to_queue(LOCK_REC | mode, rec, index, trx); - if (srv_locks_unsafe_for_binlog - || trx->isolation_level - == TRX_ISO_READ_COMMITTED) { - trx_register_new_rec_lock(trx, index); - } } err = DB_SUCCESS; diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 088d944cb91..2d9ed4fc944 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1476,12 +1476,9 @@ row_unlock_for_mysql( and clust_pcur, and we do not need to reposition the cursors. */ { - dict_index_t* index; btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur; trx_t* trx = prebuilt->trx; - rec_t* rec; - mtr_t mtr; ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1501,9 +1498,12 @@ row_unlock_for_mysql( trx->op_info = "unlock_row"; - index = btr_pcur_get_btr_cur(pcur)->index; + if (prebuilt->new_rec_locks >= 1) { - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { + rec_t* rec; + dict_index_t* index; + dulint rec_trx_id; + mtr_t mtr; mtr_start(&mtr); @@ -1514,43 +1514,64 @@ row_unlock_for_mysql( } rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; - lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + if (prebuilt->new_rec_locks >= 2) { + /* Restore the cursor position and find the record + in the clustered index. */ - mtr_commit(&mtr); + if (!has_latches_on_recs) { + btr_pcur_restore_position(BTR_SEARCH_LEAF, + clust_pcur, &mtr); + } - /* If the search was done through the clustered index, then - we have not used clust_pcur at all, and we must NOT try to - reset locks on clust_pcur. The values in clust_pcur may be - garbage! */ - - if (index->type & DICT_CLUSTERED) { - - goto func_exit; - } - } - - index = btr_pcur_get_btr_cur(clust_pcur)->index; - - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { - - mtr_start(&mtr); - - /* Restore the cursor position and find the record */ - - if (!has_latches_on_recs) { - btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur, - &mtr); + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; } - rec = btr_pcur_get_rec(clust_pcur); + /* If the record has been modified by this + transaction, do not unlock it. */ + ut_a(index->type & DICT_CLUSTERED); - lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + if (index->trx_id_offset) { + rec_trx_id = trx_read_trx_id(rec + + index->trx_id_offset); + } else { + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; + + *offsets_ = (sizeof offsets_) / sizeof *offsets_; + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); + + rec_trx_id = row_get_rec_trx_id(rec, index, offsets); + + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } + } + + if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) { + /* We did not update the record: unlock it */ + + rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; + + lock_rec_unlock(trx, rec, prebuilt->select_lock_type); + + if (prebuilt->new_rec_locks >= 2) { + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; + + lock_rec_unlock(trx, rec, + prebuilt->select_lock_type); + } + } mtr_commit(&mtr); } -func_exit: trx->op_info = ""; return(DB_SUCCESS); diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index f53dfe8a686..1746fb39f43 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2901,8 +2901,9 @@ row_sel_get_clust_rec_for_mysql( func_exit: *out_rec = clust_rec; - if (prebuilt->select_lock_type == LOCK_X) { - /* We may use the cursor in update: store its position */ + if (prebuilt->select_lock_type != LOCK_NONE) { + /* We may use the cursor in update or in unlock_row(): + store its position */ btr_pcur_store_position(prebuilt->clust_pcur, mtr); } @@ -3303,13 +3304,7 @@ row_search_for_mysql( is set or session is using a READ COMMITED isolation level. Then we are able to remove the record locks set here on an individual row. */ - - if ((srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - - trx_reset_new_rec_lock_info(trx); - } + prebuilt->new_rec_locks = 0; /*-------------------------------------------------------------*/ /* PHASE 1: Try to pop the row from the prefetch cache */ @@ -3951,6 +3946,12 @@ no_gap_lock: switch (err) { rec_t* old_vers; case DB_SUCCESS: + if (srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) { + /* Note that a record of + prebuilt->index was locked. */ + prebuilt->new_rec_locks = 1; + } break; case DB_LOCK_WAIT: if (UNIV_LIKELY(prebuilt->row_read_type @@ -3981,7 +3982,7 @@ no_gap_lock: if (UNIV_LIKELY(trx->wait_lock != NULL)) { lock_cancel_waiting_and_release( trx->wait_lock); - trx_reset_new_rec_lock_info(trx); + prebuilt->new_rec_locks = 0; } else { mutex_exit(&kernel_mutex); @@ -3993,6 +3994,9 @@ no_gap_lock: ULINT_UNDEFINED, &heap); err = DB_SUCCESS; + /* Note that a record of + prebuilt->index was locked. */ + prebuilt->new_rec_locks = 1; break; } mutex_exit(&kernel_mutex); @@ -4142,6 +4146,15 @@ requires_clust_rec: goto next_rec; } + if ((srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { + /* Note that both the secondary index record + and the clustered index record were locked. */ + ut_ad(prebuilt->new_rec_locks == 1); + prebuilt->new_rec_locks = 2; + } + if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) { /* The record is delete marked: we can skip it */ @@ -4267,13 +4280,7 @@ next_rec: prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; } did_semi_consistent_read = FALSE; - - if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog - || trx->isolation_level == TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - - trx_reset_new_rec_lock_info(trx); - } + prebuilt->new_rec_locks = 0; /*-------------------------------------------------------------*/ /* PHASE 5: Move the cursor to the next index record */ @@ -4379,7 +4386,7 @@ lock_wait_or_error: rec_loop we will again try to set a lock, and new_rec_lock_info in trx will be right at the end. */ - trx_reset_new_rec_lock_info(trx); + prebuilt->new_rec_locks = 0; } mode = pcur->search_mode; diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 43456865903..8ada38845c5 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -192,8 +192,6 @@ trx_create( trx->n_autoinc_rows = 0; - trx_reset_new_rec_lock_info(trx); - return(trx); } From 2a6c67e2be57dfb3674c08e1b6ab9cd4ae567582 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:24:13 +0200 Subject: [PATCH 122/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2857.1.8 > revision-id: sergey.glukhov@sun.com-20090417084627-yvt63k51vvvjbx9j > parent: anurag.shekhar@sun.com-20090417055354-7vw80v1rwn0z1tt4 > parent: sergey.glukhov@sun.com-20090417074115-dv9h5ijalj2hgq3r > committer: Sergey Glukhov > branch nick: mysql-5.1-bugteam > timestamp: Fri 2009-04-17 13:46:27 +0500 > message: > 5.0-bugteam->5.1-bugteam merge > ------------------------------------------------------------ > revno: 1810.3882.12 > revision-id: sergey.glukhov@sun.com-20090417074115-dv9h5ijalj2hgq3r > parent: patrick.crews@sun.com-20090416174744-u9fxu6ophud91a1h > committer: Sergey Glukhov > branch nick: mysql-5.0-bugteam > timestamp: Fri 2009-04-17 12:41:15 +0500 > message: > Bug#44151 using handler commands on information_schema tables crashes server > information schema tables are based on internal tmp tables which are removed > after each statement execution. So HANDLER comands can not be used with > information schema. --- mysql-test/include/handler.inc | 8 ++++++++ mysql-test/r/handler_innodb.result | 4 ++++ mysql-test/r/handler_myisam.result | 4 ++++ sql/sql_handler.cc | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc index 4eb9e413822..96f90aba8e0 100644 --- a/mysql-test/include/handler.inc +++ b/mysql-test/include/handler.inc @@ -720,3 +720,11 @@ connection con1; drop table t1; disconnect con1; connection default; + +# +# Bug#44151 using handler commands on information_schema tables crashes server +# +USE information_schema; +--error ER_WRONG_USAGE +HANDLER COLUMNS OPEN; +USE test; diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result index 59a46cabe5f..957fc30acef 100644 --- a/mysql-test/r/handler_innodb.result +++ b/mysql-test/r/handler_innodb.result @@ -739,3 +739,7 @@ handler t1 read a next; ERROR HY000: Table storage engine for 't1' doesn't have this option handler t1 close; drop table t1; +USE information_schema; +HANDLER COLUMNS OPEN; +ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema +USE test; diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result index afbf2d9fb6d..dde6a4586bc 100644 --- a/mysql-test/r/handler_myisam.result +++ b/mysql-test/r/handler_myisam.result @@ -737,3 +737,7 @@ handler t1 read a next; ERROR HY000: Table storage engine for 't1' doesn't have this option handler t1 close; drop table t1; +USE information_schema; +HANDLER COLUMNS OPEN; +ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema +USE test; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 9c8bba6208c..16810e29343 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -199,6 +199,14 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) tables->db, tables->table_name, tables->alias, (int) reopen)); + if (tables->schema_table) + { + my_error(ER_WRONG_USAGE, MYF(0), "HANDLER OPEN", + INFORMATION_SCHEMA_NAME.str); + DBUG_PRINT("exit",("ERROR")); + DBUG_RETURN(TRUE); + } + if (! hash_inited(&thd->handler_tables_hash)) { /* From 41f812677f37bd926d224cddaaaab522a7495751 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 24 Jun 2009 19:34:19 +0200 Subject: [PATCH 123/188] Backport into build-200906240007-5.1.34sp1 > ------------------------------------------------------------ > revno: 2871.4.1 > revision-id: vvaintroub@mysql.com-20090429115110-1ye4700m8it5tyc5 > parent: staale.smedseng@sun.com-20090428161955-3vnku1igwt0knpfu > committer: Vladislav Vaintroub > branch nick: mysql-5.1-bugteam > timestamp: Wed 2009-04-29 13:51:10 +0200 > message: > Bug#43932 myisam index corruption with large index and large > key_buffer_size. > > The cause of corruption was number overflow when multiplying > two ulong values, number of used keycache blocks with size > of a single block. The result of multiplication exceeded ulong > range (4G) and this lead to incorrectly calculated buffer offset > in the key cache. > > The fix is to use size_t for multiplication result. > > This patch also fixes pointless cast in safemalloc > (size of allocated block to uint), that creates lot of false > alarm warnings when using big keycache (> 4GB) in debug mode. --- mysys/mf_keycache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 397a3332740..16bcb11eb91 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -2044,13 +2044,15 @@ restart: } else { + size_t block_mem_offset; /* There are some never used blocks, take first of them */ DBUG_ASSERT(keycache->blocks_used < (ulong) keycache->disk_blocks); block= &keycache->block_root[keycache->blocks_used]; + block_mem_offset= + ((size_t) keycache->blocks_used) * keycache->key_cache_block_size; block->buffer= ADD_TO_PTR(keycache->block_mem, - ((ulong) keycache->blocks_used* - keycache->key_cache_block_size), + block_mem_offset, uchar*); keycache->blocks_used++; DBUG_ASSERT(!block->next_used); From f7435b89023b76fbbc492a69472aab936a70c238 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Thu, 25 Jun 2009 00:15:51 +0200 Subject: [PATCH 124/188] bump version to 5.1.34sp1 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index d86218bd782..7ac10bf408b 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.34) +AM_INIT_AUTOMAKE(mysql, 5.1.34sp1) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From bebc98759507a23914a54acc445916eeab130561 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 25 Jun 2009 11:22:39 +0500 Subject: [PATCH 125/188] Bug#45485 replication different between master/slaver using procedure with gbk In Item_param::set_from_user_var value.cs_info.character_set_client is set to 'fromcs' value. It's wrong, it should be set to thd->variables.character_set_client. mysql-test/r/ctype_gbk_binlog.result: test result mysql-test/t/ctype_gbk_binlog.test: test case sql/item.cc: In Item_param::set_from_user_var value.cs_info.character_set_client is set to 'fromcs' value. It's wrong, it should be set to thd->variables.character_set_client. --- mysql-test/r/ctype_gbk_binlog.result | 26 ++++++++++++++++++++ mysql-test/t/ctype_gbk_binlog.test | 36 ++++++++++++++++++++++++++++ sql/item.cc | 4 ++-- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/ctype_gbk_binlog.result create mode 100644 mysql-test/t/ctype_gbk_binlog.test diff --git a/mysql-test/r/ctype_gbk_binlog.result b/mysql-test/r/ctype_gbk_binlog.result new file mode 100644 index 00000000000..a49e170ff19 --- /dev/null +++ b/mysql-test/r/ctype_gbk_binlog.result @@ -0,0 +1,26 @@ +SET NAMES gbk; +CREATE TABLE t1 ( +f1 BLOB +) ENGINE=MyISAM DEFAULT CHARSET=gbk; +CREATE PROCEDURE p1(IN val BLOB) +BEGIN +SET @tval = val; +SET @sql_cmd = CONCAT_WS(' ', 'insert into t1(f1) values(?)'); +PREPARE stmt FROM @sql_cmd; +EXECUTE stmt USING @tval; +DEALLOCATE PREPARE stmt; +END| +SET @`tcontent`:=_binary 0x50434B000900000000000000E9000000 COLLATE `binary`/*!*/; +CALL p1(@`tcontent`); +FLUSH LOGS; +DROP PROCEDURE p1; +RENAME TABLE t1 to t2; +SELECT hex(f1) FROM t2; +hex(f1) +50434B000900000000000000E9000000 +SELECT hex(f1) FROM t1; +hex(f1) +50434B000900000000000000E9000000 +DROP PROCEDURE p1; +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/t/ctype_gbk_binlog.test b/mysql-test/t/ctype_gbk_binlog.test new file mode 100644 index 00000000000..99763667f4f --- /dev/null +++ b/mysql-test/t/ctype_gbk_binlog.test @@ -0,0 +1,36 @@ +-- source include/have_log_bin.inc +-- source include/have_gbk.inc + +SET NAMES gbk; +--character_set gbk + +CREATE TABLE t1 ( + f1 BLOB +) ENGINE=MyISAM DEFAULT CHARSET=gbk; + +delimiter |; +CREATE PROCEDURE p1(IN val BLOB) +BEGIN + SET @tval = val; + SET @sql_cmd = CONCAT_WS(' ', 'insert into t1(f1) values(?)'); + PREPARE stmt FROM @sql_cmd; + EXECUTE stmt USING @tval; + DEALLOCATE PREPARE stmt; +END| +delimiter ;| + +SET @`tcontent`:=_binary 0x50434B000900000000000000E9000000 COLLATE `binary`/*!*/; +CALL p1(@`tcontent`); + +FLUSH LOGS; +DROP PROCEDURE p1; +RENAME TABLE t1 to t2; + +let $MYSQLD_DATADIR= `select @@datadir`; +--exec $MYSQL_BINLOG --force-if-open --short-form $MYSQLD_DATADIR/master-bin.000001 | $MYSQL +SELECT hex(f1) FROM t2; +SELECT hex(f1) FROM t1; + +DROP PROCEDURE p1; +DROP TABLE t1; +DROP TABLE t2; diff --git a/sql/item.cc b/sql/item.cc index e693bf32f61..4c967200a3a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2771,8 +2771,8 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) CHARSET_INFO *tocs= thd->variables.collation_connection; uint32 dummy_offset; - value.cs_info.character_set_of_placeholder= - value.cs_info.character_set_client= fromcs; + value.cs_info.character_set_of_placeholder= fromcs; + value.cs_info.character_set_client= thd->variables.character_set_client; /* Setup source and destination character sets so that they are different only if conversion is necessary: this will From d5f8459beba411357214b8b55e5966c630f17876 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 25 Jun 2009 13:44:50 +0500 Subject: [PATCH 126/188] test case fix mysql-test/r/ctype_cp932_binlog_stm.result: result fix mysql-test/t/ctype_gbk_binlog.test: test fix --- mysql-test/r/ctype_cp932_binlog_stm.result | 16 ++++++++-------- mysql-test/t/ctype_cp932_binlog_stm.test | 5 +++-- mysql-test/t/ctype_gbk_binlog.test | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/ctype_cp932_binlog_stm.result b/mysql-test/r/ctype_cp932_binlog_stm.result index 2f67eb16b2e..044885d1ea7 100644 --- a/mysql-test/r/ctype_cp932_binlog_stm.result +++ b/mysql-test/r/ctype_cp932_binlog_stm.result @@ -9,7 +9,7 @@ EXECUTE stmt1 USING @var1; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; CREATE TABLE t1(f1 blob) -master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES('ƒ\0') +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(0x8300) SELECT HEX(f1) FROM t1; HEX(f1) 8300 @@ -29,22 +29,22 @@ HEX(s1) HEX(s2) d 466F6F2773206120426172 ED40ED41ED42 47.93 DROP PROCEDURE bug18293| DROP TABLE t4| -SHOW BINLOG EVENTS FROM 369| +SHOW BINLOG EVENTS FROM 370| Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 369 Query 1 535 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, +master-bin.000001 370 Query 1 536 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, s2 CHAR(50) CHARACTER SET cp932, d DECIMAL(10,2)) -master-bin.000001 535 Query 1 784 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `bug18293`(IN ins1 CHAR(50), +master-bin.000001 536 Query 1 785 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `bug18293`(IN ins1 CHAR(50), IN ins2 CHAR(50) CHARACTER SET cp932, IN ind DECIMAL(10,2)) BEGIN INSERT INTO t4 VALUES (ins1, ins2, ind); END -master-bin.000001 784 Query 1 1048 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172 COLLATE 'latin1_swedish_ci'), NAME_CONST('ins2',_cp932 0xED40ED41ED42 COLLATE 'cp932_japanese_ci'), NAME_CONST('ind',47.93)) -master-bin.000001 1048 Query 1 1137 use `test`; DROP PROCEDURE bug18293 -master-bin.000001 1137 Query 1 1216 use `test`; DROP TABLE t4 +master-bin.000001 785 Query 1 1049 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172 COLLATE 'latin1_swedish_ci'), NAME_CONST('ins2',_cp932 0xED40ED41ED42 COLLATE 'cp932_japanese_ci'), NAME_CONST('ind',47.93)) +master-bin.000001 1049 Query 1 1138 use `test`; DROP PROCEDURE bug18293 +master-bin.000001 1138 Query 1 1217 use `test`; DROP TABLE t4 End of 5.0 tests -SHOW BINLOG EVENTS FROM 364; +SHOW BINLOG EVENTS FROM 365; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment. CREATE TABLE t1 (a varchar(16)) character set cp932; diff --git a/mysql-test/t/ctype_cp932_binlog_stm.test b/mysql-test/t/ctype_cp932_binlog_stm.test index 9e9716e5ddb..89df33a6df5 100644 --- a/mysql-test/t/ctype_cp932_binlog_stm.test +++ b/mysql-test/t/ctype_cp932_binlog_stm.test @@ -22,7 +22,7 @@ CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)| SELECT HEX(s1),HEX(s2),d FROM t4| DROP PROCEDURE bug18293| DROP TABLE t4| -SHOW BINLOG EVENTS FROM 369| +SHOW BINLOG EVENTS FROM 370| delimiter ;| --echo End of 5.0 tests @@ -31,8 +31,9 @@ delimiter ;| # #28436: Incorrect position in SHOW BINLOG EVENTS causes server coredump # Note: 364 is a magic position (found experimentally, depends on # the log's contents) that caused the server crash. + --error 1220 -SHOW BINLOG EVENTS FROM 364; +SHOW BINLOG EVENTS FROM 365; --echo Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment. CREATE TABLE t1 (a varchar(16)) character set cp932; diff --git a/mysql-test/t/ctype_gbk_binlog.test b/mysql-test/t/ctype_gbk_binlog.test index 99763667f4f..a8f653d1b1e 100644 --- a/mysql-test/t/ctype_gbk_binlog.test +++ b/mysql-test/t/ctype_gbk_binlog.test @@ -1,4 +1,4 @@ --- source include/have_log_bin.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/have_gbk.inc SET NAMES gbk; From 0158cafab9275dcba4f718be1c92bbeb923ca26d Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 25 Jun 2009 15:06:12 +0530 Subject: [PATCH 127/188] Applying InnoDB snashot 5.0-ss5406, part 1. Fixes BUG#38479 BUG#38479 - valgrind warnings in show table status for innodb tables Detailed revision comments: r5080 | vasil | 2009-05-22 14:45:34 +0300 (Fri, 22 May 2009) | 6 lines branches/5.0: Fix Bug#38479 valgrind warnings in show table status for innodb tables by initializing prebuilt->hint_need_to_fetch_extra_cols. --- innobase/row/row0mysql.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index d7213b25145..cab6a9ce272 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -625,7 +625,9 @@ row_create_prebuilt( prebuilt->ins_node = NULL; prebuilt->ins_upd_rec_buff = NULL; - + + prebuilt->hint_need_to_fetch_extra_cols = 0; + prebuilt->upd_node = NULL; prebuilt->ins_graph = NULL; prebuilt->upd_graph = NULL; From faaa9e0855ceaee0ba3611e21b4e7ee69659a9ae Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 25 Jun 2009 15:20:26 +0530 Subject: [PATCH 128/188] Applying InnoDB snashot 5.0-ss5406, part 2. Fixes BUG#40565 BUG#40565 - Update Query Results in "1 Row Affected" But Should Be "Zero Rows" Detailed revision comments: r5232 | marko | 2009-06-03 14:31:04 +0300 (Wed, 03 Jun 2009) | 21 lines branches/5.0: Merge r3590 from branches/5.1 in order to fix Bug #40565 (Update Query Results in "1 Row Affected" But Should Be "Zero Rows"). Also, add a test case for Bug #40565. rb://128 approved by Heikki Tuuri ------------------------------------------------------------------------ r3590 | marko | 2008-12-18 15:33:36 +0200 (Thu, 18 Dec 2008) | 11 lines branches/5.1: When converting a record to MySQL format, copy the default column values for columns that are SQL NULL. This addresses failures in row-based replication (Bug #39648). row_prebuilt_t: Add default_rec, for the default values of the columns in MySQL format. row_sel_store_mysql_rec(): Use prebuilt->default_rec instead of padding columns. rb://64 approved by Heikki Tuuri ------------------------------------------------------------------------ --- innobase/include/row0mysql.h | 2 + innobase/row/row0mysql.c | 2 + innobase/row/row0sel.c | 57 ++++------------------------- mysql-test/r/innodb_bug40565.result | 9 +++++ mysql-test/t/innodb_bug40565.test | 10 +++++ sql/ha_innodb.cc | 3 ++ 6 files changed, 33 insertions(+), 50 deletions(-) create mode 100644 mysql-test/r/innodb_bug40565.result create mode 100644 mysql-test/t/innodb_bug40565.test diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 9e28fabe491..2349539eafd 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -581,6 +581,8 @@ struct row_prebuilt_struct { byte* ins_upd_rec_buff;/* buffer for storing data converted to the Innobase format from the MySQL format */ + const void* default_rec; /* the default values of all columns + (a "default row") in MySQL format */ ulint hint_need_to_fetch_extra_cols; /* normally this is set to 0; if this is set to ROW_RETRIEVE_PRIMARY_KEY, diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index cab6a9ce272..75c54cec4b3 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -626,6 +626,8 @@ row_create_prebuilt( prebuilt->ins_upd_rec_buff = NULL; + prebuilt->default_rec = NULL; + prebuilt->hint_need_to_fetch_extra_cols = 0; prebuilt->upd_node = NULL; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index c956492900d..973d8fad2e7 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2423,8 +2423,9 @@ row_sel_store_mysql_rec( byte* data; ulint len; ulint i; - + ut_ad(prebuilt->mysql_template); + ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { @@ -2520,58 +2521,14 @@ row_sel_store_mysql_rec( ~(byte) (templ->mysql_null_bit_mask); } } else { - /* MySQL seems to assume the field for an SQL NULL - value is set to zero or space. Not taking this into - account caused seg faults with NULL BLOB fields, and - bug number 154 in the MySQL bug database: GROUP BY - and DISTINCT could treat NULL values inequal. */ - int pad_char; + /* MySQL assumes that the field for an SQL + NULL value is set to the default value. */ mysql_rec[templ->mysql_null_byte_offset] |= (byte) (templ->mysql_null_bit_mask); - switch (templ->type) { - case DATA_VARCHAR: - case DATA_BINARY: - case DATA_VARMYSQL: - if (templ->mysql_type - == DATA_MYSQL_TRUE_VARCHAR) { - /* This is a >= 5.0.3 type - true VARCHAR. Zero the field. */ - pad_char = 0x00; - break; - } - /* Fall through */ - case DATA_CHAR: - case DATA_FIXBINARY: - case DATA_MYSQL: - /* MySQL pads all string types (except - BLOB, TEXT and true VARCHAR) with space. */ - if (UNIV_UNLIKELY(templ->mbminlen == 2)) { - /* Treat UCS2 as a special case. */ - data = mysql_rec - + templ->mysql_col_offset; - len = templ->mysql_col_len; - /* There are two UCS2 bytes per char, - so the length has to be even. */ - ut_a(!(len & 1)); - /* Pad with 0x0020. */ - while (len) { - *data++ = 0x00; - *data++ = 0x20; - len -= 2; - } - continue; - } - pad_char = 0x20; - break; - default: - pad_char = 0x00; - break; - } - - ut_ad(!pad_char || templ->mbminlen == 1); - memset(mysql_rec + templ->mysql_col_offset, - pad_char, templ->mysql_col_len); + memcpy(mysql_rec + templ->mysql_col_offset, + prebuilt->default_rec + templ->mysql_col_offset, + templ->mysql_col_len); } } diff --git a/mysql-test/r/innodb_bug40565.result b/mysql-test/r/innodb_bug40565.result new file mode 100644 index 00000000000..21e923d9336 --- /dev/null +++ b/mysql-test/r/innodb_bug40565.result @@ -0,0 +1,9 @@ +create table bug40565(value decimal(4,2)) engine=innodb; +insert into bug40565 values (1), (null); +update bug40565 set value=NULL; +affected rows: 1 +info: Rows matched: 2 Changed: 1 Warnings: 0 +update bug40565 set value=NULL; +affected rows: 0 +info: Rows matched: 2 Changed: 0 Warnings: 0 +drop table bug40565; diff --git a/mysql-test/t/innodb_bug40565.test b/mysql-test/t/innodb_bug40565.test new file mode 100644 index 00000000000..d7aa0fd514a --- /dev/null +++ b/mysql-test/t/innodb_bug40565.test @@ -0,0 +1,10 @@ +# Bug #40565 Update Query Results in "1 Row Affected" But Should Be "Zero Rows" +-- source include/have_innodb.inc + +create table bug40565(value decimal(4,2)) engine=innodb; +insert into bug40565 values (1), (null); +--enable_info +update bug40565 set value=NULL; +update bug40565 set value=NULL; +--disable_info +drop table bug40565; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f71e891e88d..7eb6ef05d9c 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2253,6 +2253,9 @@ ha_innobase::open( ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->s->reclength; + ((row_prebuilt_t*)innobase_prebuilt)->default_rec + = table->s->default_values; + ut_ad(table->s->default_values); /* Looks like MySQL-3.23 sometimes has primary key number != 0 */ From 5eab9716ba7e335824ee373780f623355627d25b Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 25 Jun 2009 15:52:50 +0500 Subject: [PATCH 129/188] Bug#45412 SHOW CREATE TRIGGER does not require privileges to disclose trigger data Added privilege checking to SHOW CREATE TRIGGER code. mysql-test/r/trigger_notembedded.result: test result mysql-test/t/trigger_notembedded.test: test case sql/sql_show.cc: Added privilege checking to SHOW CREATE TRIGGER code. --- mysql-test/r/trigger_notembedded.result | 14 ++++++++++++++ mysql-test/t/trigger_notembedded.test | 23 +++++++++++++++++++++++ sql/sql_show.cc | 6 ++++++ 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result index 1e13bff03b1..335e6910a3a 100644 --- a/mysql-test/r/trigger_notembedded.result +++ b/mysql-test/r/trigger_notembedded.result @@ -462,4 +462,18 @@ unlock tables; select * from t1; i drop table t1; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a char(30)) ENGINE=MEMORY; +CREATE TRIGGER db1.trg AFTER INSERT ON db1.t1 FOR EACH ROW +INSERT INTO db1.t1 VALUES('Some very sensitive data goes here'); +CREATE USER 'no_rights'@'localhost'; +REVOKE ALL ON *.* FROM 'no_rights'@'localhost'; +FLUSH PRIVILEGES; +SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS +WHERE trigger_schema = 'db1'; +trigger_name +SHOW CREATE TRIGGER db1.trg; +ERROR 42000: Access denied; you need the TRIGGER privilege for this operation +DROP USER 'no_rights'@'localhost'; +DROP DATABASE db1; End of 5.1 tests. diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test index 9588ec6e3ed..7a7e6c6bc85 100644 --- a/mysql-test/t/trigger_notembedded.test +++ b/mysql-test/t/trigger_notembedded.test @@ -909,4 +909,27 @@ select * from t1; drop table t1; disconnect flush; +# +# Bug#45412 SHOW CREATE TRIGGER does not require privileges to disclose trigger data +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a char(30)) ENGINE=MEMORY; +CREATE TRIGGER db1.trg AFTER INSERT ON db1.t1 FOR EACH ROW + INSERT INTO db1.t1 VALUES('Some very sensitive data goes here'); + +CREATE USER 'no_rights'@'localhost'; +REVOKE ALL ON *.* FROM 'no_rights'@'localhost'; +FLUSH PRIVILEGES; + +connect (con1,localhost,no_rights,,); +SELECT trigger_name FROM INFORMATION_SCHEMA.TRIGGERS + WHERE trigger_schema = 'db1'; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +SHOW CREATE TRIGGER db1.trg; + +connection default; +disconnect con1; +DROP USER 'no_rights'@'localhost'; +DROP DATABASE db1; + --echo End of 5.1 tests. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3964e38db5e..d07e951bfd1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7071,6 +7071,12 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) if (!lst) return TRUE; + if (check_table_access(thd, TRIGGER_ACL, lst, 1, TRUE)) + { + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "TRIGGER"); + return TRUE; + } + /* Open the table by name in order to load Table_triggers_list object. From de91a33d5e1d73e480a1fcee10020ed34f595118 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Thu, 25 Jun 2009 15:55:26 +0200 Subject: [PATCH 130/188] Bug#45336 --enable-foobar doesn't work for any plugin foobar. Because of a regression introduced by bug#19027 the option --enable-foobar doesn't work anymore for any plugin 'foobar'. The reason is that plugin names are tristate options variables with optional parameters and integer values are not accepted. Since the 'enable' prefix attempts to assign '1' to the option the operation fails. This patch translates any number n assigned to a plugin variable of type ENUM to be the corresponding enumerated item. As a side effect --enable-foobar and --disable-foobar will also start working again. mysys/my_getopt.c: * setval now accepts integer values for option variables of type ENUM. --- mysys/my_getopt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 33942d87e4f..fd3c2501226 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -20,6 +20,7 @@ #include #include #include +#include typedef void (*init_func_p)(const struct my_option *option, uchar* *variable, longlong value); @@ -649,8 +650,18 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument, return EXIT_OUT_OF_MEMORY; break; case GET_ENUM: - if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0) - return EXIT_ARGUMENT_INVALID; + if (((*(int*)result_pos)= + find_type(argument, opts->typelib, 2) - 1) < 0) + { + /* + Accept an integer representation of the enumerated item. + */ + char *endptr; + unsigned int arg= (unsigned int) strtol(argument, &endptr, 10); + if (*endptr || arg >= opts->typelib->count) + return EXIT_ARGUMENT_INVALID; + *(int*)result_pos= arg; + } break; case GET_SET: *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err); From 0fdebc8c49a14685b8ff1cc79f1379f0415ecf5a Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 26 Jun 2009 12:05:56 +0100 Subject: [PATCH 131/188] BUG#44270: Post-push fix The test case added failed sporadically on PB. This is due to the fact that the user thread in some cases is waiting for slave IO to stop and then check the error number. Thence, sometimes the user thread would race for the error number with IO thread. This post push fix addresses this by replacing the wait for slave io to stop with a wait for slave io error (as it seems it was added in 6.0 also after patch on which this is based was pushed). This implied backporting wait_for_slave_io_error.inc from 6.0 also. --- .../extra/rpl_tests/rpl_reset_slave.test | 4 ++-- .../include/wait_for_slave_io_error.inc | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/wait_for_slave_io_error.inc diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 49a142f10c2..1f88c792fce 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -58,7 +58,7 @@ echo *** errno must be zero: $last_io_errno ***; change master to master_user='impossible_user_name'; start slave; -source include/wait_for_slave_io_to_stop.inc; +source include/wait_for_slave_io_error.inc; let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); --disable_query_log eval SELECT $last_io_errno > 0 as ONE; @@ -79,7 +79,7 @@ let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1); source include/stop_slave.inc; change master to master_user='impossible_user_name'; start slave; -source include/wait_for_slave_io_to_stop.inc; +source include/wait_for_slave_io_error.inc; let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1); --disable_query_log eval SELECT $last_io_errno > 0 as ONE; diff --git a/mysql-test/include/wait_for_slave_io_error.inc b/mysql-test/include/wait_for_slave_io_error.inc new file mode 100644 index 00000000000..094406e02b2 --- /dev/null +++ b/mysql-test/include/wait_for_slave_io_error.inc @@ -0,0 +1,23 @@ +# ==== Purpose ==== +# +# Waits until the IO thread of the current connection has got an +# error, or until a timeout is reached. +# +# ==== Usage ==== +# +# source include/wait_for_slave_io_error.inc; +# +# Parameters to this macro are $slave_timeout and +# $slave_keep_connection. See wait_for_slave_param.inc for +# descriptions. + +let $old_slave_param_comparison= $slave_param_comparison; + +let $slave_param= Last_IO_Errno; +let $slave_param_comparison= !=; +let $slave_param_value= 0; +let $slave_error_message= Failed while waiting for slave to produce an error in its sql thread; +source include/wait_for_slave_param.inc; +let $slave_error_message= ; + +let $slave_param_comparison= $old_slave_param_comparison; From eefdd70ab2bf00146c399a3ed042f77ac74730b8 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 25 Jun 2009 12:25:23 -0300 Subject: [PATCH 132/188] Bug#45548: XA transaction without access to InnoDB tables crashes the server The problem is that the one phase commit function failed to properly end a empty transaction. The solution is to ensure that the transaction cleanup procedure is invoked even for empty transactions. mysql-test/r/xa.result: Add test case result for Bug#45548 mysql-test/t/xa.test: Add test case for Bug#45548 sql/handler.cc: Invoke transaction cleanup function whenever a transaction is ended. --- mysql-test/r/xa.result | 8 ++++++++ mysql-test/t/xa.test | 14 ++++++++++++++ sql/handler.cc | 5 +++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 92f52b402ec..a597806d897 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -81,3 +81,11 @@ xa rollback 'a'; xa start 'a'; xa end 'a'; xa rollback 'a'; +xa start 'a'; +xa end 'a'; +xa prepare 'a'; +xa commit 'a'; +xa start 'a'; +xa end 'a'; +xa prepare 'a'; +xa commit 'a'; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index a0d5aa60641..7b1c6a268d5 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -135,6 +135,20 @@ xa start 'a'; xa end 'a'; xa rollback 'a'; +# +# Bug#45548: XA transaction without access to InnoDB tables crashes the server +# + +xa start 'a'; +xa end 'a'; +xa prepare 'a'; +xa commit 'a'; + +xa start 'a'; +xa end 'a'; +xa prepare 'a'; +xa commit 'a'; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/handler.cc b/sql/handler.cc index 7e584b8fcf3..e65ceba4181 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1242,9 +1242,10 @@ int ha_commit_one_phase(THD *thd, bool all) #endif thd->variables.tx_isolation=thd->session_tx_isolation; } - if (is_real_trans) - thd->transaction.cleanup(); } + /* Free resources and perform other cleanup even for 'empty' transactions. */ + if (is_real_trans) + thd->transaction.cleanup(); #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); } From b828da994f7f376be0ce298527952efef17117d1 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Thu, 25 Jun 2009 17:41:05 +0200 Subject: [PATCH 133/188] Bug #34002 uninitialized Rows_examined for some admin queries such as quit and shutdown Logging to slow log can produce an undetermined value for Rows_examined in special cases. In debug mode this manifests itself as any of the various marker values used to mark uninitialized memory on various platforms. If logging happens on a THD object that hasn't performed any row reads (on this or any previous connections), the THD::examined_row_count may be uninitialized. This patch adds initialization for this attribute. No automated test cases are added, as for this to be meaningful, we need to ensure that we're using a THD fulfilling the above conditions. This is hard to do in the mysql-test-run framework. The patch has been verified manually, however, by restarting mysqld and running the test included with the bug report. --- sql/sql_class.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f1ad410b877..409e4dc4b8b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -546,6 +546,7 @@ THD::THD() first_successful_insert_id_in_prev_stmt_for_binlog(0), first_successful_insert_id_in_cur_stmt(0), stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE), + examined_row_count(0), global_read_lock(0), is_fatal_error(0), transaction_rollback_request(0), From 93bac51ef33b2f368bb81064481ca9398c2480ef Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Fri, 26 Jun 2009 19:57:42 +0000 Subject: [PATCH 134/188] Bug#45266: Uninitialized variable lead to an empty result. The TABLE::reginfo.impossible_range is used by the optimizer to indicate that the condition applied to the table is impossible. It wasn't initialized at table opening and this might lead to an empty result on complex queries: a query might set the impossible_range flag on a table and when the query finishes, all tables are returned back to the table cache. The next query that uses the table with the impossible_range flag set and an index over the table will see the flag and thus return an empty result. The open_table function now initializes the TABLE::reginfo.impossible_range variable. mysql-test/r/select.result: A test case for the bug#45266: Uninitialized variable lead to an empty result. mysql-test/t/select.test: A test case for the bug#45266: Uninitialized variable lead to an empty result. sql/sql_base.cc: Bug#45266: Uninitialized variable lead to an empty result. The open_table function now initializes the TABLE::reginfo.impossible_range variable. sql/sql_select.cc: Bug#45266: Uninitialized variable lead to an empty result. The open_table function now initializes the TABLE::reginfo.impossible_range variable. sql/structs.h: Bug#45266: Uninitialized variable lead to an empty result. A comment is added. --- mysql-test/r/select.result | 79 ++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 86 ++++++++++++++++++++++++++++++++++++++ sql/sql_base.cc | 1 + sql/sql_select.cc | 1 - sql/structs.h | 4 ++ 5 files changed, 170 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 09c7d1b329d..50b5c3c13fb 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4457,4 +4457,83 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1 DROP TABLE t1; +# +# Bug#45266: Uninitialized variable lead to an empty result. +# +drop table if exists A,AA,B,BB; +CREATE TABLE `A` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`date_key` date NOT NULL, +`date_nokey` date NOT NULL, +`datetime_key` datetime NOT NULL, +`int_nokey` int(11) NOT NULL, +`time_key` time NOT NULL, +`time_nokey` time NOT NULL, +PRIMARY KEY (`pk`), +KEY `date_key` (`date_key`), +KEY `time_key` (`time_key`), +KEY `datetime_key` (`datetime_key`) +); +CREATE TABLE `AA` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`int_nokey` int(11) NOT NULL, +`time_key` time NOT NULL, +KEY `time_key` (`time_key`), +PRIMARY KEY (`pk`) +); +CREATE TABLE `B` ( +`date_nokey` date NOT NULL, +`date_key` date NOT NULL, +`time_key` time NOT NULL, +`datetime_nokey` datetime NOT NULL, +`varchar_key` varchar(1) NOT NULL, +KEY `date_key` (`date_key`), +KEY `time_key` (`time_key`), +KEY `varchar_key` (`varchar_key`) +); +INSERT INTO `B` VALUES ('2003-07-28','2003-07-28','15:13:38','0000-00-00 00:00:00','f'),('0000-00-00','0000-00-00','00:05:48','2004-07-02 14:34:13','x'); +CREATE TABLE `BB` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`int_nokey` int(11) NOT NULL, +`date_key` date NOT NULL, +`varchar_nokey` varchar(1) NOT NULL, +`date_nokey` date NOT NULL, +PRIMARY KEY (`pk`), +KEY `date_key` (`date_key`) +); +INSERT INTO `BB` VALUES (10,8,'0000-00-00','i','0000-00-00'),(11,0,'2005-08-18','','2005-08-18'); +SELECT table1 . `pk` AS field1 +FROM +(BB AS table1 INNER JOIN +(AA AS table2 STRAIGHT_JOIN A AS table3 +ON ( table3 . `date_key` = table2 . `pk` )) +ON ( table3 . `datetime_key` = table2 . `int_nokey` )) +WHERE ( table3 . `date_key` <= 4 AND table2 . `pk` = table1 . `varchar_nokey`) +GROUP BY field1 ; +field1 +SELECT table3 .`date_key` field1 +FROM +B table1 LEFT JOIN B table3 JOIN +(BB table6 JOIN A table7 ON table6 .`varchar_nokey`) +ON table6 .`int_nokey` ON table6 .`date_key` + WHERE NOT ( table1 .`varchar_key` AND table7 .`pk`) GROUP BY field1; +field1 +NULL +SELECT table4 . `time_nokey` AS field1 FROM +(AA AS table1 CROSS JOIN +(AA AS table2 STRAIGHT_JOIN +(B AS table3 STRAIGHT_JOIN A AS table4 +ON ( table4 . `date_key` = table3 . `time_key` )) +ON ( table4 . `pk` = table3 . `date_nokey` )) +ON ( table4 . `time_key` = table3 . `datetime_nokey` )) +WHERE ( table4 . `time_key` < table1 . `time_key` AND +table1 . `int_nokey` != 'f') +GROUP BY field1 ORDER BY field1 , field1; +field1 +SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON table5 .`date_nokey` ON table5 .`int_nokey` GROUP BY field2; +field2 +00:05:48 +15:13:38 +drop table A,AA,B,BB; +#end of test for bug#45266 End of 5.1 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 715bdf0e667..7d3785ecccc 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3799,4 +3799,90 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20; EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20; DROP TABLE t1; + +--echo # +--echo # Bug#45266: Uninitialized variable lead to an empty result. +--echo # +--disable_warnings +drop table if exists A,AA,B,BB; +CREATE TABLE `A` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `date_key` date NOT NULL, + `date_nokey` date NOT NULL, + `datetime_key` datetime NOT NULL, + `int_nokey` int(11) NOT NULL, + `time_key` time NOT NULL, + `time_nokey` time NOT NULL, + PRIMARY KEY (`pk`), + KEY `date_key` (`date_key`), + KEY `time_key` (`time_key`), + KEY `datetime_key` (`datetime_key`) +); + +CREATE TABLE `AA` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `int_nokey` int(11) NOT NULL, + `time_key` time NOT NULL, + KEY `time_key` (`time_key`), + PRIMARY KEY (`pk`) +); + +CREATE TABLE `B` ( + `date_nokey` date NOT NULL, + `date_key` date NOT NULL, + `time_key` time NOT NULL, + `datetime_nokey` datetime NOT NULL, + `varchar_key` varchar(1) NOT NULL, + KEY `date_key` (`date_key`), + KEY `time_key` (`time_key`), + KEY `varchar_key` (`varchar_key`) +); + +INSERT INTO `B` VALUES ('2003-07-28','2003-07-28','15:13:38','0000-00-00 00:00:00','f'),('0000-00-00','0000-00-00','00:05:48','2004-07-02 14:34:13','x'); + +CREATE TABLE `BB` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `int_nokey` int(11) NOT NULL, + `date_key` date NOT NULL, + `varchar_nokey` varchar(1) NOT NULL, + `date_nokey` date NOT NULL, + PRIMARY KEY (`pk`), + KEY `date_key` (`date_key`) +); + +INSERT INTO `BB` VALUES (10,8,'0000-00-00','i','0000-00-00'),(11,0,'2005-08-18','','2005-08-18'); +# Test #1 +SELECT table1 . `pk` AS field1 + FROM + (BB AS table1 INNER JOIN + (AA AS table2 STRAIGHT_JOIN A AS table3 + ON ( table3 . `date_key` = table2 . `pk` )) + ON ( table3 . `datetime_key` = table2 . `int_nokey` )) + WHERE ( table3 . `date_key` <= 4 AND table2 . `pk` = table1 . `varchar_nokey`) + GROUP BY field1 ; + +SELECT table3 .`date_key` field1 + FROM + B table1 LEFT JOIN B table3 JOIN + (BB table6 JOIN A table7 ON table6 .`varchar_nokey`) + ON table6 .`int_nokey` ON table6 .`date_key` + WHERE NOT ( table1 .`varchar_key` AND table7 .`pk`) GROUP BY field1; + +# Test #2 +SELECT table4 . `time_nokey` AS field1 FROM + (AA AS table1 CROSS JOIN + (AA AS table2 STRAIGHT_JOIN + (B AS table3 STRAIGHT_JOIN A AS table4 + ON ( table4 . `date_key` = table3 . `time_key` )) + ON ( table4 . `pk` = table3 . `date_nokey` )) + ON ( table4 . `time_key` = table3 . `datetime_nokey` )) + WHERE ( table4 . `time_key` < table1 . `time_key` AND + table1 . `int_nokey` != 'f') + GROUP BY field1 ORDER BY field1 , field1; + +SELECT table1 .`time_key` field2 FROM B table1 LEFT JOIN BB JOIN A table5 ON table5 .`date_nokey` ON table5 .`int_nokey` GROUP BY field2; +--enable_warnings + +drop table A,AA,B,BB; +--echo #end of test for bug#45266 --echo End of 5.1 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 134b45a9100..88e1620b152 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2963,6 +2963,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->insert_values= 0; table->fulltext_searched= 0; table->file->ft_handler= 0; + table->reginfo.impossible_range= 0; /* Catch wrong handling of the auto_increment_field_not_null. */ DBUG_ASSERT(!table->auto_increment_field_not_null); table->auto_increment_field_not_null= FALSE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 41f5e7a1815..916603344e3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2432,7 +2432,6 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, if (select) { select->head=table; - table->reginfo.impossible_range=0; if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, limit, 0)) == 1) DBUG_RETURN(select->quick->records); diff --git a/sql/structs.h b/sql/structs.h index 0a20eee0e9a..a58c18f97c5 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -107,6 +107,10 @@ typedef struct st_reginfo { /* Extra info about reg */ struct st_join_table *join_tab; /* Used by SELECT() */ enum thr_lock_type lock_type; /* How database is used */ bool not_exists_optimize; + /* + TRUE <=> range optimizer found that there is no rows satisfying + table conditions. + */ bool impossible_range; } REGINFO; From 92956ef6277c3eafbfecc341cd39135e8e8579d0 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sat, 27 Jun 2009 14:18:47 +0100 Subject: [PATCH 135/188] BUG#42851: Spurious "Statement is not safe to log in statement format." warnings Despite the fact that a statement would be filtered out from binlog, a warning would still be thrown if it was issued with the LIMIT. This patch addresses this issue by checking the filtering rules before printing out the warning. mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt: Parameter to filter out database: "b42851". mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test: Added a new test case. sql/sql_class.cc: Added filtering rules check to condition used to decide whether to printout warning or not. --- .../binlog/r/binlog_stm_unsafe_warning.result | 30 ++++++++ .../t/binlog_stm_unsafe_warning-master.opt | 1 + .../binlog/t/binlog_stm_unsafe_warning.test | 73 +++++++++++++++++++ sql/sql_class.cc | 4 +- 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result create mode 100644 mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt create mode 100644 mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test diff --git a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result new file mode 100644 index 00000000000..439bff0cfe1 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result @@ -0,0 +1,30 @@ +### NOT filtered database => assertion: warnings ARE shown +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +DROP TABLE t1; +### NOT filtered database => assertion: binlog disabled and warnings ARE NOT shown +SET SQL_LOG_BIN= 0; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +DROP TABLE t1; +SET SQL_LOG_BIN= 1; +### FILTERED database => assertion: warnings ARE NOT shown +CREATE DATABASE b42851; +USE b42851; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +DROP TABLE t1; +DROP DATABASE b42851; diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt new file mode 100644 index 00000000000..24c2027e399 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning-master.opt @@ -0,0 +1 @@ +--binlog-ignore-db=b42851 diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test new file mode 100644 index 00000000000..0bf685ea921 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -0,0 +1,73 @@ +# BUG#42851: Spurious "Statement is not safe to log in statement +# format." warnings +# +# WHY +# === +# +# This test aims at checking that the fix that removes spurious +# entries in the error log when the statement is filtered out from +# binlog, is working. +# +# HOW +# === +# +# The test case is split into three assertions when issuing statements +# containing LIMIT and ORDER BY: +# +# i) issue statements in database that is not filtered => check +# that warnings ARE shown; +# +# ii) issue statements in database that is not filtered, but with +# binlog disabled => check that warnings ARE NOT shown; +# +# iii) issue statements in database that is filtered => check that +# warnings ARE NOT shown. + +-- source include/have_log_bin.inc +-- source include/have_binlog_format_statement.inc + +-- echo ### NOT filtered database => assertion: warnings ARE shown + +-- disable_warnings +DROP TABLE IF EXISTS t1; +-- enable_warnings + +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +DROP TABLE t1; + +-- echo ### NOT filtered database => assertion: binlog disabled and warnings ARE NOT shown + +SET SQL_LOG_BIN= 0; + +-- disable_warnings +DROP TABLE IF EXISTS t1; +-- enable_warnings + +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +DROP TABLE t1; + +SET SQL_LOG_BIN= 1; + +-- echo ### FILTERED database => assertion: warnings ARE NOT shown + +CREATE DATABASE b42851; +USE b42851; + +-- disable_warnings +DROP TABLE IF EXISTS t1; +-- enable_warnings + +CREATE TABLE t1 (a int, b int, primary key (a)); +INSERT INTO t1 VALUES (1,2), (2,3); +UPDATE t1 SET b='4' WHERE a=1 LIMIT 1; +UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1; +DROP TABLE t1; + +# clean up +DROP DATABASE b42851; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 409e4dc4b8b..48ddb42f0d8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -27,6 +27,7 @@ #include "mysql_priv.h" #include "rpl_rli.h" +#include "rpl_filter.h" #include "rpl_record.h" #include "slave.h" #include @@ -3684,7 +3685,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, we should print a warning. */ if (sql_log_bin_toplevel && lex->is_stmt_unsafe() && - variables.binlog_format == BINLOG_FORMAT_STMT) + variables.binlog_format == BINLOG_FORMAT_STMT && + binlog_filter->db_ok(this->db)) { /* A warning can be elevated a error when STRICT sql mode. From db044ad94fedb7a3427d0ffaa4162f18fc1e8add Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Mon, 29 Jun 2009 07:32:17 +0530 Subject: [PATCH 136/188] Bug#45196 Some collations do not sort correctly with IBMDB2I Some collations--including cp1250_czech_cs,latin2_czech_cs, ucs2/utf8_czech_ci, ucs2/utf8_danish_ci--are not being sorted correctly by the IBMDB2I storage engine. This was being caused because the sort order used by DB2 is incompatible with the order expected by MySQL. This patch removes support for the cp1250_czech_cs and latin2_czech_cs collations because it has been determined that the sort order used by DB2 is incompatible with the order expected by MySQL. Users needing a czech collation with IBMDB2I are encouraged to use a Unicode-based collation instead of these single-byte collations. This patch also modifies the DB2 sort sequence used for ucs2/utf8_czech_ci and ucs2/utf8_danish_ci collations to better match the sorting expected by MySQL. This will only affect indexes or tables that are newly created through the IBMDB2I storage engine. Existing IBMDB2I tables will retain the old sort sequence until recreated. mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result: Bug#45196 Some collations do not sort correctly with IBMDB2I Result file for the test case. mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test: Bug#45196 Some collations do not sort correctly with IBMDB2I Adding tests for testing the sort order with the modified collations. storage/ibmdb2i/db2i_collationSupport.cc: Bug#45196 Some collations do not sort correctly with IBMDB2I Remove the support for the cp1250_czech_cs and latin2_czech_cs collations because it has been determined that the sort order used by DB2 is incompatible with the order expected by MySQL. Users needing a czech collation with IBMDB2I are encouraged to use a Unicode-based collation instead of these single-byte collations. This patch also modifies the DB2 sort sequence used for ucs2/utf8_czech_ci and ucs2/utf8_danish_ci collations to better match the sorting expected by MySQL. This will only affect indexes or tables that are newly created through the IBMDB2I storage engine. Existing IBMDB2I tables will retain the old sort sequence until recreated. --- .../suite/ibmdb2i/r/ibmdb2i_bug_45196.result | 33 +++++++++++++++++++ .../suite/ibmdb2i/t/ibmdb2i_bug_45196.test | 26 +++++++++++++++ storage/ibmdb2i/db2i_collationSupport.cc | 14 +++----- 3 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result new file mode 100644 index 00000000000..916e1d93ee5 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45196.result @@ -0,0 +1,33 @@ +drop table if exists t1; +create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i; +insert into t1 values ("ch"),("h"),("i"); +select * from t1 order by c; +c +h +ch +i +drop table t1; +create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i; +insert into t1 values ("ch"),("h"),("i"); +select * from t1 order by c; +c +h +ch +i +drop table t1; +create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i; +insert into t1 values("abc"),("abcd"),("aaaa"); +select c from t1 order by c; +c +abc +abcd +aaaa +drop table t1; +create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i; +insert into t1 values("abc"),("abcd"),("aaaa"); +select c from t1 order by c; +c +abc +abcd +aaaa +drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test new file mode 100644 index 00000000000..17b1d658975 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45196.test @@ -0,0 +1,26 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source suite/ibmdb2i/include/have_i61.inc; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (c char(10), index(c)) collate ucs2_czech_ci engine=ibmdb2i; +insert into t1 values ("ch"),("h"),("i"); +select * from t1 order by c; +drop table t1; + +create table t1 (c char(10), index(c)) collate utf8_czech_ci engine=ibmdb2i; +insert into t1 values ("ch"),("h"),("i"); +select * from t1 order by c; +drop table t1; + +create table t1 (c char(10), index(c)) collate ucs2_danish_ci engine=ibmdb2i; +insert into t1 values("abc"),("abcd"),("aaaa"); +select c from t1 order by c; +drop table t1; + +create table t1 (c char(10), index(c)) collate utf8_danish_ci engine=ibmdb2i; +insert into t1 values("abc"),("abcd"),("aaaa"); +select c from t1 order by c; +drop table t1; diff --git a/storage/ibmdb2i/db2i_collationSupport.cc b/storage/ibmdb2i/db2i_collationSupport.cc index a41f211a689..65a17fd2452 100644 --- a/storage/ibmdb2i/db2i_collationSupport.cc +++ b/storage/ibmdb2i/db2i_collationSupport.cc @@ -44,7 +44,7 @@ OF SUCH DAMAGE. between corresponding array slots but is incomplete without case-sensitivity markers dynamically added to the mySqlSortSequence names. */ -#define MAX_COLLATION 89 +#define MAX_COLLATION 87 static const char* mySQLCollation[MAX_COLLATION] = { {"ascii_general"}, @@ -52,7 +52,6 @@ static const char* mySQLCollation[MAX_COLLATION] = {"big5_chinese"}, {"big5"}, {"cp1250_croatian"}, - {"cp1250_czech"}, {"cp1250_general"}, {"cp1250_polish"}, {"cp1250"}, @@ -84,7 +83,6 @@ static const char* mySQLCollation[MAX_COLLATION] = {"latin1_swedish"}, {"latin1"}, {"latin2_croatian"}, - {"latin2_czech"}, {"latin2_general"}, {"latin2_hungarian"}, {"latin2"}, @@ -146,7 +144,6 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"QACHT04B0"}, {"QBCHT04B0"}, {"QALA20481"}, - {"QBLA20481"}, {"QCLA20481"}, {"QDLA20481"}, {"QELA20481"}, @@ -178,7 +175,6 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"QELA1047C"}, {"QFLA1047C"}, {"QCLA20366"}, - {"QDLA20366"}, {"QELA20366"}, {"QFLA20366"}, {"QGLA20366"}, @@ -190,8 +186,8 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"QDJPN04B0"}, {"QATHA0346"}, {"QBTHA0346"}, - {"ACS"}, - {"ADA"}, + {"ACS_CZ"}, + {"ADA_DK"}, {"AEO"}, {"AET"}, {"QAUCS04B0"}, @@ -211,8 +207,8 @@ static const char* mySqlSortSequence[MAX_COLLATION] = {"*HEX"}, {"QEJPN04B0"}, {"QFJPN04B0"}, - {"ACS"}, - {"ADA"}, + {"ACS_CZ"}, + {"ADA_DK"}, {"AEO"}, {"AET"}, {"QAUCS04B0"}, From 729648c4b776ec4992f6333f0c70b4b749e8d996 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 29 Jun 2009 17:57:22 +0530 Subject: [PATCH 137/188] Additional Fix for BUG#40565 - Update Query Results in "1 Row Affected" But Should Be "Zero Rows" After applying the innodb snapshot 5.0-ss5406 for bug#40565, the windows push build tests failed because of the missing cast of void * pointer in row0sel.c file Informed the innodb developers and received patch by email. innobase/row/row0sel.c: Cast the default_rec which is a void * pointer --- innobase/row/row0sel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 973d8fad2e7..7fbf7fe7328 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2527,7 +2527,8 @@ row_sel_store_mysql_rec( mysql_rec[templ->mysql_null_byte_offset] |= (byte) (templ->mysql_null_bit_mask); memcpy(mysql_rec + templ->mysql_col_offset, - prebuilt->default_rec + templ->mysql_col_offset, + (const byte*) prebuilt->default_rec + + templ->mysql_col_offset, templ->mysql_col_len); } } From 67771508836edda4bad393f1a00d89cd419e3814 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Mon, 29 Jun 2009 15:17:01 +0200 Subject: [PATCH 138/188] Merge from 5.0-bt --- client/mysql.cc | 6 +- client/mysqlbinlog.cc | 4 +- client/mysqltest.c | 2 +- cmd-line-utils/readline/bind.c | 48 +++++++------- cmd-line-utils/readline/complete.c | 15 +++-- cmd-line-utils/readline/display.c | 23 ++++--- cmd-line-utils/readline/histexpand.c | 6 +- cmd-line-utils/readline/histfile.c | 6 +- cmd-line-utils/readline/history.h | 4 +- cmd-line-utils/readline/input.c | 2 +- cmd-line-utils/readline/isearch.c | 8 +-- cmd-line-utils/readline/kill.c | 18 ++--- cmd-line-utils/readline/macro.c | 6 +- cmd-line-utils/readline/mbutil.c | 8 +-- cmd-line-utils/readline/misc.c | 18 ++--- cmd-line-utils/readline/nls.c | 6 +- cmd-line-utils/readline/readline.c | 2 +- cmd-line-utils/readline/readline.h | 6 +- cmd-line-utils/readline/rlprivate.h | 28 ++++---- cmd-line-utils/readline/rltty.c | 4 +- cmd-line-utils/readline/search.c | 10 +-- cmd-line-utils/readline/terminal.c | 81 ++++++++++++----------- cmd-line-utils/readline/text.c | 38 +++++------ cmd-line-utils/readline/tilde.c | 2 +- cmd-line-utils/readline/undo.c | 7 +- cmd-line-utils/readline/util.c | 6 +- cmd-line-utils/readline/vi_mode.c | 66 +++++++++--------- extra/yassl/src/handshake.cpp | 6 +- extra/yassl/src/yassl_imp.cpp | 2 + extra/yassl/taocrypt/include/modes.hpp | 2 + extra/yassl/taocrypt/src/asn.cpp | 6 ++ server-tools/instance-manager/user_map.cc | 4 +- sql/ha_myisam.cc | 2 +- sql/log_event.cc | 4 +- sql/slave.cc | 6 +- sql/sql_parse.cc | 4 +- sql/sql_repl.cc | 2 +- sql/sql_table.cc | 2 +- sql/thr_malloc.cc | 2 +- strings/decimal.c | 6 +- 40 files changed, 254 insertions(+), 224 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 216a8f87c27..0d61ed4ec88 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1974,7 +1974,7 @@ static COMMANDS *find_command(char *name,char cmd_char) (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || - !name && commands[i].cmd_char == cmd_char)) + (!name && commands[i].cmd_char == cmd_char))) { DBUG_PRINT("exit",("found command: %s", commands[i].name)); DBUG_RETURN(&commands[i]); @@ -2132,7 +2132,7 @@ static bool add_line(String &buffer,char *line,char *in_string, buffer.length(0); } else if (!*ml_comment && (!*in_string && (inchar == '#' || - inchar == '-' && pos[1] == '-' && + (inchar == '-' && pos[1] == '-' && /* The third byte is either whitespace or is the end of the line -- which would occur only @@ -2140,7 +2140,7 @@ static bool add_line(String &buffer,char *line,char *in_string, itself whitespace and should also match. */ (my_isspace(charset_info,pos[2]) || - !pos[2])))) + !pos[2]))))) { // Flush previously accepted characters if (out != line) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 36b86ae7a96..ab78bbea944 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -527,8 +527,8 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, Format events are not concerned by --offset and such, we always need to read them to be able to process the wanted events. */ - if ((rec_count >= offset) && - ((my_time_t)(ev->when) >= start_datetime) || + if (((rec_count >= offset) && + ((my_time_t)(ev->when) >= start_datetime)) || (ev_type == FORMAT_DESCRIPTION_EVENT)) { if (ev_type != FORMAT_DESCRIPTION_EVENT) diff --git a/client/mysqltest.c b/client/mysqltest.c index f81968ee5a2..24d021b7239 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1682,7 +1682,7 @@ void check_result(DYNAMIC_STRING* ds) dynstr_set(ds, NULL); /* Don't create a .log file */ show_diff(NULL, result_file_name, reject_file); - die(mess); + die("%s", mess); break; } default: /* impossible */ diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index fc7bebfd813..aa5bd3d829a 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -79,7 +79,7 @@ static int _rl_read_init_file PARAMS((const char *, int)); static int glean_key_from_name PARAMS((char *)); static int find_boolean_var PARAMS((const char *)); -static char *_rl_get_string_variable_value PARAMS((const char *)); +static const char *_rl_get_string_variable_value PARAMS((const char *)); static int substring_member_of_array PARAMS((char *, const char **)); static int currently_reading_init_file; @@ -442,7 +442,7 @@ rl_translate_keyseq (seq, array, len) { register int i, c, l, temp; - for (i = l = 0; c = seq[i]; i++) + for (i = l = 0; (c = seq[i]); i++) { if (c == '\\') { @@ -776,7 +776,8 @@ _rl_read_file (filename, sizep) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ - if (file_size != finfo.st_size || file_size + 1 < file_size) +if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + file_size + 1 < file_size) { if (file >= 0) close (file); @@ -807,7 +808,7 @@ _rl_read_file (filename, sizep) /* Re-read the current keybindings file. */ int rl_re_read_init_file (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { int r; r = rl_read_init_file ((const char *)NULL); @@ -1031,7 +1032,7 @@ parser_if (args) /* Invert the current parser state if there is anything on the stack. */ static int parser_else (args) - char *args; + char *args __attribute__((unused)); { register int i; @@ -1062,7 +1063,7 @@ parser_else (args) _rl_parsing_conditionalized_out from the stack. */ static int parser_endif (args) - char *args; + char *args __attribute__((unused)); { if (if_stack_depth) _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; @@ -1185,7 +1186,7 @@ rl_parse_and_bind (string) { int passc = 0; - for (i = 1; c = string[i]; i++) + for (i = 1; (c = string[i]); i++) { if (passc) { @@ -1276,7 +1277,7 @@ rl_parse_and_bind (string) int delimiter, passc; delimiter = string[i++]; - for (passc = 0; c = string[i]; i++) + for (passc = 0; (c = string[i]); i++) { if (passc) { @@ -1436,7 +1437,7 @@ static struct { #if defined (VISIBLE_STATS) { "visible-stats", &rl_visible_stats, 0 }, #endif /* VISIBLE_STATS */ - { (char *)NULL, (int *)NULL } + { (char *)NULL, (int *)NULL, 0 } }; static int @@ -1505,7 +1506,7 @@ static struct { { "editing-mode", V_STRING, sv_editmode }, { "isearch-terminators", V_STRING, sv_isrchterm }, { "keymap", V_STRING, sv_keymap }, - { (char *)NULL, 0 } + { (char *)NULL, 0, (_rl_sv_func_t*)NULL } }; static int @@ -1532,7 +1533,7 @@ bool_to_int (value) (value[0] == '1' && value[1] == '\0')); } -char * +const char * rl_variable_value (name) const char *name; { @@ -1799,7 +1800,7 @@ rl_set_keymap_from_edit_mode () #endif /* VI_MODE */ } -char * +const char * rl_get_keymap_name_from_edit_mode () { if (rl_editing_mode == emacs_mode) @@ -2048,7 +2049,7 @@ rl_function_dumper (print_readably) fprintf (rl_outstream, "\n"); - for (i = 0; name = names[i]; i++) + for (i = 0; (name = names[i]); i++) { rl_command_func_t *function; char **invokers; @@ -2108,7 +2109,7 @@ rl_function_dumper (print_readably) the output in such a way that it can be read back in. */ int rl_dump_functions (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); @@ -2188,7 +2189,7 @@ rl_macro_dumper (print_readably) int rl_dump_macros (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); @@ -2197,12 +2198,13 @@ rl_dump_macros (count, key) return (0); } -static char * +static const char * _rl_get_string_variable_value (name) const char *name; { static char numbuf[32]; - char *ret; + const char *ret; + char *tmp; if (_rl_stricmp (name, "bell-style") == 0) { @@ -2230,11 +2232,11 @@ _rl_get_string_variable_value (name) { if (_rl_isearch_terminators == 0) return 0; - ret = _rl_untranslate_macro_value (_rl_isearch_terminators); - if (ret) + tmp = _rl_untranslate_macro_value (_rl_isearch_terminators); + if (tmp) { - strncpy (numbuf, ret, sizeof (numbuf) - 1); - free (ret); + strncpy (numbuf, tmp, sizeof (numbuf) - 1); + free (tmp); numbuf[sizeof(numbuf) - 1] = '\0'; } else @@ -2257,7 +2259,7 @@ rl_variable_dumper (print_readably) int print_readably; { int i; - char *v; + const char *v; for (i = 0; boolean_varlist[i].name; i++) { @@ -2286,7 +2288,7 @@ rl_variable_dumper (print_readably) the output in such a way that it can be read back in. */ int rl_dump_variables (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c index d0c9e772f0f..97423507d5b 100644 --- a/cmd-line-utils/readline/complete.c +++ b/cmd-line-utils/readline/complete.c @@ -358,14 +358,14 @@ rl_complete (ignore, invoking_key) /* List the possible completions. See description of rl_complete (). */ int rl_possible_completions (ignore, invoking_key) - int ignore, invoking_key; + int ignore __attribute__((unused)), invoking_key __attribute__((unused)); { return (rl_complete_internal ('?')); } int rl_insert_completions (ignore, invoking_key) - int ignore, invoking_key; + int ignore __attribute__((unused)), invoking_key __attribute__((unused)); { return (rl_complete_internal ('*')); } @@ -695,7 +695,8 @@ print_filename (to_print, full_pathname) char *to_print, *full_pathname; { int printed_len, extension_char, slen, tlen; - char *s, c, *new_full_pathname, *dn; + char *s, c, *new_full_pathname; + const char *dn; extension_char = 0; printed_len = fnprint (to_print); @@ -782,7 +783,7 @@ print_filename (to_print, full_pathname) static char * rl_quote_filename (s, rtype, qcp) char *s; - int rtype; + int rtype __attribute__((unused)); char *qcp; { char *r; @@ -883,7 +884,7 @@ _rl_find_completion_word (fp, dp) /* We didn't find an unclosed quoted substring upon which to do completion, so use the word break characters to find the substring on which to complete. */ - while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)) + while ((rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))) { scan = rl_line_buffer[rl_point]; @@ -1802,7 +1803,7 @@ rl_completion_matches (text, entry_function) match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); match_list[1] = (char *)NULL; - while (string = (*entry_function) (text, matches)) + while ((string = (*entry_function) (text, matches))) { if (matches + 1 == match_list_size) match_list = (char **)xrealloc @@ -2110,7 +2111,7 @@ rl_filename_completion_function (text, state) ring the bell, and reset the counter to zero. */ int rl_menu_complete (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { rl_compentry_func_t *our_func; int matching_filenames, found_quote; diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index 842a586b76b..fa5b67a8e69 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -127,7 +127,7 @@ int _rl_want_redisplay = 0; /* The stuff that gets printed out before the actual text of the line. This is usually pointing to rl_prompt. */ -char *rl_display_prompt = (char *)NULL; +const char *rl_display_prompt = (const char *)NULL; /* Pseudo-global variables declared here. */ @@ -229,7 +229,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp) int *lp, *lip, *niflp, *vlp; { char *r, *ret, *p, *igstart; - int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; + int l, rl, last, ignoring, ninvis, invfl, invflset, physchars; +#if defined (HANDLE_MULTIBYTE) + int ind, pind; +#endif /* Short-circuit if we can. */ if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0) @@ -242,7 +245,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp) if (niflp) *niflp = 0; if (vlp) - *vlp = lp ? *lp : strlen (r); + *vlp = lp ? *lp : (int)strlen (r); return r; } @@ -459,9 +462,10 @@ rl_redisplay () register int in, out, c, linenum, cursor_linenum; register char *line; int inv_botlin, lb_botlin, lb_linenum, o_cpos; - int newlines, lpos, temp, modmark, n0, num; - char *prompt_this_line; + int newlines, lpos, temp, modmark; + const char *prompt_this_line; #if defined (HANDLE_MULTIBYTE) + int num, n0; wchar_t wc; size_t wc_bytes; int wc_width; @@ -626,7 +630,6 @@ rl_redisplay () contents of the command line? */ while (lpos >= _rl_screenwidth) { - int z; /* fix from Darin Johnson for prompt string with invisible characters that is longer than the screen width. The prompt_invis_chars_first_line variable could be made into an array @@ -635,6 +638,7 @@ rl_redisplay () prompts that exceed two physical lines? Additional logic fix from Edward Catmur */ #if defined (HANDLE_MULTIBYTE) + int z; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { n0 = num; @@ -878,6 +882,7 @@ rl_redisplay () if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) { int nleft, pos, changed_screen_line, tx; + char empty_str[1] = { 0 }; if (!rl_display_fixed || forced_display) { @@ -902,7 +907,7 @@ rl_redisplay () #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) #define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) #define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) -#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) +#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? empty_str : VIS_CHARS(line) #define INV_LINE(line) (invisible_line + inv_lbreaks[line]) /* For each line in the buffer, do the updating display. */ @@ -969,7 +974,7 @@ rl_redisplay () _rl_move_vert (linenum); _rl_move_cursor_relative (0, tt); _rl_clear_to_eol - ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); + ((linenum == _rl_vis_botlin) ? (int)strlen (tt) : _rl_screenwidth); } } _rl_vis_botlin = inv_botlin; @@ -2261,7 +2266,7 @@ static void redraw_prompt (t) char *t; { - char *oldp; + const char *oldp; oldp = rl_display_prompt; rl_save_prompt (); diff --git a/cmd-line-utils/readline/histexpand.c b/cmd-line-utils/readline/histexpand.c index 45377fc3b5e..ab8d8ecc866 100644 --- a/cmd-line-utils/readline/histexpand.c +++ b/cmd-line-utils/readline/histexpand.c @@ -87,14 +87,14 @@ char history_comment_char = '\0'; /* The list of characters which inhibit the expansion of text if found immediately following history_expansion_char. */ -char *history_no_expand_chars = " \t\n\r="; +const char *history_no_expand_chars = " \t\n\r="; /* If set to a non-zero value, single quotes inhibit history expansion. The default is 0. */ int history_quotes_inhibit_expansion = 0; /* Used to split words by history_tokenize_internal. */ -char *history_word_delimiters = HISTORY_WORD_DELIMITERS; +const char *history_word_delimiters = HISTORY_WORD_DELIMITERS; /* If set, this points to a function that is called to verify that a particular history expansion should be performed. */ @@ -203,7 +203,7 @@ get_history_event (string, caller_index, delimiting_quote) } /* Only a closing `?' or a newline delimit a substring search string. */ - for (local_index = i; c = string[i]; i++) + for (local_index = i; (c = string[i]); i++) { #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index d98293d933c..118c5ebd328 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -186,7 +186,8 @@ read_history_range (filename, from, to) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ - if (file_size != finfo.st_size || file_size + 1 < file_size) +if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + file_size + 1 < file_size) { errno = overflow_errno; goto error_and_exit; @@ -339,7 +340,8 @@ history_truncate_file (fname, lines) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ - if (file_size != finfo.st_size || file_size + 1 < file_size) +if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + file_size + 1 < file_size) { close (file); #if defined (EFBIG) diff --git a/cmd-line-utils/readline/history.h b/cmd-line-utils/readline/history.h index 14ca2a996c7..5790ed1c71d 100644 --- a/cmd-line-utils/readline/history.h +++ b/cmd-line-utils/readline/history.h @@ -243,9 +243,9 @@ extern int history_length; extern int history_max_entries; extern char history_expansion_char; extern char history_subst_char; -extern char *history_word_delimiters; +extern const char *history_word_delimiters; extern char history_comment_char; -extern char *history_no_expand_chars; +extern const char *history_no_expand_chars; extern char *history_search_delimiter_chars; extern int history_quotes_inhibit_expansion; diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c index 62c0443d890..84c0422059a 100644 --- a/cmd-line-utils/readline/input.c +++ b/cmd-line-utils/readline/input.c @@ -420,7 +420,7 @@ rl_read_key () else { /* If input is coming from a macro, then use that. */ - if (c = _rl_next_macro_key ()) + if ((c = _rl_next_macro_key ())) return (c); /* If the user has an event function, then call it periodically. */ diff --git a/cmd-line-utils/readline/isearch.c b/cmd-line-utils/readline/isearch.c index 8060adb97cd..305c847d8da 100644 --- a/cmd-line-utils/readline/isearch.c +++ b/cmd-line-utils/readline/isearch.c @@ -75,7 +75,7 @@ static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int)); static char *last_isearch_string; static int last_isearch_string_len; -static char *default_isearch_terminators = "\033\012"; +static const char *default_isearch_terminators = "\033\012"; _rl_search_cxt * _rl_scxt_alloc (type, flags) @@ -119,7 +119,7 @@ _rl_scxt_alloc (type, flags) void _rl_scxt_dispose (cxt, flags) _rl_search_cxt *cxt; - int flags; + int flags __attribute__((unused)); { FREE (cxt->search_string); FREE (cxt->allocated_line); @@ -154,7 +154,7 @@ rl_forward_search_history (sign, key) static void rl_display_search (search_string, reverse_p, where) char *search_string; - int reverse_p, where; + int reverse_p, where __attribute__((unused)); { char *message; int msglen, searchlen; @@ -614,7 +614,7 @@ _rl_isearch_cleanup (cxt, r) backwards. */ static int rl_search_history (direction, invoking_key) - int direction, invoking_key; + int direction, invoking_key __attribute__((unused)); { _rl_search_cxt *cxt; /* local for now, but saved globally */ int c, r; diff --git a/cmd-line-utils/readline/kill.c b/cmd-line-utils/readline/kill.c index 42c53948689..adae2e1cd07 100644 --- a/cmd-line-utils/readline/kill.c +++ b/cmd-line-utils/readline/kill.c @@ -79,7 +79,7 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int)); of kill material. */ int rl_set_retained_kills (num) - int num; + int num __attribute__((unused)); { return 0; } @@ -296,7 +296,7 @@ rl_backward_kill_line (direction, ignore) /* Kill the whole line, no matter where point is. */ int rl_kill_full_line (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { rl_begin_undo_group (); rl_point = 0; @@ -314,7 +314,7 @@ rl_kill_full_line (count, ignore) using behaviour that they expect. */ int rl_unix_word_rubout (count, key) - int count, key; + int count, key __attribute__((unused)); { int orig_point; @@ -347,7 +347,7 @@ rl_unix_word_rubout (count, key) deletes backward to directory separator (`/') or whitespace. */ int rl_unix_filename_rubout (count, key) - int count, key; + int count, key __attribute__((unused)); { int orig_point, c; @@ -391,7 +391,7 @@ rl_unix_filename_rubout (count, key) doing. */ int rl_unix_line_discard (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (rl_point == 0) rl_ding (); @@ -428,7 +428,7 @@ region_kill_internal (delete) /* Copy the text in the region to the kill ring. */ int rl_copy_region_to_kill (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { return (region_kill_internal (0)); } @@ -436,7 +436,7 @@ rl_copy_region_to_kill (count, ignore) /* Kill the text between the point and mark. */ int rl_kill_region (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { int r, npoint; @@ -501,7 +501,7 @@ rl_copy_backward_word (count, key) /* Yank back the last killed text. This ignores arguments. */ int rl_yank (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { if (rl_kill_ring == 0) { @@ -520,7 +520,7 @@ rl_yank (count, ignore) yank back some other text. */ int rl_yank_pop (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { int l, n; diff --git a/cmd-line-utils/readline/macro.c b/cmd-line-utils/readline/macro.c index 3473f705335..0ee7b3077c3 100644 --- a/cmd-line-utils/readline/macro.c +++ b/cmd-line-utils/readline/macro.c @@ -201,7 +201,7 @@ _rl_kill_kbd_macro () re-executing the existing macro. */ int rl_start_kbd_macro (ignore1, ignore2) - int ignore1, ignore2; + int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); { if (RL_ISSTATE (RL_STATE_MACRODEF)) { @@ -226,7 +226,7 @@ rl_start_kbd_macro (ignore1, ignore2) that many times, counting the definition as the first time. */ int rl_end_kbd_macro (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) { @@ -246,7 +246,7 @@ rl_end_kbd_macro (count, ignore) COUNT says how many times to execute it. */ int rl_call_last_kbd_macro (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { if (current_macro == 0) _rl_abort_internal (); diff --git a/cmd-line-utils/readline/mbutil.c b/cmd-line-utils/readline/mbutil.c index e21708fb748..b571afa18bb 100644 --- a/cmd-line-utils/readline/mbutil.c +++ b/cmd-line-utils/readline/mbutil.c @@ -346,8 +346,8 @@ _rl_char_value (buf, ind) #undef _rl_find_next_mbchar int _rl_find_next_mbchar (string, seed, count, flags) - char *string; - int seed, count, flags; + char *string __attribute__((unused)); + int seed, count, flags __attribute__((unused)); { #if defined (HANDLE_MULTIBYTE) return _rl_find_next_mbchar_internal (string, seed, count, flags); @@ -362,8 +362,8 @@ _rl_find_next_mbchar (string, seed, count, flags) #undef _rl_find_prev_mbchar int _rl_find_prev_mbchar (string, seed, flags) - char *string; - int seed, flags; + char *string __attribute__((unused)); + int seed, flags __attribute__((unused)); { #if defined (HANDLE_MULTIBYTE) return _rl_find_prev_mbchar_internal (string, seed, flags); diff --git a/cmd-line-utils/readline/misc.c b/cmd-line-utils/readline/misc.c index e0e6893c60e..f5f0370fb6a 100644 --- a/cmd-line-utils/readline/misc.c +++ b/cmd-line-utils/readline/misc.c @@ -228,7 +228,7 @@ _rl_reset_argument () /* Start a numeric argument with initial value KEY */ int rl_digit_argument (ignore, key) - int ignore, key; + int ignore __attribute__((unused)), key; { _rl_arg_init (); if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -249,7 +249,7 @@ rl_digit_argument (ignore, key) dispatch on it. If the key is the abort character then abort. */ int rl_universal_argument (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { _rl_arg_init (); rl_numeric_arg *= 4; @@ -413,7 +413,7 @@ _rl_history_set_point () void rl_replace_from_history (entry, flags) HIST_ENTRY *entry; - int flags; /* currently unused */ + int flags __attribute__((unused)); /* currently unused */ { /* Can't call with `1' because rl_undo_list might point to an undo list from a history entry, just like we're setting up here. */ @@ -440,7 +440,7 @@ rl_replace_from_history (entry, flags) /* Meta-< goes to the start of the history. */ int rl_beginning_of_history (count, key) - int count, key; + int count __attribute__((unused)), key; { return (rl_get_previous_history (1 + where_history (), key)); } @@ -448,7 +448,7 @@ rl_beginning_of_history (count, key) /* Meta-> goes to the end of the history. (The current line). */ int rl_end_of_history (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { rl_maybe_replace_line (); using_history (); @@ -553,7 +553,7 @@ rl_get_previous_history (count, key) /* How to toggle back and forth between editing modes. */ int rl_vi_editing_mode (count, key) - int count, key; + int count __attribute__((unused)), key; { #if defined (VI_MODE) _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ @@ -566,7 +566,7 @@ rl_vi_editing_mode (count, key) int rl_emacs_editing_mode (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { rl_editing_mode = emacs_mode; _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ @@ -577,7 +577,7 @@ rl_emacs_editing_mode (count, key) /* Function for the rest of the library to use to set insert/overwrite mode. */ void _rl_set_insert_mode (im, force) - int im, force; + int im, force __attribute__((unused)); { #ifdef CURSOR_MODE _rl_set_cursor (im, force); @@ -590,7 +590,7 @@ _rl_set_insert_mode (im, force) mode. A negative or zero explicit argument selects insert mode. */ int rl_overwrite_mode (count, key) - int count, key; + int count, key __attribute__((unused)); { if (rl_explicit_arg == 0) _rl_set_insert_mode (rl_insert_mode ^ 1, 0); diff --git a/cmd-line-utils/readline/nls.c b/cmd-line-utils/readline/nls.c index 6ec685ed9ea..ff40b14228c 100644 --- a/cmd-line-utils/readline/nls.c +++ b/cmd-line-utils/readline/nls.c @@ -101,7 +101,8 @@ _rl_init_eightbit () /* If we have setlocale(3), just check the current LC_CTYPE category value, and go into eight-bit mode if it's not C or POSIX. */ #if defined (HAVE_SETLOCALE) - char *lspec, *t; + const char *lspec; + char *t; /* Set the LC_CTYPE locale category from environment variables. */ lspec = _rl_get_locale_var ("LC_CTYPE"); @@ -127,7 +128,8 @@ _rl_init_eightbit () return (0); #else /* !HAVE_SETLOCALE */ - char *lspec, *t; + const char *lspec; + char *t; int i; /* We don't have setlocale. Finesse it. Check the environment for the diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c index 8c3cad52d36..fb92becdbf9 100644 --- a/cmd-line-utils/readline/readline.c +++ b/cmd-line-utils/readline/readline.c @@ -90,7 +90,7 @@ static void bind_arrow_keys_internal PARAMS((Keymap)); static void bind_arrow_keys PARAMS((void)); static void readline_default_bindings PARAMS((void)); -static void reset_default_bindings PARAMS((void)); +static void reset_default_bindings PARAMS((void)) __attribute__((unused)); static int _rl_subseq_result PARAMS((int, Keymap, int, int)); static int _rl_subseq_getchar PARAMS((int)); diff --git a/cmd-line-utils/readline/readline.h b/cmd-line-utils/readline/readline.h index b71bf98d204..668a452c765 100644 --- a/cmd-line-utils/readline/readline.h +++ b/cmd-line-utils/readline/readline.h @@ -304,7 +304,7 @@ extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *)) extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap)); extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap)); -extern char *rl_variable_value PARAMS((const char *)); +extern const char *rl_variable_value PARAMS((const char *)); extern int rl_variable_bind PARAMS((const char *, const char *)); /* Backwards compatibility, use rl_bind_keyseq_in_map instead. */ @@ -343,7 +343,7 @@ extern void rl_set_keymap PARAMS((Keymap)); extern Keymap rl_get_keymap PARAMS((void)); /* Undocumented; used internally only. */ extern void rl_set_keymap_from_edit_mode PARAMS((void)); -extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); +extern const char *rl_get_keymap_name_from_edit_mode PARAMS((void)); /* Functions for manipulating the funmap, which maps command names to functions. */ extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); @@ -406,7 +406,7 @@ extern void rl_set_screen_size PARAMS((int, int)); extern void rl_get_screen_size PARAMS((int *, int *)); extern void rl_reset_screen_size PARAMS((void)); -extern char *rl_get_termcap PARAMS((const char *)); +extern const char *rl_get_termcap PARAMS((const char *)); /* Functions for character input. */ extern int rl_stuff_char PARAMS((int)); diff --git a/cmd-line-utils/readline/rlprivate.h b/cmd-line-utils/readline/rlprivate.h index 64aa7bdd3fa..1ab696766b0 100644 --- a/cmd-line-utils/readline/rlprivate.h +++ b/cmd-line-utils/readline/rlprivate.h @@ -77,7 +77,7 @@ typedef struct __rl_search_context int sline_len; int sline_index; - char *search_terminators; + const char *search_terminators; } _rl_search_cxt; /* Callback data for reading numeric arguments */ @@ -164,7 +164,7 @@ extern int rl_set_retained_kills PARAMS((int)); extern void _rl_set_screen_size PARAMS((int, int)); /* undo.c */ -extern int _rl_fix_last_undo_of_type PARAMS((int, int, int)); +extern int _rl_fix_last_undo_of_type PARAMS((enum undo_code, int, int)); /* util.c */ extern char *_rl_savestring PARAMS((const char *)); @@ -359,7 +359,7 @@ extern int _rl_vis_botlin; extern int _rl_last_c_pos; extern int _rl_suppress_redisplay; extern int _rl_want_redisplay; -extern char *rl_display_prompt; +extern const char *rl_display_prompt; /* isearch.c */ extern char *_rl_isearch_terminators; @@ -398,17 +398,17 @@ extern _rl_search_cxt *_rl_nscxt; /* terminal.c */ extern int _rl_enable_keypad; extern int _rl_enable_meta; -extern char *_rl_term_clreol; -extern char *_rl_term_clrpag; -extern char *_rl_term_im; -extern char *_rl_term_ic; -extern char *_rl_term_ei; -extern char *_rl_term_DC; -extern char *_rl_term_up; -extern char *_rl_term_dc; -extern char *_rl_term_cr; -extern char *_rl_term_IC; -extern char *_rl_term_forward_char; +extern const char *_rl_term_clreol; +extern const char *_rl_term_clrpag; +extern const char *_rl_term_im; +extern const char *_rl_term_ic; +extern const char *_rl_term_ei; +extern const char *_rl_term_DC; +extern const char *_rl_term_up; +extern const char *_rl_term_dc; +extern const char *_rl_term_cr; +extern const char *_rl_term_IC; +extern const char *_rl_term_forward_char; extern int _rl_screenheight; extern int _rl_screenwidth; extern int _rl_screenchars; diff --git a/cmd-line-utils/readline/rltty.c b/cmd-line-utils/readline/rltty.c index b5bc5d367a5..08e3ef945ef 100644 --- a/cmd-line-utils/readline/rltty.c +++ b/cmd-line-utils/readline/rltty.c @@ -765,7 +765,7 @@ rl_deprep_terminal () int rl_restart_output (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { #if defined (__MINGW32__) return 0; @@ -803,7 +803,7 @@ rl_restart_output (count, key) int rl_stop_output (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { #if defined (__MINGW32__) return 0; diff --git a/cmd-line-utils/readline/search.c b/cmd-line-utils/readline/search.c index cfa5db1dc17..1da450a692a 100644 --- a/cmd-line-utils/readline/search.c +++ b/cmd-line-utils/readline/search.c @@ -211,7 +211,7 @@ _rl_nsearch_init (dir, pchar) rl_end = rl_point = 0; p = _rl_make_prompt_for_search (pchar ? pchar : ':'); - rl_message ("%s", p, 0); + rl_message ("%s", p); free (p); RL_SETSTATE(RL_STATE_NSEARCH); @@ -383,7 +383,7 @@ noninc_search (dir, pchar) code calls this, KEY will be `?'. */ int rl_noninc_forward_search (count, key) - int count, key; + int count __attribute__((unused)), key; { return noninc_search (1, (key == '?') ? '?' : 0); } @@ -392,7 +392,7 @@ rl_noninc_forward_search (count, key) calls this, KEY will be `/'. */ int rl_noninc_reverse_search (count, key) - int count, key; + int count __attribute__((unused)), key; { return noninc_search (-1, (key == '/') ? '/' : 0); } @@ -401,7 +401,7 @@ rl_noninc_reverse_search (count, key) for. If there is no saved search string, abort. */ int rl_noninc_forward_search_again (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { int r; @@ -418,7 +418,7 @@ rl_noninc_forward_search_again (count, key) for. If there is no saved search string, abort. */ int rl_noninc_reverse_search_again (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { int r; diff --git a/cmd-line-utils/readline/terminal.c b/cmd-line-utils/readline/terminal.c index a630bc02e05..3f92821f9dd 100644 --- a/cmd-line-utils/readline/terminal.c +++ b/cmd-line-utils/readline/terminal.c @@ -104,34 +104,36 @@ char PC, *BC, *UP; #endif /* __linux__ */ /* Some strings to control terminal actions. These are output by tputs (). */ -char *_rl_term_clreol; -char *_rl_term_clrpag; -char *_rl_term_cr; -char *_rl_term_backspace; -char *_rl_term_goto; -char *_rl_term_pc; +const char *_rl_term_clreol; +const char *_rl_term_clrpag; +const char *_rl_term_cr; +const char *_rl_term_backspace; +char _rl_term_backspace_default[2] = { '\b', 0 }; +const char *_rl_term_goto; +const char *_rl_term_pc; /* Non-zero if we determine that the terminal can do character insertion. */ int _rl_terminal_can_insert = 0; /* How to insert characters. */ -char *_rl_term_im; -char *_rl_term_ei; -char *_rl_term_ic; -char *_rl_term_ip; -char *_rl_term_IC; +const char *_rl_term_im; +const char *_rl_term_ei; +const char *_rl_term_ic; +const char *_rl_term_ip; +const char *_rl_term_IC; /* How to delete characters. */ -char *_rl_term_dc; -char *_rl_term_DC; +const char *_rl_term_dc; +const char *_rl_term_DC; -char *_rl_term_forward_char; +const char *_rl_term_forward_char; /* How to go up a line. */ -char *_rl_term_up; +const char *_rl_term_up; +char _rl_term_up_default[2] = { 0, 0 }; /* A visible bell; char if the terminal can be made to flash the screen. */ -static char *_rl_visible_bell; +static const char *_rl_visible_bell; /* Non-zero means the terminal can auto-wrap lines. */ int _rl_term_autowrap = -1; @@ -141,33 +143,33 @@ static int term_has_meta; /* The sequences to write to turn on and off the meta key, if this terminal has one. */ -static char *_rl_term_mm; -static char *_rl_term_mo; +static const char *_rl_term_mm; +static const char *_rl_term_mo; /* The key sequences output by the arrow keys, if this terminal has any. */ -static char *_rl_term_ku; -static char *_rl_term_kd; -static char *_rl_term_kr; -static char *_rl_term_kl; +static const char *_rl_term_ku; +static const char *_rl_term_kd; +static const char *_rl_term_kr; +static const char *_rl_term_kl; /* How to initialize and reset the arrow keys, if this terminal has any. */ -static char *_rl_term_ks; -static char *_rl_term_ke; +static const char *_rl_term_ks; +static const char *_rl_term_ke; /* The key sequences sent by the Home and End keys, if any. */ -static char *_rl_term_kh; -static char *_rl_term_kH; -static char *_rl_term_at7; /* @7 */ +static const char *_rl_term_kh; +static const char *_rl_term_kH; +static const char *_rl_term_at7; /* @7 */ /* Delete key */ -static char *_rl_term_kD; +static const char *_rl_term_kD; /* Insert key */ -static char *_rl_term_kI; +static const char *_rl_term_kI; /* Cursor control */ -static char *_rl_term_vs; /* very visible */ -static char *_rl_term_ve; /* normal */ +static const char *_rl_term_vs; /* very visible */ +static const char *_rl_term_ve; /* normal */ static void bind_termcap_arrow_keys PARAMS((Keymap)); @@ -362,7 +364,7 @@ rl_resize_terminal () struct _tc_string { const char *tc_var; - char **tc_value; + const char **tc_value; }; /* This should be kept sorted, just in case we decide to change the @@ -409,7 +411,7 @@ get_term_capabilities (bp) char **bp; { #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ - register int i; + register unsigned int i; for (i = 0; i < NUM_TC_STRINGS; i++) *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp); @@ -496,8 +498,9 @@ _rl_init_terminal_io (terminal_name) tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we change that later... */ PC = '\0'; - BC = _rl_term_backspace = "\b"; - UP = _rl_term_up; + _rl_term_backspace = _rl_term_backspace_default; + BC = (char*)_rl_term_backspace; + UP = (char*)_rl_term_up; return 0; } @@ -507,8 +510,8 @@ _rl_init_terminal_io (terminal_name) /* Set up the variables that the termcap library expects the application to provide. */ PC = _rl_term_pc ? *_rl_term_pc : 0; - BC = _rl_term_backspace; - UP = _rl_term_up; + BC = (char*)_rl_term_backspace; + UP = (char*)_rl_term_up; if (!_rl_term_cr) _rl_term_cr = "\r"; @@ -568,11 +571,11 @@ bind_termcap_arrow_keys (map) _rl_keymap = xkeymap; } -char * +const char * rl_get_termcap (cap) const char *cap; { - register int i; + register unsigned int i; if (tcap_initialized == 0) return ((char *)NULL); diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c index b26afeda525..272848c798c 100644 --- a/cmd-line-utils/readline/text.c +++ b/cmd-line-utils/readline/text.c @@ -410,7 +410,7 @@ rl_backward (count, key) /* Move to the beginning of the line. */ int rl_beg_of_line (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { rl_point = 0; return 0; @@ -419,7 +419,7 @@ rl_beg_of_line (count, key) /* Move to the end of the line. */ int rl_end_of_line (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { rl_point = rl_end; return 0; @@ -527,7 +527,7 @@ rl_backward_word (count, key) /* Clear the current line. Numeric argument to C-l does this. */ int rl_refresh_line (ignore1, ignore2) - int ignore1, ignore2; + int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); { int curr_line; @@ -566,7 +566,7 @@ rl_clear_screen (count, key) int rl_arrow_keys (count, c) - int count, c; + int count, c __attribute__((unused)); { int ch; @@ -884,7 +884,7 @@ _rl_insert_next_callback (data) int rl_quoted_insert (count, key) - int count, key; + int count, key __attribute__((unused)); { /* Let's see...should the callback interface futz with signal handling? */ #if defined (HANDLE_SIGNALS) @@ -907,7 +907,7 @@ rl_quoted_insert (count, key) /* Insert a tab character. */ int rl_tab_insert (count, key) - int count, key; + int count, key __attribute__((unused)); { return (_rl_insert_char (count, '\t')); } @@ -917,7 +917,7 @@ rl_tab_insert (count, key) meaning in the future. */ int rl_newline (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { rl_done = 1; @@ -951,7 +951,7 @@ rl_newline (count, key) is special cased. */ int rl_do_lowercase_version (ignore1, ignore2) - int ignore1, ignore2; + int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); { return 0; } @@ -1118,7 +1118,7 @@ rl_rubout_or_delete (count, key) /* Delete all spaces and tabs around point. */ int rl_delete_horizontal_space (count, ignore) - int count, ignore; + int count __attribute__((unused)), ignore __attribute__((unused)); { int start = rl_point; @@ -1163,9 +1163,9 @@ rl_delete_or_show_completions (count, key) A K*rn shell style function. */ int rl_insert_comment (count, key) - int count, key; + int count __attribute__((unused)), key; { - char *rl_comment_text; + const char *rl_comment_text; int rl_comment_len; rl_beg_of_line (1, key); @@ -1202,7 +1202,7 @@ rl_insert_comment (count, key) /* Uppercase the word at point. */ int rl_upcase_word (count, key) - int count, key; + int count, key __attribute__((unused)); { return (rl_change_case (count, UpCase)); } @@ -1210,7 +1210,7 @@ rl_upcase_word (count, key) /* Lowercase the word at point. */ int rl_downcase_word (count, key) - int count, key; + int count, key __attribute__((unused)); { return (rl_change_case (count, DownCase)); } @@ -1218,7 +1218,7 @@ rl_downcase_word (count, key) /* Upcase the first letter, downcase the rest. */ int rl_capitalize_word (count, key) - int count, key; + int count, key __attribute__((unused)); { return (rl_change_case (count, CapCase)); } @@ -1381,7 +1381,7 @@ rl_transpose_words (count, key) then transpose the characters before point. */ int rl_transpose_chars (count, key) - int count, key; + int count, key __attribute__((unused)); { #if defined (HANDLE_MULTIBYTE) char *dummy; @@ -1557,7 +1557,7 @@ _rl_char_search_callback (data) int rl_char_search (count, key) - int count, key; + int count, key __attribute__((unused)); { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -1575,7 +1575,7 @@ rl_char_search (count, key) int rl_backward_char_search (count, key) - int count, key; + int count, key __attribute__((unused)); { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -1612,7 +1612,7 @@ _rl_set_mark_at_pos (position) /* A bindable command to set the mark. */ int rl_set_mark (count, key) - int count, key; + int count, key __attribute__((unused)); { return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); } @@ -1620,7 +1620,7 @@ rl_set_mark (count, key) /* Exchange the position of mark and point. */ int rl_exchange_point_and_mark (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (rl_mark > rl_end) rl_mark = -1; diff --git a/cmd-line-utils/readline/tilde.c b/cmd-line-utils/readline/tilde.c index d50f7a0ffa4..128cc26d9a7 100644 --- a/cmd-line-utils/readline/tilde.c +++ b/cmd-line-utils/readline/tilde.c @@ -196,7 +196,7 @@ tilde_expand (string) int result_size, result_index; result_index = result_size = 0; - if (result = strchr (string, '~')) + if ((result = strchr (string, '~'))) result = (char *)xmalloc (result_size = (strlen (string) + 16)); else result = (char *)xmalloc (result_size = (strlen (string) + 1)); diff --git a/cmd-line-utils/readline/undo.c b/cmd-line-utils/readline/undo.c index 5699193b14c..79846c26024 100644 --- a/cmd-line-utils/readline/undo.c +++ b/cmd-line-utils/readline/undo.c @@ -231,7 +231,8 @@ rl_do_undo () int _rl_fix_last_undo_of_type (type, start, end) - int type, start, end; + enum undo_code type; + int start, end; { UNDO_LIST *rl; @@ -289,7 +290,7 @@ rl_modifying (start, end) /* Revert the current line to its previous state. */ int rl_revert_line (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { if (!rl_undo_list) rl_ding (); @@ -309,7 +310,7 @@ rl_revert_line (count, key) /* Do some undoing of things that were done. */ int rl_undo_command (count, key) - int count, key; + int count, key __attribute__((unused)); { if (count < 0) return 0; /* Nothing to do. */ diff --git a/cmd-line-utils/readline/util.c b/cmd-line-utils/readline/util.c index 935c9c927c2..50cfea75cb9 100644 --- a/cmd-line-utils/readline/util.c +++ b/cmd-line-utils/readline/util.c @@ -115,14 +115,14 @@ _rl_abort_internal () int rl_abort (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { return (_rl_abort_internal ()); } int rl_tty_status (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { #if defined (TIOCSTAT) ioctl (1, TIOCSTAT, (char *)0); @@ -172,7 +172,7 @@ rl_extend_line_buffer (len) /* A function for simple tilde expansion. */ int rl_tilde_expand (ignore, key) - int ignore, key; + int ignore __attribute__((unused)), key __attribute__((unused)); { register int start, end; char *homedir, *temp; diff --git a/cmd-line-utils/readline/vi_mode.c b/cmd-line-utils/readline/vi_mode.c index 25213cb762f..620bb863c7b 100644 --- a/cmd-line-utils/readline/vi_mode.c +++ b/cmd-line-utils/readline/vi_mode.c @@ -131,7 +131,7 @@ static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); void _rl_vi_initialize_line () { - register int i; + register size_t i; for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) vi_mark_chars[i] = -1; @@ -190,7 +190,7 @@ _rl_vi_stuff_insert (count) puts you back into insert mode. */ int rl_vi_redo (count, c) - int count, c; + int count, c __attribute__((unused)); { int r; @@ -238,7 +238,7 @@ rl_vi_undo (count, key) /* Yank the nth arg from the previous line into this line at point. */ int rl_vi_yank_arg (count, key) - int count, key; + int count, key __attribute__((unused)); { /* Readline thinks that the first word on a line is the 0th, while vi thinks the first word on a line is the 1st. Compensate. */ @@ -321,7 +321,7 @@ rl_vi_search (count, key) /* Completion, from vi's point of view. */ int rl_vi_complete (ignore, key) - int ignore, key; + int ignore __attribute__((unused)), key; { if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) { @@ -348,7 +348,7 @@ rl_vi_complete (ignore, key) /* Tilde expansion for vi mode. */ int rl_vi_tilde_expand (ignore, key) - int ignore, key; + int ignore __attribute__((unused)), key; { rl_tilde_expand (0, key); rl_vi_start_inserting (key, 1, rl_arg_sign); @@ -419,7 +419,7 @@ rl_vi_end_word (count, key) /* Move forward a word the way that 'W' does. */ int rl_vi_fWord (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point < (rl_end - 1)) { @@ -436,7 +436,7 @@ rl_vi_fWord (count, ignore) int rl_vi_bWord (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point > 0) { @@ -460,7 +460,7 @@ rl_vi_bWord (count, ignore) int rl_vi_eWord (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point < (rl_end - 1)) { @@ -491,7 +491,7 @@ rl_vi_eWord (count, ignore) int rl_vi_fword (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point < (rl_end - 1)) { @@ -517,7 +517,7 @@ rl_vi_fword (count, ignore) int rl_vi_bword (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point > 0) { @@ -556,7 +556,7 @@ rl_vi_bword (count, ignore) int rl_vi_eword (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { while (count-- && rl_point < rl_end - 1) { @@ -581,7 +581,7 @@ rl_vi_eword (count, ignore) int rl_vi_insert_beg (count, key) - int count, key; + int count __attribute__((unused)), key; { rl_beg_of_line (1, key); rl_vi_insertion_mode (1, key); @@ -610,7 +610,7 @@ _rl_vi_append_forward (key) int rl_vi_append_mode (count, key) - int count, key; + int count __attribute__((unused)), key; { _rl_vi_append_forward (key); rl_vi_start_inserting (key, 1, rl_arg_sign); @@ -619,7 +619,7 @@ rl_vi_append_mode (count, key) int rl_vi_append_eol (count, key) - int count, key; + int count __attribute__((unused)), key; { rl_end_of_line (1, key); rl_vi_append_mode (1, key); @@ -629,7 +629,7 @@ rl_vi_append_eol (count, key) /* What to do in the case of C-d. */ int rl_vi_eof_maybe (count, c) - int count, c; + int count __attribute__((unused)), c __attribute__((unused)); { return (rl_newline (1, '\n')); } @@ -640,7 +640,7 @@ rl_vi_eof_maybe (count, c) switching keymaps. */ int rl_vi_insertion_mode (count, key) - int count, key; + int count __attribute__((unused)), key; { _rl_keymap = vi_insertion_keymap; _rl_vi_last_key_before_insert = key; @@ -703,7 +703,7 @@ _rl_vi_done_inserting () int rl_vi_movement_mode (count, key) - int count, key; + int count __attribute__((unused)), key; { if (rl_point > 0) rl_backward_char (1, key); @@ -783,7 +783,7 @@ _rl_vi_change_mbchar_case (count) int rl_vi_change_case (count, ignore) - int count, ignore; + int count, ignore __attribute__((unused)); { int c, p; @@ -1031,7 +1031,7 @@ rl_digit_loop1 () int rl_vi_delete_to (count, key) - int count, key; + int count __attribute__((unused)), key; { int c; @@ -1057,7 +1057,7 @@ rl_vi_delete_to (count, key) int rl_vi_change_to (count, key) - int count, key; + int count __attribute__((unused)), key; { int c, start_pos; @@ -1110,7 +1110,7 @@ rl_vi_change_to (count, key) int rl_vi_yank_to (count, key) - int count, key; + int count __attribute__((unused)), key; { int c, save; @@ -1202,7 +1202,7 @@ rl_vi_delete (count, key) int rl_vi_back_to_indent (count, key) - int count, key; + int count __attribute__((unused)), key; { rl_beg_of_line (1, key); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) @@ -1212,7 +1212,7 @@ rl_vi_back_to_indent (count, key) int rl_vi_first_print (count, key) - int count, key; + int count __attribute__((unused)), key; { return (rl_vi_back_to_indent (1, key)); } @@ -1319,7 +1319,7 @@ rl_vi_char_search (count, key) /* Match brackets */ int rl_vi_match (ignore, key) - int ignore, key; + int ignore __attribute__((unused)), key; { int count = 1, brack, pos, tmp, pre; @@ -1426,7 +1426,7 @@ rl_vi_bracktype (c) static int _rl_vi_change_char (count, c, mb) int count, c; - char *mb; + char *mb __attribute__((unused)); { int p; @@ -1458,8 +1458,8 @@ _rl_vi_change_char (count, c, mb) static int _rl_vi_callback_getchar (mb, mlen) - char *mb; - int mlen; + char *mb __attribute__((unused)); + int mlen __attribute__((unused)); { int c; @@ -1494,7 +1494,7 @@ _rl_vi_callback_change_char (data) int rl_vi_change_char (count, key) - int count, key; + int count, key __attribute__((unused)); { int c; char mb[MB_LEN_MAX]; @@ -1582,7 +1582,7 @@ rl_vi_overstrike_delete (count, key) int rl_vi_replace (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { int i; @@ -1663,7 +1663,7 @@ _rl_vi_set_mark () #if defined (READLINE_CALLBACKS) static int _rl_vi_callback_set_mark (data) - _rl_callback_generic_arg *data; + _rl_callback_generic_arg *data __attribute__((unused)); { _rl_callback_func = 0; _rl_want_redisplay = 1; @@ -1674,7 +1674,7 @@ _rl_vi_callback_set_mark (data) int rl_vi_set_mark (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -1721,7 +1721,7 @@ _rl_vi_goto_mark () #if defined (READLINE_CALLBACKS) static int _rl_vi_callback_goto_mark (data) - _rl_callback_generic_arg *data; + _rl_callback_generic_arg *data __attribute__((unused)); { _rl_callback_func = 0; _rl_want_redisplay = 1; @@ -1732,7 +1732,7 @@ _rl_vi_callback_goto_mark (data) int rl_vi_goto_mark (count, key) - int count, key; + int count __attribute__((unused)), key __attribute__((unused)); { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 262b5cb3b8b..b4d9005af15 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -790,15 +790,17 @@ void processReply(SSL& ssl) if (ssl.GetError()) return; if (DoProcessReply(ssl)) + { // didn't complete process if (!ssl.getSocket().IsNonBlocking()) { // keep trying now, blocking ok while (!ssl.GetError()) if (DoProcessReply(ssl) == 0) break; - } + } else // user will have try again later, non blocking ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); + } } @@ -873,10 +875,12 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer) void sendChangeCipher(SSL& ssl, BufferOutput buffer) { if (ssl.getSecurity().get_parms().entity_ == server_end) + { if (ssl.getSecurity().get_resuming()) ssl.verifyState(clientKeyExchangeComplete); else ssl.verifyState(clientFinishedComplete); + } if (ssl.GetError()) return; ChangeCipherSpec ccs; diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 4ee0fb99d3a..2b2efbbe04f 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -1272,6 +1272,7 @@ void ServerHello::Process(input_buffer&, SSL& ssl) ssl.useSecurity().use_connection().sessionID_Set_ = false; if (ssl.getSecurity().get_resuming()) + { if (memcmp(session_id_, ssl.getSecurity().get_resume().GetID(), ID_LEN) == 0) { ssl.set_masterSecret(ssl.getSecurity().get_resume().GetSecret()); @@ -1286,6 +1287,7 @@ void ServerHello::Process(input_buffer&, SSL& ssl) ssl.useSecurity().set_resuming(false); ssl.useLog().Trace("server denied resumption"); } + } if (ssl.CompressionOn() && !compression_method_) ssl.UnSetCompression(); // server isn't supporting yaSSL zlib request diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index d1ebce7568b..4575fe1414b 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -96,10 +96,12 @@ inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz) if (mode_ == ECB) ECB_Process(out, in, sz); else if (mode_ == CBC) + { if (dir_ == ENCRYPTION) CBC_Encrypt(out, in, sz); else CBC_Decrypt(out, in, sz); + } } diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 3b1c1c2136a..78200841bda 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -781,10 +781,12 @@ void CertDecoder::GetDate(DateType dt) source_.advance(length); if (!ValidateDate(date, b, dt) && verify_) + { if (dt == BEFORE) source_.SetError(BEFORE_DATE_E); else source_.SetError(AFTER_DATE_E); + } // save for later use if (dt == BEFORE) { @@ -1062,6 +1064,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz) } word32 rLen = GetLength(source); if (rLen != 20) + { if (rLen == 21) { // zero at front, eat source.next(); --rLen; @@ -1074,6 +1077,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz) source.SetError(DSA_SZ_E); return 0; } + } memcpy(decoded, source.get_buffer() + source.get_index(), rLen); source.advance(rLen); @@ -1084,6 +1088,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz) } word32 sLen = GetLength(source); if (sLen != 20) + { if (sLen == 21) { source.next(); // zero at front, eat --sLen; @@ -1096,6 +1101,7 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz) source.SetError(DSA_SZ_E); return 0; } + } memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen); source.advance(sLen); diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc index 7871cad7814..cdd7ebcf04b 100644 --- a/server-tools/instance-manager/user_map.cc +++ b/server-tools/instance-manager/user_map.cc @@ -145,8 +145,8 @@ int User_map::load(const char *password_file_name) while (fgets(line, sizeof(line), file)) { /* skip comments and empty lines */ - if (line[0] == '#' || line[0] == '\n' && - (line[1] == '\0' || line[1] == '\r')) + if (line[0] == '#' || (line[0] == '\n' && + (line[1] == '\0' || line[1] == '\r'))) continue; if ((user= new User) == 0) goto done; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 086b1209a7a..dadd39bb6e8 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -97,7 +97,7 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, if (!thd->vio_ok()) { - sql_print_error(msgbuf); + sql_print_error("%s", msgbuf); return; } diff --git a/sql/log_event.cc b/sql/log_event.cc index c6c7bea651a..d50c7cc8111 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3096,7 +3096,7 @@ void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info, { if (i) fputc(',', file); - fprintf(file, field); + fprintf(file, "%s", field); field += field_lens[i] + 1; } @@ -5203,7 +5203,7 @@ void Execute_load_query_log_event::print(FILE* file, { my_fwrite(file, (byte*) query, fn_pos_start, MYF(MY_NABP | MY_WME)); fprintf(file, " LOCAL INFILE \'"); - fprintf(file, local_fname); + fprintf(file, "%s", local_fname); fprintf(file, "\'"); if (dup_handling == LOAD_DUP_REPLACE) fprintf(file, " REPLACE"); diff --git a/sql/slave.cc b/sql/slave.cc index dd80b13ed46..33ce8c21963 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1435,7 +1435,7 @@ static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi) if (errmsg) { - sql_print_error(errmsg); + sql_print_error("%s", errmsg); return 1; } @@ -1558,7 +1558,7 @@ be equal for replication to work"; err: if (errmsg) { - sql_print_error(errmsg); + sql_print_error("%s", errmsg); return 1; } @@ -1968,7 +1968,7 @@ Failed to open the existing relay log info file '%s' (errno %d)", DBUG_RETURN(error); err: - sql_print_error(msg); + sql_print_error("%s", msg); end_io_cache(&rli->info_file); if (info_fd >= 0) my_close(info_fd, MYF(0)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 79b9b479a0c..0b7d0e6ee10 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -363,7 +363,7 @@ int check_user(THD *thd, enum enum_server_command command, if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) { net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); - mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + mysql_log.write(thd, COM_CONNECT, "%s", ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } if (passwd_len != 0 && @@ -500,7 +500,7 @@ int check_user(THD *thd, enum enum_server_command command, else if (res == 2) // client gave short hash, server has long hash { net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); - mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE)); + mysql_log.write(thd,COM_CONNECT,"%s",ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } net_printf_error(thd, ER_ACCESS_DENIED_ERROR, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 33c2855c20b..3d2cee6433b 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -144,7 +144,7 @@ static int send_file(THD *thd) if (errmsg) { sql_print_error("Failed in send_file() %s", errmsg); - DBUG_PRINT("error", (errmsg)); + DBUG_PRINT("error", ("%s", errmsg)); } DBUG_RETURN(error); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c4360c8d52e..84370873054 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2521,7 +2521,7 @@ send_result_message: { if (!thd->vio_ok()) { - sql_print_error(err_msg); + sql_print_error("%s", err_msg); } else { diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index 4ebcf1c50af..3c0f96fedc1 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -21,7 +21,7 @@ extern "C" { void sql_alloc_error_handler(void) { - sql_print_error(ER(ER_OUT_OF_RESOURCES)); + sql_print_error("%s", ER(ER_OUT_OF_RESOURCES)); THD *thd=current_thd; if (thd) diff --git a/strings/decimal.c b/strings/decimal.c index 8b431ad9bab..c535d0f73dc 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -306,7 +306,7 @@ int decimal_actual_fraction(decimal_t *from) { for (i= DIG_PER_DEC1 - ((frac - 1) % DIG_PER_DEC1); *buf0 % powers10[i++] == 0; - frac--); + frac--) ; } return frac; } @@ -500,7 +500,7 @@ static void digits_bounds(decimal_t *from, int *start_result, int *end_result) stop= (int) ((buf_end - from->buf + 1) * DIG_PER_DEC1); i= 1; } - for (; *buf_end % powers10[i++] == 0; stop--); + for (; *buf_end % powers10[i++] == 0; stop--) ; *end_result= stop; /* index of position after last decimal digit (from 0) */ } @@ -1005,7 +1005,7 @@ static int ull2dec(ulonglong from, decimal_t *to) sanity(to); - for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE); + for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) ; if (unlikely(intg1 > to->len)) { intg1=to->len; From 8d83b73985e7461d8128cd96e0a7c55fba60f4cd Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 30 Jun 2009 15:29:10 -0300 Subject: [PATCH 139/188] Post-merge fix for Innodb snapshot. Add new header to Makefile.am so it gets bundled. storage/innobase/Makefile.am: Add header so it becomes part of a source distribution. --- storage/innobase/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 7410bf7e591..f0849be9c49 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -56,7 +56,7 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \ include/ha0ha.ic include/hash0hash.h \ include/hash0hash.ic include/ibuf0ibuf.h \ include/ibuf0ibuf.ic include/ibuf0types.h \ - include/lock0iter.h \ + include/lock0iter.h include/fsp0types.h \ include/lock0lock.h include/lock0lock.ic \ include/lock0priv.h include/lock0priv.ic \ include/lock0types.h include/log0log.h \ From f903db67536098d0cce924a1b5014a423e62b345 Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 1 Jul 2009 11:06:05 +0530 Subject: [PATCH 140/188] Fix build failure after applying Innodb snapshot 5.1-ss5282 After applying Innodb snapshot 5.1-ss5282, build was broken because of missing header file. Adding the header file to Makefile.am after informing the innodb developers. --- storage/innobase/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 7410bf7e591..a597e3c24e4 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -50,7 +50,8 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \ include/eval0eval.h include/eval0eval.ic \ include/eval0proc.h include/eval0proc.ic \ include/fil0fil.h include/fsp0fsp.h \ - include/fsp0fsp.ic include/fut0fut.h \ + include/fsp0fsp.ic include/fsp0types.h \ + include/fut0fut.h \ include/fut0fut.ic include/fut0lst.h \ include/fut0lst.ic include/ha0ha.h \ include/ha0ha.ic include/hash0hash.h \ From 3cd431d553d722ec56db2635d88b8bb17087952a Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 1 Jul 2009 14:09:44 +0200 Subject: [PATCH 141/188] Bug #45790 Potential DoS vector: Writing of user input to log without proper formatting The problem is that a suitably crafted database identifier supplied to COM_CREATE_DB or COM_DROP_DB can cause a SIGSEGV, and thereby a denial of service. The database name is printed to the log without using a format string, so potential attackers can control the behavior of my_b_vprintf() by supplying their own format string. A CREATE or DROP privilege would be required. This patch supplies a format string to the printing of the database name. A test case is added to mysql_client_test. sql/sql_parse.cc: Added format strings. tests/mysql_client_test.c: Added new test case. --- sql/sql_parse.cc | 4 ++-- tests/mysql_client_test.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0b7d0e6ee10..bcde4a971d0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2096,7 +2096,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db))) break; - mysql_log.write(thd,command,packet); + mysql_log.write(thd, command, "%s", db); bzero(&create_info, sizeof(create_info)); mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), &create_info, 0); @@ -2121,7 +2121,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); break; } - mysql_log.write(thd,command,db); + mysql_log.write(thd, command, "%s", db); mysql_rm_db(thd, db, 0, 0); break; } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9dfacb7436d..ce1a1a99b04 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -12063,6 +12063,27 @@ static void test_bug6081() } +/* + Verify that bogus database names are handled properly with + COM_CREATE_DB and COM_DROP_DB, i.e., cannot cause SIGSEGV through + the use of printf specifiers in the database name. +*/ +static void test_bug45790() +{ + const char* bogus_db = "%s%s%s%s%s%s%s"; + int rc; + + myheader("test_bug45790"); + rc= simple_command(mysql, COM_CREATE_DB, bogus_db, + (ulong)strlen(bogus_db), 0); + myquery(rc); + + rc= simple_command(mysql, COM_DROP_DB, bogus_db, + (ulong)strlen(bogus_db), 0); + myquery(rc); +} + + static void test_bug6096() { MYSQL_STMT *stmt; @@ -16829,6 +16850,7 @@ static struct my_tests_st my_tests[]= { { "test_bug6059", test_bug6059 }, { "test_bug6046", test_bug6046 }, { "test_bug6081", test_bug6081 }, + { "test_bug45790",test_bug45790 }, { "test_bug6096", test_bug6096 }, { "test_datetime_ranges", test_datetime_ranges }, { "test_bug4172", test_bug4172 }, From fdf1461a4f987f7e2943112e1dd31d966fa57f4f Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Thu, 2 Jul 2009 13:34:23 +0530 Subject: [PATCH 142/188] Bug#45793 macce charset causes error with IBMDB2I Creating an IBMDB2I table with the macce character set is successful, but any attempt to insert data into the table was failing. This was happening because the character set name "macce" is not a valid iconv descriptor for IBM i PASE. This patch adds an override to convertTextDesc to use the equivalent valid iconv descriptor "IBM-1282" instead. mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result: Bug#45793 macce charset causes error with IBMDB2I Result file for the test case. mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test: Bug#45793 macce charset causes error with IBMDB2I Add a testcase for the macce charater set. storage/ibmdb2i/db2i_charsetSupport.cc: Bug#45793 macce charset causes error with IBMDB2I The character set name "macce" is not a valid iconv descriptor for IBM i PASE. Add an override to convertTextDesc to use the equivalent valid iconv descriptor "IBM-1282" instead. --- mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result | 7 +++++++ mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test | 11 +++++++++++ storage/ibmdb2i/db2i_charsetSupport.cc | 5 +++++ 3 files changed, 23 insertions(+) create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result new file mode 100644 index 00000000000..2392b746877 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45793.result @@ -0,0 +1,7 @@ +drop table if exists t1; +create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i; +insert into t1 values ("test"); +select * from t1 order by c; +c +test +drop table t1; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test new file mode 100644 index 00000000000..93fb78ff421 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45793.test @@ -0,0 +1,11 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source suite/ibmdb2i/include/have_i61.inc; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (c char(10), index(c)) charset macce engine=ibmdb2i; +insert into t1 values ("test"); +select * from t1 order by c; +drop table t1; diff --git a/storage/ibmdb2i/db2i_charsetSupport.cc b/storage/ibmdb2i/db2i_charsetSupport.cc index 7ff3a8c98f6..83bf1b9448b 100644 --- a/storage/ibmdb2i/db2i_charsetSupport.cc +++ b/storage/ibmdb2i/db2i_charsetSupport.cc @@ -384,6 +384,11 @@ static int32 convertTextDesc(const int32 inType, const int32 outType, const char strcpy(outDesc,"IBM-1256"); DBUG_RETURN(0); } + else if (strcmp("macce", inDescOverride) == 0) + { + strcpy(outDesc,"IBM-1282"); + DBUG_RETURN(0); + } } else if (outType == Qlg_TypeAS400CCSID) { From 3abee40e6b15a99b5765b003af8a793b36ae0818 Mon Sep 17 00:00:00 2001 From: Matthias Leich Date: Thu, 2 Jul 2009 13:22:12 +0200 Subject: [PATCH 143/188] Fix for Bug#45902 rpl_sp fails sporadically in check testcases Details: - Add "sync_slave_with_master" at test end - Restore the initial value of log_bin_trust_function_creators --- mysql-test/r/rpl_sp.result | 1 + mysql-test/t/rpl_sp.test | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 0f4d0fa8dad..7f1ae19035f 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -949,3 +949,4 @@ use test; drop procedure mysqltestbug36570_p1; drop procedure ` mysqltestbug36570_p2`; drop function mysqltestbug36570_f1; +set global log_bin_trust_function_creators = 0; diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index f045257d279..6ac6729e662 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -7,6 +7,9 @@ # accepted). The old name could be removed in 5.1 or 6.0. source include/master-slave.inc; +# Save the current value and restore at end of testing +let $log_bin_trust_function_creators= + `SELECT @@global.log_bin_trust_function_creators`; # we need a db != test, where we don't have automatic grants --disable_warnings @@ -629,3 +632,10 @@ use test; drop procedure mysqltestbug36570_p1; drop procedure ` mysqltestbug36570_p2`; drop function mysqltestbug36570_f1; + +# Cleanup +sync_slave_with_master; +# Restore the initial value of log_bin_trust_function_creators +eval +set global log_bin_trust_function_creators = $log_bin_trust_function_creators; + From ae8950f1e831e267894e8363cd289a9ebb5d2311 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 2 Jul 2009 17:42:00 +0300 Subject: [PATCH 144/188] Bug #45807: crash accessing partitioned table and sql_mode contains ONLY_FULL_GROUP_BY The partitioning code needs to issue a Item::fix_fields() on the partitioning expression in order to prepare it for being evaluated. It does this by creating a special table and a table list for the scope of the partitioning expression. But when checking ONLY_FULL_GROUP_BY the Item_field::fix_fields() was relying that there always be cached_table set and was trying to use it to get the select_lex of the SELECT the field's table is in. But the cached_table was not set by the partitioning code that creates the artificial TABLE_LIST used to resolve the partitioning expression and this resulted in a crash. Fixed by rectifying the following errors : 1. Item_field::fix_fields() : the code that check for ONLY_FULL_GROUP_BY relies on having tables with cacheable_table set. This is mostly true, the only two exceptions being the partitioning context table and the trigger context table. Fixed by taking the current parsing context if no pointer to the TABLE_LIST instance is present in the cached_table. 2. fix_fields_part_func() : 2a. The code that adds the table being created to the scope for the partitioning expression is mostly a copy of the add_table_to_list and friends with one exception : it was not marking the table as cacheable (something that normal add_table_to_list is doing). This caused the problem in the check for ONLY_FULL_GROUP_BY in Item_field::fix_fields() to appear. Fixed by setting the correct members to make the table cacheable. The ideal structural fix for this is to use a unified interface for adding a table to a table list (add_table_to_list?) : noted in a TODO comment 2b. The Item::fix_fields() was called with a NULL destination pointer. This causes uninitalized memory reads in the overloaded ::fix_fields() function (namely Item_field::fix_fields()) as it expects a non-zero pointer there. Fixed by passing the source pointer similarly to how it's done in JOIN::prepare(). mysql-test/r/partition.result: Bug #45807: test case mysql-test/t/partition.test: Bug #45807: test case sql/item.cc: Bug #45807: fix the ONLY_FULL_GROUP_BY check code to handle correctly non-cacheable tables. sql/sql_partition.cc: Bug #45807: fix the Item::fix_fields() context initializatio for the partitioning expression in CREATE TABLE. --- mysql-test/r/partition.result | 9 +++++++++ mysql-test/t/partition.test | 11 +++++++++++ sql/item.cc | 10 ++++++++-- sql/sql_partition.cc | 13 +++++++++++-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 20853da1af0..8e3fbde1ea8 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1982,5 +1982,14 @@ SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range bc bc 10 NULL 7 Using where; Using index for group-by DROP TABLE t1; +# +# Bug #45807: crash accessing partitioned table and sql_mode +# contains ONLY_FULL_GROUP_BY +# +SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY'; +CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM +PARTITION BY HASH(id) PARTITIONS 2; +DROP TABLE t1; +SET SESSION SQL_MODE=DEFAULT; End of 5.1 tests SET @@global.general_log= @old_general_log; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 8535e1bc5c2..8b4af201af2 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1976,6 +1976,17 @@ SELECT b, c FROM t1 WHERE b = 1 GROUP BY b, c; DROP TABLE t1; +--echo # +--echo # Bug #45807: crash accessing partitioned table and sql_mode +--echo # contains ONLY_FULL_GROUP_BY +--echo # + +SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY'; +CREATE TABLE t1(id INT,KEY(id)) ENGINE=MYISAM + PARTITION BY HASH(id) PARTITIONS 2; +DROP TABLE t1; +SET SESSION SQL_MODE=DEFAULT; + --echo End of 5.1 tests SET @@global.general_log= @old_general_log; diff --git a/sql/item.cc b/sql/item.cc index 4c967200a3a..d380cafbee3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4406,16 +4406,22 @@ mark_non_agg_field: Fields from outer selects added to the aggregate function outer_fields list as its unknown at the moment whether it's aggregated or not. + We're using either the select lex of the cached table (if present) + or the field's resolution context. context->select_lex is + safe for use because it's either the SELECT we want to use + (the current level) or a stub added by non-SELECT queries. */ + SELECT_LEX *select_lex= cached_table ? + cached_table->select_lex : context->select_lex; if (!thd->lex->in_sum_func) - cached_table->select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; + select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; else { if (outer_fixed) thd->lex->in_sum_func->outer_fields.push_back(this); else if (thd->lex->in_sum_func->nest_level != thd->lex->current_select->nest_level) - cached_table->select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; + select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; } } return FALSE; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 3713a10997d..4472b9be2cd 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -918,6 +918,9 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, Set-up the TABLE_LIST object to be a list with a single table Set the object to zero to create NULL pointers and set alias and real name to table name and get database name from file name. + TODO: Consider generalizing or refactoring Lex::add_table_to_list() so + it can be used in all places where we create TABLE_LIST objects. + Also consider creating appropriate constructors for TABLE_LIST. */ bzero((void*)&tables, sizeof(TABLE_LIST)); @@ -925,6 +928,13 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, tables.table= table; tables.next_local= 0; tables.next_name_resolution_table= 0; + /* + Cache the table in Item_fields. All the tables can be cached except + the trigger pseudo table. + */ + tables.cacheable_table= TRUE; + context= thd->lex->current_context(); + tables.select_lex= context->select_lex; strmov(db_name_string, table->s->normalized_path.str); dir_length= dirname_length(db_name_string); db_name_string[dir_length - 1]= 0; @@ -932,7 +942,6 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, db_name= &db_name_string[home_dir_length]; tables.db= db_name; - context= thd->lex->current_context(); table->map= 1; //To ensure correct calculation of const item table->get_fields_in_item_tree= TRUE; save_table_list= context->table_list; @@ -965,7 +974,7 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, save_use_only_table_context= thd->lex->use_only_table_context; thd->lex->use_only_table_context= TRUE; - error= func_expr->fix_fields(thd, (Item**)0); + error= func_expr->fix_fields(thd, (Item**)&func_expr); thd->lex->use_only_table_context= save_use_only_table_context; From 096c12b2c42b83d879314276fe6471edf8c61fd0 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Fri, 3 Jul 2009 11:41:19 +0400 Subject: [PATCH 145/188] Bug #45262: Bad effects with CREATE TABLE and DECIMAL Using DECIMAL constants with more than 65 digits in CREATE TABLE ... SELECT led to bogus errors in release builds or assertion failures in debug builds. The problem was in inconsistency in how DECIMAL constants and fields are handled internally. We allow arbitrarily long DECIMAL constants, whereas DECIMAL(M,D) columns are limited to M<=65 and D<=30. my_decimal_precision_to_length() was used in both Item and Field code and truncated precision to DECIMAL_MAX_PRECISION when calculating value length without adjusting precision and decimals. As a result, a DECIMAL constant with more than 65 digits ended up having length less than precision or decimals which led to assertion failures. Fixed by modifying my_decimal_precision_to_length() so that precision is truncated to DECIMAL_MAX_PRECISION only for Field object which is indicated by the new 'truncate' parameter. Another inconsistency fixed by this patch is how DECIMAL constants and expressions are handled for CREATE ... SELECT. create_tmp_field_from_item() (which is used for constants) was changed as a part of the bugfix for bug #24907 to handle long DECIMAL constants gracefully. Item_func::tmp_table_field() (which is used for expressions) on the other hand was still using a simplistic approach when creating a Field_new_decimal from a DECIMAL expression. mysql-test/r/type_newdecimal.result: Added a test case for bug #45262. mysql-test/t/type_newdecimal.test: Added a test case for bug #45262. sql/item.cc: Use the new 'truncate' parameter in my_decimal_precision_to_length(). sql/item_cmpfunc.cc: Use the new 'truncate' parameter in my_decimal_precision_to_length(). sql/item_func.cc: 1. Use the new 'truncate' parameter in my_decimal_precision_to_length(). 2. Do not truncate decimal precision to DECIMAL_MAX_PRECISION for additive expressions involving long DECIMAL constants. 3. Fixed an incosistency in how DECIMAL constants and expressions are handled for CREATE ... SELECT. sql/item_func.h: Use the new 'truncate' parameter in my_decimal_precision_to_length(). sql/item_sum.cc: Use the new 'truncate' parameter in my_decimal_precision_to_length(). sql/my_decimal.h: Do not truncate precision to DECIMAL_MAX_PRECISION when calculating length in my_decimal_precision_to_length() if 'truncate' parameter is FALSE. sql/sql_select.cc: 1. Use the new 'truncate' parameter in my_decimal_precision_to_length(). 2. Use a more correct logic when adjusting value's length. --- mysql-test/r/type_newdecimal.result | 57 ++++++++++++++++++++++- mysql-test/t/type_newdecimal.test | 29 ++++++++++++ sql/item.cc | 49 ++++++++++++-------- sql/item_cmpfunc.cc | 5 +- sql/item_func.cc | 71 ++++++++++++++++++++++------- sql/item_func.h | 3 +- sql/item_sum.cc | 15 +++--- sql/my_decimal.h | 17 ++++++- sql/sql_select.cc | 10 ++-- 9 files changed, 205 insertions(+), 51 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 90b6f524692..3497633b5d4 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1514,10 +1514,10 @@ Warnings: Warning 1264 Out of range value adjusted for column 'f1' at row 1 DESC t1; Field Type Null Key Default Extra -f1 decimal(59,30) NO 0.000000000000000000000000000000 +f1 decimal(65,30) NO 0.000000000000000000000000000000 SELECT f1 FROM t1; f1 -99999999999999999999999999999.999999999999999999999999999999 +99999999999999999999999999999999999.999999999999999999999999999999 DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); @@ -1539,4 +1539,57 @@ select * from t1; 5.05 / 0.014 360.714286 DROP TABLE t1; +# +# Bug #45262: Bad effects with CREATE TABLE and DECIMAL +# +CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(30,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +0.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +1.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +0.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,4) YES NULL +SELECT my_col FROM t1; +my_col +8.1000 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) YES NULL +SELECT my_col FROM t1; +my_col +0.012345687012345687012345687012 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index a5331582df6..d767f2a4d22 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1235,4 +1235,33 @@ show create table t1; select * from t1; DROP TABLE t1; +--echo # +--echo # Bug #45262: Bad effects with CREATE TABLE and DECIMAL +--echo # + +CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 1e379527fb7..47242e1b7c2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2215,8 +2215,10 @@ Item_decimal::Item_decimal(const char *str_arg, uint length, name= (char*) str_arg; decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } Item_decimal::Item_decimal(longlong val, bool unsig) @@ -2224,8 +2226,10 @@ Item_decimal::Item_decimal(longlong val, bool unsig) int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2234,8 +2238,10 @@ Item_decimal::Item_decimal(double val, int precision, int scale) double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2255,8 +2261,10 @@ Item_decimal::Item_decimal(my_decimal *value_par) my_decimal2decimal(value_par, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2266,8 +2274,8 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale) &decimal_value, precision, scale); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -2322,8 +2330,10 @@ void Item_decimal::set_decimal_value(my_decimal *value_par) my_decimal2decimal(value_par, &decimal_value); decimals= (uint8) decimal_value.frac; unsigned_flag= !decimal_value.sign(); - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2553,8 +2563,9 @@ void Item_param::set_decimal(const char *str, ulong length) str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end); state= DECIMAL_VALUE; decimals= decimal_value.frac; - max_length= my_decimal_precision_to_length(decimal_value.precision(), - decimals, unsigned_flag); + max_length= + my_decimal_precision_to_length_no_truncation(decimal_value.precision(), + decimals, unsigned_flag); maybe_null= 0; DBUG_VOID_RETURN; } @@ -2712,8 +2723,9 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) my_decimal2decimal(ent_value, &decimal_value); state= DECIMAL_VALUE; decimals= ent_value->frac; - max_length= my_decimal_precision_to_length(ent_value->precision(), - decimals, unsigned_flag); + max_length= + my_decimal_precision_to_length_no_truncation(ent_value->precision(), + decimals, unsigned_flag); item_type= Item::DECIMAL_ITEM; break; } @@ -6931,8 +6943,9 @@ bool Item_type_holder::join_types(THD *thd, Item *item) int item_prec = max(prev_decimal_int_part, item_int_part) + decimals; int precision= min(item_prec, DECIMAL_MAX_PRECISION); unsigned_flag&= item->unsigned_flag; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); } switch (Field::result_merge_type(fld_type)) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c940c4ab3c0..aafc250fb73 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2716,8 +2716,9 @@ void Item_func_case::fix_length_and_dec() agg_num_lengths(args[i + 1]); if (else_expr_num != -1) agg_num_lengths(args[else_expr_num]); - max_length= my_decimal_precision_to_length(max_length + decimals, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(max_length + + decimals, decimals, + unsigned_flag); } } diff --git a/sql/item_func.cc b/sql/item_func.cc index 6193ab285f2..7f7f79480ca 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -447,11 +447,46 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) res= make_string_field(t_arg); break; case DECIMAL_RESULT: - res= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(), - decimals, - unsigned_flag), - maybe_null, name, t_arg, decimals, unsigned_flag); + { + uint8 dec= decimals; + uint8 intg= decimal_precision() - dec; + uint32 len= max_length; + + /* + Trying to put too many digits overall in a DECIMAL(prec,dec) + will always throw a warning. We must limit dec to + DECIMAL_MAX_SCALE however to prevent an assert() later. + */ + + if (dec > 0) + { + int overflow; + + dec= min(dec, DECIMAL_MAX_SCALE); + + /* + If the value still overflows the field with the corrected dec, + we'll throw out decimals rather than integers. This is still + bad and of course throws a truncation warning. + */ + + const int required_length= + my_decimal_precision_to_length(intg + dec, dec, + unsigned_flag); + + overflow= required_length - len; + + if (overflow > 0) + dec= max(0, dec - overflow); // too long, discard fract + else + /* Corrected value fits. */ + len= required_length; + } + + res= new Field_new_decimal(len, maybe_null, name, + t_arg, dec, unsigned_flag); break; + } case ROW_RESULT: default: // This case should never be chosen @@ -540,8 +575,8 @@ void Item_func::count_decimal_length() set_if_smaller(unsigned_flag, args[i]->unsigned_flag); } int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1158,16 +1193,15 @@ void Item_func_additive_op::result_precision() decimals= max(args[0]->decimals, args[1]->decimals); int arg1_int= args[0]->decimal_precision() - args[0]->decimals; int arg2_int= args[1]->decimal_precision() - args[1]->decimals; - int est_prec= max(arg1_int, arg2_int) + 1 + decimals; - int precision= min(est_prec, DECIMAL_MAX_PRECISION); + int precision= max(arg1_int, arg2_int) + 1 + decimals; /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1270,7 +1304,8 @@ void Item_func_mul::result_precision() decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE); uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision(); uint precision= min(est_prec, DECIMAL_MAX_PRECISION); - max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1326,8 +1361,8 @@ void Item_func_div::result_precision() else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -2013,8 +2048,9 @@ void Item_func_round::fix_length_and_dec() precision-= decimals_delta - length_increase; decimals= min(decimals_to_set, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); break; } default: @@ -2249,8 +2285,9 @@ void Item_func_min_max::fix_length_and_dec() } } else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) - max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(max_int_part + + decimals, decimals, + unsigned_flag); cached_field_type= agg_field_type(args, arg_count); } diff --git a/sql/item_func.h b/sql/item_func.h index 33aeddfe6e6..fac8db9bade 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -367,7 +367,8 @@ public: Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a) { decimals= dec; - max_length= my_decimal_precision_to_length(len, dec, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(len, dec, + unsigned_flag); } String *val_str(String *str); double val_real(); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index a381361e8a2..79295904d65 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -786,8 +786,9 @@ void Item_sum_sum::fix_length_and_dec() { /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */ int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); curr_dec_buff= 0; hybrid_type= DECIMAL_RESULT; my_decimal_set_zero(dec_buffs); @@ -1217,8 +1218,9 @@ void Item_sum_avg::fix_length_and_dec() { int precision= args[0]->decimal_precision() + prec_increment; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION); f_scale= args[0]->decimals; dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale); @@ -1418,8 +1420,9 @@ void Item_sum_variance::fix_length_and_dec() { int precision= args[0]->decimal_precision()*2 + prec_increment; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); break; } diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 6a0d05921ec..ed1cffdccc5 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -170,6 +170,19 @@ inline uint my_decimal_length_to_precision(uint length, uint scale, (unsigned_flag || !length ? 0:1)); } +inline uint32 my_decimal_precision_to_length_no_truncation(uint precision, + uint8 scale, + bool unsigned_flag) +{ + /* + When precision is 0 it means that original length was also 0. Thus + unsigned_flag is ignored in this case. + */ + DBUG_ASSERT(precision || !scale); + return (uint32)(precision + (scale > 0 ? 1 : 0) + + (unsigned_flag || !precision ? 0 : 1)); +} + inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, bool unsigned_flag) { @@ -179,8 +192,8 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, */ DBUG_ASSERT(precision || !scale); set_if_smaller(precision, DECIMAL_MAX_PRECISION); - return (uint32)(precision + (scale>0 ? 1:0) + - (unsigned_flag || !precision ? 0:1)); + return my_decimal_precision_to_length_no_truncation(precision, scale, + unsigned_flag); } inline diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 672ebaf9259..da9a81daf95 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9087,13 +9087,17 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, +1: for decimal point */ - overflow= my_decimal_precision_to_length(intg + dec, dec, - item->unsigned_flag) - len; + const int required_length= + my_decimal_precision_to_length(intg + dec, dec, + item->unsigned_flag); + + overflow= required_length - len; if (overflow > 0) dec= max(0, dec - overflow); // too long, discard fract else - len -= item->decimals - dec; // corrected value fits + /* Corrected value fits. */ + len= required_length; } new_field= new Field_new_decimal(len, maybe_null, item->name, From e0a3403b457a5458915131732561caad9d8c6871 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Fri, 3 Jul 2009 10:19:32 +0200 Subject: [PATCH 146/188] Bug#15866 Prepared for push on 5.0 --- mysql-test/r/sp-fib.result | 21 ++++----------------- mysql-test/t/sp-fib.test | 24 +++++++++--------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/mysql-test/r/sp-fib.result b/mysql-test/r/sp-fib.result index c51aa7d7ad1..a26e104c1e8 100644 --- a/mysql-test/r/sp-fib.result +++ b/mysql-test/r/sp-fib.result @@ -10,24 +10,17 @@ declare c cursor for select f from t3 order by f desc limit 2; open c; fetch c into y; fetch c into x; -close c; insert into t3 values (x+y); call fib(n-1); +## Close the cursor AFTER the recursion to ensure that the stack +## frame is somewhat intact. +close c; end; end if; end| set @@max_sp_recursion_depth= 20| insert into t3 values (0), (1)| -call fib(3)| -select * from t3 order by f asc| -f -0 -1 -1 -2 -delete from t3| -insert into t3 values (0), (1)| -call fib(10)| +call fib(4)| select * from t3 order by f asc| f 0 @@ -35,12 +28,6 @@ f 1 2 3 -5 -8 -13 -21 -34 -55 drop table t3| drop procedure fib| set @@max_sp_recursion_depth= 0| diff --git a/mysql-test/t/sp-fib.test b/mysql-test/t/sp-fib.test index e6682395a2c..24a51b99c2d 100644 --- a/mysql-test/t/sp-fib.test +++ b/mysql-test/t/sp-fib.test @@ -22,13 +22,14 @@ begin begin declare x, y bigint unsigned; declare c cursor for select f from t3 order by f desc limit 2; - open c; fetch c into y; fetch c into x; - close c; insert into t3 values (x+y); call fib(n-1); + ## Close the cursor AFTER the recursion to ensure that the stack + ## frame is somewhat intact. + close c; end; end if; end| @@ -36,24 +37,17 @@ end| # Enable recursion set @@max_sp_recursion_depth= 20| -# Minimum test: recursion of 3 levels - insert into t3 values (0), (1)| -call fib(3)| +# The small number of recursion levels is intentional. +# We need to avoid +# Bug#15866 main.sp fails (thread stack limit +# insufficient for recursive call "fib(20)") +# which affects some platforms. +call fib(4)| select * from t3 order by f asc| -delete from t3| - -# The original test, 20 levels, ran into memory limits on some machines -# and builds. Try 10 instead... - -insert into t3 values (0), (1)| - -call fib(10)| - -select * from t3 order by f asc| drop table t3| drop procedure fib| set @@max_sp_recursion_depth= 0| From 45d59063cb5c835c01d4744ad3b3b4c141a639a2 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 3 Jul 2009 13:22:06 +0500 Subject: [PATCH 147/188] Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table enabled message storing into error message list for 'drop table' command mysql-test/r/warnings.result: test result mysql-test/t/warnings.test: test case sql/sql_table.cc: We should skip error sending then we should return warnings to client as some functions may send its own errors, so we should set no_warnings_for_error= 0 only in case of warning. The fix is to enable message storing into error message list for 'drop table' command(only for error case). tests/mysql_client_test.c: test fix --- mysql-test/r/warnings.result | 5 +++++ mysql-test/t/warnings.test | 7 +++++++ sql/sql_table.cc | 2 +- tests/mysql_client_test.c | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 2e393aea9e4..8a87852d582 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1 insert into t2 values(@q); ERROR 22001: Data too long for column 'c_tinyblob' at row 1 drop table t1, t2; +DROP TABLE t1; +ERROR 42S02: Unknown table 't1' +SHOW ERRORS; +Level Code Message +Error 1051 Unknown table 't1' End of 5.0 tests diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 12421170eba..176f320e390 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -225,4 +225,11 @@ insert into t2 values(@q); drop table t1, t2; +# +# Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table +# +--error ER_BAD_TABLE_ERROR +DROP TABLE t1; +SHOW ERRORS; + --echo End of 5.0 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e752421223a..813a0472b76 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1995,6 +1995,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, pthread_mutex_unlock(&LOCK_open); thd->thread_specific_used|= tmp_table_deleted; error= 0; + thd->no_warnings_for_error= 0; if (wrong_tables.length()) { if (!foreign_key_error) @@ -2056,7 +2057,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, err_with_placeholders: unlock_table_names(thd, tables, (TABLE_LIST*) 0); pthread_mutex_unlock(&LOCK_open); - thd->no_warnings_for_error= 0; DBUG_RETURN(error); } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b836293442a..73d0ab6ce1e 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -4769,6 +4769,8 @@ static void test_errors() result= mysql_store_result(mysql); mytest(result); + DIE_UNLESS(mysql_num_rows(result) == 1); + (void) my_process_result_set(result); mysql_free_result(result); } From 2dd709468194c3b5399c4dc614037c0557e17e14 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 3 Jul 2009 13:35:00 +0500 Subject: [PATCH 148/188] Bug#45806 crash when replacing into a view with a join! The crash happend because for views which are joins we have table_list->table == 0 and table_list->table->'any method' call leads to crash. The fix is to perform table_list->table->file->extra() method for all tables belonging to view. mysql-test/r/view.result: test result mysql-test/t/view.test: test case sql/sql_insert.cc: added prepare_for_positional_update() function which updates extra info about primary key for tables belonging to view. --- mysql-test/r/view.result | 111 +++++++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 32 +++++++++++ sql/sql_insert.cc | 32 +++++++++-- 3 files changed, 172 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index a7ac971ef45..715fb225550 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3723,6 +3723,117 @@ DROP TABLE t1; # -- End of test case for Bug#40825 +# +# Bug #45806 crash when replacing into a view with a join! +# +CREATE TABLE t1(a INT UNIQUE); +CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a; +INSERT INTO t1 VALUES (1), (2); +REPLACE INTO v1(a) SELECT 1 FROM t1,t1 AS c; +SELECT * FROM v1; +a +1 +2 +1 +2 +REPLACE INTO v1(a) SELECT 3 FROM t1,t1 AS c; +SELECT * FROM v1; +a +1 +2 +3 +1 +2 +3 +1 +2 +3 +DELETE FROM t1 WHERE a=3; +INSERT INTO v1(a) SELECT 1 FROM t1,t1 AS c +ON DUPLICATE KEY UPDATE `v1`.`a`= 1; +SELECT * FROM v1; +a +1 +2 +1 +2 +CREATE VIEW v2 AS SELECT t1.a FROM t1, v1 AS a; +REPLACE INTO v2(a) SELECT 1 FROM t1,t1 AS c; +SELECT * FROM v2; +a +1 +2 +1 +2 +1 +2 +1 +2 +REPLACE INTO v2(a) SELECT 3 FROM t1,t1 AS c; +SELECT * FROM v2; +a +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +INSERT INTO v2(a) SELECT 1 FROM t1,t1 AS c +ON DUPLICATE KEY UPDATE `v2`.`a`= 1; +SELECT * FROM v2; +a +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 +DROP VIEW v1; +DROP VIEW v2; +DROP TABLE t1; +# -- End of test case for Bug#45806 # ----------------------------------------------------------------- # -- End of 5.0 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 89e68e4bd99..6f03ff12448 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3703,6 +3703,38 @@ DROP TABLE t1; --echo # -- End of test case for Bug#40825 --echo +--echo # +--echo # Bug #45806 crash when replacing into a view with a join! +--echo # +CREATE TABLE t1(a INT UNIQUE); +CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a; +INSERT INTO t1 VALUES (1), (2); + +REPLACE INTO v1(a) SELECT 1 FROM t1,t1 AS c; +SELECT * FROM v1; +REPLACE INTO v1(a) SELECT 3 FROM t1,t1 AS c; +SELECT * FROM v1; +DELETE FROM t1 WHERE a=3; +INSERT INTO v1(a) SELECT 1 FROM t1,t1 AS c +ON DUPLICATE KEY UPDATE `v1`.`a`= 1; +SELECT * FROM v1; + +CREATE VIEW v2 AS SELECT t1.a FROM t1, v1 AS a; + +REPLACE INTO v2(a) SELECT 1 FROM t1,t1 AS c; +SELECT * FROM v2; +REPLACE INTO v2(a) SELECT 3 FROM t1,t1 AS c; +SELECT * FROM v2; +INSERT INTO v2(a) SELECT 1 FROM t1,t1 AS c +ON DUPLICATE KEY UPDATE `v2`.`a`= 1; +SELECT * FROM v2; + +DROP VIEW v1; +DROP VIEW v2; +DROP TABLE t1; + +--echo # -- End of test case for Bug#45806 + --echo # ----------------------------------------------------------------- --echo # -- End of 5.0 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 28b8bcd320d..83f3b181091 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1148,6 +1148,33 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, } +/* + Get extra info for tables we insert into + + @param table table(TABLE object) we insert into, + might be NULL in case of view + @param table(TABLE_LIST object) or view we insert into +*/ + +static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables) +{ + if (table) + { + if(table->reginfo.lock_type != TL_WRITE_DELAYED) + table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); + return; + } + + DBUG_ASSERT(tables->view); + List_iterator it(*tables->view_tables); + TABLE_LIST *tbl; + while ((tbl= it++)) + prepare_for_positional_update(tbl->table, tbl); + + return; +} + + /* Prepare items in INSERT statement @@ -1298,9 +1325,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, Only call extra() handler method if we are not performing a DELAYED operation. It will instead be executed by delayed insert thread. */ - if ((duplic == DUP_UPDATE || duplic == DUP_REPLACE) && - (table->reginfo.lock_type != TL_WRITE_DELAYED)) - table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); + if (duplic == DUP_UPDATE || duplic == DUP_REPLACE) + prepare_for_positional_update(table, table_list); DBUG_RETURN(FALSE); } From 5899e13a8e9cc88e94b6ea1c991a142fddb62c83 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Fri, 3 Jul 2009 13:55:45 +0200 Subject: [PATCH 149/188] Bug#37274 client 'status' command doesn't print all info after losing connection to server If the server connection was lost during repeated status commands, the client would fail to detect this and the client output would be inconsistent. This patch fixes this issue by making sure that the server is online before the client attempts to execute the status command. client/mysql.cc: * Replace variable "connected" with a call to mysql_real_query_for_lazy() will attempt to reconnect to server on if there is a failure. --- client/mysql.cc | 63 +++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 40c446299be..5afbc2e960b 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4264,41 +4264,36 @@ com_status(String *buffer __attribute__((unused)), MYSQL_RES *result; LINT_INIT(result); + if (mysql_real_query_for_lazy( + C_STRING_WITH_LEN("select DATABASE(), USER() limit 1"))) + return 0; + tee_puts("--------------", stdout); usage(1); /* Print version */ - if (connected) + tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql)); + /* + Don't remove "limit 1", + it is protection againts SQL_SELECT_LIMIT=0 + */ + if (mysql_store_result_for_lazy(&result)) { - tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql)); - /* - Don't remove "limit 1", - it is protection againts SQL_SELECT_LIMIT=0 - */ - if (!mysql_query(&mysql,"select DATABASE(), USER() limit 1") && - (result=mysql_use_result(&mysql))) + MYSQL_ROW cur=mysql_fetch_row(result); + if (cur) { - MYSQL_ROW cur=mysql_fetch_row(result); - if (cur) - { - tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : ""); - tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]); - } - mysql_free_result(result); - } + tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : ""); + tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]); + } + mysql_free_result(result); + } + #ifdef HAVE_OPENSSL - if ((status_str= mysql_get_ssl_cipher(&mysql))) - tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n", - status_str); - else -#endif /* HAVE_OPENSSL */ - tee_puts("SSL:\t\t\tNot in use", stdout); - } + if ((status_str= mysql_get_ssl_cipher(&mysql))) + tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n", + status_str); else - { - vidattr(A_BOLD); - tee_fprintf(stdout, "\nNo connection\n"); - vidattr(A_NORMAL); - return 0; - } +#endif /* HAVE_OPENSSL */ + tee_puts("SSL:\t\t\tNot in use", stdout); + if (skip_updates) { vidattr(A_BOLD); @@ -4317,8 +4312,14 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff)); /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */ - if (!mysql_query(&mysql,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") && - (result=mysql_use_result(&mysql))) + if (mysql_real_query_for_lazy(C_STRING_WITH_LEN( + "select @@character_set_client, @@character_set_connection, " + "@@character_set_server, @@character_set_database limit 1"))) + { + if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) + return 0; + } + if (mysql_store_result_for_lazy(&result)) { MYSQL_ROW cur=mysql_fetch_row(result); if (cur) From 345e8347cb0931f212fdd22cca6d8558b4e0843c Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Mon, 6 Jul 2009 11:55:53 +0500 Subject: [PATCH 150/188] Fix for bug#42364 reverted. --- mysql-test/r/warnings.result | 5 ----- mysql-test/t/warnings.test | 7 ------- sql/sql_table.cc | 2 +- tests/mysql_client_test.c | 2 -- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 8a87852d582..2e393aea9e4 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -313,9 +313,4 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1 insert into t2 values(@q); ERROR 22001: Data too long for column 'c_tinyblob' at row 1 drop table t1, t2; -DROP TABLE t1; -ERROR 42S02: Unknown table 't1' -SHOW ERRORS; -Level Code Message -Error 1051 Unknown table 't1' End of 5.0 tests diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 176f320e390..12421170eba 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -225,11 +225,4 @@ insert into t2 values(@q); drop table t1, t2; -# -# Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table -# ---error ER_BAD_TABLE_ERROR -DROP TABLE t1; -SHOW ERRORS; - --echo End of 5.0 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 813a0472b76..e752421223a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1995,7 +1995,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, pthread_mutex_unlock(&LOCK_open); thd->thread_specific_used|= tmp_table_deleted; error= 0; - thd->no_warnings_for_error= 0; if (wrong_tables.length()) { if (!foreign_key_error) @@ -2057,6 +2056,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, err_with_placeholders: unlock_table_names(thd, tables, (TABLE_LIST*) 0); pthread_mutex_unlock(&LOCK_open); + thd->no_warnings_for_error= 0; DBUG_RETURN(error); } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 73d0ab6ce1e..b836293442a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -4769,8 +4769,6 @@ static void test_errors() result= mysql_store_result(mysql); mytest(result); - DIE_UNLESS(mysql_num_rows(result) == 1); - (void) my_process_result_set(result); mysql_free_result(result); } From 8ba57fa3c90ed17ed54e487e1f05fe42ba550d6e Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Mon, 6 Jul 2009 09:02:14 +0100 Subject: [PATCH 151/188] BUG#44581 Slave stops when transaction with non-transactional table gets lock wait timeout In STMT and MIXED modes, a statement that changes both non-transactional and transactional tables must be written to the binary log whenever there are changes to non-transactional tables. This means that the statement gets into the binary log even when the changes to the transactional tables fail. In particular , in the presence of a failure such statement is annotated with the error number and wrapped in a begin/rollback. On the slave, while applying the statement, it is expected the same failure and the rollback prevents the transactional changes to be persisted. Unfortunately, statements that fail due to concurrency issues (e.g. deadlocks, timeouts) are logged in the same way causing the slave to stop as the statements are applied sequentially by the SQL Thread. To fix this bug, we automatically ignore concurrency failures on the slave. Specifically, the following failures are ignored: ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK and ER_XA_RBDEADLOCK. --- .../suite/rpl/r/rpl_concurrency_error.result | 119 ++++++++++++++ .../rpl/t/rpl_concurrency_error-master.opt | 1 + .../suite/rpl/t/rpl_concurrency_error.test | 149 ++++++++++++++++++ sql/log_event.cc | 37 ++++- sql/slave.cc | 19 --- sql/slave.h | 1 - 6 files changed, 302 insertions(+), 24 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_concurrency_error.result create mode 100644 mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_concurrency_error.test diff --git a/mysql-test/suite/rpl/r/rpl_concurrency_error.result b/mysql-test/suite/rpl/r/rpl_concurrency_error.result new file mode 100644 index 00000000000..ba617667d5a --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_concurrency_error.result @@ -0,0 +1,119 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +######################################################################## +# Environment +######################################################################## +CREATE TABLE t (i INT, PRIMARY KEY(i), f CHAR(8)) engine = Innodb; +CREATE TABLE n (d DATETIME, f CHAR(32)) engine = MyIsam; +CREATE TRIGGER tr AFTER UPDATE ON t FOR EACH ROW +BEGIN +INSERT INTO n VALUES ( now(), concat( 'updated t: ', old.f, ' -> ', new.f ) ); +END | +INSERT INTO t VALUES (4,'black'), (2,'red'), (3,'yelow'), (1,'cyan'); +######################################################################## +# Testing ER_LOCK_WAIT_TIMEOUT +######################################################################## +SET AUTOCOMMIT = 1; +BEGIN; +UPDATE t SET f = 'yellow 2' WHERE i = 3; +SET AUTOCOMMIT = 1; +BEGIN; +UPDATE t SET f = 'magenta 2' WHERE f = 'red'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t VALUES (5 + (2 * 10),"brown"); +INSERT INTO n VALUES (now(),"brown"); +COMMIT; +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'magenta 2' WHERE f = 'red' +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'yellow 2' WHERE i = 3 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (5 + (2 * 10),"brown") +master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown") +master-bin.000001 # Query # # ROLLBACK +SET AUTOCOMMIT = 1; +BEGIN; +UPDATE t SET f = 'gray 2' WHERE i = 3; +SET AUTOCOMMIT = 1; +BEGIN; +UPDATE t SET f = 'dark blue 2' WHERE f = 'red'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t VALUES (6 + (2 * 10),"brown"); +INSERT INTO n VALUES (now(),"brown"); +COMMIT; +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'dark blue 2' WHERE f = 'red' +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'gray 2' WHERE i = 3 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (2 * 10),"brown") +master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown") +master-bin.000001 # Xid # # COMMIT /* XID */ +SET AUTOCOMMIT = 0; +UPDATE t SET f = 'yellow 1' WHERE i = 3; +SET AUTOCOMMIT = 0; +UPDATE t SET f = 'magenta 1' WHERE f = 'red'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t VALUES (5 + (1 * 10),"brown"); +INSERT INTO n VALUES (now(),"brown"); +COMMIT; +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'magenta 1' WHERE f = 'red' +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'yellow 1' WHERE i = 3 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (5 + (1 * 10),"brown") +master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown") +master-bin.000001 # Query # # ROLLBACK +SET AUTOCOMMIT = 0; +UPDATE t SET f = 'gray 1' WHERE i = 3; +SET AUTOCOMMIT = 0; +UPDATE t SET f = 'dark blue 1' WHERE f = 'red'; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t VALUES (6 + (1 * 10),"brown"); +INSERT INTO n VALUES (now(),"brown"); +COMMIT; +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'dark blue 1' WHERE f = 'red' +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE t SET f = 'gray 1' WHERE i = 3 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (6 + (1 * 10),"brown") +master-bin.000001 # Query # # use `test`; INSERT INTO n VALUES (now(),"brown") +master-bin.000001 # Xid # # COMMIT /* XID */ +source include/diff_master_slave.inc; +source include/diff_master_slave.inc; +######################################################################## +# Cleanup +######################################################################## +DROP TRIGGER tr; +DROP TABLE t; +DROP TABLE n; diff --git a/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt b/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt new file mode 100644 index 00000000000..a6ef074a120 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt @@ -0,0 +1 @@ +--innodb-lock-wait-timeout=1 diff --git a/mysql-test/suite/rpl/t/rpl_concurrency_error.test b/mysql-test/suite/rpl/t/rpl_concurrency_error.test new file mode 100644 index 00000000000..da2951afb1a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_concurrency_error.test @@ -0,0 +1,149 @@ +############################################################################### +#BUG#44581 Slave stops when transaction with non-transactional table gets +#lock wait timeout +# +# In STMT and MIXED modes, a statement that changes both non-transactional and +# transactional tables must be written to the binary log whenever there are +# changes to non-transactional tables. This means that the statement gets into +# the # binary log even when the changes to the transactional tables fail. In +# particular, in the presence of a failure such statement is annotated with the +# error number and wrapped in a begin/rollback. On the slave, while applying +# the statement, it is expected the same failure and the rollback prevents the +# transactional changes to be persisted. + +# This test aims to verify if a statement that updates both transactional and +# non-transacitonal tables and fails due to concurrency problems is correctly +# processed by the slave in the sense that the statements get into the binary +# log, the error is ignored and only the non-transactional tables are changed. +############################################################################### + +--source include/master-slave.inc +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc + +--echo ######################################################################## +--echo # Environment +--echo ######################################################################## +connection master; + +CREATE TABLE t (i INT, PRIMARY KEY(i), f CHAR(8)) engine = Innodb; +CREATE TABLE n (d DATETIME, f CHAR(32)) engine = MyIsam; + +DELIMITER |; +CREATE TRIGGER tr AFTER UPDATE ON t FOR EACH ROW +BEGIN + INSERT INTO n VALUES ( now(), concat( 'updated t: ', old.f, ' -> ', new.f ) ); +END | +DELIMITER ;| + +INSERT INTO t VALUES (4,'black'), (2,'red'), (3,'yelow'), (1,'cyan'); + +connect (conn1, 127.0.0.1,root,,); +connect (conn2, 127.0.0.1,root,,); + +--echo ######################################################################## +--echo # Testing ER_LOCK_WAIT_TIMEOUT +--echo ######################################################################## + +let $type=2; + +while ($type) +{ + let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); + connection conn1; + if (`select $type = 2`) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if (`select $type = 1`) + { + SET AUTOCOMMIT = 0; + } + eval UPDATE t SET f = 'yellow $type' WHERE i = 3; + + connection conn2; + if (`select $type = 2`) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if (`select $type = 1`) + { + SET AUTOCOMMIT = 0; + } + --error ER_LOCK_WAIT_TIMEOUT + eval UPDATE t SET f = 'magenta $type' WHERE f = 'red'; + eval INSERT INTO t VALUES (5 + ($type * 10),"brown"); + INSERT INTO n VALUES (now(),"brown"); + + connection conn1; + COMMIT; + + connection conn2; + ROLLBACK; + --source include/show_binlog_events.inc + + let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); + connection conn1; + if (`select $type = 2`) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if (`select $type = 1`) + { + SET AUTOCOMMIT = 0; + } + eval UPDATE t SET f = 'gray $type' WHERE i = 3; + + connection conn2; + if (`select $type = 2`) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if (`select $type = 1`) + { + SET AUTOCOMMIT = 0; + } + --error ER_LOCK_WAIT_TIMEOUT + eval UPDATE t SET f = 'dark blue $type' WHERE f = 'red'; + eval INSERT INTO t VALUES (6 + ($type * 10),"brown"); + INSERT INTO n VALUES (now(),"brown"); + + connection conn1; + COMMIT; + + connection conn2; + COMMIT; + --source include/show_binlog_events.inc + + dec $type; +} + +connection master; +sync_slave_with_master; + +connection master; +let $diff_statement= SELECT * FROM t order by i; +source include/diff_master_slave.inc; + +connection master; +let $diff_statement= SELECT * FROM n order by d, f; +source include/diff_master_slave.inc; + +--echo ######################################################################## +--echo # Cleanup +--echo ######################################################################## + +connection master; +DROP TRIGGER tr; +DROP TABLE t; +DROP TABLE n; + +sync_slave_with_master; + +connection master; +disconnect conn1; +disconnect conn2; diff --git a/sql/log_event.cc b/sql/log_event.cc index 493db62e7ef..5f77ab3dcc4 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -369,6 +369,34 @@ int convert_handler_error(int error, THD* thd, TABLE *table) return (actual_error); } +inline bool concurrency_error_code(int error) +{ + switch (error) + { + case ER_LOCK_WAIT_TIMEOUT: + case ER_LOCK_DEADLOCK: + case ER_XA_RBDEADLOCK: + return TRUE; + default: + return (FALSE); + } +} + +inline bool unexpected_error_code(int unexpected_error) +{ + switch (unexpected_error) + { + case ER_NET_READ_ERROR: + case ER_NET_ERROR_ON_WRITE: + case ER_QUERY_INTERRUPTED: + case ER_SERVER_SHUTDOWN: + case ER_NEW_ABORTING_CONNECTION: + return(TRUE); + default: + return(FALSE); + } +} + /* pretty_print_str() */ @@ -3006,7 +3034,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, DBUG_PRINT("query",("%s",thd->query)); if (ignored_error_code((expected_error= error_code)) || - !check_expected_error(thd,rli,expected_error)) + !unexpected_error_code(expected_error)) { if (flags2_inited) /* @@ -3138,8 +3166,8 @@ compare_errors: actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0; DBUG_PRINT("info",("expected_error: %d sql_errno: %d", expected_error, actual_error)); - if ((expected_error != actual_error) && - expected_error && + if ((expected_error && expected_error != actual_error && + !concurrency_error_code(expected_error)) && !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) { @@ -3158,7 +3186,8 @@ Default database: '%s'. Query: '%s'", /* If we get the same error code as expected, or they should be ignored. */ - else if (expected_error == actual_error || + else if ((expected_error == actual_error && + !concurrency_error_code(expected_error)) || ignored_error_code(actual_error)) { DBUG_PRINT("info",("error ignored")); diff --git a/sql/slave.cc b/sql/slave.cc index 0270db9253d..81be7064f89 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1884,25 +1884,6 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings) DBUG_RETURN(len - 1); } - -int check_expected_error(THD* thd, Relay_log_info const *rli, - int expected_error) -{ - DBUG_ENTER("check_expected_error"); - - switch (expected_error) { - case ER_NET_READ_ERROR: - case ER_NET_ERROR_ON_WRITE: - case ER_QUERY_INTERRUPTED: - case ER_SERVER_SHUTDOWN: - case ER_NEW_ABORTING_CONNECTION: - DBUG_RETURN(1); - default: - DBUG_RETURN(0); - } -} - - /* Check if the current error is of temporary nature of not. Some errors are temporary in nature, such as diff --git a/sql/slave.h b/sql/slave.h index 160418955b5..a44a7eed83e 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -171,7 +171,6 @@ bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, bool rpl_master_erroneous_autoinc(THD* thd); const char *print_slave_db_safe(const char *db); -int check_expected_error(THD* thd, Relay_log_info const *rli, int error_code); void skip_load_data_infile(NET* net); void end_slave(); /* release slave threads */ From 0c66f4a64af8f26f2f5f80b9e60c54600cb8da7f Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Mon, 6 Jul 2009 14:19:32 +0530 Subject: [PATCH 152/188] Bug#45803 Inaccurate estimates for partial key values with IBMDB2I Some collations were causing IBMDB2I to report inaccurate key range estimations to the optimizer for LIKE clauses that select substrings. This can be seen by running EXPLAIN. This problem primarily affects multi-byte and unicode character sets. This patch involves substantial changes to several modules. There are a number of problems with the character set and collation handling. These problems have been or are being fixed, and a comprehensive test has been included which should provide much better coverage than there was before. This test is enabled only for IBM i 6.1, because that version has support for the greatest number of collations. mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I result file for test case. mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I Tests for character sets and collations. This test is enabled only for IBM i 6.1, because that version has support for the greatest number of collations. storage/ibmdb2i/db2i_conversion.cc: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I - Added support in convertFieldChars to enable records_in_range to determine how many substitute characters were inserted and to suppress conversion warnings. - Fixed bug which was causing all multi-byte and Unicode fields to be created as UTF16 (CCSID 1200) fields in DB2. The corrected code will now create UCS2 fields as UCS2 (CCSID 13488), UTF8 fields (except for utf8_general_ci) as UTF8 (CCSID 1208), and all other multi-byte or Unicode fields as UTF16. This will only affect tables that are newly created through the IBMDB2I storage engine. Existing IBMDB2I tables will retain the original CCSID until recreated. The existing behavior is believed to be functionally correct, but it may negatively impact performance by causing unnecessary character conversion. Additionally, users accessing IBMDB2I tables through DB2 should be aware that mixing tables created before and after this change may require extra type casts or other workarounds. For this reason, users who have existing IBMDB2I tables using a Unicode collation other than utf8_general_ci are encouraged to recreate their tables (e.g. ALTER TABLE t1 ENGINE=IBMDB2I) in order to get the updated CCSIDs associated with their DB2 tables. - Improved error reporting for unsupported character sets by forcing a check for the iconv conversion table at table creation time, rather than at data access time. storage/ibmdb2i/db2i_myconv.h: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I Fix to set errno when iconv fails. storage/ibmdb2i/db2i_rir.cc: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I Significant improvements were made to the records_in_range code that handles partial length string data in keys for optimizer plan estimation. Previously, to obtain an estimate for a partial key value, the implementation would perform any necessary character conversion and then attempt to determine the unpadded length of the partial key by searching for the minimum or maximum sort character. While this algorithm was sufficient for most single-byte character sets, it did not treat Unicode and multi-byte strings correctly. Furthermore, due to an operating system limitation, partial keys having UTF8 collations (ICU sort sequences in DB2) could not be estimated with this method. With this patch, the code no longer attempts to explicitly determine the unpadded length of the key. Instead, the entire key is converted (if necessary), including padding, and then passed to the operating system for estimation. Depending on the source and target character sets and collations, additional logic is required to correctly handle cases in which MySQL uses unconvertible or differently -weighted values to pad the key. The bulk of the patch exists to implement this additional logic. storage/ibmdb2i/ha_ibmdb2i.h: Bug#45803 Inaccurate estimates for partial key values with IBMDB2I The convertFieldChars declaration was updated to support additional optional behaviors. --- .../suite/ibmdb2i/r/ibmdb2i_collations.result | 1204 +++++++++++++++++ .../suite/ibmdb2i/t/ibmdb2i_collations.test | 44 + storage/ibmdb2i/db2i_conversion.cc | 44 +- storage/ibmdb2i/db2i_myconv.h | 1 + storage/ibmdb2i/db2i_rir.cc | 405 ++++-- storage/ibmdb2i/ha_ibmdb2i.h | 10 +- 6 files changed, 1596 insertions(+), 112 deletions(-) create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result new file mode 100644 index 00000000000..4f7d71cab2d --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_collations.result @@ -0,0 +1,1204 @@ +drop table if exists t1, ffd, fd; +CREATE TABLE t1 (armscii8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_bin engine=ibmdb2i; +CREATE TABLE t1 (armscii8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate armscii8_general_ci engine=ibmdb2i; +CREATE TABLE t1 (ascii_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (ascii_bin char(10) primary key) collate ascii_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ascii_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ascii_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (ascii_general_ci char(10) primary key) collate ascii_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (big5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate big5_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (big5_bin char(10) primary key) collate big5_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (big5_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate big5_chinese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (big5_chinese_ci char(10) primary key) collate big5_chinese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1250_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1250_bin char(10) primary key) collate cp1250_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1250_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_croatian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1250_croatian_ci char(10) primary key) collate cp1250_croatian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1250_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_czech_cs engine=ibmdb2i; +CREATE TABLE t1 (cp1250_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1250_general_ci char(10) primary key) collate cp1250_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1250_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1250_polish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1250_polish_ci char(10) primary key) collate cp1250_polish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1251_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1251_bin char(10) primary key) collate cp1251_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1251_bulgarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_bulgarian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1251_bulgarian_ci char(10) primary key) collate cp1251_bulgarian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1251_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1251_general_ci char(10) primary key) collate cp1251_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1251_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_general_cs engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1251_general_cs char(10) primary key) collate cp1251_general_cs engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1251_ukrainian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1251_ukrainian_ci engine=ibmdb2i; +CREATE TABLE t1 (cp1256_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1256_bin char(10) primary key) collate cp1256_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1256_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1256_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp1256_general_ci char(10) primary key) collate cp1256_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp1257_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_bin engine=ibmdb2i; +CREATE TABLE t1 (cp1257_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_general_ci engine=ibmdb2i; +CREATE TABLE t1 (cp1257_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp1257_lithuanian_ci engine=ibmdb2i; +CREATE TABLE t1 (cp850_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp850_bin char(10) primary key) collate cp850_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp850_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp850_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp850_general_ci char(10) primary key) collate cp850_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp852_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp852_bin char(10) primary key) collate cp852_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp852_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp852_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (cp852_general_ci char(10) primary key) collate cp852_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp866_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_bin engine=ibmdb2i; +CREATE TABLE t1 (cp866_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp866_general_ci engine=ibmdb2i; +CREATE TABLE t1 (cp932_bin integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (cp932_bin char(10) primary key) collate cp932_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (cp932_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate cp932_japanese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (cp932_japanese_ci char(10) primary key) collate cp932_japanese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (dec8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_bin engine=ibmdb2i; +CREATE TABLE t1 (dec8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate dec8_swedish_ci engine=ibmdb2i; +CREATE TABLE t1 (eucjpms_bin integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_bin engine=ibmdb2i; +CREATE TABLE t1 (eucjpms_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate eucjpms_japanese_ci engine=ibmdb2i; +CREATE TABLE t1 (euckr_bin integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (euckr_bin char(10) primary key) collate euckr_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (euckr_korean_ci integer, c char(10), v varchar(20), index(c), index(v)) collate euckr_korean_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (euckr_korean_ci char(10) primary key) collate euckr_korean_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (gb2312_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (gb2312_bin char(10) primary key) collate gb2312_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (gb2312_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gb2312_chinese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (gb2312_chinese_ci char(10) primary key) collate gb2312_chinese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (gbk_bin integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (gbk_bin char(10) primary key) collate gbk_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (gbk_chinese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate gbk_chinese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (gbk_chinese_ci char(10) primary key) collate gbk_chinese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (geostd8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_bin engine=ibmdb2i; +CREATE TABLE t1 (geostd8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate geostd8_general_ci engine=ibmdb2i; +CREATE TABLE t1 (greek_bin integer, c char(10), v varchar(20), index(c), index(v)) collate greek_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (greek_bin char(10) primary key) collate greek_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (greek_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate greek_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (greek_general_ci char(10) primary key) collate greek_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (hebrew_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (hebrew_bin char(10) primary key) collate hebrew_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (hebrew_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hebrew_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (hebrew_general_ci char(10) primary key) collate hebrew_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (hp8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_bin engine=ibmdb2i; +CREATE TABLE t1 (hp8_english_ci integer, c char(10), v varchar(20), index(c), index(v)) collate hp8_english_ci engine=ibmdb2i; +CREATE TABLE t1 (keybcs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_bin engine=ibmdb2i; +CREATE TABLE t1 (keybcs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate keybcs2_general_ci engine=ibmdb2i; +CREATE TABLE t1 (koi8r_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_bin engine=ibmdb2i; +CREATE TABLE t1 (koi8r_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8r_general_ci engine=ibmdb2i; +CREATE TABLE t1 (koi8u_bin integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_bin engine=ibmdb2i; +CREATE TABLE t1 (koi8u_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate koi8u_general_ci engine=ibmdb2i; +CREATE TABLE t1 (latin1_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_bin char(10) primary key) collate latin1_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_danish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_danish_ci char(10) primary key) collate latin1_danish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_general_ci char(10) primary key) collate latin1_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_general_cs engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_general_cs char(10) primary key) collate latin1_general_cs engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_german1_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german1_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_german1_ci char(10) primary key) collate latin1_german1_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_german2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_german2_ci engine=ibmdb2i; +CREATE TABLE t1 (latin1_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_spanish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_spanish_ci char(10) primary key) collate latin1_spanish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin1_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin1_swedish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin1_swedish_ci char(10) primary key) collate latin1_swedish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin2_bin char(10) primary key) collate latin2_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin2_croatian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_croatian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin2_croatian_ci char(10) primary key) collate latin2_croatian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin2_czech_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_czech_cs engine=ibmdb2i; +CREATE TABLE t1 (latin2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin2_general_ci char(10) primary key) collate latin2_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin2_hungarian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin2_hungarian_ci char(10) primary key) collate latin2_hungarian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin5_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin5_bin char(10) primary key) collate latin5_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin5_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin5_turkish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (latin5_turkish_ci char(10) primary key) collate latin5_turkish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (latin7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_bin engine=ibmdb2i; +CREATE TABLE t1 (latin7_estonian_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_estonian_cs engine=ibmdb2i; +CREATE TABLE t1 (latin7_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_ci engine=ibmdb2i; +CREATE TABLE t1 (latin7_general_cs integer, c char(10), v varchar(20), index(c), index(v)) collate latin7_general_cs engine=ibmdb2i; +CREATE TABLE t1 (macce_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macce_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (macce_bin char(10) primary key) collate macce_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (macce_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macce_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (macce_general_ci char(10) primary key) collate macce_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (macroman_bin integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_bin engine=ibmdb2i; +CREATE TABLE t1 (macroman_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate macroman_general_ci engine=ibmdb2i; +CREATE TABLE t1 (sjis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (sjis_bin char(10) primary key) collate sjis_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (sjis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate sjis_japanese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (sjis_japanese_ci char(10) primary key) collate sjis_japanese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (swe7_bin integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_bin engine=ibmdb2i; +CREATE TABLE t1 (swe7_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate swe7_swedish_ci engine=ibmdb2i; +CREATE TABLE t1 (tis620_bin integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (tis620_bin char(10) primary key) collate tis620_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (tis620_thai_ci integer, c char(10), v varchar(20), index(c), index(v)) collate tis620_thai_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 11 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 23 NULL 6 Using where +drop table t1; +create table t1 (tis620_thai_ci char(10) primary key) collate tis620_thai_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_bin char(10) primary key) collate ucs2_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_czech_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_czech_ci char(10) primary key) collate ucs2_czech_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_danish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_danish_ci char(10) primary key) collate ucs2_danish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_esperanto_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_esperanto_ci char(10) primary key) collate ucs2_esperanto_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_estonian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_estonian_ci char(10) primary key) collate ucs2_estonian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_general_ci char(10) primary key) collate ucs2_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_hungarian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_hungarian_ci char(10) primary key) collate ucs2_hungarian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_icelandic_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_icelandic_ci char(10) primary key) collate ucs2_icelandic_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_latvian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_latvian_ci char(10) primary key) collate ucs2_latvian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_lithuanian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_lithuanian_ci char(10) primary key) collate ucs2_lithuanian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_persian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_persian_ci char(10) primary key) collate ucs2_persian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_polish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_polish_ci char(10) primary key) collate ucs2_polish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_romanian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_romanian_ci char(10) primary key) collate ucs2_romanian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_roman_ci engine=ibmdb2i; +CREATE TABLE t1 (ucs2_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovak_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_slovak_ci char(10) primary key) collate ucs2_slovak_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_slovenian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_slovenian_ci char(10) primary key) collate ucs2_slovenian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish2_ci engine=ibmdb2i; +CREATE TABLE t1 (ucs2_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_spanish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_spanish_ci char(10) primary key) collate ucs2_spanish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_swedish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_swedish_ci char(10) primary key) collate ucs2_swedish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_turkish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_turkish_ci char(10) primary key) collate ucs2_turkish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ucs2_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ucs2_unicode_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 21 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 43 NULL 6 Using where +drop table t1; +create table t1 (ucs2_unicode_ci char(10) primary key) collate ucs2_unicode_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ujis_bin integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (ujis_bin char(10) primary key) collate ujis_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (ujis_japanese_ci integer, c char(10), v varchar(20), index(c), index(v)) collate ujis_japanese_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (ujis_japanese_ci char(10) primary key) collate ujis_japanese_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_bin integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_bin engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_bin char(10) primary key) collate utf8_bin engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_czech_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_czech_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_czech_ci char(10) primary key) collate utf8_czech_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_danish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_danish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_danish_ci char(10) primary key) collate utf8_danish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_esperanto_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_esperanto_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_esperanto_ci char(10) primary key) collate utf8_esperanto_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_estonian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_estonian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_estonian_ci char(10) primary key) collate utf8_estonian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_general_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_general_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_general_ci char(10) primary key) collate utf8_general_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_hungarian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_hungarian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_hungarian_ci char(10) primary key) collate utf8_hungarian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_icelandic_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_icelandic_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_icelandic_ci char(10) primary key) collate utf8_icelandic_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_latvian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_latvian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_latvian_ci char(10) primary key) collate utf8_latvian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_lithuanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_lithuanian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_lithuanian_ci char(10) primary key) collate utf8_lithuanian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_persian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_persian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_persian_ci char(10) primary key) collate utf8_persian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_polish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_polish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_polish_ci char(10) primary key) collate utf8_polish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_romanian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_romanian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_romanian_ci char(10) primary key) collate utf8_romanian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_roman_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_roman_ci engine=ibmdb2i; +CREATE TABLE t1 (utf8_slovak_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovak_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_slovak_ci char(10) primary key) collate utf8_slovak_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_slovenian_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_slovenian_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_slovenian_ci char(10) primary key) collate utf8_slovenian_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_spanish2_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish2_ci engine=ibmdb2i; +CREATE TABLE t1 (utf8_spanish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_spanish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_spanish_ci char(10) primary key) collate utf8_spanish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_swedish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_swedish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_swedish_ci char(10) primary key) collate utf8_swedish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_turkish_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_turkish_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_turkish_ci char(10) primary key) collate utf8_turkish_ci engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (utf8_unicode_ci integer, c char(10), v varchar(20), index(c), index(v)) collate utf8_unicode_ci engine=ibmdb2i; +insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); +insert into t1 select * from t1; +explain select c,v from t1 force index(c) where c like "ab%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 31 NULL 6 Using where +explain select c,v from t1 force index(v) where v like "de%"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range v v 63 NULL 6 Using where +drop table t1; +create table t1 (utf8_unicode_ci char(10) primary key) collate utf8_unicode_ci engine=ibmdb2i; +drop table t1; +create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i; +create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; +create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer); +insert into intermed (cs, ccsid) select * from ffd; +create temporary table intermed2 (row integer key auto_increment, srtseq char(10)); +insert into intermed2 (srtseq) select * from fd; +select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row; +ccsid cs srtseq +500 "ascii_bin" QBLA101F4U +500 "ascii_general_ci" QALA101F4S +1200 "big5_bin" QBCHT04B0U +1200 "big5_chinese_ci" QACHT04B0S +1153 "cp1250_bin" QELA20481U +1153 "cp1250_croatian_ci" QALA20481S +1153 "cp1250_general_ci" QCLA20481S +1153 "cp1250_polish_ci" QDLA20481S +1025 "cp1251_bin" QCCYR0401U +1025 "cp1251_bulgarian_ci QACYR0401S +1025 "cp1251_general_ci" QBCYR0401S +1025 "cp1251_general_cs" QBCYR0401U +420 "cp1256_bin" QBARA01A4U +420 "cp1256_general_ci" QAARA01A4S +500 "cp850_bin" QDLA101F4U +500 "cp850_general_ci" QCLA101F4S +870 "cp852_bin" QBLA20366U +870 "cp852_general_ci" QALA20366S +1200 "cp932_bin" QBJPN04B0U +1200 "cp932_japanese_ci" QAJPN04B0S +1200 "euckr_bin" QBKOR04B0U +1200 "euckr_korean_ci" QAKOR04B0S +1200 "gb2312_bin" QBCHS04B0U +1200 "gb2312_chinese_ci" QACHS04B0S +1200 "gbk_bin" QDCHS04B0U +1200 "gbk_chinese_ci" QCCHS04B0S +875 "greek_bin" QBELL036BU +875 "greek_general_ci" QAELL036BS +424 "hebrew_bin" QBHEB01A8U +424 "hebrew_general_ci" QAHEB01A8S +1148 "latin1_bin" QFLA1047CU +1148 "latin1_danish_ci" QALA1047CS +1148 "latin1_general_ci" QBLA1047CS +1148 "latin1_general_cs" QBLA1047CU +1148 "latin1_german1_ci" QCLA1047CS +1148 "latin1_spanish_ci" QDLA1047CS +1148 "latin1_swedish_ci" QELA1047CS +870 "latin2_bin" QGLA20366U +870 "latin2_croatian_ci" QCLA20366S +870 "latin2_general_ci" QELA20366S +870 "latin2_hungarian_ci QFLA20366S +1026 "latin5_bin" QBTRK0402U +1026 "latin5_turkish_ci" QATRK0402S +870 "macce_bin" QILA20366U +870 "macce_general_ci" QHLA20366S +1200 "sjis_bin" QDJPN04B0U +1200 "sjis_japanese_ci" QCJPN04B0S +838 "tis620_bin" QBTHA0346U +838 "tis620_thai_ci" QATHA0346S +13488 "ucs2_bin" *HEX +13488 "ucs2_czech_ci" I34ACS_CZ +13488 "ucs2_danish_ci" I34ADA_DK +13488 "ucs2_esperanto_ci" I34AEO +13488 "ucs2_estonian_ci" I34AET +13488 "ucs2_general_ci" QAUCS04B0S +13488 "ucs2_hungarian_ci" I34AHU +13488 "ucs2_icelandic_ci" I34AIS +13488 "ucs2_latvian_ci" I34ALV +13488 "ucs2_lithuanian_ci" I34ALT +13488 "ucs2_persian_ci" I34AFA +13488 "ucs2_polish_ci" I34APL +13488 "ucs2_romanian_ci" I34ARO +13488 "ucs2_slovak_ci" I34ASK +13488 "ucs2_slovenian_ci" I34ASL +13488 "ucs2_spanish_ci" I34AES +13488 "ucs2_swedish_ci" I34ASW +13488 "ucs2_turkish_ci" I34ATR +13488 "ucs2_unicode_ci" I34AEN +1200 "ujis_bin" QFJPN04B0U +1200 "ujis_japanese_ci" QEJPN04B0S +1208 "utf8_bin" *HEX +1208 "utf8_czech_ci" I34ACS_CZ +1208 "utf8_danish_ci" I34ADA_DK +1208 "utf8_esperanto_ci" I34AEO +1208 "utf8_estonian_ci" I34AET +1200 "utf8_general_ci" QAUCS04B0S +1208 "utf8_hungarian_ci" I34AHU +1208 "utf8_icelandic_ci" I34AIS +1208 "utf8_latvian_ci" I34ALV +1208 "utf8_lithuanian_ci" I34ALT +1208 "utf8_persian_ci" I34AFA +1208 "utf8_polish_ci" I34APL +1208 "utf8_romanian_ci" I34ARO +1208 "utf8_slovak_ci" I34ASK +1208 "utf8_slovenian_ci" I34ASL +1208 "utf8_spanish_ci" I34AES +1208 "utf8_swedish_ci" I34ASW +1208 "utf8_turkish_ci" I34ATR +1208 "utf8_unicode_ci" I34AEN +drop table ffd, fd; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test new file mode 100644 index 00000000000..899f330d360 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_collations.test @@ -0,0 +1,44 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source suite/ibmdb2i/include/have_i61.inc; +--disable_warnings +drop table if exists t1, ffd, fd; +--enable_warnings + +--disable_abort_on_error +--error 0,255 +exec system "DLTF QGPL/FFDOUT" > /dev/null; +--error 0,255 +exec system "DLTF QGPL/FDOUT" > /dev/null; +--enable_abort_on_error +let $count= query_get_value(select count(*) from information_schema.COLLATIONS where COLLATION_NAME <> "binary", count(*),1); + +while ($count) +{ + let $collation = query_get_value(select COLLATION_NAME from information_schema.COLLATIONS where COLLATION_NAME <> "binary" order by COLLATION_NAME desc, COLLATION_NAME, $count); + error 0,1005,2504,2028; + eval CREATE TABLE t1 ($collation integer, c char(10), v varchar(20), index(c), index(v)) collate $collation engine=ibmdb2i; + if (!$mysql_errno) + { + insert into t1 (c,v) values ("abc","def"),("abcd", "def"),("abcde","defg"),("aaaa","bbbb"); + insert into t1 select * from t1; + explain select c,v from t1 force index(c) where c like "ab%"; + explain select c,v from t1 force index(v) where v like "de%"; + drop table t1; + eval create table t1 ($collation char(10) primary key) collate $collation engine=ibmdb2i; + system system "DSPFFD FILE(\"test\"/\"t1\") OUTPUT(*OUTFILE) OUTFILE(QGPL/FFDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; + system system "DSPFD FILE(\"test\"/\"t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; + drop table t1; + } + dec $count; +} + +create table ffd (WHCHD1 CHAR(20), WHCSID decimal(5,0)) engine=ibmdb2i; +system system "CPYF FROMFILE(QGPL/FFDOUT) TOFILE(\"test\"/\"ffd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; +create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; +system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; +create temporary table intermed (row integer key auto_increment, cs char(30), ccsid integer); +insert into intermed (cs, ccsid) select * from ffd; +create temporary table intermed2 (row integer key auto_increment, srtseq char(10)); +insert into intermed2 (srtseq) select * from fd; +select ccsid, cs, srtseq from intermed inner join intermed2 on intermed.row = intermed2.row; +drop table ffd, fd; diff --git a/storage/ibmdb2i/db2i_conversion.cc b/storage/ibmdb2i/db2i_conversion.cc index 0acde10a4cd..9a85eb01c9b 100644 --- a/storage/ibmdb2i/db2i_conversion.cc +++ b/storage/ibmdb2i/db2i_conversion.cc @@ -137,7 +137,9 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction, char* output, size_t ilen, size_t olen, - size_t* outDataLen) + size_t* outDataLen, + bool tacitErrors, + size_t* substChars) { DBUG_PRINT("ha_ibmdb2i::convertFieldChars",("Direction: %d; length = %d", direction, ilen)); @@ -157,26 +159,26 @@ int ha_ibmdb2i::convertFieldChars(enum_conversionDirection direction, size_t initOLen= olen; size_t substitutedChars = 0; int rc = iconv(conversion, (char**)&input, &ilen, &output, &olen, &substitutedChars ); + if (outDataLen) *outDataLen = initOLen - olen; + if (substChars) *substChars = substitutedChars; if (unlikely(rc < 0)) { int er = errno; if (er == EILSEQ) { - getErrTxt(DB2I_ERR_ILL_CHAR, table->field[fieldID]->field_name); + if (!tacitErrors) getErrTxt(DB2I_ERR_ILL_CHAR, table->field[fieldID]->field_name); return (DB2I_ERR_ILL_CHAR); } else { - getErrTxt(DB2I_ERR_ICONV,er); + if (!tacitErrors) getErrTxt(DB2I_ERR_ICONV,er); return (DB2I_ERR_ICONV); } } - if (unlikely(substitutedChars)) + if (unlikely(substitutedChars) && (!tacitErrors)) { warning(ha_thd(), DB2I_ERR_SUB_CHARS, table->field[fieldID]->field_name); } - - if (outDataLen) *outDataLen = initOLen - olen; return (0); } @@ -555,12 +557,12 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field, return 1; if (fieldCharSet->mbmaxlen > 1) { - if (strncmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")) == 0 ) // UCS2 + if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 { sprintf(stringBuildBuffer, "GRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters db2Ccsid = 13488; } - else if (strncmp(fieldCharSet->name, "utf8_", sizeof("utf8_")) == 0 && + else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && strcmp(fieldCharSet->name, "utf8_general_ci") != 0) { sprintf(stringBuildBuffer, "CHAR(%d)", max(fieldLength, 1)); // Number of bytes @@ -584,12 +586,12 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field, { if (fieldCharSet->mbmaxlen > 1) { - if (strncmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")) == 0 ) // UCS2 + if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 { sprintf(stringBuildBuffer, "VARGRAPHIC(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters db2Ccsid = 13488; } - else if (strncmp(fieldCharSet->name, "utf8_", sizeof("utf8_")) == 0 && + else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && strcmp(fieldCharSet->name, "utf8_general_ci") != 0) { sprintf(stringBuildBuffer, "VARCHAR(%d)", max(fieldLength, 1)); // Number of bytes @@ -611,12 +613,12 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field, { if (fieldCharSet->mbmaxlen > 1) { - if (strncmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")) == 0 ) // UCS2 + if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 { sprintf(stringBuildBuffer, "LONG VARGRAPHIC "); db2Ccsid = 13488; } - else if (strncmp(fieldCharSet->name, "utf8_", sizeof("utf8_")) == 0 && + else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && strcmp(fieldCharSet->name, "utf8_general_ci") != 0) { sprintf(stringBuildBuffer, "LONG VARCHAR "); @@ -639,12 +641,12 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field, if (fieldCharSet->mbmaxlen > 1) { - if (strncmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")) == 0 ) // UCS2 + if (memcmp(fieldCharSet->name, "ucs2_", sizeof("ucs2_")-1) == 0 ) // UCS2 { sprintf(stringBuildBuffer, "DBCLOB(%d)", max(fieldLength / fieldCharSet->mbmaxlen, 1)); // Number of characters db2Ccsid = 13488; } - else if (strncmp(fieldCharSet->name, "utf8_", sizeof("utf8_")) == 0 && + else if (memcmp(fieldCharSet->name, "utf8_", sizeof("utf8_")-1) == 0 && strcmp(fieldCharSet->name, "utf8_general_ci") != 0) { sprintf(stringBuildBuffer, "CLOB(%d)", max(fieldLength, 1)); // Number of bytes @@ -671,11 +673,15 @@ int ha_ibmdb2i::getFieldTypeMapping(Field* field, return rtnCode; } - // Check whether there is a character conversion available. - iconv_t temp; - int32 rc = getConversion(toDB2, fieldCharSet, db2Ccsid, temp); - if (unlikely(rc)) - return rc; + if (db2Ccsid != 1208 && + db2Ccsid != 13488) + { + // Check whether there is a character conversion available. + iconv_t temp; + int32 rc = getConversion(toDB2, fieldCharSet, db2Ccsid, temp); + if (unlikely(rc)) + return rc; + } sprintf(stringBuildBuffer, " CCSID %d ", db2Ccsid); mapping.append(stringBuildBuffer); diff --git a/storage/ibmdb2i/db2i_myconv.h b/storage/ibmdb2i/db2i_myconv.h index a9e87474505..98032748148 100644 --- a/storage/ibmdb2i/db2i_myconv.h +++ b/storage/ibmdb2i/db2i_myconv.h @@ -220,6 +220,7 @@ INTERN size_t myconv_dmap(myconv_t cd, } else { *pOut=dmapS2S[*pIn]; if (*pOut == 0x00) { + errno=EILSEQ; /* 116 */ *outBytesLeft-=(*inBytesLeft-inLen); *inBytesLeft=inLen; *outBuf=pOut; diff --git a/storage/ibmdb2i/db2i_rir.cc b/storage/ibmdb2i/db2i_rir.cc index a80a181c9ac..091c4d98383 100644 --- a/storage/ibmdb2i/db2i_rir.cc +++ b/storage/ibmdb2i/db2i_rir.cc @@ -51,7 +51,6 @@ static inline int getKeyCntFromMap(key_part_map keypart_map) return (cnt); } - /** @brief Given a starting key and an ending key, estimate the number of rows that @@ -270,81 +269,163 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx, DB2Field& db2Field = db2Table->db2Field(field->field_index); litDefPtr->DataType = db2Field.getType(); /* - Convert the literal to DB2 format. - */ - rc = convertMySQLtoDB2(field, - db2Field, - literalPtr, - (uchar*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); + Convert the literal to DB2 format + */ + if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data + (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data + (litDefPtr->DataType == QMY_CHAR || + litDefPtr->DataType == QMY_VARCHAR || + litDefPtr->DataType == QMY_GRAPHIC || + litDefPtr->DataType == QMY_VARGRAPHIC)) + { + // Most of the code is required by the considerable wrangling needed + // to prepare partial keys for use by DB2 + // 1. UTF8 (CCSID 1208) data can be copied across unmodified if it is + // utf8_bin. Otherwise, we need to convert the min and max + // characters into the min and max characters employed + // by the DB2 sort sequence. This is complicated by the fact that + // the character widths are not always equal. + // 2. Likewise, UCS2 (CCSID 13488) data can be copied across unmodified + // if it is ucs2_bin or ucs2_general_ci. Otherwise, we need to + // convert the min and max characters into the min and max characters + // employed by the DB2 sort sequence. + // 3. All other data will use standard iconv conversions. If an + // unconvertible character is encountered, we assume it is the min + // char and fill the remainder of the DB2 key with 0s. This may not + // always be accurate, but it is probably sufficient for range + // estimations. + const char* keyData = minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0); + char* db2Data = literalPtr; + uint16 outLen = db2Field.getByteLengthInRecord(); + uint16 inLen; + if (litDefPtr->DataType == QMY_VARCHAR || + litDefPtr->DataType == QMY_VARGRAPHIC) + { + inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8); + keyData += 2; + outLen -= sizeof(uint16); + db2Data += sizeof(uint16); + } + else + { + inLen = field->max_display_length(); + } + + size_t convertedBytes = 0; + if (db2Field.getCCSID() == 1208) + { + DBUG_ASSERT(inLen <= outLen); + if (strcmp(field->charset()->name, "utf8_bin")) + { + const char* end = keyData+inLen; + const char* curKey = keyData; + char* curDB2 = db2Data; + uint32 min = field->charset()->min_sort_char; + while ((curKey < end) && (curDB2 < db2Data+outLen-3)) + { + my_wc_t temp; + int len = field->charset()->cset->mb_wc(field->charset(), + &temp, + (const uchar*)curKey, + (const uchar*)end); + if (temp != min) + { + DBUG_ASSERT(len <= 3); + switch (len) + { + case 3: *(curDB2+2) = *(curKey+2); + case 2: *(curDB2+1) = *(curKey+1); + case 1: *(curDB2) = *(curKey); + } + curDB2 += len; + } + else + { + *(curDB2++) = 0xEF; + *(curDB2++) = 0xBF; + *(curDB2++) = 0xBF; + } + curKey += len; + } + convertedBytes = curDB2 - db2Data; + } + else + { + memcpy(db2Data, keyData, inLen); + convertedBytes = inLen; + } + rc = 0; + } + else if (db2Field.getCCSID() == 13488) + { + DBUG_ASSERT(inLen <= outLen); + if (strcmp(field->charset()->name, "ucs2_bin") && + strcmp(field->charset()->name, "ucs2_general_ci")) + { + const char* end = keyData+inLen; + const uint16* curKey = (uint16*)keyData; + uint16* curDB2 = (uint16*)db2Data; + uint16 min = field->charset()->min_sort_char; + while (curKey < (uint16*)end) + { + if (*curKey != min) + *curDB2 = *curKey; + else + *curDB2 = 0xFFFF; + ++curKey; + ++curDB2; + } + } + else + { + memcpy(db2Data, keyData, inLen); + } + convertedBytes = inLen; + rc = 0; + } + else + { + rc = convertFieldChars(toDB2, + field->field_index, + keyData, + db2Data, + inLen, + outLen, + &convertedBytes, + true); + + if (rc == DB2I_ERR_ILL_CHAR) + { + // If an illegal character is encountered, we fill the remainder + // of the key with 0x00. This was implemented as a corollary to + // Bug#45012, though it should probably remain even after that + // bug is fixed. + memset(db2Data+convertedBytes, 0x00, outLen-convertedBytes); + convertedBytes = outLen; + rc = 0; + } + } + + if (!rc && + (litDefPtr->DataType == QMY_VARGRAPHIC || + litDefPtr->DataType == QMY_VARCHAR)) + { + *(uint16*)(db2Data-sizeof(uint16)) = + convertedBytes / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1); + } + + } + else // Non-character fields + { + rc = convertMySQLtoDB2(field, + db2Field, + literalPtr, + (uchar*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); + } + if (rc != 0) break; litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr); litDefPtr->Length = db2Field.getByteLengthInRecord(); - tempLen = litDefPtr->Length; - /* - Do additional conversion of a character or graphic value. - */ - CHARSET_INFO* fieldCharSet = field->charset(); - if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data - (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data - (litDefPtr->DataType == QMY_CHAR || litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_GRAPHIC || litDefPtr->DataType == QMY_VARGRAPHIC)) - { - if (litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_VARGRAPHIC) - tempPtr = literalPtr + sizeof(uint16); - else - tempPtr = literalPtr; - /* The following code checks to determine if MySQL is passing a - partial key. DB2 will accept a partial field value, but only - in the last field position of the key composite (and only if - there is no ICU sort sequence on the index). */ - tempMinPtr = (char*)minPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0); - if (field->type() == MYSQL_TYPE_VARCHAR) - { - /* MySQL always stores key lengths as 2 bytes, little-endian. */ - tempLen = *(uint8*)tempMinPtr + ((*(uint8*)(tempMinPtr+1)) << 8); - tempMinPtr = (char*)((char*)tempMinPtr + 2); - } - else - tempLen = field->field_length; - - /* Determine if we are dealing with a partial key and if so, find the end of the partial key. */ - if (litDefPtr->DataType == QMY_CHAR || litDefPtr->DataType == QMY_VARCHAR ) - { /* Char or varchar. If UTF8, no conversion is done to DB2 graphic.) */ - endOfMinPtr = (char*)memchr(tempMinPtr,field->charset()->min_sort_char,tempLen); - if (endOfMinPtr) - endOfLiteralPtr = tempPtr + ((uint32_t)(endOfMinPtr - tempMinPtr)); - } - else - { - if (strncmp(fieldCharSet->csname, "utf8", sizeof("utf8")) == 0) - { /* The MySQL charset is UTF8 but we are converting to graphic on DB2. Divide number of UTF8 bytes - by 3 to get the number of characters, then multiple by 2 for double-byte graphic.*/ - endOfMinPtr = (char*)memchr(tempMinPtr,field->charset()->min_sort_char,tempLen); - if (endOfMinPtr) - endOfLiteralPtr = tempPtr + (((uint32_t)((endOfMinPtr - tempMinPtr)) / 3) * 2); - } - else - { /* The DB2 data type is graphic or vargraphic, and we are not converting from UTF8 to graphic. */ - endOfMinPtr = (char*)wmemchr((wchar_t*)tempMinPtr,field->charset()->min_sort_char,tempLen/2); - if (endOfMinPtr) - endOfLiteralPtr = tempPtr + (endOfMinPtr - tempMinPtr); - } - } - /* Enforce here that a partial is only allowed on the last field position - of the key composite */ - if (endOfLiteralPtr) - { - if ((partsInUse + 1) < minKeyCnt) - { - rc = HA_POS_ERROR; - break; - } - endByte = endOfLiteralPtr - tempPtr; - /* We're making an assumption that if MySQL gives us a partial key, - the length of the partial is the same for both the min_key and max_key. */ - } - } literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal } /* If there is a max_key value for this field, and if the max_key value is @@ -389,28 +470,168 @@ ha_rows ha_ibmdb2i::records_in_range(uint inx, /* Convert the literal to DB2 format */ - rc = convertMySQLtoDB2(field, - db2Field, - literalPtr, - (uchar*)maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); + if ((field->type() != MYSQL_TYPE_BIT) && // Don't do conversion on BIT data + (field->charset() != &my_charset_bin) && // Don't do conversion on BINARY data + (litDefPtr->DataType == QMY_CHAR || + litDefPtr->DataType == QMY_VARCHAR || + litDefPtr->DataType == QMY_GRAPHIC || + litDefPtr->DataType == QMY_VARGRAPHIC)) + { + // We need to handle char fields in a special way in order to account + // for partial keys. Refer to the note above for a description of the + // basic design. + char* keyData = maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0); + char* db2Data = literalPtr; + uint16 outLen = db2Field.getByteLengthInRecord(); + uint16 inLen; + if (litDefPtr->DataType == QMY_VARCHAR || + litDefPtr->DataType == QMY_VARGRAPHIC) + { + inLen = *(uint8*)keyData + ((*(uint8*)(keyData+1)) << 8); + keyData += 2; + outLen -= sizeof(uint16); + db2Data += sizeof(uint16); + } + else + { + inLen = field->max_display_length(); + } + + size_t convertedBytes; + if (db2Field.getCCSID() == 1208) + { + if (strcmp(field->charset()->name, "utf8_bin")) + { + const char* end = keyData+inLen; + const char* curKey = keyData; + char* curDB2 = db2Data; + uint32 max = field->charset()->max_sort_char; + while (curKey < end && (curDB2 < db2Data+outLen-3)) + { + my_wc_t temp; + int len = field->charset()->cset->mb_wc(field->charset(), &temp, (const uchar*)curKey, (const uchar*)end); + if (temp != max) + { + DBUG_ASSERT(len <= 3); + switch (len) + { + case 3: *(curDB2+2) = *(curKey+2); + case 2: *(curDB2+1) = *(curKey+1); + case 1: *(curDB2) = *(curKey); + } + curDB2 += len; + } + else + { + *(curDB2++) = 0xE4; + *(curDB2++) = 0xB6; + *(curDB2++) = 0xBF; + } + curKey += len; + } + convertedBytes = curDB2 - db2Data; + } + else + { + DBUG_ASSERT(inLen <= outLen); + memcpy(db2Data, keyData, inLen); + convertedBytes = inLen; + } + rc = 0; + } + else if (db2Field.getCCSID() == 13488) + { + if (strcmp(field->charset()->name, "ucs2_bin") && + strcmp(field->charset()->name, "ucs2_general_ci")) + { + char* end = keyData+inLen; + uint16* curKey = (uint16*)keyData; + uint16* curDB2 = (uint16*)db2Data; + uint16 max = field->charset()->max_sort_char; + while (curKey < (uint16*)end) + { + if (*curKey != max) + *curDB2 = *curKey; + else + *curDB2 = 0x4DBF; + ++curKey; + ++curDB2; + } + } + else + { + memcpy(db2Data, keyData, outLen); + } + rc = 0; + } + else + { + size_t substituteChars = 0; + rc = convertFieldChars(toDB2, + field->field_index, + keyData, + db2Data, + inLen, + outLen, + &convertedBytes, + true, + &substituteChars); + + if (rc == DB2I_ERR_ILL_CHAR) + { + // If an illegal character is encountered, we fill the remainder + // of the key with 0xFF. This was implemented to work around + // Bug#45012, though it should probably remain even after that + // bug is fixed. + memset(db2Data+convertedBytes, 0xFF, outLen-convertedBytes); + rc = 0; + } + else if ((substituteChars && + (litDefPtr->DataType == QMY_VARCHAR || + litDefPtr->DataType == QMY_CHAR)) || + strcmp(field->charset()->name, "cp1251_bulgarian_ci") == 0) + { + // When iconv translates the max_sort_char with a substitute + // character, we have no way to know whether this affects + // the sort order of the key. Therefore, to be safe, when + // we know that substitute characters have been used in a + // single-byte string, we traverse the translated key + // in reverse, replacing substitue characters with 0xFF, which + // always sorts with the greatest weight in DB2 sort sequences. + // cp1251_bulgarian_ci is also handled this way because the + // max_sort_char is a control character which does not sort + // equivalently in DB2. + DBUG_ASSERT(inLen == outLen); + char* tmpKey = keyData + inLen - 1; + char* tmpDB2 = db2Data + outLen - 1; + while (*tmpKey == field->charset()->max_sort_char && + *tmpDB2 != 0xFF) + { + *tmpDB2 = 0xFF; + --tmpKey; + --tmpDB2; + } + } + } + + if (!rc && + (litDefPtr->DataType == QMY_VARGRAPHIC || + litDefPtr->DataType == QMY_VARCHAR)) + { + *(uint16*)(db2Data-sizeof(uint16)) = + outLen / (litDefPtr->DataType == QMY_VARGRAPHIC ? 2 : 1); + } + } + else + { + rc = convertMySQLtoDB2(field, + db2Field, + literalPtr, + (uchar*)maxPtr+((curKey.key_part[partsInUse].null_bit)? 1 : 0)); + } if (rc != 0) break; litDefPtr->Offset = (uint32_t)(literalPtr - literalsPtr); litDefPtr->Length = db2Field.getByteLengthInRecord(); - tempLen = litDefPtr->Length; - /* - Now convert a character or graphic value. - */ - if ((field->type() != MYSQL_TYPE_BIT) && - (litDefPtr->DataType == QMY_CHAR || litDefPtr->DataType == QMY_VARCHAR || - litDefPtr->DataType == QMY_GRAPHIC || litDefPtr->DataType == QMY_VARGRAPHIC)) - { - if (litDefPtr->DataType == QMY_VARCHAR || litDefPtr->DataType == QMY_VARGRAPHIC) - { - tempPtr = literalPtr + sizeof(uint16); - } - else - tempPtr = literalPtr; - } literalPtr = literalPtr + litDefPtr->Length; // Bump pointer for next literal } boundsPtr->HiBound.Position = literalCnt; diff --git a/storage/ibmdb2i/ha_ibmdb2i.h b/storage/ibmdb2i/ha_ibmdb2i.h index 2a8d65825bf..006b6b163b8 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.h +++ b/storage/ibmdb2i/ha_ibmdb2i.h @@ -383,7 +383,15 @@ private: int32 prepareWriteBufferForLobs(); uint32 adjustLobBuffersForRead(); bool lobFieldsRequested(); - int convertFieldChars(enum_conversionDirection direction, uint16 fieldID, const char* input, char* output, size_t ilen, size_t olen, size_t* outDataLen); + int convertFieldChars(enum_conversionDirection direction, + uint16 fieldID, + const char* input, + char* output, + size_t ilen, + size_t olen, + size_t* outDataLen, + bool tacitErrors=FALSE, + size_t* substChars=NULL); /** Fast integer log2 function From 6cc65b7e6993ed52c22a3f4631fa1b12daced37b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 12:01:56 +0300 Subject: [PATCH 153/188] Bug#38315 and Bug#35148: disabled sporadically failing NDB tests --- mysql-test/t/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index da7b4f70a46..79afeb102d4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -18,3 +18,5 @@ im_options_unset : Bug#20294: Instance manager tests fail randomly im_utils : Bug#20294: Instance manager tests fail randomly rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes kill : Bug#29149 Test "kill" fails on Windows +ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb +strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" From b74f6cda43720d746fc504ddf429677dd86e45c1 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 13:15:40 +0300 Subject: [PATCH 154/188] Bug #38499 : test marked as a big test : takes approx 275 secs on a P4 2.4 GHz. --- mysql-test/t/lock_multi_bug38499.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/lock_multi_bug38499.test b/mysql-test/t/lock_multi_bug38499.test index 8178987e802..def58187ced 100644 --- a/mysql-test/t/lock_multi_bug38499.test +++ b/mysql-test/t/lock_multi_bug38499.test @@ -1,6 +1,7 @@ # Bug38499 flush tables and multitable table update with derived table cause crash # MySQL >= 5.0 # +--source include/big_test.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc From fd709c840851400146fea09434e3adf2e4d80610 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 13:20:41 +0300 Subject: [PATCH 155/188] Bug #45521: disabled the test case --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 79afeb102d4..1023375d89f 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -20,3 +20,4 @@ rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes kill : Bug#29149 Test "kill" fails on Windows ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" +rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 From 07e69e29eaa05534a16db0678eb07a02b77fe840 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 13:23:35 +0300 Subject: [PATCH 156/188] Bug #35148: disabled testcase loaddata_autocom_ndb --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 1023375d89f..ba019c21115 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -21,3 +21,4 @@ kill : Bug#29149 Test "kill" fails on Windows ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 +loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms From 2a17098a60ffefb22113c338af0db3b3cd1db0bc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 13:27:19 +0300 Subject: [PATCH 157/188] Bug #35148: ndb_autodiscover3 disabled --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ba019c21115..ac01ad29415 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -22,3 +22,4 @@ ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms +ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms From 9d94015b342c4e59560e5f55bf611deed438c228 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 17:44:25 +0300 Subject: [PATCH 158/188] Bug#45972: disable the test case in 5.0 --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ac01ad29415..bbf11f2f8f8 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -23,3 +23,4 @@ strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms +ndb_autodiscover : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 From ba83235f42c3be415461ccfce8458e058d9a8e21 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 18:17:39 +0300 Subject: [PATCH 159/188] Bug #45974: disable test case in 5.1-bugteam --- mysql-test/suite/rpl_ndb/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index 6908269d014..2f15112515e 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -11,3 +11,4 @@ ############################################################################## # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open +rpl_ndb_2ndb : Bug#45974: rpl_ndb_2ndb fails sporadically From e92c6815328a9d7c70348d3107b539958bb0ae8c Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jul 2009 20:00:43 +0300 Subject: [PATCH 160/188] disable ndb_autodiscover2 : dependent on the disabled ndb_autodiscover --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index bbf11f2f8f8..062667c249e 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,3 +24,4 @@ rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 +ndb_autodiscover2 : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 From 869e6bd19f41d6a2773111e75249cff9d9e8fca5 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Mon, 6 Jul 2009 18:20:17 -0400 Subject: [PATCH 161/188] Bug#44920: MTR2 is not processing master.opt input properly on Windows. Had attempted to disable this test on Windows only, but the nature of this bug does not allow for this. The master.opt file is processed before anything in in the actual test. As a result, we must use disabled.def files to ensure these tests are skipped on the problematic platforms. Removed Windows-only code and updated the proper disabled.def files accordingly. --- mysql-test/suite/rpl/t/disabled.def | 2 ++ mysql-test/suite/rpl/t/rpl_init_slave.test | 6 ------ mysql-test/t/disabled.def | 2 ++ mysql-test/t/init_connect.test | 5 ----- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 38fc9e21322..af8eef764ed 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,3 +11,5 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx +rpl_init_slave : Bug#44920 2009-07006 pcrews MTR2 is not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug* + diff --git a/mysql-test/suite/rpl/t/rpl_init_slave.test b/mysql-test/suite/rpl/t/rpl_init_slave.test index dd58b973fca..58d1f6bdc01 100644 --- a/mysql-test/suite/rpl/t/rpl_init_slave.test +++ b/mysql-test/suite/rpl/t/rpl_init_slave.test @@ -1,9 +1,3 @@ -if(`SELECT CONVERT(@@version_compile_os using latin1) IN ("Win32", "Win64", "Windows")`) -{ ---skip Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows -} - - source include/master-slave.inc; # diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 6d8f0af0c28..5436b7166f4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,3 +12,5 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically +init_connect : Bug#44920 2009-07-06 pcrews MTR not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug* + diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index 1e93d0d671f..b6bac5f65fa 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -2,11 +2,6 @@ # Test of init_connect variable # -if(`SELECT CONVERT(@@version_compile_os using latin1) IN ("Win32", "Win64", "Windows")`) -{ ---skip Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows -} - # should work with embedded server after mysqltest is fixed --source include/not_embedded.inc From 2a9da3fac5e4bd62d6f62edf04fc5bab9d29e43f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 10:49:38 +0300 Subject: [PATCH 162/188] tree name change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 006d97dc972bead95351dba20a1027d235d1b05f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Jul 2009 11:47:23 +0200 Subject: [PATCH 163/188] Raise version number after cloning 5.0.84 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index ec432e19ce3..ddebde47d12 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.84) +AM_INIT_AUTOMAKE(mysql, 5.0.85) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=84 +NDB_VERSION_BUILD=85 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 2e8eb6ce94c75518d0c76bd7c428e17455aaf97b Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Wed, 8 Jul 2009 14:40:01 +0530 Subject: [PATCH 164/188] Bug#45983 ibmdb2i_create_index_option=1 not working for primary key With ibmdb2i_create_index_option set to 1, creating an IBMDB2I table with a primary key should produce an additional index that uses EBCDIC hexadecimal sorting. However, this does not work. Adding indexes that are not primary keys does work. The ibmdb2i_create_index_option should be honoured when creating a table with a primary key. This patch adds code to the create() function to check for the value of the ibmdb2i_create_index_option variable and, when appropriate, to generate a *HEX-based shadow index in DB2 for the primary key. Previously this behavior was limited to secondary indexes. Additionally, this patch restricts the creation of shadow indexes to cases in which a non-*HEX sort sequence is used, as the documentation for ibmdb2i_create_index_option describes. Previously, the shadow index would in some cases be created even when the MySQL-specific index used *HEX sorting, leading to redundant indexes. Finally, the code used to generate the list of fields for indexes and the code used to generate the SQL statement for the shadow indexes has been refactored into individual functions. mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result: Bug#45983 ibmdb2i_create_index_option=1 not working for primary key Result file for the test case. mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test: Bug#45983 ibmdb2i_create_index_option=1 not working for primary key Add tests to verify that the ibmdb2i_create_index_option is being honoured when creating a table with a primary key. storage/ibmdb2i/ha_ibmdb2i.cc: Bug#45983 ibmdb2i_create_index_option=1 not working for primary key - Add code to the create() function to check for the value of the ibmdb2i_create_index_option variable and, when appropriate, to generate a *HEX-based shadow index in DB2 for the primary key. - Restrict the creation of shadow indexes to cases in which a non-*HEX sort sequence is used. - Refractor code used to generate the list of fields for indexes and the code used to generate the SQL statement for the shadow indexes into individual functions. storage/ibmdb2i/ha_ibmdb2i.h: Bug#45983 ibmdb2i_create_index_option=1 not working for primary key Add function prototypes for the functions that. - Generate the list of fields for indexes - Generate the SQL statement for the shadow indexes --- .../suite/ibmdb2i/r/ibmdb2i_bug_45983.result | 20 ++ .../suite/ibmdb2i/t/ibmdb2i_bug_45983.test | 47 +++++ storage/ibmdb2i/ha_ibmdb2i.cc | 197 ++++++++++++------ storage/ibmdb2i/ha_ibmdb2i.h | 13 ++ 4 files changed, 210 insertions(+), 67 deletions(-) create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result new file mode 100644 index 00000000000..b9f4dcfc656 --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_45983.result @@ -0,0 +1,20 @@ +set ibmdb2i_create_index_option=1; +drop schema if exists test1; +create schema test1; +use test1; +CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i; +drop table t1; +CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i; +drop table t1; +create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; +select * from fd; +SQSSEQ +*HEX +*HEX +*HEX +*HEX +drop table fd; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test new file mode 100644 index 00000000000..695d8e90ada --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_45983.test @@ -0,0 +1,47 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; + +# Confirm that ibmdb2i_create_index_option causes additional *HEX sorted indexes to be created for all non-binary keys. + +set ibmdb2i_create_index_option=1; +--disable_warnings +drop schema if exists test1; +create schema test1; +use test1; +--enable_warnings + +--disable_abort_on_error +--error 0,255 +exec system "DLTF QGPL/FDOUT" > /dev/null; +--enable_abort_on_error + +#No additional index because no string fields in key +CREATE TABLE t1 (f int primary key, index(f)) engine=ibmdb2i; +--error 255 +exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +--error 255 +exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +drop table t1; + +#No additional index because binary sorting +CREATE TABLE t1 (f char(10) collate utf8_bin primary key, index(f)) engine=ibmdb2i; +--error 255 +exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +--error 255 +exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +drop table t1; + +CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, index(f)) engine=ibmdb2i; +exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +exec system "DSPFD FILE(\"test1\"/\"f___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +drop table t1; + +CREATE TABLE t1 (f char(10) collate latin1_swedish_ci primary key, i int, index i(i,f)) engine=ibmdb2i; +exec system "DSPFD FILE(\"test1\"/PRIM0001) TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +exec system "DSPFD FILE(\"test1\"/\"i___H_t1\") TYPE(*SEQ) OUTPUT(*OUTFILE) OUTFILE(QGPL/FDOUT) OUTMBR(*FIRST *ADD)" > /dev/null; +drop table t1; + + +create table fd (SQSSEQ CHAR(10)) engine=ibmdb2i; +system system "CPYF FROMFILE(QGPL/FDOUT) TOFILE(\"test1\"/\"fd\") mbropt(*replace) fmtopt(*drop *map)" > /dev/null; +select * from fd; +drop table fd; diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 5cf9568be67..0fc2d1e83dc 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -2230,34 +2230,19 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg, } } - bool primaryHasStringField = false; - + String fieldDefinition(128); + if (table_arg->s->primary_key != MAX_KEY && !isTemporary) { - KEY& curKey = table_arg->key_info[table_arg->s->primary_key]; - query.append(STRING_WITH_LEN(", PRIMARY KEY( ")); - for (int j = 0; j < curKey.key_parts; ++j) - { - if (j != 0) - { - query.append( STRING_WITH_LEN(" , ") ); - } - Field* field = curKey.key_part[j].field; - convertMySQLNameToDB2Name(field->field_name, colName, sizeof(colName)); - query.append(colName); - enum_field_types type = field->real_type(); - if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_BLOB || - type == MYSQL_TYPE_STRING) - { - rc = updateAssociatedSortSequence(field->charset(), - &fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - if (rc) DBUG_RETURN (rc); - primaryHasStringField = true; - } - } - query.append(STRING_WITH_LEN(" ) ")); + query.append(STRING_WITH_LEN(", PRIMARY KEY ")); + rc = buildIndexFieldList(fieldDefinition, + table_arg->key_info[table_arg->s->primary_key], + true, + &fileSortSequenceType, + fileSortSequence, + fileSortSequenceLibrary); + if (rc) DBUG_RETURN(rc); + query.append(fieldDefinition); } rc = buildDB2ConstraintString(thd->lex, @@ -2283,6 +2268,19 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg, SqlStatementStream sqlStream(query.length()); sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary); + if (table_arg->s->primary_key != MAX_KEY && + !isTemporary && + (THDVAR(thd, create_index_option)==1) && + (fileSortSequenceType != 'B') && + (fileSortSequenceType != ' ')) + { + rc = generateShadowIndex(sqlStream, + table_arg->key_info[table_arg->s->primary_key], + libName, + fileName, + fieldDefinition); + if (rc) DBUG_RETURN(rc); + } for (uint i = 0; i < table_arg->s->keys; ++i) { if (i != table_arg->s->primary_key || isTemporary) @@ -3012,52 +3010,27 @@ int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream, } String fieldDefinition(128); - fieldDefinition.length(0); - fieldDefinition.append(STRING_WITH_LEN(" ( ")); - for (int j = 0; j < key.key_parts; ++j) - { - char colName[MAX_DB2_COLNAME_LENGTH+1]; - if (j != 0) - { - fieldDefinition.append(STRING_WITH_LEN(" , ")); - } - Field* field = key.key_part[j].field; - convertMySQLNameToDB2Name(field->field_name, colName, sizeof(colName)); - fieldDefinition.append(colName); - rc = updateAssociatedSortSequence(field->charset(), - &fileSortSequenceType, - fileSortSequence, - fileSortSequenceLibrary); - if (rc) DBUG_RETURN (rc); - } - fieldDefinition.append(STRING_WITH_LEN(" ) ")); + rc = buildIndexFieldList(fieldDefinition, + key, + isPrimary, + &fileSortSequenceType, + fileSortSequence, + fileSortSequenceLibrary); + if (rc) DBUG_RETURN(rc); + query.append(fieldDefinition); if ((THDVAR(ha_thd(), create_index_option)==1) && - (fileSortSequenceType != 'B')) + (fileSortSequenceType != 'B') && + (fileSortSequenceType != ' ')) { - String shadowQuery(256); - shadowQuery.length(0); - - shadowQuery.append(STRING_WITH_LEN("CREATE INDEX ")); - - shadowQuery.append(db2LibName); - shadowQuery.append('.'); - if (db2i_table::appendQualifiedIndexFileName(key.name, db2FileName, shadowQuery, db2i_table::ASCII_SQL, typeHex)) - { - getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); - DBUG_RETURN(DB2I_ERR_INVALID_NAME ); - } - - shadowQuery.append(STRING_WITH_LEN(" ON ")); - - shadowQuery.append(db2LibName); - shadowQuery.append('.'); - shadowQuery.append(db2FileName); - shadowQuery.append(fieldDefinition); - DBUG_PRINT("ha_ibmdb2i::buildCreateIndexStatement", ("Sent to DB2: %s",shadowQuery.c_ptr_safe())); - sqlStream.addStatement(shadowQuery,"*HEX","QSYS"); + rc = generateShadowIndex(sqlStream, + key, + db2LibName, + db2FileName, + fieldDefinition); + if (rc) DBUG_RETURN(rc); } DBUG_PRINT("ha_ibmdb2i::buildCreateIndexStatement", ("Sent to DB2: %s",query.c_ptr_safe())); @@ -3066,7 +3039,97 @@ int32 ha_ibmdb2i::buildCreateIndexStatement(SqlStatementStream& sqlStream, DBUG_RETURN(0); } +/** + Generate the SQL syntax for the list of fields to be assigned to the + specified key. The corresponding sort sequence is also calculated. + + @param[out] appendHere The string to receive the generated SQL + @param key The key to evaluate + @param isPrimary True if this is being generated on behalf of the primary key + @param[out] fileSortSequenceType The type of the associated sort sequence + @param[out] fileSortSequence The name of the associated sort sequence + @param[out] fileSortSequenceLibrary The library of the associated sort sequence + + @return 0 if successful; error value otherwise +*/ +int32 ha_ibmdb2i::buildIndexFieldList(String& appendHere, + const KEY& key, + bool isPrimary, + char* fileSortSequenceType, + char* fileSortSequence, + char* fileSortSequenceLibrary) +{ + DBUG_ENTER("ha_ibmdb2i::buildIndexFieldList"); + appendHere.append(STRING_WITH_LEN(" ( ")); + for (int j = 0; j < key.key_parts; ++j) + { + char colName[MAX_DB2_COLNAME_LENGTH+1]; + if (j != 0) + { + appendHere.append(STRING_WITH_LEN(" , ")); + } + + KEY_PART_INFO& kpi = key.key_part[j]; + Field* field = kpi.field; + + convertMySQLNameToDB2Name(field->field_name, + colName, + sizeof(colName)); + appendHere.append(colName); + + int32 rc; + rc = updateAssociatedSortSequence(field->charset(), + fileSortSequenceType, + fileSortSequence, + fileSortSequenceLibrary); + if (rc) DBUG_RETURN (rc); + } + + appendHere.append(STRING_WITH_LEN(" ) ")); + + DBUG_RETURN(0); +} + +/** + Generate an SQL statement that defines a *HEX sorted index to implement + the ibmdb2i_create_index. + + @param[out] stream The stream to append the generated statement to + @param key The key to evaluate + @param[out] libName The library containg the table + @param[out] fileName The DB2-compatible name of the table + @param[out] fieldDefinition The list of the fields in the index, in SQL syntax + + @return 0 if successful; error value otherwise +*/ +int32 ha_ibmdb2i::generateShadowIndex(SqlStatementStream& stream, + const KEY& key, + const char* libName, + const char* fileName, + const String& fieldDefinition) +{ + String shadowQuery(256); + shadowQuery.length(0); + shadowQuery.append(STRING_WITH_LEN("CREATE INDEX ")); + shadowQuery.append(libName); + shadowQuery.append('.'); + if (db2i_table::appendQualifiedIndexFileName(key.name, fileName, shadowQuery, db2i_table::ASCII_SQL, typeHex)) + { + getErrTxt(DB2I_ERR_INVALID_NAME,"index","*generated*"); + return DB2I_ERR_INVALID_NAME; + } + shadowQuery.append(STRING_WITH_LEN(" ON ")); + shadowQuery.append(libName); + shadowQuery.append('.'); + shadowQuery.append(fileName); + shadowQuery.append(fieldDefinition); + DBUG_PRINT("ha_ibmdb2i::generateShadowIndex", ("Sent to DB2: %s",shadowQuery.c_ptr_safe())); + stream.addStatement(shadowQuery,"*HEX","QSYS"); + return 0; +} + + void ha_ibmdb2i::doInitialRead(char orientation, uint32 rowsToBuffer, ILEMemHandle key, diff --git a/storage/ibmdb2i/ha_ibmdb2i.h b/storage/ibmdb2i/ha_ibmdb2i.h index 006b6b163b8..b2a43232f2d 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.h +++ b/storage/ibmdb2i/ha_ibmdb2i.h @@ -530,6 +530,13 @@ private: bool isPrimary, const char* db2LibName, const char* db2FileName); + + int32 buildIndexFieldList(String& appendHere, + const KEY& key, + bool isPrimary, + char* fileSortSequenceType, + char* fileSortSequence, + char* fileSortSequenceLibrary); // Specify NULL for data when using the data pointed to by field int32 convertMySQLtoDB2(Field* field, const DB2Field& db2Field, char* db2Buf, const uchar* data = NULL); @@ -806,4 +813,10 @@ private: query.append(STRING_WITH_LEN(" RCDFMT ")); query.append(rcdfmt); } + + int32 generateShadowIndex(SqlStatementStream& stream, + const KEY& key, + const char* libName, + const char* fileName, + const String& fieldDefinition); }; From 02e70f1691bdbd9001e4d17b69606624f1f1fa39 Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 8 Jul 2009 17:41:34 +0530 Subject: [PATCH 165/188] Bug#35111 - Truncate a MyISAM partitioned table does not reset the auto_increment value This is an alternative patch that instead of allowing RECREATE TABLE on TRUNCATE TABLE it implements reset_auto_increment that is called after delete_all_rows. Note: this bug was fixed by Mattias Jonsson: Pusing this patch: http://lists.mysql.com/commits/70370 mysql-test/suite/parts/r/partition_auto_increment_memory.result: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value mysql-test/suite/parts/r/partition_auto_increment_myisam.result: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value sql/ha_partition.cc: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value Added reset_auto_increment, to be used after delete_all_rows to simulate truncate. storage/heap/ha_heap.cc: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value Added reset_auto_increment, to be used after delete_all_rows to simulate truncate storage/heap/ha_heap.h: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value Added reset_auto_increment, to be used after delete_all_rows to simulate truncate storage/myisam/ha_myisam.cc: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value Added reset_auto_increment, to be used after delete_all_rows to simulate truncate. storage/myisam/ha_myisam.h: Bug#35111: Truncate a MyISAM partitioned table does not reset the auto_increment value Added reset_auto_increment, to be used after delete_all_rows to simulate truncate. --- .../suite/parts/r/partition_auto_increment_memory.result | 4 ++-- .../suite/parts/r/partition_auto_increment_myisam.result | 4 ++-- sql/ha_partition.cc | 5 +++++ storage/heap/ha_heap.cc | 8 ++++++++ storage/heap/ha_heap.h | 1 + storage/myisam/ha_myisam.cc | 6 ++++++ storage/myisam/ha_myisam.h | 1 + 7 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result index 77bab79f020..f4d783825f4 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result @@ -381,12 +381,12 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MEMORY AUTO_INCREMENT=28 DEFAULT CHARSET=latin1 +) ENGINE=MEMORY AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; c1 -27 +1 INSERT INTO t1 VALUES (100); INSERT INTO t1 VALUES (NULL); DELETE FROM t1 WHERE c1 >= 100; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result index b5b001ec17a..6abf08b68a0 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result @@ -381,12 +381,12 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`c1`) -) ENGINE=MyISAM AUTO_INCREMENT=28 DEFAULT CHARSET=latin1 +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (c1) PARTITIONS 2 */ SELECT * FROM t1 ORDER BY c1; c1 -27 +1 INSERT INTO t1 VALUES (100); INSERT INTO t1 VALUES (NULL); DELETE FROM t1 WHERE c1 >= 100; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 67bc3156260..74742f58028 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3179,6 +3179,7 @@ int ha_partition::delete_row(const uchar *buf) int ha_partition::delete_all_rows() { int error; + bool truncate= FALSE; handler **file; THD *thd= ha_thd(); DBUG_ENTER("ha_partition::delete_all_rows"); @@ -3190,12 +3191,16 @@ int ha_partition::delete_all_rows() ha_data->next_auto_inc_val= 0; ha_data->auto_inc_initialized= FALSE; unlock_auto_increment(); + truncate= TRUE; } file= m_file; do { if ((error= (*file)->ha_delete_all_rows())) DBUG_RETURN(error); + /* Ignore the error */ + if (truncate) + (void) (*file)->ha_reset_auto_increment(0); } while (*(++file)); DBUG_RETURN(0); } diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 19863d83874..fb7c13e4e41 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -419,6 +419,14 @@ int ha_heap::delete_all_rows() return 0; } + +int ha_heap::reset_auto_increment(ulonglong value) +{ + file->s->auto_increment= value; + return 0; +} + + int ha_heap::external_lock(THD *thd, int lock_type) { return 0; // No external locking diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 5c5ad43658e..22722129f4c 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -98,6 +98,7 @@ public: int reset(); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); + int reset_auto_increment(ulonglong value); int disable_indexes(uint mode); int enable_indexes(uint mode); int indexes_are_disabled(void); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index efdd9c35b0a..d0e5f5a5c88 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1870,6 +1870,12 @@ int ha_myisam::delete_all_rows() return mi_delete_all_rows(file); } +int ha_myisam::reset_auto_increment(ulonglong value) +{ + file->s->state.auto_increment= value; + return 0; +} + int ha_myisam::delete_table(const char *name) { return mi_delete_table(name); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index ca44ae9ad87..55a5eac92de 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -101,6 +101,7 @@ class ha_myisam: public handler int reset(void); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); + int reset_auto_increment(ulonglong value); int disable_indexes(uint mode); int enable_indexes(uint mode); int indexes_are_disabled(void); From a56ab623ba1004ba073b9a494236ed12b018fe78 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 8 Jul 2009 09:31:22 -0300 Subject: [PATCH 166/188] Fix warnings generated by SunStudio and GCC. Based upon patch contributed by Stewart Smith mysql-test/lib/My/SafeProcess/safe_process.cc: Fix style -- remove unneeded spaces. Specify C linkage for the signal handling functions. Check return value from read()/write(). --- mysql-test/lib/My/SafeProcess/safe_process.cc | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index dc7b7da28c7..50c433b9b39 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -89,7 +89,7 @@ static void die(const char* fmt, ...) } -static void kill_child (void) +static void kill_child(void) { int status= 0; @@ -119,7 +119,7 @@ static void kill_child (void) } -static void handle_abort (int sig) +extern "C" void handle_abort(int sig) { message("Got signal %d, child_pid: %d, sending ABRT", sig, child_pid); @@ -128,8 +128,8 @@ static void handle_abort (int sig) } } - -static void handle_signal (int sig) + +extern "C" void handle_signal(int sig) { message("Got signal %d, child_pid: %d", sig, child_pid); terminated= 1; @@ -152,7 +152,7 @@ int main(int argc, char* const argv[] ) pid_t own_pid= getpid(); pid_t parent_pid= getppid(); bool nocore = false; - + /* Install signal handlers */ signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); @@ -232,10 +232,11 @@ int main(int argc, char* const argv[] ) message("setrlimit failed, errno=%d", errno); } } - + // Signal that child is ready buf= 37; - write(pfd[1], &buf, 1); + if ((write(pfd[1], &buf, 1)) < 1) + die("Failed to signal that child is ready"); // Close write end close(pfd[1]); @@ -246,8 +247,10 @@ int main(int argc, char* const argv[] ) close(pfd[1]); // Close unused write end // Wait for child to signal it's ready - read(pfd[0], &buf, 1); - if(buf != 37) + if ((read(pfd[0], &buf, 1)) < 1) + die("Failed to read signal from child"); + + if (buf != 37) die("Didn't get 37 from pipe"); close(pfd[0]); // Close read end @@ -272,7 +275,7 @@ int main(int argc, char* const argv[] ) if (WIFEXITED(status)) { // Process has exited, collect return status - int ret_code= WEXITSTATUS(status); + ret_code= WEXITSTATUS(status); message("Child exit: %d", ret_code); // Exit with exit status of the child exit(ret_code); @@ -287,6 +290,6 @@ int main(int argc, char* const argv[] ) } kill_child(); - exit(1); + return 1; } From 22717a04598853b6a2327679b17d5e3557faa52a Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 9 Jul 2009 10:28:38 +0300 Subject: [PATCH 167/188] Bug #44115 purge_relay_logs doesn't return an error when count_relay_log_space fails purge_relay_logs() did not propagate an error happend in count_relay_log_space(). Fixed with the suggestesd setting the error= true. Note, propagation generally out of purge_relay_logs() was fixed for Bug #44179, and the issue does not exist in 6.0 thanks to a patch for WL#2775. sql/rpl_rli.cc: the error is set on if count_relay_log_space(rli) fails. --- sql/rpl_rli.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 45c0efb10c2..18fbae9bb9d 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -947,6 +947,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, if (count_relay_log_space(rli)) { *errmsg= "Error counting relay log space"; + error=1; goto err; } if (!just_reset) From 33380cf0b780cfa2e7f2b2aac7e2ccaa56156cfa Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 15:52:34 +0300 Subject: [PATCH 168/188] Bug #36259 (Optimizing with ORDER BY) and bug#45828 (Optimizer won't use partial primary key if another index can prevent filesort The fix for bug #28404 causes the covering ordering indexes to be preferred unconditionally over non-covering and ref indexes. Fixed by comparing the cost of using a covering index to the cost of using a ref index even for covering ordering indexes. Added an assertion to clarify the condition the local variables should be in. mysql-test/include/mix1.inc: Bug #36259: fixed a non-stable test case mysql-test/r/innodb_mysql.result: Bug #36259 and #45828 : test case mysql-test/t/innodb_mysql.test: Bug #36259 and #45828 : test case sql/sql_select.cc: Bug #36259 and #45828 : don't consider covering indexes supperior to ref keys. --- mysql-test/include/mix1.inc | 4 +- mysql-test/r/innodb_mysql.result | 77 ++++++++++++++++++++++++++++-- mysql-test/t/innodb_mysql.test | 81 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 10 +++- 4 files changed, 166 insertions(+), 6 deletions(-) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 3f7b44bd9ef..19a327d079e 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1498,9 +1498,9 @@ INSERT INTO t1 VALUES (4,1,3,'pk',NULL),(5,1,3,'c2',NULL), (2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); -EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; -SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; DROP TABLE t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 272782f6647..3ff5f04b6c6 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1701,10 +1701,10 @@ INSERT INTO t1 VALUES (4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL), (4,1,3,'pk',NULL),(5,1,3,'c2',NULL), (2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); -EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index vid PRIMARY 12 NULL 16 Using where -SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +1 SIMPLE t1 index NULL PRIMARY 12 NULL 16 Using where +SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; vid tid idx name type 3 1 4 c_extra NULL 3 1 3 c2 NULL @@ -2137,4 +2137,75 @@ GROUP BY t1.b; a b c d a b e a b 1 1 1 0 1 1 2 1 1 DROP TABLE t1, t2, t3; +# +# Bug #45828: Optimizer won't use partial primary key if another +# index can prevent filesort +# +CREATE TABLE `t1` ( +c1 int NOT NULL, +c2 int NOT NULL, +c3 int NOT NULL, +PRIMARY KEY (c1,c2), +KEY (c3) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (5,2,1246276747); +INSERT INTO t1 VALUES (2,1,1246281721); +INSERT INTO t1 VALUES (7,3,1246281756); +INSERT INTO t1 VALUES (4,2,1246282139); +INSERT INTO t1 VALUES (3,1,1246282230); +INSERT INTO t1 VALUES (1,0,1246282712); +INSERT INTO t1 VALUES (8,3,1246282765); +INSERT INTO t1 SELECT c1+10,c2+10,c3+10 FROM t1; +INSERT INTO t1 SELECT c1+100,c2+100,c3+100 from t1; +INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1; +INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; +INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; +INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; +SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +c1 c2 c3 +EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,c3 PRIMARY 4 const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY PRIMARY 4 const 1 Using where; Using filesort +CREATE TABLE t2 ( +c1 int NOT NULL, +c2 int NOT NULL, +c3 int NOT NULL, +KEY (c1,c2), +KEY (c3) +) ENGINE=InnoDB; +explain SELECT * FROM t2 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c1,c3 c1 4 const 1 Using where; Using filesort +DROP TABLE t1,t2; +# +# 36259: Optimizing with ORDER BY +# +CREATE TABLE t1 ( +a INT NOT NULL AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL, +d VARCHAR(5), +e INT NOT NULL, +PRIMARY KEY (a), KEY i2 (b,c,d) +) ENGINE=InnoDB; +INSERT INTO t1 (b,c,d,e) VALUES (1,1,'a',1), (2,2,'b',2); +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=1 AND c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i2 i2 8 const,const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX(i2) WHERE b=1 and c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i2 i2 8 const,const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 128 Using where +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 3e1968b8007..c643465b2f3 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -380,4 +380,85 @@ SELECT * FROM t1, t2, t3 DROP TABLE t1, t2, t3; +--echo # +--echo # Bug #45828: Optimizer won't use partial primary key if another +--echo # index can prevent filesort +--echo # + +# Create the table +CREATE TABLE `t1` ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 int NOT NULL, + PRIMARY KEY (c1,c2), + KEY (c3) +) ENGINE=InnoDB; + +# populate with data +INSERT INTO t1 VALUES (5,2,1246276747); +INSERT INTO t1 VALUES (2,1,1246281721); +INSERT INTO t1 VALUES (7,3,1246281756); +INSERT INTO t1 VALUES (4,2,1246282139); +INSERT INTO t1 VALUES (3,1,1246282230); +INSERT INTO t1 VALUES (1,0,1246282712); +INSERT INTO t1 VALUES (8,3,1246282765); +INSERT INTO t1 SELECT c1+10,c2+10,c3+10 FROM t1; +INSERT INTO t1 SELECT c1+100,c2+100,c3+100 from t1; +INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1; +INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; +INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; +INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; + +# query and no rows will match the c1 condition, whereas all will match c3 +SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +# SHOULD use the pk. +# index on c3 will be used instead of primary key +EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +# if we force the primary key, we can see the estimate is 1 +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + + +CREATE TABLE t2 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 int NOT NULL, + KEY (c1,c2), + KEY (c3) +) ENGINE=InnoDB; + +# SHOULD use the pk. +# if we switch it from a primary key to a regular index, it works correctly as well +explain SELECT * FROM t2 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +DROP TABLE t1,t2; + + +--echo # +--echo # 36259: Optimizing with ORDER BY +--echo # + +CREATE TABLE t1 ( + a INT NOT NULL AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL, + d VARCHAR(5), + e INT NOT NULL, + PRIMARY KEY (a), KEY i2 (b,c,d) +) ENGINE=InnoDB; + +INSERT INTO t1 (b,c,d,e) VALUES (1,1,'a',1), (2,2,'b',2); +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=1 AND c=1 ORDER BY a; +EXPLAIN SELECT * FROM t1 FORCE INDEX(i2) WHERE b=1 and c=1 ORDER BY a; +EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 37721660184..401745bd9b8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13132,9 +13132,17 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, for (nr=0; nr < table->s->keys ; nr++) { int direction; + if (keys.is_set(nr) && (direction= test_if_order_by_key(order, table, nr, &used_key_parts))) { + /* + At this point we are sure that ref_key is a non-ordering + key (where "ordering key" is a key that will return rows + in the order required by ORDER BY). + */ + DBUG_ASSERT (ref_key != (int) nr); + bool is_covering= table->covering_keys.is_set(nr) || (nr == table->s->primary_key && table->file->primary_key_is_clustered()); @@ -13215,7 +13223,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ index_scan_time= select_limit/rec_per_key * min(rec_per_key, table->file->scan_time()); - if (is_covering || + if ((ref_key < 0 && is_covering) || (ref_key < 0 && (group || table->force_index)) || index_scan_time < read_time) { From 2275faa00e62e752d70221fcc6cc5c16bcd04d3a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 16:09:06 +0300 Subject: [PATCH 169/188] fixed a failing test ctype_gbk_binlog : Table 't2' already exists --- mysql-test/r/ctype_gbk_binlog.result | 1 + mysql-test/t/ctype_gbk_binlog.test | 3 +++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/r/ctype_gbk_binlog.result b/mysql-test/r/ctype_gbk_binlog.result index a49e170ff19..39cf21d5a63 100644 --- a/mysql-test/r/ctype_gbk_binlog.result +++ b/mysql-test/r/ctype_gbk_binlog.result @@ -14,6 +14,7 @@ SET @`tcontent`:=_binary 0x50434B000900000000000000E9000000 COLLATE `binary`/*!* CALL p1(@`tcontent`); FLUSH LOGS; DROP PROCEDURE p1; +DROP TABLE IF EXISTS t2; RENAME TABLE t1 to t2; SELECT hex(f1) FROM t2; hex(f1) diff --git a/mysql-test/t/ctype_gbk_binlog.test b/mysql-test/t/ctype_gbk_binlog.test index a8f653d1b1e..114c1c8385f 100644 --- a/mysql-test/t/ctype_gbk_binlog.test +++ b/mysql-test/t/ctype_gbk_binlog.test @@ -24,6 +24,9 @@ CALL p1(@`tcontent`); FLUSH LOGS; DROP PROCEDURE p1; +--disable_warnings +DROP TABLE IF EXISTS t2; +--enable_warnings RENAME TABLE t1 to t2; let $MYSQLD_DATADIR= `select @@datadir`; From abfe915ac986c3fe152429719a13f1235d9ed9a6 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 16:11:46 +0300 Subject: [PATCH 170/188] fixed compilation warnings on macosx --- client/mysqldump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index d755a17b815..6b2c2a06834 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4110,7 +4110,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table(hash_key,end - hash_key)) + if (include_table((uchar*) hash_key,end - hash_key)) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -4131,7 +4131,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table(hash_key, end - hash_key)) + if (include_table((uchar*) hash_key, end - hash_key)) get_view_structure(table, database); } if (opt_xml) From 6a2f91bff4a656be55b9001e7ef8dc2d0217cb5f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 17:15:53 +0300 Subject: [PATCH 171/188] merge of making bug 45578, 46010 and 45576 experimental in pb2. --- mysql-test/collections/default.experimental | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 103069f79cf..6b42ee9c1c7 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -1 +1,4 @@ funcs_1.charset_collation_1 # depends on compile-time decisions +binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2' +main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists +rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2 From d03714da6b251cca565746bb5336078c4238d715 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 17:18:44 +0300 Subject: [PATCH 172/188] revert of hiding of the error exposed by this suite. --- mysql-test/r/ctype_gbk_binlog.result | 1 - mysql-test/t/ctype_gbk_binlog.test | 3 --- 2 files changed, 4 deletions(-) diff --git a/mysql-test/r/ctype_gbk_binlog.result b/mysql-test/r/ctype_gbk_binlog.result index 39cf21d5a63..a49e170ff19 100644 --- a/mysql-test/r/ctype_gbk_binlog.result +++ b/mysql-test/r/ctype_gbk_binlog.result @@ -14,7 +14,6 @@ SET @`tcontent`:=_binary 0x50434B000900000000000000E9000000 COLLATE `binary`/*!* CALL p1(@`tcontent`); FLUSH LOGS; DROP PROCEDURE p1; -DROP TABLE IF EXISTS t2; RENAME TABLE t1 to t2; SELECT hex(f1) FROM t2; hex(f1) diff --git a/mysql-test/t/ctype_gbk_binlog.test b/mysql-test/t/ctype_gbk_binlog.test index 114c1c8385f..a8f653d1b1e 100644 --- a/mysql-test/t/ctype_gbk_binlog.test +++ b/mysql-test/t/ctype_gbk_binlog.test @@ -24,9 +24,6 @@ CALL p1(@`tcontent`); FLUSH LOGS; DROP PROCEDURE p1; ---disable_warnings -DROP TABLE IF EXISTS t2; ---enable_warnings RENAME TABLE t1 to t2; let $MYSQLD_DATADIR= `select @@datadir`; From 61425acb3d1c662b38c9d08ff5cf7147590bf52d Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Tue, 7 Jul 2009 10:19:38 -0400 Subject: [PATCH 173/188] Bug#37746: Arithmetic range ("int") is smaller than expected Added code to the .test file to skip this test on Win64 for PB2 stability. Please remove this code when the bug is fixed. --- mysql-test/suite/funcs_1/t/storedproc.test | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test index 67fc33269a3..16c4d61bf58 100644 --- a/mysql-test/suite/funcs_1/t/storedproc.test +++ b/mysql-test/suite/funcs_1/t/storedproc.test @@ -10,6 +10,17 @@ # ############################################################################ +# Bug#37746 - Arithmetic range ("int") is smaller than expected +# This code is in place to ensure this test is only skipped +# for the Win64 platform +if(`SELECT CONVERT(@@version_compile_os using latin1) IN ("Win64")`) +{ +--skip Bug#37746 2009-07-07 pcrews Arithmetic range ("int") is smaller than expected +} + + + + # This test cannot be used for the embedded server because we check here # privileges. --source include/not_embedded.inc From c8c22c7a981110cb678308199136d8c3760789ec Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 7 Jul 2009 17:41:34 +0300 Subject: [PATCH 174/188] Bug #40796 : adding the tests to the experimental pb2 set. --- mysql-test/collections/default.experimental | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 6b42ee9c1c7..01e5ecd9da0 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -2,3 +2,8 @@ funcs_1.charset_collation_1 # depends on compile-time decisions binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2' main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2 +rpl.rpl_extraColmaster_myisam # Bug#46013: rpl_extraColmaster_myisam fails on pb2 +rpl.rpl_stm_reset_slave # Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2 +rpl_extraCol_myisam # Bug#40796 +rpl_extraColmaster_innodb # Bug#40796 +rpl_extraCol_innodb # Bug#40796 From c2ec53f94ab3bec0fec75b34b4eb2d00463690e5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 8 Jul 2009 10:31:49 +0300 Subject: [PATCH 175/188] Bug#38998, Bug#46029, Bug#45243, Bug#46030 making tests experimental --- mysql-test/collections/default.experimental | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 01e5ecd9da0..faa8ba110d3 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -4,6 +4,10 @@ main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fail rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2 rpl.rpl_extraColmaster_myisam # Bug#46013: rpl_extraColmaster_myisam fails on pb2 rpl.rpl_stm_reset_slave # Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2 -rpl_extraCol_myisam # Bug#40796 -rpl_extraColmaster_innodb # Bug#40796 -rpl_extraCol_innodb # Bug#40796 +rpl.rpl_extraCol_myisam # Bug#40796 +rpl.rpl_extraColmaster_innodb # Bug#40796 +rpl.rpl_extraCol_innodb # Bug#40796 +rpl_ndb.rpl_ndb_log # Bug#38998 +rpl.rpl_innodb_bug28430 # Bug#46029 +rpl.rpl_row_basic_3innodb # Bug#45243 +rpl.rpl_truncate_3innodb # Bug#46030 From ead1ce94e61b0e4436def29515c2e15c95a9b1aa Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 8 Jul 2009 13:12:27 +0300 Subject: [PATCH 176/188] Addendum to the fix for bug 45807 : initialize a member needed in Item_field::fix_fields() --- sql/sql_partition.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 4472b9be2cd..284eaebbe87 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -973,6 +973,7 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, save_use_only_table_context= thd->lex->use_only_table_context; thd->lex->use_only_table_context= TRUE; + thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS; error= func_expr->fix_fields(thd, (Item**)&func_expr); From ab2f3dd2a2d23d2b96604515ddc0576b54ad8049 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 8 Jul 2009 16:49:45 +0200 Subject: [PATCH 177/188] Bug #43397 mysql headers redefine pthread_mutex_init unnecessarily The problem is that libmysqlclient.so is built with THREAD undefined, while a client compiling against the same header files will see THREAD as defined and definitions in my_pthread.h will be included, possibly resulting in undefined symbols that cannot be resolved with libmysqlclient.so. The suggested solution is to require that clients wanting to link with libmysqlclient.so should be built with MYSQL_CLIENT_NO_THREADS defined. This requires a documentation change, and more details for this will be supplied if this patch is approved. The MYSQL_CLIENT_NO_THREADS define was renamed from UNDEF_THREADS_HACK, to get a more suitable (less suspicious) name for the define. (The UNDEF_THREADS_HACK is retained for backwards compatibility, though.) This patch is also in anticipation of WL#4958, which will remove this problem altogether by dropping the building of libmysqlclient. --- client/Makefile.am | 6 +++--- cmd-line-utils/readline/Makefile.am | 2 +- include/my_global.h | 2 +- libmysql/Makefile.am | 4 ++-- tests/Makefile.am | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index 94db565ba37..5fadbc171ae 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -80,14 +80,14 @@ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ mysqlshow_SOURCES= mysqlshow.c mysqlslap_SOURCES= mysqlslap.c -mysqlslap_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK +mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ $(top_builddir)/mysys/libmysys.a mysqltest_SOURCES= mysqltest.cc -mysqltest_CXXFLAGS= -DTHREAD -UUNDEF_THREADS_HACK +mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ @@ -99,7 +99,7 @@ mysql_upgrade_SOURCES= mysql_upgrade.c \ $(top_srcdir)/mysys/my_getpagesize.c # Fix for mit-threads -DEFS = -DUNDEF_THREADS_HACK \ +DEFS = -DMYSQL_CLIENT_NO_THREADS \ -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ -DDATADIR="\"$(localstatedir)\"" diff --git a/cmd-line-utils/readline/Makefile.am b/cmd-line-utils/readline/Makefile.am index 5fcbcde0516..e5f5717858d 100644 --- a/cmd-line-utils/readline/Makefile.am +++ b/cmd-line-utils/readline/Makefile.am @@ -31,7 +31,7 @@ noinst_HEADERS = readline.h chardefs.h keymaps.h \ EXTRA_DIST= emacs_keymap.c vi_keymap.c -DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR +DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/include/my_global.h b/include/my_global.h index 9e8c9bdfc70..5b29c7ce000 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -276,7 +276,7 @@ #endif /* The client defines this to avoid all thread code */ -#if defined(UNDEF_THREADS_HACK) +#if defined(MYSQL_CLIENT_NO_THREADS) || defined(UNDEF_THREADS_HACK) #undef THREAD #undef HAVE_LINUXTHREADS #undef HAVE_NPTL diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 21f8f372d0f..f67abfd8ac6 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -21,7 +21,7 @@ # This file is public domain and comes with NO WARRANTY of any kind target = libmysqlclient.la -target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ +target_defs = -DMYSQL_CLIENT_NO_THREADS -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ LIBS = @CLIENT_LIBS@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) @ZLIB_INCLUDES@ @@ -104,7 +104,7 @@ do-lib-dist: echo "# A very minimal Makefile to compile" > $$dir/Makefile; \ echo "# the minimized libmysql library" >> $$dir/Makefile; \ echo "# This file is autogenerated from Makefile.am" >> $$dir/Makefile; \ - echo 'CFLAGS= -I. -DUNDEF_THREADS_HACK' >>$$dir/Makefile; \ + echo 'CFLAGS= -I. -DMYSQL_CLIENT_NO_THREADS' >>$$dir/Makefile; \ echo "obj=$$objs" >>$$dir/Makefile; \ echo 'all: libmysql.a' >>$$dir/Makefile; \ echo 'libmysql.a: $$(obj)' >>$$dir/Makefile; \ diff --git a/tests/Makefile.am b/tests/Makefile.am index fbd58b88b9c..ddc6da86e1c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -56,7 +56,7 @@ bug25714_SOURCES= bug25714.c bug25714_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) # Fix for mit-threads -DEFS = -DUNDEF_THREADS_HACK +DEFS = -DMYSQL_CLIENT_NO_THREADS thread_test.o: thread_test.c $(COMPILE) -c $(INCLUDES) $< From bb4778b57fc657d0f247db816df6c3cc91d8e937 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 10 Jul 2009 15:55:08 +0530 Subject: [PATCH 178/188] Applying InnoDB snashot 5.1-ss5488, part 1 1. Fixes build warnings caused by applying snapshot 5.1-ss5282 2. Fix the Makefile.am in storage/innobase to remove the header file 'fsp0types.h' which was added twice to fix build warning generated after applying the 5.1-ss5282 snapshot Detailed revision comments: r5410 | marko | 2009-06-24 22:26:34 +0300 (Wed, 24 Jun 2009) | 2 lines branches/5.1: Add missing #include "mtr0log.h" to avoid warnings when compiling with -DUNIV_MUST_NOT_INLINE. --- storage/innobase/Makefile.am | 2 +- storage/innobase/include/trx0sys.ic | 1 + storage/innobase/trx/trx0purge.c | 1 + storage/innobase/trx/trx0sys.c | 2 +- storage/innobase/trx/trx0undo.c | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 0143aee8e1a..3df9a6bf988 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -57,7 +57,7 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \ include/ha0ha.ic include/hash0hash.h \ include/hash0hash.ic include/ibuf0ibuf.h \ include/ibuf0ibuf.ic include/ibuf0types.h \ - include/lock0iter.h include/fsp0types.h \ + include/lock0iter.h \ include/lock0lock.h include/lock0lock.ic \ include/lock0priv.h include/lock0priv.ic \ include/lock0types.h include/log0log.h \ diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index 86b71df08d6..55bcc12a414 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -9,6 +9,7 @@ Created 3/26/1996 Heikki Tuuri #include "srv0srv.h" #include "trx0trx.h" #include "data0type.h" +#include "mtr0log.h" /* The typedef for rseg slot in the file copy */ typedef byte trx_sysf_rseg_t; diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index f0e85ef1604..f0f300d918e 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -14,6 +14,7 @@ Created 3/26/1996 Heikki Tuuri #include "fsp0fsp.h" #include "mach0data.h" +#include "mtr0log.h" #include "trx0rseg.h" #include "trx0trx.h" #include "trx0roll.h" diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 7975950e912..19c5159e15f 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -13,7 +13,7 @@ Created 3/26/1996 Heikki Tuuri #endif #include "fsp0fsp.h" -#include "mtr0mtr.h" +#include "mtr0log.h" #include "trx0trx.h" #include "trx0rseg.h" #include "trx0undo.h" diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index b31580d0ce0..deb6c85e6e3 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -14,6 +14,7 @@ Created 3/26/1996 Heikki Tuuri #include "fsp0fsp.h" #include "mach0data.h" +#include "mtr0log.h" #include "trx0rseg.h" #include "trx0trx.h" #include "srv0srv.h" From c64b76edeb97048fbf9150ba7a329ad66cb5f267 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 10 Jul 2009 16:06:07 +0530 Subject: [PATCH 179/188] Applying InnoDB snapshot 5.1-ss5488,part 2. Fixes BUG#45749 BUG#45749 - Race condition in SET GLOBAL innodb_commit_concurrency=DEFAULT Detailed revision comments: r5419 | marko | 2009-06-25 16:11:57 +0300 (Thu, 25 Jun 2009) | 18 lines branches/5.1: Merge r5418 from branches/zip: ------------------------------------------------------------------------ r5418 | marko | 2009-06-25 15:55:52 +0300 (Thu, 25 Jun 2009) | 5 lines Changed paths: M /branches/zip/ChangeLog M /branches/zip/handler/ha_innodb.cc M /branches/zip/mysql-test/innodb_bug42101-nonzero.result M /branches/zip/mysql-test/innodb_bug42101-nonzero.test M /branches/zip/mysql-test/innodb_bug42101.result M /branches/zip/mysql-test/innodb_bug42101.test branches/zip: Fix a race condition caused by SET GLOBAL innodb_commit_concurrency=DEFAULT. (Bug #45749) When innodb_commit_concurrency is initially set nonzero, DEFAULT would change it back to 0, triggering Bug #42101. rb://139 approved by Heikki Tuuri. ------------------------------------------------------------------------ --- mysql-test/r/innodb_bug42101-nonzero.result | 6 +++- mysql-test/r/innodb_bug42101.result | 4 +++ mysql-test/t/innodb_bug42101-nonzero.test | 2 ++ mysql-test/t/innodb_bug42101.test | 2 ++ storage/innobase/handler/ha_innodb.cc | 34 +++++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_bug42101-nonzero.result b/mysql-test/r/innodb_bug42101-nonzero.result index 8a14296381c..277dfffdd35 100644 --- a/mysql-test/r/innodb_bug42101-nonzero.result +++ b/mysql-test/r/innodb_bug42101-nonzero.result @@ -11,11 +11,15 @@ set global innodb_commit_concurrency=42; select @@innodb_commit_concurrency; @@innodb_commit_concurrency 42 +set global innodb_commit_concurrency=DEFAULT; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +1 set global innodb_commit_concurrency=0; ERROR HY000: Incorrect arguments to SET select @@innodb_commit_concurrency; @@innodb_commit_concurrency -42 +1 set global innodb_commit_concurrency=1; select @@innodb_commit_concurrency; @@innodb_commit_concurrency diff --git a/mysql-test/r/innodb_bug42101.result b/mysql-test/r/innodb_bug42101.result index 9a9c8e0ce9b..805097ffe9d 100644 --- a/mysql-test/r/innodb_bug42101.result +++ b/mysql-test/r/innodb_bug42101.result @@ -16,3 +16,7 @@ set global innodb_commit_concurrency=0; select @@innodb_commit_concurrency; @@innodb_commit_concurrency 0 +set global innodb_commit_concurrency=DEFAULT; +select @@innodb_commit_concurrency; +@@innodb_commit_concurrency +0 diff --git a/mysql-test/t/innodb_bug42101-nonzero.test b/mysql-test/t/innodb_bug42101-nonzero.test index c691a234c51..685fdf20489 100644 --- a/mysql-test/t/innodb_bug42101-nonzero.test +++ b/mysql-test/t/innodb_bug42101-nonzero.test @@ -12,6 +12,8 @@ set global innodb_commit_concurrency=1; select @@innodb_commit_concurrency; set global innodb_commit_concurrency=42; select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=DEFAULT; +select @@innodb_commit_concurrency; --error ER_WRONG_ARGUMENTS set global innodb_commit_concurrency=0; select @@innodb_commit_concurrency; diff --git a/mysql-test/t/innodb_bug42101.test b/mysql-test/t/innodb_bug42101.test index 13d531ecde7..b6536490d48 100644 --- a/mysql-test/t/innodb_bug42101.test +++ b/mysql-test/t/innodb_bug42101.test @@ -15,3 +15,5 @@ set global innodb_commit_concurrency=42; select @@innodb_commit_concurrency; set global innodb_commit_concurrency=0; select @@innodb_commit_concurrency; +set global innodb_commit_concurrency=DEFAULT; +select @@innodb_commit_concurrency; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 56e28cf5f14..993cd688032 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -166,6 +166,20 @@ static handler *innobase_create_handler(handlerton *hton, static const char innobase_hton_name[]= "InnoDB"; +/** @brief Initialize the default value of innodb_commit_concurrency. + +Once InnoDB is running, the innodb_commit_concurrency must not change +from zero to nonzero. (Bug #42101) + +The initial default value is 0, and without this extra initialization, +SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter +to 0, even if it was initially set to nonzero at the command line +or configuration file. */ +static +void +innobase_commit_concurrency_init_default(void); +/*==========================================*/ + /***************************************************************** Check for a valid value of innobase_commit_concurrency. */ static @@ -1775,6 +1789,8 @@ innobase_init( (char*)"latin1_swedish_ci")); memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256); + innobase_commit_concurrency_init_default(); + /* Since we in this module access directly the fields of a trx struct, and due to different headers and flags it might happen that mutex_t has a different size in this module and in InnoDB @@ -8464,3 +8480,21 @@ mysql_declare_plugin(innobase) NULL /* reserved */ } mysql_declare_plugin_end; + +/** @brief Initialize the default value of innodb_commit_concurrency. + +Once InnoDB is running, the innodb_commit_concurrency must not change +from zero to nonzero. (Bug #42101) + +The initial default value is 0, and without this extra initialization, +SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter +to 0, even if it was initially set to nonzero at the command line +or configuration file. */ +static +void +innobase_commit_concurrency_init_default(void) +/*==========================================*/ +{ + MYSQL_SYSVAR_NAME(commit_concurrency).def_val + = innobase_commit_concurrency; +} From 38d9fa89123bce55128f287fe2a31534ace84b26 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 10 Jul 2009 16:10:31 +0530 Subject: [PATCH 180/188] Applying InnoDB snapshot 5.1-ss5488 part3,Fixes BUG#45814 Detailed revision comments: r5440 | vasil | 2009-06-30 13:04:29 +0300 (Tue, 30 Jun 2009) | 8 lines branches/5.1: Fix Bug#45814 URL reference in InnoDB server errors needs adjusting to match documentation by changing the URL from http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html to http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting-datadict.html --- storage/innobase/fil/fil0fil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index c63d67cae60..42e5166c9e4 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -2745,7 +2745,7 @@ fil_open_single_table_tablespace( "InnoDB: and MySQL removed the .ibd file for this.\n" "InnoDB: Please refer to\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "innodb-troubleshooting-datadict.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(filepath); @@ -2786,7 +2786,7 @@ fil_open_single_table_tablespace( " IMPORT TABLESPACE?\n" "InnoDB: Please refer to\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "innodb-troubleshooting-datadict.html\n" "InnoDB: for how to resolve the issue.\n", (ulong) space_id, (ulong) id); @@ -3477,7 +3477,7 @@ fil_space_for_table_exists_in_mem( error_exit: fputs("InnoDB: Please refer to\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "innodb-troubleshooting.html\n" + "innodb-troubleshooting-datadict.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(path); From 2b26729eceeebe6c19349d5a4d0010241bf92847 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Fri, 10 Jul 2009 17:34:03 +0600 Subject: [PATCH 181/188] Bug #45796: invalid memory reads and writes when altering merge and base tables myrg_attach_children() could reuse a buffer that was allocated previously based on a definition of a child table. The problem was that the child's definition might have been changed, so reusing the buffer could lead to crashes or valgrind errors under some circumstances. Fixed by changing myrg_attach_children() so that the rec_per_key_part buffer is reused only when the child table have not changed, and reallocated otherwise (the old buffer is deallocated if necessary). include/myisammrg.h: Added a pointer to need_compat_check as an argument to myrg_attach_children(). mysql-test/r/merge.result: Added a test case for bug #45796. mysql-test/t/merge.test: Added a test case for bug #45796. storage/myisammrg/ha_myisammrg.cc: Pass a pointer to need_compat_check to myrg_attach_children(). storage/myisammrg/myrg_open.c: Changed myrg_attach_children() so that the rec_per_key_part buffer is reused only when the child table have not changed, and reallocated otherwise (the old buffer is deallocated if necessary). --- include/myisammrg.h | 3 ++- mysql-test/r/merge.result | 14 ++++++++++++++ mysql-test/t/merge.test | 20 ++++++++++++++++++++ storage/myisammrg/ha_myisammrg.cc | 3 ++- storage/myisammrg/myrg_open.c | 20 ++++++++++++++------ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/include/myisammrg.h b/include/myisammrg.h index dafae157ee0..446ecb7d719 100644 --- a/include/myisammrg.h +++ b/include/myisammrg.h @@ -88,7 +88,8 @@ extern MYRG_INFO *myrg_parent_open(const char *parent_name, void *callback_param); extern int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, MI_INFO *(*callback)(void*), - void *callback_param); + void *callback_param, + my_bool *need_compat_check); extern int myrg_detach_children(MYRG_INFO *m_info); extern int myrg_panic(enum ha_panic_function function); extern int myrg_rfirst(MYRG_INFO *file,uchar *buf,int inx); diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index f53b328d14e..bf9108459d7 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2127,4 +2127,18 @@ SELECT * FROM m1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP VIEW v1; DROP TABLE m1, t1; +# +# Bug #45796: invalid memory reads and writes when altering merge and +# base tables +# +CREATE TABLE t1(c1 INT) ENGINE=MyISAM; +CREATE TABLE m1(c1 INT) ENGINE=MERGE UNION=(t1); +ALTER TABLE m1 ADD INDEX idx_c1(c1); +SELECT * FROM m1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +ALTER TABLE t1 ADD INDEX idx_c1(c1); +SELECT * FROM m1; +c1 +DROP TABLE m1; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 5315c91daa6..8760876b7ee 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1535,4 +1535,24 @@ SELECT * FROM m1; DROP VIEW v1; DROP TABLE m1, t1; + +--echo # +--echo # Bug #45796: invalid memory reads and writes when altering merge and +--echo # base tables +--echo # + +CREATE TABLE t1(c1 INT) ENGINE=MyISAM; +CREATE TABLE m1(c1 INT) ENGINE=MERGE UNION=(t1); +ALTER TABLE m1 ADD INDEX idx_c1(c1); +# Open the MERGE table and allocate buffers based on children's definition. +--error ER_WRONG_MRG_TABLE +SELECT * FROM m1; +# Change the child table definition. +ALTER TABLE t1 ADD INDEX idx_c1(c1); +# Check that old buffers are not reused +SELECT * FROM m1; + +DROP TABLE m1; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 1e82983b97c..19510d0eae1 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -545,7 +545,8 @@ int ha_myisammrg::attach_children(void) if (myrg_attach_children(this->file, this->test_if_locked | current_thd->open_options, - myisammrg_attach_children_callback, this)) + myisammrg_attach_children_callback, this, + (my_bool *) &need_compat_check)) { DBUG_PRINT("error", ("my_errno %d", my_errno)); DBUG_RETURN(my_errno ? my_errno : -1); diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 14ba2853b22..01420f47a0c 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -365,11 +365,14 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, The callback returns the MyISAM table handle of the child table. Check table definition match. - @param[in] m_info MERGE parent table structure - @param[in] handle_locking if contains HA_OPEN_FOR_REPAIR, warn about - incompatible child tables, but continue - @param[in] callback function to call for each child table - @param[in] callback_param data pointer to give to the callback + @param[in] m_info MERGE parent table structure + @param[in] handle_locking if contains HA_OPEN_FOR_REPAIR, warn about + incompatible child tables, but continue + @param[in] callback function to call for each child table + @param[in] callback_param data pointer to give to the callback + @param[in] need_compat_check pointer to ha_myisammrg::need_compat_check + (we need this one to decide if previously + allocated buffers can be reused). @return status @retval 0 OK @@ -382,7 +385,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, MI_INFO *(*callback)(void*), - void *callback_param) + void *callback_param, my_bool *need_compat_check) { ulonglong file_offset; MI_INFO *myisam; @@ -423,6 +426,11 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, m_info->reclength= myisam->s->base.reclength; min_keys= myisam->s->base.keys; key_parts= myisam->s->base.key_parts; + if (*need_compat_check && m_info->rec_per_key_part) + { + my_free((char *) m_info->rec_per_key_part, MYF(0)); + m_info->rec_per_key_part= NULL; + } if (!m_info->rec_per_key_part) { if(!(m_info->rec_per_key_part= (ulong*) From 526a42e2549edab6b73c1f50327ad6346f89b57b Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 10 Jul 2009 17:05:53 +0530 Subject: [PATCH 182/188] Applying InnoDB snapshot 5.1-ss5488,part 4. Fixes BUG#21704 1. BUG#21704 - Renaming column does not update FK definition 2. Changes in mysql-test/include/mtr_warnings.sql so that the testcase for BUG#21704 doesn't fail because of the warnings generated. Detailed revision comments: r5488 | vasil | 2009-07-09 19:16:44 +0300 (Thu, 09 Jul 2009) | 13 lines branches/5.1: Fix Bug#21704 Renaming column does not update FK definition by checking whether a column that participates in a FK definition is being renamed and denying the ALTER in this case. The patch was originally developed by Davi Arnaut : http://lists.mysql.com/commits/77714 and was later adjusted to conform to InnoDB coding style by me (Vasil), I also added some more comments and moved the bug specific mysql-test to a separate file to make it more manageable and flexible. --- mysql-test/include/mtr_warnings.sql | 4 +- mysql-test/r/innodb_bug21704.result | 55 +++++++++++++++ mysql-test/t/innodb_bug21704.test | 96 ++++++++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 98 +++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/innodb_bug21704.result create mode 100644 mysql-test/t/innodb_bug21704.test diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 73287900f3c..b99402c8031 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -139,9 +139,9 @@ INSERT INTO global_suppressions VALUES ("Cannot find or open table test\/bug29807 from"), /* innodb foreign key tests that fail in ALTER or RENAME produce this */ - ("InnoDB: Error: in ALTER TABLE `test`.`t[12]`"), + ("InnoDB: Error: in ALTER TABLE `test`.`t[123]`"), ("InnoDB: Error: in RENAME TABLE table `test`.`t1`"), - ("InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal"), + ("InnoDB: Error: table `test`.`t[123]` does not exist in the InnoDB internal"), /* Test case for Bug#14233 produces the following warnings: */ ("Stored routine 'test'.'bug14233_1': invalid value in column mysql.proc"), diff --git a/mysql-test/r/innodb_bug21704.result b/mysql-test/r/innodb_bug21704.result new file mode 100644 index 00000000000..b8e0b15d50d --- /dev/null +++ b/mysql-test/r/innodb_bug21704.result @@ -0,0 +1,55 @@ +# +# Bug#21704: Renaming column does not update FK definition. +# + +# Test that it's not possible to rename columns participating in a +# foreign key (either in the referencing or referenced table). + +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ROW_FORMAT=COMPACT ENGINE=INNODB; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, +CONSTRAINT fk1 FOREIGN KEY (a) REFERENCES t1(a)) +ROW_FORMAT=COMPACT ENGINE=INNODB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT, KEY(b), C INT, +CONSTRAINT fk2 FOREIGN KEY (b) REFERENCES t3 (a)) +ROW_FORMAT=COMPACT ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +INSERT INTO t3 VALUES (1,1,1),(2,2,2),(3,3,3); + +# Test renaming the column in the referenced table. + +ALTER TABLE t1 CHANGE a c INT; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t1' (errno: 150) +# Ensure that online column rename works. +ALTER TABLE t1 CHANGE b c INT; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 + +# Test renaming the column in the referencing table + +ALTER TABLE t2 CHANGE a c INT; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150) +# Ensure that online column rename works. +ALTER TABLE t2 CHANGE b c INT; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 + +# Test with self-referential constraints + +ALTER TABLE t3 CHANGE a d INT; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t3' (errno: 150) +ALTER TABLE t3 CHANGE b d INT; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t3' (errno: 150) +# Ensure that online column rename works. +ALTER TABLE t3 CHANGE c d INT; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 + +# Cleanup. + +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/t/innodb_bug21704.test b/mysql-test/t/innodb_bug21704.test new file mode 100644 index 00000000000..c649b61034c --- /dev/null +++ b/mysql-test/t/innodb_bug21704.test @@ -0,0 +1,96 @@ +-- source include/have_innodb.inc + +--echo # +--echo # Bug#21704: Renaming column does not update FK definition. +--echo # + +--echo +--echo # Test that it's not possible to rename columns participating in a +--echo # foreign key (either in the referencing or referenced table). +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +--enable_warnings + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ROW_FORMAT=COMPACT ENGINE=INNODB; + +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, + CONSTRAINT fk1 FOREIGN KEY (a) REFERENCES t1(a)) +ROW_FORMAT=COMPACT ENGINE=INNODB; + +CREATE TABLE t3 (a INT PRIMARY KEY, b INT, KEY(b), C INT, + CONSTRAINT fk2 FOREIGN KEY (b) REFERENCES t3 (a)) +ROW_FORMAT=COMPACT ENGINE=INNODB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +INSERT INTO t3 VALUES (1,1,1),(2,2,2),(3,3,3); + +--echo +--echo # Test renaming the column in the referenced table. +--echo + +# mysqltest first does replace_regex, then replace_result +--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +# Embedded server doesn't chdir to data directory +--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--error ER_ERROR_ON_RENAME +ALTER TABLE t1 CHANGE a c INT; + +--echo # Ensure that online column rename works. + +--enable_info +ALTER TABLE t1 CHANGE b c INT; +--disable_info + +--echo +--echo # Test renaming the column in the referencing table +--echo + +# mysqltest first does replace_regex, then replace_result +--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +# Embedded server doesn't chdir to data directory +--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--error ER_ERROR_ON_RENAME +ALTER TABLE t2 CHANGE a c INT; + +--echo # Ensure that online column rename works. + +--enable_info +ALTER TABLE t2 CHANGE b c INT; +--disable_info + +--echo +--echo # Test with self-referential constraints +--echo + +# mysqltest first does replace_regex, then replace_result +--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +# Embedded server doesn't chdir to data directory +--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--error ER_ERROR_ON_RENAME +ALTER TABLE t3 CHANGE a d INT; + +# mysqltest first does replace_regex, then replace_result +--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +# Embedded server doesn't chdir to data directory +--replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--error ER_ERROR_ON_RENAME +ALTER TABLE t3 CHANGE b d INT; + +--echo # Ensure that online column rename works. + +--enable_info +ALTER TABLE t3 CHANGE c d INT; +--disable_info + +--echo +--echo # Cleanup. +--echo + +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 993cd688032..2f29ca62000 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8177,6 +8177,97 @@ innobase_set_cursor_view( } +/*********************************************************************** +Check whether any of the given columns is being renamed in the table. */ +static +bool +column_is_being_renamed( +/*====================*/ + /* out: true if any of col_names is + being renamed in table */ + TABLE* table, /* in: MySQL table */ + uint n_cols, /* in: number of columns */ + const char** col_names) /* in: names of the columns */ +{ + uint j; + uint k; + Field* field; + const char* col_name; + + for (j = 0; j < n_cols; j++) { + col_name = col_names[j]; + for (k = 0; k < table->s->fields; k++) { + field = table->field[k]; + if ((field->flags & FIELD_IS_RENAMED) + && innobase_strcasecmp(field->field_name, + col_name) == 0) { + return(true); + } + } + } + + return(false); +} + +/*********************************************************************** +Check whether a column in table "table" is being renamed and if this column +is part of a foreign key, either part of another table, referencing this +table or part of this table, referencing another table. */ +static +bool +foreign_key_column_is_being_renamed( +/*================================*/ + /* out: true if a column that + participates in a foreign key definition + is being renamed */ + row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */ + TABLE* table) /* in: MySQL table */ +{ + dict_foreign_t* foreign; + + /* check whether there are foreign keys at all */ + if (UT_LIST_GET_LEN(prebuilt->table->foreign_list) == 0 + && UT_LIST_GET_LEN(prebuilt->table->referenced_list) == 0) { + /* no foreign keys involved with prebuilt->table */ + + return(false); + } + + row_mysql_lock_data_dictionary(prebuilt->trx); + + /* Check whether any column in the foreign key constraints which refer + to this table is being renamed. */ + for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list); + foreign != NULL; + foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + + if (column_is_being_renamed(table, foreign->n_fields, + foreign->referenced_col_names)) { + + row_mysql_unlock_data_dictionary(prebuilt->trx); + return(true); + } + } + + /* Check whether any column in the foreign key constraints in the + table is being renamed. */ + for (foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); + foreign != NULL; + foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) { + + if (column_is_being_renamed(table, foreign->n_fields, + foreign->foreign_col_names)) { + + row_mysql_unlock_data_dictionary(prebuilt->trx); + return(true); + } + } + + row_mysql_unlock_data_dictionary(prebuilt->trx); + + return(false); +} + bool ha_innobase::check_if_incompatible_data( HA_CREATE_INFO* info, uint table_changes) @@ -8193,6 +8284,13 @@ bool ha_innobase::check_if_incompatible_data( return COMPATIBLE_DATA_NO; } + /* Check if a column participating in a foreign key is being renamed. + There is no mechanism for updating InnoDB foreign key definitions. */ + if (foreign_key_column_is_being_renamed(prebuilt, table)) { + + return COMPATIBLE_DATA_NO; + } + /* Check that row format didn't change */ if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) && get_row_type() != info->row_type) { From 5beae1f8dcf6417315aec0940fadd8b32c218afe Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Jul 2009 15:00:34 +0300 Subject: [PATCH 183/188] Bug #46080: group_concat(... order by) crashes server when sort_buffer_size cannot allocate The NULL return from tree_insert() (on low memory) was not checked for in Item_func_group_concat::add(). As a result on low memory conditions a crash happens. Fixed by properly checking the return code. --- mysql-test/r/bug46080.result | 14 ++++++++++++++ mysql-test/t/bug46080-master.opt | 1 + mysql-test/t/bug46080.test | 19 +++++++++++++++++++ sql/item_sum.cc | 5 +++++ 4 files changed, 39 insertions(+) create mode 100644 mysql-test/r/bug46080.result create mode 100644 mysql-test/t/bug46080-master.opt create mode 100644 mysql-test/t/bug46080.test diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result new file mode 100644 index 00000000000..9ae4b55d8ea --- /dev/null +++ b/mysql-test/r/bug46080.result @@ -0,0 +1,14 @@ +# +# Bug #46080: group_concat(... order by) crashes server when +# sort_buffer_size cannot allocate +# +CREATE TABLE t1(a CHAR(255)); +INSERT INTO t1 VALUES ('a'); +SET @@SESSION.sort_buffer_size=5*16*1000000; +SET @@SESSION.max_heap_table_size=5*1000000; +# Must not crash. +SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a +DROP TABLE t1; +SET @@SESSION.sort_buffer_size=default; +SET @@SESSION.max_heap_table_size=default; +End of 5.0 tests diff --git a/mysql-test/t/bug46080-master.opt b/mysql-test/t/bug46080-master.opt new file mode 100644 index 00000000000..f59740afe60 --- /dev/null +++ b/mysql-test/t/bug46080-master.opt @@ -0,0 +1 @@ +--skip-grant-tables --skip-name-resolve --safemalloc-mem-limit=4000000 diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test new file mode 100644 index 00000000000..9e6cc69b958 --- /dev/null +++ b/mysql-test/t/bug46080.test @@ -0,0 +1,19 @@ +--echo # +--echo # Bug #46080: group_concat(... order by) crashes server when +--echo # sort_buffer_size cannot allocate +--echo # + +CREATE TABLE t1(a CHAR(255)); +INSERT INTO t1 VALUES ('a'); + +SET @@SESSION.sort_buffer_size=5*16*1000000; +SET @@SESSION.max_heap_table_size=5*1000000; + +echo # Must not crash. +SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a; + +DROP TABLE t1; +SET @@SESSION.sort_buffer_size=default; +SET @@SESSION.max_heap_table_size=default; + +--echo End of 5.0 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index a381361e8a2..dde8fe29e5a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3291,8 +3291,13 @@ bool Item_func_group_concat::add() TREE_ELEMENT *el= 0; // Only for safety if (row_eligible && tree) + { el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0, tree->custom_arg); + /* check if there was enough memory to insert the row */ + if (!el) + return 1; + } /* If the row is not a duplicate (el->count == 1) we can dump the row here in case of GROUP_CONCAT(DISTINCT...) From 3e642d155eedb0321b8b51fae976a5053fad3b82 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 10 Jul 2009 09:19:19 -0300 Subject: [PATCH 184/188] Bug#21704: Renaming column does not update FK definition Remove commented-out test case. It has been moved to innodb_bug21704.test --- mysql-test/include/mix1.inc | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 19a327d079e..6dabe4864a9 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1504,37 +1504,6 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DE DROP TABLE t1; -# -# Bug#21704: Renaming column does not update FK definition. -# - -# -# --disable_warnings -# DROP TABLE IF EXISTS t1; -# DROP TABLE IF EXISTS t2; -# --enable_warnings -# -# CREATE TABLE t1(id INT PRIMARY KEY) -# ENGINE=innodb; -# -# CREATE TABLE t2( -# t1_id INT PRIMARY KEY, -# CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id)) -# ENGINE=innodb; -# -# --echo -# -# --disable_result_log -# --error ER_ERROR_ON_RENAME -# ALTER TABLE t1 CHANGE id id2 INT; -# --enable_result_log -# -# --echo -# -# DROP TABLE t2; -# DROP TABLE t1; -# - --echo # --echo # Bug #44290: explain crashes for subquery with distinct in --echo # SQL_SELECT::test_quick_select From 55f514ad0505182cb3a7f3f955a16baadb2493ba Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Jul 2009 16:00:17 +0300 Subject: [PATCH 185/188] fixed the CPU checking code. --- BUILD/check-cpu | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/BUILD/check-cpu b/BUILD/check-cpu index 4974d3f4ecc..e7cae1c1da8 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -44,8 +44,13 @@ check_cpu () { model_name=`sysctl -n hw.model` ;; Darwin) - cpu_family=`uname -p` - model_name=`machine` + cpu_family=`sysctl -n machdep.cpu.vendor` + model_name=`sysctl -n machdep.cpu.brand_string` + if [ -z "$cpu_family" -o -z "$model_name" ] + then + cpu_family=`uname -p` + model_name=`machine` + fi ;; *) cpu_family=`uname -m`; From 924c8c5bfbc346de72d27a06fa5d6cb87b471c08 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 10 Jul 2009 17:03:09 +0300 Subject: [PATCH 186/188] Addendum to the fix for bug #46080: fixed the test case --- mysql-test/r/bug46080.result | 3 ++- mysql-test/t/bug46080.test | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result index 9ae4b55d8ea..f69c4ac1f71 100644 --- a/mysql-test/r/bug46080.result +++ b/mysql-test/r/bug46080.result @@ -7,7 +7,8 @@ INSERT INTO t1 VALUES ('a'); SET @@SESSION.sort_buffer_size=5*16*1000000; SET @@SESSION.max_heap_table_size=5*1000000; # Must not crash. -SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a +SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a; +Got one of the listed errors DROP TABLE t1; SET @@SESSION.sort_buffer_size=default; SET @@SESSION.max_heap_table_size=default; diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test index 9e6cc69b958..277d513f3e5 100644 --- a/mysql-test/t/bug46080.test +++ b/mysql-test/t/bug46080.test @@ -9,7 +9,8 @@ INSERT INTO t1 VALUES ('a'); SET @@SESSION.sort_buffer_size=5*16*1000000; SET @@SESSION.max_heap_table_size=5*1000000; -echo # Must not crash. +--echo # Must not crash. +--error 5,0 SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a; DROP TABLE t1; From 8b2788478b9267b3e7b5cb3a83628e1b710a6671 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Sat, 11 Jul 2009 23:44:29 +0500 Subject: [PATCH 187/188] Bug #41156: List of derived tables acts like a chain of mutually-nested subqueries Queries of the form SELECT * FROM (SELECT 1) AS t1, (SELECT 2) AS t2,... (SELECT 32) AS t32 caused the "Too high level of nesting for select" error as if the query has a form SELECT * FROM (SELECT 1 FROM (SELECT 2 FROM (SELECT 3 FROM... The table_factor parser rule has been modified to adjust the LEX::nest_level variable value after every derived table. mysql-test/r/derived.result: Added test case for bug #41156. mysql-test/t/derived.test: Added test case for bug #41156. sql/sql_yacc.yy: Bug #41156: List of derived tables acts like a chain of mutually-nested subqueries The select_derived2 parser rule calls mysql_new_select() calls push_context() and nest_level++, however only the pop_context() was called at the end of derived table parsing at the table_factor rule. The table_factor parser rule has been modified to adjust the LEX::nest_level variable value after every derived table. --- mysql-test/r/derived.result | 18 ++++++++++++++++++ mysql-test/t/derived.test | 24 +++++++++++++++++++++++- sql/sql_yacc.yy | 5 +++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 306c51fb8cf..80f04ffd455 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -383,3 +383,21 @@ select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID; ID DATA FID drop table t1, t2; drop user mysqltest_1; +# End of 4.1 tests +SELECT 0 FROM +(SELECT 0) t01, (SELECT 0) t02, (SELECT 0) t03, (SELECT 0) t04, (SELECT 0) t05, +(SELECT 0) t06, (SELECT 0) t07, (SELECT 0) t08, (SELECT 0) t09, (SELECT 0) t10, +(SELECT 0) t11, (SELECT 0) t12, (SELECT 0) t13, (SELECT 0) t14, (SELECT 0) t15, +(SELECT 0) t16, (SELECT 0) t17, (SELECT 0) t18, (SELECT 0) t19, (SELECT 0) t20, +(SELECT 0) t21, (SELECT 0) t22, (SELECT 0) t23, (SELECT 0) t24, (SELECT 0) t25, +(SELECT 0) t26, (SELECT 0) t27, (SELECT 0) t28, (SELECT 0) t29, (SELECT 0) t30, +(SELECT 0) t31, (SELECT 0) t32, (SELECT 0) t33, (SELECT 0) t34, (SELECT 0) t35, +(SELECT 0) t36, (SELECT 0) t37, (SELECT 0) t38, (SELECT 0) t39, (SELECT 0) t40, +(SELECT 0) t41, (SELECT 0) t42, (SELECT 0) t43, (SELECT 0) t44, (SELECT 0) t45, +(SELECT 0) t46, (SELECT 0) t47, (SELECT 0) t48, (SELECT 0) t49, (SELECT 0) t50, +(SELECT 0) t51, (SELECT 0) t52, (SELECT 0) t53, (SELECT 0) t54, (SELECT 0) t55, +(SELECT 0) t56, (SELECT 0) t57, (SELECT 0) t58, (SELECT 0) t59, (SELECT 0) t60, +(SELECT 0) t61; +0 +0 +# End of 5.0 tests diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index bf5cd4aa8d8..d28c19bbd18 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -279,4 +279,26 @@ disconnect con1; connection default; drop user mysqltest_1; -# End of 4.1 tests +--echo # End of 4.1 tests + +# +# Bug #41156: List of derived tables acts like a chain of +# mutually-nested subqueries +# + +SELECT 0 FROM +(SELECT 0) t01, (SELECT 0) t02, (SELECT 0) t03, (SELECT 0) t04, (SELECT 0) t05, +(SELECT 0) t06, (SELECT 0) t07, (SELECT 0) t08, (SELECT 0) t09, (SELECT 0) t10, +(SELECT 0) t11, (SELECT 0) t12, (SELECT 0) t13, (SELECT 0) t14, (SELECT 0) t15, +(SELECT 0) t16, (SELECT 0) t17, (SELECT 0) t18, (SELECT 0) t19, (SELECT 0) t20, +(SELECT 0) t21, (SELECT 0) t22, (SELECT 0) t23, (SELECT 0) t24, (SELECT 0) t25, +(SELECT 0) t26, (SELECT 0) t27, (SELECT 0) t28, (SELECT 0) t29, (SELECT 0) t30, +(SELECT 0) t31, (SELECT 0) t32, (SELECT 0) t33, (SELECT 0) t34, (SELECT 0) t35, +(SELECT 0) t36, (SELECT 0) t37, (SELECT 0) t38, (SELECT 0) t39, (SELECT 0) t40, +(SELECT 0) t41, (SELECT 0) t42, (SELECT 0) t43, (SELECT 0) t44, (SELECT 0) t45, +(SELECT 0) t46, (SELECT 0) t47, (SELECT 0) t48, (SELECT 0) t49, (SELECT 0) t50, +(SELECT 0) t51, (SELECT 0) t52, (SELECT 0) t53, (SELECT 0) t54, (SELECT 0) t55, +(SELECT 0) t56, (SELECT 0) t57, (SELECT 0) t58, (SELECT 0) t59, (SELECT 0) t60, +(SELECT 0) t61; # 61 == MAX_TABLES + +--echo # End of 5.0 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 57a828a690b..7d6a7ade540 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8493,6 +8493,7 @@ table_factor: MYSQL_YYABORT; sel->add_joined_table($$); lex->pop_context(); + lex->nest_level--; } else if ($4 || $6) { @@ -8501,7 +8502,11 @@ table_factor: MYSQL_YYABORT; } else + { + /* nested join: FROM (t1 JOIN t2 ...), + nest_level is the same as in the outer query */ $$= $3; + } } ; From 42cab12a9366a42ae6dd2dee9024d9a56467bda3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 13 Jul 2009 14:17:14 +0300 Subject: [PATCH 188/188] Addendum to the fix for bug #46080: fixed the error handling --- mysql-test/r/bug46080.result | 1 - mysql-test/t/bug46080.test | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result index f69c4ac1f71..18c7c22829a 100644 --- a/mysql-test/r/bug46080.result +++ b/mysql-test/r/bug46080.result @@ -8,7 +8,6 @@ SET @@SESSION.sort_buffer_size=5*16*1000000; SET @@SESSION.max_heap_table_size=5*1000000; # Must not crash. SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a; -Got one of the listed errors DROP TABLE t1; SET @@SESSION.sort_buffer_size=default; SET @@SESSION.max_heap_table_size=default; diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test index 277d513f3e5..7e56e3ce421 100644 --- a/mysql-test/t/bug46080.test +++ b/mysql-test/t/bug46080.test @@ -10,8 +10,10 @@ SET @@SESSION.sort_buffer_size=5*16*1000000; SET @@SESSION.max_heap_table_size=5*1000000; --echo # Must not crash. ---error 5,0 +--disable_result_log +--error 0,5 SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY a; +--enable_result_log DROP TABLE t1; SET @@SESSION.sort_buffer_size=default;