Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
7c2c408c
Commit
7c2c408c
authored
Apr 15, 2004
by
magnus@neptunus.(none)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added NDB storage engine
parent
ec9e88ba
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
3564 additions
and
48 deletions
+3564
-48
include/my_base.h
include/my_base.h
+3
-0
sql/Makefile.am
sql/Makefile.am
+5
-5
sql/discover.cc
sql/discover.cc
+172
-0
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.cc
+2943
-0
sql/ha_ndbcluster.h
sql/ha_ndbcluster.h
+218
-0
sql/handler.cc
sql/handler.cc
+88
-4
sql/handler.h
sql/handler.h
+16
-8
sql/lex.h
sql/lex.h
+5
-3
sql/mysql_priv.h
sql/mysql_priv.h
+6
-1
sql/mysqld.cc
sql/mysqld.cc
+27
-3
sql/set_var.cc
sql/set_var.cc
+4
-0
sql/sql_base.cc
sql/sql_base.cc
+19
-2
sql/sql_class.h
sql/sql_class.h
+6
-2
sql/sql_table.cc
sql/sql_table.cc
+29
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+21
-19
sql/table.cc
sql/table.cc
+2
-1
No files found.
include/my_base.h
View file @
7c2c408c
...
@@ -287,6 +287,9 @@ enum ha_base_keytype {
...
@@ -287,6 +287,9 @@ enum ha_base_keytype {
#define HA_ERR_ROW_IS_REFERENCED 152
/* Cannot delete a parent row */
#define HA_ERR_ROW_IS_REFERENCED 152
/* Cannot delete a parent row */
#define HA_ERR_NO_SAVEPOINT 153
/* No savepoint with that name */
#define HA_ERR_NO_SAVEPOINT 153
/* No savepoint with that name */
#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 154
/* Non unique key block size */
#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 154
/* Non unique key block size */
#define HA_ERR_OLD_METADATA 155
/* The frm file on disk is old */
#define HA_ERR_TABLE_EXIST 156
/* The table existed in storage engine */
#define HA_ERR_NO_CONNECTION 157
/* Could not connect to storage engine */
/* Other constants */
/* Other constants */
...
...
sql/Makefile.am
View file @
7c2c408c
...
@@ -16,12 +16,11 @@
...
@@ -16,12 +16,11 @@
#called from the top level Makefile
#called from the top level Makefile
MYSQLDATAdir
=
$(localstatedir)
MYSQLDATAdir
=
$(localstatedir)
MYSQLSHAREdir
=
$(pkgdatadir)
MYSQLSHAREdir
=
$(pkgdatadir)
MYSQLBASEdir
=
$(prefix)
MYSQLBASEdir
=
$(prefix)
INCLUDES
=
@MT_INCLUDES@
\
INCLUDES
=
@MT_INCLUDES@
\
@bdb_includes@ @innodb_includes@
\
@bdb_includes@ @innodb_includes@
@ndbcluster_includes@
\
-I
$(top_srcdir)
/include
-I
$(top_srcdir)
/regex
\
-I
$(top_srcdir)
/include
-I
$(top_srcdir)
/regex
\
-I
$(srcdir)
$(openssl_includes)
-I
$(srcdir)
$(openssl_includes)
WRAPLIBS
=
@WRAPLIBS@
WRAPLIBS
=
@WRAPLIBS@
...
@@ -42,6 +41,7 @@ LDADD = @isam_libs@ \
...
@@ -42,6 +41,7 @@ LDADD = @isam_libs@ \
mysqld_LDADD
=
@MYSQLD_EXTRA_LDFLAGS@
\
mysqld_LDADD
=
@MYSQLD_EXTRA_LDFLAGS@
\
@bdb_libs@ @innodb_libs@ @pstack_libs@
\
@bdb_libs@ @innodb_libs@ @pstack_libs@
\
@innodb_system_libs@
\
@innodb_system_libs@
\
@ndbcluster_libs@ @ndbcluster_system_libs@
\
$(LDADD)
$(CXXLDFLAGS)
$(WRAPLIBS)
@LIBDL@ @openssl_libs@
$(LDADD)
$(CXXLDFLAGS)
$(WRAPLIBS)
@LIBDL@ @openssl_libs@
noinst_HEADERS
=
item.h item_func.h item_sum.h item_cmpfunc.h
\
noinst_HEADERS
=
item.h item_func.h item_sum.h item_cmpfunc.h
\
item_strfunc.h item_timefunc.h item_uniq.h
\
item_strfunc.h item_timefunc.h item_uniq.h
\
...
@@ -52,7 +52,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
...
@@ -52,7 +52,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
field.h handler.h
\
field.h handler.h
\
ha_isammrg.h ha_isam.h ha_myisammrg.h
\
ha_isammrg.h ha_isam.h ha_myisammrg.h
\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h
\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h
\
opt_range.h protocol.h
\
ha_ndbcluster.h
opt_range.h protocol.h
\
sql_select.h structs.h table.h sql_udf.h hash_filo.h
\
sql_select.h structs.h table.h sql_udf.h hash_filo.h
\
lex.h lex_symbol.h sql_acl.h sql_crypt.h
\
lex.h lex_symbol.h sql_acl.h sql_crypt.h
\
log_event.h sql_repl.h slave.h
\
log_event.h sql_repl.h slave.h
\
...
@@ -75,11 +75,11 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
...
@@ -75,11 +75,11 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
procedure.cc item_uniq.cc sql_test.cc
\
procedure.cc item_uniq.cc sql_test.cc
\
log.cc log_event.cc init.cc derror.cc sql_acl.cc
\
log.cc log_event.cc init.cc derror.cc sql_acl.cc
\
unireg.cc des_key_file.cc
\
unireg.cc des_key_file.cc
\
time.cc opt_range.cc opt_sum.cc
\
discover.cc
time.cc opt_range.cc opt_sum.cc
\
records.cc filesort.cc handler.cc
\
records.cc filesort.cc handler.cc
\
ha_heap.cc ha_myisam.cc ha_myisammrg.cc
\
ha_heap.cc ha_myisam.cc ha_myisammrg.cc
\
ha_berkeley.cc ha_innodb.cc
\
ha_berkeley.cc ha_innodb.cc
\
ha_isam.cc ha_isammrg.cc
\
ha_isam.cc ha_isammrg.cc
ha_ndbcluster.cc
\
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc
\
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc
\
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc
\
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc
\
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc
\
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc
\
...
...
sql/discover.cc
0 → 100644
View file @
7c2c408c
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
/* Functions for discover of frm file from handler */
#include "mysql_priv.h"
#include <my_dir.h>
/*
Read the contents of a .frm file
SYNOPSIS
readfrm()
name path to table-file "db/name"
frmdata frm data
len length of the read frmdata
RETURN VALUES
0 ok
1 Could not open file
2 Could not stat file
3 Could not allocate data for read
Could not read file
frmdata and len are set to 0 on error
*/
int
readfrm
(
const
char
*
name
,
const
void
**
frmdata
,
uint
*
len
)
{
int
error
;
char
index_file
[
FN_REFLEN
];
File
file
;
ulong
read_len
;
char
*
read_data
;
MY_STAT
state
;
DBUG_ENTER
(
"readfrm"
);
DBUG_PRINT
(
"enter"
,(
"name: '%s'"
,
name
));
*
frmdata
=
NULL
;
// In case of errors
*
len
=
0
;
error
=
1
;
if
((
file
=
my_open
(
fn_format
(
index_file
,
name
,
""
,
reg_ext
,
4
),
O_RDONLY
|
O_SHARE
,
MYF
(
0
)))
<
0
)
goto
err_end
;
// Get length of file
error
=
2
;
if
(
my_fstat
(
file
,
&
state
,
MYF
(
0
)))
goto
err
;
read_len
=
state
.
st_size
;
// Read whole frm file
error
=
3
;
read_data
=
0
;
if
(
read_string
(
file
,
&
read_data
,
read_len
))
goto
err
;
// Setup return data
*
frmdata
=
(
void
*
)
read_data
;
*
len
=
read_len
;
error
=
0
;
err:
if
(
file
>
0
)
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
err_end:
/* Here when no file */
DBUG_RETURN
(
error
);
}
/* readfrm */
/*
Write the content of a frm data pointer
to a frm file
SYNOPSIS
writefrm()
name path to table-file "db/name"
frmdata frm data
len length of the frmdata
RETURN VALUES
0 ok
2 Could not write file
*/
int
writefrm
(
const
char
*
name
,
const
void
*
frmdata
,
uint
len
)
{
File
file
;
char
index_file
[
FN_REFLEN
];
int
error
;
DBUG_ENTER
(
"writefrm"
);
DBUG_PRINT
(
"enter"
,(
"name: '%s' len: %d "
,
name
,
len
));
//DBUG_DUMP("frmdata", (char*)frmdata, len);
error
=
0
;
if
((
file
=
my_create
(
fn_format
(
index_file
,
name
,
""
,
reg_ext
,
4
),
CREATE_MODE
,
O_RDWR
|
O_TRUNC
,
MYF
(
MY_WME
)))
>=
0
)
{
if
(
my_write
(
file
,(
byte
*
)
frmdata
,
len
,
MYF
(
MY_WME
|
MY_NABP
)))
error
=
2
;
}
VOID
(
my_close
(
file
,
MYF
(
0
)));
DBUG_RETURN
(
error
);
}
/* writefrm */
/*
Try to discover table from handler and
if found, write the frm file to disk.
RETURN VALUES:
0 : Table existed in handler and created
on disk if so requested
1 : Table does not exist
>1 : error
*/
int
create_table_from_handler
(
const
char
*
db
,
const
char
*
name
,
bool
create_if_found
)
{
int
error
=
0
;
const
void
*
frmblob
=
NULL
;
char
path
[
FN_REFLEN
];
uint
frmlen
=
0
;
DBUG_ENTER
(
"create_table_from_handler"
);
DBUG_PRINT
(
"enter"
,
(
"create_if_found: %d"
,
create_if_found
));
if
(
ha_discover
(
db
,
name
,
&
frmblob
,
&
frmlen
))
DBUG_RETURN
(
1
);
// Table does not exist
// Table exists in handler
if
(
create_if_found
)
{
(
void
)
strxnmov
(
path
,
FN_REFLEN
,
mysql_data_home
,
"/"
,
db
,
"/"
,
name
,
NullS
);
// Save the frm file
error
=
writefrm
(
path
,
frmblob
,
frmlen
);
}
err:
if
(
frmblob
)
my_free
((
char
*
)
frmblob
,
MYF
(
0
));
DBUG_RETURN
(
error
);
}
int
table_exists_in_handler
(
const
char
*
db
,
const
char
*
name
)
{
return
(
create_table_from_handler
(
db
,
name
,
false
)
==
0
);
}
sql/ha_ndbcluster.cc
0 → 100755
View file @
7c2c408c
This diff is collapsed.
Click to expand it.
sql/ha_ndbcluster.h
0 → 100755
View file @
7c2c408c
/* Copyright (C) 2000-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 */
/*
This file defines the NDB Cluster handler: the interface between MySQL and
NDB Cluster
*/
/* The class defining a handle to an NDB Cluster table */
#ifdef __GNUC__
#pragma interface
/* gcc class implementation */
#endif
#include <ndbapi_limits.h>
#include <ndb_types.h>
class
Ndb
;
// Forward declaration
class
NdbOperation
;
// Forward declaration
class
NdbConnection
;
// Forward declaration
class
NdbRecAttr
;
// Forward declaration
class
NdbResultSet
;
// Forward declaration
typedef
enum
ndb_index_type
{
UNDEFINED_INDEX
=
0
,
PRIMARY_KEY_INDEX
=
1
,
UNIQUE_INDEX
=
2
,
ORDERED_INDEX
=
3
}
NDB_INDEX_TYPE
;
typedef
struct
st_ndbcluster_share
{
THR_LOCK
lock
;
pthread_mutex_t
mutex
;
char
*
table_name
;
uint
table_name_length
,
use_count
;
}
NDB_SHARE
;
class
ha_ndbcluster
:
public
handler
{
public:
ha_ndbcluster
(
TABLE
*
table
);
~
ha_ndbcluster
();
int
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
);
int
close
(
void
);
int
write_row
(
byte
*
buf
);
int
update_row
(
const
byte
*
old_data
,
byte
*
new_data
);
int
delete_row
(
const
byte
*
buf
);
int
index_init
(
uint
index
);
int
index_end
();
int
index_read
(
byte
*
buf
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
);
int
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
);
int
index_next
(
byte
*
buf
);
int
index_prev
(
byte
*
buf
);
int
index_first
(
byte
*
buf
);
int
index_last
(
byte
*
buf
);
int
rnd_init
(
bool
scan
=
1
);
int
rnd_end
();
int
rnd_next
(
byte
*
buf
);
int
rnd_pos
(
byte
*
buf
,
byte
*
pos
);
void
position
(
const
byte
*
record
);
void
info
(
uint
);
int
extra
(
enum
ha_extra_function
operation
);
int
extra_opt
(
enum
ha_extra_function
operation
,
ulong
cache_size
);
int
reset
();
int
external_lock
(
THD
*
thd
,
int
lock_type
);
int
start_stmt
(
THD
*
thd
);
const
char
*
table_type
()
const
{
return
(
"ndbcluster"
);}
const
char
**
bas_ext
()
const
;
ulong
table_flags
(
void
)
const
{
return
m_table_flags
;
}
ulong
index_flags
(
uint
idx
)
const
;
uint
max_record_length
()
const
{
return
NDB_MAX_TUPLE_SIZE
;
};
uint
max_keys
()
const
{
return
MAX_KEY
;
}
uint
max_key_parts
()
const
{
return
NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY
;
};
uint
max_key_length
()
const
{
return
NDB_MAX_KEY_SIZE
;};
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
delete_table
(
const
char
*
name
);
int
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
info
);
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
);
bool
low_byte_first
()
const
{
#ifdef WORDS_BIGENDIAN
return
false
;
#else
return
true
;
#endif
}
bool
has_transactions
()
{
return
true
;}
const
char
*
index_type
(
uint
key_number
)
{
switch
(
get_index_type
(
key_number
))
{
case
ORDERED_INDEX
:
return
"BTREE"
;
case
UNIQUE_INDEX
:
case
PRIMARY_KEY_INDEX
:
default:
return
"HASH"
;
}
}
double
scan_time
();
ha_rows
records_in_range
(
int
inx
,
const
byte
*
start_key
,
uint
start_key_len
,
enum
ha_rkey_function
start_search_flag
,
const
byte
*
end_key
,
uint
end_key_len
,
enum
ha_rkey_function
end_search_flag
);
static
Ndb
*
seize_ndb
();
static
void
release_ndb
(
Ndb
*
ndb
);
private:
int
alter_table_name
(
const
char
*
from
,
const
char
*
to
);
int
drop_table
();
int
create_index
(
const
char
*
name
,
KEY
*
key_info
);
int
initialize_autoincrement
(
const
void
*
table
);
int
get_metadata
(
const
char
*
path
);
void
release_metadata
();
const
char
*
get_index_name
(
uint
idx_no
)
const
;
NDB_INDEX_TYPE
get_index_type
(
uint
idx_no
)
const
;
NDB_INDEX_TYPE
get_index_type_from_table
(
uint
index_no
)
const
;
int
pk_read
(
const
byte
*
key
,
uint
key_len
,
byte
*
buf
);
int
unique_index_read
(
const
byte
*
key
,
uint
key_len
,
byte
*
buf
);
int
ordered_index_scan
(
const
byte
*
key
,
uint
key_len
,
byte
*
buf
,
enum
ha_rkey_function
find_flag
);
int
full_table_scan
(
byte
*
buf
);
int
next_result
(
byte
*
buf
);
#if 0
int filtered_scan(const byte *key, uint key_len,
byte *buf,
enum ha_rkey_function find_flag);
#endif
void
unpack_record
(
byte
*
buf
);
void
set_dbname
(
const
char
*
pathname
);
void
set_tabname
(
const
char
*
pathname
);
void
set_tabname
(
const
char
*
pathname
,
char
*
tabname
);
bool
set_hidden_key
(
NdbOperation
*
,
uint
fieldnr
,
const
byte
*
field_ptr
);
int
set_ndb_key
(
NdbOperation
*
,
Field
*
field
,
uint
fieldnr
,
const
byte
*
field_ptr
);
int
set_ndb_value
(
NdbOperation
*
,
Field
*
field
,
uint
fieldnr
);
int
get_ndb_value
(
NdbOperation
*
,
uint
fieldnr
,
byte
*
field_ptr
);
int
set_primary_key
(
NdbOperation
*
op
,
const
byte
*
key
);
int
set_primary_key
(
NdbOperation
*
op
);
int
key_cmp
(
uint
keynr
,
const
byte
*
old_row
,
const
byte
*
new_row
);
void
print_results
();
longlong
get_auto_increment
();
int
ndb_err
(
NdbConnection
*
);
private:
int
check_ndb_connection
();
NdbConnection
*
m_active_trans
;
NdbResultSet
*
m_active_cursor
;
Ndb
*
m_ndb
;
void
*
m_table
;
char
m_dbname
[
FN_HEADLEN
];
//char m_schemaname[FN_HEADLEN];
char
m_tabname
[
FN_HEADLEN
];
ulong
m_table_flags
;
THR_LOCK_DATA
m_lock
;
NDB_SHARE
*
m_share
;
NDB_INDEX_TYPE
m_indextype
[
MAX_KEY
];
NdbRecAttr
*
m_value
[
NDB_MAX_ATTRIBUTES_IN_TABLE
];
bool
m_use_write
;
};
bool
ndbcluster_init
(
void
);
bool
ndbcluster_end
(
void
);
int
ndbcluster_commit
(
THD
*
thd
,
void
*
ndb_transaction
);
int
ndbcluster_rollback
(
THD
*
thd
,
void
*
ndb_transaction
);
void
ndbcluster_close_connection
(
THD
*
thd
);
int
ndbcluster_discover
(
const
char
*
dbname
,
const
char
*
name
,
const
void
**
frmblob
,
uint
*
frmlen
);
int
ndbcluster_drop_database
(
const
char
*
path
);
sql/handler.cc
View file @
7c2c408c
...
@@ -37,6 +37,9 @@
...
@@ -37,6 +37,9 @@
#else
#else
#define innobase_query_caching_of_table_permitted(X,Y,Z) 1
#define innobase_query_caching_of_table_permitted(X,Y,Z) 1
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
#include <myisampack.h>
#include <myisampack.h>
#include <errno.h>
#include <errno.h>
...
@@ -48,7 +51,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
...
@@ -48,7 +51,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count
,
ha_read_next_count
,
ha_read_prev_count
,
ha_read_key_count
,
ha_read_next_count
,
ha_read_prev_count
,
ha_read_first_count
,
ha_read_last_count
,
ha_read_first_count
,
ha_read_last_count
,
ha_commit_count
,
ha_rollback_count
,
ha_commit_count
,
ha_rollback_count
,
ha_read_rnd_count
,
ha_read_rnd_next_count
;
ha_read_rnd_count
,
ha_read_rnd_next_count
,
ha_discover_count
;
static
SHOW_COMP_OPTION
have_yes
=
SHOW_OPTION_YES
;
static
SHOW_COMP_OPTION
have_yes
=
SHOW_OPTION_YES
;
...
@@ -76,6 +79,10 @@ struct show_table_type_st sys_table_types[]=
...
@@ -76,6 +79,10 @@ struct show_table_type_st sys_table_types[]=
"Supports transactions and page-level locking"
,
DB_TYPE_BERKELEY_DB
},
"Supports transactions and page-level locking"
,
DB_TYPE_BERKELEY_DB
},
{
"BERKELEYDB"
,
&
have_berkeley_db
,
{
"BERKELEYDB"
,
&
have_berkeley_db
,
"Alias for BDB"
,
DB_TYPE_BERKELEY_DB
},
"Alias for BDB"
,
DB_TYPE_BERKELEY_DB
},
{
"NDBCLUSTER"
,
&
have_ndbcluster
,
"Clustered, fault tolerant memory based tables"
,
DB_TYPE_NDBCLUSTER
},
{
"NDB"
,
&
have_ndbcluster
,
"Alias for NDBCLUSTER"
,
DB_TYPE_NDBCLUSTER
},
{
NullS
,
NULL
,
NullS
,
DB_TYPE_UNKNOWN
}
{
NullS
,
NULL
,
NullS
,
DB_TYPE_UNKNOWN
}
};
};
...
@@ -171,6 +178,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
...
@@ -171,6 +178,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifdef HAVE_INNOBASE_DB
#ifdef HAVE_INNOBASE_DB
case
DB_TYPE_INNODB
:
case
DB_TYPE_INNODB
:
return
new
ha_innobase
(
table
);
return
new
ha_innobase
(
table
);
#endif
#ifdef HAVE_NDBCLUSTER_DB
case
DB_TYPE_NDBCLUSTER
:
return
new
ha_ndbcluster
(
table
);
#endif
#endif
case
DB_TYPE_HEAP
:
case
DB_TYPE_HEAP
:
return
new
ha_heap
(
table
);
return
new
ha_heap
(
table
);
...
@@ -215,6 +226,18 @@ int ha_init()
...
@@ -215,6 +226,18 @@ int ha_init()
else
else
opt_using_transactions
=
1
;
opt_using_transactions
=
1
;
}
}
#endif
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
{
if
(
ndbcluster_init
())
{
have_ndbcluster
=
SHOW_OPTION_DISABLED
;
error
=
1
;
}
else
opt_using_transactions
=
1
;
}
#endif
#endif
return
error
;
return
error
;
}
}
...
@@ -242,6 +265,10 @@ int ha_panic(enum ha_panic_function flag)
...
@@ -242,6 +265,10 @@ int ha_panic(enum ha_panic_function flag)
#ifdef HAVE_INNOBASE_DB
#ifdef HAVE_INNOBASE_DB
if
(
have_innodb
==
SHOW_OPTION_YES
)
if
(
have_innodb
==
SHOW_OPTION_YES
)
error
|=
innobase_end
();
error
|=
innobase_end
();
#endif
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
error
|=
ndbcluster_end
();
#endif
#endif
return
error
;
return
error
;
}
/* ha_panic */
}
/* ha_panic */
...
@@ -252,6 +279,10 @@ void ha_drop_database(char* path)
...
@@ -252,6 +279,10 @@ void ha_drop_database(char* path)
if
(
have_innodb
==
SHOW_OPTION_YES
)
if
(
have_innodb
==
SHOW_OPTION_YES
)
innobase_drop_database
(
path
);
innobase_drop_database
(
path
);
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
ndbcluster_drop_database
(
path
);
#endif
}
}
void
ha_close_connection
(
THD
*
thd
)
void
ha_close_connection
(
THD
*
thd
)
...
@@ -260,6 +291,10 @@ void ha_close_connection(THD* thd)
...
@@ -260,6 +291,10 @@ void ha_close_connection(THD* thd)
if
(
have_innodb
==
SHOW_OPTION_YES
)
if
(
have_innodb
==
SHOW_OPTION_YES
)
innobase_close_connection
(
thd
);
innobase_close_connection
(
thd
);
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
ndbcluster_close_connection
(
thd
);
#endif
}
}
/*
/*
...
@@ -419,6 +454,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
...
@@ -419,6 +454,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
WRITE_CACHE
,
(
my_off_t
)
0
,
0
,
1
);
WRITE_CACHE
,
(
my_off_t
)
0
,
0
,
1
);
thd
->
transaction
.
trans_log
.
end_of_file
=
max_binlog_cache_size
;
thd
->
transaction
.
trans_log
.
end_of_file
=
max_binlog_cache_size
;
}
}
#ifdef HAVE_NDBCLUSTER_DB
if
(
trans
->
ndb_tid
)
{
if
((
error
=
ndbcluster_commit
(
thd
,
trans
->
ndb_tid
)))
{
my_error
(
ER_ERROR_DURING_COMMIT
,
MYF
(
0
),
error
);
error
=
1
;
}
if
(
trans
==
&
thd
->
transaction
.
all
)
operation_done
=
transaction_commited
=
1
;
trans
->
ndb_tid
=
0
;
}
#endif
#ifdef HAVE_BERKELEY_DB
#ifdef HAVE_BERKELEY_DB
if
(
trans
->
bdb_tid
)
if
(
trans
->
bdb_tid
)
{
{
...
@@ -472,6 +520,18 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
...
@@ -472,6 +520,18 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
if
(
opt_using_transactions
)
if
(
opt_using_transactions
)
{
{
bool
operation_done
=
0
;
bool
operation_done
=
0
;
#ifdef HAVE_NDBCLUSTER_DB
if
(
trans
->
ndb_tid
)
{
if
((
error
=
ndbcluster_rollback
(
thd
,
trans
->
ndb_tid
)))
{
my_error
(
ER_ERROR_DURING_ROLLBACK
,
MYF
(
0
),
error
);
error
=
1
;
}
trans
->
ndb_tid
=
0
;
operation_done
=
1
;
}
#endif
#ifdef HAVE_BERKELEY_DB
#ifdef HAVE_BERKELEY_DB
if
(
trans
->
bdb_tid
)
if
(
trans
->
bdb_tid
)
{
{
...
@@ -1151,8 +1211,10 @@ bool handler::caching_allowed(THD* thd, char* table_key,
...
@@ -1151,8 +1211,10 @@ bool handler::caching_allowed(THD* thd, char* table_key,
** Some general functions that isn't in the handler class
** Some general functions that isn't in the handler class
****************************************************************************/
****************************************************************************/
/* Initiates table-file and calls apropriate database-creator */
/*
/* Returns 1 if something got wrong */
Initiates table-file and calls apropriate database-creator
Returns 1 if something got wrong
*/
int
ha_create_table
(
const
char
*
name
,
HA_CREATE_INFO
*
create_info
,
int
ha_create_table
(
const
char
*
name
,
HA_CREATE_INFO
*
create_info
,
bool
update_create_info
)
bool
update_create_info
)
...
@@ -1168,7 +1230,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
...
@@ -1168,7 +1230,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
{
{
update_create_info_from_table
(
create_info
,
&
table
);
update_create_info_from_table
(
create_info
,
&
table
);
if
(
table
.
file
->
table_flags
()
&
HA_DROP_BEFORE_CREATE
)
if
(
table
.
file
->
table_flags
()
&
HA_DROP_BEFORE_CREATE
)
table
.
file
->
delete_table
(
name
);
// Needed for BDB tables
table
.
file
->
delete_table
(
name
);
}
}
if
(
lower_case_table_names
==
2
&&
if
(
lower_case_table_names
==
2
&&
!
(
table
.
file
->
table_flags
()
&
HA_FILE_BASED
))
!
(
table
.
file
->
table_flags
()
&
HA_FILE_BASED
))
...
@@ -1289,6 +1351,26 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
...
@@ -1289,6 +1351,26 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
}
}
/*
Try to discover one table from handler(s)
*/
int
ha_discover
(
const
char
*
dbname
,
const
char
*
name
,
const
void
**
frmblob
,
uint
*
frmlen
)
{
int
error
=
1
;
// Table does not exist in any handler
DBUG_ENTER
(
"ha_discover"
);
DBUG_PRINT
(
"enter"
,
(
"db: %s, name: %s"
,
dbname
,
name
));
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
error
=
ndbcluster_discover
(
dbname
,
name
,
frmblob
,
frmlen
);
#endif
if
(
!
error
)
statistic_increment
(
ha_discover_count
,
&
LOCK_status
);
DBUG_RETURN
(
error
);
}
/*
/*
Read first row between two ranges.
Read first row between two ranges.
Store ranges for future calls to read_range_next
Store ranges for future calls to read_range_next
...
@@ -1425,3 +1507,5 @@ int handler::compare_key(key_range *range)
...
@@ -1425,3 +1507,5 @@ int handler::compare_key(key_range *range)
}
}
return
key_compare_result_on_equal
;
return
key_compare_result_on_equal
;
}
}
sql/handler.h
View file @
7c2c408c
...
@@ -28,7 +28,8 @@
...
@@ -28,7 +28,8 @@
#define NO_HASH
/* Not yet implemented */
#define NO_HASH
/* Not yet implemented */
#endif
#endif
#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB)
#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) || \
defined(HAVE_NDBCLUSTER_DB)
#define USING_TRANSACTIONS
#define USING_TRANSACTIONS
#endif
#endif
...
@@ -80,7 +81,6 @@
...
@@ -80,7 +81,6 @@
#define HA_FILE_BASED (1 << 26)
#define HA_FILE_BASED (1 << 26)
/* bits in index_flags(index_number) for what you can do with index */
/* bits in index_flags(index_number) for what you can do with index */
#define HA_WRONG_ASCII_ORDER 1
/* Can't use sorting through key */
#define HA_WRONG_ASCII_ORDER 1
/* Can't use sorting through key */
#define HA_READ_NEXT 2
/* Read next record with same key */
#define HA_READ_NEXT 2
/* Read next record with same key */
...
@@ -141,12 +141,17 @@
...
@@ -141,12 +141,17 @@
#define HA_CACHE_TBL_ASKTRANSACT 1
#define HA_CACHE_TBL_ASKTRANSACT 1
#define HA_CACHE_TBL_TRANSACT 2
#define HA_CACHE_TBL_TRANSACT 2
enum
db_type
{
DB_TYPE_UNKNOWN
=
0
,
DB_TYPE_DIAB_ISAM
=
1
,
enum
db_type
DB_TYPE_HASH
,
DB_TYPE_MISAM
,
DB_TYPE_PISAM
,
{
DB_TYPE_RMS_ISAM
,
DB_TYPE_HEAP
,
DB_TYPE_ISAM
,
DB_TYPE_UNKNOWN
=
0
,
DB_TYPE_DIAB_ISAM
=
1
,
DB_TYPE_MRG_ISAM
,
DB_TYPE_MYISAM
,
DB_TYPE_MRG_MYISAM
,
DB_TYPE_HASH
,
DB_TYPE_MISAM
,
DB_TYPE_PISAM
,
DB_TYPE_BERKELEY_DB
,
DB_TYPE_INNODB
,
DB_TYPE_GEMINI
,
DB_TYPE_RMS_ISAM
,
DB_TYPE_HEAP
,
DB_TYPE_ISAM
,
DB_TYPE_DEFAULT
};
DB_TYPE_MRG_ISAM
,
DB_TYPE_MYISAM
,
DB_TYPE_MRG_MYISAM
,
DB_TYPE_BERKELEY_DB
,
DB_TYPE_INNODB
,
DB_TYPE_GEMINI
,
DB_TYPE_NDBCLUSTER
,
DB_TYPE_DEFAULT
// Must be last
};
struct
show_table_type_st
{
struct
show_table_type_st
{
const
char
*
type
;
const
char
*
type
;
...
@@ -176,6 +181,7 @@ typedef struct st_thd_trans {
...
@@ -176,6 +181,7 @@ typedef struct st_thd_trans {
void
*
bdb_tid
;
void
*
bdb_tid
;
void
*
innobase_tid
;
void
*
innobase_tid
;
bool
innodb_active_trans
;
bool
innodb_active_trans
;
void
*
ndb_tid
;
}
THD_TRANS
;
}
THD_TRANS
;
enum
enum_tx_isolation
{
ISO_READ_UNCOMMITTED
,
ISO_READ_COMMITTED
,
enum
enum_tx_isolation
{
ISO_READ_UNCOMMITTED
,
ISO_READ_COMMITTED
,
...
@@ -479,3 +485,5 @@ bool ha_flush_logs(void);
...
@@ -479,3 +485,5 @@ bool ha_flush_logs(void);
int
ha_recovery_logging
(
THD
*
thd
,
bool
on
);
int
ha_recovery_logging
(
THD
*
thd
,
bool
on
);
int
ha_change_key_cache
(
KEY_CACHE
*
old_key_cache
,
int
ha_change_key_cache
(
KEY_CACHE
*
old_key_cache
,
KEY_CACHE
*
new_key_cache
);
KEY_CACHE
*
new_key_cache
);
int
ha_discover
(
const
char
*
dbname
,
const
char
*
name
,
const
void
**
frmblob
,
uint
*
frmlen
);
sql/lex.h
View file @
7c2c408c
...
@@ -48,7 +48,7 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
...
@@ -48,7 +48,7 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
*/
*/
static
SYMBOL
symbols
[]
=
{
static
SYMBOL
symbols
[]
=
{
{
"&&"
,
SYM
(
AND
)},
{
"&&"
,
SYM
(
AND
_SYM
)},
{
"<"
,
SYM
(
LT
)},
{
"<"
,
SYM
(
LT
)},
{
"<="
,
SYM
(
LE
)},
{
"<="
,
SYM
(
LE
)},
{
"<>"
,
SYM
(
NE
)},
{
"<>"
,
SYM
(
NE
)},
...
@@ -67,7 +67,7 @@ static SYMBOL symbols[] = {
...
@@ -67,7 +67,7 @@ static SYMBOL symbols[] = {
{
"ALL"
,
SYM
(
ALL
)},
{
"ALL"
,
SYM
(
ALL
)},
{
"ALTER"
,
SYM
(
ALTER
)},
{
"ALTER"
,
SYM
(
ALTER
)},
{
"ANALYZE"
,
SYM
(
ANALYZE_SYM
)},
{
"ANALYZE"
,
SYM
(
ANALYZE_SYM
)},
{
"AND"
,
SYM
(
AND
)},
{
"AND"
,
SYM
(
AND
_SYM
)},
{
"ANY"
,
SYM
(
ANY_SYM
)},
{
"ANY"
,
SYM
(
ANY_SYM
)},
{
"AS"
,
SYM
(
AS
)},
{
"AS"
,
SYM
(
AS
)},
{
"ASC"
,
SYM
(
ASC
)},
{
"ASC"
,
SYM
(
ASC
)},
...
@@ -295,6 +295,8 @@ static SYMBOL symbols[] = {
...
@@ -295,6 +295,8 @@ static SYMBOL symbols[] = {
{
"NAMES"
,
SYM
(
NAMES_SYM
)},
{
"NAMES"
,
SYM
(
NAMES_SYM
)},
{
"NATIONAL"
,
SYM
(
NATIONAL_SYM
)},
{
"NATIONAL"
,
SYM
(
NATIONAL_SYM
)},
{
"NATURAL"
,
SYM
(
NATURAL
)},
{
"NATURAL"
,
SYM
(
NATURAL
)},
{
"NDB"
,
SYM
(
NDBCLUSTER_SYM
)},
{
"NDBCLUSTER"
,
SYM
(
NDBCLUSTER_SYM
)},
{
"NCHAR"
,
SYM
(
NCHAR_SYM
)},
{
"NCHAR"
,
SYM
(
NCHAR_SYM
)},
{
"NEW"
,
SYM
(
NEW_SYM
)},
{
"NEW"
,
SYM
(
NEW_SYM
)},
{
"NEXT"
,
SYM
(
NEXT_SYM
)},
{
"NEXT"
,
SYM
(
NEXT_SYM
)},
...
@@ -312,7 +314,7 @@ static SYMBOL symbols[] = {
...
@@ -312,7 +314,7 @@ static SYMBOL symbols[] = {
{
"OPTIMIZE"
,
SYM
(
OPTIMIZE
)},
{
"OPTIMIZE"
,
SYM
(
OPTIMIZE
)},
{
"OPTION"
,
SYM
(
OPTION
)},
{
"OPTION"
,
SYM
(
OPTION
)},
{
"OPTIONALLY"
,
SYM
(
OPTIONALLY
)},
{
"OPTIONALLY"
,
SYM
(
OPTIONALLY
)},
{
"OR"
,
SYM
(
OR
)},
{
"OR"
,
SYM
(
OR
_SYM
)},
{
"ORDER"
,
SYM
(
ORDER_SYM
)},
{
"ORDER"
,
SYM
(
ORDER_SYM
)},
{
"OUTER"
,
SYM
(
OUTER
)},
{
"OUTER"
,
SYM
(
OUTER
)},
{
"OUTFILE"
,
SYM
(
OUTFILE
)},
{
"OUTFILE"
,
SYM
(
OUTFILE
)},
...
...
sql/mysql_priv.h
View file @
7c2c408c
...
@@ -837,7 +837,7 @@ extern ulong server_id, concurrency;
...
@@ -837,7 +837,7 @@ extern ulong server_id, concurrency;
extern
ulong
ha_read_count
,
ha_write_count
,
ha_delete_count
,
ha_update_count
;
extern
ulong
ha_read_count
,
ha_write_count
,
ha_delete_count
,
ha_update_count
;
extern
ulong
ha_read_key_count
,
ha_read_next_count
,
ha_read_prev_count
;
extern
ulong
ha_read_key_count
,
ha_read_next_count
,
ha_read_prev_count
;
extern
ulong
ha_read_first_count
,
ha_read_last_count
;
extern
ulong
ha_read_first_count
,
ha_read_last_count
;
extern
ulong
ha_read_rnd_count
,
ha_read_rnd_next_count
;
extern
ulong
ha_read_rnd_count
,
ha_read_rnd_next_count
,
ha_discover_count
;
extern
ulong
ha_commit_count
,
ha_rollback_count
,
table_cache_size
;
extern
ulong
ha_commit_count
,
ha_rollback_count
,
table_cache_size
;
extern
ulong
max_connections
,
max_connect_errors
,
connect_timeout
;
extern
ulong
max_connections
,
max_connect_errors
,
connect_timeout
;
extern
ulong
slave_net_timeout
;
extern
ulong
slave_net_timeout
;
...
@@ -891,6 +891,7 @@ extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
...
@@ -891,6 +891,7 @@ extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
extern
SHOW_COMP_OPTION
have_isam
;
extern
SHOW_COMP_OPTION
have_isam
;
extern
SHOW_COMP_OPTION
have_innodb
;
extern
SHOW_COMP_OPTION
have_innodb
;
extern
SHOW_COMP_OPTION
have_berkeley_db
;
extern
SHOW_COMP_OPTION
have_berkeley_db
;
extern
SHOW_COMP_OPTION
have_ndbcluster
;
extern
struct
system_variables
global_system_variables
;
extern
struct
system_variables
global_system_variables
;
extern
struct
system_variables
max_system_variables
;
extern
struct
system_variables
max_system_variables
;
extern
struct
rand_struct
sql_rand
;
extern
struct
rand_struct
sql_rand
;
...
@@ -960,6 +961,10 @@ int format_number(uint inputflag,uint max_length,my_string pos,uint length,
...
@@ -960,6 +961,10 @@ int format_number(uint inputflag,uint max_length,my_string pos,uint length,
my_string
*
errpos
);
my_string
*
errpos
);
int
openfrm
(
const
char
*
name
,
const
char
*
alias
,
uint
filestat
,
uint
prgflag
,
int
openfrm
(
const
char
*
name
,
const
char
*
alias
,
uint
filestat
,
uint
prgflag
,
uint
ha_open_flags
,
TABLE
*
outparam
);
uint
ha_open_flags
,
TABLE
*
outparam
);
int
readfrm
(
const
char
*
name
,
const
void
**
data
,
uint
*
length
);
int
writefrm
(
const
char
*
name
,
const
void
*
data
,
uint
len
);
int
create_table_from_handler
(
const
char
*
db
,
const
char
*
name
,
bool
create_if_found
);
int
closefrm
(
TABLE
*
table
);
int
closefrm
(
TABLE
*
table
);
db_type
get_table_type
(
const
char
*
name
);
db_type
get_table_type
(
const
char
*
name
);
int
read_string
(
File
file
,
gptr
*
to
,
uint
length
);
int
read_string
(
File
file
,
gptr
*
to
,
uint
length
);
...
...
sql/mysqld.cc
View file @
7c2c408c
...
@@ -32,6 +32,9 @@
...
@@ -32,6 +32,9 @@
#ifdef HAVE_ISAM
#ifdef HAVE_ISAM
#include "ha_isam.h"
#include "ha_isam.h"
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
#include <nisam.h>
#include <nisam.h>
#include <thr_alarm.h>
#include <thr_alarm.h>
#include <ft_global.h>
#include <ft_global.h>
...
@@ -261,7 +264,7 @@ my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol;
...
@@ -261,7 +264,7 @@ my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol;
my_bool
opt_safe_user_create
=
0
,
opt_no_mix_types
=
0
;
my_bool
opt_safe_user_create
=
0
,
opt_no_mix_types
=
0
;
my_bool
opt_show_slave_auth_info
,
opt_sql_bin_update
=
0
;
my_bool
opt_show_slave_auth_info
,
opt_sql_bin_update
=
0
;
my_bool
opt_log_slave_updates
=
0
;
my_bool
opt_log_slave_updates
=
0
;
my_bool
opt_console
=
0
,
opt_bdb
,
opt_innodb
,
opt_isam
;
my_bool
opt_console
=
0
,
opt_bdb
,
opt_innodb
,
opt_isam
,
opt_ndbcluster
;
my_bool
opt_readonly
,
use_temp_pool
,
relay_log_purge
;
my_bool
opt_readonly
,
use_temp_pool
,
relay_log_purge
;
my_bool
opt_sync_bdb_logs
,
opt_sync_frm
;
my_bool
opt_sync_bdb_logs
,
opt_sync_frm
;
my_bool
opt_secure_auth
=
0
;
my_bool
opt_secure_auth
=
0
;
...
@@ -370,7 +373,7 @@ KEY_CACHE *sql_key_cache;
...
@@ -370,7 +373,7 @@ KEY_CACHE *sql_key_cache;
CHARSET_INFO
*
system_charset_info
,
*
files_charset_info
;
CHARSET_INFO
*
system_charset_info
,
*
files_charset_info
;
CHARSET_INFO
*
national_charset_info
,
*
table_alias_charset
;
CHARSET_INFO
*
national_charset_info
,
*
table_alias_charset
;
SHOW_COMP_OPTION
have_berkeley_db
,
have_innodb
,
have_isam
;
SHOW_COMP_OPTION
have_berkeley_db
,
have_innodb
,
have_isam
,
have_ndbcluster
;
SHOW_COMP_OPTION
have_raid
,
have_openssl
,
have_symlink
,
have_query_cache
;
SHOW_COMP_OPTION
have_raid
,
have_openssl
,
have_symlink
,
have_query_cache
;
SHOW_COMP_OPTION
have_crypt
,
have_compress
;
SHOW_COMP_OPTION
have_crypt
,
have_compress
;
...
@@ -3625,7 +3628,7 @@ enum options_mysqld
...
@@ -3625,7 +3628,7 @@ enum options_mysqld
OPT_INNODB_FAST_SHUTDOWN
,
OPT_INNODB_FAST_SHUTDOWN
,
OPT_INNODB_FILE_PER_TABLE
,
OPT_INNODB_FILE_PER_TABLE
,
OPT_SAFE_SHOW_DB
,
OPT_SAFE_SHOW_DB
,
OPT_INNODB
,
OPT_ISAM
,
OPT_SKIP_SAFEMALLOC
,
OPT_INNODB
,
OPT_ISAM
,
OPT_
NDBCLUSTER
,
OPT_
SKIP_SAFEMALLOC
,
OPT_TEMP_POOL
,
OPT_TX_ISOLATION
,
OPT_TEMP_POOL
,
OPT_TX_ISOLATION
,
OPT_SKIP_STACK_TRACE
,
OPT_SKIP_SYMLINKS
,
OPT_SKIP_STACK_TRACE
,
OPT_SKIP_SYMLINKS
,
OPT_MAX_BINLOG_DUMP_EVENTS
,
OPT_SPORADIC_BINLOG_DUMP_FAIL
,
OPT_MAX_BINLOG_DUMP_EVENTS
,
OPT_SPORADIC_BINLOG_DUMP_FAIL
,
...
@@ -4158,6 +4161,13 @@ Disable with --skip-innodb (will save memory).",
...
@@ -4158,6 +4161,13 @@ Disable with --skip-innodb (will save memory).",
Disable with --skip-isam."
,
Disable with --skip-isam."
,
(
gptr
*
)
&
opt_isam
,
(
gptr
*
)
&
opt_isam
,
0
,
GET_BOOL
,
NO_ARG
,
1
,
0
,
0
,
(
gptr
*
)
&
opt_isam
,
(
gptr
*
)
&
opt_isam
,
0
,
GET_BOOL
,
NO_ARG
,
1
,
0
,
0
,
0
,
0
,
0
},
0
,
0
,
0
},
#ifdef HAVE_NDBCLUSTER_DB
{
"ndbcluster"
,
OPT_NDBCLUSTER
,
"Enable NDB Cluster (if this version of MySQL
supports it). \
Disable with --skip-ndbcluster (will save memory)."
,
(
gptr
*
)
&
opt_ndbcluster
,
(
gptr
*
)
&
opt_ndbcluster
,
0
,
GET_BOOL
,
NO_ARG
,
1
,
0
,
0
,
0
,
0
,
0
},
#endif
{
"skip-locking"
,
OPT_SKIP_LOCK
,
{
"skip-locking"
,
OPT_SKIP_LOCK
,
"Deprecated option, use --skip-external-locking instead."
,
"Deprecated option, use --skip-external-locking instead."
,
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
...
@@ -4828,6 +4838,7 @@ struct show_var_st status_vars[]= {
...
@@ -4828,6 +4838,7 @@ struct show_var_st status_vars[]= {
{
"Handler_rollback"
,
(
char
*
)
&
ha_rollback_count
,
SHOW_LONG
},
{
"Handler_rollback"
,
(
char
*
)
&
ha_rollback_count
,
SHOW_LONG
},
{
"Handler_update"
,
(
char
*
)
&
ha_update_count
,
SHOW_LONG
},
{
"Handler_update"
,
(
char
*
)
&
ha_update_count
,
SHOW_LONG
},
{
"Handler_write"
,
(
char
*
)
&
ha_write_count
,
SHOW_LONG
},
{
"Handler_write"
,
(
char
*
)
&
ha_write_count
,
SHOW_LONG
},
{
"Handler_discover"
,
(
char
*
)
&
ha_discover_count
,
SHOW_LONG
},
{
"Key_blocks_not_flushed"
,
(
char
*
)
&
dflt_key_cache_var
.
global_blocks_changed
,
{
"Key_blocks_not_flushed"
,
(
char
*
)
&
dflt_key_cache_var
.
global_blocks_changed
,
SHOW_KEY_CACHE_LONG
},
SHOW_KEY_CACHE_LONG
},
{
"Key_blocks_used"
,
(
char
*
)
&
dflt_key_cache_var
.
global_blocks_used
,
{
"Key_blocks_used"
,
(
char
*
)
&
dflt_key_cache_var
.
global_blocks_used
,
...
@@ -5121,6 +5132,11 @@ static void mysql_init_variables(void)
...
@@ -5121,6 +5132,11 @@ static void mysql_init_variables(void)
#else
#else
have_isam
=
SHOW_OPTION_NO
;
have_isam
=
SHOW_OPTION_NO
;
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
have_ndbcluster
=
SHOW_OPTION_YES
;
#else
have_ndbcluster
=
SHOW_OPTION_NO
;
#endif
#ifdef USE_RAID
#ifdef USE_RAID
have_raid
=
SHOW_OPTION_YES
;
have_raid
=
SHOW_OPTION_YES
;
#else
#else
...
@@ -5589,6 +5605,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
...
@@ -5589,6 +5605,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_isam
=
SHOW_OPTION_YES
;
have_isam
=
SHOW_OPTION_YES
;
else
else
have_isam
=
SHOW_OPTION_DISABLED
;
have_isam
=
SHOW_OPTION_DISABLED
;
#endif
break
;
case
OPT_NDBCLUSTER
:
#ifdef HAVE_NDBCLUSTER_DB
if
(
opt_ndbcluster
)
have_ndbcluster
=
SHOW_OPTION_YES
;
else
have_ndbcluster
=
SHOW_OPTION_DISABLED
;
#endif
#endif
break
;
break
;
case
OPT_INNODB
:
case
OPT_INNODB
:
...
...
sql/set_var.cc
View file @
7c2c408c
...
@@ -59,6 +59,9 @@
...
@@ -59,6 +59,9 @@
#ifdef HAVE_INNOBASE_DB
#ifdef HAVE_INNOBASE_DB
#include "ha_innodb.h"
#include "ha_innodb.h"
#endif
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
static
HASH
system_variable_hash
;
static
HASH
system_variable_hash
;
const
char
*
bool_type_names
[]
=
{
"OFF"
,
"ON"
,
NullS
};
const
char
*
bool_type_names
[]
=
{
"OFF"
,
"ON"
,
NullS
};
...
@@ -638,6 +641,7 @@ struct show_var_st init_vars[]= {
...
@@ -638,6 +641,7 @@ struct show_var_st init_vars[]= {
{
"have_crypt"
,
(
char
*
)
&
have_crypt
,
SHOW_HAVE
},
{
"have_crypt"
,
(
char
*
)
&
have_crypt
,
SHOW_HAVE
},
{
"have_innodb"
,
(
char
*
)
&
have_innodb
,
SHOW_HAVE
},
{
"have_innodb"
,
(
char
*
)
&
have_innodb
,
SHOW_HAVE
},
{
"have_isam"
,
(
char
*
)
&
have_isam
,
SHOW_HAVE
},
{
"have_isam"
,
(
char
*
)
&
have_isam
,
SHOW_HAVE
},
{
"have_ndbcluster"
,
(
char
*
)
&
have_ndbcluster
,
SHOW_HAVE
},
{
"have_openssl"
,
(
char
*
)
&
have_openssl
,
SHOW_HAVE
},
{
"have_openssl"
,
(
char
*
)
&
have_openssl
,
SHOW_HAVE
},
{
"have_query_cache"
,
(
char
*
)
&
have_query_cache
,
SHOW_HAVE
},
{
"have_query_cache"
,
(
char
*
)
&
have_query_cache
,
SHOW_HAVE
},
{
"have_raid"
,
(
char
*
)
&
have_raid
,
SHOW_HAVE
},
{
"have_raid"
,
(
char
*
)
&
have_raid
,
SHOW_HAVE
},
...
...
sql/sql_base.cc
View file @
7c2c408c
...
@@ -1317,18 +1317,34 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
...
@@ -1317,18 +1317,34 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
{
{
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
int
error
;
int
error
;
uint
discover_retry_count
=
0
;
DBUG_ENTER
(
"open_unireg_entry"
);
DBUG_ENTER
(
"open_unireg_entry"
);
strxmov
(
path
,
mysql_data_home
,
"/"
,
db
,
"/"
,
name
,
NullS
);
strxmov
(
path
,
mysql_data_home
,
"/"
,
db
,
"/"
,
name
,
NullS
);
if
(
openfrm
(
path
,
alias
,
while
(
openfrm
(
path
,
alias
,
(
uint
)
(
HA_OPEN_KEYFILE
|
HA_OPEN_RNDFILE
|
HA_GET_INDEX
|
(
uint
)
(
HA_OPEN_KEYFILE
|
HA_OPEN_RNDFILE
|
HA_GET_INDEX
|
HA_TRY_READ_ONLY
),
HA_TRY_READ_ONLY
),
READ_KEYINFO
|
COMPUTE_TYPES
|
EXTRA_RECORD
,
READ_KEYINFO
|
COMPUTE_TYPES
|
EXTRA_RECORD
,
thd
->
open_options
,
entry
))
thd
->
open_options
,
entry
))
{
{
if
(
!
entry
->
crashed
)
if
(
!
entry
->
crashed
)
goto
err
;
// Can't repair the table
{
/*
Frm file could not be found on disk
Since it does not exist, no one can be using it
LOCK_open has been locked to protect from someone else
trying to discover the table at the same time.
*/
if
(
discover_retry_count
++
!=
0
)
goto
err
;
if
(
create_table_from_handler
(
db
,
name
,
true
)
!=
0
)
goto
err
;
thd
->
clear_error
();
// Clear error message
continue
;
}
// Code below is for repairing a crashed file
TABLE_LIST
table_list
;
TABLE_LIST
table_list
;
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
// just for safe
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
// just for safe
table_list
.
db
=
(
char
*
)
db
;
table_list
.
db
=
(
char
*
)
db
;
...
@@ -1374,6 +1390,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
...
@@ -1374,6 +1390,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
if
(
error
)
if
(
error
)
goto
err
;
goto
err
;
break
;
}
}
/*
/*
If we are here, there was no fatal error (but error may be still
If we are here, there was no fatal error (but error may be still
...
...
sql/sql_class.h
View file @
7c2c408c
...
@@ -688,7 +688,10 @@ public:
...
@@ -688,7 +688,10 @@ public:
THD_TRANS
all
;
// Trans since BEGIN WORK
THD_TRANS
all
;
// Trans since BEGIN WORK
THD_TRANS
stmt
;
// Trans for current statement
THD_TRANS
stmt
;
// Trans for current statement
uint
bdb_lock_count
;
uint
bdb_lock_count
;
uint
ndb_lock_count
;
#ifdef HAVE_NDBCLUSTER_DB
void
*
ndb
;
#endif
/*
/*
Tables changed in transaction (that must be invalidated in query cache).
Tables changed in transaction (that must be invalidated in query cache).
List contain only transactional tables, that not invalidated in query
List contain only transactional tables, that not invalidated in query
...
@@ -878,7 +881,8 @@ public:
...
@@ -878,7 +881,8 @@ public:
{
{
#ifdef USING_TRANSACTIONS
#ifdef USING_TRANSACTIONS
return
(
transaction
.
all
.
bdb_tid
!=
0
||
return
(
transaction
.
all
.
bdb_tid
!=
0
||
transaction
.
all
.
innodb_active_trans
!=
0
);
transaction
.
all
.
innodb_active_trans
!=
0
||
transaction
.
all
.
ndb_tid
!=
0
);
#else
#else
return
0
;
return
0
;
#endif
#endif
...
...
sql/sql_table.cc
View file @
7c2c408c
...
@@ -1148,6 +1148,35 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1148,6 +1148,35 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
}
}
/*
Check that table with given name does not already
exist in any storage engine. In such a case it should
be discovered and the error ER_TABLE_EXISTS_ERROR be returned
unless user specified CREATE TABLE IF EXISTS
The LOCK_open mutex has been locked to make sure no
one else is attempting to discover the table. Since
it's not on disk as a frm file, no one could be using it!
*/
if
(
!
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
))
{
bool
create_if_not_exists
=
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
;
if
(
!
create_table_from_handler
(
db
,
table_name
,
create_if_not_exists
))
{
DBUG_PRINT
(
"info"
,
(
"Table already existed in handler"
));
if
(
create_if_not_exists
)
{
create_info
->
table_existed
=
1
;
// Mark that table existed
error
=
0
;
}
else
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
table_name
);
goto
end
;
}
}
thd
->
proc_info
=
"creating table"
;
thd
->
proc_info
=
"creating table"
;
create_info
->
table_existed
=
0
;
// Mark that table is created
create_info
->
table_existed
=
0
;
// Mark that table is created
...
...
sql/sql_yacc.yy
View file @
7c2c408c
...
@@ -181,7 +181,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -181,7 +181,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ACTION
%token ACTION
%token AGGREGATE_SYM
%token AGGREGATE_SYM
%token ALL
%token ALL
%token AND
%token AND
_SYM
%token AS
%token AS
%token ASC
%token ASC
%token AUTO_INC
%token AUTO_INC
...
@@ -305,6 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -305,6 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NAMES_SYM
%token NAMES_SYM
%token NATIONAL_SYM
%token NATIONAL_SYM
%token NATURAL
%token NATURAL
%token NDBCLUSTER_SYM
%token NEW_SYM
%token NEW_SYM
%token NCHAR_SYM
%token NCHAR_SYM
%token NCHAR_STRING
%token NCHAR_STRING
...
@@ -318,7 +319,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -318,7 +319,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token OPEN_SYM
%token OPEN_SYM
%token OPTION
%token OPTION
%token OPTIONALLY
%token OPTIONALLY
%token OR
%token OR
_SYM
%token OR_OR_CONCAT
%token OR_OR_CONCAT
%token ORDER_SYM
%token ORDER_SYM
%token OUTER
%token OUTER
...
@@ -574,8 +575,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -574,8 +575,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token BEFORE_SYM
%token BEFORE_SYM
%left SET_VAR
%left SET_VAR
%left OR_OR_CONCAT OR XOR
%left OR_OR_CONCAT OR
_SYM
XOR
%left AND
%left AND
_SYM
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
%left '|'
%left '|'
...
@@ -727,7 +728,7 @@ END_OF_INPUT
...
@@ -727,7 +728,7 @@ END_OF_INPUT
%type <NONE>
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
'-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND
OR
OR_OR_CONCAT BETWEEN_SYM CASE_SYM
',' '!' '{' '}' '&' '|' AND
_SYM OR_SYM
OR_OR_CONCAT BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM
%%
%%
...
@@ -2421,14 +2422,14 @@ expr_expr:
...
@@ -2421,14 +2422,14 @@ expr_expr:
{
{
$$= new Item_func_not(new Item_in_subselect($1, $4));
$$= new Item_func_not(new Item_in_subselect($1, $4));
}
}
| expr BETWEEN_SYM no_and_expr AND expr
| expr BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_between($1,$3,$5); }
{ $$= new Item_func_between($1,$3,$5); }
| expr NOT BETWEEN_SYM no_and_expr AND expr
| expr NOT BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| expr OR
expr
{ $$= new Item_cond_or($1,$3); }
| expr OR
_SYM expr
{ $$= new Item_cond_or($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND
expr
{ $$= new Item_cond_and($1,$3); }
| expr AND
_SYM expr
{ $$= new Item_cond_and($1,$3); }
| expr SOUNDS_SYM LIKE expr
| expr SOUNDS_SYM LIKE expr
{
{
$$= new Item_func_eq(new Item_func_soundex($1),
$$= new Item_func_eq(new Item_func_soundex($1),
...
@@ -2469,14 +2470,14 @@ expr_expr:
...
@@ -2469,14 +2470,14 @@ expr_expr:
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
no_in_expr:
no_in_expr:
no_in_expr BETWEEN_SYM no_and_expr AND expr
no_in_expr BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_between($1,$3,$5); }
{ $$= new Item_func_between($1,$3,$5); }
| no_in_expr NOT BETWEEN_SYM no_and_expr AND expr
| no_in_expr NOT BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_in_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_in_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_in_expr OR
expr
{ $$= new Item_cond_or($1,$3); }
| no_in_expr OR
_SYM expr
{ $$= new Item_cond_or($1,$3); }
| no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND
expr
{ $$= new Item_cond_and($1,$3); }
| no_in_expr AND
_SYM expr
{ $$= new Item_cond_and($1,$3); }
| no_in_expr SOUNDS_SYM LIKE expr
| no_in_expr SOUNDS_SYM LIKE expr
{
{
$$= new Item_func_eq(new Item_func_soundex($1),
$$= new Item_func_eq(new Item_func_soundex($1),
...
@@ -2527,12 +2528,12 @@ no_and_expr:
...
@@ -2527,12 +2528,12 @@ no_and_expr:
{
{
$$= new Item_func_not(new Item_in_subselect($1, $4));
$$= new Item_func_not(new Item_in_subselect($1, $4));
}
}
| no_and_expr BETWEEN_SYM no_and_expr AND expr
| no_and_expr BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_between($1,$3,$5); }
{ $$= new Item_func_between($1,$3,$5); }
| no_and_expr NOT BETWEEN_SYM no_and_expr AND expr
| no_and_expr NOT BETWEEN_SYM no_and_expr AND
_SYM
expr
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); }
| no_and_expr OR
expr
{ $$= new Item_cond_or($1,$3); }
| no_and_expr OR
_SYM expr
{ $$= new Item_cond_or($1,$3); }
| no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_and_expr SOUNDS_SYM LIKE expr
| no_and_expr SOUNDS_SYM LIKE expr
{
{
...
@@ -4147,8 +4148,8 @@ show_param:
...
@@ -4147,8 +4148,8 @@ show_param:
YYABORT;
YYABORT;
}
}
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
TEXT_STRING_sys AND MASTER_LOG_POS_SYM EQ ulonglong_num
TEXT_STRING_sys AND
_SYM
MASTER_LOG_POS_SYM EQ ulonglong_num
AND MASTER_SERVER_ID_SYM EQ
AND
_SYM
MASTER_SERVER_ID_SYM EQ
ULONG_NUM
ULONG_NUM
{
{
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
...
@@ -4983,6 +4984,7 @@ keyword:
...
@@ -4983,6 +4984,7 @@ keyword:
| NAMES_SYM {}
| NAMES_SYM {}
| NATIONAL_SYM {}
| NATIONAL_SYM {}
| NCHAR_SYM {}
| NCHAR_SYM {}
| NDBCLUSTER_SYM {}
| NEXT_SYM {}
| NEXT_SYM {}
| NEW_SYM {}
| NEW_SYM {}
| NO_SYM {}
| NO_SYM {}
...
@@ -5434,7 +5436,7 @@ grant_privilege:
...
@@ -5434,7 +5436,7 @@ grant_privilege:
opt_and:
opt_and:
/* empty */ {}
/* empty */ {}
| AND
{}
| AND
_SYM
{}
;
;
require_list:
require_list:
...
...
sql/table.cc
View file @
7c2c408c
...
@@ -944,7 +944,8 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype)
...
@@ -944,7 +944,8 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype)
break
;
break
;
case
2
:
case
2
:
{
{
datext
=
form
->
file
?
*
form
->
file
->
bas_ext
()
:
""
;
datext
=
form
->
file
?
*
form
->
file
->
bas_ext
()
:
""
;
datext
=
datext
==
NullS
?
""
:
datext
;
err_no
=
(
my_errno
==
ENOENT
)
?
ER_FILE_NOT_FOUND
:
(
my_errno
==
EAGAIN
)
?
err_no
=
(
my_errno
==
ENOENT
)
?
ER_FILE_NOT_FOUND
:
(
my_errno
==
EAGAIN
)
?
ER_FILE_USED
:
ER_CANT_OPEN_FILE
;
ER_FILE_USED
:
ER_CANT_OPEN_FILE
;
my_error
(
err_no
,
errortype
,
my_error
(
err_no
,
errortype
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment