mirror of
https://github.com/MariaDB/server.git
synced 2025-01-21 22:34:18 +01:00
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into rurik.mysql.com:/home/igor/mysql-5.1
This commit is contained in:
commit
a6be98b8a8
628 changed files with 734 additions and 90739 deletions
|
@ -653,7 +653,7 @@ static struct my_option my_long_options[] =
|
|||
"Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
|
||||
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"socket", 'S', "Socket file to use for connection. (This will override --port unless --protocol=TCP is specified.)",
|
||||
{"socket", 'S', "Socket file to use for connection.",
|
||||
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#include "sslopt-longopts.h"
|
||||
|
@ -939,14 +939,7 @@ static int get_options(int argc, char **argv)
|
|||
opt_reconnect= 0;
|
||||
connect_flag= 0; /* Not in interactive mode */
|
||||
}
|
||||
|
||||
if (opt_mysql_port && (!opt_protocol) && (!opt_mysql_unix_port))
|
||||
{
|
||||
/* Not checking return type since we are using a constant value */
|
||||
/* straight from the initialization of sql_protocol_typelib. */
|
||||
opt_protocol= find_type("TCP", &sql_protocol_typelib, 0);
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(default_charset, charset_info->csname) &&
|
||||
!(charset_info= get_charset_by_csname(default_charset,
|
||||
MY_CS_PRIMARY, MYF(MY_WME))))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* rsa.h for openSSL */
|
||||
|
||||
|
||||
#ifndef ysSSL_rsa_h__
|
||||
#ifndef yaSSL_rsa_h__
|
||||
#define yaSSL_rsa_h__
|
||||
|
||||
enum { RSA_F4 = 1 };
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ysSSL_openssl_h__
|
||||
#ifndef yaSSL_openssl_h__
|
||||
#define yaSSL_openssl_h__
|
||||
|
||||
#include <stdio.h> /* ERR_print fp */
|
||||
|
|
|
@ -123,8 +123,6 @@ public:
|
|||
|
||||
friend sslFactory& GetSSL_Factory(); // singleton creator
|
||||
private:
|
||||
static sslFactory instance_;
|
||||
|
||||
sslFactory(const sslFactory&); // hide copy
|
||||
sslFactory& operator=(const sslFactory&); // and assign
|
||||
};
|
||||
|
@ -216,8 +214,6 @@ public:
|
|||
|
||||
friend Sessions& GetSessions(); // singleton creator
|
||||
private:
|
||||
static Sessions instance_;
|
||||
|
||||
Sessions(const Sessions&); // hide copy
|
||||
Sessions& operator=(const Sessions&); // and assign
|
||||
};
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
// Delete static singleton memory holders
|
||||
void CleanUp();
|
||||
|
||||
|
||||
// library allocation
|
||||
struct new_t {}; // yaSSL New type
|
||||
extern new_t ys; // pass in parameter
|
||||
|
|
|
@ -648,8 +648,6 @@ void build_certHashes(SSL& ssl, Hashes& hashes)
|
|||
}
|
||||
|
||||
|
||||
mySTL::auto_ptr<input_buffer> null_buffer(ysDelete);
|
||||
|
||||
// do process input requests
|
||||
mySTL::auto_ptr<input_buffer>
|
||||
DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
||||
|
@ -659,7 +657,8 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
|||
if (!ready) {
|
||||
// Nothing to receive after blocking wait => error
|
||||
ssl.SetError(receive_error);
|
||||
return buffered= null_buffer;
|
||||
buffered.reset(0);
|
||||
return buffered;
|
||||
}
|
||||
|
||||
// add buffered data if its there
|
||||
|
@ -667,10 +666,10 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
|||
input_buffer buffer(buffSz + ready);
|
||||
if (buffSz) {
|
||||
buffer.assign(buffered.get()->get_buffer(), buffSz);
|
||||
buffered = null_buffer;
|
||||
buffered.reset(0);
|
||||
}
|
||||
|
||||
// add new (ys) data
|
||||
// add new data
|
||||
uint read = ssl.getSocket().receive(buffer.get_buffer() + buffSz, ready);
|
||||
buffer.add_size(read);
|
||||
uint offset = 0;
|
||||
|
@ -703,11 +702,15 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
|||
mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_), ysDelete);
|
||||
if (!msg.get()) {
|
||||
ssl.SetError(factory_error);
|
||||
return buffered = null_buffer;
|
||||
buffered.reset(0);
|
||||
return buffered;
|
||||
}
|
||||
buffer >> *msg;
|
||||
msg->Process(buffer, ssl);
|
||||
if (ssl.GetError()) return buffered = null_buffer;
|
||||
if (ssl.GetError()) {
|
||||
buffered.reset(0);
|
||||
return buffered;
|
||||
}
|
||||
}
|
||||
offset += hdr.length_ + RECORD_HEADER;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ template void ysDelete<BulkCipher>(BulkCipher*);
|
|||
template void ysDelete<Digest>(Digest*);
|
||||
template void ysDelete<X509>(X509*);
|
||||
template void ysDelete<Message>(Message*);
|
||||
template void ysDelete<sslFactory>(sslFactory*);
|
||||
template void ysDelete<Sessions>(Sessions*);
|
||||
template void ysArrayDelete<unsigned char>(unsigned char*);
|
||||
template void ysArrayDelete<char>(char*);
|
||||
}
|
||||
|
|
|
@ -1361,19 +1361,31 @@ SSL_SESSION::~SSL_SESSION()
|
|||
}
|
||||
|
||||
|
||||
Sessions Sessions::instance_; // simple singleton
|
||||
static Sessions* sessionsInstance = 0;
|
||||
|
||||
Sessions& GetSessions()
|
||||
{
|
||||
return Sessions::instance_;
|
||||
if (!sessionsInstance)
|
||||
sessionsInstance = new (ys) Sessions;
|
||||
return *sessionsInstance;
|
||||
}
|
||||
|
||||
|
||||
sslFactory sslFactory::instance_; // simple singleton
|
||||
static sslFactory* sslFactoryInstance = 0;
|
||||
|
||||
sslFactory& GetSSL_Factory()
|
||||
{
|
||||
return sslFactory::instance_;
|
||||
{
|
||||
if (!sslFactoryInstance)
|
||||
sslFactoryInstance = new (ys) sslFactory;
|
||||
return *sslFactoryInstance;
|
||||
}
|
||||
|
||||
|
||||
void CleanUp()
|
||||
{
|
||||
TaoCrypt::CleanUp();
|
||||
ysDelete(sslFactoryInstance);
|
||||
ysDelete(sessionsInstance);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -275,8 +275,6 @@ private:
|
|||
AlignedWordBlock reg_;
|
||||
Sign sign_;
|
||||
|
||||
static const Integer zero_;
|
||||
static const Integer one_;
|
||||
};
|
||||
|
||||
inline bool operator==(const Integer& a, const Integer& b)
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// Delete static singleton holders
|
||||
void CleanUp();
|
||||
|
||||
|
||||
// library allocation
|
||||
struct new_t {}; // TaoCrypt New type
|
||||
extern new_t tc; // pass in parameter
|
||||
|
|
|
@ -25,11 +25,27 @@
|
|||
|
||||
|
||||
|
||||
#if !defined(yaSSL_NEW_HPP) && defined(__GNUC__)
|
||||
#if !(defined(__ICC) || defined(__INTEL_COMPILER))
|
||||
|
||||
#ifndef yaSSL_NEW_HPP
|
||||
#define yaSSL_NEW_HPP
|
||||
|
||||
|
||||
#ifdef __sun
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Handler for pure virtual functions
|
||||
namespace __Crun {
|
||||
static void pure_error(void)
|
||||
{
|
||||
assert("Pure virtual method called." == "Aborted");
|
||||
}
|
||||
} // namespace __Crun
|
||||
|
||||
#endif // __sun
|
||||
|
||||
|
||||
#if defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
|
||||
|
||||
#if __GNUC__ > 2
|
||||
|
||||
extern "C" {
|
||||
|
@ -47,6 +63,6 @@ static int __cxa_pure_virtual()
|
|||
} // extern "C"
|
||||
|
||||
#endif // __GNUC__ > 2
|
||||
#endif // ! _ICC
|
||||
#endif // yaSSL_NEW_HPP && __GNUC__
|
||||
#endif // compiler check
|
||||
#endif // yaSSL_NEW_HPP
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ const Integer& AbstractEuclideanDomain::Mod(const Element &a,
|
|||
const Integer& AbstractEuclideanDomain::Gcd(const Element &a,
|
||||
const Element &b) const
|
||||
{
|
||||
Element g[3]={b, a};
|
||||
mySTL::vector<Element> g(3);
|
||||
g[0]= b;
|
||||
g[1]= a;
|
||||
unsigned int i0=0, i1=1, i2=2;
|
||||
|
||||
while (!Equal(g[i1], this->Identity()))
|
||||
|
|
|
@ -2709,19 +2709,32 @@ unsigned int Integer::Encode(byte* output, unsigned int outputLen,
|
|||
}
|
||||
|
||||
|
||||
const Integer Integer::zero_;
|
||||
static Integer* zero = 0;
|
||||
|
||||
const Integer &Integer::Zero()
|
||||
{
|
||||
return zero_;
|
||||
if (!zero)
|
||||
zero = new (tc) Integer;
|
||||
return *zero;
|
||||
}
|
||||
|
||||
|
||||
const Integer Integer::one_(1,2);
|
||||
static Integer* one = 0;
|
||||
|
||||
const Integer &Integer::One()
|
||||
{
|
||||
return one_;
|
||||
if (!one)
|
||||
one = new (tc) Integer(1,2);
|
||||
return *one;
|
||||
}
|
||||
|
||||
|
||||
// Clean up static singleton holders, not a leak, but helpful to have gone
|
||||
// when checking for leaks
|
||||
void CleanUp()
|
||||
{
|
||||
tcDelete(one);
|
||||
tcDelete(zero);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ template class RSA_Decryptor<RSA_BlockType2>;
|
|||
template class RSA_Encryptor<RSA_BlockType1>;
|
||||
template class RSA_Encryptor<RSA_BlockType2>;
|
||||
template void tcDelete<HASH>(HASH*);
|
||||
template void tcDelete<Integer>(Integer*);
|
||||
template void tcArrayDelete<byte>(byte*);
|
||||
template AllocatorWithCleanup<byte>::pointer StdReallocate<byte, AllocatorWithCleanup<byte> >(AllocatorWithCleanup<byte>&, byte*, AllocatorWithCleanup<byte>::size_type, AllocatorWithCleanup<byte>::size_type, bool);
|
||||
template void tcArrayDelete<word>(word*);
|
||||
|
|
|
@ -608,6 +608,7 @@ extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
|
|||
#define my_access access
|
||||
#endif
|
||||
extern int check_if_legal_filename(const char *path);
|
||||
extern int check_if_legal_tablename(const char *path);
|
||||
|
||||
#ifndef TERMINATE
|
||||
extern void TERMINATE(FILE *file);
|
||||
|
|
|
@ -136,14 +136,17 @@ else
|
|||
then \
|
||||
$(libmysqld_a_AR) libmysqld.a libmysqld_int.a $(INC_LIB) ; \
|
||||
else \
|
||||
current_dir=`pwd`; \
|
||||
rm -rf tmp; mkdir tmp; \
|
||||
(for arc in ./libmysqld_int.a $(INC_LIB); do \
|
||||
arpath=`echo $$arc|sed 's|[^/]*$$||'|sed 's|\.libs/$$||'`; \
|
||||
artmp=`echo $$arc|sed 's|^.*/|tmp/lib-|'`; \
|
||||
for F in `$(AR) t $$arc`; do \
|
||||
if test -e "$$arpath/$$F" ; then echo "$$arpath/$$F"; else \
|
||||
mkdir $$artmp; cd $$artmp; $(AR) x ../../$$arc; \
|
||||
cd ../..; ls $$artmp/*; \
|
||||
mkdir $$artmp; cd $$artmp > /dev/null; \
|
||||
$(AR) x ../../$$arc; \
|
||||
cd $$current_dir > /dev/null; \
|
||||
ls $$artmp/*; \
|
||||
continue 2; fi; done; \
|
||||
done; echo $(libmysqld_a_DEPENDENCIES) ) | sort -u | xargs $(AR) cq libmysqld.a ; \
|
||||
$(RANLIB) libmysqld.a ; \
|
||||
|
|
|
@ -77,6 +77,11 @@ connection slave;
|
|||
# to go into the relay log (the master always sends a fake one when replication
|
||||
# starts).
|
||||
start slave;
|
||||
#
|
||||
# This is timing out in pushbuild and should be changed to use
|
||||
# wait_slave_status.inc
|
||||
#
|
||||
sleep 2;
|
||||
sync_with_master;
|
||||
flush logs;
|
||||
stop slave;
|
||||
|
|
|
@ -14,20 +14,22 @@ source include/master-slave.inc;
|
|||
#
|
||||
SHOW VARIABLES LIKE 'relay_log_space_limit';
|
||||
|
||||
# Matz says: I have no idea what this is supposed to test, but it has
|
||||
# potential for generating different results with some storage engines
|
||||
# that process rows in an order not dependent on the insertion order.
|
||||
# For instance, I would assume that distributed storage engines (like
|
||||
# NDB) could process rows based on locality.
|
||||
|
||||
eval CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=$engine_type;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT t1 SET name='Jacob', age=2;
|
||||
INSERT into t1 SET name='Caleb', age=1;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT INTO t1 SET name='Jacob', age=2;
|
||||
INSERT INTO t1 SET name='Caleb', age=1;
|
||||
ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
connection master;
|
||||
drop table t1;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
DROP TABLE t1;
|
||||
sync_slave_with_master;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -41,7 +41,7 @@ SELECT id,hex(b1),vc,bc,d,f,total,y,t FROM t1 WHERE id = 412;
|
|||
|
||||
# Must give injector thread a little time to get update
|
||||
# into the binlog other wise we will miss the update.
|
||||
sleep 3;
|
||||
sleep 10;
|
||||
|
||||
sync_slave_with_master;
|
||||
--echo --- Check Update on slave ---
|
||||
|
|
|
@ -532,10 +532,10 @@ sub command_line_setup () {
|
|||
|
||||
my $opt_master_myport= 9306;
|
||||
my $opt_slave_myport= 9308;
|
||||
$opt_ndbcluster_port= 9350;
|
||||
$opt_ndbcluster_port_slave= 9358;
|
||||
my $im_port= 9310;
|
||||
my $im_mysqld1_port= 9312;
|
||||
$opt_ndbcluster_port= 9310;
|
||||
$opt_ndbcluster_port_slave= 9311;
|
||||
my $im_port= 9312;
|
||||
my $im_mysqld1_port= 9313;
|
||||
my $im_mysqld2_port= 9314;
|
||||
|
||||
#
|
||||
|
|
|
@ -7,17 +7,11 @@
|
|||
# List of failed cases (--force) backported from 4.1 by Joerg
|
||||
# :-)
|
||||
|
||||
|
||||
echo "##################################################";
|
||||
echo "This script is deprecated and will soon be removed";
|
||||
echo "Use mysql-test-run.pl instead";
|
||||
echo "Now sleeping 20 seconds...";
|
||||
echo "##################################################";
|
||||
sleep 20;
|
||||
echo "continuing";
|
||||
echo;
|
||||
|
||||
|
||||
#echo "##################################################";
|
||||
#echo "This script is deprecated and will soon be removed";
|
||||
#echo "Use mysql-test-run.pl instead";
|
||||
#echo "##################################################";
|
||||
#echo
|
||||
|
||||
#++
|
||||
# Access Definitions
|
||||
|
@ -250,6 +244,7 @@ MASTER_MYPORT=9306
|
|||
SLAVE_RUNNING=0
|
||||
SLAVE_MYHOST=127.0.0.1
|
||||
SLAVE_MYPORT=9308 # leave room for 2 masters for cluster tests
|
||||
MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log
|
||||
NDBCLUSTER_PORT=9350
|
||||
NDBCLUSTER_PORT_SLAVE=9358
|
||||
|
||||
|
@ -1196,6 +1191,7 @@ abort_if_failed()
|
|||
|
||||
launch_in_background()
|
||||
{
|
||||
shift
|
||||
echo $@ | /bin/sh >> $CUR_MYERR 2>&1 &
|
||||
sleep 2 #hack
|
||||
return
|
||||
|
|
13
mysql-test/r/ctype_filename.result
Normal file
13
mysql-test/r/ctype_filename.result
Normal file
|
@ -0,0 +1,13 @@
|
|||
drop table if exists con, aux, nul, lpt1, com1, `clock$`;
|
||||
create table con (a int);
|
||||
drop table con;
|
||||
create table aux (a int);
|
||||
drop table aux;
|
||||
create table nul (a int);
|
||||
drop table nul;
|
||||
create table lpt1 (a int);
|
||||
drop table lpt1;
|
||||
create table com1 (a int);
|
||||
drop table com1;
|
||||
create table `clock$` (a int);
|
||||
drop table `clock$`;
|
|
@ -28,7 +28,6 @@ b INT NOT NULL,
|
|||
c INT NOT NULL
|
||||
) ENGINE=ndbcluster;
|
||||
select * from t1;
|
||||
a b c
|
||||
select * from t1;
|
||||
a b c
|
||||
select * from t1;
|
||||
|
|
|
@ -8,6 +8,7 @@ a b c
|
|||
2 two two
|
||||
alter table t1 drop index c;
|
||||
select * from t1 where c = 'two';
|
||||
select * from t1 where c = 'two';
|
||||
a b c
|
||||
2 two two
|
||||
drop table t1;
|
||||
|
|
|
@ -8,9 +8,9 @@ SHOW VARIABLES LIKE 'relay_log_space_limit';
|
|||
Variable_name Value
|
||||
relay_log_space_limit 0
|
||||
CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=NDB;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT t1 SET name='Jacob', age=2;
|
||||
INSERT into t1 SET name='Caleb', age=1;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT INTO t1 SET name='Jacob', age=2;
|
||||
INSERT INTO t1 SET name='Caleb', age=1;
|
||||
ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
name age id
|
||||
|
@ -22,4 +22,4 @@ name age id
|
|||
Andy 31 00000001
|
||||
Caleb 1 00000002
|
||||
Jacob 2 00000003
|
||||
drop table t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -8,9 +8,9 @@ SHOW VARIABLES LIKE 'relay_log_space_limit';
|
|||
Variable_name Value
|
||||
relay_log_space_limit 0
|
||||
CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=InnoDB;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT t1 SET name='Jacob', age=2;
|
||||
INSERT into t1 SET name='Caleb', age=1;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT INTO t1 SET name='Jacob', age=2;
|
||||
INSERT INTO t1 SET name='Caleb', age=1;
|
||||
ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
name age id
|
||||
|
@ -22,4 +22,4 @@ name age id
|
|||
Andy 31 00000001
|
||||
Jacob 2 00000002
|
||||
Caleb 1 00000003
|
||||
drop table t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -8,9 +8,9 @@ SHOW VARIABLES LIKE 'relay_log_space_limit';
|
|||
Variable_name Value
|
||||
relay_log_space_limit 0
|
||||
CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=MyISAM;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT t1 SET name='Jacob', age=2;
|
||||
INSERT into t1 SET name='Caleb', age=1;
|
||||
INSERT INTO t1 SET name='Andy', age=31;
|
||||
INSERT INTO t1 SET name='Jacob', age=2;
|
||||
INSERT INTO t1 SET name='Caleb', age=1;
|
||||
ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
|
||||
SELECT * FROM t1 ORDER BY id;
|
||||
name age id
|
||||
|
@ -22,4 +22,4 @@ name age id
|
|||
Andy 31 00000001
|
||||
Jacob 2 00000002
|
||||
Caleb 1 00000003
|
||||
drop table t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -468,6 +468,30 @@ extractValue(@xml, '/a/@b[substring(.,2,1)="1"]')
|
|||
select extractValue(@xml, '/a/@b[substring(.,2,1)="2"]');
|
||||
extractValue(@xml, '/a/@b[substring(.,2,1)="2"]')
|
||||
12 22
|
||||
SET @xml='<a><b>b1</b><b>b2</b></a>';
|
||||
SELECT extractValue(@xml, '/a/b[string-length("x")=1]');
|
||||
extractValue(@xml, '/a/b[string-length("x")=1]')
|
||||
b1 b2
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xx")=2]');
|
||||
extractValue(@xml, '/a/b[string-length("xx")=2]')
|
||||
b1 b2
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xxx")=2]');
|
||||
extractValue(@xml, '/a/b[string-length("xxx")=2]')
|
||||
|
||||
SELECT extractValue(@xml, '/a/b[string-length("x")]');
|
||||
extractValue(@xml, '/a/b[string-length("x")]')
|
||||
b1
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xx")]');
|
||||
extractValue(@xml, '/a/b[string-length("xx")]')
|
||||
b2
|
||||
SELECT extractValue(@xml, '/a/b[string-length()]');
|
||||
extractValue(@xml, '/a/b[string-length()]')
|
||||
b2
|
||||
SELECT extractValue(@xml, 'string-length()');
|
||||
ERROR HY000: XPATH syntax error: ''
|
||||
SELECT extractValue(@xml, 'string-length("x")');
|
||||
extractValue(@xml, 'string-length("x")')
|
||||
1
|
||||
SET @xml='<a b="b11" b="b12" b="b21" b="22"/>';
|
||||
select extractValue(@xml,'/a/@b');
|
||||
extractValue(@xml,'/a/@b')
|
||||
|
|
21
mysql-test/t/ctype_filename.test
Normal file
21
mysql-test/t/ctype_filename.test
Normal file
|
@ -0,0 +1,21 @@
|
|||
--disable_warnings
|
||||
drop table if exists con, aux, nul, lpt1, com1, `clock$`;
|
||||
--enable_warnings
|
||||
|
||||
create table con (a int);
|
||||
drop table con;
|
||||
|
||||
create table aux (a int);
|
||||
drop table aux;
|
||||
|
||||
create table nul (a int);
|
||||
drop table nul;
|
||||
|
||||
create table lpt1 (a int);
|
||||
drop table lpt1;
|
||||
|
||||
create table com1 (a int);
|
||||
drop table com1;
|
||||
|
||||
create table `clock$` (a int);
|
||||
drop table `clock$`;
|
|
@ -28,9 +28,9 @@ rpl_ndb_ddl : result file needs update + test needs to checked
|
|||
rpl_ndb_innodb2ndb : BUG#18094 2006-03-16 mats Slave caches invalid table definition after atlters causes select failure
|
||||
rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ
|
||||
rpl_ndb_myisam2ndb : BUG#18094 2006-03-16 mats Slave caches invalid table definition after atlters causes select failure
|
||||
rpl_ndb_relay_space : BUG#16993 2006-02-16 jmiller RBR: ALTER TABLE ZEROFILL AUTO_INCREMENT is not replicated correctly
|
||||
#rpl_ndb_relay_space : BUG#16993 2006-02-16 jmiller RBR: ALTER TABLE ZEROFILL AUTO_INCREMENT is not replicated correctly
|
||||
rpl_switch_stm_row_mixed : BUG#18590 2006-03-28 brian
|
||||
rpl_row_basic_7ndb : BUG#17400 2006-04-09 brian Cluster Replication: delete & update of rows in table without pk fails on slave.
|
||||
#rpl_row_basic_7ndb : BUG#17400 2006-04-09 brian Cluster Replication: delete & update of rows in table without pk fails on slave.
|
||||
rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
|
||||
rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed
|
||||
rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever
|
||||
|
|
|
@ -72,7 +72,10 @@ CREATE TABLE t1 (
|
|||
|
||||
connection server1;
|
||||
|
||||
--disable_result_log
|
||||
--error 0,1412
|
||||
select * from t1;
|
||||
--enable_result_log
|
||||
select * from t1;
|
||||
select * from t1;
|
||||
select * from t1;
|
||||
|
|
|
@ -17,6 +17,12 @@ select * from t1 where c = 'two';
|
|||
connection server1;
|
||||
alter table t1 drop index c;
|
||||
connection server2;
|
||||
|
||||
--disable_result_log
|
||||
--error 0,1412
|
||||
select * from t1 where c = 'two';
|
||||
--enable_result_log
|
||||
|
||||
select * from t1 where c = 'two';
|
||||
connection server1;
|
||||
drop table t1;
|
||||
|
|
301
mysql-test/t/rpl_ndb_dd_partitions.test
Normal file
301
mysql-test/t/rpl_ndb_dd_partitions.test
Normal file
|
@ -0,0 +1,301 @@
|
|||
#######################################
|
||||
# Author: JBM #
|
||||
# Date: 2006-03-09 #
|
||||
# Purpose: To test the replication of #
|
||||
# Cluster Disk Data using partitions #
|
||||
#######################################
|
||||
|
||||
--source include/have_ndb.inc
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo --- Doing pre test cleanup ---
|
||||
|
||||
connection master;
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_query_log
|
||||
|
||||
|
||||
# Start by creating a logfile group
|
||||
##################################
|
||||
|
||||
CREATE LOGFILE GROUP lg1
|
||||
ADD UNDOFILE 'undofile.dat'
|
||||
INITIAL_SIZE 16M
|
||||
UNDO_BUFFER_SIZE = 1M
|
||||
ENGINE=NDB;
|
||||
|
||||
ALTER LOGFILE GROUP lg1
|
||||
ADD UNDOFILE 'undofile02.dat'
|
||||
INITIAL_SIZE = 4M
|
||||
ENGINE=NDB;
|
||||
|
||||
###################################################
|
||||
# Create a tablespace connected to the logfile group
|
||||
###################################################
|
||||
|
||||
CREATE TABLESPACE ts1
|
||||
ADD DATAFILE 'datafile.dat'
|
||||
USE LOGFILE GROUP lg1
|
||||
INITIAL_SIZE 12M
|
||||
ENGINE NDB;
|
||||
|
||||
ALTER TABLESPACE ts1
|
||||
ADD DATAFILE 'datafile02.dat'
|
||||
INITIAL_SIZE = 4M
|
||||
ENGINE=NDB;
|
||||
|
||||
#################################################################
|
||||
|
||||
--echo --- Start test 2 partition RANGE testing --
|
||||
--echo --- Do setup --
|
||||
|
||||
|
||||
#################################################
|
||||
# Requirment: Create table that is partitioned #
|
||||
# by range on year i.e. year(t) and replicate #
|
||||
# basice operations such at insert, update #
|
||||
# delete between 2 different storage engines #
|
||||
# Alter table and ensure table is handled #
|
||||
# Correctly on the slave #
|
||||
#################################################
|
||||
|
||||
CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(63),
|
||||
bc CHAR(63), d DECIMAL(10,4) DEFAULT 0,
|
||||
f FLOAT DEFAULT 0, total BIGINT UNSIGNED,
|
||||
y YEAR, t DATE)
|
||||
TABLESPACE ts1 STORAGE DISK
|
||||
ENGINE=NDB
|
||||
PARTITION BY RANGE (YEAR(t))
|
||||
(PARTITION p0 VALUES LESS THAN (1901),
|
||||
PARTITION p1 VALUES LESS THAN (1946),
|
||||
PARTITION p2 VALUES LESS THAN (1966),
|
||||
PARTITION p3 VALUES LESS THAN (1986),
|
||||
PARTITION p4 VALUES LESS THAN (2005),
|
||||
PARTITION p5 VALUES LESS THAN MAXVALUE);
|
||||
|
||||
--echo --- Show table on master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Show table on slave --
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- Check that simple Alter statements are replicated correctly ---
|
||||
|
||||
ALTER TABLE t1 MODIFY vc VARCHAR(255);
|
||||
|
||||
--echo --- Show the new improved table on the master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Make sure that our tables on slave are still same engine ---
|
||||
--echo --- and that the alter statements replicated correctly ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
--enable_query_log
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- End test 2 partition RANGE testing ---
|
||||
--echo --- Do Cleanup ---
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
||||
########################################################
|
||||
|
||||
--echo --- Start test 3 partition LIST testing ---
|
||||
--echo --- Do setup ---
|
||||
#################################################
|
||||
|
||||
|
||||
CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(63),
|
||||
bc CHAR(63), d DECIMAL(10,4) DEFAULT 0,
|
||||
f FLOAT DEFAULT 0, total BIGINT UNSIGNED,
|
||||
y YEAR, t DATE)
|
||||
TABLESPACE ts1 STORAGE DISK
|
||||
ENGINE=NDB
|
||||
PARTITION BY LIST(id)
|
||||
(PARTITION p0 VALUES IN (2, 4),
|
||||
PARTITION p1 VALUES IN (42, 142));
|
||||
|
||||
--echo --- Test 3 Alter to add partition ---
|
||||
|
||||
ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES IN (412));
|
||||
|
||||
--echo --- Show table on master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Show table on slave ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- Check that simple Alter statements are replicated correctly ---
|
||||
|
||||
ALTER TABLE t1 MODIFY vc VARCHAR(255);
|
||||
|
||||
--echo --- Show the new improved table on the master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Make sure that our tables on slave are still same engine ---
|
||||
--echo --- and that the alter statements replicated correctly ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- End test 3 partition LIST testing ---
|
||||
--echo --- Do Cleanup --
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
||||
########################################################
|
||||
|
||||
--echo --- Start test 4 partition HASH testing ---
|
||||
--echo --- Do setup ---
|
||||
#################################################
|
||||
|
||||
|
||||
CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(63),
|
||||
bc CHAR(63), d DECIMAL(10,4) DEFAULT 0,
|
||||
f FLOAT DEFAULT 0, total BIGINT UNSIGNED,
|
||||
y YEAR, t DATE)
|
||||
TABLESPACE ts1 STORAGE DISK
|
||||
ENGINE=NDB
|
||||
PARTITION BY HASH( YEAR(t) )
|
||||
PARTITIONS 4;
|
||||
|
||||
--echo --- show that tables have been created correctly ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- Check that simple Alter statements are replicated correctly ---
|
||||
|
||||
ALTER TABLE t1 MODIFY vc VARCHAR(255);
|
||||
|
||||
--echo --- Show the new improved table on the master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Make sure that our tables on slave are still same engine ---
|
||||
--echo --- and that the alter statements replicated correctly ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- End test 4 partition HASH testing ---
|
||||
--echo --- Do Cleanup --
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
||||
########################################################
|
||||
|
||||
--echo --- Start test 5 partition by key testing ---
|
||||
--echo --- Create Table Section ---
|
||||
|
||||
#################################################
|
||||
|
||||
CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(63),
|
||||
bc CHAR(63), d DECIMAL(10,4) DEFAULT 0,
|
||||
f FLOAT DEFAULT 0, total BIGINT UNSIGNED,
|
||||
y YEAR, t DATE,PRIMARY KEY(id))
|
||||
TABLESPACE ts1 STORAGE DISK
|
||||
ENGINE=NDB
|
||||
PARTITION BY KEY()
|
||||
PARTITIONS 4;
|
||||
|
||||
--echo --- Show that tables on master are ndbcluster tables ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Show that tables on slave ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
# Okay lets see how it holds up to table changes
|
||||
--echo --- Check that simple Alter statements are replicated correctly ---
|
||||
|
||||
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(id, total);
|
||||
|
||||
--echo --- Show the new improved table on the master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Make sure that our tables on slave are still right type ---
|
||||
--echo --- and that the alter statements replicated correctly ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- Check that simple Alter statements are replicated correctly ---
|
||||
|
||||
ALTER TABLE t1 MODIFY vc VARCHAR(255);
|
||||
|
||||
--echo --- Show the new improved table on the master ---
|
||||
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Make sure that our tables on slave are still same engine ---
|
||||
--echo --- and that the alter statements replicated correctly ---
|
||||
|
||||
sync_slave_with_master;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo --- Perform basic operation on master ---
|
||||
--echo --- and ensure replicated correctly ---
|
||||
|
||||
--source include/rpl_multi_engine3.inc
|
||||
|
||||
--echo --- End test 5 key partition testing ---
|
||||
--echo --- Do Cleanup ---
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
||||
# End of 5.1 test case
|
|
@ -3,5 +3,6 @@
|
|||
# Share test code between engine tests #
|
||||
#########################################
|
||||
--source include/have_ndb.inc
|
||||
-- source include/have_binlog_format_row.inc
|
||||
let $engine_type=NDB;
|
||||
-- source extra/rpl_tests/rpl_delete_no_where.test
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# Wrapper for rpl_insert_ignore.test#
|
||||
#####################################
|
||||
-- source include/have_ndb.inc
|
||||
-- source include/have_binlog_format_row.inc
|
||||
let $engine_type=NDB;
|
||||
let $engine_type2=myisam;
|
||||
-- source extra/rpl_tests/rpl_insert_ignore.test
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
# to reuse test code between engine runs #
|
||||
############################################################
|
||||
-- source include/have_ndb.inc
|
||||
-- source include/have_binlog_format_row.inc
|
||||
let $engine_type=NDB;
|
||||
-- source extra/rpl_tests/rpl_multi_update3.test
|
||||
|
|
|
@ -192,6 +192,20 @@ select extractValue(@xml, '/a/@b[substring(.,1,1)="2"]');
|
|||
select extractValue(@xml, '/a/@b[substring(.,2,1)="1"]');
|
||||
select extractValue(@xml, '/a/@b[substring(.,2,1)="2"]');
|
||||
|
||||
#
|
||||
# Bug#16319: XML: extractvalue() returns syntax errors for some functions
|
||||
#
|
||||
SET @xml='<a><b>b1</b><b>b2</b></a>';
|
||||
SELECT extractValue(@xml, '/a/b[string-length("x")=1]');
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xx")=2]');
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xxx")=2]');
|
||||
SELECT extractValue(@xml, '/a/b[string-length("x")]');
|
||||
SELECT extractValue(@xml, '/a/b[string-length("xx")]');
|
||||
SELECT extractValue(@xml, '/a/b[string-length()]');
|
||||
--error 1105
|
||||
SELECT extractValue(@xml, 'string-length()');
|
||||
SELECT extractValue(@xml, 'string-length("x")');
|
||||
|
||||
SET @xml='<a b="b11" b="b12" b="b21" b="22"/>';
|
||||
select extractValue(@xml,'/a/@b');
|
||||
select extractValue(@xml,'/a/@b[contains(.,"1")]');
|
||||
|
|
|
@ -54,24 +54,111 @@ int my_access(const char *path, int amode)
|
|||
|
||||
#endif /* __WIN__ */
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__)
|
||||
|
||||
/*
|
||||
List of file names that causes problem on windows
|
||||
|
||||
NOTE that one can also not have file names of type CON.TXT
|
||||
|
||||
NOTE: it is important to keep "CLOCK$" on the first place,
|
||||
we skip it in check_if_legal_tablename.
|
||||
*/
|
||||
|
||||
static const char *reserved_names[]=
|
||||
{
|
||||
"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
|
||||
"COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6",
|
||||
"LPT7", "LPT8", "LPT9", "CLOCK$",
|
||||
"CLOCK$",
|
||||
"CON", "PRN", "AUX", "NUL",
|
||||
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
|
||||
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
|
||||
NullS
|
||||
};
|
||||
|
||||
#define MAX_RESERVED_NAME_LENGTH 6
|
||||
|
||||
|
||||
/*
|
||||
Looks up a null-terminated string in a list,
|
||||
case insensitively.
|
||||
|
||||
SYNOPSIS
|
||||
str_list_find()
|
||||
list list of items
|
||||
str item to find
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 reserved file name
|
||||
*/
|
||||
static int str_list_find(const char **list, const char *str)
|
||||
{
|
||||
const char **name;
|
||||
for (name= list; *name; name++)
|
||||
{
|
||||
if (!my_strcasecmp(&my_charset_latin1, *name, str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
A map for faster reserved_names lookup,
|
||||
helps to avoid loops in many cases.
|
||||
1 - can be the first letter
|
||||
2 - can be the second letter
|
||||
4 - can be the third letter
|
||||
*/
|
||||
static char reserved_map[256]=
|
||||
{
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* !"#$%&'()*+,-./ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0123456789:;<=>? */
|
||||
0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* @ABCDEFGHIJKLMNO */
|
||||
3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* PQRSTUVWXYZ[\]^_ */
|
||||
0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* bcdefghijklmno */
|
||||
3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* pqrstuvwxyz{|}~. */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ................ */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Check if a table name may cause problems
|
||||
|
||||
SYNOPSIS
|
||||
check_if_legal_tablename
|
||||
name Table name (without any extensions)
|
||||
|
||||
DESCRIPTION
|
||||
We don't check 'CLOCK$' because dollar sign is encoded as @0024,
|
||||
making table file name 'CLOCK@0024', which is safe.
|
||||
This is why we start lookup from the second element
|
||||
(i.e. &reserver_name[1])
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 reserved file name
|
||||
*/
|
||||
|
||||
int check_if_legal_tablename(const char *name)
|
||||
{
|
||||
DBUG_ENTER("check_if_legal_tablename");
|
||||
DBUG_RETURN((reserved_map[(uchar) name[0]] & 1) &&
|
||||
(reserved_map[(uchar) name[1]] & 2) &&
|
||||
(reserved_map[(uchar) name[2]] & 4) &&
|
||||
str_list_find(&reserved_names[1], name));
|
||||
}
|
||||
|
||||
|
||||
#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
|
||||
|
||||
|
||||
/*
|
||||
Check if a path will access a reserverd file name that may cause problems
|
||||
|
||||
|
@ -111,4 +198,5 @@ int check_if_legal_filename(const char *path)
|
|||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(MSDOS) || defined(__WIN__) || defined(__EMX__) */
|
||||
|
|
|
@ -1133,6 +1133,13 @@ static Item *create_func_number(MY_XPATH *xpath, Item **args, uint nargs)
|
|||
}
|
||||
|
||||
|
||||
static Item *create_func_string_length(MY_XPATH *xpath, Item **args, uint nargs)
|
||||
{
|
||||
Item *arg= nargs ? args[0] : xpath->context;
|
||||
return arg ? new Item_func_char_length(arg) : 0;
|
||||
}
|
||||
|
||||
|
||||
static Item *create_func_round(MY_XPATH *xpath, Item **args, uint nargs)
|
||||
{
|
||||
return new Item_func_round(args[0], new Item_int((char*)"0",0,1),0);
|
||||
|
@ -1246,6 +1253,7 @@ static MY_XPATH_FUNC my_func_names[] =
|
|||
{"local-name" , 10 , 0 , 1 , 0},
|
||||
{"starts-with" , 11 , 2 , 2 , 0},
|
||||
{"namespace-uri" , 13 , 0 , 1 , 0},
|
||||
{"string-length" , 13 , 0 , 1 , create_func_string_length},
|
||||
{"substring-after" , 15 , 2 , 2 , 0},
|
||||
{"normalize-space" , 15 , 0 , 1 , 0},
|
||||
{"substring-before" , 16 , 2 , 2 , 0},
|
||||
|
@ -1837,7 +1845,11 @@ static int my_xpath_parse_FunctionCall(MY_XPATH *xpath)
|
|||
for (nargs= 0 ; nargs < func->maxargs; )
|
||||
{
|
||||
if (!my_xpath_parse_Expr(xpath))
|
||||
return 0;
|
||||
{
|
||||
if (nargs < func->minargs)
|
||||
return 0;
|
||||
goto right_paren;
|
||||
}
|
||||
args[nargs++]= xpath->item;
|
||||
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_COMMA))
|
||||
{
|
||||
|
@ -1847,6 +1859,8 @@ static int my_xpath_parse_FunctionCall(MY_XPATH *xpath)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
right_paren:
|
||||
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_RP))
|
||||
return 0;
|
||||
|
||||
|
|
38
sql/log.cc
38
sql/log.cc
|
@ -676,20 +676,36 @@ bool LOGGER::flush_logs(THD *thd)
|
|||
/* reopen log files */
|
||||
file_log_handler->flush();
|
||||
|
||||
/*
|
||||
this will lock and wait for all but the logger thread to release the
|
||||
tables. Then we could reopen log tables. Then release the name locks.
|
||||
*/
|
||||
lock_and_wait_for_table_name(thd, &close_slow_log);
|
||||
lock_and_wait_for_table_name(thd, &close_general_log);
|
||||
/* flush tables, in the case they are enabled */
|
||||
if (logger.is_log_tables_initialized)
|
||||
{
|
||||
/*
|
||||
This will lock and wait for all but the logger thread to release the
|
||||
tables. Then we could reopen log tables. Then release the name locks.
|
||||
|
||||
/* deny others from logging to general and slow log, while reopening tables */
|
||||
logger.lock();
|
||||
NOTE: in fact, the first parameter used in lock_and_wait_for_table_name()
|
||||
and table_log_handler->flush() could be any non-NULL THD, as the
|
||||
underlying code makes certain assumptions about this.
|
||||
Here we use one of the logger handler THD's. Simply because it
|
||||
seems appropriate.
|
||||
*/
|
||||
lock_and_wait_for_table_name(table_log_handler->general_log_thd,
|
||||
&close_slow_log);
|
||||
lock_and_wait_for_table_name(table_log_handler->general_log_thd,
|
||||
&close_general_log);
|
||||
|
||||
table_log_handler->flush(thd, &close_slow_log, &close_general_log);
|
||||
/*
|
||||
Deny others from logging to general and slow log,
|
||||
while reopening tables.
|
||||
*/
|
||||
logger.lock();
|
||||
|
||||
/* end of log tables flush */
|
||||
logger.unlock();
|
||||
table_log_handler->flush(table_log_handler->general_log_thd,
|
||||
&close_slow_log, &close_general_log);
|
||||
|
||||
/* end of log tables flush */
|
||||
logger.unlock();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6579,18 +6579,6 @@ int Delete_rows_log_event::do_before_row_operations(TABLE *table)
|
|||
if (!m_memory)
|
||||
return HA_ERR_OUT_OF_MEM;
|
||||
|
||||
if (table->s->keys > 0)
|
||||
{
|
||||
/* We have a key: search the table using the index */
|
||||
if (!table->file->inited)
|
||||
error= table->file->ha_index_init(0, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We doesn't have a key: search the table using rnd_next() */
|
||||
error= table->file->ha_rnd_init(1);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -6638,6 +6626,20 @@ int Delete_rows_log_event::do_exec_row(TABLE *table)
|
|||
{
|
||||
DBUG_ASSERT(table != NULL);
|
||||
|
||||
if (table->s->keys > 0)
|
||||
{
|
||||
/* We have a key: search the table using the index */
|
||||
if (!table->file->inited)
|
||||
if (int error= table->file->ha_index_init(0, FALSE))
|
||||
return error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We doesn't have a key: search the table using rnd_next() */
|
||||
if (int error= table->file->ha_rnd_init(1))
|
||||
return error;
|
||||
}
|
||||
|
||||
int error= find_and_fetch_row(table, m_key);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -6649,6 +6651,11 @@ int Delete_rows_log_event::do_exec_row(TABLE *table)
|
|||
*/
|
||||
error= table->file->ha_delete_row(table->record[0]);
|
||||
|
||||
/*
|
||||
Have to restart the scan to be able to fetch the next row.
|
||||
*/
|
||||
table->file->ha_index_or_rnd_end();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,12 +72,19 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
|
|||
|
||||
uint tablename_to_filename(const char *from, char *to, uint to_length)
|
||||
{
|
||||
uint errors;
|
||||
uint errors, length;
|
||||
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
|
||||
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
|
||||
return my_snprintf(to, to_length, "%s", from + 9);
|
||||
return strconvert(system_charset_info, from,
|
||||
&my_charset_filename, to, to_length, &errors);
|
||||
length= strconvert(system_charset_info, from,
|
||||
&my_charset_filename, to, to_length, &errors);
|
||||
if (check_if_legal_tablename(to) &&
|
||||
length + 4 < to_length)
|
||||
{
|
||||
memcpy(to + length, "@@@", 4);
|
||||
length+= 3;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
|
||||
static handler* example_create_handler(TABLE_SHARE *table);
|
||||
static int example_init_func();
|
||||
static bool example_init_func_for_handlerton();
|
||||
static int example_panic(enum ha_panic_function flag);
|
||||
|
||||
handlerton example_hton= {
|
||||
MYSQL_HANDLERTON_INTERFACE_VERSION,
|
||||
|
@ -81,7 +83,7 @@ handlerton example_hton= {
|
|||
SHOW_OPTION_YES,
|
||||
"Example storage engine",
|
||||
DB_TYPE_EXAMPLE_DB,
|
||||
(bool (*)()) example_init_func,
|
||||
example_init_func_for_handlerton,
|
||||
0, /* slot */
|
||||
0, /* savepoint size. */
|
||||
NULL, /* close_connection */
|
||||
|
@ -99,7 +101,7 @@ handlerton example_hton= {
|
|||
NULL, /* close_cursor_read_view */
|
||||
example_create_handler, /* Create a new handler */
|
||||
NULL, /* Drop a database */
|
||||
NULL, /* Panic call */
|
||||
example_panic, /* Panic call */
|
||||
NULL, /* Start Consistent Snapshot */
|
||||
NULL, /* Flush logs */
|
||||
NULL, /* Show status */
|
||||
|
@ -107,7 +109,10 @@ handlerton example_hton= {
|
|||
NULL, /* Alter table flags */
|
||||
NULL, /* Alter tablespace */
|
||||
NULL, /* Fill Files table */
|
||||
HTON_CAN_RECREATE
|
||||
HTON_CAN_RECREATE,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Variables for example share methods */
|
||||
|
@ -126,32 +131,43 @@ static byte* example_get_key(EXAMPLE_SHARE *share,uint *length,
|
|||
return (byte*) share->table_name;
|
||||
}
|
||||
|
||||
|
||||
static int example_init_func()
|
||||
{
|
||||
DBUG_ENTER("example_init_func");
|
||||
if (!example_init)
|
||||
{
|
||||
example_init++;
|
||||
example_init= 1;
|
||||
VOID(pthread_mutex_init(&example_mutex,MY_MUTEX_INIT_FAST));
|
||||
(void) hash_init(&example_open_tables,system_charset_info,32,0,0,
|
||||
(hash_get_key) example_get_key,0,0);
|
||||
}
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static int example_done_func()
|
||||
{
|
||||
int error= 0;
|
||||
DBUG_ENTER("example_done_func");
|
||||
|
||||
if (example_init)
|
||||
{
|
||||
example_init= 0;
|
||||
if (example_open_tables.records)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
error= 1;
|
||||
hash_free(&example_open_tables);
|
||||
pthread_mutex_destroy(&example_mutex);
|
||||
example_init--;
|
||||
}
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static bool example_init_func_for_handlerton()
|
||||
{
|
||||
return example_init_func();
|
||||
}
|
||||
|
||||
static int example_panic(enum ha_panic_function flag)
|
||||
{
|
||||
return example_done_func();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ include $(top_srcdir)/storage/ndb/config/common.mk.am
|
|||
|
||||
dist-hook:
|
||||
-rm -rf `find $(distdir) -type d -name SCCS`
|
||||
-rm -rf `find $(distdir) -type d -name old_files`
|
||||
-rm -rf `find $(distdir)/ndbapi-examples -name '*.o'`
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" != "." -a "$$subdir" != "include"; then \
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
CC=gcc
|
||||
LD=$(CC)
|
||||
SOURCES=memtest.c
|
||||
OUTPUT=memtest
|
||||
all:
|
||||
$(CC) $(SOURCES) -o $(OUTPUT)
|
||||
|
||||
debug:
|
||||
$(CC) -g $(SOURCES) -o $(OUTPUT)
|
||||
|
||||
clean: rm -rf *.o
|
||||
rm -rf core*
|
|
@ -1,14 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
TYPE := ndbapitest
|
||||
BIN_TARGET := munmaptest
|
||||
|
||||
|
||||
SOURCES = munmaptest.cpp
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
TYPE :=
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
ARCHIVE_TARGET := portlib
|
||||
|
||||
SOURCES = NdbOut.cpp
|
||||
|
||||
SOURCES.c = NdbCondition.c \
|
||||
NdbMutex.c \
|
||||
NdbSleep.c \
|
||||
NdbTick.c \
|
||||
NdbEnv.c \
|
||||
NdbThread.c \
|
||||
NdbHost.c \
|
||||
NdbTCP.c
|
||||
|
||||
ifeq ($(NDB_OS), SOFTOSE)
|
||||
SOURCES += NdbMem_SoftOse.cpp
|
||||
else
|
||||
SOURCES.c += NdbMem.c
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbCondition.h"
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <NdbMutex.h>
|
||||
|
||||
#include "NdbConditionOSE.h"
|
||||
struct NdbCondition
|
||||
{
|
||||
PROCESS condserv_pid;
|
||||
};
|
||||
|
||||
|
||||
OS_PROCESS(ndbcond_serv){
|
||||
|
||||
union SIGNAL* sig;
|
||||
union SIGNAL* sig2;
|
||||
|
||||
static const SIGSELECT sel_signal[] = {2, NDBCOND_SIGNAL, NDBCOND_BROADCAST};
|
||||
static const SIGSELECT sel_cond[] = {2, NDBCOND_WAIT, NDBCOND_WAITTIMEOUT};
|
||||
|
||||
for(;;){
|
||||
/* Receive condition wait signal */
|
||||
sig = receive((SIGSELECT*)sel_cond);
|
||||
if (sig != NIL){
|
||||
switch (sig->sigNo){
|
||||
|
||||
case NDBCOND_WAIT:
|
||||
/* Wait for a SIGNAL or BROADCAST from anyone */
|
||||
sig2 = receive((SIGSELECT*)sel_signal);
|
||||
if (sig2 != NIL){
|
||||
switch(sig2->sigNo){
|
||||
|
||||
case NDBCOND_SIGNAL:
|
||||
((struct NdbCondWait*)sig)->status = NDBCOND_SIGNALED;
|
||||
/* Send signal back to the one waiting for this condition */
|
||||
send(&sig, sender(&sig));
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
/* Not handled yet */
|
||||
assert(1==0);
|
||||
break;
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
}
|
||||
free_buf(&sig2);
|
||||
}
|
||||
break;
|
||||
|
||||
case NDBCOND_WAITTIMEOUT:
|
||||
/* Wait for a SIGNAL or BROADCAST from anyone */
|
||||
sig2 = receive_w_tmo(((struct NdbCondWaitTimeout*)sig)->timeout, (SIGSELECT*)sel_signal);
|
||||
if (sig2 != NIL){
|
||||
switch(sig2->sigNo){
|
||||
|
||||
case NDBCOND_SIGNAL:
|
||||
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_SIGNALED;
|
||||
/* Send signal back to the one waiting for this condition */
|
||||
send(&sig, sender(&sig));
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
/* Not handled yet */
|
||||
assert(1==0);
|
||||
break;
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
}
|
||||
free_buf(&sig2);
|
||||
}else{
|
||||
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_TIMEOUT;
|
||||
send(&sig, sender(&sig));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct NdbCondition*
|
||||
NdbCondition_Create(void)
|
||||
{
|
||||
struct NdbCondition* tmpCond;
|
||||
|
||||
|
||||
tmpCond = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
|
||||
|
||||
if (tmpCond == NULL)
|
||||
return NULL;
|
||||
|
||||
/**
|
||||
* Start this process with a quite high
|
||||
* priority, we want it to be responsive
|
||||
*/
|
||||
tmpCond->condserv_pid = create_process(OS_PRI_PROC, /* Process type */
|
||||
"ndbcond_serv", /* Name */
|
||||
ndbcond_serv, /* Entry point */
|
||||
2048, /* Stack size */
|
||||
10, /* Priority */
|
||||
0, /* Time slice */
|
||||
get_bid(current_process()), /* Block */
|
||||
NULL, /* Redir table */
|
||||
0,
|
||||
0);
|
||||
|
||||
start(tmpCond->condserv_pid);
|
||||
|
||||
return tmpCond;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Wait(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex)
|
||||
{
|
||||
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAIT};
|
||||
union SIGNAL* sig;
|
||||
int result;
|
||||
if (p_cond == NULL || p_mutex == NULL)
|
||||
return 0;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondWait), NDBCOND_WAIT);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
NdbMutex_Unlock(p_mutex);
|
||||
|
||||
result = 1;
|
||||
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBCOND_WAIT){
|
||||
/* Condition is signaled */
|
||||
result = 0;
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
|
||||
}
|
||||
NdbMutex_Lock(p_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex,
|
||||
int msecs){
|
||||
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAITTIMEOUT};
|
||||
union SIGNAL* sig;
|
||||
int result;
|
||||
if (p_cond == NULL || p_mutex == NULL)
|
||||
return 0;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondWaitTimeout), NDBCOND_WAITTIMEOUT);
|
||||
((struct NdbCondWaitTimeout*)sig)->timeout = msecs;
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
NdbMutex_Unlock(p_mutex);
|
||||
|
||||
result = 1;
|
||||
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBCOND_WAITTIMEOUT){
|
||||
/* Condition is signaled */
|
||||
result = 0;
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
|
||||
}
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Signal(struct NdbCondition* p_cond){
|
||||
|
||||
union SIGNAL* sig;
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondSignal), NDBCOND_SIGNAL);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
|
||||
{
|
||||
union SIGNAL* sig;
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
sig = alloc(sizeof(struct NdbCondBroadcast), NDBCOND_BROADCAST);
|
||||
send(&sig, p_cond->condserv_pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Destroy(struct NdbCondition* p_cond)
|
||||
{
|
||||
if (p_cond == NULL)
|
||||
return 1;
|
||||
|
||||
kill_proc(p_cond->condserv_pid);
|
||||
free(p_cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef NDB_CONDITIONOSE_H
|
||||
#define NDB_CONDITIONOSE_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define NDBCOND_SIGBASE 4000
|
||||
|
||||
#define NDBCOND_WAIT (NDBCOND_SIGBASE + 1) /* !-SIGNO(struct NdbCondWait)-! */
|
||||
#define NDBCOND_WAITTIMEOUT (NDBCOND_SIGBASE + 2) /* !-SIGNO(struct NdbCondWaitTimeOut)-! */
|
||||
#define NDBCOND_SIGNAL (NDBCOND_SIGBASE + 3) /* !-SIGNO(struct NdbCondSignal)-! */
|
||||
#define NDBCOND_BROADCAST (NDBCOND_SIGBASE + 4) /* !-SIGNO(struct NdbCondBroadcast)-! */
|
||||
|
||||
|
||||
const char *
|
||||
sigNo2String(SIGSELECT sigNo){
|
||||
switch(sigNo){
|
||||
case NDBCOND_WAIT:
|
||||
return "NDBCOND_WAIT";
|
||||
break;
|
||||
case NDBCOND_WAITTIMEOUT:
|
||||
return "NDBCOND_WAITTIMEOUT";
|
||||
break;
|
||||
case NDBCOND_SIGNAL:
|
||||
return "NDBCOND_SIGNAL";
|
||||
break;
|
||||
case NDBCOND_BROADCAST:
|
||||
return "NDBCOND_BROADCAST";
|
||||
break;
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
struct NdbCondWait
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
int status;
|
||||
};
|
||||
|
||||
/**
|
||||
* Signal received
|
||||
*/
|
||||
#define NDBCOND_SIGNALED 1
|
||||
|
||||
/**
|
||||
* Timeout occured
|
||||
*/
|
||||
#define NDBCOND_TIMEOUT 2
|
||||
|
||||
struct NdbCondWaitTimeout
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
int timeout;
|
||||
int status;
|
||||
|
||||
};
|
||||
|
||||
struct NdbCondSignal
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
struct NdbCondBroadcast
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct NdbCondWait condWait;
|
||||
struct NdbCondWaitTimeout condWaitTimeout;
|
||||
struct NdbCondSignal condSignal;
|
||||
struct NdbCondBroadcast condBroadcast;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbEnv.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
|
||||
{
|
||||
/**
|
||||
* All environment variables are associated with a process
|
||||
* it's important to read env from the correct process
|
||||
* for now read from own process, own block and last the "ose_shell" process.
|
||||
*
|
||||
* TODO! What process should this be read from in the future?
|
||||
*
|
||||
*/
|
||||
PROCESS proc_;
|
||||
char* p = NULL;
|
||||
/* Look in own process */
|
||||
p = get_env(current_process(), (char*)name);
|
||||
if (p == NULL){
|
||||
/* Look in block process */
|
||||
p = get_env(get_bid(current_process()), (char*)name);
|
||||
if (p == NULL){
|
||||
/* Look in ose_shell process */
|
||||
if (hunt("ose_shell", 0, &proc_, NULL)){
|
||||
p = get_env(proc_, (char*)name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p != NULL){
|
||||
strncpy(buf, p, buflen);
|
||||
buf[buflen-1] = 0;
|
||||
free_buf((union SIGNAL **)&p);
|
||||
p = buf;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbHost.h"
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include <inet.sig>
|
||||
#include <string.h>
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct InetIfUp inetIfUp;
|
||||
};
|
||||
|
||||
int NdbHost_GetHostName(char* buf)
|
||||
{
|
||||
#if 0
|
||||
extern PROCESS ose_inet_;
|
||||
union SIGNAL *signal;
|
||||
static const SIGSELECT select_if_up_reply[] = { 1, INET_IF_UP_REPLY };
|
||||
|
||||
signal = alloc(sizeof(struct InetIfUp), INET_IF_UP_REQUEST);
|
||||
strcpy(signal->inetIfUp.ifName, "*");
|
||||
send((union SIGNAL **)&signal, ose_inet_);
|
||||
signal = receive((SIGSELECT *)select_if_up_reply);
|
||||
strcpy(buf, signal->inetIfUp.ifName);
|
||||
free_buf(&signal);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int NdbHost_GetProcessId(void)
|
||||
{
|
||||
return current_process();
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbMem.h"
|
||||
|
||||
|
||||
#if defined NDB_OSE
|
||||
#include <ose.h>
|
||||
#include <mms.sig>
|
||||
#include <mms_err.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <NdbOut.hpp>
|
||||
|
||||
// Page size for mp750 is 4096 bytes.
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
/**
|
||||
* NOTE: To use NdbMem from a OSE system ose_mms has to be defined
|
||||
* as a "Required External Process"(see OSE Kernel User's Guide/R1.1(p. 148)),
|
||||
* like this in osemain.con:
|
||||
* EXT_PROC(ose_mms, ose_mms, 50000)
|
||||
* This will create a global variable ose_mms_ that is used from here.
|
||||
*/
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct MmsAllocateRegionRequest mmsAllocateRegionRequest;
|
||||
struct MmsAllocateRegionReply mmsAllocateRegionReply;
|
||||
struct MmsFreeRegionRequest mmsFreeRegionRequest;
|
||||
struct MmsFreeRegionReply mmsFreeRegionReply;
|
||||
}; /* union SIGNAL */
|
||||
|
||||
extern PROCESS ose_mms_;
|
||||
|
||||
void NdbMem_Create(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
static SIGSELECT allocate_sig[] = {1,MMS_ALLOCATE_REGION_REPLY};
|
||||
union SIGNAL *sig;
|
||||
U32 allocatedAdress;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
// Only allowed to allocate multiples of the page size.
|
||||
if(size % PAGE_SIZE != 0) {
|
||||
size += PAGE_SIZE - size%PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Allocate a new region in the callers memory segment. */
|
||||
sig = alloc(sizeof(struct MmsAllocateRegionRequest),
|
||||
MMS_ALLOCATE_REGION_REQUEST);
|
||||
/* -1: The callers domain is used */
|
||||
sig->mmsAllocateRegionRequest.domain = (MemoryDomain)-1;
|
||||
sig->mmsAllocateRegionRequest.useAddr = False;
|
||||
sig->mmsAllocateRegionRequest.size = size;
|
||||
sig->mmsAllocateRegionRequest.access = SuperRW_UserRW;
|
||||
sig->mmsAllocateRegionRequest.resident = False;
|
||||
sig->mmsAllocateRegionRequest.memory = CodeData;
|
||||
sig->mmsAllocateRegionRequest.cache = CopyBack;
|
||||
strcpy(sig->mmsAllocateRegionRequest.name, "NDB_DATA");
|
||||
send(&sig, ose_mms_);
|
||||
sig = receive(allocate_sig);
|
||||
|
||||
if (sig->mmsAllocateRegionReply.status != MMS_SUCCESS){
|
||||
/* Memory allocation failed, make sure this function returns NULL */
|
||||
allocatedAdress = NULL;
|
||||
}
|
||||
else{
|
||||
allocatedAdress = sig->mmsAllocateRegionReply.address;
|
||||
}
|
||||
free_buf(&sig);
|
||||
return (void*)allocatedAdress;
|
||||
}
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
static SIGSELECT free_sig[] = {1,MMS_FREE_REGION_REPLY};
|
||||
union SIGNAL *sig;
|
||||
|
||||
/* Free a region in the callers domain. */
|
||||
sig = alloc(sizeof(struct MmsFreeRegionRequest),
|
||||
MMS_FREE_REGION_REQUEST);
|
||||
sig->mmsFreeRegionRequest.address = (U32)ptr;
|
||||
send(&sig, ose_mms_);
|
||||
sig = receive(free_sig);
|
||||
|
||||
if (sig->mmsFreeRegionReply.status != MMS_SUCCESS){
|
||||
ndbout_c("The MMS Region could not be deallocated.\r\n");
|
||||
error(sig->mmsFreeRegionReply.status);
|
||||
};
|
||||
free_buf(&sig);
|
||||
}
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void NdbMem_Create()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
assert(size > 0);
|
||||
return (void*)malloc(size);
|
||||
}
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
/*
|
||||
return (void*)memalign(alignment, size);
|
||||
TEMP fix
|
||||
*/
|
||||
return (void*)malloc(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbMem.h"
|
||||
|
||||
extern "C"
|
||||
void NdbMem_Create()
|
||||
{
|
||||
}
|
||||
extern "C"
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
return new char[size];
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
delete [] (char *)(ptr);
|
||||
}
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll(){
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbMutex.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
NdbMutex* NdbMutex_Create(void)
|
||||
{
|
||||
NdbMutex* pNdbMutex;
|
||||
|
||||
pNdbMutex = create_sem(1);
|
||||
|
||||
return pNdbMutex;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Destroy(NdbMutex* p_mutex)
|
||||
{
|
||||
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
kill_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Lock(NdbMutex* p_mutex)
|
||||
{
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
wait_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Unlock(NdbMutex* p_mutex)
|
||||
{
|
||||
|
||||
if (p_mutex == NULL)
|
||||
return -1;
|
||||
|
||||
signal_sem(p_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Trylock(NdbMutex* p_mutex)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (p_mutex != NULL) {
|
||||
OSSEMVAL semvalue = get_sem(p_mutex);
|
||||
if (semvalue > 0) {
|
||||
wait_sem(p_mutex);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <ndb_global.h>
|
||||
|
||||
#include "NdbOut.hpp"
|
||||
|
||||
#if defined NDB_SOFTOSE
|
||||
#include <dbgprintf.h>
|
||||
#define printfunc dbgprintf
|
||||
#else
|
||||
#define printfunc printf
|
||||
#endif
|
||||
|
||||
static char const* const endlineString = "\r\n";
|
||||
|
||||
static int CtrlC = 0;
|
||||
NdbOut ndbout;
|
||||
|
||||
|
||||
NdbOut& NdbOut::operator<<(int aVal)
|
||||
{
|
||||
char* format;
|
||||
char HexFormat[] = "0x%08x";
|
||||
char DecFormat[] = "%d";
|
||||
if (isHexFormat == 1)
|
||||
format = HexFormat;
|
||||
else
|
||||
format = DecFormat;
|
||||
|
||||
printfunc(format, aVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::operator<<(char* pVal)
|
||||
{
|
||||
printfunc("%s", pVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::endline()
|
||||
{
|
||||
isHexFormat = 0; // Reset hex to normal, if user forgot this
|
||||
printfunc(endlineString);
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::flushline()
|
||||
{
|
||||
isHexFormat = 0; // Reset hex to normal, if user forgot this
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut& NdbOut::setHexFormat(int _format)
|
||||
{
|
||||
isHexFormat = _format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
NdbOut::NdbOut()
|
||||
{
|
||||
CtrlC = 0;
|
||||
isHexFormat = 0;
|
||||
}
|
||||
|
||||
NdbOut::~NdbOut()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
void
|
||||
ndbout_c(const char * fmt, ...){
|
||||
va_list ap;
|
||||
char buf[1000];
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (fmt != 0)
|
||||
vsnprintf(buf, sizeof(buf)-1, fmt, ap);
|
||||
ndbout << buf << endl;
|
||||
va_end(ap);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbSleep.h"
|
||||
|
||||
#include <ose.h>
|
||||
|
||||
|
||||
int
|
||||
NdbSleep_MilliSleep(int milliseconds){
|
||||
const OSTIME millisecond_delay = milliseconds;
|
||||
delay(millisecond_delay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbSleep_SecSleep(int seconds){
|
||||
const OSTIME millisecond_delay = seconds*1000;
|
||||
delay(millisecond_delay);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbTCP.h"
|
||||
|
||||
|
||||
int
|
||||
Ndb_getInAddr(struct in_addr * dst, const char *address) {
|
||||
struct hostent * host;
|
||||
host = gethostbyname_r(address);
|
||||
if(host != 0){
|
||||
dst->s_addr = ((struct in_addr *) *host->h_addr_list)->s_addr;
|
||||
free_buf((union SIGNAL **)&host);
|
||||
return 0;
|
||||
}
|
||||
/* Try it as aaa.bbb.ccc.ddd. */
|
||||
dst->s_addr = inet_addr(address);
|
||||
if (dst->s_addr != INADDR_NONE) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbThread.h"
|
||||
#include <pthread.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <NdbOut.hpp>
|
||||
|
||||
#define MAX_THREAD_NAME 16
|
||||
|
||||
|
||||
struct NdbThread
|
||||
{
|
||||
PROCESS pid;
|
||||
char thread_name[MAX_THREAD_NAME];
|
||||
};
|
||||
|
||||
#define NDBTHREAD_SIGBASE 4010
|
||||
|
||||
#define NDBTHREAD_START (NDBTHREAD_SIGBASE + 1) /* !-SIGNO(struct NdbThreadStart)-! */
|
||||
|
||||
struct NdbThreadStart
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
NDB_THREAD_FUNC* func;
|
||||
NDB_THREAD_ARG arg;
|
||||
};
|
||||
|
||||
struct NdbThreadStopped
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
};
|
||||
|
||||
union SIGNAL
|
||||
{
|
||||
SIGSELECT sigNo;
|
||||
struct NdbThreadStart threadStart;
|
||||
struct NdbThreadStopped threadStopped;
|
||||
};
|
||||
|
||||
OS_PROCESS(thread_starter){
|
||||
static const SIGSELECT sel_start[] = {1, NDBTHREAD_START};
|
||||
struct NdbThreadStart* sigstart;
|
||||
union SIGNAL* sig;
|
||||
|
||||
/* Receive function adress and params */
|
||||
sig = receive((SIGSELECT*)sel_start);
|
||||
if (sig != NIL){
|
||||
if (sig->sigNo == NDBTHREAD_START){
|
||||
sigstart = ((struct NdbThreadStart*)sig);
|
||||
/* Execute function with arg */
|
||||
(*sigstart->func)(sigstart->arg);
|
||||
}else{
|
||||
assert(1==0);
|
||||
}
|
||||
free_buf(&sig);
|
||||
}
|
||||
}
|
||||
|
||||
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC* p_thread_func,
|
||||
NDB_THREAD_ARG *p_thread_arg,
|
||||
const NDB_THREAD_STACKSIZE thread_stack_size,
|
||||
const char* p_thread_name,
|
||||
NDB_THREAD_PRIO thread_prio)
|
||||
{
|
||||
struct NdbThread* tmpThread;
|
||||
union SIGNAL* sig;
|
||||
int ose_prio;
|
||||
|
||||
if (p_thread_func == NULL)
|
||||
return 0;
|
||||
|
||||
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
|
||||
if (tmpThread == NULL)
|
||||
return NULL;
|
||||
|
||||
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
|
||||
|
||||
switch(thread_prio){
|
||||
case NDB_THREAD_PRIO_HIGHEST:
|
||||
ose_prio = 1;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_HIGH:
|
||||
ose_prio = 10;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_MEAN:
|
||||
ose_prio = 16;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_LOW:
|
||||
ose_prio = 23;
|
||||
break;
|
||||
case NDB_THREAD_PRIO_LOWEST:
|
||||
ose_prio = 31;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create process */
|
||||
tmpThread->pid = create_process(OS_PRI_PROC, /* Process type */
|
||||
(char*)p_thread_name, /* Name */
|
||||
thread_starter, /* Entry point */
|
||||
thread_stack_size, /* Stack size */
|
||||
ose_prio, /* Priority */
|
||||
0, /* Time slice */
|
||||
get_bid(current_process()), /* Block */
|
||||
NULL, /* Redir table */
|
||||
0,
|
||||
0);
|
||||
|
||||
/* Send params to process */
|
||||
sig = alloc(sizeof(struct NdbThreadStart), NDBTHREAD_START);
|
||||
((struct NdbThreadStart*)sig)->func = p_thread_func;
|
||||
((struct NdbThreadStart*)sig)->arg = p_thread_arg;
|
||||
send(&sig, tmpThread->pid);
|
||||
|
||||
/* Enable NDB_HOME environment variable for the thread */
|
||||
{
|
||||
/* Hardcoded NDB_HOME...*/
|
||||
char* ndb_home_env = get_env(current_process(), "NDB_HOME");
|
||||
if (ndb_home_env != NULL)
|
||||
{
|
||||
/* Set NDB_HOME */
|
||||
int rc = set_env(tmpThread->pid, "NDB_HOME", ndb_home_env);
|
||||
if (rc != 0)
|
||||
{
|
||||
/* Not really a problem */
|
||||
}
|
||||
} /* Enable NDB_HOME */
|
||||
}
|
||||
|
||||
/* Start process */
|
||||
start(tmpThread->pid);
|
||||
|
||||
return tmpThread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NdbThread_Destroy(struct NdbThread** p_thread)
|
||||
{
|
||||
free(* p_thread); * p_thread = 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
|
||||
{
|
||||
while(hunt(p_wait_thread->thread_name, 0, NULL, NULL) != 0)
|
||||
delay(1000);
|
||||
|
||||
* status = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Exit(int a)
|
||||
{
|
||||
kill_proc(current_process());
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_SetConcurrencyLevel(int level)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbTick.h"
|
||||
#include <time.h>
|
||||
|
||||
#define NANOSEC_PER_SEC 1000000000
|
||||
#define MICROSEC_PER_SEC 1000000
|
||||
#define MILLISEC_PER_SEC 1000
|
||||
#define MICROSEC_PER_MILLISEC 1000
|
||||
#define MILLISEC_PER_NANOSEC 1000000
|
||||
|
||||
#ifdef NDB_OSE
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
return get_ticks()*4;
|
||||
}
|
||||
#include <rtc.h>
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
|
||||
struct TimePair tvp;
|
||||
rtc_get_time(&tvp);
|
||||
* secs = tvp.seconds;
|
||||
* micros = tvp.micros;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined NDB_SOFTOSE
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
/**
|
||||
* Depends on the interval counter in solaris
|
||||
* that means each "tick" in OSE is really 10 milliseconds
|
||||
*/
|
||||
return get_ticks()*10;
|
||||
}
|
||||
|
||||
#include <rtc.h>
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
|
||||
struct TimePair tvp;
|
||||
rtc_get_time(&tvp);
|
||||
* secs = tvp.seconds;
|
||||
* micros = tvp.micros;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
TYPE := kernel
|
||||
|
||||
BIN_TARGET := PortLibTest
|
||||
BIN_TARGET_ARCHIVES := portlib general
|
||||
|
||||
SOURCES = NdbPortLibTest.cpp
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
TYPE := util
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
ARCHIVE_TARGET := portlib
|
||||
|
||||
SOURCES.c = NdbCondition.c \
|
||||
NdbMutex.c \
|
||||
NdbSleep.c \
|
||||
NdbTick.c \
|
||||
NdbEnv.c \
|
||||
NdbThread.c \
|
||||
NdbHost.c \
|
||||
NdbTCP.c \
|
||||
NdbDaemon.c
|
||||
|
||||
ifeq ($(NDB_OS), SOFTOSE)
|
||||
SOURCES += NdbMem_SoftOse.cpp
|
||||
else
|
||||
SOURCES.c += NdbMem.c
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "NdbCondition.h"
|
||||
#include <NdbMutex.h>
|
||||
|
||||
|
||||
struct NdbCondition
|
||||
{
|
||||
long nWaiters;
|
||||
NdbMutex* pNdbMutexWaitersLock;
|
||||
HANDLE hSemaphore;
|
||||
HANDLE hEventWaitersDone;
|
||||
int bWasBroadcast;
|
||||
};
|
||||
|
||||
|
||||
struct NdbCondition*
|
||||
NdbCondition_Create(void)
|
||||
{
|
||||
int result = 0;
|
||||
struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
|
||||
if(!pNdbCondition)
|
||||
return 0;
|
||||
|
||||
pNdbCondition->nWaiters = 0;
|
||||
pNdbCondition->bWasBroadcast = 0;
|
||||
if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
|
||||
result = -1;
|
||||
else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
|
||||
result = -1;
|
||||
else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
|
||||
result = -1;
|
||||
|
||||
assert(!result);
|
||||
return pNdbCondition;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Wait(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex)
|
||||
{
|
||||
int result;
|
||||
int bLastWaiter;
|
||||
if(!p_cond || !p_mutex)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters++;
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(NdbMutex_Unlock(p_mutex))
|
||||
return -1;
|
||||
result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters--;
|
||||
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(result==WAIT_OBJECT_0 && bLastWaiter)
|
||||
SetEvent(p_cond->hEventWaitersDone);
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
|
||||
NdbMutex* p_mutex,
|
||||
int msecs)
|
||||
{
|
||||
int result;
|
||||
int bLastWaiter;
|
||||
if (!p_cond || !p_mutex)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters++;
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
if(msecs<0)
|
||||
msecs = 0;
|
||||
|
||||
if(NdbMutex_Unlock(p_mutex))
|
||||
return -1;
|
||||
result = WaitForSingleObject(p_cond->hSemaphore, msecs);
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
p_cond->nWaiters--;
|
||||
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(result!=WAIT_OBJECT_0)
|
||||
result = -1;
|
||||
|
||||
if(bLastWaiter)
|
||||
SetEvent(p_cond->hEventWaitersDone);
|
||||
|
||||
NdbMutex_Lock(p_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NdbCondition_Signal(struct NdbCondition* p_cond)
|
||||
{
|
||||
int bHaveWaiters;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
bHaveWaiters = (p_cond->nWaiters > 0);
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
|
||||
if(bHaveWaiters)
|
||||
return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
|
||||
{
|
||||
int bHaveWaiters;
|
||||
int result = 0;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
|
||||
bHaveWaiters = 0;
|
||||
if(p_cond->nWaiters > 0)
|
||||
{
|
||||
p_cond->bWasBroadcast = !0;
|
||||
bHaveWaiters = 1;
|
||||
}
|
||||
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
|
||||
if(bHaveWaiters)
|
||||
{
|
||||
if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
|
||||
result = -1;
|
||||
else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
|
||||
result = -1;
|
||||
p_cond->bWasBroadcast = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int NdbCondition_Destroy(struct NdbCondition* p_cond)
|
||||
{
|
||||
int result;
|
||||
if(!p_cond)
|
||||
return 1;
|
||||
|
||||
CloseHandle(p_cond->hEventWaitersDone);
|
||||
NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
|
||||
result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1);
|
||||
|
||||
free(p_cond);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <ndb_global.h>
|
||||
#include "NdbDaemon.h"
|
||||
|
||||
#define NdbDaemon_ErrorSize 500
|
||||
long NdbDaemon_DaemonPid;
|
||||
int NdbDaemon_ErrorCode;
|
||||
char NdbDaemon_ErrorText[NdbDaemon_ErrorSize];
|
||||
|
||||
int
|
||||
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
|
||||
{
|
||||
/* Fail */
|
||||
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
|
||||
"Daemon mode not implemented");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef NDB_DAEMON_TEST
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
|
||||
fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
|
||||
return 1;
|
||||
}
|
||||
sleep(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbEnv.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
|
||||
{
|
||||
char* p = NULL;
|
||||
p = getenv(name);
|
||||
|
||||
if (p != NULL && buf != NULL){
|
||||
strncpy(buf, p, buflen);
|
||||
buf[buflen-1] = 0;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbHost.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
int NdbHost_GetHostName(char* buf)
|
||||
{
|
||||
/* We must initialize TCP/IP if we want to call gethostname */
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
|
||||
wVersionRequested = MAKEWORD( 2, 0 );
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( err != 0 ) {
|
||||
/**
|
||||
* Tell the user that we couldn't find a usable
|
||||
* WinSock DLL.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get host name */
|
||||
if(gethostname(buf, MAXHOSTNAMELEN))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbHost_GetProcessId(void)
|
||||
{
|
||||
return _getpid();
|
||||
}
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <windows.h>
|
||||
|
||||
#include "NdbMem.h"
|
||||
|
||||
|
||||
struct AWEINFO
|
||||
{
|
||||
SIZE_T dwSizeInBytesRequested;
|
||||
ULONG_PTR nNumberOfPagesRequested;
|
||||
ULONG_PTR nNumberOfPagesActual;
|
||||
ULONG_PTR nNumberOfPagesFreed;
|
||||
ULONG_PTR* pnPhysicalMemoryPageArray;
|
||||
void* pRegionReserved;
|
||||
};
|
||||
|
||||
const size_t cNdbMem_nMaxAWEinfo = 256;
|
||||
size_t gNdbMem_nAWEinfo = 0;
|
||||
|
||||
struct AWEINFO* gNdbMem_pAWEinfo = 0;
|
||||
|
||||
|
||||
void ShowLastError(const char* szContext, const char* szFunction)
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dwError,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
printf("%s : %s failed : %lu : %s\n", szContext, szFunction, dwError, (char*)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NdbMem_Create()
|
||||
{
|
||||
// Address Windowing Extensions
|
||||
struct PRIVINFO
|
||||
{
|
||||
DWORD Count;
|
||||
LUID_AND_ATTRIBUTES Privilege[1];
|
||||
} Info;
|
||||
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
HANDLE hToken;
|
||||
if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "OpenProcessToken");
|
||||
}
|
||||
|
||||
Info.Count = 1;
|
||||
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if(!LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &(Info.Privilege[0].Luid)))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "LookupPrivilegeValue");
|
||||
}
|
||||
|
||||
if(!AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&Info, 0, 0, 0))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "AdjustTokenPrivileges");
|
||||
}
|
||||
|
||||
if(!CloseHandle(hToken))
|
||||
{
|
||||
ShowLastError("NdbMem_Create", "CloseHandle");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NdbMem_Destroy()
|
||||
{
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
void* NdbMem_Allocate(size_t size)
|
||||
{
|
||||
// Address Windowing Extensions
|
||||
struct AWEINFO* pAWEinfo;
|
||||
HANDLE hProcess;
|
||||
SYSTEM_INFO sysinfo;
|
||||
|
||||
if(!gNdbMem_pAWEinfo)
|
||||
{
|
||||
gNdbMem_pAWEinfo = VirtualAlloc(0,
|
||||
sizeof(struct AWEINFO)*cNdbMem_nMaxAWEinfo,
|
||||
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
assert(gNdbMem_nAWEinfo < cNdbMem_nMaxAWEinfo);
|
||||
pAWEinfo = gNdbMem_pAWEinfo+gNdbMem_nAWEinfo++;
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
GetSystemInfo(&sysinfo);
|
||||
pAWEinfo->nNumberOfPagesRequested = (size+sysinfo.dwPageSize-1)/sysinfo.dwPageSize;
|
||||
pAWEinfo->pnPhysicalMemoryPageArray = VirtualAlloc(0,
|
||||
sizeof(ULONG_PTR)*pAWEinfo->nNumberOfPagesRequested,
|
||||
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
|
||||
pAWEinfo->nNumberOfPagesActual = pAWEinfo->nNumberOfPagesRequested;
|
||||
if(!AllocateUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesActual), pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "AllocateUserPhysicalPages");
|
||||
return 0;
|
||||
}
|
||||
if(pAWEinfo->nNumberOfPagesRequested != pAWEinfo->nNumberOfPagesActual)
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "nNumberOfPagesRequested != nNumberOfPagesActual");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pAWEinfo->dwSizeInBytesRequested = size;
|
||||
pAWEinfo->pRegionReserved = VirtualAlloc(0, pAWEinfo->dwSizeInBytesRequested, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE);
|
||||
if(!pAWEinfo->pRegionReserved)
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "VirtualAlloc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!MapUserPhysicalPages(pAWEinfo->pRegionReserved, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Allocate", "MapUserPhysicalPages");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
printf("allocate AWE memory: %lu bytes, %lu pages, address %lx\n",
|
||||
pAWEinfo->dwSizeInBytesRequested,
|
||||
pAWEinfo->nNumberOfPagesActual,
|
||||
pAWEinfo->pRegionReserved);
|
||||
*/
|
||||
return pAWEinfo->pRegionReserved;
|
||||
}
|
||||
|
||||
|
||||
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
|
||||
{
|
||||
/*
|
||||
return (void*)memalign(alignment, size);
|
||||
TEMP fix
|
||||
*/
|
||||
return NdbMem_Allocate(size);
|
||||
}
|
||||
|
||||
|
||||
void NdbMem_Free(void* ptr)
|
||||
{
|
||||
// VirtualFree(ptr, 0, MEM_DECOMMIT|MEM_RELEASE);
|
||||
|
||||
// Address Windowing Extensions
|
||||
struct AWEINFO* pAWEinfo = 0;
|
||||
size_t i;
|
||||
HANDLE hProcess;
|
||||
|
||||
for(i=0; i<gNdbMem_nAWEinfo; ++i)
|
||||
{
|
||||
if(ptr==gNdbMem_pAWEinfo[i].pRegionReserved)
|
||||
{
|
||||
pAWEinfo = gNdbMem_pAWEinfo+i;
|
||||
}
|
||||
}
|
||||
if(!pAWEinfo)
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "ptr is not AWE memory");
|
||||
}
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
if(!MapUserPhysicalPages(ptr, pAWEinfo->nNumberOfPagesActual, 0))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "MapUserPhysicalPages");
|
||||
}
|
||||
|
||||
if(!VirtualFree(ptr, 0, MEM_RELEASE))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "VirtualFree");
|
||||
}
|
||||
|
||||
pAWEinfo->nNumberOfPagesFreed = pAWEinfo->nNumberOfPagesActual;
|
||||
if(!FreeUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesFreed), pAWEinfo->pnPhysicalMemoryPageArray))
|
||||
{
|
||||
ShowLastError("NdbMem_Free", "FreeUserPhysicalPages");
|
||||
}
|
||||
|
||||
VirtualFree(pAWEinfo->pnPhysicalMemoryPageArray, 0, MEM_DECOMMIT|MEM_RELEASE);
|
||||
}
|
||||
|
||||
|
||||
int NdbMem_MemLockAll()
|
||||
{
|
||||
/*
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
SIZE_T nMinimumWorkingSetSize;
|
||||
SIZE_T nMaximumWorkingSetSize;
|
||||
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
|
||||
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
|
||||
|
||||
SetProcessWorkingSetSize(hProcess, 50000000, 100000000);
|
||||
|
||||
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
|
||||
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbMem_MemUnlockAll()
|
||||
{
|
||||
//VirtualUnlock();
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "NdbMutex.h"
|
||||
|
||||
|
||||
NdbMutex* NdbMutex_Create(void)
|
||||
{
|
||||
NdbMutex* pNdbMutex = (NdbMutex*)malloc(sizeof(NdbMutex));
|
||||
if(!pNdbMutex)
|
||||
return 0;
|
||||
|
||||
InitializeCriticalSection(pNdbMutex);
|
||||
return pNdbMutex;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Destroy(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
DeleteCriticalSection(p_mutex);
|
||||
free(p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Lock(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
EnterCriticalSection (p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Unlock(NdbMutex* p_mutex)
|
||||
{
|
||||
if(!p_mutex)
|
||||
return -1;
|
||||
|
||||
LeaveCriticalSection(p_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbMutex_Trylock(NdbMutex* p_mutex)
|
||||
{
|
||||
int result = -1;
|
||||
if(p_mutex)
|
||||
{
|
||||
result = (TryEnterCriticalSection(p_mutex) ? 0 : -1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbSleep.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
int
|
||||
NdbSleep_MilliSleep(int milliseconds)
|
||||
{
|
||||
Sleep(milliseconds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbSleep_SecSleep(int seconds)
|
||||
{
|
||||
return NdbSleep_MilliSleep(seconds*1000);
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "NdbTCP.h"
|
||||
|
||||
int
|
||||
Ndb_getInAddr(struct in_addr * dst, const char *address)
|
||||
{
|
||||
struct hostent * hostPtr;
|
||||
|
||||
/* Try it as aaa.bbb.ccc.ddd. */
|
||||
dst->s_addr = inet_addr(address);
|
||||
if (dst->s_addr != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hostPtr = gethostbyname(address);
|
||||
if (hostPtr != NULL) {
|
||||
dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "NdbThread.h"
|
||||
|
||||
|
||||
#define MAX_THREAD_NAME 16
|
||||
|
||||
typedef unsigned (WINAPI* NDB_WIN32_THREAD_FUNC)(void*);
|
||||
|
||||
|
||||
struct NdbThread
|
||||
{
|
||||
HANDLE hThread;
|
||||
unsigned nThreadId;
|
||||
char thread_name[MAX_THREAD_NAME];
|
||||
};
|
||||
|
||||
|
||||
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
|
||||
NDB_THREAD_ARG *p_thread_arg,
|
||||
const NDB_THREAD_STACKSIZE thread_stack_size,
|
||||
const char* p_thread_name,
|
||||
NDB_THREAD_PRIO thread_prio)
|
||||
{
|
||||
struct NdbThread* tmpThread;
|
||||
unsigned initflag;
|
||||
int nPriority = 0;
|
||||
|
||||
if(!p_thread_func)
|
||||
return 0;
|
||||
|
||||
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
|
||||
if(!tmpThread)
|
||||
return 0;
|
||||
|
||||
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
|
||||
|
||||
switch(thread_prio)
|
||||
{
|
||||
case NDB_THREAD_PRIO_HIGHEST: nPriority=THREAD_PRIORITY_HIGHEST; break;
|
||||
case NDB_THREAD_PRIO_HIGH: nPriority=THREAD_PRIORITY_ABOVE_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_MEAN: nPriority=THREAD_PRIORITY_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_LOW: nPriority=THREAD_PRIORITY_BELOW_NORMAL; break;
|
||||
case NDB_THREAD_PRIO_LOWEST: nPriority=THREAD_PRIORITY_LOWEST; break;
|
||||
}
|
||||
initflag = (nPriority ? CREATE_SUSPENDED : 0);
|
||||
|
||||
tmpThread->hThread = (HANDLE)_beginthreadex(0, thread_stack_size,
|
||||
(NDB_WIN32_THREAD_FUNC)p_thread_func, p_thread_arg,
|
||||
initflag, &tmpThread->nThreadId);
|
||||
|
||||
if(nPriority && tmpThread->hThread)
|
||||
{
|
||||
SetThreadPriority(tmpThread->hThread, nPriority);
|
||||
ResumeThread (tmpThread->hThread);
|
||||
}
|
||||
|
||||
assert(tmpThread->hThread);
|
||||
return tmpThread;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Destroy(struct NdbThread** p_thread)
|
||||
{
|
||||
CloseHandle((*p_thread)->hThread);
|
||||
(*p_thread)->hThread = 0;
|
||||
free(*p_thread);
|
||||
*p_thread = 0;
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
|
||||
{
|
||||
void *local_status = 0;
|
||||
if (status == 0)
|
||||
status = &local_status;
|
||||
|
||||
if(WaitForSingleObject(p_wait_thread->hThread, INFINITE) == WAIT_OBJECT_0
|
||||
&& GetExitCodeThread(p_wait_thread->hThread, (LPDWORD)status))
|
||||
{
|
||||
CloseHandle(p_wait_thread->hThread);
|
||||
p_wait_thread->hThread = 0;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void NdbThread_Exit(int status)
|
||||
{
|
||||
_endthreadex((DWORD) status);
|
||||
}
|
||||
|
||||
|
||||
int NdbThread_SetConcurrencyLevel(int level)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <windows.h>
|
||||
#include "NdbTick.h"
|
||||
|
||||
/*
|
||||
#define FILETIME_PER_MICROSEC 10
|
||||
#define FILETIME_PER_MILLISEC 10000
|
||||
#define FILETIME_PER_SEC 10000000
|
||||
|
||||
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
ULONGLONG ullTime;
|
||||
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
|
||||
return (ullTime / FILETIME_PER_MILLISEC);
|
||||
}
|
||||
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
|
||||
{
|
||||
ULONGLONG ullTime;
|
||||
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
|
||||
*secs = (ullTime / FILETIME_PER_SEC);
|
||||
*micros = (Uint32)((ullTime % FILETIME_PER_SEC) / FILETIME_PER_MICROSEC);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
NDB_TICKS NdbTick_CurrentMillisecond(void)
|
||||
{
|
||||
LARGE_INTEGER liCount, liFreq;
|
||||
QueryPerformanceCounter(&liCount);
|
||||
QueryPerformanceFrequency(&liFreq);
|
||||
return (liCount.QuadPart*1000) / liFreq.QuadPart;
|
||||
}
|
||||
|
||||
int
|
||||
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
|
||||
{
|
||||
LARGE_INTEGER liCount, liFreq;
|
||||
QueryPerformanceCounter(&liCount);
|
||||
QueryPerformanceFrequency(&liFreq);
|
||||
*secs = liCount.QuadPart / liFreq.QuadPart;
|
||||
liCount.QuadPart -= *secs * liFreq.QuadPart;
|
||||
*micros = (liCount.QuadPart*1000000) / liFreq.QuadPart;
|
||||
return 0;
|
||||
}
|
|
@ -114,6 +114,7 @@ EmulatorData::destroy(){
|
|||
delete theSimBlockList; theSimBlockList = 0;
|
||||
if(m_socket_server)
|
||||
delete m_socket_server; m_socket_server = 0;
|
||||
NdbMutex_Destroy(theShutdownMutex);
|
||||
if (m_mem_manager)
|
||||
delete m_mem_manager; m_mem_manager = 0;
|
||||
|
||||
|
|
|
@ -138,6 +138,12 @@ setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){
|
|||
return ret; \
|
||||
}
|
||||
|
||||
#define DBUG_CHECK_REPLY(reply, ret) \
|
||||
if (reply == NULL) { \
|
||||
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
|
||||
DBUG_RETURN(ret); \
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Handles
|
||||
*****************************************************************************/
|
||||
|
@ -2171,9 +2177,9 @@ ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
|
|||
int param,
|
||||
int value,
|
||||
struct ndb_mgm_reply* mgmreply){
|
||||
DBUG_ENTER("ndb_mgm_set_connection_int_parameter");
|
||||
CHECK_HANDLE(handle, 0);
|
||||
CHECK_CONNECTED(handle, 0);
|
||||
DBUG_ENTER("ndb_mgm_set_connection_int_parameter");
|
||||
|
||||
Properties args;
|
||||
args.put("node1", node1);
|
||||
|
@ -2190,7 +2196,7 @@ ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
|
|||
|
||||
const Properties *prop;
|
||||
prop= ndb_mgm_call(handle, reply, "set connection parameter", &args);
|
||||
CHECK_REPLY(prop, -1);
|
||||
DBUG_CHECK_REPLY(prop, -1);
|
||||
|
||||
int res= -1;
|
||||
do {
|
||||
|
@ -2214,9 +2220,9 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
|
|||
int param,
|
||||
int *value,
|
||||
struct ndb_mgm_reply* mgmreply){
|
||||
DBUG_ENTER("ndb_mgm_get_connection_int_parameter");
|
||||
CHECK_HANDLE(handle, -1);
|
||||
CHECK_CONNECTED(handle, -2);
|
||||
DBUG_ENTER("ndb_mgm_get_connection_int_parameter");
|
||||
|
||||
Properties args;
|
||||
args.put("node1", node1);
|
||||
|
@ -2232,7 +2238,7 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
|
|||
|
||||
const Properties *prop;
|
||||
prop = ndb_mgm_call(handle, reply, "get connection parameter", &args);
|
||||
CHECK_REPLY(prop, -3);
|
||||
DBUG_CHECK_REPLY(prop, -3);
|
||||
|
||||
int res= -1;
|
||||
do {
|
||||
|
@ -2280,9 +2286,9 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
|
|||
{
|
||||
Uint32 nodeid=0;
|
||||
|
||||
DBUG_ENTER("ndb_mgm_get_mgmd_nodeid");
|
||||
CHECK_HANDLE(handle, 0);
|
||||
CHECK_CONNECTED(handle, 0);
|
||||
DBUG_ENTER("ndb_mgm_get_mgmd_nodeid");
|
||||
|
||||
Properties args;
|
||||
|
||||
|
@ -2294,7 +2300,7 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
|
|||
|
||||
const Properties *prop;
|
||||
prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args);
|
||||
CHECK_REPLY(prop, 0);
|
||||
DBUG_CHECK_REPLY(prop, 0);
|
||||
|
||||
if(!prop->get("nodeid",&nodeid)){
|
||||
fprintf(handle->errstream, "Unable to get value\n");
|
||||
|
@ -2308,9 +2314,9 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
|
|||
extern "C"
|
||||
int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
|
||||
{
|
||||
DBUG_ENTER("ndb_mgm_report_event");
|
||||
CHECK_HANDLE(handle, 0);
|
||||
CHECK_CONNECTED(handle, 0);
|
||||
DBUG_ENTER("ndb_mgm_report_event");
|
||||
|
||||
Properties args;
|
||||
args.put("length", length);
|
||||
|
@ -2329,7 +2335,7 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
|
|||
|
||||
const Properties *prop;
|
||||
prop = ndb_mgm_call(handle, reply, "report event", &args);
|
||||
CHECK_REPLY(prop, -1);
|
||||
DBUG_CHECK_REPLY(prop, -1);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -2337,9 +2343,9 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
|
|||
extern "C"
|
||||
int ndb_mgm_end_session(NdbMgmHandle handle)
|
||||
{
|
||||
DBUG_ENTER("ndb_mgm_end_session");
|
||||
CHECK_HANDLE(handle, 0);
|
||||
CHECK_CONNECTED(handle, 0);
|
||||
DBUG_ENTER("ndb_mgm_end_session");
|
||||
|
||||
SocketOutputStream s_output(handle->socket);
|
||||
s_output.println("end session");
|
||||
|
|
|
@ -1079,7 +1079,7 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
|
|||
}
|
||||
if (node_state->node_group >= 0) {
|
||||
ndbout << ", Nodegroup: " << node_state->node_group;
|
||||
if (node_state->dynamic_id == master_id)
|
||||
if (master_id && node_state->dynamic_id == master_id)
|
||||
ndbout << ", Master";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
DIRS =
|
||||
|
||||
ifneq ($(NDB_ODBC),N)
|
||||
DIRS += odbc
|
||||
endif
|
||||
|
||||
include $(NDB_TOP)/Epilogue.mk
|
|
@ -1,59 +0,0 @@
|
|||
# before Epilogue.mk
|
||||
|
||||
CCFLAGS_LOC += -I..
|
||||
|
||||
CCFLAGS_LOC += \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/ndbapi) \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/util) \
|
||||
-I$(call fixpath,$(NDB_TOP)/include/portlib)
|
||||
|
||||
ifeq ($(NDB_OS),SOLARIS)
|
||||
|
||||
CCFLAGS_LOC += -I/usr/local/include
|
||||
|
||||
ifeq ($(NDB_COMPILER),GCC)
|
||||
LIBS_LOC += -Wl,-z,text
|
||||
CCFLAGS_WARNINGS += -Wno-unused -Wformat
|
||||
CCFLAGS_TOP += -D__STL_PTHREADS
|
||||
endif
|
||||
|
||||
ifeq ($(NDB_COMPILER),FORTE6)
|
||||
LIBS_LOC += -z text
|
||||
LIBS_SPEC += /usr/lib/libCrun.so.1
|
||||
endif
|
||||
|
||||
LIB_TARGET_LIBS += -lthread -lrt
|
||||
|
||||
endif
|
||||
ifneq ($(filter $(NDB_OS), LINUX MACOSX IBMAIX TRU64X),)
|
||||
|
||||
LIBS_LOC += -Wl,-z,text
|
||||
CCFLAGS_WARNINGS += -Wno-unused -Wformat
|
||||
GCC_VER := $(shell $(CC) --version)
|
||||
|
||||
ifeq ($(GCC_VER),2.96)
|
||||
CCFLAGS_TOP += -D__STL_PTHREADS
|
||||
CCFLAGS_TOP += -fmessage-length=0
|
||||
endif
|
||||
|
||||
CCFLAGS_TOP += -fno-rtti
|
||||
|
||||
LIB_TARGET_LIBS += -lpthread
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(NDB_OS),WIN32)
|
||||
ifeq (RELEASE, $(NDB_VERSION))
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
else
|
||||
ifeq (RELEASE_TRACE, $(NDB_VERSION))
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
else
|
||||
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
CCFLAGS_TOP += -DYYDEBUG=0 -fexceptions
|
||||
|
||||
CCFLAGS_TOP += -DHAVE_LONG_LONG
|
|
@ -1,75 +0,0 @@
|
|||
include .defs.mk
|
||||
|
||||
TYPE = *
|
||||
|
||||
A_LIB = N
|
||||
PIC_LIB = Y
|
||||
SO_LIB = Y
|
||||
|
||||
LIB_TARGET = NDB_ODBC
|
||||
|
||||
LIB_TARGET_ARCHIVES = $(LIB_DIRS:%=odbc%) NDB_API
|
||||
|
||||
# Overide Defs.mk
|
||||
LDFLAGS_LAST = -lstdc++ -lm
|
||||
|
||||
XXX = \
|
||||
ndbapi \
|
||||
mgmsrvcommon \
|
||||
transporter \
|
||||
general \
|
||||
signaldataprint \
|
||||
portlib \
|
||||
logger \
|
||||
trace
|
||||
|
||||
ifeq ($(NDB_OS),WIN32)
|
||||
|
||||
LIB_DIRS = \
|
||||
handles \
|
||||
dictionary \
|
||||
codegen \
|
||||
executor \
|
||||
common
|
||||
|
||||
SOURCES += NdbOdbc.cpp
|
||||
CFLAGS_NdbOdbc.cpp += -I. -I$(call fixpath,driver)
|
||||
|
||||
PIC_ARCHIVE := Y
|
||||
NONPIC_ARCHIVE := N
|
||||
ARCHIVE_TARGET := ndb_odbcwin32
|
||||
LIB_TARGET_ARCHIVES += ndb_odbcwin32
|
||||
|
||||
ifeq (RELEASE, $(NDB_VERSION))
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
else
|
||||
ifeq (RELEASE_TRACE, $(NDB_VERSION))
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
else
|
||||
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL /DLL /DEBUG /SUBSYSTEM:WINDOWS /MACHINE:IX86 /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
|
||||
endif
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
LIB_DIRS = \
|
||||
driver \
|
||||
handles \
|
||||
dictionary \
|
||||
codegen \
|
||||
executor \
|
||||
common
|
||||
|
||||
endif
|
||||
|
||||
include Extra.mk
|
||||
include $(NDB_TOP)/Epilogue.mk
|
||||
|
||||
# yo
|
||||
|
||||
test:
|
||||
$(MAKE) -j4
|
||||
$(MAKE) -C $(NDB_TOP)/tools/ndbsql
|
||||
$(MAKE) -C $(NDB_TOP)/test/odbc/driver tidy
|
||||
$(MAKE) -C $(NDB_TOP)/test/odbc/driver
|
||||
$(MAKE) -C $(NDB_TOP)/test/ndbapi/testOIBasic
|
|
@ -1,78 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <NdbUnistd.h>
|
||||
#include <odbcinst.h>
|
||||
|
||||
#include "driver.cpp"
|
||||
|
||||
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL INSTAPI ConfigDSN(
|
||||
HWND hwndParent,
|
||||
WORD fRequest,
|
||||
LPCSTR lpszDriver,
|
||||
LPCSTR lpszAttributes)
|
||||
{
|
||||
const char* szDSN = "NDB";
|
||||
|
||||
switch(fRequest)
|
||||
{
|
||||
case ODBC_ADD_DSN:
|
||||
SQLWriteDSNToIni(szDSN, lpszDriver);
|
||||
break;
|
||||
|
||||
case ODBC_CONFIG_DSN:
|
||||
break;
|
||||
|
||||
case ODBC_REMOVE_DSN:
|
||||
SQLRemoveDSNFromIni(szDSN);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int FAR PASCAL
|
||||
DriverConnectProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void);
|
||||
/* Entry point to cause DM to load using ordinals */
|
||||
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
LIBRARY NdbOdbc.DLL
|
||||
VERSION 03.51.00
|
||||
EXPORTS
|
||||
SQLAllocConnect
|
||||
SQLAllocEnv
|
||||
SQLAllocHandle
|
||||
SQLAllocHandleStd
|
||||
SQLAllocStmt
|
||||
SQLBindCol
|
||||
SQLBindParam
|
||||
SQLBindParameter
|
||||
SQLBrowseConnect
|
||||
SQLBulkOperations
|
||||
SQLCancel
|
||||
SQLCloseCursor
|
||||
SQLColAttribute
|
||||
SQLColAttributes
|
||||
SQLColumnPrivileges
|
||||
SQLColumns
|
||||
SQLConnect
|
||||
SQLCopyDesc
|
||||
SQLDataSources
|
||||
SQLDescribeCol
|
||||
SQLDescribeParam
|
||||
SQLDisconnect
|
||||
SQLDriverConnect
|
||||
SQLDrivers
|
||||
SQLEndTran
|
||||
SQLError
|
||||
SQLExecDirect
|
||||
SQLExecute
|
||||
SQLExtendedFetch
|
||||
SQLFetch
|
||||
SQLFetchScroll
|
||||
SQLForeignKeys
|
||||
SQLFreeConnect
|
||||
SQLFreeEnv
|
||||
SQLFreeHandle
|
||||
SQLFreeStmt
|
||||
SQLGetConnectAttr
|
||||
SQLGetConnectOption
|
||||
SQLGetCursorName
|
||||
SQLGetData
|
||||
SQLGetDescField
|
||||
SQLGetDescRec
|
||||
SQLGetDiagField
|
||||
SQLGetDiagRec
|
||||
SQLGetEnvAttr
|
||||
SQLGetFunctions
|
||||
SQLGetInfo
|
||||
SQLGetStmtAttr
|
||||
SQLGetStmtOption
|
||||
SQLGetTypeInfo
|
||||
SQLMoreResults
|
||||
SQLNativeSql
|
||||
SQLNumParams
|
||||
SQLNumResultCols
|
||||
SQLParamData
|
||||
SQLParamOptions
|
||||
SQLPrepare
|
||||
SQLPrimaryKeys
|
||||
SQLProcedureColumns
|
||||
SQLProcedures
|
||||
SQLPutData
|
||||
SQLRowCount
|
||||
SQLSetConnectAttr
|
||||
SQLSetConnectOption
|
||||
SQLSetCursorName
|
||||
SQLSetDescField
|
||||
SQLSetDescRec
|
||||
SQLSetEnvAttr
|
||||
SQLSetParam
|
||||
SQLSetPos
|
||||
SQLSetScrollOptions
|
||||
SQLSetStmtAttr
|
||||
SQLSetStmtOption
|
||||
SQLSpecialColumns
|
||||
SQLStatistics
|
||||
SQLTablePrivileges
|
||||
SQLTables
|
||||
SQLTransact
|
||||
DllMain
|
||||
DriverConnectProc
|
||||
ConfigDSN
|
||||
LoadByOrdinal
|
|
@ -1,229 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <common/StmtArea.hpp>
|
||||
#include <common/CodeTree.hpp>
|
||||
#include <executor/Executor.hpp>
|
||||
#include "CodeGen.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
#include <FlexLexer.h>
|
||||
#include "SimpleParser.hpp"
|
||||
|
||||
void
|
||||
CodeGen::prepare(Ctx& ctx)
|
||||
{
|
||||
parse(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::execute(Ctx& ctx)
|
||||
{
|
||||
DescArea& ipd = m_stmtArea.descArea(Desc_usage_IPD);
|
||||
if (m_stmtArea.m_unbound) {
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
if (m_stmtArea.m_unbound) {
|
||||
ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "%u input parameters have unbound SQL type", m_stmtArea.m_unbound);
|
||||
return;
|
||||
}
|
||||
ipd.setBound(true);
|
||||
}
|
||||
if (! ipd.isBound()) {
|
||||
ctx_log2(("IPD changed between executes - reanalyze"));
|
||||
// jdbc can change parameter length at each execute
|
||||
analyze(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
describe(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
freeExec(ctx);
|
||||
codegen(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
alloc(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ipd.setBound(true);
|
||||
}
|
||||
if (m_stmtArea.m_execTree == 0) {
|
||||
codegen(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
alloc(ctx);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
Executor executor(m_stmtArea);
|
||||
executor.execute(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::fetch(Ctx& ctx)
|
||||
{
|
||||
// XXX parameter types are not checked any more
|
||||
ctx_assert(! m_stmtArea.m_unbound);
|
||||
Executor executor(m_stmtArea);
|
||||
executor.fetch(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::parse(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = new Plan_root(m_stmtArea);
|
||||
SimpleParser simpleParser(ctx, m_stmtArea, planRoot);
|
||||
simpleParser.yyparse();
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
planRoot->m_paramList.resize(1 + simpleParser.paramNumber());
|
||||
ctx_log2(("CodeGen: parse done - plan tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
planRoot->print(ctx);
|
||||
m_stmtArea.m_planTree = planRoot;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::analyze(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
Plan_base::Ctl ctl(0);
|
||||
planRoot->analyze(ctx, ctl); // returns itself
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_log2(("CodeGen: analyze done - plan tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
planRoot->print(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::describe(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
planRoot->describe(ctx);
|
||||
ctx_log2(("CodeGen: describe done"));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::codegen(Ctx& ctx)
|
||||
{
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
Plan_base::Ctl ctl(0);
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(planRoot->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_assert(execRoot != 0);
|
||||
ctx_log2(("CodeGen: codegen done - code tree follows"));
|
||||
if (ctx.logLevel() >= 2)
|
||||
execRoot->print(ctx);
|
||||
m_stmtArea.m_execTree = execRoot;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::alloc(Ctx& ctx)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
Exec_base::Ctl ctl(0);
|
||||
execRoot->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
ctx_log2(("CodeGen: alloc done"));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::close(Ctx& ctx)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
if (execRoot != 0) {
|
||||
execRoot->close(ctx);
|
||||
ctx_log2(("CodeGen: close done"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::free(Ctx& ctx)
|
||||
{
|
||||
freePlan(ctx);
|
||||
freeExec(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::freePlan(Ctx & ctx)
|
||||
{
|
||||
if (m_stmtArea.m_planTree != 0) {
|
||||
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
|
||||
ctx_assert(planRoot != 0);
|
||||
unsigned count = 1 + planRoot->m_nodeList.size();
|
||||
planRoot->freeNodeList();
|
||||
delete planRoot;
|
||||
m_stmtArea.m_planTree = 0;
|
||||
ctx_log3(("CodeGen: freed %u plan tree nodes", count));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::freeExec(Ctx & ctx)
|
||||
{
|
||||
if (m_stmtArea.m_execTree != 0) {
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
unsigned count = 1 + execRoot->m_nodeList.size();
|
||||
execRoot->freeNodeList();
|
||||
delete execRoot;
|
||||
m_stmtArea.m_execTree = 0;
|
||||
ctx_log3(("CodeGen: freed %u exec tree nodes", count));
|
||||
}
|
||||
}
|
||||
|
||||
// odbc support
|
||||
|
||||
void
|
||||
CodeGen::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::sqlParamData(Ctx& ctx, SQLPOINTER* value)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlParamData(ctx, value);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGen::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind)
|
||||
{
|
||||
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
|
||||
ctx_assert(execRoot != 0);
|
||||
execRoot->sqlPutData(ctx, data, strlen_or_Ind);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_CodeGen_hpp
|
||||
#define ODBC_CODEGEN_CodeGen_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
|
||||
class StmtArea;
|
||||
class SqlField;
|
||||
class ExtField;
|
||||
|
||||
/**
|
||||
* @class CodeGen
|
||||
* @brief Compiles SQL text into ExecTree::Code
|
||||
*/
|
||||
class CodeGen {
|
||||
public:
|
||||
CodeGen(StmtArea& stmtArea);
|
||||
~CodeGen();
|
||||
// parse and analyze SQL statement
|
||||
void prepare(Ctx& ctx);
|
||||
// these are passed to Executor
|
||||
void execute(Ctx& ctx);
|
||||
void fetch(Ctx& ctx);
|
||||
// close statement (mainly scan)
|
||||
void close(Ctx& ctx);
|
||||
// free data structures
|
||||
void free(Ctx& ctx);
|
||||
// odbc support
|
||||
void sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind);
|
||||
void sqlParamData(Ctx& ctx, SQLPOINTER* value);
|
||||
void sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind);
|
||||
private:
|
||||
void parse(Ctx& ctx);
|
||||
void analyze(Ctx& ctx);
|
||||
void describe(Ctx& ctx);
|
||||
void codegen(Ctx& ctx);
|
||||
void alloc(Ctx& ctx);
|
||||
void freePlan(Ctx& ctx);
|
||||
void freeExec(Ctx& ctx);
|
||||
StmtArea& m_stmtArea;
|
||||
};
|
||||
|
||||
inline
|
||||
CodeGen::CodeGen(StmtArea& stmtArea) :
|
||||
m_stmtArea(stmtArea)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
CodeGen::~CodeGen()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,167 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <common/StmtArea.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_base
|
||||
|
||||
Plan_base::~Plan_base()
|
||||
{
|
||||
}
|
||||
|
||||
StmtArea&
|
||||
Plan_base::stmtArea() const
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
return m_root->m_stmtArea;
|
||||
}
|
||||
|
||||
DescArea&
|
||||
Plan_base::descArea(DescUsage u) const
|
||||
{
|
||||
return stmtArea().descArea(u);
|
||||
}
|
||||
|
||||
ConnArea&
|
||||
Plan_base::connArea() const
|
||||
{
|
||||
return stmtArea().connArea();
|
||||
}
|
||||
|
||||
DictCatalog&
|
||||
Plan_base::dictCatalog() const
|
||||
{
|
||||
return connArea().dictCatalog();
|
||||
}
|
||||
|
||||
DictSchema&
|
||||
Plan_base::dictSchema() const
|
||||
{
|
||||
return connArea().dictSchema();
|
||||
}
|
||||
|
||||
Ndb*
|
||||
Plan_base::ndbObject() const
|
||||
{
|
||||
Ndb* ndb = connArea().ndbObject();
|
||||
ctx_assert(ndb != 0);
|
||||
return ndb;
|
||||
}
|
||||
|
||||
NdbSchemaCon*
|
||||
Plan_base::ndbSchemaCon() const
|
||||
{
|
||||
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
|
||||
ctx_assert(ndbSchemaCon != 0);
|
||||
return ndbSchemaCon;
|
||||
}
|
||||
|
||||
NdbConnection*
|
||||
Plan_base::ndbConnection() const
|
||||
{
|
||||
NdbConnection* ndbConnection = connArea().ndbConnection();
|
||||
ctx_assert(ndbConnection != 0);
|
||||
return ndbConnection;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_base::printList(Ctx& ctx, Plan_base* a[], unsigned n)
|
||||
{
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (a[i] == 0)
|
||||
ctx.print(" -");
|
||||
else
|
||||
a[i]->print(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// Exec_base
|
||||
|
||||
Exec_base::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_base::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_base::~Exec_base()
|
||||
{
|
||||
delete m_code; // remove when code becomes shared
|
||||
m_code = 0;
|
||||
delete m_data;
|
||||
m_data = 0;
|
||||
}
|
||||
|
||||
StmtArea&
|
||||
Exec_base::stmtArea() const
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
return m_root->m_stmtArea;
|
||||
}
|
||||
|
||||
DescArea&
|
||||
Exec_base::descArea(DescUsage u) const
|
||||
{
|
||||
return stmtArea().descArea(u);
|
||||
}
|
||||
|
||||
ConnArea&
|
||||
Exec_base::connArea() const
|
||||
{
|
||||
return stmtArea().connArea();
|
||||
}
|
||||
|
||||
DictSchema&
|
||||
Exec_base::dictSchema() const
|
||||
{
|
||||
return connArea().dictSchema();
|
||||
}
|
||||
|
||||
Ndb*
|
||||
Exec_base::ndbObject() const
|
||||
{
|
||||
Ndb* ndb = connArea().ndbObject();
|
||||
ctx_assert(ndb != 0);
|
||||
return ndb;
|
||||
}
|
||||
|
||||
NdbSchemaCon*
|
||||
Exec_base::ndbSchemaCon() const
|
||||
{
|
||||
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
|
||||
ctx_assert(ndbSchemaCon != 0);
|
||||
return ndbSchemaCon;
|
||||
}
|
||||
|
||||
NdbConnection*
|
||||
Exec_base::ndbConnection() const
|
||||
{
|
||||
NdbConnection* ndbConnection = connArea().ndbConnection();
|
||||
ctx_assert(ndbConnection != 0);
|
||||
return ndbConnection;
|
||||
}
|
||||
|
||||
void
|
||||
Exec_base::printList(Ctx& ctx, Exec_base* a[], unsigned n)
|
||||
{
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
ctx_assert(a[i] != 0);
|
||||
a[i]->print(ctx);
|
||||
}
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_base_hpp
|
||||
#define ODBC_CODEGEN_Code_base_hpp
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include <common/CodeTree.hpp>
|
||||
#include <common/DescArea.hpp>
|
||||
|
||||
class Ctx;
|
||||
class ConnArea;
|
||||
class StmtArea;
|
||||
class DescArea;
|
||||
class DictCatalog;
|
||||
class DictSchema;
|
||||
class ResultArea;
|
||||
class ResultSet;
|
||||
class SpecRow;
|
||||
class Ndb;
|
||||
class NdbSchemaCon;
|
||||
class NdbConnection;
|
||||
class NdbOperation;
|
||||
class NdbScanFilter;
|
||||
|
||||
class Plan_root;
|
||||
class Plan_table;
|
||||
class Plan_column;
|
||||
class Plan_expr;
|
||||
class Plan_expr_param;
|
||||
class Plan_pred;
|
||||
class Plan_dml_row;
|
||||
class Plan_dml_column;
|
||||
class Plan_ddl_column;
|
||||
class Plan_ddl_constr;
|
||||
class Plan_idx_column;
|
||||
class Exec_root;
|
||||
class Exec_base;
|
||||
class Exec_query;
|
||||
class Exec_expr;
|
||||
class Exec_expr_row;
|
||||
class Exec_expr_param;
|
||||
|
||||
/**
|
||||
* @class Plan_base
|
||||
* @brief Base class for plan trees
|
||||
*/
|
||||
class Plan_base : public PlanTree {
|
||||
public:
|
||||
Plan_base(Plan_root* root);
|
||||
virtual ~Plan_base() = 0;
|
||||
// get references to StmtArea via Plan_root
|
||||
StmtArea& stmtArea() const;
|
||||
DescArea& descArea(DescUsage u) const;
|
||||
ConnArea& connArea() const;
|
||||
// catalogs
|
||||
DictCatalog& dictCatalog() const;
|
||||
DictSchema& dictSchema() const;
|
||||
// ndb
|
||||
Ndb* ndbObject() const;
|
||||
NdbSchemaCon* ndbSchemaCon() const;
|
||||
NdbConnection* ndbConnection() const;
|
||||
// containers for Plan classes
|
||||
typedef std::vector<Plan_table*> TableVector;
|
||||
typedef std::vector<Plan_column*> ColumnVector;
|
||||
typedef std::vector<Plan_dml_column*> DmlColumnVector;
|
||||
typedef std::vector<Plan_ddl_column*> DdlColumnVector;
|
||||
typedef std::vector<Plan_ddl_constr*> DdlConstrVector;
|
||||
typedef std::vector<Plan_idx_column*> IdxColumnVector;
|
||||
typedef std::vector<Plan_expr*> ExprVector;
|
||||
typedef std::list<Plan_expr*> ExprList;
|
||||
typedef std::vector<ExprList> ExprListVector;
|
||||
typedef std::list<Plan_pred*> PredList;
|
||||
typedef std::set<Plan_table*> TableSet;
|
||||
typedef std::vector<Plan_expr_param*> ParamVector;
|
||||
// control area on the stack XXX needs to be designed
|
||||
struct Ctl {
|
||||
Ctl(Ctl* up);
|
||||
Ctl* m_up; // up the stack
|
||||
// analyze
|
||||
TableVector m_tableList; // resolve column names
|
||||
bool m_topand; // in top-level where clause
|
||||
bool m_extra; // anything but single pk=expr
|
||||
bool m_aggrok; // aggregate allowed
|
||||
bool m_aggrin; // within aggregate args
|
||||
bool m_const; // only constants in set clause
|
||||
PredList m_topcomp; // top level comparisons
|
||||
Plan_dml_row *m_dmlRow; // row type to convert to
|
||||
Plan_table* m_topTable; // top level table for interpreted progs
|
||||
bool m_having; // in having-predicate
|
||||
// codegen
|
||||
Exec_root* m_execRoot; // root of Exec tree
|
||||
const Exec_query* m_execQuery; // pass to column
|
||||
};
|
||||
// semantic analysis and optimization
|
||||
virtual Plan_base* analyze(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// generate "executable" code
|
||||
virtual Exec_base* codegen(Ctx& ctx, Ctl& ctl) = 0;
|
||||
// misc
|
||||
virtual void print(Ctx& ctx) = 0;
|
||||
protected:
|
||||
Plan_root* m_root;
|
||||
void printList(Ctx& ctx, Plan_base* a[], unsigned n);
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_base::Plan_base(Plan_root* root) :
|
||||
m_root(root)
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
}
|
||||
|
||||
inline
|
||||
Plan_base::Ctl::Ctl(Ctl* up) :
|
||||
m_up(up),
|
||||
m_tableList(1), // 1-based
|
||||
m_topand(false),
|
||||
m_extra(false),
|
||||
m_aggrok(false),
|
||||
m_aggrin(false),
|
||||
m_dmlRow(0),
|
||||
m_topTable(0),
|
||||
m_having(false),
|
||||
m_execRoot(0),
|
||||
m_execQuery(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_base
|
||||
* @brief Base class for exec trees
|
||||
*/
|
||||
class Exec_base : public ExecTree {
|
||||
public:
|
||||
class Code : public ExecTree::Code {
|
||||
public:
|
||||
virtual ~Code() = 0;
|
||||
};
|
||||
class Data : public ExecTree::Data {
|
||||
public:
|
||||
virtual ~Data() = 0;
|
||||
};
|
||||
Exec_base(Exec_root* root);
|
||||
virtual ~Exec_base() = 0;
|
||||
// get references to StmtArea via Exec_root
|
||||
virtual StmtArea& stmtArea() const;
|
||||
DescArea& descArea(DescUsage u) const;
|
||||
ConnArea& connArea() const;
|
||||
// catalogs
|
||||
DictSchema& dictSchema() const;
|
||||
// ndb
|
||||
Ndb* ndbObject() const;
|
||||
NdbSchemaCon* ndbSchemaCon() const;
|
||||
NdbConnection* ndbConnection() const;
|
||||
// containers for Exec classes
|
||||
typedef std::vector<Exec_expr*> ExprVector;
|
||||
typedef std::vector<Exec_expr_param*> ParamVector;
|
||||
// control area on the stack
|
||||
struct Ctl {
|
||||
Ctl(Ctl* up);
|
||||
Ctl* m_up; // up the stack
|
||||
const Exec_query* m_query; // pass Data
|
||||
ExprVector m_exprList; // pass Data
|
||||
NdbOperation* m_scanOp; // scan operation
|
||||
bool m_postEval; // for rownum
|
||||
unsigned m_groupIndex; // for group by
|
||||
bool m_groupInit; // first in group
|
||||
Exec_expr_row* m_sortRow; // from sort to group by
|
||||
NdbScanFilter* m_scanFilter; // scan filter
|
||||
};
|
||||
// allocate and deallocate Data instances
|
||||
virtual void alloc(Ctx& ctx, Ctl& ctl) = 0;
|
||||
virtual void close(Ctx& ctx) = 0;
|
||||
// set Code and Data
|
||||
void setCode(const Code& code);
|
||||
void setData(Data& data);
|
||||
// misc
|
||||
virtual void print(Ctx& ctx) = 0;
|
||||
protected:
|
||||
const Code* m_code;
|
||||
Data* m_data;
|
||||
Exec_root* m_root;
|
||||
void printList(Ctx& ctx, Exec_base* a[], unsigned n);
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_base::Exec_base(Exec_root* root) :
|
||||
m_code(0),
|
||||
m_data(0),
|
||||
m_root(root)
|
||||
{
|
||||
ctx_assert(m_root != 0);
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_base::setCode(const Code& code)
|
||||
{
|
||||
ctx_assert(m_code == 0);
|
||||
m_code = &code;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_base::setData(Data& data)
|
||||
{
|
||||
ctx_assert(m_data == 0);
|
||||
m_data = &data;
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_base::Ctl::Ctl(Ctl* up) :
|
||||
m_up(up),
|
||||
m_scanOp(0),
|
||||
m_postEval(false),
|
||||
m_groupIndex(0),
|
||||
m_groupInit(false),
|
||||
m_sortRow(0),
|
||||
m_scanFilter(0)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include <dictionary/DictSchema.hpp>
|
||||
#include <dictionary/DictColumn.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_table_list.hpp"
|
||||
#include "Code_table.hpp"
|
||||
|
||||
// Plan_column
|
||||
|
||||
Plan_column::~Plan_column()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Plan_column::analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl)
|
||||
{
|
||||
if (m_resTable != 0) // done on previous pass
|
||||
return;
|
||||
if (! (ctl.m_tableList.size() > 1)) {
|
||||
ctx.pushStatus(Sqlstate::_42000, Error::Gen, "column %s not allowed here", getPrintName());
|
||||
return;
|
||||
}
|
||||
unsigned resCount = 0;
|
||||
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
|
||||
Plan_table* table = ctl.m_tableList[i];
|
||||
ctx_assert(table != 0);
|
||||
int ret = table->resolveColumn(ctx, this);
|
||||
if (ret < 0)
|
||||
return;
|
||||
if (ret)
|
||||
resCount++;
|
||||
}
|
||||
if (resCount == 0) {
|
||||
// XXX try to strip "schema name" from table name
|
||||
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
|
||||
Plan_table* table = ctl.m_tableList[i];
|
||||
ctx_assert(table != 0);
|
||||
int ret = table->resolveColumn(ctx, this, true);
|
||||
if (ret < 0)
|
||||
return;
|
||||
if (ret)
|
||||
resCount++;
|
||||
}
|
||||
}
|
||||
if (resCount == 0) {
|
||||
ctx.pushStatus(Sqlstate::_42S22, Error::Gen, "column %s not found", getPrintName());
|
||||
return;
|
||||
}
|
||||
if (resCount > 1) {
|
||||
ctx.pushStatus(Error::Gen, "column %s is ambiguous", getPrintName());
|
||||
return;
|
||||
}
|
||||
// copy SQL type
|
||||
m_sqlType = dictColumn().sqlType();
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_column_hpp
|
||||
#define ODBC_CODEGEN_Code_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataType.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_column
|
||||
* @brief Abstract base class for columns
|
||||
*/
|
||||
class Plan_column {
|
||||
public:
|
||||
enum Type {
|
||||
Type_expr = 1,
|
||||
Type_dml = 2,
|
||||
Type_ddl = 3, // new columns in create table
|
||||
Type_idx = 4 // old columns in create index
|
||||
};
|
||||
Plan_column(Type type, const BaseString& name);
|
||||
virtual ~Plan_column() = 0;
|
||||
void analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
const BaseString& getCname() const;
|
||||
const char* getPrintName() const;
|
||||
void setCname(const BaseString& cname);
|
||||
const DictColumn& dictColumn() const;
|
||||
const SqlType& sqlType() const;
|
||||
protected:
|
||||
friend class Plan_table;
|
||||
friend class Plan_comp_op;
|
||||
Type m_type;
|
||||
BaseString m_name;
|
||||
BaseString m_cname;
|
||||
BaseString m_printName;
|
||||
DictColumn* m_dictColumn;
|
||||
/**
|
||||
* Resolve to table and operational position (for example
|
||||
* column number in scan query).
|
||||
*/
|
||||
Plan_table* m_resTable;
|
||||
unsigned m_resPos;
|
||||
SqlType m_sqlType;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_column::Plan_column(Type type, const BaseString& name) :
|
||||
m_type(type),
|
||||
m_name(name),
|
||||
m_printName(name),
|
||||
m_dictColumn(0),
|
||||
m_resTable(0),
|
||||
m_resPos(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_column::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_column::getCname() const
|
||||
{
|
||||
return m_cname;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
Plan_column::getPrintName() const
|
||||
{
|
||||
return m_printName.c_str();
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_column::setCname(const BaseString& cname)
|
||||
{
|
||||
m_cname.assign(cname);
|
||||
if (m_cname.empty())
|
||||
m_printName.assign(m_name);
|
||||
else {
|
||||
m_printName.assign(m_cname);
|
||||
m_printName.append(".");
|
||||
m_printName.append(m_name);
|
||||
}
|
||||
}
|
||||
|
||||
inline const DictColumn&
|
||||
Plan_column::dictColumn() const
|
||||
{
|
||||
ctx_assert(m_dictColumn != 0);
|
||||
return *m_dictColumn;
|
||||
}
|
||||
|
||||
inline const SqlType&
|
||||
Plan_column::sqlType() const
|
||||
{
|
||||
ctx_assert(m_sqlType.type() != SqlType::Undef);
|
||||
return m_sqlType;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,485 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <dictionary/DictColumn.hpp>
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_comp_op.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_expr_column.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Comp_op
|
||||
|
||||
const char*
|
||||
Comp_op::name() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Eq:
|
||||
return "=";
|
||||
case Noteq:
|
||||
return "!=";
|
||||
case Lt:
|
||||
return "<";
|
||||
case Lteq:
|
||||
return "<=";
|
||||
case Gt:
|
||||
return ">";
|
||||
case Gteq:
|
||||
return ">=";
|
||||
case Like:
|
||||
return "like";
|
||||
case Notlike:
|
||||
return "not like";
|
||||
case Isnull:
|
||||
return "is null";
|
||||
case Isnotnull:
|
||||
return "is not null";
|
||||
}
|
||||
ctx_assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned
|
||||
Comp_op::arity() const
|
||||
{
|
||||
switch (m_opcode) {
|
||||
case Eq:
|
||||
case Noteq:
|
||||
case Lt:
|
||||
case Lteq:
|
||||
case Gt:
|
||||
case Gteq:
|
||||
case Like:
|
||||
case Notlike:
|
||||
return 2;
|
||||
case Isnull:
|
||||
case Isnotnull:
|
||||
return 1;
|
||||
}
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Plan_comp_op
|
||||
|
||||
Plan_comp_op::~Plan_comp_op()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_comp_op::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
m_exec = 0;
|
||||
const unsigned arity = m_op.arity();
|
||||
// analyze operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// for each operand, find type to convert to
|
||||
SqlType con[1 + 2];
|
||||
if (arity == 1) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
case SqlType::Datetime:
|
||||
case SqlType::Null:
|
||||
case SqlType::Unbound:
|
||||
con[1] = t1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef) {
|
||||
char b1[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s", b1, m_op.name());
|
||||
return 0;
|
||||
}
|
||||
} else if (arity == 2) {
|
||||
const SqlType& t1 = m_expr[1]->sqlType();
|
||||
const SqlType& t2 = m_expr[2]->sqlType();
|
||||
switch (t1.type()) {
|
||||
case SqlType::Char:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Varchar:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
// conversion would mask primary key optimization
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
con[1].setType(ctx, SqlType::Double);
|
||||
con[2] = con[1];
|
||||
break;
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
con[1].setType(ctx, SqlType::Double);
|
||||
con[2] = con[1];
|
||||
break;
|
||||
case SqlType::Null:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Datetime:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Datetime:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Null:
|
||||
switch (t2.type()) {
|
||||
case SqlType::Char:
|
||||
case SqlType::Varchar:
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
case SqlType::Real:
|
||||
case SqlType::Double:
|
||||
case SqlType::Datetime:
|
||||
con[1] = t1;
|
||||
con[2] = t2;
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SqlType::Unbound:
|
||||
con[1] = con[2] = t1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (con[1].type() == SqlType::Undef || con[2].type() == SqlType::Undef) {
|
||||
char b1[40], b2[40];
|
||||
t1.print(b1, sizeof(b1));
|
||||
t2.print(b2, sizeof(b2));
|
||||
ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s %s", b1, m_op.name(), b2);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// insert required conversions
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
if (con[i].type() == SqlType::Unbound) {
|
||||
continue;
|
||||
}
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, con[i]);
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_expr[i]);
|
||||
m_expr[i] = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
}
|
||||
// look for column=expr
|
||||
if (ctl.m_topand && m_op.m_opcode == Comp_op::Eq) {
|
||||
ctx_assert(arity == 2);
|
||||
for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
|
||||
if (m_expr[i]->type() != Plan_expr::TypeColumn)
|
||||
continue;
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
if (! column->resolveEq(ctx, m_expr[j]))
|
||||
ctl.m_extra = true;
|
||||
}
|
||||
} else {
|
||||
ctl.m_extra = true;
|
||||
}
|
||||
// save top level comparison on list
|
||||
if (ctl.m_topand) {
|
||||
ctl.m_topcomp.push_back(this);
|
||||
}
|
||||
// table dependencies are union from operands
|
||||
m_tableSet.clear();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_tableSet.insert(ts.begin(), ts.end());
|
||||
}
|
||||
// set of tables for which interpreter cannot be used
|
||||
m_noInterp.clear();
|
||||
// convenient
|
||||
#undef ustype
|
||||
#define ustype(b, n) (((b) ? 1 : 0) * 100 + (n))
|
||||
if (arity == 1) {
|
||||
for (unsigned i = 1; i <= 1; i++) {
|
||||
const SqlType t1 = m_expr[i]->sqlType();
|
||||
switch (m_op.m_opcode) {
|
||||
case Comp_op::Isnull:
|
||||
case Comp_op::Isnotnull:
|
||||
if (m_expr[i]->type() == Plan_expr::TypeColumn) {
|
||||
switch (ustype(t1.unSigned(), t1.type())) {
|
||||
// all types accepted now
|
||||
default:
|
||||
{
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
m_interpColumn[i] = column;
|
||||
continue; // ok
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_noInterp.insert(ts.begin(), ts.end());
|
||||
}
|
||||
} else if (arity == 2) {
|
||||
for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
|
||||
const SqlType t1 = m_expr[i]->sqlType();
|
||||
switch (m_op.m_opcode) {
|
||||
case Comp_op::Like:
|
||||
case Comp_op::Notlike:
|
||||
if (i == 2) // col like val but not val like col
|
||||
break;
|
||||
/*FALLTHRU*/
|
||||
case Comp_op::Eq:
|
||||
case Comp_op::Noteq:
|
||||
case Comp_op::Lt:
|
||||
case Comp_op::Lteq:
|
||||
case Comp_op::Gt:
|
||||
case Comp_op::Gteq:
|
||||
if (m_expr[i]->type() == Plan_expr::TypeColumn) {
|
||||
switch (ustype(t1.unSigned(), t1.type())) {
|
||||
case ustype(false, SqlType::Char):
|
||||
case ustype(false, SqlType::Varchar):
|
||||
case ustype(true, SqlType::Smallint):
|
||||
case ustype(true, SqlType::Integer):
|
||||
case ustype(true, SqlType::Bigint):
|
||||
{
|
||||
Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
const TableSet& ts = m_expr[j]->tableSet();
|
||||
if (ts.find(column->m_resTable) == ts.end()) {
|
||||
// candidate for column=const
|
||||
m_interpColumn[i] = column;
|
||||
continue; // ok
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const TableSet& ts = m_expr[i]->tableSet();
|
||||
m_noInterp.insert(ts.begin(), ts.end());
|
||||
}
|
||||
} else {
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
#undef ustype
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_comp_op::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
if (m_exec != 0)
|
||||
return m_exec;
|
||||
const unsigned arity = m_op.arity();
|
||||
Exec_comp_op* exec = new Exec_comp_op(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
// create code for operands
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr[i]->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
exec->setExpr(i, execExpr);
|
||||
}
|
||||
// create the code
|
||||
Exec_comp_op::Code& code = *new Exec_comp_op::Code(m_op);
|
||||
// interpreted column=const
|
||||
if (! ctl.m_having) {
|
||||
ctx_assert(ctl.m_topTable != 0);
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
Plan_expr_column* column = m_interpColumn[i];
|
||||
if (column == 0)
|
||||
continue;
|
||||
ctx_assert(column->m_resTable != 0);
|
||||
if (column->m_resTable != ctl.m_topTable)
|
||||
continue;
|
||||
ctx_assert(code.m_interpColumn == 0);
|
||||
code.m_interpColumn = i;
|
||||
code.m_interpAttrId = column->dictColumn().getAttrId();
|
||||
ctx_log2(("can use interpreter on %s", column->getPrintName()));
|
||||
}
|
||||
}
|
||||
exec->setCode(code);
|
||||
m_exec = exec;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_comp_op::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [%s", m_op.name());
|
||||
Plan_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
bool
|
||||
Plan_comp_op::isGroupBy(const Plan_expr_row* row) const
|
||||
{
|
||||
const unsigned arity = m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
if (! m_expr[i]->isGroupBy(row))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Code_comp_op
|
||||
|
||||
Exec_comp_op::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_comp_op::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_comp_op::~Exec_comp_op()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
// allocate subexpressions
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->alloc(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return;
|
||||
}
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
unsigned arity = code.m_op.arity();
|
||||
for (unsigned i = 1; i <= arity; i++) {
|
||||
ctx_assert(m_expr[i] != 0);
|
||||
m_expr[i]->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_comp_op::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [%s", code.m_op.name());
|
||||
Exec_base* a[] = { m_expr[1], m_expr[2] };
|
||||
printList(ctx, a, code.m_op.arity());
|
||||
ctx.print("]");
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_comp_op_hpp
|
||||
#define ODBC_CODEGEN_Code_comp_op_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataField.hpp>
|
||||
#include "Code_pred.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
#include "Code_expr_column.hpp"
|
||||
|
||||
/**
|
||||
* @class Comp_op
|
||||
* @brief Comparison operations
|
||||
*/
|
||||
struct Comp_op {
|
||||
enum Opcode {
|
||||
Eq = 1, // binary
|
||||
Noteq,
|
||||
Lt,
|
||||
Lteq,
|
||||
Gt,
|
||||
Gteq,
|
||||
Like,
|
||||
Notlike,
|
||||
Isnull, // unary
|
||||
Isnotnull
|
||||
};
|
||||
Comp_op(Opcode opcode);
|
||||
const char* name() const;
|
||||
unsigned arity() const;
|
||||
Opcode m_opcode;
|
||||
};
|
||||
|
||||
inline
|
||||
Comp_op::Comp_op(Opcode opcode) :
|
||||
m_opcode(opcode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Plan_comp_op
|
||||
* @brief Comparison operator node in PlanTree
|
||||
*/
|
||||
class Plan_comp_op : public Plan_pred {
|
||||
public:
|
||||
Plan_comp_op(Plan_root* root, Comp_op op);
|
||||
virtual ~Plan_comp_op();
|
||||
void setExpr(unsigned i, Plan_expr* expr);
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
virtual bool isGroupBy(const Plan_expr_row* row) const;
|
||||
protected:
|
||||
Comp_op m_op;
|
||||
Plan_expr* m_expr[1 + 2];
|
||||
Plan_expr_column* m_interpColumn[1 + 2]; // candidates
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_comp_op::Plan_comp_op(Plan_root* root, Comp_op op) :
|
||||
Plan_pred(root, TypeComp),
|
||||
m_op(op)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
m_interpColumn[0] = m_interpColumn[1] = m_interpColumn[2] = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_comp_op::setExpr(unsigned i, Plan_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_comp_op
|
||||
* @brief Comparison operator node in ExecTree
|
||||
*/
|
||||
class Exec_comp_op : public Exec_pred {
|
||||
public:
|
||||
class Code : public Exec_pred::Code {
|
||||
public:
|
||||
Code(Comp_op op);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_comp_op;
|
||||
friend class Exec_comp_op;
|
||||
Comp_op m_op;
|
||||
unsigned m_interpColumn; // 1 or 2 if interpreted column, 0 if both constant
|
||||
NdbAttrId m_interpAttrId;
|
||||
};
|
||||
class Data : public Exec_pred::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_comp_op;
|
||||
};
|
||||
Exec_comp_op(Exec_root* root);
|
||||
virtual ~Exec_comp_op();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execInterp(Ctx& ctx, Ctl& ctl);
|
||||
void evaluate(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
void setExpr(unsigned i, Exec_expr* expr);
|
||||
protected:
|
||||
Exec_expr* m_expr[1 + 2];
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_comp_op::Code::Code(Comp_op op) :
|
||||
m_op(op),
|
||||
m_interpColumn(0),
|
||||
m_interpAttrId((NdbAttrId)-1)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_comp_op::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_comp_op::Exec_comp_op(Exec_root* root) :
|
||||
Exec_pred(root)
|
||||
{
|
||||
m_expr[0] = m_expr[1] = m_expr[2] = 0;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_comp_op::Code&
|
||||
Exec_comp_op::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_comp_op::Data&
|
||||
Exec_comp_op::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
inline void
|
||||
Exec_comp_op::setExpr(unsigned i, Exec_expr* expr)
|
||||
{
|
||||
ctx_assert(1 <= i && i <= 2 && m_expr[i] == 0);
|
||||
m_expr[i] = expr;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,124 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <common/StmtArea.hpp>
|
||||
#include "Code_create_index.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_create_index
|
||||
|
||||
Plan_create_index::~Plan_create_index()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_index::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_create_index);
|
||||
// analyze the table
|
||||
ctx_assert(m_table != 0);
|
||||
m_table->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// analyze the columns
|
||||
ctl.m_tableList.resize(1 + 1); // indexed from 1
|
||||
ctl.m_tableList[1] = m_table;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
column->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_index::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "CREATE INDEX", SQL_DIAG_CREATE_INDEX);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_index::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Exec_create_index* exec = new Exec_create_index(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
const unsigned count = countColumn();
|
||||
const char** attrList = new const char* [1 + count];
|
||||
attrList[0] = 0; // unused
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
const char* cname = column->getName().c_str();
|
||||
attrList[i] = strcpy(new char[strlen(cname) + 1], cname);
|
||||
}
|
||||
Exec_create_index::Code& code = *new Exec_create_index::Code(m_name, m_table->getName(), m_type, count, attrList);
|
||||
exec->setCode(code);
|
||||
code.m_fragmentType = m_fragmentType;
|
||||
code.m_logging = m_logging;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_index::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_index name=%s table=%s type=%d", m_name.c_str(), m_table->getName().c_str(), (int)m_type);
|
||||
ctx.print(" [");
|
||||
for (unsigned i = 1; i <= countColumn(); i++) {
|
||||
Plan_idx_column* column = getColumn(i);
|
||||
if (i > 1)
|
||||
ctx.print(" ");
|
||||
column->print(ctx);
|
||||
}
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_create_index
|
||||
|
||||
Exec_create_index::Code::~Code()
|
||||
{
|
||||
for (unsigned i = 1; i <= m_attrCount; i++) {
|
||||
delete[] m_attrList[i];
|
||||
m_attrList[i] = 0;
|
||||
}
|
||||
delete[] m_attrList;
|
||||
}
|
||||
|
||||
Exec_create_index::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_create_index::~Exec_create_index()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::close(Ctx& ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_index::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [create_index %s]", code.m_tableName.c_str());
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_index_hpp
|
||||
#define ODBC_CODEGEN_Code_create_index_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <NdbApi.hpp>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
#include "Code_table.hpp"
|
||||
#include "Code_idx_column.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_create_index
|
||||
* @brief Create table in PlanTree
|
||||
*/
|
||||
class Plan_create_index : public Plan_ddl {
|
||||
public:
|
||||
Plan_create_index(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_create_index();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
// children
|
||||
void setType(NdbDictionary::Object::Type type);
|
||||
void setTable(Plan_table* table);
|
||||
unsigned countColumn() const;
|
||||
void addColumn(Plan_idx_column* column);
|
||||
Plan_idx_column* getColumn(unsigned i) const;
|
||||
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
|
||||
void setLogging(bool logging);
|
||||
protected:
|
||||
BaseString m_name;
|
||||
NdbDictionary::Object::Type m_type;
|
||||
Plan_table* m_table;
|
||||
IdxColumnVector m_columnList;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_index::Plan_create_index(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name),
|
||||
m_type(NdbDictionary::Object::TypeUndefined),
|
||||
m_columnList(1),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_create_index::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_create_index::setType(NdbDictionary::Object::Type type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setTable(Plan_table* table)
|
||||
{
|
||||
ctx_assert(table != 0);
|
||||
m_table = table;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
Plan_create_index::countColumn() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::addColumn(Plan_idx_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_idx_column*
|
||||
Plan_create_index::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= countColumn() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
|
||||
{
|
||||
m_fragmentType = fragmentType;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_index::setLogging(bool logging)
|
||||
{
|
||||
m_logging = logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_create_index
|
||||
* @brief Create table in ExecTree
|
||||
*/
|
||||
class Exec_create_index : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_create_index;
|
||||
friend class Exec_create_index;
|
||||
const BaseString m_indexName;
|
||||
const BaseString m_tableName;
|
||||
NdbDictionary::Object::Type m_type;
|
||||
const unsigned m_attrCount;
|
||||
const char** m_attrList;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_create_index;
|
||||
};
|
||||
Exec_create_index(Exec_root* root);
|
||||
virtual ~Exec_create_index();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_create_index::Code::Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList) :
|
||||
m_indexName(indexName),
|
||||
m_tableName(tableName),
|
||||
m_type(type),
|
||||
m_attrCount(attrCount),
|
||||
m_attrList(attrList),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_index::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_index::Exec_create_index(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_create_index::Code&
|
||||
Exec_create_index::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_create_index::Data&
|
||||
Exec_create_index::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,162 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "Code_create_row.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
Plan_create_row::~Plan_create_row()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_row::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
// check for duplicate column name
|
||||
for (unsigned i = 1, n = countColumn(); i < n; i++) {
|
||||
const BaseString& a = getColumn(i)->getName();
|
||||
for (unsigned i2 = i + 1; i2 <= n; i2++) {
|
||||
const BaseString& a2 = getColumn(i2)->getName();
|
||||
if (strcmp(a.c_str(), a2.c_str()) == 0) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate column %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// move single-column primary key constraint to constraint list
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (column->m_primaryKey) {
|
||||
Plan_ddl_row* ddlRow = new Plan_ddl_row(m_root);
|
||||
m_root->saveNode(ddlRow);
|
||||
ddlRow->addColumn(column);
|
||||
Plan_ddl_constr* constr = new Plan_ddl_constr(m_root);
|
||||
m_root->saveNode(constr);
|
||||
constr->setRow(ddlRow);
|
||||
addConstr(constr);
|
||||
column->m_primaryKey = false; // will be set again
|
||||
}
|
||||
}
|
||||
// check primary key constraints
|
||||
if (countConstr() < 1) {
|
||||
ctx.pushStatus(Error::Gen, "table must have a primary key");
|
||||
return 0;
|
||||
}
|
||||
if (countConstr() > 1) {
|
||||
ctx.pushStatus(Error::Gen, "table can have only one primary key");
|
||||
return 0;
|
||||
}
|
||||
Plan_ddl_row* ddlRow = getConstr(1)->getRow();
|
||||
for (unsigned i = 1, n = ddlRow->countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = ddlRow->getColumn(i);
|
||||
const BaseString& a = column->getName();
|
||||
bool found = false;
|
||||
for (unsigned i2 = 1, n2 = countColumn(); i2 <= n2; i2++) {
|
||||
Plan_ddl_column* column2 = getColumn(i2);
|
||||
const BaseString& a2 = column2->getName();
|
||||
if (strcmp(a.c_str(), a2.c_str()) != 0)
|
||||
continue;
|
||||
if (column2->getPrimaryKey()) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate primary key constraint on %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
column2->setPrimaryKey();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (! found) {
|
||||
ctx.pushStatus(Error::Gen, "undefined primary key column %s", a.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// analyze column types
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
getColumn(i)->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
}
|
||||
// check TupleId
|
||||
unsigned tupleId = 0;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (! column->getTupleId())
|
||||
continue;
|
||||
if (i != 1) {
|
||||
ctx.pushStatus(Error::Gen, "tuple id column %u is not first column", i);
|
||||
return 0;
|
||||
}
|
||||
if (tupleId != 0) { // cannot happen now since attr name is fixed
|
||||
ctx.pushStatus(Error::Gen, "duplicate tuple id column %u", i);
|
||||
return 0;
|
||||
}
|
||||
tupleId = i;
|
||||
}
|
||||
if (tupleId != 0) {
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (i == tupleId)
|
||||
continue;
|
||||
if (! column->getPrimaryKey())
|
||||
continue;
|
||||
ctx.pushStatus(Error::Gen, "cannot have both tuple id and other primary key column %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check auto-increment
|
||||
unsigned autoIncrement = 0;
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (! column->getAutoIncrement())
|
||||
continue;
|
||||
if (autoIncrement != 0) {
|
||||
ctx.pushStatus(Error::Gen, "duplicate auto-increment column %u", i);
|
||||
return 0;
|
||||
}
|
||||
autoIncrement = i;
|
||||
}
|
||||
if (autoIncrement != 0) {
|
||||
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
|
||||
Plan_ddl_column* column = getColumn(i);
|
||||
if (i == autoIncrement)
|
||||
continue;
|
||||
if (! column->getPrimaryKey())
|
||||
continue;
|
||||
ctx.pushStatus(Error::Gen, "cannot have both auto-increment column and other primary key column %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_row::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_row::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_row");
|
||||
for (unsigned i = 1; i <= countColumn(); i++) {
|
||||
Plan_base* a = m_columnList[i];
|
||||
printList(ctx, &a, 1);
|
||||
}
|
||||
for (unsigned i = 1; i <= countConstr(); i++) {
|
||||
Plan_base* a = m_constrList[i];
|
||||
printList(ctx, &a, 1);
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_row_hpp
|
||||
#define ODBC_CODEGEN_Code_create_row_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_base.hpp"
|
||||
#include "Code_ddl_column.hpp"
|
||||
#include "Code_ddl_constr.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_create_row
|
||||
* @brief Row of columns and constraints in create statement
|
||||
*/
|
||||
class Plan_create_row : public Plan_base {
|
||||
public:
|
||||
Plan_create_row(Plan_root* root);
|
||||
virtual ~Plan_create_row();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
unsigned countColumn() const;
|
||||
void addColumn(Plan_ddl_column* column);
|
||||
Plan_ddl_column* getColumn(unsigned i) const;
|
||||
unsigned countConstr() const;
|
||||
void addConstr(Plan_ddl_constr* constr);
|
||||
Plan_ddl_constr* getConstr(unsigned i) const;
|
||||
protected:
|
||||
DdlColumnVector m_columnList;
|
||||
DdlConstrVector m_constrList;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_row::Plan_create_row(Plan_root* root) :
|
||||
Plan_base(root),
|
||||
m_columnList(1),
|
||||
m_constrList(1)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline unsigned
|
||||
Plan_create_row::countColumn() const
|
||||
{
|
||||
return m_columnList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_row::addColumn(Plan_ddl_column* column)
|
||||
{
|
||||
ctx_assert(column != 0);
|
||||
m_columnList.push_back(column);
|
||||
}
|
||||
|
||||
inline Plan_ddl_column*
|
||||
Plan_create_row::getColumn(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_columnList.size() && m_columnList[i] != 0);
|
||||
return m_columnList[i];
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
Plan_create_row::countConstr() const
|
||||
{
|
||||
return m_constrList.size() - 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_row::addConstr(Plan_ddl_constr* constr)
|
||||
{
|
||||
ctx_assert(constr != 0);
|
||||
m_constrList.push_back(constr);
|
||||
}
|
||||
|
||||
inline Plan_ddl_constr*
|
||||
Plan_create_row::getConstr(unsigned i) const
|
||||
{
|
||||
ctx_assert(1 <= i && i <= m_constrList.size() && m_constrList[i] != 0);
|
||||
return m_constrList[i];
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,137 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <common/StmtArea.hpp>
|
||||
#include "Code_create_table.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_create_table
|
||||
|
||||
Plan_create_table::~Plan_create_table()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_create_table::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
stmtArea().stmtInfo().setName(Stmt_name_create_table);
|
||||
// analyze the create row
|
||||
ctx_assert(m_createRow != 0);
|
||||
m_createRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_table::describe(Ctx& ctx)
|
||||
{
|
||||
stmtArea().setFunction(ctx, "CREATE TABLE", SQL_DIAG_CREATE_TABLE);
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_create_table::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_createRow != 0);
|
||||
Exec_create_table* exec = new Exec_create_table(ctl.m_execRoot);
|
||||
ctl.m_execRoot->saveNode(exec);
|
||||
const unsigned count = m_createRow->countColumn();
|
||||
Exec_create_table::Code::Attr* attrList = new Exec_create_table::Code::Attr[1 + count];
|
||||
unsigned tupleId = 0;
|
||||
unsigned autoIncrement = 0;
|
||||
for (unsigned i = 1; i <= count; i++) {
|
||||
Plan_ddl_column* column = m_createRow->getColumn(i);
|
||||
Exec_create_table::Code::Attr& attr = attrList[i];
|
||||
attr.m_attrName.assign(column->getName());
|
||||
attr.m_sqlType = column->sqlType();
|
||||
attr.m_tupleKey = column->getPrimaryKey();
|
||||
attr.m_tupleId = column->getTupleId();
|
||||
attr.m_autoIncrement = column->getAutoIncrement();
|
||||
if (attr.m_tupleId)
|
||||
tupleId = i;
|
||||
if (attr.m_autoIncrement)
|
||||
autoIncrement = i;
|
||||
attr.m_defaultValue = 0;
|
||||
Plan_expr* expr;
|
||||
if ((expr = column->getDefaultValue()) != 0) {
|
||||
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(execExpr != 0);
|
||||
attr.m_defaultValue = execExpr;
|
||||
}
|
||||
}
|
||||
Exec_create_table::Code& code = *new Exec_create_table::Code(m_name, count, attrList, tupleId, autoIncrement);
|
||||
exec->setCode(code);
|
||||
code.m_fragmentType = m_fragmentType;
|
||||
code.m_logging = m_logging;
|
||||
return exec;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_create_table::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [create_table '%s'", m_name.c_str());
|
||||
Plan_base* a[] = { m_createRow };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
||||
|
||||
// Exec_create_table
|
||||
|
||||
Exec_create_table::Code::~Code()
|
||||
{
|
||||
delete[] m_attrList;
|
||||
}
|
||||
|
||||
Exec_create_table::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_create_table::~Exec_create_table()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::alloc(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
for (unsigned i = 1; i <= code.m_attrCount; i++) {
|
||||
const Code::Attr& attr = code.m_attrList[i];
|
||||
if (attr.m_defaultValue != 0)
|
||||
attr.m_defaultValue->alloc(ctx, ctl);
|
||||
}
|
||||
Data& data = *new Data;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::close(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
for (unsigned i = 1; i <= code.m_attrCount; i++) {
|
||||
const Code::Attr& attr = code.m_attrList[i];
|
||||
if (attr.m_defaultValue != 0)
|
||||
attr.m_defaultValue->close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exec_create_table::print(Ctx& ctx)
|
||||
{
|
||||
const Code& code = getCode();
|
||||
ctx.print(" [create_table %s]", code.m_tableName.c_str());
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_create_table_hpp
|
||||
#define ODBC_CODEGEN_Code_create_table_hpp
|
||||
|
||||
#include <vector>
|
||||
#include <common/common.hpp>
|
||||
#include "Code_ddl.hpp"
|
||||
#include "Code_ddl_row.hpp"
|
||||
#include "Code_create_row.hpp"
|
||||
|
||||
class DictTable;
|
||||
class DictColumn;
|
||||
|
||||
/**
|
||||
* @class Plan_create_table
|
||||
* @brief Create table in PlanTree
|
||||
*/
|
||||
class Plan_create_table : public Plan_ddl {
|
||||
public:
|
||||
Plan_create_table(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_create_table();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void describe(Ctx & ctx);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
const BaseString& getName() const;
|
||||
// children
|
||||
void setCreateRow(Plan_create_row* createRow);
|
||||
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
|
||||
void setLogging(bool logging);
|
||||
protected:
|
||||
BaseString m_name;
|
||||
Plan_create_row* m_createRow;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_create_table::Plan_create_table(Plan_root* root, const BaseString& name) :
|
||||
Plan_ddl(root),
|
||||
m_name(name),
|
||||
m_createRow(0),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline const BaseString&
|
||||
Plan_create_table::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_create_table::setCreateRow(Plan_create_row* createRow)
|
||||
{
|
||||
ctx_assert(createRow != 0);
|
||||
m_createRow = createRow;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_table::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
|
||||
{
|
||||
m_fragmentType = fragmentType;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_create_table::setLogging(bool logging)
|
||||
{
|
||||
m_logging = logging;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_create_table
|
||||
* @brief Create table in ExecTree
|
||||
*/
|
||||
class Exec_create_table : public Exec_ddl {
|
||||
public:
|
||||
class Code : public Exec_ddl::Code {
|
||||
public:
|
||||
struct Attr {
|
||||
Attr() : m_defaultValue(0) {}
|
||||
BaseString m_attrName;
|
||||
SqlType m_sqlType;
|
||||
bool m_tupleKey;
|
||||
bool m_tupleId;
|
||||
bool m_autoIncrement;
|
||||
Exec_expr* m_defaultValue;
|
||||
};
|
||||
Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement);
|
||||
virtual ~Code();
|
||||
protected:
|
||||
friend class Plan_create_table;
|
||||
friend class Exec_create_table;
|
||||
const BaseString m_tableName;
|
||||
const unsigned m_attrCount;
|
||||
const Attr* const m_attrList;
|
||||
unsigned m_tupleId;
|
||||
unsigned m_autoIncrement;
|
||||
NdbDictionary::Object::FragmentType m_fragmentType;
|
||||
bool m_logging;
|
||||
};
|
||||
class Data : public Exec_ddl::Data {
|
||||
public:
|
||||
Data();
|
||||
virtual ~Data();
|
||||
protected:
|
||||
friend class Exec_create_table;
|
||||
};
|
||||
Exec_create_table(Exec_root* root);
|
||||
virtual ~Exec_create_table();
|
||||
void alloc(Ctx& ctx, Ctl& ctl);
|
||||
void execute(Ctx& ctx, Ctl& ctl);
|
||||
void close(Ctx& ctx);
|
||||
void print(Ctx& ctx);
|
||||
// children
|
||||
const Code& getCode() const;
|
||||
Data& getData() const;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_create_table::Code::Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement) :
|
||||
m_tableName(tableName),
|
||||
m_attrCount(attrCount),
|
||||
m_attrList(attrList),
|
||||
m_tupleId(tupleId),
|
||||
m_autoIncrement(autoIncrement),
|
||||
m_fragmentType(NdbDictionary::Object::FragUndefined),
|
||||
m_logging(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_table::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Exec_create_table::Exec_create_table(Exec_root* root) :
|
||||
Exec_ddl(root)
|
||||
{
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline const Exec_create_table::Code&
|
||||
Exec_create_table::getCode() const
|
||||
{
|
||||
const Code* code = static_cast<const Code*>(m_code);
|
||||
return *code;
|
||||
}
|
||||
|
||||
inline Exec_create_table::Data&
|
||||
Exec_create_table::getData() const
|
||||
{
|
||||
Data* data = static_cast<Data*>(m_data);
|
||||
return *data;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_data_type.hpp"
|
||||
|
||||
// Plan_data_type
|
||||
|
||||
Plan_data_type::~Plan_data_type()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_data_type::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_data_type::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_data_type::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [data_type]");
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_data_type_hpp
|
||||
#define ODBC_CODEGEN_Code_data_type_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include <common/DataType.hpp>
|
||||
#include "Code_base.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_data_type
|
||||
* @brief Data type in DDL statement
|
||||
*
|
||||
* This is pure plan node.
|
||||
*/
|
||||
class Plan_data_type : public Plan_base {
|
||||
public:
|
||||
Plan_data_type(Plan_root* root, const SqlType& sqlType);
|
||||
virtual ~Plan_data_type();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
private:
|
||||
friend class Plan_ddl_column;
|
||||
SqlType m_sqlType;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_data_type::Plan_data_type(Plan_root* root, const SqlType& sqlType) :
|
||||
Plan_base(root),
|
||||
m_sqlType(sqlType)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 "Code_ddl.hpp"
|
||||
|
||||
// Plan_ddl
|
||||
|
||||
Plan_ddl::~Plan_ddl()
|
||||
{
|
||||
}
|
||||
|
||||
// Exec_ddl
|
||||
|
||||
Exec_ddl::Code::~Code()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_ddl::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Exec_ddl::~Exec_ddl()
|
||||
{
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_stmt.hpp"
|
||||
|
||||
/**
|
||||
* @class Plan_ddl
|
||||
* @brief Base class for DDL statements in PlanTree
|
||||
*/
|
||||
class Plan_ddl : public Plan_stmt {
|
||||
public:
|
||||
Plan_ddl(Plan_root* root);
|
||||
virtual ~Plan_ddl() = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl::Plan_ddl(Plan_root* root) :
|
||||
Plan_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Exec_ddl
|
||||
* @brief Base class for DDL statements in ExecTree
|
||||
*/
|
||||
class Exec_ddl : public Exec_stmt {
|
||||
public:
|
||||
class Code : public Exec_stmt::Code {
|
||||
public:
|
||||
virtual ~Code() = 0;
|
||||
};
|
||||
class Data : public Exec_stmt::Data {
|
||||
public:
|
||||
virtual ~Data() = 0;
|
||||
};
|
||||
Exec_ddl(Exec_root* root);
|
||||
virtual ~Exec_ddl() = 0;
|
||||
};
|
||||
|
||||
inline
|
||||
Exec_ddl::Exec_ddl(Exec_root* root) :
|
||||
Exec_stmt(root)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,104 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_ddl_column.hpp"
|
||||
#include "Code_expr_conv.hpp"
|
||||
#include "Code_root.hpp"
|
||||
|
||||
// Plan_ddl_column
|
||||
|
||||
Plan_ddl_column::~Plan_ddl_column()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_ddl_column::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_type != 0);
|
||||
if (! m_type->m_sqlType.nullable()) {
|
||||
m_nullable = false;
|
||||
}
|
||||
m_sqlType = m_type->m_sqlType;
|
||||
m_sqlType.nullable(m_nullable);
|
||||
const BaseString& name = getName();
|
||||
if (m_unSigned) {
|
||||
switch (m_sqlType.type()) {
|
||||
case SqlType::Smallint:
|
||||
case SqlType::Integer:
|
||||
case SqlType::Bigint:
|
||||
break;
|
||||
default:
|
||||
ctx.pushStatus(Error::Gen, "invalid unsigned qualifier on column %s", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
m_sqlType.unSigned(true);
|
||||
}
|
||||
if (strcmp(name.c_str(), "NDB$TID") == 0) {
|
||||
if (! m_primaryKey) {
|
||||
ctx.pushStatus(Error::Gen, "column %s must be a primary key", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
if (sqlType().type() != SqlType::Bigint || ! sqlType().unSigned()) {
|
||||
ctx.pushStatus(Error::Gen, "tuple id %s must have type BIGINT UNSIGNED", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
setTupleId();
|
||||
}
|
||||
if (m_autoIncrement) {
|
||||
if (! m_primaryKey) {
|
||||
ctx.pushStatus(Error::Gen, "auto-increment column %s must be a primary key", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
if (sqlType().type() != SqlType::Smallint && sqlType().type() != SqlType::Integer && sqlType().type() != SqlType::Bigint) {
|
||||
ctx.pushStatus(Error::Gen, "auto-increment column %s must have an integral type", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (m_defaultValue != 0) {
|
||||
if (m_primaryKey) {
|
||||
ctx.pushStatus(Sqlstate::_42000, Error::Gen, "default value not allowed on primary key column %s", name.c_str());
|
||||
return 0;
|
||||
}
|
||||
m_defaultValue->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
// insert conversion node
|
||||
Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, sqlType());
|
||||
m_root->saveNode(exprConv);
|
||||
exprConv->setExpr(m_defaultValue);
|
||||
Plan_expr* expr = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
ctx_assert(expr != 0);
|
||||
m_defaultValue = expr;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_ddl_column::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_ddl_column::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [ddl_column %s key=%d id=%d]", getPrintName(), m_primaryKey, m_tupleId);
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 */
|
||||
|
||||
#ifndef ODBC_CODEGEN_Code_ddl_column_hpp
|
||||
#define ODBC_CODEGEN_Code_ddl_column_hpp
|
||||
|
||||
#include <common/common.hpp>
|
||||
#include "Code_column.hpp"
|
||||
#include "Code_data_type.hpp"
|
||||
#include "Code_expr.hpp"
|
||||
|
||||
class DictColumn;
|
||||
class Plan_table;
|
||||
|
||||
/**
|
||||
* @class Plan_ddl_column
|
||||
* @brief Column in DDL statement
|
||||
*/
|
||||
class Plan_ddl_column : public Plan_base, public Plan_column {
|
||||
public:
|
||||
Plan_ddl_column(Plan_root* root, const BaseString& name);
|
||||
virtual ~Plan_ddl_column();
|
||||
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
|
||||
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
|
||||
void print(Ctx& ctx);
|
||||
// attributes
|
||||
void setNotNull();
|
||||
void setUnSigned();
|
||||
void setPrimaryKey();
|
||||
bool getPrimaryKey() const;
|
||||
void setTupleId();
|
||||
bool getTupleId() const;
|
||||
void setAutoIncrement();
|
||||
bool getAutoIncrement() const;
|
||||
// children
|
||||
void setType(Plan_data_type* type);
|
||||
void setDefaultValue(Plan_expr* defaultValue);
|
||||
Plan_expr* getDefaultValue() const;
|
||||
protected:
|
||||
friend class Plan_create_row;
|
||||
Plan_data_type* m_type;
|
||||
Plan_expr* m_defaultValue;
|
||||
bool m_nullable;
|
||||
bool m_unSigned;
|
||||
bool m_primaryKey;
|
||||
bool m_tupleId;
|
||||
bool m_autoIncrement;
|
||||
};
|
||||
|
||||
inline
|
||||
Plan_ddl_column::Plan_ddl_column(Plan_root* root, const BaseString& name) :
|
||||
Plan_base(root),
|
||||
Plan_column(Type_ddl, name),
|
||||
m_type(0),
|
||||
m_defaultValue(0),
|
||||
m_nullable(true),
|
||||
m_unSigned(false),
|
||||
m_primaryKey(false),
|
||||
m_tupleId(false),
|
||||
m_autoIncrement(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setNotNull()
|
||||
{
|
||||
m_nullable = false;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setUnSigned()
|
||||
{
|
||||
m_unSigned = true;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setPrimaryKey()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_primaryKey = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getPrimaryKey() const
|
||||
{
|
||||
return m_primaryKey;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setTupleId()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_tupleId = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getTupleId() const
|
||||
{
|
||||
return m_tupleId;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setAutoIncrement()
|
||||
{
|
||||
m_nullable = false;
|
||||
m_autoIncrement = true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
Plan_ddl_column::getAutoIncrement() const
|
||||
{
|
||||
return m_autoIncrement;
|
||||
}
|
||||
|
||||
// children
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setType(Plan_data_type* type)
|
||||
{
|
||||
ctx_assert(type != 0);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
inline void
|
||||
Plan_ddl_column::setDefaultValue(Plan_expr* defaultValue)
|
||||
{
|
||||
ctx_assert(defaultValue != 0);
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
inline Plan_expr*
|
||||
Plan_ddl_column::getDefaultValue() const
|
||||
{
|
||||
return m_defaultValue;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,51 +0,0 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
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.
|
||||
|
||||
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 <NdbApi.hpp>
|
||||
#include <common/StmtArea.hpp>
|
||||
#include "Code_ddl_constr.hpp"
|
||||
|
||||
// Plan_ddl_constr
|
||||
|
||||
Plan_ddl_constr::~Plan_ddl_constr()
|
||||
{
|
||||
}
|
||||
|
||||
Plan_base*
|
||||
Plan_ddl_constr::analyze(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(m_ddlRow != 0);
|
||||
m_ddlRow->analyze(ctx, ctl);
|
||||
if (! ctx.ok())
|
||||
return 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
Exec_base*
|
||||
Plan_ddl_constr::codegen(Ctx& ctx, Ctl& ctl)
|
||||
{
|
||||
ctx_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Plan_ddl_constr::print(Ctx& ctx)
|
||||
{
|
||||
ctx.print(" [ddl_constr");
|
||||
Plan_base* a[] = { m_ddlRow };
|
||||
printList(ctx, a, 1);
|
||||
ctx.print("]");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue