Commit 88478c28 authored by magnus@neptunus.(none)'s avatar magnus@neptunus.(none)

Merge conflicts with EXAMPLE handler

parents 692e9dd6 50ff8ea3
......@@ -287,6 +287,9 @@ enum ha_base_keytype {
#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_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 */
......
......@@ -16,12 +16,11 @@
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ \
@bdb_includes@ @innodb_includes@ \
@bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \
-I$(top_srcdir)/include -I$(top_srcdir)/regex \
-I$(srcdir) $(openssl_includes)
WRAPLIBS= @WRAPLIBS@
......@@ -42,6 +41,7 @@ LDADD = @isam_libs@ \
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
@bdb_libs@ @innodb_libs@ @pstack_libs@ \
@innodb_system_libs@ \
@ndbcluster_libs@ @ndbcluster_system_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.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 \
field.h handler.h \
ha_isammrg.h ha_isam.h ha_myisammrg.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\
lex.h lex_symbol.h sql_acl.h sql_crypt.h \
log_event.h sql_repl.h slave.h \
......@@ -76,11 +76,11 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
procedure.cc item_uniq.cc sql_test.cc \
log.cc log_event.cc init.cc derror.cc sql_acl.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 \
ha_heap.cc ha_myisam.cc ha_myisammrg.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_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
......
/* 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);
}
......@@ -461,7 +461,7 @@ int main(int argc,char **argv)
hash_map= sql_functions_map;\n\
register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\
\n\
for(;;){\n\
for (;;){\n\
register uchar first_char= (uchar)cur_struct;\n\
\n\
if (first_char == 0)\n\
......@@ -492,7 +492,7 @@ int main(int argc,char **argv)
hash_map= symbols_map;\n\
register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\
\n\
for(;;){\n\
for (;;){\n\
register uchar first_char= (uchar)cur_struct;\n\
\n\
if (first_char==0){\n\
......
This diff is collapsed.
/* 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);
......@@ -40,6 +40,9 @@
#else
#define innobase_query_caching_of_table_permitted(X,Y,Z) 1
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
#include <myisampack.h>
#include <errno.h>
......@@ -51,7 +54,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_first_count, ha_read_last_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;
......@@ -79,6 +82,10 @@ struct show_table_type_st sys_table_types[]=
"Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB},
{"BERKELEYDB",&have_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},
{"EXAMPLE",&have_example_db,
"Example storage engine", DB_TYPE_EXAMPLE_DB},
{NullS, NULL, NullS, DB_TYPE_UNKNOWN}
......@@ -180,6 +187,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifdef HAVE_EXAMPLE_DB
case DB_TYPE_EXAMPLE_DB:
return new ha_example(table);
#endif
#ifdef HAVE_NDBCLUSTER_DB
case DB_TYPE_NDBCLUSTER:
return new ha_ndbcluster(table);
#endif
case DB_TYPE_HEAP:
return new ha_heap(table);
......@@ -224,6 +235,18 @@ int ha_init()
else
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
return error;
}
......@@ -251,6 +274,10 @@ int ha_panic(enum ha_panic_function flag)
#ifdef HAVE_INNOBASE_DB
if (have_innodb == SHOW_OPTION_YES)
error|=innobase_end();
#endif
#ifdef HAVE_NDBCLUSTER_DB
if (have_ndbcluster == SHOW_OPTION_YES)
error|=ndbcluster_end();
#endif
return error;
} /* ha_panic */
......@@ -261,6 +288,10 @@ void ha_drop_database(char* path)
if (have_innodb == SHOW_OPTION_YES)
innobase_drop_database(path);
#endif
#ifdef HAVE_NDBCLUSTER_DB
if (have_ndbcluster == SHOW_OPTION_YES)
ndbcluster_drop_database(path);
#endif
}
void ha_close_connection(THD* thd)
......@@ -269,6 +300,10 @@ void ha_close_connection(THD* thd)
if (have_innodb == SHOW_OPTION_YES)
innobase_close_connection(thd);
#endif
#ifdef HAVE_NDBCLUSTER_DB
if (have_ndbcluster == SHOW_OPTION_YES)
ndbcluster_close_connection(thd);
#endif
}
/*
......@@ -428,6 +463,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
WRITE_CACHE, (my_off_t) 0, 0, 1);
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
if (trans->bdb_tid)
{
......@@ -481,6 +529,18 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
if (opt_using_transactions)
{
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
if (trans->bdb_tid)
{
......@@ -1160,8 +1220,10 @@ bool handler::caching_allowed(THD* thd, char* table_key,
** 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,
bool update_create_info)
......@@ -1177,7 +1239,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
{
update_create_info_from_table(create_info, &table);
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 &&
!(table.file->table_flags() & HA_FILE_BASED))
......@@ -1298,6 +1360,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.
Store ranges for future calls to read_range_next
......@@ -1434,3 +1516,5 @@ int handler::compare_key(key_range *range)
}
return key_compare_result_on_equal;
}
......@@ -28,7 +28,8 @@
#define NO_HASH /* Not yet implemented */
#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
#endif
......@@ -80,7 +81,6 @@
#define HA_FILE_BASED (1 << 26)
/* 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_READ_NEXT 2 /* Read next record with same key */
......@@ -141,12 +141,18 @@
#define HA_CACHE_TBL_ASKTRANSACT 1
#define HA_CACHE_TBL_TRANSACT 2
enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
enum db_type
{
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI,
DB_TYPE_EXAMPLE_DB, DB_TYPE_DEFAULT };
DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
DB_TYPE_EXAMPLE_DB,
DB_TYPE_DEFAULT // Must be last
};
struct show_table_type_st {
const char *type;
......@@ -176,6 +182,7 @@ typedef struct st_thd_trans {
void *bdb_tid;
void *innobase_tid;
bool innodb_active_trans;
void *ndb_tid;
} THD_TRANS;
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
......@@ -479,3 +486,5 @@ bool ha_flush_logs(void);
int ha_recovery_logging(THD *thd, bool on);
int ha_change_key_cache(KEY_CACHE *old_key_cache,
KEY_CACHE *new_key_cache);
int ha_discover(const char* dbname, const char* name,
const void** frmblob, uint* frmlen);
......@@ -1356,7 +1356,7 @@ void subselect_uniquesubquery_engine::exclude()
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
{
table_map map= 0;
for(; table; table= table->next)
for (; table; table= table->next)
{
TABLE *tbl= table->table;
if (tbl && tbl->const_table)
......
......@@ -48,7 +48,7 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
*/
static SYMBOL symbols[] = {
{ "&&", SYM(AND)},
{ "&&", SYM(AND_SYM)},
{ "<", SYM(LT)},
{ "<=", SYM(LE)},
{ "<>", SYM(NE)},
......@@ -67,7 +67,7 @@ static SYMBOL symbols[] = {
{ "ALL", SYM(ALL)},
{ "ALTER", SYM(ALTER)},
{ "ANALYZE", SYM(ANALYZE_SYM)},
{ "AND", SYM(AND)},
{ "AND", SYM(AND_SYM)},
{ "ANY", SYM(ANY_SYM)},
{ "AS", SYM(AS)},
{ "ASC", SYM(ASC)},
......@@ -295,6 +295,8 @@ static SYMBOL symbols[] = {
{ "NAMES", SYM(NAMES_SYM)},
{ "NATIONAL", SYM(NATIONAL_SYM)},
{ "NATURAL", SYM(NATURAL)},
{ "NDB", SYM(NDBCLUSTER_SYM)},
{ "NDBCLUSTER", SYM(NDBCLUSTER_SYM)},
{ "NCHAR", SYM(NCHAR_SYM)},
{ "NEW", SYM(NEW_SYM)},
{ "NEXT", SYM(NEXT_SYM)},
......@@ -312,7 +314,7 @@ static SYMBOL symbols[] = {
{ "OPTIMIZE", SYM(OPTIMIZE)},
{ "OPTION", SYM(OPTION)},
{ "OPTIONALLY", SYM(OPTIONALLY)},
{ "OR", SYM(OR)},
{ "OR", SYM(OR_SYM)},
{ "ORDER", SYM(ORDER_SYM)},
{ "OUTER", SYM(OUTER)},
{ "OUTFILE", SYM(OUTFILE)},
......
......@@ -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_key_count, ha_read_next_count, ha_read_prev_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 max_connections,max_connect_errors, connect_timeout;
extern ulong slave_net_timeout;
......@@ -891,6 +891,7 @@ extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
extern SHOW_COMP_OPTION have_isam;
extern SHOW_COMP_OPTION have_innodb;
extern SHOW_COMP_OPTION have_berkeley_db;
extern SHOW_COMP_OPTION have_ndbcluster;
extern struct system_variables global_system_variables;
extern struct system_variables max_system_variables;
extern struct rand_struct sql_rand;
......@@ -960,6 +961,10 @@ int format_number(uint inputflag,uint max_length,my_string pos,uint length,
my_string *errpos);
int openfrm(const char *name,const char *alias,uint filestat,uint prgflag,
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);
db_type get_table_type(const char *name);
int read_string(File file, gptr *to, uint length);
......
......@@ -32,6 +32,9 @@
#ifdef HAVE_ISAM
#include "ha_isam.h"
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
#include <nisam.h>
#include <thr_alarm.h>
#include <ft_global.h>
......@@ -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_show_slave_auth_info, opt_sql_bin_update = 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_sync_bdb_logs, opt_sync_frm;
my_bool opt_secure_auth= 0;
......@@ -370,7 +373,8 @@ KEY_CACHE *sql_key_cache;
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam, have_example_db;
SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam,
have_ndbcluster, have_example_db;
SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
SHOW_COMP_OPTION have_crypt, have_compress;
......@@ -3625,7 +3629,7 @@ enum options_mysqld
OPT_INNODB_FAST_SHUTDOWN,
OPT_INNODB_FILE_PER_TABLE,
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_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
......@@ -4158,6 +4162,13 @@ Disable with --skip-innodb (will save memory).",
Disable with --skip-isam.",
(gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 1, 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,
"Deprecated option, use --skip-external-locking instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
......@@ -4828,6 +4839,7 @@ struct show_var_st status_vars[]= {
{"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
{"Handler_update", (char*) &ha_update_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,
SHOW_KEY_CACHE_LONG},
{"Key_blocks_used", (char*) &dflt_key_cache_var.global_blocks_used,
......@@ -5126,6 +5138,11 @@ static void mysql_init_variables(void)
#else
have_example_db= SHOW_OPTION_NO;
#endif
#ifdef HAVE_NDBCLUSTER_DB
have_ndbcluster=SHOW_OPTION_YES;
#else
have_ndbcluster=SHOW_OPTION_NO;
#endif
#ifdef USE_RAID
have_raid=SHOW_OPTION_YES;
#else
......@@ -5594,6 +5611,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
have_isam= SHOW_OPTION_YES;
else
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
break;
case OPT_INNODB:
......
......@@ -59,6 +59,9 @@
#ifdef HAVE_INNOBASE_DB
#include "ha_innodb.h"
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS };
......@@ -638,6 +641,7 @@ struct show_var_st init_vars[]= {
{"have_crypt", (char*) &have_crypt, SHOW_HAVE},
{"have_innodb", (char*) &have_innodb, SHOW_HAVE},
{"have_isam", (char*) &have_isam, SHOW_HAVE},
{"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE},
{"have_openssl", (char*) &have_openssl, SHOW_HAVE},
{"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
{"have_raid", (char*) &have_raid, SHOW_HAVE},
......
......@@ -1317,18 +1317,34 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
{
char path[FN_REFLEN];
int error;
uint discover_retry_count= 0;
DBUG_ENTER("open_unireg_entry");
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 |
HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
thd->open_options, entry))
{
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;
bzero((char*) &table_list, sizeof(table_list)); // just for safe
table_list.db=(char*) db;
......@@ -1374,6 +1390,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
if (error)
goto err;
break;
}
/*
If we are here, there was no fatal error (but error may be still
......
......@@ -688,7 +688,10 @@ public:
THD_TRANS all; // Trans since BEGIN WORK
THD_TRANS stmt; // Trans for current statement
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).
List contain only transactional tables, that not invalidated in query
......@@ -878,7 +881,8 @@ public:
{
#ifdef USING_TRANSACTIONS
return (transaction.all.bdb_tid != 0 ||
transaction.all.innodb_active_trans != 0);
transaction.all.innodb_active_trans != 0 ||
transaction.all.ndb_tid != 0);
#else
return 0;
#endif
......
......@@ -1529,7 +1529,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
*/
bool st_select_lex_unit::check_updateable(char *db, char *table)
{
for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
if (sl->check_updateable(db, table))
return 1;
return 0;
......
......@@ -830,7 +830,7 @@ outp:
void String::print(String *str)
{
char *st= (char*)Ptr, *end= st+str_length;
for(; st < end; st++)
for (; st < end; st++)
{
uchar c= *st;
switch (c)
......
......@@ -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";
create_info->table_existed= 0; // Mark that table is created
......
......@@ -181,7 +181,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ACTION
%token AGGREGATE_SYM
%token ALL
%token AND
%token AND_SYM
%token AS
%token ASC
%token AUTO_INC
......@@ -305,6 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NAMES_SYM
%token NATIONAL_SYM
%token NATURAL
%token NDBCLUSTER_SYM
%token NEW_SYM
%token NCHAR_SYM
%token NCHAR_STRING
......@@ -318,7 +319,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token OPEN_SYM
%token OPTION
%token OPTIONALLY
%token OR
%token OR_SYM
%token OR_OR_CONCAT
%token ORDER_SYM
%token OUTER
......@@ -574,8 +575,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token BEFORE_SYM
%left SET_VAR
%left OR_OR_CONCAT OR XOR
%left AND
%left OR_OR_CONCAT OR_SYM XOR
%left AND_SYM
%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 '|'
......@@ -727,7 +728,7 @@ END_OF_INPUT
%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
%%
......@@ -2421,14 +2422,14 @@ expr_expr:
{
$$= 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); }
| 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)); }
| 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 AND expr { $$= new Item_cond_and($1,$3); }
| expr AND_SYM expr { $$= new Item_cond_and($1,$3); }
| expr SOUNDS_SYM LIKE expr
{
$$= new Item_func_eq(new Item_func_soundex($1),
......@@ -2469,14 +2470,14 @@ expr_expr:
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
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); }
| 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)); }
| 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 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
{
$$= new Item_func_eq(new Item_func_soundex($1),
......@@ -2527,12 +2528,12 @@ no_and_expr:
{
$$= 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); }
| 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)); }
| 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 SOUNDS_SYM LIKE expr
{
......@@ -4147,8 +4148,8 @@ show_param:
YYABORT;
}
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
TEXT_STRING_sys AND MASTER_LOG_POS_SYM EQ ulonglong_num
AND MASTER_SERVER_ID_SYM EQ
TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num
AND_SYM MASTER_SERVER_ID_SYM EQ
ULONG_NUM
{
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
......@@ -4983,6 +4984,7 @@ keyword:
| NAMES_SYM {}
| NATIONAL_SYM {}
| NCHAR_SYM {}
| NDBCLUSTER_SYM {}
| NEXT_SYM {}
| NEW_SYM {}
| NO_SYM {}
......@@ -5434,7 +5436,7 @@ grant_privilege:
opt_and:
/* empty */ {}
| AND {}
| AND_SYM {}
;
require_list:
......
......@@ -944,7 +944,8 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype)
break;
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) ?
ER_FILE_USED : ER_CANT_OPEN_FILE;
my_error(err_no,errortype,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment