Commit a6d7bfe4 authored by unknown's avatar unknown

Fixed <=>

Added mysqltest for <=>
Removed use of TAB in output from mysql-test-run


Docs/manual.texi:
  Changelog
client/mysqltest.c:
  Added missing argument;  Changed to use standard defines
mysql-test/README:
  Cleaned up
mysql-test/mysql-test-run.sh:
  Removed use of TAB in output
  (We are now also depening on sed)
sql/item_cmpfunc.cc:
  Fixed <=>
sql/item_cmpfunc.h:
  Fixed <=>
parent 139d8db8
......@@ -9232,7 +9232,6 @@ problems. @xref{Windows}.
If you are using BDB (Berkeley DB) tables, you should familiarize
yourself with the different BDB specific startup options. @xref{BDB start}.
@node Automatic start, Command-line options, Starting server, Post-installation
@subsection Starting and Stopping MySQL Automatically
@cindex starting, the server automatically
......@@ -28765,11 +28764,12 @@ connection and the server you are using. If you are running in the
the @code{mysql} variables that affect your queries.
@cindex @code{safe-mode} command
A useful startup option for beginners (introduced in @strong{MySQL} Version 3.23.11) is
@code{--safe-mode} (or @code{--i-am-a-dummy} for users that has at some
time done a @code{DELETE FROM table_name} but forgot the @code{WHERE}
clause. When using this option, @code{mysql} sends the following
command to the @strong{MySQL} server when opening the connection:
A useful startup option for beginners (introduced in @strong{MySQL}
Version 3.23.11) is @code{--safe-mode} (or @code{--i-am-a-dummy} for
users that has at some time done a @code{DELETE FROM table_name} but
forgot the @code{WHERE} clause. When using this option, @code{mysql}
sends the following command to the @strong{MySQL} server when opening
the connection:
@example
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
......@@ -39782,6 +39782,8 @@ though, so Version 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.29
@itemize @bullet
@item
Fixed bug in <=> operator.
@item
Fixed bug in @code{REPLACE} with BDB tables.
@item
@code{LPAD()} and @code{RPAD()} will shorten the result string if it's longer
......@@ -42,7 +42,6 @@
#include <errno.h>
#define MAX_QUERY 16384
#define MAX_RECORD_FILE 128
#define PAD_SIZE 128
#define MAX_CONS 1024
#define MAX_INCLUDE_DEPTH 16
......@@ -109,7 +108,7 @@ struct query
int first_word_len;
int abort_on_error;
uint expected_errno;
char record_file[MAX_RECORD_FILE];
char record_file[FN_REFLEN];
enum {Q_CONNECTION, Q_QUERY, Q_CONNECT,
Q_SLEEP, Q_INC, Q_DEC,Q_SOURCE,
Q_DISCONNECT,Q_LET, Q_ECHO, Q_WHILE, Q_END_BLOCK,
......@@ -928,6 +927,7 @@ void usage()
-P, --port=... Port number to use for connection.\n\
-S, --socket=... Socket file to use for connection.\n\
-r, --record Record output of test_file into result file.\n\
-R, --result-file=... Store result in this file\n\
-v, --verbose Write more.\n\
-q, --quiet, --silent Suppress all normal output.\n\
-V, --version Output version information and exit.\n\n");
......@@ -1024,22 +1024,21 @@ char* safe_str_append(char* buf, const char* str, int size)
void str_to_file(const char* fname, char* str, int size)
{
int fd;
if((fd = my_open(fname, O_WRONLY|O_CREAT, MYF(MY_WME))) < 0)
if((fd = my_open(fname, O_WRONLY|O_CREAT, MYF(MY_WME | MY_FFNF))) < 0)
die("Could not open %s: errno = %d", fname, errno);
if(my_write(fd, (byte*)str, size, MYF(MY_WME|MY_NABP)))
if(my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP)))
die("write failed");
my_close(fd, MYF(0));
}
void reject_dump(const char* record_file, char* buf, int size)
{
char reject_file[MAX_RECORD_FILE+16];
char reject_file[FN_REFLEN];
char* p;
p = reject_file;
p = safe_str_append(p, record_file, sizeof(reject_file));
p = safe_str_append(p, (char*)".reject", reject_file - p +
sizeof(reject_file));
if (strlen(record_file) >= FN_REFLEN-8)
die("too long path name for reject");
strmov(strmov(reject_file, record_file),".reject");
str_to_file(reject_file, buf, size);
}
......
......@@ -16,14 +16,27 @@ You can create your own test cases. To create a test case:
in the file, put a set of SQL commands that will create some tables,
load test data, run some queries to manipulate it.
then do ./mysql-test-run -record test_case_name
and look at r/test_case_name.result - edit the result if necessary. If you
have to edit it, you have found a bug.
We would appreciate if the test tables were called t1, t2, t3 ... (to not
conflict too much with existing tables).
If you are using mysqltest commands (like result file names) in your
test case you should do create the result file as follows:
mysql-test-run --record < t/test_case_name.test
If you only have a simple test cases consistent of SQL commands and comments
you can create the test case one of the following ways:
mysql < t/test_case_name.test > r/test_case_name.result
mysql-test-run --record --record-file=r/test_case_name.result < t/test_case_name.test
When this is done, take a look at r/test_case_name.result
- If the result is wrong, you have found a bug; In this case you should
edit the test result to the correct results so that we can verify
that the bug is corrected in future releases.
To submit your test case, put your .test file and .result file(s) into
a tar.gz archive, add a README that explains the problem, ftp the
archive to ftp://support.mysql.com/pub/mysql/secret/ and send a mail
to bugs@lists.mysql.com
#! /bin/sh
# mysql-test-run - originally written by Matt Wagner <matt@mysql.com>
# modified by Sasha Pachev <sasha@mysql.com>
# Sligtly updated by Monty
#++
# Access Definitions
......@@ -23,9 +24,9 @@ else
if [ -f ./mysql-test-run ] && [ -d ../sql ] ; then
SOURCE_DIST=1
else
echo "If you are using binary distribution, run me from install root as \
scripts/mysql-test-run. On source distribution run me from source root as \
mysql-test/mysql-test-run or from mysql-test as ./mysql-test-run"
echo "If you are using binary distribution, run me from install root as"
echo "scripts/mysql-test-run. On source distribution run me from source root"
echo "as mysql-test/mysql-test-run or from mysql-test as ./mysql-test-run"
exit 1
fi
......@@ -44,6 +45,7 @@ BASEDIR=`pwd`
cd $CWD
MYSQL_TEST_DIR=$BASEDIR/mysql-test
STD_DATA=$MYSQL_TEST_DIR/std_data
SED=sed
TESTDIR="$MYSQL_TEST_DIR/t/"
TESTSUFFIX=test
......@@ -55,7 +57,6 @@ SYST=0
REALT=0
MY_TMP_DIR=$MYSQL_TEST_DIR/var/tmp
TIMEFILE="$MYSQL_TEST_DIR/var/tmp/mysqltest-time"
DASHBLANK="---- ---- -------"
RES_SPACE=" "
MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \
myisammrg heap sql"
......@@ -69,13 +70,7 @@ SLAVE_RUNNING=0
[ -z "$COLUMNS" ] && COLUMNS=80
E=`expr $COLUMNS - 8`
C=0
while [ $C != $E ]
do
DASH72="${DASH72}-"
C=`expr $C + 1`
done
DASH72=`expr substr '________________________________________________________________________' 1 $E`
#++
# mysqld Environment Parameters
......@@ -193,6 +188,10 @@ error () {
exit 1
}
prefix_to_8() {
echo " $1" | $SED -e 's:.*\(........\)$:\1:'
}
pass_inc () {
TOT_PASS=`$EXPR $TOT_PASS + 1`
}
......@@ -393,8 +392,7 @@ mysql_loadstd () {
run_testcase ()
{
tf=$1
tname=`$BASENAME $tf`
tname=`$ECHO $tname | $CUT -d . -f 1`
tname=`$BASENAME $tf .test`
master_opt_file=$TESTDIR/$tname-master.opt
slave_opt_file=$TESTDIR/$tname-slave.opt
slave_master_info_file=$TESTDIR/$tname-slave-master-info.opt
......@@ -459,23 +457,27 @@ run_testcase ()
mytime=`$CAT $TIMEFILE | $TR '\n' '-'`
USERT=`$ECHO $mytime | $CUT -d - -f 2 | $CUT -d ' ' -f 2`
USERT=`prefix_to_8 $USERT`
SYST=`$ECHO $mytime | $CUT -d - -f 3 | $CUT -d ' ' -f 2`
SYST=`prefix_to_8 $SYST`
REALT=`$ECHO $mytime | $CUT -d - -f 1 | $CUT -d ' ' -f 2`
REALT=`prefix_to_8 $REALT`
else
USERT="...."
SYST="...."
REALT="...."
USERT=" ...."
SYST=" ...."
REALT=" ...."
fi
timestr="$USERT $SYST $REALT"
outstr="$tname $timestr"
pname=`$EXPR substr "$tname " 1 16`
$SETCOLOR_NORMAL && $ECHO -n "$pname $timestr"
total_inc
if [ $res != 0 ]; then
fail_inc
echo "$outstr $RES_SPACE [ fail ]"
echo "$RES_SPACE [ fail ]"
$ECHO "failed output"
$CAT $TIMEFILE
$ECHO
......@@ -491,7 +493,7 @@ run_testcase ()
echo "Resuming Tests"
else
pass_inc
echo "$outstr $RES_SPACE [ pass ]"
echo "$RES_SPACE [ pass ]"
fi
fi
......
0<=>0 0.0<=>0.0 "A"<=>"A" NULL<=>NULL
1 1 1 1
1<=>0 0<=>NULL NULL<=>0
0 0 0
1.0<=>0.0 0.0<=>NULL NULL<=>0.0
0 0 0
"A"<=>"B" "A"<=>NULL NULL<=>"A"
0 0 0
id value id value t1.value<=>t2.value
1 NULL 1 NULL 1
id value
1 NULL
id value
1 NULL
id value
#
# Testing of the <=> operator
#
#
# First some simple tests
#
select 0<=>0,0.0<=>0.0,"A"<=>"A",NULL<=>NULL;
select 1<=>0,0<=>NULL,NULL<=>0;
select 1.0<=>0.0,0.0<=>NULL,NULL<=>0.0;
select "A"<=>"B","A"<=>NULL,NULL<=>"A";
#
# Test with tables
#
drop table if exists t1,t2;
create table t1 (id int, value int);
create table t2 (id int, value int);
insert into t1 values (1,null);
insert into t2 values (1,null);
select t1.*, t2.*, t1.value<=>t2.value from t1, t2 where t1.id=t2.id and t1.id=1;
select * from t1 where id <=>id;
select * from t1 where value <=> value;
select * from t1 where id <=> value or value<=>id;
drop table t1,t2;
......@@ -170,15 +170,44 @@ longlong Item_func_eq::val_int()
/* Same as Item_func_eq, but NULL = NULL */
void Item_func_equal::fix_length_and_dec()
{
Item_bool_func2::fix_length_and_dec();
result_type=item_cmp_type(args[0]->result_type(),args[1]->result_type());
maybe_null=null_value=0;
}
longlong Item_func_equal::val_int()
{
int value=(this->*cmp_func)();
if (null_value)
switch (result_type) {
case STRING_RESULT:
{
null_value=0;
return (args[0]->null_value && args[1]->null_value) ? 1 : 0;
String *res1,*res2;
res1=args[0]->val_str(&tmp_value1);
res2=args[1]->val_str(&tmp_value2);
if (!res1 || !res2)
return test(res1 == res2);
return (binary ? test(stringcmp(res1,res2) == 0) :
test(sortcmp(res1,res2) == 0));
}
case REAL_RESULT:
{
double val1=args[0]->val();
double val2=args[1]->val();
if (args[0]->null_value || args[1]->null_value)
return test(args[0]->null_value && args[1]->null_value);
return test(val1 == val2);
}
case INT_RESULT:
{
longlong val1=args[0]->val_int();
longlong val2=args[1]->val_int();
if (args[0]->null_value || args[1]->null_value)
return test(args[0]->null_value && args[1]->null_value);
return test(val1 == val2);
}
}
return value == 0;
return 0; // Impossible
}
......
......@@ -70,11 +70,11 @@ class Item_func_eq :public Item_bool_func2
class Item_func_equal :public Item_bool_func2
{
Item_result result_type;
public:
Item_func_equal(Item *a,Item *b) :Item_bool_func2(a,b) { };
longlong val_int();
void fix_length_and_dec()
{ Item_bool_func2::fix_length_and_dec() ; maybe_null=0; }
void fix_length_and_dec();
enum Functype functype() const { return EQUAL_FUNC; }
enum Functype rev_functype() const { return EQUAL_FUNC; }
cond_result eq_cmp_result() const { return COND_TRUE; }
......
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