mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merge mysql.com:/home/jonas/src/mysql-5.0
into mysql.com:/home/jonas/src/mysql-5.0-ndb ndb/include/ndbapi/Ndb.hpp: Auto merged ndb/src/ndbapi/Ndb.cpp: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/sql_parse.cc: Auto merged
This commit is contained in:
@@ -434,7 +434,7 @@ d date YES NULL
|
||||
e varchar(1) NO
|
||||
f datetime YES NULL
|
||||
g time YES NULL
|
||||
h varbinary(23) NO
|
||||
h longblob NO
|
||||
dd time YES NULL
|
||||
select * from t2;
|
||||
a b c d e f g h dd
|
||||
|
||||
@@ -464,3 +464,11 @@ SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
html prod
|
||||
1 0.0000
|
||||
drop table t1;
|
||||
create table t1 (id int, dsc varchar(50));
|
||||
insert into t1 values (1, "line number one"), (2, "line number two"), (3, "line number three");
|
||||
select distinct id, IFNULL(dsc, '-') from t1;
|
||||
id IFNULL(dsc, '-')
|
||||
1 line number one
|
||||
2 line number two
|
||||
3 line number three
|
||||
drop table t1;
|
||||
|
||||
@@ -40,3 +40,22 @@ p u o
|
||||
5 5 5
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
create table t1 (p int not null primary key, u int not null) engine=ndb;
|
||||
insert into t1 values (1,1),(2,2),(3,3);
|
||||
create table t2 as
|
||||
select t1.*
|
||||
from t1 as t1, t1 as t2, t1 as t3, t1 as t4, t1 as t5, t1 as t6, t1 as t7, t1 as t8
|
||||
where t1.u = t2.u
|
||||
and t2.u = t3.u
|
||||
and t3.u = t4.u
|
||||
and t4.u = t5.u
|
||||
and t5.u = t6.u
|
||||
and t6.u = t7.u
|
||||
and t7.u = t8.u;
|
||||
select * from t2 order by 1;
|
||||
p u
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
@@ -672,3 +672,17 @@ select default(t30.s1) from t30;
|
||||
end|
|
||||
drop procedure bug10969|
|
||||
drop table t1|
|
||||
prepare stmt from "select 1";
|
||||
create procedure p() deallocate prepare stmt;
|
||||
ERROR 0A000: DEALLOCATE is not allowed in stored procedures
|
||||
create function f() returns int begin deallocate prepare stmt;
|
||||
ERROR 0A000: DEALLOCATE is not allowed in stored procedures
|
||||
create procedure p() prepare stmt from "select 1";
|
||||
ERROR 0A000: PREPARE is not allowed in stored procedures
|
||||
create function f() returns int begin prepare stmt from "select 1";
|
||||
ERROR 0A000: PREPARE is not allowed in stored procedures
|
||||
create procedure p() execute stmt;
|
||||
ERROR 0A000: EXECUTE is not allowed in stored procedures
|
||||
create function f() returns int begin execute stmt;
|
||||
ERROR 0A000: EXECUTE is not allowed in stored procedures
|
||||
deallocate prepare stmt;
|
||||
|
||||
@@ -40,3 +40,18 @@ Id User Host db Command Time State Info
|
||||
unlock tables;
|
||||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
drop procedure if exists bug11158;
|
||||
create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id;
|
||||
create table t1 (id int, j int);
|
||||
insert into t1 values (1, 1), (2, 2);
|
||||
create table t2 (id int);
|
||||
insert into t2 values (1);
|
||||
call bug11158();
|
||||
select * from t1;
|
||||
id j
|
||||
2 2
|
||||
lock tables t2 read;
|
||||
call bug11158();
|
||||
unlock tables;
|
||||
drop procedure bug11158;
|
||||
drop table t1, t2;
|
||||
|
||||
@@ -896,6 +896,8 @@ create table t1( d1 decimal(18) unsigned, d2 decimal(20) unsigned, d3 decimal (2
|
||||
insert into t1 values(1,-1,-1);
|
||||
ERROR 22003: Out of range value adjusted for column 'd2' at row 1
|
||||
drop table t1;
|
||||
set sql_mode='';
|
||||
set @sav_dpi= @@div_precision_increment;
|
||||
set @@div_precision_increment=15;
|
||||
create table t1 (col1 int, col2 decimal(30,25), col3 numeric(30,25));
|
||||
insert into t1 values (1,0.0123456789012345678912345,0.0123456789012345678912345);
|
||||
@@ -909,3 +911,12 @@ select 77777777/7777777;
|
||||
77777777/7777777
|
||||
10.000000900000090
|
||||
drop table t1;
|
||||
set div_precision_increment= @sav_dpi;
|
||||
create table t1 (a decimal(4,2));
|
||||
insert into t1 values (0.00);
|
||||
select * from t1 where a > -0.00;
|
||||
a
|
||||
select * from t1 where a = -0.00;
|
||||
a
|
||||
0.00
|
||||
drop table t1;
|
||||
|
||||
@@ -332,3 +332,11 @@ CREATE TABLE t1 (
|
||||
INSERT INTO t1 VALUES ('1',1,0);
|
||||
SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug 9784 DISTINCT IFNULL truncates data
|
||||
#
|
||||
create table t1 (id int, dsc varchar(50));
|
||||
insert into t1 values (1, "line number one"), (2, "line number two"), (3, "line number three");
|
||||
select distinct id, IFNULL(dsc, '-') from t1;
|
||||
drop table t1;
|
||||
|
||||
@@ -37,3 +37,26 @@ drop table t1;
|
||||
drop table t2;
|
||||
# bug#5367
|
||||
##########
|
||||
|
||||
###
|
||||
# bug#11205
|
||||
create table t1 (p int not null primary key, u int not null) engine=ndb;
|
||||
insert into t1 values (1,1),(2,2),(3,3);
|
||||
|
||||
create table t2 as
|
||||
select t1.*
|
||||
from t1 as t1, t1 as t2, t1 as t3, t1 as t4, t1 as t5, t1 as t6, t1 as t7, t1 as t8
|
||||
where t1.u = t2.u
|
||||
and t2.u = t3.u
|
||||
and t3.u = t4.u
|
||||
and t4.u = t5.u
|
||||
and t5.u = t6.u
|
||||
and t6.u = t7.u
|
||||
and t7.u = t8.u;
|
||||
|
||||
select * from t2 order by 1;
|
||||
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
|
||||
|
||||
@@ -965,3 +965,24 @@ drop procedure bug10969|
|
||||
drop table t1|
|
||||
|
||||
delimiter ;|
|
||||
|
||||
#
|
||||
# Bug#10975, #10605, #7115: Dynamic SQL by means of
|
||||
# PREPARE/EXECUTE/DEALLOCATE is not supported yet.
|
||||
# Check that an error message is returned.
|
||||
#
|
||||
prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() deallocate prepare stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin deallocate prepare stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin prepare stmt from "select 1";
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create procedure p() execute stmt;
|
||||
--error ER_SP_BADSTATEMENT
|
||||
create function f() returns int begin execute stmt;
|
||||
deallocate prepare stmt;
|
||||
|
||||
|
||||
@@ -84,6 +84,32 @@ reap;
|
||||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# BUG#11158: Can't perform multi-delete in stored procedure
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug11158;
|
||||
--enable_warnings
|
||||
create procedure bug11158() delete t1 from t1, t2 where t1.id = t2.id;
|
||||
create table t1 (id int, j int);
|
||||
insert into t1 values (1, 1), (2, 2);
|
||||
create table t2 (id int);
|
||||
insert into t2 values (1);
|
||||
# Procedure should work and cause proper effect (delete only first row)
|
||||
call bug11158();
|
||||
select * from t1;
|
||||
# Also let us test that we obtain only read (and thus non exclusive) lock
|
||||
# for table from which we are not going to delete rows.
|
||||
connection con2root;
|
||||
lock tables t2 read;
|
||||
connection con1root;
|
||||
call bug11158();
|
||||
connection con2root;
|
||||
unlock tables;
|
||||
connection con1root;
|
||||
# Clean-up
|
||||
drop procedure bug11158;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
|
||||
@@ -934,10 +934,12 @@ create table t1( d1 decimal(18) unsigned, d2 decimal(20) unsigned, d3 decimal (2
|
||||
--error 1264
|
||||
insert into t1 values(1,-1,-1);
|
||||
drop table t1;
|
||||
set sql_mode='';
|
||||
|
||||
#
|
||||
# Bug #8425 (insufficient precision of the division)
|
||||
#
|
||||
set @sav_dpi= @@div_precision_increment;
|
||||
set @@div_precision_increment=15;
|
||||
create table t1 (col1 int, col2 decimal(30,25), col3 numeric(30,25));
|
||||
insert into t1 values (1,0.0123456789012345678912345,0.0123456789012345678912345);
|
||||
@@ -945,4 +947,13 @@ select col2/9999999999 from t1 where col1=1;
|
||||
select 9999999999/col2 from t1 where col1=1;
|
||||
select 77777777/7777777;
|
||||
drop table t1;
|
||||
set div_precision_increment= @sav_dpi;
|
||||
|
||||
#
|
||||
# Bug #10896 (0.00 > -0.00)
|
||||
#
|
||||
create table t1 (a decimal(4,2));
|
||||
insert into t1 values (0.00);
|
||||
select * from t1 where a > -0.00;
|
||||
select * from t1 where a = -0.00;
|
||||
drop table t1;
|
||||
|
||||
@@ -1616,7 +1616,7 @@ private:
|
||||
Uint32 theNoOfPreparedTransactions;
|
||||
Uint32 theNoOfSentTransactions;
|
||||
Uint32 theNoOfCompletedTransactions;
|
||||
Uint32 theNoOfAllocatedTransactions;
|
||||
Uint32 theRemainingStartTransactions;
|
||||
Uint32 theMaxNoOfTransactions;
|
||||
Uint32 theMinNoOfEventsToWakeUp;
|
||||
|
||||
|
||||
@@ -425,12 +425,20 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId)
|
||||
DBUG_ENTER("Ndb::startTransactionLocal");
|
||||
DBUG_PRINT("enter", ("nodeid: %d", nodeId));
|
||||
|
||||
if(unlikely(theRemainingStartTransactions == 0))
|
||||
{
|
||||
theError.code = 4006;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
NdbTransaction* tConnection;
|
||||
Uint64 tFirstTransId = theFirstTransId;
|
||||
tConnection = doConnect(nodeId);
|
||||
if (tConnection == NULL) {
|
||||
DBUG_RETURN(NULL);
|
||||
}//if
|
||||
|
||||
theRemainingStartTransactions--;
|
||||
NdbTransaction* tConNext = theTransactionList;
|
||||
tConnection->init();
|
||||
theTransactionList = tConnection; // into a transaction list.
|
||||
@@ -481,6 +489,7 @@ Ndb::closeTransaction(NdbTransaction* aConnection)
|
||||
CHECK_STATUS_MACRO_VOID;
|
||||
|
||||
tCon = theTransactionList;
|
||||
theRemainingStartTransactions++;
|
||||
|
||||
DBUG_PRINT("info",("close trans: 0x%x transid: 0x%llx",
|
||||
aConnection, aConnection->getTransactionId()));
|
||||
|
||||
@@ -89,15 +89,18 @@ int
|
||||
NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection)
|
||||
{
|
||||
m_transConnection = myConnection;
|
||||
//NdbTransaction* aScanConnection = theNdb->startTransaction(myConnection);
|
||||
//NdbConnection* aScanConnection = theNdb->startTransaction(myConnection);
|
||||
theNdb->theRemainingStartTransactions++; // will be checked in hupp...
|
||||
NdbTransaction* aScanConnection = theNdb->hupp(myConnection);
|
||||
if (!aScanConnection){
|
||||
theNdb->theRemainingStartTransactions--;
|
||||
setErrorCodeAbort(theNdb->getNdbError().code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// NOTE! The hupped trans becomes the owner of the operation
|
||||
if(NdbOperation::init(tab, aScanConnection) != 0){
|
||||
theNdb->theRemainingStartTransactions--;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -675,6 +678,7 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp)
|
||||
|
||||
tCon->theScanningOp = 0;
|
||||
theNdb->closeTransaction(tCon);
|
||||
theNdb->theRemainingStartTransactions--;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,12 +107,10 @@ Ndb::init(int aMaxNoOfTransactions)
|
||||
goto error_handler;
|
||||
}
|
||||
|
||||
tMaxNoOfTransactions = aMaxNoOfTransactions * 3;
|
||||
if (tMaxNoOfTransactions > 1024) {
|
||||
tMaxNoOfTransactions = 1024;
|
||||
}//if
|
||||
|
||||
tMaxNoOfTransactions = aMaxNoOfTransactions;
|
||||
theMaxNoOfTransactions = tMaxNoOfTransactions;
|
||||
|
||||
theRemainingStartTransactions= tMaxNoOfTransactions;
|
||||
thePreparedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
|
||||
theSentTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
|
||||
theCompletedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
|
||||
|
||||
@@ -59,7 +59,7 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
|
||||
theNoOfPreparedTransactions= 0;
|
||||
theNoOfSentTransactions= 0;
|
||||
theNoOfCompletedTransactions= 0;
|
||||
theNoOfAllocatedTransactions= 0;
|
||||
theRemainingStartTransactions= 0;
|
||||
theMaxNoOfTransactions= 0;
|
||||
theMinNoOfEventsToWakeUp= 0;
|
||||
theConIdleList= NULL;
|
||||
|
||||
@@ -93,7 +93,6 @@ Ndb::createConIdleList(int aNrOfCon)
|
||||
}
|
||||
tNdbCon->Status(NdbTransaction::NotConnected);
|
||||
}
|
||||
theNoOfAllocatedTransactions = aNrOfCon;
|
||||
return aNrOfCon;
|
||||
}
|
||||
|
||||
@@ -193,14 +192,8 @@ Ndb::getNdbCon()
|
||||
{
|
||||
NdbTransaction* tNdbCon;
|
||||
if ( theConIdleList == NULL ) {
|
||||
if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) {
|
||||
tNdbCon = new NdbTransaction(this);
|
||||
if (tNdbCon == NULL) {
|
||||
return NULL;
|
||||
}//if
|
||||
theNoOfAllocatedTransactions++;
|
||||
} else {
|
||||
ndbout << "theNoOfAllocatedTransactions = " << theNoOfAllocatedTransactions << " theMaxNoOfTransactions = " << theMaxNoOfTransactions << endl;
|
||||
tNdbCon = new NdbTransaction(this);
|
||||
if (tNdbCon == NULL) {
|
||||
return NULL;
|
||||
}//if
|
||||
tNdbCon->next(NULL);
|
||||
|
||||
@@ -1269,6 +1269,101 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
|
||||
return result;
|
||||
}
|
||||
|
||||
int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
|
||||
int result = NDBT_OK;
|
||||
const Uint32 max= 5;
|
||||
const NdbDictionary::Table* pTab = ctx->getTab();
|
||||
|
||||
Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
|
||||
if (pNdb == NULL){
|
||||
ndbout << "pNdb == NULL" << endl;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
if (pNdb->init(max)){
|
||||
ERR(pNdb->getNdbError());
|
||||
delete pNdb;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbConnection* pCon = pNdb->startTransaction();
|
||||
if (pCon == NULL){
|
||||
pNdb->closeTransaction(pCon);
|
||||
delete pNdb;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
Uint32 i;
|
||||
Vector<NdbScanOperation*> scans;
|
||||
for(i = 0; i<10*max; i++)
|
||||
{
|
||||
NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
delete pNdb;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->readTuples() != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
delete pNdb;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
scans.push_back(pOp);
|
||||
}
|
||||
|
||||
// Dont' call any equal or setValues
|
||||
|
||||
// Execute should not work
|
||||
int check = pCon->execute(NoCommit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
}
|
||||
|
||||
for(i= 0; i<scans.size(); i++)
|
||||
{
|
||||
NdbScanOperation* pOp= scans[i];
|
||||
while((check= pOp->nextResult()) == 0);
|
||||
if(check != 1)
|
||||
{
|
||||
ERR(pOp->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
delete pNdb;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
pNdb->closeTransaction(pCon);
|
||||
|
||||
Vector<NdbConnection*> cons;
|
||||
for(i= 0; i<10*max; i++)
|
||||
{
|
||||
pCon= pNdb->startTransaction();
|
||||
if(pCon)
|
||||
cons.push_back(pCon);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
for(i= 0; i<cons.size(); i++)
|
||||
{
|
||||
cons[i]->close();
|
||||
}
|
||||
|
||||
if(cons.size() != max)
|
||||
{
|
||||
result= NDBT_FAILED;
|
||||
}
|
||||
|
||||
delete pNdb;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template class Vector<NdbScanOperation*>;
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testNdbApi);
|
||||
@@ -1351,6 +1446,12 @@ TESTCASE("Bug_11133",
|
||||
INITIALIZER(runBug_11133);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
TESTCASE("Scan_4006",
|
||||
"Check that getNdbScanOperation does not get 4006\n"){
|
||||
INITIALIZER(runLoadTable);
|
||||
INITIALIZER(runScan_4006);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testNdbApi);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
||||
@@ -520,6 +520,10 @@ max-time: 500
|
||||
cmd: testNdbApi
|
||||
args: -n Bug_11133 T1
|
||||
|
||||
max-time: 500
|
||||
cmd: testNdbApi
|
||||
args: -n Scan_4006 T1
|
||||
|
||||
#max-time: 500
|
||||
#cmd: testInterpreter
|
||||
#args: T1
|
||||
|
||||
@@ -13,7 +13,7 @@ save_args=$*
|
||||
VERSION="ndb-autotest.sh version 1.04"
|
||||
|
||||
DATE=`date '+%Y-%m-%d'`
|
||||
HOST=`hostname -s`
|
||||
HOST=`hostname`
|
||||
export DATE HOST
|
||||
|
||||
set -e
|
||||
@@ -330,7 +330,10 @@ start(){
|
||||
tar cfz /tmp/res.$2.$$.tgz `basename $p2`/$DATE
|
||||
scp /tmp/res.$2.$$.tgz \
|
||||
$result_host:$result_path/res.$DATE.$HOST.$2.$$.tgz
|
||||
rm -f /tmp/res.$2.$$.tgz
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
rm -f /tmp/res.$2.$$.tgz
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ static const int parallelism= 0;
|
||||
|
||||
// Default value for max number of transactions
|
||||
// createable against NDB from this handler
|
||||
static const int max_transactions= 256;
|
||||
static const int max_transactions= 2;
|
||||
|
||||
static const char *ha_ndb_ext=".ndb";
|
||||
|
||||
|
||||
@@ -1109,12 +1109,14 @@ void Item_func_between::print(String *str)
|
||||
void
|
||||
Item_func_ifnull::fix_length_and_dec()
|
||||
{
|
||||
agg_result_type(&hybrid_type, args, 2);
|
||||
maybe_null=args[1]->maybe_null;
|
||||
decimals= max(args[0]->decimals, args[1]->decimals);
|
||||
max_length= (max(args[0]->max_length - args[0]->decimals,
|
||||
args[1]->max_length - args[1]->decimals) +
|
||||
decimals);
|
||||
agg_result_type(&hybrid_type, args, 2);
|
||||
max_length= (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) ?
|
||||
(max(args[0]->max_length - args[0]->decimals,
|
||||
args[1]->max_length - args[1]->decimals) + decimals) :
|
||||
max(args[0]->max_length, args[1]->max_length);
|
||||
|
||||
switch (hybrid_type) {
|
||||
case STRING_RESULT:
|
||||
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
|
||||
@@ -1225,16 +1227,7 @@ Item_func_if::fix_length_and_dec()
|
||||
{
|
||||
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
|
||||
decimals= max(args[1]->decimals, args[2]->decimals);
|
||||
if (decimals == NOT_FIXED_DEC)
|
||||
{
|
||||
max_length= max(args[1]->max_length, args[2]->max_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_length= (max(args[1]->max_length - args[1]->decimals,
|
||||
args[2]->max_length - args[2]->decimals) +
|
||||
decimals);
|
||||
}
|
||||
|
||||
enum Item_result arg1_type=args[1]->result_type();
|
||||
enum Item_result arg2_type=args[2]->result_type();
|
||||
bool null1=args[1]->const_item() && args[1]->null_value;
|
||||
@@ -1263,6 +1256,11 @@ Item_func_if::fix_length_and_dec()
|
||||
collation.set(&my_charset_bin); // Number
|
||||
}
|
||||
}
|
||||
max_length=
|
||||
(cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ?
|
||||
(max(args[1]->max_length - args[1]->decimals,
|
||||
args[2]->max_length - args[2]->decimals) + decimals) :
|
||||
max(args[1]->max_length, args[2]->max_length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -290,6 +290,11 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
|
||||
inline
|
||||
void my_decimal_neg(decimal_t *arg)
|
||||
{
|
||||
if (decimal_is_zero(arg))
|
||||
{
|
||||
arg->sign= 0;
|
||||
return;
|
||||
}
|
||||
decimal_neg(arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -482,7 +482,7 @@ bool check_merge_table_access(THD *thd, char *db,
|
||||
TABLE_LIST *table_list);
|
||||
bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
|
||||
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
|
||||
bool mysql_multi_update_prepare(THD *thd);
|
||||
bool mysql_multi_delete_prepare(THD *thd);
|
||||
bool mysql_insert_select_prepare(THD *thd);
|
||||
@@ -577,6 +577,7 @@ void mysql_init_query(THD *thd, uchar *buf, uint length);
|
||||
bool mysql_new_select(LEX *lex, bool move_down);
|
||||
void create_select_for_variable(const char *var_name);
|
||||
void mysql_init_multi_delete(LEX *lex);
|
||||
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
|
||||
void init_max_user_conn(void);
|
||||
void init_update_queries(void);
|
||||
void free_max_user_conn(void);
|
||||
|
||||
@@ -42,7 +42,6 @@ static my_bool open_new_frm(const char *path, const char *alias,
|
||||
uint db_stat, uint prgflag,
|
||||
uint ha_open_flags, TABLE *outparam,
|
||||
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
|
||||
static void relink_tables_for_multidelete(THD *thd);
|
||||
|
||||
extern "C" byte *table_cache_key(const byte *record,uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
@@ -2089,7 +2088,6 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
||||
(thd->fill_derived_tables() &&
|
||||
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
relink_tables_for_multidelete(thd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@@ -2119,36 +2117,10 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables)
|
||||
if (open_tables(thd, &tables, &counter) ||
|
||||
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
relink_tables_for_multidelete(thd); // Not really needed, but
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Let us propagate pointers to open tables from global table list
|
||||
to table lists for multi-delete
|
||||
*/
|
||||
|
||||
static void relink_tables_for_multidelete(THD *thd)
|
||||
{
|
||||
if (thd->lex->all_selects_list->next_select_in_list())
|
||||
{
|
||||
for (SELECT_LEX *sl= thd->lex->all_selects_list;
|
||||
sl;
|
||||
sl= sl->next_select_in_list())
|
||||
{
|
||||
for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first;
|
||||
cursor;
|
||||
cursor=cursor->next_local)
|
||||
{
|
||||
if (cursor->correspondent_table)
|
||||
cursor->table= cursor->correspondent_table->table;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Mark all real tables in the list as free for reuse.
|
||||
|
||||
|
||||
@@ -751,7 +751,12 @@ typedef struct st_lex
|
||||
uint grant, grant_tot_col, which_columns;
|
||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||
uint slave_thd_opt, start_transaction_opt;
|
||||
uint table_count; /* used when usual update transformed in multiupdate */
|
||||
/*
|
||||
In LEX representing update which were transformed to multi-update
|
||||
stores total number of tables. For LEX representing multi-delete
|
||||
holds number of tables from which we will delete records.
|
||||
*/
|
||||
uint table_count;
|
||||
uint8 describe;
|
||||
uint8 derived_tables;
|
||||
uint8 create_view_algorithm;
|
||||
|
||||
@@ -3291,10 +3291,9 @@ end_with_restore_list:
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
TABLE_LIST *aux_tables=
|
||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
||||
uint table_count;
|
||||
multi_delete *result;
|
||||
|
||||
if ((res= multi_delete_precheck(thd, all_tables, &table_count)))
|
||||
if ((res= multi_delete_precheck(thd, all_tables)))
|
||||
break;
|
||||
|
||||
/* condition will be TRUE on SP re-excuting */
|
||||
@@ -3311,7 +3310,7 @@ end_with_restore_list:
|
||||
goto error;
|
||||
|
||||
if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables,
|
||||
table_count)))
|
||||
lex->table_count)))
|
||||
{
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
select_lex->get_table_list(),
|
||||
@@ -6801,23 +6800,19 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
|
||||
multi_delete_precheck()
|
||||
thd Thread handler
|
||||
tables Global/local table list
|
||||
table_count Pointer to table counter
|
||||
|
||||
RETURN VALUE
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
||||
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
TABLE_LIST *aux_tables=
|
||||
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
|
||||
TABLE_LIST *target_tbl;
|
||||
DBUG_ENTER("multi_delete_precheck");
|
||||
|
||||
*table_count= 0;
|
||||
|
||||
/* sql_yacc guarantees that tables and aux_tables are not zero */
|
||||
DBUG_ASSERT(aux_tables != 0);
|
||||
if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
|
||||
@@ -6830,9 +6825,35 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
||||
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Link tables in auxilary table list of multi-delete with corresponding
|
||||
elements in main table list, and set proper locks for them.
|
||||
|
||||
SYNOPSIS
|
||||
multi_delete_set_locks_and_link_aux_tables()
|
||||
lex - pointer to LEX representing multi-delete
|
||||
|
||||
RETURN VALUE
|
||||
FALSE - success
|
||||
TRUE - error
|
||||
*/
|
||||
|
||||
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
||||
{
|
||||
TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
|
||||
TABLE_LIST *target_tbl;
|
||||
DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
|
||||
|
||||
lex->table_count= 0;
|
||||
|
||||
for (target_tbl= (TABLE_LIST *)lex->auxilliary_table_list.first;
|
||||
target_tbl; target_tbl= target_tbl->next_local)
|
||||
{
|
||||
(*table_count)++;
|
||||
lex->table_count++;
|
||||
/* All tables in aux_tables must be found in FROM PART */
|
||||
TABLE_LIST *walk;
|
||||
for (walk= tables; walk; walk= walk->next_local)
|
||||
@@ -6850,14 +6871,6 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
|
||||
}
|
||||
walk->lock_type= target_tbl->lock_type;
|
||||
target_tbl->correspondent_table= walk; // Remember corresponding table
|
||||
|
||||
/* in case of subselects, we need to set lock_type in
|
||||
* corresponding table in list of all tables */
|
||||
if (walk->correspondent_table)
|
||||
{
|
||||
target_tbl->correspondent_table= walk->correspondent_table;
|
||||
walk->correspondent_table->lock_type= walk->lock_type;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -919,6 +919,11 @@ deallocate:
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "DEALLOCATE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
||||
lex->prepared_stmt_name= $3;
|
||||
};
|
||||
@@ -939,6 +944,11 @@ prepare:
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "PREPARE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_PREPARE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
};
|
||||
@@ -969,6 +979,11 @@ execute:
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
}
|
||||
if (lex->sphead)
|
||||
{
|
||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "EXECUTE");
|
||||
YYABORT;
|
||||
}
|
||||
lex->sql_command= SQLCOM_EXECUTE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
}
|
||||
@@ -6132,10 +6147,17 @@ single_multi:
|
||||
| table_wild_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
FROM join_table_list where_clause
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
YYABORT;
|
||||
}
|
||||
| FROM table_wild_list
|
||||
{ mysql_init_multi_delete(Lex); }
|
||||
USING join_table_list where_clause
|
||||
{}
|
||||
{
|
||||
if (multi_delete_set_locks_and_link_aux_tables(Lex))
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
table_wild_list:
|
||||
|
||||
Reference in New Issue
Block a user