mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merge mskold@build.mysql.com:/home/bk/mysql-4.1
into mysql.com:/usr/local/home/marty/MySQL/test/mysql-4.1
This commit is contained in:
@@ -30,6 +30,7 @@ bk@admin.bk
|
||||
bk@mysql.r18.ru
|
||||
brian@avenger.(none)
|
||||
brian@brian-akers-computer.local
|
||||
brian@private-client-ip-101.oz.net
|
||||
carsten@tsort.bitbybit.dk
|
||||
davida@isil.mysql.com
|
||||
dlenev@brandersnatch.localdomain
|
||||
|
||||
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(sql/mysqld.cc)
|
||||
AC_CANONICAL_SYSTEM
|
||||
# The Docs Makefile.am parses this line!
|
||||
AM_INIT_AUTOMAKE(mysql, 4.1.5-gamma)
|
||||
AM_INIT_AUTOMAKE(mysql, 4.1.6-gamma)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
PROTOCOL_VERSION=10
|
||||
|
||||
@@ -47,6 +47,7 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
|
||||
uint key_length, hash_get_key get_key,
|
||||
void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
|
||||
void hash_free(HASH *tree);
|
||||
void hash_reset(HASH *hash);
|
||||
byte *hash_element(HASH *hash,uint idx);
|
||||
gptr hash_search(HASH *info,const byte *key,uint length);
|
||||
gptr hash_next(HASH *info,const byte *key,uint length);
|
||||
@@ -56,7 +57,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
|
||||
void hash_replace(HASH *hash, uint idx, byte *new_row);
|
||||
my_bool hash_check(HASH *hash); /* Only in debug library */
|
||||
|
||||
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
|
||||
#define hash_inited(H) ((H)->array.buffer != 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -42,6 +42,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename);
|
||||
|
||||
void mysql_read_default_options(struct st_mysql_options *options,
|
||||
const char *filename,const char *group);
|
||||
void mysql_detach_stmt_list(LIST **stmt_list);
|
||||
MYSQL * STDCALL
|
||||
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
const char *passwd, const char *db,
|
||||
|
||||
@@ -662,6 +662,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
const char *passwd, const char *db)
|
||||
{
|
||||
char buff[512],*end=buff;
|
||||
int rc;
|
||||
DBUG_ENTER("mysql_change_user");
|
||||
|
||||
if (!user)
|
||||
@@ -695,18 +696,26 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
/* Write authentication package */
|
||||
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
|
||||
|
||||
if ((*mysql->methods->read_change_user_result)(mysql, buff, passwd))
|
||||
DBUG_RETURN(1);
|
||||
/* Free old connect information */
|
||||
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
|
||||
rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
|
||||
|
||||
/* alloc new connect information */
|
||||
mysql->user= my_strdup(user,MYF(MY_WME));
|
||||
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
|
||||
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
|
||||
DBUG_RETURN(0);
|
||||
/*
|
||||
The server will close all statements no matter was the attempt
|
||||
to change user successful or not.
|
||||
*/
|
||||
mysql_detach_stmt_list(&mysql->stmts);
|
||||
if (rc == 0)
|
||||
{
|
||||
/* Free old connect information */
|
||||
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
|
||||
|
||||
/* alloc new connect information */
|
||||
mysql->user= my_strdup(user,MYF(MY_WME));
|
||||
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
|
||||
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
|
||||
}
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1297,4 +1297,6 @@ INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
|
||||
INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
|
||||
INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
|
||||
SELECT * FROM t2;
|
||||
OPTIMIZE TABLE t2;
|
||||
SELECT * FROM t2;
|
||||
drop table t1, t2;
|
||||
|
||||
26
mysys/hash.c
26
mysys/hash.c
@@ -88,6 +88,32 @@ void hash_free(HASH *hash)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete all elements from the hash (the hash itself is to be reused).
|
||||
|
||||
SYNOPSIS
|
||||
hash_reset()
|
||||
hash the hash to delete elements of
|
||||
*/
|
||||
|
||||
void hash_reset(HASH *hash)
|
||||
{
|
||||
DBUG_ENTER("hash_reset");
|
||||
if (hash->free)
|
||||
{
|
||||
HASH_LINK *link= dynamic_element(&hash->array, 0, HASH_LINK*);
|
||||
HASH_LINK *end= link + hash->records;
|
||||
for (; link < end; ++link)
|
||||
(*hash->free)(link->data);
|
||||
}
|
||||
reset_dynamic(&hash->array);
|
||||
hash->records= 0;
|
||||
hash->blength= 1;
|
||||
hash->current_record= NO_RECORD;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* some helper functions */
|
||||
|
||||
/*
|
||||
|
||||
@@ -229,10 +229,10 @@ LocalConfig::parseString(const char * connectString, char *line){
|
||||
|
||||
bool LocalConfig::readFile(const char * filename, bool &fopenError)
|
||||
{
|
||||
char line[150], line2[150];
|
||||
|
||||
char line[1024];
|
||||
|
||||
fopenError = false;
|
||||
|
||||
|
||||
FILE * file = fopen(filename, "r");
|
||||
if(file == 0){
|
||||
snprintf(line, 150, "Unable to open local config file: %s", filename);
|
||||
@@ -241,31 +241,33 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError)
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int sz = 1024;
|
||||
char* theString = (char*)NdbMem_Allocate(sz);
|
||||
theString[0] = 0;
|
||||
BaseString theString;
|
||||
|
||||
fgets(theString, sz, file);
|
||||
while (fgets(line+1, 100, file)) {
|
||||
line[0] = ';';
|
||||
while (strlen(theString) + strlen(line) >= sz) {
|
||||
sz = sz*2;
|
||||
char *newString = (char*)NdbMem_Allocate(sz);
|
||||
strcpy(newString, theString);
|
||||
free(theString);
|
||||
theString = newString;
|
||||
while(fgets(line, 1024, file)){
|
||||
BaseString tmp(line);
|
||||
tmp.trim(" \t\n\r");
|
||||
if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
|
||||
theString.append(tmp);
|
||||
break;
|
||||
}
|
||||
strcat(theString, line);
|
||||
}
|
||||
|
||||
bool return_value = parseString(theString, line);
|
||||
while (fgets(line, 1024, file)) {
|
||||
BaseString tmp(line);
|
||||
tmp.trim(" \t\n\r");
|
||||
if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
|
||||
theString.append(";");
|
||||
theString.append(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
bool return_value = parseString(theString.c_str(), line);
|
||||
|
||||
if (!return_value) {
|
||||
snprintf(line2, 150, "Reading %s: %s", filename, line);
|
||||
setError(0,line2);
|
||||
BaseString tmp;
|
||||
tmp.assfmt("Reading %s: %s", filename, line);
|
||||
setError(0, tmp.c_str());
|
||||
}
|
||||
|
||||
free(theString);
|
||||
fclose(file);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@@ -2239,6 +2239,32 @@ static void mysql_close_free(MYSQL *mysql)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Clear connection pointer of every statement: this is necessary
|
||||
to give error on attempt to use a prepared statement of closed
|
||||
connection.
|
||||
|
||||
SYNOPSYS
|
||||
mysql_detach_stmt_list()
|
||||
stmt_list pointer to mysql->stmts
|
||||
*/
|
||||
|
||||
void mysql_detach_stmt_list(LIST **stmt_list)
|
||||
{
|
||||
#ifdef MYSQL_CLIENT
|
||||
/* Reset connection handle in all prepared statements. */
|
||||
LIST *element= *stmt_list;
|
||||
for (; element; element= element->next)
|
||||
{
|
||||
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
|
||||
stmt->mysql= 0;
|
||||
/* No need to call list_delete for statement here */
|
||||
}
|
||||
*stmt_list= 0;
|
||||
#endif /* MYSQL_CLIENT */
|
||||
}
|
||||
|
||||
|
||||
void STDCALL mysql_close(MYSQL *mysql)
|
||||
{
|
||||
DBUG_ENTER("mysql_close");
|
||||
@@ -2255,20 +2281,7 @@ void STDCALL mysql_close(MYSQL *mysql)
|
||||
}
|
||||
mysql_close_free_options(mysql);
|
||||
mysql_close_free(mysql);
|
||||
#ifdef MYSQL_CLIENT
|
||||
if (mysql->stmts)
|
||||
{
|
||||
/* Reset connection handle in all prepared statements. */
|
||||
LIST *element;
|
||||
for (element= mysql->stmts; element; element= element->next)
|
||||
{
|
||||
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
|
||||
stmt->mysql= 0;
|
||||
/* No need to call list_delete for statement here */
|
||||
}
|
||||
mysql->stmts= 0;
|
||||
}
|
||||
#endif /*MYSQL_CLIENT*/
|
||||
mysql_detach_stmt_list(&mysql->stmts);
|
||||
#ifndef TO_BE_DELETED
|
||||
/* free/close slave list */
|
||||
if (mysql->rpl_pivot)
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
Allow users to set compression level.
|
||||
Add truncate table command.
|
||||
Implement versioning, should be easy.
|
||||
Implement optimize so we can fix broken tables.
|
||||
Allow for errors, find a way to mark bad rows.
|
||||
See if during an optimize you can make the table smaller.
|
||||
Talk to the gzip guys, come up with a writable format so that updates are doable
|
||||
@@ -88,6 +87,7 @@ static int archive_init= 0;
|
||||
|
||||
/* The file extension */
|
||||
#define ARZ ".ARZ"
|
||||
#define ARN ".ARN"
|
||||
|
||||
/*
|
||||
Used for hash table that tracks open tables.
|
||||
@@ -117,7 +117,7 @@ static ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table)
|
||||
if (!archive_init)
|
||||
{
|
||||
VOID(pthread_mutex_init(&archive_mutex,MY_MUTEX_INIT_FAST));
|
||||
if (!hash_init(&archive_open_tables,system_charset_info,32,0,0,
|
||||
if (hash_init(&archive_open_tables,system_charset_info,32,0,0,
|
||||
(hash_get_key) archive_get_key,0,0))
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_mysql_create_db);
|
||||
@@ -205,7 +205,7 @@ static int free_share(ARCHIVE_SHARE *share)
|
||||
We just implement one additional file extension.
|
||||
*/
|
||||
const char **ha_archive::bas_ext() const
|
||||
{ static const char *ext[]= { ARZ, NullS }; return ext; }
|
||||
{ static const char *ext[]= { ARZ, ARN, NullS }; return ext; }
|
||||
|
||||
|
||||
/*
|
||||
@@ -322,6 +322,11 @@ err:
|
||||
/*
|
||||
Look at ha_archive::open() for an explanation of the row format.
|
||||
Here we just write out the row.
|
||||
|
||||
Wondering about start_bulk_insert()? We don't implement it for
|
||||
archive since it optimizes for lots of writes. The only save
|
||||
for implementing start_bulk_insert() is that we could skip
|
||||
setting dirty to true each time.
|
||||
*/
|
||||
int ha_archive::write_row(byte * buf)
|
||||
{
|
||||
@@ -380,17 +385,7 @@ int ha_archive::rnd_init(bool scan)
|
||||
pthread_mutex_lock(&share->mutex);
|
||||
if (share->dirty == TRUE)
|
||||
{
|
||||
/* I was having problems with OSX, but it worked for 10.3 so I am wrapping this with and ifdef */
|
||||
#ifdef BROKEN_GZFLUSH
|
||||
gzclose(share->archive_write);
|
||||
if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
|
||||
{
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
DBUG_RETURN(errno ? errno : -1);
|
||||
}
|
||||
#else
|
||||
gzflush(share->archive_write, Z_SYNC_FLUSH);
|
||||
#endif
|
||||
share->dirty= FALSE;
|
||||
}
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
@@ -504,6 +499,54 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
|
||||
DBUG_RETURN(get_row(buf));
|
||||
}
|
||||
|
||||
/*
|
||||
The table can become fragmented if data was inserted, read, and then
|
||||
inserted again. What we do is open up the file and recompress it completely.
|
||||
*/
|
||||
int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
||||
{
|
||||
DBUG_ENTER("ha_archive::optimize");
|
||||
int read; // Bytes read, gzread() returns int
|
||||
gzFile reader, writer;
|
||||
char block[IO_SIZE];
|
||||
char writer_filename[FN_REFLEN];
|
||||
|
||||
/* Lets create a file to contain the new data */
|
||||
fn_format(writer_filename,share->table_name,"",ARN, MY_REPLACE_EXT|MY_UNPACK_FILENAME);
|
||||
|
||||
/* Closing will cause all data waiting to be flushed, to be flushed */
|
||||
gzclose(share->archive_write);
|
||||
|
||||
if ((reader= gzopen(share->data_file_name, "rb")) == NULL)
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
if ((writer= gzopen(writer_filename, "wb")) == NULL)
|
||||
{
|
||||
gzclose(reader);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
while (read= gzread(reader, block, IO_SIZE))
|
||||
gzwrite(writer, block, read);
|
||||
|
||||
gzclose(reader);
|
||||
gzclose(writer);
|
||||
|
||||
my_rename(writer_filename,share->data_file_name,MYF(0));
|
||||
|
||||
/*
|
||||
We reopen the file in case some IO is waiting to go through.
|
||||
In theory the table is closed right after this operation,
|
||||
but it is possible for IO to still happen.
|
||||
I may be being a bit too paranoid right here.
|
||||
*/
|
||||
if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
|
||||
DBUG_RETURN(errno ? errno : -1);
|
||||
share->dirty= FALSE;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
Everything below here is default, please look at ha_example.cc for
|
||||
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
int external_lock(THD *thd, int lock_type);
|
||||
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
|
||||
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
|
||||
|
||||
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
|
||||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||
enum thr_lock_type lock_type);
|
||||
};
|
||||
|
||||
@@ -185,7 +185,7 @@ void ha_ndbcluster::records_update()
|
||||
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
|
||||
((const NDBTAB *)m_table)->getTableId(),
|
||||
info->no_uncommitted_rows_count));
|
||||
if (info->records == ~(ha_rows)0)
|
||||
// if (info->records == ~(ha_rows)0)
|
||||
{
|
||||
Uint64 rows;
|
||||
if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
|
||||
@@ -617,7 +617,7 @@ int ha_ndbcluster::get_metadata(const char *path)
|
||||
DBUG_ENTER("get_metadata");
|
||||
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path));
|
||||
|
||||
if (!(tab= dict->getTable(m_tabname, &m_table_info)))
|
||||
if (!(tab= dict->getTable(m_tabname)))
|
||||
ERR_RETURN(dict->getNdbError());
|
||||
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
|
||||
|
||||
@@ -665,8 +665,8 @@ int ha_ndbcluster::get_metadata(const char *path)
|
||||
if (error)
|
||||
DBUG_RETURN(error);
|
||||
|
||||
// All checks OK, lets use the table
|
||||
m_table= (void*)tab;
|
||||
m_table= NULL;
|
||||
m_table_info= NULL;
|
||||
|
||||
DBUG_RETURN(build_index_list(table, ILBP_OPEN));
|
||||
}
|
||||
@@ -781,6 +781,7 @@ void ha_ndbcluster::release_metadata()
|
||||
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
|
||||
|
||||
m_table= NULL;
|
||||
m_table_info= NULL;
|
||||
|
||||
// Release index list
|
||||
for (i= 0; i < MAX_KEY; i++)
|
||||
@@ -2402,7 +2403,17 @@ void ha_ndbcluster::info(uint flag)
|
||||
if (flag & HA_STATUS_VARIABLE)
|
||||
{
|
||||
DBUG_PRINT("info", ("HA_STATUS_VARIABLE"));
|
||||
records_update();
|
||||
if (m_table_info)
|
||||
{
|
||||
records_update();
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint64 rows;
|
||||
if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
|
||||
records= rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag & HA_STATUS_CONST)
|
||||
{
|
||||
@@ -2794,6 +2805,16 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
|
||||
// Start of transaction
|
||||
retrieve_all_fields= FALSE;
|
||||
ops_pending= 0;
|
||||
{
|
||||
NDBDICT *dict= m_ndb->getDictionary();
|
||||
const NDBTAB *tab;
|
||||
void *tab_info;
|
||||
if (!(tab= dict->getTable(m_tabname, &tab_info)))
|
||||
ERR_RETURN(dict->getNdbError());
|
||||
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
|
||||
m_table= (void *)tab;
|
||||
m_table_info= tab_info;
|
||||
}
|
||||
no_uncommitted_rows_init(thd);
|
||||
}
|
||||
else
|
||||
@@ -2816,6 +2837,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
|
||||
thd->transaction.stmt.ndb_tid= 0;
|
||||
}
|
||||
}
|
||||
m_table= NULL;
|
||||
m_table_info= NULL;
|
||||
if (m_active_trans)
|
||||
DBUG_PRINT("warning", ("m_active_trans != NULL"));
|
||||
if (m_active_cursor)
|
||||
@@ -3301,6 +3324,7 @@ int ha_ndbcluster::alter_table_name(const char *from, const char *to)
|
||||
ERR_RETURN(dict->getNdbError());
|
||||
|
||||
m_table= NULL;
|
||||
m_table_info= NULL;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@@ -328,6 +328,7 @@ void THD::change_user(void)
|
||||
cleanup();
|
||||
cleanup_done= 0;
|
||||
init();
|
||||
stmt_map.reset();
|
||||
hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_var_key,
|
||||
(hash_free_key) free_user_var, 0);
|
||||
|
||||
@@ -566,7 +566,7 @@ public:
|
||||
assignment in Statement::Statement)
|
||||
Non-empty statement names are unique too: attempt to insert a new statement
|
||||
with duplicate name causes older statement to be deleted
|
||||
|
||||
|
||||
Statements are auto-deleted when they are removed from the map and when the
|
||||
map is deleted.
|
||||
*/
|
||||
@@ -575,7 +575,7 @@ class Statement_map
|
||||
{
|
||||
public:
|
||||
Statement_map();
|
||||
|
||||
|
||||
int insert(Statement *statement);
|
||||
|
||||
Statement *find_by_name(LEX_STRING *name)
|
||||
@@ -608,11 +608,18 @@ public:
|
||||
}
|
||||
hash_delete(&st_hash, (byte *) statement);
|
||||
}
|
||||
/* Erase all statements (calls Statement destructor) */
|
||||
void reset()
|
||||
{
|
||||
hash_reset(&names_hash);
|
||||
hash_reset(&st_hash);
|
||||
last_found_statement= 0;
|
||||
}
|
||||
|
||||
~Statement_map()
|
||||
{
|
||||
hash_free(&st_hash);
|
||||
hash_free(&names_hash);
|
||||
hash_free(&st_hash);
|
||||
}
|
||||
private:
|
||||
HASH st_hash;
|
||||
|
||||
@@ -10391,6 +10391,34 @@ static void test_bug5194()
|
||||
}
|
||||
|
||||
|
||||
static void test_bug5315()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
const char *stmt_text;
|
||||
int rc;
|
||||
|
||||
myheader("test_bug5315");
|
||||
|
||||
stmt_text= "SELECT 1";
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
DBUG_ASSERT(rc == 0);
|
||||
mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
DBUG_ASSERT(rc != 0);
|
||||
if (rc)
|
||||
printf("Got error (as expected):\n%s", mysql_stmt_error(stmt));
|
||||
/* check that connection is OK */
|
||||
mysql_stmt_close(stmt);
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
DBUG_ASSERT(rc == 0);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
DBUG_ASSERT(rc == 0);
|
||||
mysql_stmt_close(stmt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read and parse arguments and MySQL options from my.cnf
|
||||
*/
|
||||
@@ -10694,6 +10722,8 @@ int main(int argc, char **argv)
|
||||
test_bug5399(); /* check that statement id uniquely identifies
|
||||
statement */
|
||||
test_bug5194(); /* bulk inserts in prepared mode */
|
||||
test_bug5315(); /* check that mysql_change_user closes all
|
||||
prepared statements */
|
||||
/*
|
||||
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
|
||||
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
|
||||
|
||||
Reference in New Issue
Block a user