Commit 6257ee76 authored by unknown's avatar unknown

Added isolation levels

Added SELECT .. FOR UPDATE and SELECT .. IN SHARE MODE


Docs/manual.texi:
  Updated information about SET TRANSACTION ISOLATION LEVEL
configure.in:
  Upgraded version number
isam/_dbug.c:
  Fixed wrong fprintf
isam/isamchk.c:
  Added new error message
myisam/mi_check.c:
  Added new error message
mysql-test/mysql-test-run.sh:
  Don't wait too long for server start
mysys/mf_keycache.c:
  Cleaned up some error messages
scripts/mysqlhotcopy.sh:
  Applied patch for --resetmaster --resetslave
sql-bench/bench-init.pl.sh:
  Fix for windows
sql/handler.cc:
  Added isolation levels and gemini spinlocks
sql/handler.h:
  Added isolation levels
sql/item_strfunc.cc:
  Cleanup of CONCAT_WS()
sql/lex.h:
  Added isolation levels
sql/mysql_priv.h:
  Added isolation levels
sql/mysqld.cc:
  Added isolation levels
sql/sql_class.cc:
  Added isolation levels
  Moved variable initialization to different code segments
sql/sql_class.h:
  Added isolation levels
sql/sql_lex.h:
  Added isolation levels
sql/sql_parse.cc:
  Added isolation levels
sql/sql_update.cc:
  cleanup
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent d1782bea
jani@hynda.mysql.fi monty@tik.mysql.fi
heikki@donna.mysql.fi
monty@donna.mysql.fi
paul@central.snake.net
...@@ -9738,7 +9738,7 @@ uses: ...@@ -9738,7 +9738,7 @@ uses:
@cindex options, command-line @cindex options, command-line
@cindex mysqld options @cindex mysqld options
@node Command-line options, Option files, Automatic start, Post-installation @node Command-line options, Option files, Automatic start, Post-installation
@subsection Command-line Options @subsection mysqld Command-line Options
@code{mysqld} accepts the following command-line options: @code{mysqld} accepts the following command-line options:
...@@ -9952,6 +9952,9 @@ Disable using thread priorities for faster response time. ...@@ -9952,6 +9952,9 @@ Disable using thread priorities for faster response time.
Socket file to use for local connections instead of default Socket file to use for local connections instead of default
@code{/tmp/mysql.sock}. @code{/tmp/mysql.sock}.
@item transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @}
Sets the default transaction isolation level. @xref{SET TRANSACTION}.
@item -t, --tmpdir=path @item -t, --tmpdir=path
Path for temporary files. It may be useful if your default @code{/tmp} Path for temporary files. It may be useful if your default @code{/tmp}
directory resides on a partition too small to hold temporary tables. directory resides on a partition too small to hold temporary tables.
...@@ -10816,6 +10819,9 @@ This forces all function names to be treated as reserved words. ...@@ -10816,6 +10819,9 @@ This forces all function names to be treated as reserved words.
@item @item
@code{REAL} will be a synonym for @code{FLOAT} instead of a synonym of @code{REAL} will be a synonym for @code{FLOAT} instead of a synonym of
@code{DOUBLE}. @code{DOUBLE}.
@item
The default transaction isolation level is @code{SERIALIZABLE}.
@xref{SET TRANSACTION}.
@end itemize @end itemize
@node Differences from ANSI, Missing functions, ANSI mode, Compatibility @node Differences from ANSI, Missing functions, ANSI mode, Compatibility
...@@ -13463,6 +13469,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run ...@@ -13463,6 +13469,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
* COMMIT:: @code{BEGIN/COMMIT/ROLLBACK} syntax * COMMIT:: @code{BEGIN/COMMIT/ROLLBACK} syntax
* LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax * LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax
* SET OPTION:: @code{SET OPTION} syntax * SET OPTION:: @code{SET OPTION} syntax
* SET TRANSACTION::
* GRANT:: @code{GRANT} and @code{REVOKE} syntax * GRANT:: @code{GRANT} and @code{REVOKE} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax * CREATE INDEX:: @code{CREATE INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax * DROP INDEX:: @code{DROP INDEX} syntax
...@@ -13485,7 +13492,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run ...@@ -13485,7 +13492,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
* Number syntax:: Numbers * Number syntax:: Numbers
* Hexadecimal values:: Hexadecimal values * Hexadecimal values:: Hexadecimal values
* NULL values:: @code{NULL} values * NULL values:: @code{NULL} values
* Legal names:: Database, table, index, column and alias names * Legal names:: Database, Table, Index, Column, and Alias Names
@end menu @end menu
@node String syntax, Number syntax, Literals, Literals @node String syntax, Number syntax, Literals, Literals
...@@ -19327,7 +19334,8 @@ SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] ...@@ -19327,7 +19334,8 @@ SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[HAVING where_definition] [HAVING where_definition]
[ORDER BY @{unsigned_integer | col_name | formula@} [ASC | DESC] ,...] [ORDER BY @{unsigned_integer | col_name | formula@} [ASC | DESC] ,...]
[LIMIT [offset,] rows] [LIMIT [offset,] rows]
[PROCEDURE procedure_name] ] [PROCEDURE procedure_name]
[FOR UPDATE | IN SHARE MODE]]
@end example @end example
@c help end @c help end
...@@ -19570,6 +19578,17 @@ If you use @code{INTO DUMPFILE} instead of @code{INTO OUTFILE}, @strong{MySQL} ...@@ -19570,6 +19578,17 @@ If you use @code{INTO DUMPFILE} instead of @code{INTO OUTFILE}, @strong{MySQL}
will only write one row into the file, without any column or line will only write one row into the file, without any column or line
terminations and without any escaping. This is useful if you want to terminations and without any escaping. This is useful if you want to
store a blob in a file. store a blob in a file.
@item
Note that any file created by @code{INTO OUTFILE} and @code{INTO
DUMPFILE} is going to be readable for all users! The reason is that the
@strong{MySQL} server can't create a file that is owned by anyone else
than the user it's running as (you should never run @code{mysqld} as root),
the file has to be word readable so that you can retrieve the rows.
@item
If you are using @code{FOR UPDATE} on a table handler with page/row locks,
the examined rows will be write locked.
@end itemize @end itemize
@findex JOIN @findex JOIN
...@@ -20739,6 +20758,9 @@ write is aborted with an disk full error message. ...@@ -20739,6 +20758,9 @@ write is aborted with an disk full error message.
@findex SHOW TABLE STATUS @findex SHOW TABLE STATUS
@findex SHOW GRANTS @findex SHOW GRANTS
@findex SHOW CREATE TABLE @findex SHOW CREATE TABLE
@findex SHOW MASTER STATUS
@findex SHOW MASTER LOGS
@findex SHOW SLAVE STATUS
@node SHOW, EXPLAIN, KILL, Reference @node SHOW, EXPLAIN, KILL, Reference
@section @code{SHOW} Syntax (Get Information About Tables, Columns,...) @section @code{SHOW} Syntax (Get Information About Tables, Columns,...)
...@@ -22042,7 +22064,7 @@ table you will get an error (@code{ER_WARNING_NOT_COMPLETE_ROLLBACK}) as ...@@ -22042,7 +22064,7 @@ table you will get an error (@code{ER_WARNING_NOT_COMPLETE_ROLLBACK}) as
a warning. All transactional safe tables will be restored but any a warning. All transactional safe tables will be restored but any
non-transactional table will not change. non-transactional table will not change.
If you are using @code{BEGIN} or @code{SET AUTO_COMMIT=0}, you If you are using @code{BEGIN} or @code{SET AUTOCOMMIT=0}, you
should use the @strong{MySQL} binary log for backups instead of the should use the @strong{MySQL} binary log for backups instead of the
old update log; The transaction is stored in the binary log old update log; The transaction is stored in the binary log
in one chunk, during @code{COMMIT}, the to ensure and @code{ROLLBACK}:ed in one chunk, during @code{COMMIT}, the to ensure and @code{ROLLBACK}:ed
...@@ -22057,6 +22079,9 @@ a @code{COMMIT} before executing the command): ...@@ -22057,6 +22079,9 @@ a @code{COMMIT} before executing the command):
@item @code{TRUNCATE} @item @code{TRUNCATE}
@end multitable @end multitable
You can change the isolation level for transactions with
@code{SET TRANSACTION ISOLATION LEVEL ...}. @xref{SET TRANSACTION}.
@findex LOCK TABLES @findex LOCK TABLES
@findex UNLOCK TABLES @findex UNLOCK TABLES
@node LOCK TABLES, SET OPTION, COMMIT, Reference @node LOCK TABLES, SET OPTION, COMMIT, Reference
...@@ -22162,7 +22187,7 @@ automaticly commit any active transactions before attempting to lock the ...@@ -22162,7 +22187,7 @@ automaticly commit any active transactions before attempting to lock the
tables. tables.
@findex SET OPTION @findex SET OPTION
@node SET OPTION, GRANT, LOCK TABLES, Reference @node SET OPTION, SET TRANSACTION, LOCK TABLES, Reference
@section @code{SET} Syntax @section @code{SET} Syntax
@example @example
...@@ -22303,6 +22328,30 @@ command when inserting an @code{AUTO_INCREMENT} value. This is mainly used ...@@ -22303,6 +22328,30 @@ command when inserting an @code{AUTO_INCREMENT} value. This is mainly used
with the update log. with the update log.
@end table @end table
@findex ISOLATION LEVEL
@node SET TRANSACTION, GRANT, SET OPTION, Reference
@section @code{SET TRANSACTION} Syntax
@example
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]
@end example
Sets the transaction isolation level for the global, whole session or
the next transaction.
The default behaveour is to set the isolation level for the next (not started)
isolation level.
If you set the @code{GLOBAL} privilege it will affect all new created threads.
You will need the @code{PROCESS} privilege to do do this.
Setting the @code{SESSION} privilege will affect the following and all
future transactions.
You can set the default isolation level for @code{mysqld} with
@code{--transaction-isolation=...}. @xref{Command-line options}.
@cindex privileges, granting @cindex privileges, granting
@cindex privileges, revoking @cindex privileges, revoking
@cindex global privileges @cindex global privileges
...@@ -22311,7 +22360,7 @@ with the update log. ...@@ -22311,7 +22360,7 @@ with the update log.
@findex GRANT @findex GRANT
@findex REVOKE @findex REVOKE
@node GRANT, CREATE INDEX, SET OPTION, Reference @node GRANT, CREATE INDEX, SET TRANSACTION, Reference
@section @code{GRANT} and @code{REVOKE} Syntax @section @code{GRANT} and @code{REVOKE} Syntax
@example @example
...@@ -36053,7 +36102,7 @@ direct from a remote mysql server! ...@@ -36053,7 +36102,7 @@ direct from a remote mysql server!
@code{mysqlbinlog --help} will give you more information of how to use @code{mysqlbinlog --help} will give you more information of how to use
this program! this program!
If you are using @code{BEGIN} or @code{SET AUTO_COMMIT=0}, you must use If you are using @code{BEGIN} or @code{SET AUTOCOMMIT=0}, you must use
the @strong{MySQL} binary log for backups instead of the old update log. the @strong{MySQL} binary log for backups instead of the old update log.
The binary logging is done immediately after a query completes but before The binary logging is done immediately after a query completes but before
...@@ -42245,8 +42294,6 @@ Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like SyBase). ...@@ -42245,8 +42294,6 @@ Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like SyBase).
@item @item
Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}. Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}.
@item @item
Added @code{SELECT ... WITH UPDATE} and @code{SELECT ... IN SHARE MODE} to
get more locking options.
@end itemize @end itemize
@node News-3.23.x, News-3.22.x, News-4.0.x, News @node News-3.23.x, News-3.22.x, News-4.0.x, News
...@@ -42278,6 +42325,7 @@ users uses this code as the rest of the code and because of this we are ...@@ -42278,6 +42325,7 @@ users uses this code as the rest of the code and because of this we are
not yet 100 % confident in this code. not yet 100 % confident in this code.
@menu @menu
* News-3.23.36::
* News-3.23.35:: Changes in release 3.23.35 * News-3.23.35:: Changes in release 3.23.35
* News-3.23.34a:: Changes in release 3.23.34a * News-3.23.34a:: Changes in release 3.23.34a
* News-3.23.34:: Changes in release 3.23.34 * News-3.23.34:: Changes in release 3.23.34
...@@ -42317,7 +42365,15 @@ not yet 100 % confident in this code. ...@@ -42317,7 +42365,15 @@ not yet 100 % confident in this code.
* News-3.23.0:: Changes in release 3.23.0 * News-3.23.0:: Changes in release 3.23.0
@end menu @end menu
@node News-3.23.35, News-3.23.34a, News-3.23.x, News-3.23.x @node News-3.23.36, News-3.23.35, News-3.23.x, News-3.23.x
@appendixsubsec Changes in release 3.23.36
@itemize @bullet
Added @code{SET TRANSACTION ISOLATION LEVEL ...}
@item
Added @code{SELECT ... FOR UPDATE}.
@end itemize
@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
@appendixsubsec Changes in release 3.23.35 @appendixsubsec Changes in release 3.23.35
@itemize @bullet @itemize @bullet
@item @item
...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.35) AM_INIT_AUTOMAKE(mysql, 3.23.36)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
......
...@@ -85,7 +85,7 @@ void _nisam_print_key(FILE *stream, register N_KEYSEG *keyseg, const uchar *key) ...@@ -85,7 +85,7 @@ void _nisam_print_key(FILE *stream, register N_KEYSEG *keyseg, const uchar *key)
key=end; key=end;
break; break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
VOID(fprintf(stream,"%d",sint3korr(key))); VOID(fprintf(stream,"%ld",sint3korr(key)));
key=end; key=end;
break; break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
......
...@@ -284,7 +284,7 @@ static struct option long_options[] = ...@@ -284,7 +284,7 @@ static struct option long_options[] =
static void print_version(void) static void print_version(void)
{ {
printf("%s Ver 5.15 for %s at %s\n",my_progname,SYSTEM_TYPE, printf("%s Ver 5.16 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE); MACHINE_TYPE);
} }
...@@ -1793,6 +1793,9 @@ my_string name; ...@@ -1793,6 +1793,9 @@ my_string name;
if (share->base.options & HA_OPTION_COMPRESS_RECORD) if (share->base.options & HA_OPTION_COMPRESS_RECORD)
printf(" Huff tree Bits"); printf(" Huff tree Bits");
VOID(putchar('\n')); VOID(putchar('\n'));
if (verbose > 2 && share->base.pack_bits)
printf("- %-7d%-35s\n",share->base.pack_bits,"bit field");
start=1; start=1;
for (field=0 ; field < share->base.fields ; field++) for (field=0 ; field < share->base.fields ; field++)
{ {
...@@ -2806,6 +2809,11 @@ static int sort_get_next_record() ...@@ -2806,6 +2809,11 @@ static int sort_get_next_record()
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (!searching)
{
print_info("Found wrong packed record at %lu",
(ulong) sort_info.start_recpos);
}
try_next: try_next:
pos=sort_info.start_recpos+1; pos=sort_info.start_recpos+1;
searching=1; searching=1;
......
...@@ -2342,6 +2342,9 @@ static int sort_get_next_record(SORT_INFO *sort_info) ...@@ -2342,6 +2342,9 @@ static int sort_get_next_record(SORT_INFO *sort_info)
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (!searching)
mi_check_print_info(param,"Found wrong stored record at %s",
llstr(sort_info->start_recpos,llbuff));
try_next: try_next:
pos=(sort_info->start_recpos+=MI_DYN_ALIGN_SIZE); pos=(sort_info->start_recpos+=MI_DYN_ALIGN_SIZE);
searching=1; searching=1;
......
...@@ -241,7 +241,7 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov ...@@ -241,7 +241,7 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
#-- #--
wait_for_server_start () wait_for_server_start ()
{ {
$MYSQLADMIN --no-defaults -u $DBUSER --silent -w2 --host=$hostname --port=$1 ping >/dev/null $MYSQLADMIN --no-defaults -u $DBUSER --silent -O connect_timeout=10 -w2 --host=$hostname --port=$1 ping >/dev/null 2>&1
} }
prompt_user () prompt_user ()
......
...@@ -237,7 +237,7 @@ static inline void link_file_to_changed(SEC_LINK *next) ...@@ -237,7 +237,7 @@ static inline void link_file_to_changed(SEC_LINK *next)
#endif #endif
#ifndef DBUG_OFF #ifndef DBUG_OFF
static void test_key_cache(char *where, my_bool lock); static void test_key_cache(const char *where, my_bool lock);
#endif #endif
...@@ -622,9 +622,10 @@ int flush_key_blocks(File file, enum flush_type type) ...@@ -622,9 +622,10 @@ int flush_key_blocks(File file, enum flush_type type)
/* Test if disk-cachee is ok */ /* Test if disk-cachee is ok */
static void test_key_cache(char *where, my_bool lock) static void test_key_cache(const char *where, my_bool lock)
{ {
reg1 uint i,found,error,changed; reg1 uint i,error;
ulong found,changed;
SEC_LINK *pos,**prev; SEC_LINK *pos,**prev;
if (lock) if (lock)
...@@ -642,13 +643,13 @@ static void test_key_cache(char *where, my_bool lock) ...@@ -642,13 +643,13 @@ static void test_key_cache(char *where, my_bool lock)
error=1; error=1;
DBUG_PRINT("error", DBUG_PRINT("error",
("hash: %d pos: %lx : prev: %lx != pos->prev: %lx", ("hash: %d pos: %lx : prev: %lx != pos->prev: %lx",
i,pos,prev,pos->prev_hash)); i,(ulong) pos,(ulong) prev,(ulong) pos->prev_hash));
} }
if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i) if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i)
{ {
DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld", DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld",
i,pos,pos->diskpos)); i,(ulong) pos,(ulong) pos->diskpos));
error=1; error=1;
} }
} }
...@@ -667,7 +668,7 @@ static void test_key_cache(char *where, my_bool lock) ...@@ -667,7 +668,7 @@ static void test_key_cache(char *where, my_bool lock)
pos= _my_hash_root[i]; found=0; pos= _my_hash_root[i]; found=0;
while (pos && found < 10) while (pos && found < 10)
{ {
DBUG_PRINT("loop",("pos: %lx prev: %lx next: %lx file: %d disk_buffer: %ld", pos,pos->prev_hash,pos->next_hash,pos->file,pos->diskpos)); DBUG_PRINT("loop",("pos: %lx prev: %lx next: %lx file: %d disk_buffer: %ld", (ulong) pos, (ulong) pos->prev_hash, (ulong) pos->next_hash, (ulong) pos->file, (ulong) pos->diskpos));
found++; pos= pos->next_hash; found++; pos= pos->next_hash;
} }
} }
...@@ -685,7 +686,9 @@ static void test_key_cache(char *where, my_bool lock) ...@@ -685,7 +686,9 @@ static void test_key_cache(char *where, my_bool lock)
if (pos->next_used->prev_used != pos) if (pos->next_used->prev_used != pos)
{ {
DBUG_PRINT("error",("pos: %lx next_used: %lx next_used->prev: %lx", DBUG_PRINT("error",("pos: %lx next_used: %lx next_used->prev: %lx",
pos,pos->next_used,pos->next_used->prev_hash)); (ulong) pos,
(ulong) pos->next_used,
(ulong) pos->next_used->prev_hash));
error=1; error=1;
} }
pos=pos->next_used; pos=pos->next_used;
...@@ -696,7 +699,7 @@ static void test_key_cache(char *where, my_bool lock) ...@@ -696,7 +699,7 @@ static void test_key_cache(char *where, my_bool lock)
} }
if (found != _my_blocks_used) if (found != _my_blocks_used)
{ {
DBUG_PRINT("error",("Found %d of %d keyblocks",found,_my_blocks_used)); DBUG_PRINT("error",("Found %lu of %lu keyblocks",found,_my_blocks_used));
error=1; error=1;
} }
...@@ -751,7 +754,7 @@ static void test_key_cache(char *where, my_bool lock) ...@@ -751,7 +754,7 @@ static void test_key_cache(char *where, my_bool lock)
} }
if (changed != 0) if (changed != 0)
{ {
DBUG_PRINT("error",("Found %d blocks that wasn't in changed blocks", DBUG_PRINT("error",("Found %lu blocks that wasn't in changed blocks",
changed)); changed));
error=1; error=1;
} }
......
...@@ -36,7 +36,7 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome. ...@@ -36,7 +36,7 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome.
# Documentation continued at end of file # Documentation continued at end of file
my $VERSION = "1.10"; my $VERSION = "1.11";
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
...@@ -65,6 +65,8 @@ Usage: $0 db_name [new_db_name | directory] ...@@ -65,6 +65,8 @@ Usage: $0 db_name [new_db_name | directory]
--suffix=# suffix for names of copied databases --suffix=# suffix for names of copied databases
--checkpoint=# insert checkpoint entry into specified db.table --checkpoint=# insert checkpoint entry into specified db.table
--flushlog flush logs once all tables are locked --flushlog flush logs once all tables are locked
--resetmaster reset the binlog once all tables are locked
--resetslave reset the master.info once all tables are locked
--tmpdir=# temporary directory (instead of $opt_tmpdir) --tmpdir=# temporary directory (instead of $opt_tmpdir)
Try 'perldoc $0 for more complete documentation' Try 'perldoc $0 for more complete documentation'
...@@ -100,6 +102,8 @@ GetOptions( \%opt, ...@@ -100,6 +102,8 @@ GetOptions( \%opt,
"suffix=s", "suffix=s",
"checkpoint=s", "checkpoint=s",
"flushlog", "flushlog",
"resetmaster",
"resetslave",
"tmpdir|t=s", "tmpdir|t=s",
"dryrun|n", "dryrun|n",
) or usage("Invalid option"); ) or usage("Invalid option");
...@@ -369,6 +373,8 @@ if ( $opt{dryrun} ) { ...@@ -369,6 +373,8 @@ if ( $opt{dryrun} ) {
print "LOCK TABLES $hc_locks\n"; print "LOCK TABLES $hc_locks\n";
print "FLUSH TABLES /*!32323 $hc_tables */\n"; print "FLUSH TABLES /*!32323 $hc_tables */\n";
print "FLUSH LOGS\n" if ( $opt{flushlog} ); print "FLUSH LOGS\n" if ( $opt{flushlog} );
print "RESET MASTER\n" if ( $opt{resetmaster} );
print "RESET SLAVE\n" if ( $opt{resetslave} );
} }
else { else {
my $start = time; my $start = time;
...@@ -381,6 +387,8 @@ else { ...@@ -381,6 +387,8 @@ else {
$dbh->do("FLUSH TABLES /*!32323 $hc_tables */"); $dbh->do("FLUSH TABLES /*!32323 $hc_tables */");
printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet}; printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet};
$dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} ); $dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} );
$dbh->do( "RESET MASTER" ) if ( $opt{resetmaster} );
$dbh->do( "RESET SLAVE" ) if ( $opt{resetslave} );
} }
my @failed = (); my @failed = ();
...@@ -658,6 +666,18 @@ of keeping the backup directory after the copy successfully completes. ...@@ -658,6 +666,18 @@ of keeping the backup directory after the copy successfully completes.
Rotate the log files by executing "FLUSH LOGS" after all tables are Rotate the log files by executing "FLUSH LOGS" after all tables are
locked, and before they are copied. locked, and before they are copied.
=item --resetmaster
Reset the bin-log by executing "RESET MASTER" after all tables are
locked, and before they are copied. Usefull if you are recovering a
slave in a replication setup.
=item --resetslave
Reset the master.info by executing "RESET SLAVE" after all tables are
locked, and before they are copied. Usefull if you are recovering a
server in a mutual replication setup.
=item --regexp pattern =item --regexp pattern
Copy all databases with names matching the pattern Copy all databases with names matching the pattern
...@@ -742,6 +762,7 @@ Study the code inside this script and only rely on it if I<you> believe ...@@ -742,6 +762,7 @@ Study the code inside this script and only rely on it if I<you> believe
that it does the right thing for you. that it does the right thing for you.
Patches adding bug fixes, documentation and new features are welcome. Patches adding bug fixes, documentation and new features are welcome.
Please send these to internals@mysql.com.
=head1 TO DO =head1 TO DO
...@@ -780,3 +801,6 @@ Monty - working --noindex (copy only first 2048 bytes of index file) ...@@ -780,3 +801,6 @@ Monty - working --noindex (copy only first 2048 bytes of index file)
Fixes for --method=scp Fixes for --method=scp
Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again. Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again.
Emil S. Hansen - Added resetslave and resetmaster.
...@@ -152,8 +152,9 @@ sub merge_limits ...@@ -152,8 +152,9 @@ sub merge_limits
{ {
foreach $name (split(",",$cmp)) foreach $name (split(",",$cmp))
{ {
$tmp_server= get_server($name,$opt_host, $opt_database, $tmp_server= (get_server($name,$opt_host, $opt_database,
$opt_odbc) || die "Unknown SQL server: $name\n"; $opt_odbc,machine_part())
|| die "Unknown SQL server: $name\n");
$limits=$tmp_server->{'limits'}; $limits=$tmp_server->{'limits'};
%new_limits=(); %new_limits=();
foreach $limit (keys(%$limits)) foreach $limit (keys(%$limits))
...@@ -365,11 +366,13 @@ sub print_time ...@@ -365,11 +366,13 @@ sub print_time
sub machine_part sub machine_part
{ {
my ($name); my ($name,$orig);
return $opt_machine if (length($opt_machine)); # Specified by user return $opt_machine if (length($opt_machine)); # Specified by user
$name=machine(); # Specified by user
$name="win9$1" if ($name =~ /win.*9(\d)/i); $orig=$name=machine();
$name="NT_$1" if ($name =~ /Windows NT.*(\d+\.\d+)/i); $name="win9$1" if ($orig =~ /win.*9(\d)/i);
$name="NT_$1" if ($orig =~ /Windows NT.*(\d+\.\d+)/i);
$name="win2k" if ($orig =~ /Windows 2000/i);
$name =~ s/\s+/_/g; # Make the filenames easier to parse $name =~ s/\s+/_/g; # Make the filenames easier to parse
$name =~ s/-/_/g; $name =~ s/-/_/g;
$name =~ s/\//_/g; $name =~ s/\//_/g;
......
...@@ -59,6 +59,10 @@ const char *ha_row_type[] = { ...@@ -59,6 +59,10 @@ const char *ha_row_type[] = {
TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"", TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
ha_table_type+1}; ha_table_type+1};
const char *tx_isolation_names[] =
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE"};
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names),"",
tx_isolation_names};
/* Use other database handler if databasehandler is not incompiled */ /* Use other database handler if databasehandler is not incompiled */
...@@ -203,6 +207,7 @@ int ha_autocommit_or_rollback(THD *thd, int error) ...@@ -203,6 +207,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
} }
else else
(void) ha_rollback_stmt(thd); (void) ha_rollback_stmt(thd);
thd->tx_isolation=thd->session_tx_isolation;
} }
#endif #endif
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -248,6 +253,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -248,6 +253,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#endif #endif
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open()) if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
sql_print_error("Error: Got error during commit; Binlog is not up to date!"); sql_print_error("Error: Got error during commit; Binlog is not up to date!");
thd->tx_isolation=thd->session_tx_isolation;
} }
#endif // using transactions #endif // using transactions
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -286,11 +292,22 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) ...@@ -286,11 +292,22 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
reinit_io_cache(&thd->transaction.trans_log, reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1); WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size; thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
thd->tx_isolation=thd->session_tx_isolation;
} }
#endif /* USING_TRANSACTIONS */ #endif /* USING_TRANSACTIONS */
DBUG_RETURN(error); DBUG_RETURN(error);
} }
void ha_set_spin_retries(uint retries)
{
#ifdef HAVE_GEMINI_DB
if (!gemini_skip)
{
gemini_set_option_long(GEM_OPTID_SPIN_RETRIES, retries);
}
#endif /* HAVE_GEMINI_DB */
}
bool ha_flush_logs() bool ha_flush_logs()
{ {
......
...@@ -108,7 +108,7 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, ...@@ -108,7 +108,7 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM, DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM, DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM, DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
DB_TYPE_BERKELEY_DB, DB_TYPE_INNOBASE, DB_TYPE_BERKELEY_DB, DB_TYPE_INNOBASE, DB_TYPE_GEMINI,
DB_TYPE_DEFAULT }; DB_TYPE_DEFAULT };
enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
...@@ -127,6 +127,9 @@ typedef struct st_thd_trans { ...@@ -127,6 +127,9 @@ typedef struct st_thd_trans {
void *gemini_tid; void *gemini_tid;
} THD_TRANS; } THD_TRANS;
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
typedef struct st_ha_create_information typedef struct st_ha_create_information
{ {
ulong table_options; ulong table_options;
...@@ -310,7 +313,7 @@ class handler :public Sql_alloc ...@@ -310,7 +313,7 @@ class handler :public Sql_alloc
/* Some extern variables used with handlers */ /* Some extern variables used with handlers */
extern const char *ha_row_type[]; extern const char *ha_row_type[];
extern TYPELIB ha_table_typelib; extern TYPELIB ha_table_typelib, tx_isolation_typelib;
/* Wrapper functions */ /* Wrapper functions */
#define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt))) #define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt)))
...@@ -332,5 +335,6 @@ void ha_key_cache(void); ...@@ -332,5 +335,6 @@ void ha_key_cache(void);
int ha_commit_trans(THD *thd, THD_TRANS *trans); int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans);
int ha_autocommit_or_rollback(THD *thd, int error); int ha_autocommit_or_rollback(THD *thd, int error);
void ha_set_spin_retries(uint retries);
bool ha_flush_logs(void); bool ha_flush_logs(void);
...@@ -218,23 +218,22 @@ String *Item_func_concat_ws::val_str(String *str) ...@@ -218,23 +218,22 @@ String *Item_func_concat_ws::val_str(String *str)
goto null; goto null;
use_as_buff= &tmp_value; use_as_buff= &tmp_value;
str->length(0); str->length(0); // QQ; Should be removed
res=str; res=str;
// Skip until non-null and non-empty argument is found. // Skip until non-null and non-empty argument is found.
// If not, return the empty string // If not, return the empty string
for (i=0; !(res= args[i]->val_str(str)) || !res->length(); i++) for (i=0;
{ !(res= args[i]->val_str(str)) || !res->length() && i < arg_count;
if ((i + 1) == arg_count) i++) ;
if (i == arg_count)
return &empty_string; return &empty_string;
}
for (i++; i < arg_count ; i++) for (i++; i < arg_count ; i++)
{ {
if (!(res2= args[i]->val_str(use_as_buff)) || !res2->length()) if (!(res2= args[i]->val_str(use_as_buff)) || !res2->length())
continue; continue; // Skipp NULL and empty string
else
{
if (res->length() + sep_str->length() + res2->length() > if (res->length() + sep_str->length() + res2->length() >
max_allowed_packet) max_allowed_packet)
goto null; // Error check goto null; // Error check
...@@ -290,7 +289,6 @@ String *Item_func_concat_ws::val_str(String *str) ...@@ -290,7 +289,6 @@ String *Item_func_concat_ws::val_str(String *str)
use_as_buff=str; use_as_buff=str;
} }
} }
}
return res; return res;
null: null:
......
...@@ -86,6 +86,7 @@ static SYMBOL symbols[] = { ...@@ -86,6 +86,7 @@ static SYMBOL symbols[] = {
{ "COLUMNS", SYM(COLUMNS),0,0}, { "COLUMNS", SYM(COLUMNS),0,0},
{ "COMMENT", SYM(COMMENT_SYM),0,0}, { "COMMENT", SYM(COMMENT_SYM),0,0},
{ "COMMIT", SYM(COMMIT_SYM),0,0}, { "COMMIT", SYM(COMMIT_SYM),0,0},
{ "COMMITTED", SYM(COMMITTED_SYM),0,0},
{ "COMPRESSED", SYM(COMPRESSED_SYM),0,0}, { "COMPRESSED", SYM(COMPRESSED_SYM),0,0},
{ "CONSTRAINT", SYM(CONSTRAINT),0,0}, { "CONSTRAINT", SYM(CONSTRAINT),0,0},
{ "CREATE", SYM(CREATE),0,0}, { "CREATE", SYM(CREATE),0,0},
...@@ -144,6 +145,8 @@ static SYMBOL symbols[] = { ...@@ -144,6 +145,8 @@ static SYMBOL symbols[] = {
{ "FULL", SYM(FULL),0,0}, { "FULL", SYM(FULL),0,0},
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0}, { "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
{ "FUNCTION", SYM(UDF_SYM),0,0}, { "FUNCTION", SYM(UDF_SYM),0,0},
{ "GEMINI", SYM(GEMINI_SYM),0,0},
{ "GLOBAL", SYM(GLOBAL_SYM),0,0},
{ "GRANT", SYM(GRANT),0,0}, { "GRANT", SYM(GRANT),0,0},
{ "GRANTS", SYM(GRANTS),0,0}, { "GRANTS", SYM(GRANTS),0,0},
{ "GROUP", SYM(GROUP),0,0}, { "GROUP", SYM(GROUP),0,0},
...@@ -174,6 +177,7 @@ static SYMBOL symbols[] = { ...@@ -174,6 +177,7 @@ static SYMBOL symbols[] = {
{ "INTO", SYM(INTO),0,0}, { "INTO", SYM(INTO),0,0},
{ "IF", SYM(IF),0,0}, { "IF", SYM(IF),0,0},
{ "IS", SYM(IS),0,0}, { "IS", SYM(IS),0,0},
{ "ISOLATION", SYM(ISOLATION),0,0},
{ "ISAM", SYM(ISAM_SYM),0,0}, { "ISAM", SYM(ISAM_SYM),0,0},
{ "JOIN", SYM(JOIN_SYM),0,0}, { "JOIN", SYM(JOIN_SYM),0,0},
{ "KEY", SYM(KEY_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0},
...@@ -182,6 +186,7 @@ static SYMBOL symbols[] = { ...@@ -182,6 +186,7 @@ static SYMBOL symbols[] = {
{ "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0}, { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
{ "LEADING", SYM(LEADING),0,0}, { "LEADING", SYM(LEADING),0,0},
{ "LEFT", SYM(LEFT),0,0}, { "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0},
{ "LIKE", SYM(LIKE),0,0}, { "LIKE", SYM(LIKE),0,0},
{ "LINES", SYM(LINES),0,0}, { "LINES", SYM(LINES),0,0},
{ "LIMIT", SYM(LIMIT),0,0}, { "LIMIT", SYM(LIMIT),0,0},
...@@ -212,6 +217,7 @@ static SYMBOL symbols[] = { ...@@ -212,6 +217,7 @@ static SYMBOL symbols[] = {
{ "MIN_ROWS", SYM(MIN_ROWS),0,0}, { "MIN_ROWS", SYM(MIN_ROWS),0,0},
{ "MINUTE", SYM(MINUTE_SYM),0,0}, { "MINUTE", SYM(MINUTE_SYM),0,0},
{ "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM),0,0}, { "MINUTE_SECOND", SYM(MINUTE_SECOND_SYM),0,0},
{ "MODE", SYM(MODE_SYM),0,0},
{ "MODIFY", SYM(MODIFY_SYM),0,0}, { "MODIFY", SYM(MODIFY_SYM),0,0},
{ "MONTH", SYM(MONTH_SYM),0,0}, { "MONTH", SYM(MONTH_SYM),0,0},
{ "MRG_MYISAM", SYM(MERGE_SYM),0,0}, { "MRG_MYISAM", SYM(MERGE_SYM),0,0},
...@@ -252,6 +258,7 @@ static SYMBOL symbols[] = { ...@@ -252,6 +258,7 @@ static SYMBOL symbols[] = {
{ "RENAME", SYM(RENAME),0,0}, { "RENAME", SYM(RENAME),0,0},
{ "REPAIR", SYM(REPAIR),0,0}, { "REPAIR", SYM(REPAIR),0,0},
{ "REPLACE", SYM(REPLACE),0,0}, { "REPLACE", SYM(REPLACE),0,0},
{ "REPEATABLE", SYM(REPEATABLE_SYM),0,0},
{ "RESET", SYM(RESET_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0},
{ "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0},
{ "RESTRICT", SYM(RESTRICT),0,0}, { "RESTRICT", SYM(RESTRICT),0,0},
...@@ -264,7 +271,10 @@ static SYMBOL symbols[] = { ...@@ -264,7 +271,10 @@ static SYMBOL symbols[] = {
{ "ROWS", SYM(ROWS_SYM),0,0}, { "ROWS", SYM(ROWS_SYM),0,0},
{ "SECOND", SYM(SECOND_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0},
{ "SELECT", SYM(SELECT_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0},
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
{ "SESSION", SYM(SESSION_SYM),0,0},
{ "SET", SYM(SET),0,0}, { "SET", SYM(SET),0,0},
{ "SHARE", SYM(SHARE_SYM),0,0},
{ "SHOW", SYM(SHOW),0,0}, { "SHOW", SYM(SHOW),0,0},
{ "SHUTDOWN", SYM(SHUTDOWN),0,0}, { "SHUTDOWN", SYM(SHUTDOWN),0,0},
{ "SLAVE", SYM(SLAVE),0,0}, { "SLAVE", SYM(SLAVE),0,0},
...@@ -305,9 +315,11 @@ static SYMBOL symbols[] = { ...@@ -305,9 +315,11 @@ static SYMBOL symbols[] = {
{ "TINYTEXT", SYM(TINYTEXT),0,0}, { "TINYTEXT", SYM(TINYTEXT),0,0},
{ "TINYINT", SYM(TINYINT),0,0}, { "TINYINT", SYM(TINYINT),0,0},
{ "TRAILING", SYM(TRAILING),0,0}, { "TRAILING", SYM(TRAILING),0,0},
{ "TRANSACTION", SYM(TRANSACTION_SYM),0,0},
{ "TRUNCATE", SYM(TRUNCATE_SYM),0,0}, { "TRUNCATE", SYM(TRUNCATE_SYM),0,0},
{ "TO", SYM(TO_SYM),0,0}, { "TO", SYM(TO_SYM),0,0},
{ "TYPE", SYM(TYPE_SYM),0,0}, { "TYPE", SYM(TYPE_SYM),0,0},
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM),0,0},
{ "UNION", SYM(UNION_SYM),0,0}, { "UNION", SYM(UNION_SYM),0,0},
{ "UNIQUE", SYM(UNIQUE_SYM),0,0}, { "UNIQUE", SYM(UNIQUE_SYM),0,0},
{ "UNLOCK", SYM(UNLOCK_SYM),0,0}, { "UNLOCK", SYM(UNLOCK_SYM),0,0},
......
...@@ -251,6 +251,7 @@ void kill_mysql(void); ...@@ -251,6 +251,7 @@ void kill_mysql(void);
void close_connection(NET *net,uint errcode=0,bool lock=1); void close_connection(NET *net,uint errcode=0,bool lock=1);
bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0, bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0,
bool no_grant=0); bool no_grant=0);
bool check_process_priv(THD *thd=0);
int generate_table(THD *thd, TABLE_LIST *table_list, int generate_table(THD *thd, TABLE_LIST *table_list,
TABLE *locked_table); TABLE *locked_table);
...@@ -538,6 +539,7 @@ extern String empty_string; ...@@ -538,6 +539,7 @@ extern String empty_string;
extern struct show_var_st init_vars[]; extern struct show_var_st init_vars[];
extern struct show_var_st status_vars[]; extern struct show_var_st status_vars[];
extern enum db_type default_table_type; extern enum db_type default_table_type;
extern enum enum_tx_isolation default_tx_isolation;
#ifndef __WIN__ #ifndef __WIN__
extern pthread_t signal_thread; extern pthread_t signal_thread;
......
...@@ -278,6 +278,7 @@ char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; ...@@ -278,6 +278,7 @@ char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first"; const char *first_keyword="first";
const char **errmesg; /* Error messages */ const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF"; const char *myisam_recover_options_str="OFF";
enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
my_string mysql_unix_port=NULL,mysql_tmpdir=NULL; my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */ ulong my_bind_addr; /* the address we bind to */
DATE_FORMAT dayord; DATE_FORMAT dayord;
...@@ -2426,7 +2427,7 @@ enum options { ...@@ -2426,7 +2427,7 @@ enum options {
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT,
OPT_SAFE_SHOW_DB, OPT_SAFE_SHOW_DB,
OPT_GEMINI_SKIP, OPT_INNOBASE_SKIP, OPT_GEMINI_SKIP, OPT_INNOBASE_SKIP,
OPT_TEMP_POOL OPT_TEMP_POOL, OPT_TX_ISOLATION
}; };
static struct option long_options[] = { static struct option long_options[] = {
...@@ -2553,6 +2554,7 @@ static struct option long_options[] = { ...@@ -2553,6 +2554,7 @@ static struct option long_options[] = {
#ifdef __WIN__ #ifdef __WIN__
{"standalone", no_argument, 0, (int) OPT_STANDALONE}, {"standalone", no_argument, 0, (int) OPT_STANDALONE},
#endif #endif
{"transaction-isolation", required_argument, 0, (int) OPT_TX_ISOLATION},
{"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL}, {"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL},
{"tmpdir", required_argument, 0, 't'}, {"tmpdir", required_argument, 0, 't'},
{"use-locking", no_argument, 0, (int) OPT_USE_LOCKING}, {"use-locking", no_argument, 0, (int) OPT_USE_LOCKING},
...@@ -2946,6 +2948,8 @@ static void usage(void) ...@@ -2946,6 +2948,8 @@ static void usage(void)
Don't give threads different priorities.\n\ Don't give threads different priorities.\n\
--socket=... Socket file to use for connection\n\ --socket=... Socket file to use for connection\n\
-t, --tmpdir=path Path for temporary files\n\ -t, --tmpdir=path Path for temporary files\n\
--transaction-isolation\n\
Default transaction isolation level\n\
--temp-pool Use a pool of temporary files\n\ --temp-pool Use a pool of temporary files\n\
-u, --user=user_name Run mysqld daemon as user\n\ -u, --user=user_name Run mysqld daemon as user\n\
-V, --version output version information and exit"); -V, --version output version information and exit");
...@@ -3080,6 +3084,7 @@ static void get_options(int argc,char **argv) ...@@ -3080,6 +3084,7 @@ static void get_options(int argc,char **argv)
case 'a': case 'a':
opt_ansi_mode=1; opt_ansi_mode=1;
thd_startup_options|=OPTION_ANSI_MODE; thd_startup_options|=OPTION_ANSI_MODE;
default_tx_isolation= ISO_SERIALIZABLE;
break; break;
case 'b': case 'b':
strmov(mysql_home,optarg); strmov(mysql_home,optarg);
...@@ -3455,6 +3460,17 @@ static void get_options(int argc,char **argv) ...@@ -3455,6 +3460,17 @@ static void get_options(int argc,char **argv)
charsets_dir = mysql_charsets_dir; charsets_dir = mysql_charsets_dir;
break; break;
#include "sslopt-case.h" #include "sslopt-case.h"
case OPT_TX_ISOLATION:
{
int type;
if ((type=find_type(optarg, &tx_isolation_typelib, 2)) <= 0)
{
fprintf(stderr,"Unknown transaction isolation type: %s\n",optarg);
exit(1);
}
default_tx_isolation= (enum_tx_isolation) (type-1);
break;
}
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
case OPT_BDB_LOG: case OPT_BDB_LOG:
berkeley_logdir=optarg; berkeley_logdir=optarg;
......
...@@ -79,50 +79,59 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -79,50 +79,59 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
insert_id_used(0),in_lock_tables(0), insert_id_used(0),in_lock_tables(0),
global_read_lock(0),bootstrap(0) global_read_lock(0),bootstrap(0)
{ {
proc_info="login";
where="field list";
host=user=priv_user=db=query=ip=0; host=user=priv_user=db=query=ip=0;
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
query_start_used=0; query_start_used=0;
query_length=col_access=0; query_length=col_access=0;
query_error=0; query_error=0;
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
pthread_mutex_init(&active_vio_lock, NULL);
#endif
server_id = ::server_id;
server_status=SERVER_STATUS_AUTOCOMMIT;
next_insert_id=last_insert_id=0; next_insert_id=last_insert_id=0;
open_tables=temporary_tables=0; open_tables=temporary_tables=0;
tmp_table=0; tmp_table=0;
lock=locked_tables=0; lock=locked_tables=0;
used_tables=0; used_tables=0;
gemini_spin_retries=0;
cuted_fields=sent_row_count=0L; cuted_fields=sent_row_count=0L;
options=thd_startup_options;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
start_time=(time_t) 0; start_time=(time_t) 0;
current_linfo = 0; current_linfo = 0;
slave_thread = 0; slave_thread = 0;
slave_proxy_id = 0; slave_proxy_id = 0;
last_nx_table = last_nx_db = 0; last_nx_table = last_nx_db = 0;
cond_count=0;
convert_set=0;
mysys_var=0;
net.vio=0;
ull=0;
system_thread=0;
#ifdef __WIN__
real_id = 0;
#endif
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
pthread_mutex_init(&active_vio_lock, NULL);
#endif
/* Variables with default values */
proc_info="login";
where="field list";
server_id = ::server_id;
server_status=SERVER_STATUS_AUTOCOMMIT;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
options=thd_startup_options;
inactive_timeout=net_wait_timeout; inactive_timeout=net_wait_timeout;
open_options=ha_open_options; open_options=ha_open_options;
cond_count=0; tx_isolation=session_tx_isolation=default_tx_isolation;
command=COM_CONNECT; command=COM_CONNECT;
set_query_id=1; set_query_id=1;
default_select_limit= HA_POS_ERROR; default_select_limit= HA_POS_ERROR;
max_join_size= ((::max_join_size != ~ (ulong) 0L) ? ::max_join_size : max_join_size= ((::max_join_size != ~ (ulong) 0L) ? ::max_join_size :
HA_POS_ERROR); HA_POS_ERROR);
convert_set=0;
mysys_var=0;
db_access=NO_ACCESS; db_access=NO_ACCESS;
/* Initialize sub structures */
bzero((char*) &mem_root,sizeof(mem_root));
hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0, hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key, (hash_get_key) get_var_key,
(void (*)(void*)) free_var,0); (void (*)(void*)) free_var,0);
net.vio=0;
ull=0;
system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root));
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
if (opt_using_transactions) if (opt_using_transactions)
{ {
...@@ -134,10 +143,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -134,10 +143,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
transaction.trans_log.end_of_file= max_binlog_cache_size; transaction.trans_log.end_of_file= max_binlog_cache_size;
} }
#endif #endif
#ifdef __WIN__
real_id = 0 ;
#endif
} }
THD::~THD() THD::~THD()
......
...@@ -268,7 +268,8 @@ class THD :public ilink { ...@@ -268,7 +268,8 @@ class THD :public ilink {
long dbug_thread_id; long dbug_thread_id;
pthread_t real_id; pthread_t real_id;
uint current_tablenr,tmp_table,cond_count,col_access,query_length; uint current_tablenr,tmp_table,cond_count,col_access,query_length;
uint server_status,open_options; uint server_status,open_options, gemini_spin_retries;
enum_tx_isolation tx_isolation, session_tx_isolation;
char scramble[9]; char scramble[9];
bool slave_thread; bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted; bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
......
...@@ -139,7 +139,9 @@ typedef struct st_lex { ...@@ -139,7 +139,9 @@ typedef struct st_lex {
enum_sql_command sql_command; enum_sql_command sql_command;
enum lex_states next_state; enum lex_states next_state;
enum enum_duplicates duplicates; enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default; uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
uint gemini_spin_retries;
thr_lock_type lock_option; thr_lock_type lock_option;
bool create_refs,drop_primary,drop_if_exists,local_file; bool create_refs,drop_primary,drop_if_exists,local_file;
bool in_comment,ignore_space,verbose; bool in_comment,ignore_space,verbose;
......
...@@ -971,7 +971,7 @@ bool do_command(THD *thd) ...@@ -971,7 +971,7 @@ bool do_command(THD *thd)
send_ok(net); // Tell client we are alive send_ok(net); // Tell client we are alive
break; break;
case COM_PROCESS_INFO: case COM_PROCESS_INFO:
if (!thd->priv_user[0] && check_access(thd,PROCESS_ACL,any_db)) if (!thd->priv_user[0] && check_process_priv(thd))
break; break;
mysql_log.write(thd,command,NullS); mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS : mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
...@@ -984,7 +984,7 @@ bool do_command(THD *thd) ...@@ -984,7 +984,7 @@ bool do_command(THD *thd)
break; break;
} }
case COM_DEBUG: case COM_DEBUG:
if (check_access(thd,PROCESS_ACL,any_db)) if (check_process_priv(thd))
break; /* purecov: inspected */ break; /* purecov: inspected */
mysql_print_status(thd); mysql_print_status(thd);
mysql_log.write(thd,command,NullS); mysql_log.write(thd,command,NullS);
...@@ -1110,12 +1110,16 @@ mysql_execute_command(void) ...@@ -1110,12 +1110,16 @@ mysql_execute_command(void)
#endif #endif
break; break;
} }
else
if (lex->options & SELECT_HIGH_PRIORITY)
{ {
/*
Normal select:
Change lock if we are using SELECT HIGH PRIORITY,
FOR UPDATE or IN SHARE MODE
*/
TABLE_LIST *table; TABLE_LIST *table;
for (table = tables ; table ; table=table->next) for (table = tables ; table ; table=table->next)
table->lock_type=TL_READ_HIGH_PRIORITY; table->lock_type= lex->lock_option;
} }
if (!(res=open_and_lock_tables(thd,tables))) if (!(res=open_and_lock_tables(thd,tables)))
...@@ -1141,7 +1145,7 @@ mysql_execute_command(void) ...@@ -1141,7 +1145,7 @@ mysql_execute_command(void)
} }
case SQLCOM_PURGE: case SQLCOM_PURGE:
{ {
if(check_access(thd, PROCESS_ACL, any_db)) if (check_process_priv(thd))
goto error; goto error;
res = purge_master_logs(thd, lex->to_log); res = purge_master_logs(thd, lex->to_log);
break; break;
...@@ -1174,14 +1178,14 @@ mysql_execute_command(void) ...@@ -1174,14 +1178,14 @@ mysql_execute_command(void)
} }
case SQLCOM_SHOW_SLAVE_STAT: case SQLCOM_SHOW_SLAVE_STAT:
{ {
if(check_access(thd, PROCESS_ACL, any_db)) if (check_process_priv(thd))
goto error; goto error;
res = show_master_info(thd); res = show_master_info(thd);
break; break;
} }
case SQLCOM_SHOW_MASTER_STAT: case SQLCOM_SHOW_MASTER_STAT:
{ {
if (check_access(thd, PROCESS_ACL, any_db)) if (check_process_priv(thd))
goto error; goto error;
res = show_binlog_info(thd); res = show_binlog_info(thd);
break; break;
...@@ -1414,7 +1418,7 @@ mysql_execute_command(void) ...@@ -1414,7 +1418,7 @@ mysql_execute_command(void)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
#else #else
{ {
if(check_access(thd, PROCESS_ACL, any_db)) if (check_process_priv(thd))
goto error; goto error;
res = show_binlogs(thd); res = show_binlogs(thd);
break; break;
...@@ -1632,13 +1636,13 @@ mysql_execute_command(void) ...@@ -1632,13 +1636,13 @@ mysql_execute_command(void)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
#else #else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) && if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
check_access(thd,PROCESS_ACL,any_db)) check_process_priv(thd))
goto error; goto error;
res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS)); res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS));
break; break;
#endif #endif
case SQLCOM_SHOW_PROCESSLIST: case SQLCOM_SHOW_PROCESSLIST:
if (!thd->priv_user[0] && check_access(thd,PROCESS_ACL,any_db)) if (!thd->priv_user[0] && check_process_priv(thd))
break; break;
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS : mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
thd->priv_user,lex->verbose); thd->priv_user,lex->verbose);
...@@ -1778,6 +1782,12 @@ mysql_execute_command(void) ...@@ -1778,6 +1782,12 @@ mysql_execute_command(void)
thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ? thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
TL_WRITE_LOW_PRIORITY : TL_WRITE); TL_WRITE_LOW_PRIORITY : TL_WRITE);
thd->default_select_limit=lex->select_limit; thd->default_select_limit=lex->select_limit;
thd->tx_isolation=lex->tx_isolation;
if (thd->gemini_spin_retries != lex->gemini_spin_retries)
{
thd->gemini_spin_retries= lex->gemini_spin_retries;
ha_set_spin_retries(thd->gemini_spin_retries);
}
DBUG_PRINT("info",("options: %ld limit: %ld", DBUG_PRINT("info",("options: %ld limit: %ld",
thd->options,(long) thd->default_select_limit)); thd->options,(long) thd->default_select_limit));
...@@ -2092,6 +2102,12 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv, ...@@ -2092,6 +2102,12 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
} }
bool check_process_priv(THD *thd)
{
return (check_access(thd ? thd : current_thd,PROCESS_ACL,any_db));
}
/* /*
** Check the privilege for all used tables. Table privileges are cached ** Check the privilege for all used tables. Table privileges are cached
** in the table list for GRANT checking ** in the table list for GRANT checking
......
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_acl.h" #include "sql_acl.h"
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
/* Return 0 if row hasn't changed */ /* Return 0 if row hasn't changed */
static bool compare_record(TABLE *table, ulong query_id) static bool compare_record(TABLE *table, ulong query_id)
......
...@@ -54,6 +54,7 @@ inline Item *or_or_concat(Item* A, Item* B) ...@@ -54,6 +54,7 @@ inline Item *or_or_concat(Item* A, Item* B)
Key::Keytype key_type; Key::Keytype key_type;
enum db_type db_type; enum db_type db_type;
enum row_type row_type; enum row_type row_type;
enum enum_tx_isolation tx_isolation;
String *string; String *string;
key_part_spec *key_part; key_part_spec *key_part;
TABLE_LIST *table_list; TABLE_LIST *table_list;
...@@ -141,6 +142,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -141,6 +142,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token CASCADE %token CASCADE
%token CHECKSUM_SYM %token CHECKSUM_SYM
%token CHECK_SYM %token CHECK_SYM
%token COMMITTED_SYM
%token COLUMNS %token COLUMNS
%token COLUMN_SYM %token COLUMN_SYM
%token CONSTRAINT %token CONSTRAINT
...@@ -166,6 +168,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -166,6 +168,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FROM %token FROM
%token FULL %token FULL
%token FULLTEXT_SYM %token FULLTEXT_SYM
%token GEMINI_SYM
%token GEMINI_SPIN_RETRIES
%token GLOBAL_SYM
%token GRANT %token GRANT
%token GRANTS %token GRANTS
%token GREATEST_SYM %token GREATEST_SYM
...@@ -183,12 +188,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -183,12 +188,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token INNOBASE_SYM %token INNOBASE_SYM
%token INTO %token INTO
%token IN_SYM %token IN_SYM
%token ISOLATION
%token ISAM_SYM %token ISAM_SYM
%token JOIN_SYM %token JOIN_SYM
%token KEYS %token KEYS
%token KEY_SYM %token KEY_SYM
%token LEADING %token LEADING
%token LEAST_SYM %token LEAST_SYM
%token LEVEL_SYM
%token LEX_HOSTNAME %token LEX_HOSTNAME
%token LIKE %token LIKE
%token LINES %token LINES
...@@ -244,6 +251,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -244,6 +251,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token REGEXP %token REGEXP
%token RELOAD %token RELOAD
%token RENAME %token RENAME
%token REPEATABLE_SYM
%token RESTORE_SYM %token RESTORE_SYM
%token RESTRICT %token RESTRICT
%token REVOKE %token REVOKE
...@@ -251,6 +259,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -251,6 +259,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ROW_FORMAT_SYM %token ROW_FORMAT_SYM
%token ROW_SYM %token ROW_SYM
%token SET %token SET
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SHUTDOWN %token SHUTDOWN
%token STARTING %token STARTING
%token STATUS_SYM %token STATUS_SYM
...@@ -262,6 +272,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -262,6 +272,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token TEXT_STRING %token TEXT_STRING
%token TO_SYM %token TO_SYM
%token TRAILING %token TRAILING
%token TRANSACTION_SYM
%token TYPE_SYM %token TYPE_SYM
%token FUNC_ARG0 %token FUNC_ARG0
%token FUNC_ARG1 %token FUNC_ARG1
...@@ -270,6 +281,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -270,6 +281,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UDF_RETURNS_SYM %token UDF_RETURNS_SYM
%token UDF_SONAME_SYM %token UDF_SONAME_SYM
%token UDF_SYM %token UDF_SYM
%token UNCOMMITTED_SYM
%token UNION_SYM %token UNION_SYM
%token UNIQUE_SYM %token UNIQUE_SYM
%token USAGE %token USAGE
...@@ -361,6 +373,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -361,6 +373,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MAKE_SET_SYM %token MAKE_SET_SYM
%token MINUTE_SECOND_SYM %token MINUTE_SECOND_SYM
%token MINUTE_SYM %token MINUTE_SYM
%token MODE_SYM
%token MODIFY_SYM %token MODIFY_SYM
%token MONTH_SYM %token MONTH_SYM
%token NOW_SYM %token NOW_SYM
...@@ -372,6 +385,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -372,6 +385,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token RIGHT %token RIGHT
%token ROUND %token ROUND
%token SECOND_SYM %token SECOND_SYM
%token SHARE_SYM
%token SUBSTRING %token SUBSTRING
%token SUBSTRING_INDEX %token SUBSTRING_INDEX
%token TRIM %token TRIM
...@@ -484,6 +498,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -484,6 +498,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <row_type> row_types %type <row_type> row_types
%type <tx_isolation> tx_isolation isolation_types
%type <udf_type> udf_func_type %type <udf_type> udf_func_type
%type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword %type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword
...@@ -750,6 +766,7 @@ table_types: ...@@ -750,6 +766,7 @@ table_types:
| HEAP_SYM { $$= DB_TYPE_HEAP; } | HEAP_SYM { $$= DB_TYPE_HEAP; }
| BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; }
| INNOBASE_SYM { $$= DB_TYPE_INNOBASE; } | INNOBASE_SYM { $$= DB_TYPE_INNOBASE; }
| GEMINI_SYM { $$= DB_TYPE_GEMINI; }
row_types: row_types:
DEFAULT { $$= ROW_TYPE_DEFAULT; } DEFAULT { $$= ROW_TYPE_DEFAULT; }
...@@ -1216,9 +1233,10 @@ select: ...@@ -1216,9 +1233,10 @@ select:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_SELECT; lex->sql_command= SQLCOM_SELECT;
lex->lock_option=TL_READ;
mysql_init_select(lex); mysql_init_select(lex);
} }
select_options select_item_list select_into select_options select_item_list select_into select_lock_type
select_into: select_into:
/* empty */ /* empty */
...@@ -1240,13 +1258,20 @@ select_option_list: ...@@ -1240,13 +1258,20 @@ select_option_list:
select_option: select_option:
STRAIGHT_JOIN { Lex->options|= SELECT_STRAIGHT_JOIN; } STRAIGHT_JOIN { Lex->options|= SELECT_STRAIGHT_JOIN; }
| HIGH_PRIORITY { Lex->options|= SELECT_HIGH_PRIORITY; } | HIGH_PRIORITY { Lex->lock_option= TL_READ_HIGH_PRIORITY; }
| DISTINCT { Lex->options|= SELECT_DISTINCT; } | DISTINCT { Lex->options|= SELECT_DISTINCT; }
| SQL_SMALL_RESULT { Lex->options|= SELECT_SMALL_RESULT; } | SQL_SMALL_RESULT { Lex->options|= SELECT_SMALL_RESULT; }
| SQL_BIG_RESULT { Lex->options|= SELECT_BIG_RESULT; } | SQL_BIG_RESULT { Lex->options|= SELECT_BIG_RESULT; }
| SQL_BUFFER_RESULT { Lex->options|= OPTION_BUFFER_RESULT; } | SQL_BUFFER_RESULT { Lex->options|= OPTION_BUFFER_RESULT; }
| ALL {} | ALL {}
select_lock_type:
/* empty */
| FOR_SYM UPDATE_SYM
{ Lex->lock_option= TL_WRITE; }
| IN_SYM SHARE_SYM MODE_SYM
{ Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; }
select_item_list: select_item_list:
select_item_list ',' select_item select_item_list ',' select_item
| select_item | select_item
...@@ -2124,8 +2149,10 @@ opt_low_priority: ...@@ -2124,8 +2149,10 @@ opt_low_priority:
delete: delete:
DELETE_SYM DELETE_SYM
{ Lex->sql_command= SQLCOM_DELETE; Lex->options=0; {
Lex->lock_option= current_thd->update_lock_default; } Lex->sql_command= SQLCOM_DELETE; Lex->options=0;
Lex->lock_option= current_thd->update_lock_default;
}
opt_delete_options FROM table opt_delete_options FROM table
where_clause delete_limit_clause where_clause delete_limit_clause
...@@ -2479,6 +2506,7 @@ keyword: ...@@ -2479,6 +2506,7 @@ keyword:
| AGAINST {} | AGAINST {}
| AGGREGATE_SYM {} | AGGREGATE_SYM {}
| AUTOCOMMIT {} | AUTOCOMMIT {}
| AUTO_INC {}
| AVG_ROW_LENGTH {} | AVG_ROW_LENGTH {}
| AVG_SYM {} | AVG_SYM {}
| BACKUP_SYM {} | BACKUP_SYM {}
...@@ -2491,6 +2519,7 @@ keyword: ...@@ -2491,6 +2519,7 @@ keyword:
| CHECK_SYM {} | CHECK_SYM {}
| COMMENT_SYM {} | COMMENT_SYM {}
| COMMIT_SYM {} | COMMIT_SYM {}
| COMMITTED_SYM {}
| COMPRESSED_SYM {} | COMPRESSED_SYM {}
| DATA_SYM {} | DATA_SYM {}
| DATETIME {} | DATETIME {}
...@@ -2510,12 +2539,16 @@ keyword: ...@@ -2510,12 +2539,16 @@ keyword:
| FIXED_SYM {} | FIXED_SYM {}
| FLUSH_SYM {} | FLUSH_SYM {}
| GRANTS {} | GRANTS {}
| GEMINI_SYM {}
| GLOBAL_SYM {}
| HEAP_SYM {} | HEAP_SYM {}
| HOSTS_SYM {} | HOSTS_SYM {}
| HOUR_SYM {} | HOUR_SYM {}
| IDENTIFIED_SYM {} | IDENTIFIED_SYM {}
| ISOLATION {}
| ISAM_SYM {} | ISAM_SYM {}
| INNOBASE_SYM {} | INNOBASE_SYM {}
| LEVEL_SYM {}
| LOCAL_SYM {} | LOCAL_SYM {}
| LOGS_SYM {} | LOGS_SYM {}
| MAX_ROWS {} | MAX_ROWS {}
...@@ -2532,6 +2565,7 @@ keyword: ...@@ -2532,6 +2565,7 @@ keyword:
| MINUTE_SYM {} | MINUTE_SYM {}
| MIN_ROWS {} | MIN_ROWS {}
| MODIFY_SYM {} | MODIFY_SYM {}
| MODE_SYM {}
| MONTH_SYM {} | MONTH_SYM {}
| MYISAM_SYM {} | MYISAM_SYM {}
| NATIONAL_SYM {} | NATIONAL_SYM {}
...@@ -2550,6 +2584,7 @@ keyword: ...@@ -2550,6 +2584,7 @@ keyword:
| RAID_TYPE {} | RAID_TYPE {}
| RELOAD {} | RELOAD {}
| REPAIR {} | REPAIR {}
| REPEATABLE_SYM {}
| RESET_SYM {} | RESET_SYM {}
| RESTORE_SYM {} | RESTORE_SYM {}
| ROLLBACK_SYM {} | ROLLBACK_SYM {}
...@@ -2557,6 +2592,9 @@ keyword: ...@@ -2557,6 +2592,9 @@ keyword:
| ROW_FORMAT_SYM {} | ROW_FORMAT_SYM {}
| ROW_SYM {} | ROW_SYM {}
| SECOND_SYM {} | SECOND_SYM {}
| SERIALIZABLE_SYM {}
| SESSION_SYM {}
| SHARE_SYM {}
| SHUTDOWN {} | SHUTDOWN {}
| START_SYM {} | START_SYM {}
| STATUS_SYM {} | STATUS_SYM {}
...@@ -2564,11 +2602,13 @@ keyword: ...@@ -2564,11 +2602,13 @@ keyword:
| STRING_SYM {} | STRING_SYM {}
| TEMPORARY {} | TEMPORARY {}
| TEXT_SYM {} | TEXT_SYM {}
| TRANSACTION_SYM {}
| TRUNCATE_SYM {} | TRUNCATE_SYM {}
| TIMESTAMP {} | TIMESTAMP {}
| TIME_SYM {} | TIME_SYM {}
| TYPE_SYM {} | TYPE_SYM {}
| UDF_SYM {} | UDF_SYM {}
| UNCOMMITTED_SYM {}
| VARIABLES {} | VARIABLES {}
| WORK_SYM {} | WORK_SYM {}
| YEAR_SYM {} | YEAR_SYM {}
...@@ -2579,9 +2619,12 @@ keyword: ...@@ -2579,9 +2619,12 @@ keyword:
set: set:
SET opt_option SET opt_option
{ {
THD *thd=current_thd;
Lex->sql_command= SQLCOM_SET_OPTION; Lex->sql_command= SQLCOM_SET_OPTION;
Lex->options=current_thd->options; Lex->options=thd->options;
Lex->select_limit=current_thd->default_select_limit; Lex->select_limit=thd->default_select_limit;
Lex->gemini_spin_retries=thd->gemini_spin_retries;
Lex->tx_isolation=thd->tx_isolation;
} }
option_value_list option_value_list
...@@ -2601,6 +2644,7 @@ option_value: ...@@ -2601,6 +2644,7 @@ option_value:
else else
Lex->options|= $1; Lex->options|= $1;
} }
| set_isolation
| AUTOCOMMIT equal NUM | AUTOCOMMIT equal NUM
{ {
if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */ if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */
...@@ -2641,6 +2685,14 @@ option_value: ...@@ -2641,6 +2685,14 @@ option_value:
{ {
current_thd->next_insert_id=$3; current_thd->next_insert_id=$3;
} }
| GEMINI_SPIN_RETRIES equal ULONG_NUM
{
Lex->gemini_spin_retries= $3;
}
| GEMINI_SPIN_RETRIES equal DEFAULT
{
Lex->gemini_spin_retries= 1;
}
| CHAR_SYM SET IDENT | CHAR_SYM SET IDENT
{ {
CONVERT *tmp; CONVERT *tmp;
...@@ -2724,6 +2776,28 @@ set_option: ...@@ -2724,6 +2776,28 @@ set_option:
| SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; } | SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; }
| SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; } | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; }
set_isolation:
GLOBAL_SYM tx_isolation
{
if (check_process_priv())
YYABORT;
default_tx_isolation= $2;
}
| SESSION_SYM tx_isolation
{ current_thd->session_tx_isolation= $2; }
| tx_isolation
{ Lex->tx_isolation= $1; }
tx_isolation:
TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; }
isolation_types:
READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
| READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
| REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
| SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
/* Lock function */ /* Lock function */
lock: lock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment