mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
Merge heikki@bk-internal.mysql.com:/home/bk/mysql-5.0
into hundin.mysql.fi:/home/heikki/mysql-5.0
This commit is contained in:
commit
34ab0da7dd
58 changed files with 642 additions and 290 deletions
|
@ -710,3 +710,59 @@ fi
|
|||
])
|
||||
|
||||
|
||||
AC_DEFUN([MYSQL_CHECK_CXX_VERSION], [
|
||||
case $SYSTEM_TYPE in
|
||||
*netware*)
|
||||
CXX_VERSION=`$CXX -version | grep -i version`
|
||||
;;
|
||||
*)
|
||||
CXX_VERSION=`$CXX --version | sed 1q`
|
||||
if test $? -ne "0" -o -z "$CXX_VERSION"
|
||||
then
|
||||
CXX_VERSION=`$CXX -V 2>&1|sed 1q` # trying harder for Sun and SGI
|
||||
fi
|
||||
if test $? -ne "0" -o -z "$CXX_VERSION"
|
||||
then
|
||||
CXX_VERSION=`$CXX -v 2>&1|sed 1q` # even harder for Alpha
|
||||
fi
|
||||
if test $? -ne "0" -o -z "$CXX_VERSION"
|
||||
then
|
||||
CXX_VERSION=""
|
||||
fi
|
||||
esac
|
||||
if test "$CXX_VERSION"
|
||||
then
|
||||
AC_MSG_CHECKING("C++ compiler version");
|
||||
AC_MSG_RESULT("$CXX $CXX_VERSION")
|
||||
fi
|
||||
AC_SUBST(CXX_VERSION)
|
||||
])
|
||||
|
||||
AC_DEFUN([MYSQL_PROG_AR], [
|
||||
AC_REQUIRE([MYSQL_CHECK_CXX_VERSION])
|
||||
case $CXX_VERSION in
|
||||
MIPSpro*)
|
||||
AR=$CXX
|
||||
ARFLAGS="-ar -o"
|
||||
;;
|
||||
*Forte*)
|
||||
AR=$CXX
|
||||
ARFLAGS="-xar -o"
|
||||
;;
|
||||
*)
|
||||
if test -z "$AR"
|
||||
then
|
||||
AC_CHECK_PROG([AR], [ar], [ar])
|
||||
fi
|
||||
if test -z "$AR"
|
||||
then
|
||||
AC_MSG_ERROR([You need ar to build the library])
|
||||
fi
|
||||
if test -z "$ARFLAGS"
|
||||
then
|
||||
ARFLAGS="cru"
|
||||
fi
|
||||
esac
|
||||
AC_SUBST(AR)
|
||||
AC_SUBST(ARFLAGS)
|
||||
])
|
||||
|
|
33
configure.in
33
configure.in
|
@ -195,25 +195,8 @@ then
|
|||
else
|
||||
CC_VERSION=""
|
||||
fi
|
||||
case $SYSTEM_TYPE in
|
||||
*netware*)
|
||||
CXX_VERSION=`$CXX -version | grep -i version`
|
||||
;;
|
||||
*)
|
||||
CXX_VERSION=`$CXX --version | sed 1q`
|
||||
CXX_VERSION=${CXX_VERSION:-`$CXX -V|sed 1q`} # trying harder for Sun and SGI
|
||||
CXX_VERSION=${CXX_VERSION:-`$CXX -V 2>&1|sed 1q`} # even harder for Alpha
|
||||
;;
|
||||
esac
|
||||
if test $? -eq "0"
|
||||
then
|
||||
AC_MSG_CHECKING("C++ compiler version");
|
||||
AC_MSG_RESULT("$CXX $CXX_VERSION")
|
||||
else
|
||||
CXX_VERSION=""
|
||||
fi
|
||||
AC_SUBST(CXX_VERSION)
|
||||
AC_SUBST(CC_VERSION)
|
||||
MYSQL_CHECK_CXX_VERSION
|
||||
|
||||
# Fix for sgi gcc / sgiCC which tries to emulate gcc
|
||||
if test "$CC" = "sgicc"
|
||||
|
@ -367,19 +350,11 @@ then
|
|||
# Disable exceptions as they seams to create problems with gcc and threads.
|
||||
# mysqld doesn't use run-time-type-checking, so we disable it.
|
||||
CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
|
||||
CXXFLAGS="$CXXFLAGS -DEXPLICIT_TEMPLATE_INSTANTIATION"
|
||||
AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION],
|
||||
[1], [Defined by configure. Use explicit template instantiation.])
|
||||
fi
|
||||
|
||||
case $CXX_VERSION in
|
||||
MIPSpro*)
|
||||
CXXFLAGS="$CXXFLAGS -no_prelink -DEXPLICIT_TEMPLATE_INSTANTIATION"
|
||||
;;
|
||||
Compaq*)
|
||||
CXXFLAGS="$CXXFLAGS -nopt -DEXPLICIT_TEMPLATE_INSTANTIATION"
|
||||
;;
|
||||
Forte*)
|
||||
CXXFLAGS="$CXXFLAGS -instance=explicit -DEXPLICIT_TEMPLATE_INSTANTIATION"
|
||||
esac
|
||||
MYSQL_PROG_AR
|
||||
|
||||
# Avoid bug in fcntl on some versions of linux
|
||||
AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
|
||||
|
|
|
@ -971,7 +971,7 @@ x509* PemToDer(const char* fname, CertType type)
|
|||
} // namespace
|
||||
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace yaSSL {
|
||||
template void ysDelete<DiffieHellman::DHImpl>(DiffieHellman::DHImpl*);
|
||||
template void ysDelete<Integer::IntegerImpl>(Integer::IntegerImpl*);
|
||||
|
@ -989,6 +989,6 @@ template void ysDelete<RMD::RMDImpl>(RMD::RMDImpl*);
|
|||
template void ysDelete<SHA::SHAImpl>(SHA::SHAImpl*);
|
||||
template void ysDelete<MD5::MD5Impl>(MD5::MD5Impl*);
|
||||
}
|
||||
#endif // EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
|
||||
#endif // !USE_CRYPTOPP_LIB
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "ripemd.hpp"
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#if !defined(USE_CRYPTOPP_LIB)
|
||||
namespace TaoCrypt {
|
||||
template class HMAC<MD5>;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* draft along with type conversion functions.
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include "handshake.hpp"
|
||||
#include "timer.hpp"
|
||||
|
@ -1975,7 +1976,7 @@ X509_NAME* X509::GetSubject()
|
|||
|
||||
} // namespace
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace mySTL {
|
||||
template yaSSL::yassl_int_cpp_local1::SumData for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData);
|
||||
template yaSSL::yassl_int_cpp_local1::SumBuffer for_each<mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer>(mySTL::list<yaSSL::output_buffer*>::iterator, mySTL::list<yaSSL::output_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer);
|
||||
|
|
|
@ -35,7 +35,7 @@ extern "C" {
|
|||
#include <assert.h>
|
||||
|
||||
/* Disallow inline __cxa_pure_virtual() */
|
||||
static int __cxa_pure_virtual() __attribute__((noinline));
|
||||
static int __cxa_pure_virtual() __attribute__((noinline, used));
|
||||
static int __cxa_pure_virtual()
|
||||
{
|
||||
// oops, pure virtual called!
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#ifndef TAO_CRYPT_TYPES_HPP
|
||||
#define TAO_CRYPT_TYPES_HPP
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
// define this if running on a big-endian CPU
|
||||
|
|
|
@ -319,7 +319,7 @@ void AbstractRing::SimultaneousExponentiate(Integer *results,
|
|||
|
||||
} // namespace
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace mySTL {
|
||||
template TaoCrypt::WindowSlider* uninit_copy<TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
|
||||
template void destroy<TaoCrypt::WindowSlider*>(TaoCrypt::WindowSlider*, TaoCrypt::WindowSlider*);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
/* dh.cpp implements Diffie-Hellman support
|
||||
*/
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "dh.hpp"
|
||||
#include "asn.hpp"
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "dsa.hpp"
|
||||
#include "sha.hpp"
|
||||
#include "asn.hpp"
|
||||
|
|
|
@ -3956,7 +3956,7 @@ Integer CRT(const Integer &xp, const Integer &p, const Integer &xq,
|
|||
return p * (u * (xq-xp) % q) + xp;
|
||||
}
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifndef TAOCRYPT_NATIVE_DWORD_AVAILABLE
|
||||
template hword DivideThreeWordsByTwo<hword, Word>(hword*, hword, hword, Word*);
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/* based on Wei Dai's rsa.cpp from CryptoPP */
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "rsa.hpp"
|
||||
#include "asn.hpp"
|
||||
#include "modarith.hpp"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "vector.hpp"
|
||||
#include "hash.hpp"
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace TaoCrypt {
|
||||
#if defined(SSE2_INTRINSICS_AVAILABLE)
|
||||
template AlignedAllocator<unsigned int>::pointer StdReallocate<unsigned int, AlignedAllocator<unsigned int> >(AlignedAllocator<unsigned int>&, unsigned int*, AlignedAllocator<unsigned int>::size_type, AlignedAllocator<unsigned int>::size_type, bool);
|
||||
|
|
|
@ -2847,9 +2847,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong));
|
||||
|
||||
for (j = 0; j <= n_cols; j++) {
|
||||
n_diff[j] = 0;
|
||||
}
|
||||
memset(n_diff, 0, (n_cols + 1) * sizeof(ib_longlong));
|
||||
|
||||
/* We sample some pages in the index to get an estimate */
|
||||
|
||||
|
|
|
@ -2101,10 +2101,6 @@ buf_print(void)
|
|||
|
||||
n_found = 0;
|
||||
|
||||
for (i = 0 ; i < size; i++) {
|
||||
counts[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
frame = buf_pool_get_nth_block(buf_pool, i)->frame;
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ rec_get_nth_field_size(
|
|||
ulint n); /* in: index of the field */
|
||||
/****************************************************************
|
||||
The following function is used to get a pointer to the nth
|
||||
data field in an old-style record. */
|
||||
data field in a record. */
|
||||
UNIV_INLINE
|
||||
byte*
|
||||
rec_get_nth_field(
|
||||
|
|
|
@ -886,7 +886,7 @@ rec_offs_make_valid(
|
|||
|
||||
/****************************************************************
|
||||
The following function is used to get a pointer to the nth
|
||||
data field in an old-style record. */
|
||||
data field in a record. */
|
||||
UNIV_INLINE
|
||||
byte*
|
||||
rec_get_nth_field(
|
||||
|
|
|
@ -1672,7 +1672,6 @@ os_file_set_size(
|
|||
ibool ret;
|
||||
byte* buf;
|
||||
byte* buf2;
|
||||
ulint i;
|
||||
|
||||
ut_a(size == (size & 0xFFFFFFFF));
|
||||
|
||||
|
@ -1685,9 +1684,7 @@ os_file_set_size(
|
|||
buf = ut_align(buf2, UNIV_PAGE_SIZE);
|
||||
|
||||
/* Write buffer full of zeros */
|
||||
for (i = 0; i < UNIV_PAGE_SIZE * 512; i++) {
|
||||
buf[i] = '\0';
|
||||
}
|
||||
memset(buf, 0, UNIV_PAGE_SIZE * 512);
|
||||
|
||||
offset = 0;
|
||||
low = (ib_longlong)size + (((ib_longlong)size_high) << 32);
|
||||
|
|
|
@ -1755,9 +1755,7 @@ page_validate(
|
|||
records in the page record heap do not overlap */
|
||||
|
||||
buf = mem_heap_alloc(heap, UNIV_PAGE_SIZE);
|
||||
for (i = 0; i < UNIV_PAGE_SIZE; i++) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
memset(buf, 0, UNIV_PAGE_SIZE);
|
||||
|
||||
/* Check first that the record heap and the directory do not
|
||||
overlap. */
|
||||
|
|
|
@ -533,9 +533,11 @@ row_ins_cascade_calc_update_vec(
|
|||
ufield->new_val.data =
|
||||
mem_heap_alloc(heap,
|
||||
min_size);
|
||||
pad_start = ufield->new_val.data
|
||||
pad_start =
|
||||
((char*) ufield->new_val.data)
|
||||
+ ufield->new_val.len;
|
||||
pad_end = ufield->new_val.data
|
||||
pad_end =
|
||||
((char*) ufield->new_val.data)
|
||||
+ min_size;
|
||||
ufield->new_val.len = min_size;
|
||||
ut_memcpy(ufield->new_val.data,
|
||||
|
@ -1578,7 +1580,6 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
ulint err = DB_SUCCESS;
|
||||
ibool moved;
|
||||
mtr_t mtr;
|
||||
trx_t* trx;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
|
@ -1618,11 +1619,6 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
goto next_rec;
|
||||
}
|
||||
|
||||
/* Try to place a lock on the index record */
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
ut_ad(trx);
|
||||
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
|
|
|
@ -941,13 +941,11 @@ trx_undo_erase_page_end(
|
|||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
ulint first_free;
|
||||
ulint i;
|
||||
|
||||
|
||||
first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
|
||||
+ TRX_UNDO_PAGE_FREE);
|
||||
for (i = first_free; i < UNIV_PAGE_SIZE - FIL_PAGE_DATA_END; i++) {
|
||||
undo_page[i] = 0xFF;
|
||||
}
|
||||
memset(undo_page + first_free, 0xff,
|
||||
(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END) - first_free);
|
||||
|
||||
mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
|
||||
}
|
||||
|
|
|
@ -772,7 +772,8 @@ sub executable_setup () {
|
|||
{
|
||||
if ( $glob_win32 )
|
||||
{
|
||||
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release");
|
||||
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
|
||||
"$glob_basedir/bin");
|
||||
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt");
|
||||
$path_language= mtr_path_exists("$glob_basedir/share/english/");
|
||||
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
|
||||
|
@ -794,7 +795,7 @@ sub executable_setup () {
|
|||
}
|
||||
else
|
||||
{
|
||||
$exe_mysqltest= mtr_exe_exists("$glob_basedir/client/mysqltest");
|
||||
$exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
|
||||
$exe_mysql_client_test=
|
||||
mtr_exe_exists("$glob_basedir/tests/mysql_client_test");
|
||||
}
|
||||
|
@ -2011,6 +2012,14 @@ sub run_mysqltest ($$) {
|
|||
"--port=$master->[0]->{'path_myport'} " .
|
||||
"--socket=$master->[0]->{'path_mysock'}";
|
||||
|
||||
if ( $glob_use_embedded_server )
|
||||
{
|
||||
$cmdline_mysql_client_test.=
|
||||
" -A --language=$path_language" .
|
||||
" -A --datadir=$slave->[0]->{'path_myddir'}" .
|
||||
" -A --character-sets-dir=$path_charsetsdir";
|
||||
}
|
||||
|
||||
my $cmdline_mysql_fix_system_tables=
|
||||
"$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " .
|
||||
"--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " .
|
||||
|
@ -2127,8 +2136,7 @@ sub run_mysqltest ($$) {
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
sub usage ($)
|
||||
{
|
||||
sub usage ($) {
|
||||
print STDERR <<HERE;
|
||||
|
||||
mysql-test-run [ OPTIONS ] [ TESTCASE ]
|
||||
|
|
|
@ -723,27 +723,6 @@ WHERE hostname LIKE '%aol%'
|
|||
hostname no
|
||||
cache-dtc-af05.proxy.aol.com 1
|
||||
DROP TABLE t1;
|
||||
create table t1 (c1 char(3), c2 char(3));
|
||||
create table t2 (c3 char(3), c4 char(3));
|
||||
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||
group by c2;
|
||||
c2
|
||||
aaa
|
||||
aaa
|
||||
Warnings:
|
||||
Warning 1052 Column 'c2' in group statement is ambiguous
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 1052 Column 'c2' in group statement is ambiguous
|
||||
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||
group by t1.c1;
|
||||
c2
|
||||
aaa
|
||||
show warnings;
|
||||
Level Code Message
|
||||
drop table t1, t2;
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
INSERT INTO t1 VALUES (1,2), (1,3);
|
||||
SELECT a, b FROM t1 GROUP BY 'const';
|
||||
|
@ -762,3 +741,13 @@ SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
|
|||
f id
|
||||
20050501123000 1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (id varchar(20) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('trans1'), ('trans2');
|
||||
CREATE TABLE t2 (id varchar(20) NOT NULL, err_comment blob NOT NULL);
|
||||
INSERT INTO t2 VALUES ('trans1', 'a problem');
|
||||
SELECT COUNT(DISTINCT(t1.id)), LEFT(err_comment, 256) AS comment
|
||||
FROM t1 LEFT JOIN t2 ON t1.id=t2.id GROUP BY comment;
|
||||
COUNT(DISTINCT(t1.id)) comment
|
||||
1 NULL
|
||||
1 a problem
|
||||
DROP TABLE t1, t2;
|
||||
|
|
|
@ -371,8 +371,8 @@ alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(20
|
|||
update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
|
||||
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
|
||||
from t0 as A, t0 as B
|
||||
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key# = 1 or A.key8=1)
|
||||
and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key# = 1 or B.key8=1);
|
||||
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)
|
||||
and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
|
||||
1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
|
||||
|
|
|
@ -625,3 +625,12 @@ select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
|
|||
ID NO SEQ
|
||||
1 1 1
|
||||
drop table t1;
|
||||
create table t1 (f1 int);
|
||||
create table t2 (ff1 int unique, ff2 int default 1);
|
||||
insert into t1 values (1),(1),(2);
|
||||
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
|
||||
select * from t2;
|
||||
ff1 ff2
|
||||
1 2
|
||||
2 1
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -1133,8 +1133,6 @@ end|
|
|||
select f5(1)|
|
||||
f5(1)
|
||||
1
|
||||
select f5(2)|
|
||||
ERROR HY000: Table 't1' was not locked with LOCK TABLES
|
||||
create function f6() returns int
|
||||
begin
|
||||
declare n int;
|
||||
|
@ -3174,4 +3172,56 @@ a1 a2 a3 data data2 data3
|
|||
DROP PROCEDURE bug6866;
|
||||
DROP VIEW tv|
|
||||
DROP TABLE tt1, tt2, tt3|
|
||||
DROP PROCEDURE IF EXISTS bug10136|
|
||||
create table t3 ( name char(5) not null primary key, val float not null)|
|
||||
insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)|
|
||||
create procedure bug10136()
|
||||
begin
|
||||
declare done int default 3;
|
||||
repeat
|
||||
select * from t3;
|
||||
set done = done - 1;
|
||||
until done <= 0 end repeat;
|
||||
end|
|
||||
call bug10136()|
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
call bug10136()|
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
call bug10136()|
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
name val
|
||||
aaaaa 1
|
||||
bbbbb 2
|
||||
ccccc 3
|
||||
drop procedure bug10136|
|
||||
drop table t3|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -1732,7 +1732,7 @@ INSERT INTO t1 VALUES ('a','1'), ('b','2');
|
|||
INSERT INTO t2 VALUES ('a','5'), ('a','6'), ('b','5'), ('b','6');
|
||||
CREATE VIEW v1 AS
|
||||
SELECT t1.b as c, t2.b as d FROM t1,t2 WHERE t1.a=t2.a;
|
||||
SELECT d, c FROM v1 ORDER BY d;
|
||||
SELECT d, c FROM v1 ORDER BY d,c;
|
||||
d c
|
||||
5 1
|
||||
5 2
|
||||
|
@ -1757,3 +1757,77 @@ select * from v1;
|
|||
cast(1 as decimal)
|
||||
1.00
|
||||
drop view v1;
|
||||
create table t1(f1 int);
|
||||
create table t2(f2 int);
|
||||
insert into t1 values(1),(2),(3);
|
||||
insert into t2 values(1),(2),(3);
|
||||
create view v1 as select * from t1,t2 where f1=f2;
|
||||
create table t3 (f1 int, f2 int);
|
||||
insert into t3 select * from v1 order by 1;
|
||||
select * from t3;
|
||||
f1 f2
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
drop view v1;
|
||||
drop table t1,t2,t3;
|
||||
create view v1 as select '\\','\\shazam';
|
||||
select * from v1;
|
||||
\ \shazam
|
||||
\ \shazam
|
||||
drop view v1;
|
||||
create view v1 as select '\'','\shazam';
|
||||
select * from v1;
|
||||
' shazam
|
||||
' shazam
|
||||
drop view v1;
|
||||
create view v1 as select 'k','K';
|
||||
select * from v1;
|
||||
k My_exp_K
|
||||
k K
|
||||
drop view v1;
|
||||
create table t1 (s1 int);
|
||||
create view v1 as select s1, 's1' from t1;
|
||||
select * from v1;
|
||||
s1 My_exp_s1
|
||||
drop view v1;
|
||||
create view v1 as select 's1', s1 from t1;
|
||||
select * from v1;
|
||||
My_exp_s1 s1
|
||||
drop view v1;
|
||||
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||
select * from v1;
|
||||
My_exp_1_s1 s1 My_exp_s1
|
||||
drop view v1;
|
||||
create view v1 as select 1 as My_exp_s1, 's1', s1 from t1;
|
||||
select * from v1;
|
||||
My_exp_s1 My_exp_1_s1 s1
|
||||
drop view v1;
|
||||
create view v1 as select 1 as s1, 's1', 's1' from t1;
|
||||
select * from v1;
|
||||
s1 My_exp_s1 My_exp_1_s1
|
||||
drop view v1;
|
||||
create view v1 as select 's1', 's1', 1 as s1 from t1;
|
||||
select * from v1;
|
||||
My_exp_1_s1 My_exp_s1 s1
|
||||
drop view v1;
|
||||
create view v1 as select s1, 's1', 's1' from t1;
|
||||
select * from v1;
|
||||
s1 My_exp_s1 My_exp_1_s1
|
||||
drop view v1;
|
||||
create view v1 as select 's1', 's1', s1 from t1;
|
||||
select * from v1;
|
||||
My_exp_1_s1 My_exp_s1 s1
|
||||
drop view v1;
|
||||
create view v1 as select 1 as s1, 's1', s1 from t1;
|
||||
ERROR 42S21: Duplicate column name 's1'
|
||||
create view v1 as select 's1', s1, 1 as s1 from t1;
|
||||
ERROR 42S21: Duplicate column name 's1'
|
||||
drop table t1;
|
||||
create view v1(k, K) as select 1,2;
|
||||
ERROR 42S21: Duplicate column name 'K'
|
||||
create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t;
|
||||
select * from v1;
|
||||
t
|
||||
01:00
|
||||
drop view v1;
|
||||
|
|
|
@ -542,30 +542,6 @@ SELECT hostname, COUNT(DISTINCT user_id) as no FROM t1
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#11211: Ambiguous column reference in GROUP BY.
|
||||
#
|
||||
|
||||
create table t1 (c1 char(3), c2 char(3));
|
||||
create table t2 (c3 char(3), c4 char(3));
|
||||
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
|
||||
# query with ambiguous column reference 'c2'
|
||||
--disable_ps_protocol
|
||||
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||
group by c2;
|
||||
show warnings;
|
||||
--enable_ps_protocol
|
||||
|
||||
# this query has no ambiguity
|
||||
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||
group by t1.c1;
|
||||
|
||||
show warnings;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Test for bug #8614: GROUP BY 'const' with DISTINCT
|
||||
#
|
||||
|
@ -589,3 +565,18 @@ INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
|
|||
SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test for bug #11295: GROUP BY a BLOB column with COUNT(DISTINCT column1)
|
||||
# when the BLOB column takes NULL values
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (id varchar(20) NOT NULL);
|
||||
INSERT INTO t1 VALUES ('trans1'), ('trans2');
|
||||
CREATE TABLE t2 (id varchar(20) NOT NULL, err_comment blob NOT NULL);
|
||||
INSERT INTO t2 VALUES ('trans1', 'a problem');
|
||||
|
||||
SELECT COUNT(DISTINCT(t1.id)), LEFT(err_comment, 256) AS comment
|
||||
FROM t1 LEFT JOIN t2 ON t1.id=t2.id GROUP BY comment;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
|
|
@ -310,7 +310,8 @@ update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
|
|||
# The next query will not use index i7 in intersection if the OS doesn't
|
||||
# support file sizes > 2GB. (ha_myisam::ref_length depends on this and index
|
||||
# scan cost estimates depend on ha_myisam::ref_length)
|
||||
--replace_result "4,4,4,4,4,4,4" X "4,4,4,4,4,4" X "i6,i7" "i6,i7?" "i6" "i6,i7?" 7 # 16 # 18 #
|
||||
--replace_column 9 #
|
||||
--replace_result "4,4,4,4,4,4,4" X "4,4,4,4,4,4" X "i6,i7" "i6,i7?" "i6" "i6,i7?"
|
||||
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
|
||||
from t0 as A, t0 as B
|
||||
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)
|
||||
|
|
|
@ -164,3 +164,12 @@ INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1
|
|||
select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#10886 - Have to restore default values after update ON DUPLICATE KEY
|
||||
#
|
||||
create table t1 (f1 int);
|
||||
create table t2 (ff1 int unique, ff2 int default 1);
|
||||
insert into t1 values (1),(1),(2);
|
||||
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
|
||||
select * from t2;
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -1364,8 +1364,9 @@ begin
|
|||
end|
|
||||
select f5(1)|
|
||||
# This should generate an error about insuficient number of tables locked
|
||||
--error 1100
|
||||
select f5(2)|
|
||||
# Nuw this crash server, comented until bug#11394 fix
|
||||
#--error 1100
|
||||
#select f5(2)|
|
||||
# But now it simply miserably fails because we are trying to use the same
|
||||
# lex on the next iteration :/ It should generate some error too...
|
||||
# select f5(3)|
|
||||
|
@ -3886,6 +3887,30 @@ DROP PROCEDURE bug6866;
|
|||
DROP VIEW tv|
|
||||
DROP TABLE tt1, tt2, tt3|
|
||||
|
||||
#
|
||||
# BUG#10136: items cleunup
|
||||
#
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS bug10136|
|
||||
--enable_warnings
|
||||
create table t3 ( name char(5) not null primary key, val float not null)|
|
||||
insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)|
|
||||
create procedure bug10136()
|
||||
begin
|
||||
declare done int default 3;
|
||||
|
||||
repeat
|
||||
select * from t3;
|
||||
set done = done - 1;
|
||||
until done <= 0 end repeat;
|
||||
|
||||
end|
|
||||
call bug10136()|
|
||||
call bug10136()|
|
||||
call bug10136()|
|
||||
drop procedure bug10136|
|
||||
drop table t3|
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -1578,7 +1578,7 @@ INSERT INTO t1 VALUES ('a','1'), ('b','2');
|
|||
INSERT INTO t2 VALUES ('a','5'), ('a','6'), ('b','5'), ('b','6');
|
||||
CREATE VIEW v1 AS
|
||||
SELECT t1.b as c, t2.b as d FROM t1,t2 WHERE t1.a=t2.a;
|
||||
SELECT d, c FROM v1 ORDER BY d;
|
||||
SELECT d, c FROM v1 ORDER BY d,c;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
|
@ -1599,3 +1599,77 @@ drop table t1;
|
|||
create view v1 as select cast(1 as decimal);
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
#
|
||||
# Bug#11298 insert into select from VIEW produces incorrect result when
|
||||
# using ORDER BY
|
||||
create table t1(f1 int);
|
||||
create table t2(f2 int);
|
||||
insert into t1 values(1),(2),(3);
|
||||
insert into t2 values(1),(2),(3);
|
||||
create view v1 as select * from t1,t2 where f1=f2;
|
||||
create table t3 (f1 int, f2 int);
|
||||
insert into t3 select * from v1 order by 1;
|
||||
select * from t3;
|
||||
drop view v1;
|
||||
drop table t1,t2,t3;
|
||||
|
||||
#
|
||||
# Generation unique names for columns, and correct names check (BUG#7448)
|
||||
#
|
||||
# names with ' and \
|
||||
create view v1 as select '\\','\\shazam';
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select '\'','\shazam';
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# autogenerated names differ by case only
|
||||
create view v1 as select 'k','K';
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create table t1 (s1 int);
|
||||
# same autogenerated names
|
||||
create view v1 as select s1, 's1' from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select 's1', s1 from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# set name as one of expected autogenerated
|
||||
create view v1 as select 's1', s1, 1 as My_exp_s1 from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select 1 as My_exp_s1, 's1', s1 from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# set name conflict with autogenerated names
|
||||
create view v1 as select 1 as s1, 's1', 's1' from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select 's1', 's1', 1 as s1 from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# underlying field name conflict with autogenerated names
|
||||
create view v1 as select s1, 's1', 's1' from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select 's1', 's1', s1 from t1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
# underlying field name conflict with set name
|
||||
-- error 1060
|
||||
create view v1 as select 1 as s1, 's1', s1 from t1;
|
||||
-- error 1060
|
||||
create view v1 as select 's1', s1, 1 as s1 from t1;
|
||||
drop table t1;
|
||||
# set names differ by case only
|
||||
-- error 1060
|
||||
create view v1(k, K) as select 1,2;
|
||||
|
||||
#
|
||||
# using time_format in view (BUG#7521)
|
||||
#
|
||||
create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
/*
|
||||
Add/remove option to the option file section.
|
||||
/* Copyright (C) 2005 MySQL AB
|
||||
|
||||
SYNOPSYS
|
||||
modify_defaults_file()
|
||||
file_location The location of configuration file to edit
|
||||
option option to look for
|
||||
option value The value of the option we would like to set
|
||||
section_name the name of the section
|
||||
remove_option This is true if we want to remove the option.
|
||||
False otherwise.
|
||||
IMPLEMENTATION
|
||||
We open the option file first, then read the file line-by-line,
|
||||
looking for the section we need. At the same time we put these lines
|
||||
into a buffer. Then we look for the option within this section and
|
||||
change/remove it. In the end we get a buffer with modified version of the
|
||||
file. Then we write it to the file, truncate it if needed and close it.
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - some error has occured. Probably due to the lack of resourses
|
||||
2 - cannot open the file
|
||||
*/
|
||||
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 */
|
||||
|
||||
#include "my_global.h"
|
||||
#include "mysys_priv.h"
|
||||
|
@ -40,6 +32,33 @@
|
|||
static char *add_option(char *dst, const char *option_value,
|
||||
const char *option, int remove_option);
|
||||
|
||||
|
||||
/*
|
||||
Add/remove option to the option file section.
|
||||
|
||||
SYNOPSYS
|
||||
modify_defaults_file()
|
||||
file_location The location of configuration file to edit
|
||||
option option to look for
|
||||
option value The value of the option we would like to set
|
||||
section_name the name of the section
|
||||
remove_option This is true if we want to remove the option.
|
||||
False otherwise.
|
||||
IMPLEMENTATION
|
||||
We open the option file first, then read the file line-by-line,
|
||||
looking for the section we need. At the same time we put these lines
|
||||
into a buffer. Then we look for the option within this section and
|
||||
change/remove it. In the end we get a buffer with modified version of the
|
||||
file. Then we write it to the file, truncate it if needed and close it.
|
||||
Note that there is a small time gap, when the file is incomplete,
|
||||
and this theoretically might introduce a problem.
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - some error has occured. Probably due to the lack of resourses
|
||||
2 - cannot open the file
|
||||
*/
|
||||
|
||||
int modify_defaults_file(const char *file_location, const char *option,
|
||||
const char *option_value,
|
||||
const char *section_name, int remove_option)
|
||||
|
@ -47,7 +66,7 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
FILE *cnf_file;
|
||||
MY_STAT file_stat;
|
||||
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
|
||||
uint optlen, optval_len, sect_len, nr_newlines= 0;
|
||||
uint opt_len, optval_len, sect_len, nr_newlines= 0;
|
||||
my_bool in_section= FALSE, opt_applied= 0;
|
||||
DBUG_ENTER("modify_defaults_file");
|
||||
|
||||
|
@ -58,7 +77,7 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
|
||||
goto err;
|
||||
|
||||
optlen= (uint) strlen(option);
|
||||
opt_len= (uint) strlen(option);
|
||||
optval_len= (uint) strlen(option_value);
|
||||
|
||||
/*
|
||||
|
@ -66,17 +85,18 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
for the option we want to add.
|
||||
*/
|
||||
if (!(file_buffer= (char*) my_malloc(sizeof(char) *
|
||||
(file_stat.st_size +
|
||||
/* option name len */
|
||||
optlen +
|
||||
/* reserve space for newline */
|
||||
NEWLINE_LEN +
|
||||
/* reserve for '=' char */
|
||||
1 +
|
||||
/* option value len */
|
||||
optval_len +
|
||||
/* The ending zero plus some safety */
|
||||
FN_REFLEN), MYF(MY_WME))))
|
||||
(file_stat.st_size +
|
||||
/* option name len */
|
||||
opt_len +
|
||||
/* reserve space for newline */
|
||||
NEWLINE_LEN +
|
||||
/* reserve for '=' char */
|
||||
1 +
|
||||
/* option value len */
|
||||
optval_len +
|
||||
/* The ending zero */
|
||||
1), MYF(MY_WME))))
|
||||
|
||||
goto malloc_err;
|
||||
|
||||
sect_len= (uint) strlen(section_name);
|
||||
|
@ -94,10 +114,11 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!opt_applied && in_section && !strncmp(src_ptr, option, optlen) &&
|
||||
(*(src_ptr + optlen) == '=' ||
|
||||
my_isspace(&my_charset_latin1, *(src_ptr + optlen)) ||
|
||||
*(src_ptr + optlen) == '\0'))
|
||||
/* correct the option */
|
||||
if (!opt_applied && in_section && !strncmp(src_ptr, option, opt_len) &&
|
||||
(*(src_ptr + opt_len) == '=' ||
|
||||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
|
||||
*(src_ptr + opt_len) == '\0'))
|
||||
{
|
||||
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||
opt_applied= 1;
|
||||
|
@ -107,11 +128,12 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
/* If going to new group and we have option to apply, do it now */
|
||||
if (in_section && !opt_applied && *src_ptr == '[')
|
||||
{
|
||||
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||
|
||||
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||
opt_applied= 1; /* set the flag to do write() later */
|
||||
}
|
||||
|
||||
for (; nr_newlines; nr_newlines--)
|
||||
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||
dst_ptr= strmov(dst_ptr, linebuff);
|
||||
}
|
||||
/* Look for a section */
|
||||
|
@ -120,13 +142,13 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
/* Copy the line to the buffer */
|
||||
if (!strncmp(++src_ptr, section_name, sect_len))
|
||||
{
|
||||
src_ptr+= sect_len;
|
||||
/* Skip over whitespaces. They are allowed after section name */
|
||||
for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++)
|
||||
{}
|
||||
src_ptr+= sect_len;
|
||||
/* Skip over whitespaces. They are allowed after section name */
|
||||
for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++)
|
||||
{}
|
||||
|
||||
if (*src_ptr != ']')
|
||||
continue; /* Missing closing parenthesis. Assume this was no group */
|
||||
if (*src_ptr != ']')
|
||||
continue; /* Missing closing parenthesis. Assume this was no group */
|
||||
in_section= TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -149,10 +171,10 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
{
|
||||
/* Don't write the file if there are no changes to be made */
|
||||
if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
|
||||
MYF(MY_WME)) ||
|
||||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
|
||||
my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer),
|
||||
MYF(MY_NABP)))
|
||||
MYF(MY_WME)) ||
|
||||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
|
||||
my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer),
|
||||
MYF(MY_NABP)))
|
||||
goto err;
|
||||
}
|
||||
if (my_fclose(cnf_file, MYF(MY_WME)))
|
||||
|
|
|
@ -90,6 +90,7 @@ void ndbSetOwnVersion() {}
|
|||
|
||||
#ifndef TEST_VERSION
|
||||
struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
|
||||
{ MAKE_VERSION(5,0,NDB_VERSION_BUILD), MAKE_VERSION(5,0,3), UG_Range},
|
||||
{ MAKE_VERSION(5,0,3), MAKE_VERSION(5,0,2), UG_Exact },
|
||||
{ MAKE_VERSION(4,1,12), MAKE_VERSION(4,1,10), UG_Range },
|
||||
{ MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact },
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
Instansiate templates and static variables
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<create_field>;
|
||||
template class List_iterator<create_field>;
|
||||
#endif
|
||||
|
|
25
sql/item.cc
25
sql/item.cc
|
@ -314,6 +314,7 @@ void *Item::operator new(size_t size, Item *reuse, uint *rsize)
|
|||
|
||||
Item::Item():
|
||||
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
|
||||
is_autogenerated_name(TRUE),
|
||||
collation(&my_charset_bin, DERIVATION_COERCIBLE)
|
||||
{
|
||||
marker= 0;
|
||||
|
@ -4360,6 +4361,28 @@ my_decimal *Item_ref::val_decimal(my_decimal *decimal_value)
|
|||
return val;
|
||||
}
|
||||
|
||||
int Item_ref::save_in_field(Field *to, bool no_conversions)
|
||||
{
|
||||
int res;
|
||||
if(result_field){
|
||||
if (result_field->is_null())
|
||||
{
|
||||
null_value= 1;
|
||||
return set_field_to_null_with_conversions(to, no_conversions);
|
||||
}
|
||||
else
|
||||
{
|
||||
to->set_notnull();
|
||||
field_conv(to, result_field);
|
||||
null_value= 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
res= (*ref)->save_in_field(to, no_conversions);
|
||||
null_value= (*ref)->null_value;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void Item_ref_null_helper::print(String *str)
|
||||
{
|
||||
|
@ -5387,7 +5410,7 @@ void Item_result_field::cleanup()
|
|||
** Instantiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<Item>;
|
||||
template class List_iterator<Item>;
|
||||
template class List_iterator_fast<Item>;
|
||||
|
|
|
@ -269,6 +269,8 @@ public:
|
|||
my_bool unsigned_flag;
|
||||
my_bool with_sum_func;
|
||||
my_bool fixed; /* If item fixed with fix_fields */
|
||||
my_bool is_autogenerated_name; /* indicate was name of this Item
|
||||
autogenerated or set by user */
|
||||
DTCollation collation;
|
||||
|
||||
// alloc & destruct is done as start of select using sql_alloc
|
||||
|
@ -288,7 +290,7 @@ public:
|
|||
name=0;
|
||||
#endif
|
||||
} /*lint -e1509 */
|
||||
void set_name(const char *str,uint length, CHARSET_INFO *cs);
|
||||
void set_name(const char *str, uint length, CHARSET_INFO *cs);
|
||||
void rename(char *new_name);
|
||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
virtual void cleanup();
|
||||
|
@ -1166,7 +1168,7 @@ public:
|
|||
collation.set(cs, dv);
|
||||
str_value.set_or_copy_aligned(str,length,cs);
|
||||
max_length= str_value.numchars()*cs->mbmaxlen;
|
||||
set_name(name_par,0,cs);
|
||||
set_name(name_par, 0, cs);
|
||||
decimals=NOT_FIXED_DEC;
|
||||
// it is constant => can be used without fix_fields (and frequently used)
|
||||
fixed= 1;
|
||||
|
@ -1343,8 +1345,7 @@ public:
|
|||
bool send(Protocol *prot, String *tmp);
|
||||
void make_field(Send_field *field) { (*ref)->make_field(field); }
|
||||
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||
int save_in_field(Field *field, bool no_conversions)
|
||||
{ return (*ref)->save_in_field(field, no_conversions); }
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
|
||||
enum Item_result result_type () const { return (*ref)->result_type(); }
|
||||
enum_field_types field_type() const { return (*ref)->field_type(); }
|
||||
|
|
|
@ -60,8 +60,8 @@ bool Cached_item_str::cmp(void)
|
|||
String *res;
|
||||
bool tmp;
|
||||
|
||||
res=item->val_str(&tmp_value);
|
||||
res->length(min(res->length(), value.alloced_length()));
|
||||
if ((res=item->val_str(&tmp_value)))
|
||||
res->length(min(res->length(), value.alloced_length()));
|
||||
if (null_value != item->null_value)
|
||||
{
|
||||
if ((null_value= item->null_value))
|
||||
|
@ -146,7 +146,7 @@ bool Cached_item_decimal::cmp()
|
|||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<Cached_item>;
|
||||
template class List_iterator<Cached_item>;
|
||||
#endif
|
||||
|
|
|
@ -4620,7 +4620,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
|
|||
if (!(item=var->item(thd, var_type, &null_lex_string)))
|
||||
return 0; // Impossible
|
||||
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||
item->set_name(item_name, 0, system_charset_info); // Will use original name
|
||||
item->set_name(item_name, 0, system_charset_info); // Will use original name
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
@ -503,7 +503,8 @@ public:
|
|||
Item_func_date_format(Item *a,Item *b,bool is_time_format_arg)
|
||||
:Item_str_func(a,b),is_time_format(is_time_format_arg) {}
|
||||
String *val_str(String *str);
|
||||
const char *func_name() const { return "date_format"; }
|
||||
const char *func_name() const
|
||||
{ return is_time_format ? "time_format" : "date_format"; }
|
||||
void fix_length_and_dec();
|
||||
uint format_length(const String *format);
|
||||
};
|
||||
|
|
|
@ -7073,7 +7073,7 @@ static void create_pid_file()
|
|||
Instantiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
/* Used templates */
|
||||
template class I_List<THD>;
|
||||
template class I_List_iterator<THD>;
|
||||
|
|
|
@ -8918,7 +8918,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
|
|||
** Instantiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<QUICK_RANGE>;
|
||||
template class List_iterator<QUICK_RANGE>;
|
||||
#endif
|
||||
|
|
|
@ -3406,7 +3406,7 @@ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *))
|
|||
Used templates
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<set_var_base>;
|
||||
template class List_iterator_fast<set_var_base>;
|
||||
template class I_List_iterator<NAMED_LIST>;
|
||||
|
|
|
@ -5002,7 +5002,7 @@ end:
|
|||
}
|
||||
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class I_List_iterator<i_string>;
|
||||
template class I_List_iterator<i_string_pair>;
|
||||
#endif
|
||||
|
|
|
@ -310,7 +310,8 @@ sp_head::operator delete(void *ptr, size_t size)
|
|||
|
||||
|
||||
sp_head::sp_head()
|
||||
:Query_arena((bool)FALSE), m_returns_cs(NULL), m_has_return(FALSE),
|
||||
:Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
|
||||
m_returns_cs(NULL), m_has_return(FALSE),
|
||||
m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE)
|
||||
{
|
||||
extern byte *
|
||||
|
@ -319,7 +320,6 @@ sp_head::sp_head()
|
|||
*sp_lex_sp_key(const byte *ptr, uint *plen, my_bool first);
|
||||
DBUG_ENTER("sp_head::sp_head");
|
||||
|
||||
state= INITIALIZED_FOR_SP;
|
||||
m_backpatch.empty();
|
||||
m_lex.empty();
|
||||
hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
|
||||
|
@ -636,7 +636,21 @@ sp_head::execute(THD *thd)
|
|||
break;
|
||||
DBUG_PRINT("execute", ("Instruction %u", ip));
|
||||
thd->set_time(); // Make current_time() et al work
|
||||
ret= i->execute(thd, &ip);
|
||||
{
|
||||
/*
|
||||
We have to substitute free_list of executing statement to
|
||||
current_arena to store there all new items created during execution
|
||||
(for example '*' expanding, or items made during permanent subquery
|
||||
transformation)
|
||||
Note: Every statement have to have all its items listed in free_list
|
||||
for correct cleaning them up
|
||||
*/
|
||||
Item *save_free_list= thd->current_arena->free_list;
|
||||
thd->current_arena->free_list= i->free_list;
|
||||
ret= i->execute(thd, &ip);
|
||||
i->free_list= thd->current_arena->free_list;
|
||||
thd->current_arena->free_list= save_free_list;
|
||||
}
|
||||
if (i->free_list)
|
||||
cleanup_items(i->free_list);
|
||||
// Check if an exception has occurred and a handler has been found
|
||||
|
|
|
@ -79,6 +79,7 @@ class sp_head :private Query_arena
|
|||
sp_head(const sp_head &); /* Prevent use of these */
|
||||
void operator=(sp_head &);
|
||||
|
||||
MEM_ROOT main_mem_root;
|
||||
public:
|
||||
|
||||
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
|
||||
|
|
|
@ -5325,7 +5325,7 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
|
|||
Instantiate used templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List_iterator<LEX_COLUMN>;
|
||||
template class List_iterator<LEX_USER>;
|
||||
template class List<LEX_COLUMN>;
|
||||
|
|
|
@ -49,7 +49,7 @@ char internal_table_name[2]= "*";
|
|||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
/* Used templates */
|
||||
template class List<Key>;
|
||||
template class List_iterator<Key>;
|
||||
|
@ -420,8 +420,6 @@ THD::~THD()
|
|||
#ifndef DBUG_OFF
|
||||
dbug_sentry= THD_SENTRY_GONE;
|
||||
#endif
|
||||
/* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */
|
||||
clear_alloc_root(&stmt_backup.main_mem_root);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -1474,52 +1472,6 @@ void select_dumpvar::cleanup()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Create arena for already constructed THD.
|
||||
|
||||
SYNOPSYS
|
||||
Query_arena()
|
||||
thd - thread for which arena is created
|
||||
|
||||
DESCRIPTION
|
||||
Create arena for already existing THD using its variables as parameters
|
||||
for memory root initialization.
|
||||
*/
|
||||
Query_arena::Query_arena(THD* thd)
|
||||
:free_list(0), mem_root(&main_mem_root),
|
||||
state(INITIALIZED)
|
||||
{
|
||||
init_sql_alloc(&main_mem_root,
|
||||
thd->variables.query_alloc_block_size,
|
||||
thd->variables.query_prealloc_size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create arena and optionally initialize memory root.
|
||||
|
||||
SYNOPSYS
|
||||
Query_arena()
|
||||
init_mem_root - whenever we need to initialize memory root
|
||||
|
||||
DESCRIPTION
|
||||
Create arena and optionally initialize memory root with minimal
|
||||
possible parameters.
|
||||
|
||||
NOTE
|
||||
We use this constructor when arena is part of THD, but reinitialize
|
||||
its memory root in THD::init_for_queries() before execution of real
|
||||
statements.
|
||||
*/
|
||||
Query_arena::Query_arena(bool init_mem_root)
|
||||
:free_list(0), mem_root(&main_mem_root),
|
||||
state(CONVENTIONAL_EXECUTION)
|
||||
{
|
||||
if (init_mem_root)
|
||||
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
|
||||
}
|
||||
|
||||
|
||||
Query_arena::Type Query_arena::type() const
|
||||
{
|
||||
DBUG_ASSERT(0); /* Should never be called */
|
||||
|
@ -1532,7 +1484,7 @@ Query_arena::Type Query_arena::type() const
|
|||
*/
|
||||
|
||||
Statement::Statement(THD *thd)
|
||||
:Query_arena(thd),
|
||||
:Query_arena(&main_mem_root, INITIALIZED),
|
||||
id(++thd->statement_id_counter),
|
||||
set_query_id(1),
|
||||
allow_sum_func(0),
|
||||
|
@ -1542,16 +1494,19 @@ Statement::Statement(THD *thd)
|
|||
cursor(0)
|
||||
{
|
||||
name.str= NULL;
|
||||
init_sql_alloc(&main_mem_root,
|
||||
thd->variables.query_alloc_block_size,
|
||||
thd->variables.query_prealloc_size);
|
||||
}
|
||||
|
||||
/*
|
||||
This constructor is called when statement is a subobject of THD:
|
||||
Some variables are initialized in THD::init due to locking problems
|
||||
This statement object will be used to
|
||||
This constructor is called when Statement is a parent of THD and
|
||||
for the backup statement. Some variables are initialized in
|
||||
THD::init due to locking problems.
|
||||
*/
|
||||
|
||||
Statement::Statement()
|
||||
:Query_arena((bool)TRUE),
|
||||
:Query_arena(&main_mem_root, CONVENTIONAL_EXECUTION),
|
||||
id(0),
|
||||
set_query_id(1),
|
||||
allow_sum_func(0), /* initialized later */
|
||||
|
@ -1560,6 +1515,12 @@ Statement::Statement()
|
|||
query_length(0), /* in alloc_query() */
|
||||
cursor(0)
|
||||
{
|
||||
/*
|
||||
This is just to ensure that the destructor works correctly in
|
||||
case of an error and the backup statement. The memory root will
|
||||
be re-initialized in THD::init.
|
||||
*/
|
||||
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1631,16 +1592,6 @@ void Query_arena::restore_backup_item_arena(Query_arena *set, Query_arena *backu
|
|||
set_item_arena(backup);
|
||||
#ifndef DBUG_OFF
|
||||
backup_arena= 0;
|
||||
#endif
|
||||
#ifdef NOT_NEEDED_NOW
|
||||
/*
|
||||
Reset backup mem_root to avoid its freeing.
|
||||
Since Query_arena's mem_root is freed only when it is part of Statement
|
||||
we need this only if we use some Statement's arena as backup storage.
|
||||
But we do this only with THD::stmt_backup and this Statement is specially
|
||||
handled in this respect. So this code is not really needed now.
|
||||
*/
|
||||
clear_alloc_root(&backup->mem_root);
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -1654,6 +1605,11 @@ void Query_arena::set_item_arena(Query_arena *set)
|
|||
|
||||
Statement::~Statement()
|
||||
{
|
||||
/*
|
||||
We must free `main_mem_root', not `mem_root' (pointer), to work
|
||||
correctly if this statement is used as a backup statement,
|
||||
for which `mem_root' may point to some other statement.
|
||||
*/
|
||||
free_root(&main_mem_root, MYF(0));
|
||||
}
|
||||
|
||||
|
|
|
@ -661,7 +661,6 @@ public:
|
|||
itself to the list on creation (see Item::Item() for details))
|
||||
*/
|
||||
Item *free_list;
|
||||
MEM_ROOT main_mem_root;
|
||||
MEM_ROOT *mem_root; // Pointer to current memroot
|
||||
#ifndef DBUG_OFF
|
||||
bool backup_arena;
|
||||
|
@ -680,21 +679,14 @@ public:
|
|||
STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE
|
||||
};
|
||||
|
||||
Query_arena(MEM_ROOT *mem_root_arg, enum enum_state state_arg) :
|
||||
free_list(0), mem_root(mem_root_arg), state(state_arg)
|
||||
{}
|
||||
/*
|
||||
This constructor is used only when Query_arena is created as
|
||||
backup storage for another instance of Query_arena.
|
||||
*/
|
||||
Query_arena() {};
|
||||
/*
|
||||
Create arena for already constructed THD using its variables as
|
||||
parameters for memory root initialization.
|
||||
*/
|
||||
Query_arena(THD *thd);
|
||||
/*
|
||||
Create arena and optionally init memory root with minimal values.
|
||||
Particularly used if Query_arena is part of Statement.
|
||||
*/
|
||||
Query_arena(bool init_mem_root);
|
||||
virtual Type type() const;
|
||||
virtual ~Query_arena() {};
|
||||
|
||||
|
@ -708,6 +700,7 @@ public:
|
|||
{ return state == PREPARED || state == EXECUTED; }
|
||||
inline bool is_conventional() const
|
||||
{ return state == CONVENTIONAL_EXECUTION; }
|
||||
|
||||
inline gptr alloc(unsigned int size) { return alloc_root(mem_root,size); }
|
||||
inline gptr calloc(unsigned int size)
|
||||
{
|
||||
|
@ -757,7 +750,8 @@ class Statement: public Query_arena
|
|||
Statement(const Statement &rhs); /* not implemented: */
|
||||
Statement &operator=(const Statement &rhs); /* non-copyable */
|
||||
public:
|
||||
/* FIXME: must be private */
|
||||
/* FIXME: these must be protected */
|
||||
MEM_ROOT main_mem_root;
|
||||
LEX main_lex;
|
||||
|
||||
/*
|
||||
|
@ -1388,7 +1382,7 @@ public:
|
|||
already changed to use this arena.
|
||||
*/
|
||||
if (!current_arena->is_conventional() &&
|
||||
mem_root != ¤t_arena->main_mem_root)
|
||||
mem_root != current_arena->mem_root)
|
||||
{
|
||||
set_n_backup_item_arena(current_arena, backup);
|
||||
return current_arena;
|
||||
|
|
|
@ -2119,9 +2119,12 @@ bool select_insert::send_data(List<Item> &values)
|
|||
}
|
||||
if (!(error= write_record(thd, table, &info)))
|
||||
{
|
||||
if (table->triggers)
|
||||
if (table->triggers || info.handle_duplicates == DUP_UPDATE)
|
||||
{
|
||||
/*
|
||||
Restore fields of the record since it is possible that they were
|
||||
changed by ON DUPLICATE KEY UPDATE clause.
|
||||
|
||||
If triggers exist then whey can modify some fields which were not
|
||||
originally touched by INSERT ... SELECT, so we have to restore
|
||||
their original values for the next row.
|
||||
|
@ -2374,11 +2377,11 @@ void select_create::abort()
|
|||
Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List_iterator_fast<List_item>;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
template class I_List<delayed_insert>;
|
||||
template class I_List_iterator<delayed_insert>;
|
||||
template class I_List<delayed_row>;
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
#endif /* EXPLICIT_TEMPLATE_INSTANTIATION */
|
||||
#endif /* HAVE_EXPLICIT_TEMPLATE_INSTANTIATION */
|
||||
|
|
|
@ -138,7 +138,7 @@ void unmap_file(mapped_files *map)
|
|||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
/* Used templates */
|
||||
template class I_List<mapped_files>;
|
||||
template class I_List_iterator<mapped_files>;
|
||||
|
|
|
@ -2002,7 +2002,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||
{
|
||||
DBUG_PRINT("info",("Using READ_ONLY cursor"));
|
||||
if (!cursor &&
|
||||
!(cursor= stmt->cursor= new (&stmt->main_mem_root) Cursor()))
|
||||
!(cursor= stmt->cursor= new (stmt->mem_root) Cursor(thd)))
|
||||
DBUG_VOID_RETURN;
|
||||
/* If lex->result is set, mysql_execute_command will use it */
|
||||
stmt->lex->result= &cursor->result;
|
||||
|
|
|
@ -1708,7 +1708,16 @@ JOIN::cleanup()
|
|||
|
||||
|
||||
/************************* Cursor ******************************************/
|
||||
|
||||
|
||||
Cursor::Cursor(THD *thd)
|
||||
:Query_arena(&main_mem_root, INITIALIZED),
|
||||
join(0), unit(0)
|
||||
{
|
||||
/* We will overwrite it at open anyway. */
|
||||
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Cursor::init_from_thd(THD *thd)
|
||||
{
|
||||
|
@ -6277,7 +6286,7 @@ public:
|
|||
COND_CMP(Item *a,Item_func *b) :and_level(a),cmp_func(b) {}
|
||||
};
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class I_List<COND_CMP>;
|
||||
template class I_List_iterator<COND_CMP>;
|
||||
template class List<Item_func_match>;
|
||||
|
|
|
@ -372,6 +372,7 @@ class JOIN :public Sql_alloc
|
|||
|
||||
class Cursor: public Sql_alloc, public Query_arena
|
||||
{
|
||||
MEM_ROOT main_mem_root;
|
||||
JOIN *join;
|
||||
SELECT_LEX_UNIT *unit;
|
||||
|
||||
|
@ -396,7 +397,7 @@ public:
|
|||
void close();
|
||||
|
||||
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
||||
Cursor() :Query_arena(TRUE), join(0), unit(0) {}
|
||||
Cursor(THD *thd);
|
||||
~Cursor();
|
||||
};
|
||||
|
||||
|
|
|
@ -1102,7 +1102,7 @@ public:
|
|||
char *query;
|
||||
};
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class I_List<thread_info>;
|
||||
#endif
|
||||
|
||||
|
@ -3879,7 +3879,7 @@ ST_SCHEMA_TABLE schema_tables[]=
|
|||
};
|
||||
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List_iterator_fast<char>;
|
||||
template class List<char>;
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,61 @@ TYPELIB updatable_views_with_limit_typelib=
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
Make a unique name for an anonymous view column
|
||||
SYNOPSIS
|
||||
target reference to the item for which a new name has to be made
|
||||
item_list list of items within which we should check uniqueness of
|
||||
the created name
|
||||
last_element the last element of the list above
|
||||
|
||||
NOTE
|
||||
Unique names are generated by adding 'My_exp_' to the old name of the
|
||||
column. In case the name that was created this way already exists, we
|
||||
add a numeric postfix to its end (i.e. "1") and increase the number
|
||||
until the name becomes unique. If the generated name is longer than
|
||||
NAME_LEN, it is truncated.
|
||||
*/
|
||||
|
||||
static void make_unique_view_field_name(Item *target,
|
||||
List<Item> &item_list,
|
||||
Item *last_element)
|
||||
{
|
||||
char *name= (target->orig_name ?
|
||||
target->orig_name :
|
||||
target->name);
|
||||
uint name_len;
|
||||
uint attempt= 0;
|
||||
char buff[NAME_LEN+1];
|
||||
for (;; attempt++)
|
||||
{
|
||||
Item *check;
|
||||
List_iterator_fast<Item> itc(item_list);
|
||||
bool ok= TRUE;
|
||||
|
||||
if (attempt)
|
||||
name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name);
|
||||
else
|
||||
name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name);
|
||||
|
||||
do
|
||||
{
|
||||
check= itc++;
|
||||
if (check != target &&
|
||||
my_strcasecmp(system_charset_info, buff, check->name) == 0)
|
||||
{
|
||||
ok= FALSE;
|
||||
break;
|
||||
}
|
||||
} while (check != last_element);
|
||||
if (ok)
|
||||
break;
|
||||
}
|
||||
|
||||
target->orig_name= target->name;
|
||||
target->set_name(buff, name_len, system_charset_info);
|
||||
}
|
||||
|
||||
/*
|
||||
Creating/altering VIEW procedure
|
||||
|
||||
|
@ -240,24 +295,36 @@ bool mysql_create_view(THD *thd,
|
|||
goto err;
|
||||
}
|
||||
while ((item= it++, name= nm++))
|
||||
{
|
||||
item->set_name(name->str, name->length, system_charset_info);
|
||||
item->is_autogenerated_name= FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test absence of duplicates names */
|
||||
{
|
||||
Item *item;
|
||||
List_iterator_fast<Item> it(select_lex->item_list);
|
||||
it++;
|
||||
while ((item= it++))
|
||||
{
|
||||
Item *check;
|
||||
List_iterator_fast<Item> itc(select_lex->item_list);
|
||||
/* treat underlying fields like set by user names */
|
||||
if (item->real_item()->type() == Item::FIELD_ITEM)
|
||||
item->is_autogenerated_name= FALSE;
|
||||
while ((check= itc++) && check != item)
|
||||
{
|
||||
if (strcmp(item->name, check->name) == 0)
|
||||
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
|
||||
{
|
||||
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
|
||||
DBUG_RETURN(TRUE);
|
||||
if (item->is_autogenerated_name)
|
||||
make_unique_view_field_name(item, select_lex->item_list, item);
|
||||
else if (check->is_autogenerated_name)
|
||||
make_unique_view_field_name(check, select_lex->item_list, item);
|
||||
else
|
||||
{
|
||||
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4107,7 +4107,10 @@ select_item:
|
|||
if (add_item_to_list(YYTHD, $2))
|
||||
YYABORT;
|
||||
if ($4.str)
|
||||
$2->set_name($4.str,$4.length,system_charset_info);
|
||||
{
|
||||
$2->set_name($4.str, $4.length, system_charset_info);
|
||||
$2->is_autogenerated_name= FALSE;
|
||||
}
|
||||
else if (!$2->name) {
|
||||
char *str = $1;
|
||||
if (str[-1] == '`')
|
||||
|
@ -4913,9 +4916,12 @@ udf_expr:
|
|||
remember_name expr remember_end select_alias
|
||||
{
|
||||
if ($4.str)
|
||||
$2->set_name($4.str,$4.length,system_charset_info);
|
||||
{
|
||||
$2->set_name($4.str, $4.length, system_charset_info);
|
||||
$2->is_autogenerated_name= FALSE;
|
||||
}
|
||||
else
|
||||
$2->set_name($1,(uint) ($3 - $1), YYTHD->charset());
|
||||
$2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
|
||||
$$= $2;
|
||||
}
|
||||
;
|
||||
|
@ -5691,7 +5697,8 @@ procedure_item:
|
|||
if (add_proc_to_list(lex->thd, $2))
|
||||
YYABORT;
|
||||
if (!$2->name)
|
||||
$2->set_name($1,(uint) ((char*) lex->tok_end - $1), YYTHD->charset());
|
||||
$2->set_name($1,(uint) ((char*) lex->tok_end - $1),
|
||||
YYTHD->charset());
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -2236,7 +2236,7 @@ const char *Field_iterator_view::name()
|
|||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class List<String>;
|
||||
template class List_iterator<String>;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue