1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0

into dl145c.mysql.com:/home/ndbdev/tomas/mysql-5.1
This commit is contained in:
ndbdev@dl145c.mysql.com
2005-05-17 20:07:03 +02:00
11 changed files with 178 additions and 42 deletions

View File

@@ -359,6 +359,14 @@ AC_SUBST(INSTALL_SCRIPT)
export CC CXX CFLAGS LD LDFLAGS AR export CC CXX CFLAGS LD LDFLAGS AR
if test "$GCC" = "yes"
then
# mysqld requires -fno-implicit-templates.
# Disable exceptions as they seams to create problems with gcc and threads.
# mysqld doesn't use run-time-type-checking, so we disable it.
CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
fi
# Avoid bug in fcntl on some versions of linux # Avoid bug in fcntl on some versions of linux
AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os") AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
# Any variation of Linux # Any variation of Linux

View File

@@ -96,6 +96,7 @@ extern const char *client_errors[]; /* Error messages */
#define CR_NO_DATA 2051 #define CR_NO_DATA 2051
#define CR_NO_STMT_METADATA 2052 #define CR_NO_STMT_METADATA 2052
#define CR_NO_RESULT_SET 2053 #define CR_NO_RESULT_SET 2053
#define CR_ERROR_LAST /*Copy last error nr:*/ 2053 #define CR_NOT_IMPLEMENTED 2054
#define CR_ERROR_LAST /*Copy last error nr:*/ 2054
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */ /* Add error numbers before CR_ERROR_LAST and change it accordingly. */

View File

@@ -664,6 +664,7 @@ typedef struct st_mysql_stmt
unsigned char **row); unsigned char **row);
unsigned long stmt_id; /* Id for prepared statement */ unsigned long stmt_id; /* Id for prepared statement */
unsigned long flags; /* i.e. type of cursor to open */ unsigned long flags; /* i.e. type of cursor to open */
unsigned long prefetch_rows; /* number of rows per one COM_FETCH */
/* /*
Copied from mysql->server_status after execute/fetch to know Copied from mysql->server_status after execute/fetch to know
server-side cursor status for this statement. server-side cursor status for this statement.
@@ -702,7 +703,12 @@ enum enum_stmt_attr_type
unsigned long with combination of cursor flags (read only, for update, unsigned long with combination of cursor flags (read only, for update,
etc) etc)
*/ */
STMT_ATTR_CURSOR_TYPE STMT_ATTR_CURSOR_TYPE,
/*
Amount of rows to retrieve from server per one fetch if using cursors.
Accepts unsigned long attribute in the range 1 - ulong_max
*/
STMT_ATTR_PREFETCH_ROWS
}; };

View File

@@ -81,6 +81,7 @@ const char *client_errors[]=
"Attempt to read column without prior row fetch", "Attempt to read column without prior row fetch",
"Prepared statement contains no metadata", "Prepared statement contains no metadata",
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet",
"" ""
}; };
@@ -143,6 +144,7 @@ const char *client_errors[]=
"Attempt to read column without prior row fetch", "Attempt to read column without prior row fetch",
"Prepared statement contains no metadata", "Prepared statement contains no metadata",
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet",
"" ""
}; };
@@ -203,6 +205,7 @@ const char *client_errors[]=
"Attempt to read column without prior row fetch", "Attempt to read column without prior row fetch",
"Prepared statement contains no metadata", "Prepared statement contains no metadata",
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet",
"" ""
}; };
#endif #endif

View File

@@ -1736,6 +1736,9 @@ myodbc_remove_escape(MYSQL *mysql,char *name)
/******************* Declarations ***********************************/ /******************* Declarations ***********************************/
/* Default number of rows fetched per one COM_FETCH command. */
#define DEFAULT_PREFETCH_ROWS 1UL
/* /*
These functions are called by function pointer MYSQL_STMT::read_row_func. These functions are called by function pointer MYSQL_STMT::read_row_func.
@@ -1761,6 +1764,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *bind, MYSQL_FIELD *field);
#define RESET_SERVER_SIDE 1 #define RESET_SERVER_SIDE 1
#define RESET_LONG_DATA 2 #define RESET_LONG_DATA 2
#define RESET_STORE_RESULT 4
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags); static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
@@ -2001,6 +2005,7 @@ mysql_stmt_init(MYSQL *mysql)
stmt->state= MYSQL_STMT_INIT_DONE; stmt->state= MYSQL_STMT_INIT_DONE;
stmt->mysql= mysql; stmt->mysql= mysql;
stmt->read_row_func= stmt_read_row_no_data; stmt->read_row_func= stmt_read_row_no_data;
stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
/* The rest of statement members was bzeroed inside malloc */ /* The rest of statement members was bzeroed inside malloc */
DBUG_RETURN(stmt); DBUG_RETURN(stmt);
@@ -2059,7 +2064,7 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
/* This is second prepare with another statement */ /* This is second prepare with another statement */
char buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */ char buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
if (reset_stmt_handle(stmt, RESET_LONG_DATA)) if (reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT))
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
These members must be reset for API to These members must be reset for API to
@@ -2714,7 +2719,7 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
result->rows= 0; result->rows= 0;
/* Send row request to the server */ /* Send row request to the server */
int4store(buff, stmt->stmt_id); int4store(buff, stmt->stmt_id);
int4store(buff + 4, 1); /* number of rows to fetch */ int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
if (cli_advanced_command(mysql, COM_FETCH, buff, sizeof(buff), if (cli_advanced_command(mysql, COM_FETCH, buff, sizeof(buff),
NullS, 0, 1)) NullS, 0, 1))
{ {
@@ -2772,12 +2777,29 @@ my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
stmt->update_max_length= value ? *(const my_bool*) value : 0; stmt->update_max_length= value ? *(const my_bool*) value : 0;
break; break;
case STMT_ATTR_CURSOR_TYPE: case STMT_ATTR_CURSOR_TYPE:
stmt->flags= value ? *(const unsigned long *) value : 0; {
ulong cursor_type;
cursor_type= value ? *(ulong*) value : 0UL;
if (cursor_type > (ulong) CURSOR_TYPE_READ_ONLY)
goto err_not_implemented;
stmt->flags= cursor_type;
break; break;
}
case STMT_ATTR_PREFETCH_ROWS:
{
ulong prefetch_rows= value ? *(ulong*) value : DEFAULT_PREFETCH_ROWS;
if (value == 0)
return TRUE;
stmt->prefetch_rows= prefetch_rows;
break;
}
default: default:
return TRUE; goto err_not_implemented;
} }
return FALSE; return FALSE;
err_not_implemented:
set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate);
return TRUE;
} }
@@ -2854,7 +2876,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (reset_stmt_handle(stmt, 0)) if (reset_stmt_handle(stmt, RESET_STORE_RESULT))
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
No need to check for stmt->state: if the statement wasn't No need to check for stmt->state: if the statement wasn't
@@ -4862,7 +4884,11 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
MYSQL_DATA *result= &stmt->result; MYSQL_DATA *result= &stmt->result;
my_bool has_cursor= stmt->read_row_func == stmt_read_row_from_cursor; my_bool has_cursor= stmt->read_row_func == stmt_read_row_from_cursor;
if (result->data) /*
Reset stored result set if so was requested or it's a part
of cursor fetch.
*/
if (result->data && (has_cursor || (flags & RESET_STORE_RESULT)))
{ {
/* Result buffered */ /* Result buffered */
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
@@ -4921,7 +4947,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
DBUG_ENTER("mysql_stmt_free_result"); DBUG_ENTER("mysql_stmt_free_result");
/* Free the client side and close the server side cursor if there is one */ /* Free the client side and close the server side cursor if there is one */
DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA)); DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT));
} }
/******************************************************************** /********************************************************************

View File

@@ -1712,3 +1712,17 @@ a b
2 2 2 2
4 4 4 4
DROP VIEW v2,v1; DROP VIEW v2,v1;
DROP TABLE t1, t2;
create table t1 (a int);
create view v1 as select sum(a) from t1 group by a;
create procedure p1()
begin
select * from v1;
end//
call p1();
sum(a)
call p1();
sum(a)
drop procedure p1;
drop view v1;
drop table t1;

View File

@@ -1521,8 +1521,10 @@ SELECT a.col1,a.col2,b.col2,b.col3
DROP VIEW v1,v2,v3; DROP VIEW v1,v2,v3;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#8490 Select from views containing subqueries causes server to hang # BUG#8490 Select from views containing subqueries causes server to hang
# forever. # forever.
#
create table t1 as select 1 A union select 2 union select 3; create table t1 as select 1 A union select 2 union select 3;
create table t2 as select * from t1; create table t2 as select * from t1;
create view v1 as select * from t1 where a in (select * from t2); create view v1 as select * from t1 where a in (select * from t2);
@@ -1537,7 +1539,6 @@ drop table t1, t2, t3;
# #
# Test case for bug #8528: select from view over multi-table view # Test case for bug #8528: select from view over multi-table view
# #
CREATE TABLE t1 (a int); CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int); CREATE TABLE t2 (b int);
INSERT INTO t1 VALUES (1), (2), (3), (4); INSERT INTO t1 VALUES (1), (2), (3), (4);
@@ -1549,3 +1550,22 @@ CREATE VIEW v2 AS SELECT * FROM v1;
SELECT * FROM v2; SELECT * FROM v2;
DROP VIEW v2,v1; DROP VIEW v2,v1;
DROP TABLE t1, t2;
#
# Correct restoring view name in SP table locking BUG#9758
#
create table t1 (a int);
create view v1 as select sum(a) from t1 group by a;
delimiter //;
create procedure p1()
begin
select * from v1;
end//
delimiter ;//
call p1();
call p1();
drop procedure p1;
drop view v1;
drop table t1;

View File

@@ -2090,15 +2090,10 @@ sp_restore_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
typedef struct st_sp_table typedef struct st_sp_table
{ {
LEX_STRING qname; LEX_STRING qname; /* Multi-set key: db_name\0table_name\0alias\0 */
bool temp; uint db_length, table_name_length;
TABLE_LIST *table; bool temp; /* true if corresponds to a temporary table */
/* thr_lock_type lock_type; /* lock type used for prelocking */
We can't use table->lock_type as lock type for table
in multi-set since it can be changed by statement during
its execution (e.g. as this happens for multi-update).
*/
thr_lock_type lock_type;
uint lock_count; uint lock_count;
uint query_lock_count; uint query_lock_count;
} SP_TABLE; } SP_TABLE;
@@ -2150,15 +2145,15 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
for (; table ; table= table->next_global) for (; table ; table= table->next_global)
if (!table->derived && !table->schema_table) if (!table->derived && !table->schema_table)
{ {
char tname[64+1+64+1+64+1]; // db.table.alias\0 char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0
uint tlen, alen; uint tlen, alen;
tlen= table->db_length; tlen= table->db_length;
memcpy(tname, table->db, tlen); memcpy(tname, table->db, tlen);
tname[tlen++]= '.'; tname[tlen++]= '\0';
memcpy(tname+tlen, table->table_name, table->table_name_length); memcpy(tname+tlen, table->table_name, table->table_name_length);
tlen+= table->table_name_length; tlen+= table->table_name_length;
tname[tlen++]= '.'; tname[tlen++]= '\0';
alen= strlen(table->alias); alen= strlen(table->alias);
memcpy(tname+tlen, table->alias, alen); memcpy(tname+tlen, table->alias, alen);
tlen+= alen; tlen+= alen;
@@ -2181,14 +2176,15 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE)))) if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
return FALSE; return FALSE;
tab->qname.length= tlen; tab->qname.length= tlen;
tab->qname.str= (char *)thd->strmake(tname, tab->qname.length); tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1);
if (!tab->qname.str) if (!tab->qname.str)
return FALSE; return FALSE;
if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE && if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
lex_for_tmp_check->query_tables == table && lex_for_tmp_check->query_tables == table &&
lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
tab->temp= TRUE; tab->temp= TRUE;
tab->table= table; tab->table_name_length= table->table_name_length;
tab->db_length= table->db_length;
tab->lock_type= table->lock_type; tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1; tab->lock_count= tab->query_lock_count= 1;
my_hash_insert(&m_sptabs, (byte *)tab); my_hash_insert(&m_sptabs, (byte *)tab);
@@ -2236,13 +2232,11 @@ sp_head::add_used_tables_to_table_list(THD *thd,
for (i=0 ; i < m_sptabs.records ; i++) for (i=0 ; i < m_sptabs.records ; i++)
{ {
char *tab_buff; char *tab_buff;
TABLE_LIST *table, *otable; TABLE_LIST *table;
SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i); SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i);
if (stab->temp) if (stab->temp)
continue; continue;
otable= stab->table;
if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) * if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) *
stab->lock_count))) stab->lock_count)))
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
@@ -2257,11 +2251,11 @@ sp_head::add_used_tables_to_table_list(THD *thd,
that the PS will be invalidated if the functions is deleted or that the PS will be invalidated if the functions is deleted or
changed. changed.
*/ */
table->db= otable->db; table->db= stab->qname.str;
table->db_length= otable->db_length; table->db_length= stab->db_length;
table->alias= otable->alias; table->table_name= table->db + table->db_length + 1;
table->table_name= otable->table_name; table->table_name_length= stab->table_name_length;
table->table_name_length= otable->table_name_length; table->alias= table->table_name + table->table_name_length + 1;
table->lock_type= stab->lock_type; table->lock_type= stab->lock_type;
table->cacheable_table= 1; table->cacheable_table= 1;
table->prelocking_placeholder= 1; table->prelocking_placeholder= 1;

View File

@@ -3309,7 +3309,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
0) 0)
{ {
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
table->real_name); table->s->table_name);
map->set_all(); map->set_all();
return 1; return 1;
} }

View File

@@ -3994,6 +3994,7 @@ select_options:
YYABORT; YYABORT;
} }
} }
;
select_option_list: select_option_list:
select_option_list select_option select_option_list select_option
@@ -7454,8 +7455,8 @@ option_type_value:
/* /*
If we are in SP we want have own LEX for each assignment. If we are in SP we want have own LEX for each assignment.
This is mostly because it is hard for several sp_instr_set This is mostly because it is hard for several sp_instr_set
and sp_instr_set_trigger instructions share one LEX. and sp_instr_set_trigger instructions share one LEX.
(Well, it is theoretically possible but adds some extra (Well, it is theoretically possible but adds some extra
overhead on preparation for execution stage and IMO less overhead on preparation for execution stage and IMO less
robust). robust).
@@ -7464,7 +7465,7 @@ option_type_value:
LEX *lex; LEX *lex;
Lex->sphead->reset_lex(YYTHD); Lex->sphead->reset_lex(YYTHD);
lex= Lex; lex= Lex;
/* Set new LEX as if we at start of set rule. */ /* Set new LEX as if we at start of set rule. */
lex->sql_command= SQLCOM_SET_OPTION; lex->sql_command= SQLCOM_SET_OPTION;
mysql_init_select(lex); mysql_init_select(lex);
@@ -7477,11 +7478,11 @@ option_type_value:
option_type option_value option_type option_value
{ {
LEX *lex= Lex; LEX *lex= Lex;
if (lex->sphead) if (lex->sphead)
{ {
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
if (!lex->var_list.is_empty()) if (!lex->var_list.is_empty())
{ {
/* /*
@@ -7491,19 +7492,19 @@ option_type_value:
*/ */
LEX_STRING qbuff; LEX_STRING qbuff;
sp_instr_stmt *i; sp_instr_stmt *i;
if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont, if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont,
lex))) lex)))
YYABORT; YYABORT;
if (lex->ptr - lex->tok_end > 1) if (lex->ptr - lex->tok_end > 1)
qbuff.length= lex->ptr - sp->m_tmp_query; qbuff.length= lex->ptr - sp->m_tmp_query;
else else
qbuff.length= lex->tok_end - sp->m_tmp_query; qbuff.length= lex->tok_end - sp->m_tmp_query;
if (!(qbuff.str= alloc_root(YYTHD->mem_root, qbuff.length + 5))) if (!(qbuff.str= alloc_root(YYTHD->mem_root, qbuff.length + 5)))
YYABORT; YYABORT;
strmake(strmake(qbuff.str, "SET ", 4), (char *)sp->m_tmp_query, strmake(strmake(qbuff.str, "SET ", 4), (char *)sp->m_tmp_query,
qbuff.length); qbuff.length);
qbuff.length+= 4; qbuff.length+= 4;

View File

@@ -13078,6 +13078,68 @@ static void test_bug9478()
} }
/*
Error message is returned for unsupported features.
Test also cursors with non-default PREFETCH_ROWS
*/
static void test_bug9643()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
int32 a;
int rc;
const char *stmt_text;
int num_rows= 0;
ulong type;
ulong prefetch_rows= 5;
myheader("test_bug9643");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (id integer not null primary key)");
rc= mysql_query(mysql, "insert into t1 (id) values "
" (1), (2), (3), (4), (5), (6), (7), (8), (9)");
myquery(rc);
stmt= mysql_stmt_init(mysql);
/* Not implemented in 5.0 */
type= (ulong) CURSOR_TYPE_SCROLLABLE;
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
DIE_UNLESS(rc);
if (! opt_silent)
printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
type= (ulong) CURSOR_TYPE_READ_ONLY;
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
check_execute(stmt, rc);
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
(void*) &prefetch_rows);
check_execute(stmt, rc);
stmt_text= "select * from t1";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_execute(stmt, rc);
bzero(bind, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (void*) &a;
bind[0].buffer_length= sizeof(a);
mysql_stmt_bind_result(stmt, bind);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
while ((rc= mysql_stmt_fetch(stmt)) == 0)
++num_rows;
DIE_UNLESS(num_rows == 9);
rc= mysql_stmt_close(stmt);
DIE_UNLESS(rc == 0);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
@@ -13309,6 +13371,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug9159", test_bug9159 }, { "test_bug9159", test_bug9159 },
{ "test_bug9520", test_bug9520 }, { "test_bug9520", test_bug9520 },
{ "test_bug9478", test_bug9478 }, { "test_bug9478", test_bug9478 },
{ "test_bug9643", test_bug9643 },
{ 0, 0 } { 0, 0 }
}; };