mysql-test/r/sp-security.result:
  Auto merged
mysql-test/r/sp.result:
  Auto merged
mysql-test/t/sp-security.test:
  Auto merged
mysql-test/t/sp.test:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp_rcontext.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
This commit is contained in:
unknown 2004-10-28 11:02:48 +03:00
commit 46ce3d0092
61 changed files with 735 additions and 322 deletions

View File

@ -386,23 +386,24 @@
#define ER_ILLEGAL_VALUE_FOR_TYPE 1367
#define ER_VIEW_NONUPD_CHECK 1368
#define ER_VIEW_CHECK_FAILED 1369
#define ER_RELAY_LOG_FAIL 1370
#define ER_PASSWD_LENGTH 1371
#define ER_UNKNOWN_TARGET_BINLOG 1372
#define ER_IO_ERR_LOG_INDEX_READ 1373
#define ER_BINLOG_PURGE_PROHIBITED 1374
#define ER_FSEEK_FAIL 1375
#define ER_BINLOG_PURGE_FATAL_ERR 1376
#define ER_LOG_IN_USE 1377
#define ER_LOG_PURGE_UNKNOWN_ERR 1378
#define ER_RELAY_LOG_INIT 1379
#define ER_NO_BINARY_LOGGING 1380
#define ER_RESERVED_SYNTAX 1381
#define ER_WSAS_FAILED 1382
#define ER_DIFF_GROUPS_PROC 1383
#define ER_NO_GROUP_FOR_PROC 1384
#define ER_ORDER_WITH_PROC 1385
#define ER_LOGING_PROHIBIT_CHANGING_OF 1386
#define ER_NO_FILE_MAPPING 1387
#define ER_WRONG_MAGIC 1388
#define ER_ERROR_MESSAGES 389
#define ER_SP_ACCESS_DENIED_ERROR 1370
#define ER_RELAY_LOG_FAIL 1371
#define ER_PASSWD_LENGTH 1372
#define ER_UNKNOWN_TARGET_BINLOG 1373
#define ER_IO_ERR_LOG_INDEX_READ 1374
#define ER_BINLOG_PURGE_PROHIBITED 1375
#define ER_FSEEK_FAIL 1376
#define ER_BINLOG_PURGE_FATAL_ERR 1377
#define ER_LOG_IN_USE 1378
#define ER_LOG_PURGE_UNKNOWN_ERR 1379
#define ER_RELAY_LOG_INIT 1380
#define ER_NO_BINARY_LOGGING 1381
#define ER_RESERVED_SYNTAX 1382
#define ER_WSAS_FAILED 1383
#define ER_DIFF_GROUPS_PROC 1384
#define ER_NO_GROUP_FOR_PROC 1385
#define ER_ORDER_WITH_PROC 1386
#define ER_LOGING_PROHIBIT_CHANGING_OF 1387
#define ER_NO_FILE_MAPPING 1388
#define ER_WRONG_MAGIC 1389
#define ER_ERROR_MESSAGES 390

View File

@ -203,3 +203,4 @@ ER_SP_CURSOR_AFTER_HANDLER, "42000", "",
ER_SP_CASE_NOT_FOUND, "20000", "",
ER_DIVISION_BY_ZERO, "22012", "",
ER_ILLEGAL_VALUE_FOR_TYPE, "22007", "",
ER_SP_ACCESS_DENIED_ERROR, "42000", "",

View File

@ -435,8 +435,8 @@ btr_search_update_hash_ref(
ha_insert_for_fold(btr_search_sys->hash_index, fold, rec);
}
}
}
/*************************************************************************
Updates the search info. */
@ -915,17 +915,6 @@ btr_search_drop_page_hash_index(
{
hash_table_t* table;
buf_block_t* block;
ulint n_fields;
ulint n_bytes;
rec_t* rec;
rec_t* sup;
ulint fold;
ulint prev_fold;
dulint tree_id;
ulint n_cached;
ulint n_recs;
ulint* folds;
ulint i;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
@ -951,72 +940,17 @@ btr_search_drop_page_hash_index(
|| (block->buf_fix_count == 0));
#endif /* UNIV_SYNC_DEBUG */
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
ut_a(n_fields + n_bytes > 0);
ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
rw_lock_s_unlock(&btr_search_latch);
n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion
from the hash index */
folds = mem_alloc(n_recs * sizeof(ulint));
n_cached = 0;
sup = page_get_supremum_rec(page);
rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec);
if (rec != sup) {
ut_a(n_fields <= rec_get_n_fields(rec));
if (n_bytes > 0) {
ut_a(n_fields < rec_get_n_fields(rec));
}
}
tree_id = btr_page_get_index_id(page);
prev_fold = 0;
while (rec != sup) {
/* FIXME: in a mixed tree, not all records may have enough
ordering fields: */
fold = rec_fold(rec, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) {
goto next_rec;
}
/* Remove all hash nodes pointing to this page from the
hash chain */
folds[n_cached] = fold;
n_cached++;
next_rec:
rec = page_rec_get_next(rec);
prev_fold = fold;
}
rw_lock_x_lock(&btr_search_latch);
for (i = 0; i < n_cached; i++) {
ha_remove_all_nodes_to_page(table, folds[i], page);
}
ha_remove_all_nodes_to_page(table, page);
block->is_hashed = FALSE;
rw_lock_x_unlock(&btr_search_latch);
mem_free(folds);
}
/************************************************************************

View File

@ -465,6 +465,7 @@ buf_block_init(
block->in_LRU_list = FALSE;
block->n_pointers = 0;
block->hash_nodes = NULL;
rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock)));

View File

@ -789,6 +789,7 @@ buf_LRU_block_free_non_file_page(
|| (block->state == BUF_BLOCK_READY_FOR_USE));
ut_a(block->n_pointers == 0);
ut_a(block->hash_nodes == NULL);
ut_a(!block->in_free_list);
block->state = BUF_BLOCK_NOT_USED;

View File

@ -65,10 +65,53 @@ ha_create(
return(table);
}
/*****************************************************************
Removes an adaptive hash index node from the doubly linked list of hash nodes
for the buffer block. */
UNIV_INLINE
void
ha_remove_buf_block_node(
/*=====================*/
buf_block_t* block, /* in: buffer block */
ha_node_t* node) /* in: an adaptive hash index node */
{
if (node == block->hash_nodes) {
block->hash_nodes = node->next_for_block;
}
if (node->prev_for_block != NULL) {
(node->prev_for_block)->next_for_block = node->next_for_block;
}
if (node->next_for_block != NULL) {
(node->next_for_block)->prev_for_block = node->prev_for_block;
}
}
/*****************************************************************
Adds an adaptive hash index node to the start of the doubly linked list of
hash nodes for the buffer block. */
UNIV_INLINE
void
ha_add_buf_block_node(
/*==================*/
buf_block_t* block, /* in: buffer block */
ha_node_t* node) /* in: an adaptive hash index node */
{
node->next_for_block = block->hash_nodes;
node->prev_for_block = NULL;
block->hash_nodes = node;
if (node->next_for_block != NULL) {
(node->next_for_block)->prev_for_block = node;
}
}
/*****************************************************************
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
is inserted. */
is inserted. This function is only used in the adaptive hash index. */
ibool
ha_insert_for_fold(
@ -84,6 +127,7 @@ ha_insert_for_fold(
{
hash_cell_t* cell;
ha_node_t* node;
buf_block_t* block;
ha_node_t* prev_node;
buf_block_t* prev_block;
ulint hash;
@ -92,6 +136,9 @@ ha_insert_for_fold(
#ifdef UNIV_SYNC_DEBUG
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
#endif /* UNIV_SYNC_DEBUG */
block = buf_block_align(data);
hash = hash_calc_hash(fold, table);
cell = hash_get_nth_cell(table, hash);
@ -104,7 +151,15 @@ ha_insert_for_fold(
prev_block = buf_block_align(prev_node->data);
ut_a(prev_block->n_pointers > 0);
prev_block->n_pointers--;
buf_block_align(data)->n_pointers++;
block->n_pointers++;
if (prev_block != block) {
ha_remove_buf_block_node(prev_block,
prev_node);
ha_add_buf_block_node(block,
prev_node);
}
}
prev_node->data = data;
@ -131,7 +186,9 @@ ha_insert_for_fold(
ha_node_set_data(node, data);
if (table->adaptive) {
buf_block_align(data)->n_pointers++;
block->n_pointers++;
ha_add_buf_block_node(block, node);
}
node->fold = fold;
@ -166,9 +223,15 @@ ha_delete_hash_node(
hash_table_t* table, /* in: hash table */
ha_node_t* del_node) /* in: node to be deleted */
{
buf_block_t* block;
if (table->adaptive) {
ut_a(buf_block_align(del_node->data)->n_pointers > 0);
buf_block_align(del_node->data)->n_pointers--;
block = buf_block_align(del_node->data);
ut_a(block->n_pointers > 0);
block->n_pointers--;
ha_remove_buf_block_node(block, del_node);
}
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
@ -209,6 +272,8 @@ ha_search_and_update_if_found(
void* data, /* in: pointer to the data */
void* new_data)/* in: new pointer to the data */
{
buf_block_t* old_block;
buf_block_t* block;
ha_node_t* node;
#ifdef UNIV_SYNC_DEBUG
@ -220,8 +285,15 @@ ha_search_and_update_if_found(
if (node) {
if (table->adaptive) {
ut_a(buf_block_align(node->data)->n_pointers > 0);
buf_block_align(node->data)->n_pointers--;
buf_block_align(new_data)->n_pointers++;
old_block = buf_block_align(node->data);
ut_a(old_block->n_pointers > 0);
old_block->n_pointers--;
ha_remove_buf_block_node(old_block, node);
block = buf_block_align(new_data);
block->n_pointers++;
ha_add_buf_block_node(block, node);
}
node->data = new_data;
@ -236,43 +308,25 @@ void
ha_remove_all_nodes_to_page(
/*========================*/
hash_table_t* table, /* in: hash table */
ulint fold, /* in: fold value */
page_t* page) /* in: buffer page */
{
buf_block_t* block;
ha_node_t* node;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
#endif /* UNIV_SYNC_DEBUG */
node = ha_chain_get_first(table, fold);
block = buf_block_align(page);
node = block->hash_nodes;
while (node) {
if (buf_frame_align(ha_node_get_data(node)) == page) {
/* Remove the hash node */
/* Remove the hash node */
ha_delete_hash_node(table, node);
ha_delete_hash_node(table, node);
/* Start again from the first node in the chain
because the deletion may compact the heap of
nodes and move other nodes! */
node = ha_chain_get_first(table, fold);
} else {
node = ha_chain_get_next(node);
}
node = block->hash_nodes;
}
#ifdef UNIV_DEBUG
/* Check that all nodes really got deleted */
node = ha_chain_get_first(table, fold);
while (node) {
ut_a(buf_frame_align(ha_node_get_data(node)) != page);
node = ha_chain_get_next(node);
}
#endif
ut_a(block->n_pointers == 0);
ut_a(block->hash_nodes == NULL);
}
/*****************************************************************
@ -352,6 +406,7 @@ ha_print_info(
n_bufs++;
}
fprintf(file, ", node heap has %lu buffer(s)\n", (ulong) n_bufs);
fprintf(file, ", node heap has %lu buffer(s)\n",
(ulong) n_bufs);
}
}

View File

@ -29,6 +29,7 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0types.h"
#include "sync0rw.h"
#include "hash0hash.h"
#include "ha0ha.h"
#include "ut0byte.h"
#include "os0proc.h"
@ -817,7 +818,7 @@ struct buf_block_struct{
records with the same prefix should be
indexed in the hash index */
/* The following 4 fields are protected by btr_search_latch: */
/* The following 6 fields are protected by btr_search_latch: */
ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does
@ -834,6 +835,11 @@ struct buf_block_struct{
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
BTR_SEARCH_RIGHT_SIDE in hash
indexing */
ha_node_t* hash_nodes; /* a doubly linked list of hash nodes
for this buffer block; this points to
the first node in the list if any;
note that we do not use UT_LST_ macros
to manipulate this list */
/* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread

View File

@ -54,7 +54,7 @@ ha_create(
/*****************************************************************
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
is inserted. */
is inserted. This function is only used in the adaptive hash index. */
ibool
ha_insert_for_fold(
@ -111,7 +111,6 @@ void
ha_remove_all_nodes_to_page(
/*========================*/
hash_table_t* table, /* in: hash table */
ulint fold, /* in: fold value */
page_t* page); /* in: buffer page */
/*****************************************************************
Validates a hash table. */
@ -134,9 +133,18 @@ ha_print_info(
typedef struct ha_node_struct ha_node_t;
struct ha_node_struct {
ha_node_t* next; /* next chain node or NULL if none */
void* data; /* pointer to the data */
ulint fold; /* fold value for the data */
ha_node_t* next; /* next chain node; NULL if none */
void* data; /* pointer to the data */
ulint fold; /* fold value for the data */
ha_node_t* next_for_block;/* in an adaptive hash index
(btr0sea.c), a doubly linked list of hash
nodes for the buffer block; these nodes
contain pointers to index records on the
page; in the last node this field is NULL;
note that we do not use UT_LST_ macros
to manipulate this list */
ha_node_t* prev_for_block;/* pointer to the previous node; in the
first node NULL */
};
#ifndef UNIV_NONINL

View File

@ -166,7 +166,7 @@ hash_get_n_cells(
/***********************************************************************
Deletes a struct which is stored in the heap of the hash table, and compacts
the heap. The fold value must be stored in the struct NODE in a field named
'fold'. */
'fold'. This macro is only used for the adaptive hash index. */
#define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE)\
do {\
@ -191,11 +191,23 @@ do {\
/* Copy the top node in place of NODE */\
\
*(NODE) = *top_node111;\
\
/* Update the adaptive hash list of the buffer block that\
corresponds to the top node */\
if (top_node111->next_for_block != NULL) {\
(top_node111->next_for_block)->prev_for_block = NODE;\
}\
\
if (top_node111->prev_for_block != NULL) {\
(top_node111->prev_for_block)->next_for_block = NODE;\
} else {\
buf_block_align(top_node111->data)->hash_nodes = NODE;\
}\
\
/* Look for the hash pointer to the top node, to update it */\
\
cell111 = hash_get_nth_cell(TABLE,\
hash_calc_hash(top_node111->fold, TABLE));\
\
/* Look for the pointer to the top node, to update it */\
\
if (cell111->node == top_node111) {\
/* The top node is the first in the chain */\

View File

@ -395,9 +395,9 @@ select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2);
SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2)
abcdabc
select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2);
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index'
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substring_index'
select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2);
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index'
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substring_index'
select _latin1'B' between _latin1'a' and _latin1'c';
_latin1'B' between _latin1'a' and _latin1'c'
1
@ -638,7 +638,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")`
Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substring_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")`
SELECT lpad(12345, 5, "#");
lpad(12345, 5, "#")
12345

View File

@ -39,7 +39,7 @@ drop table t1;
set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10;
show variables like "%auto%";
Variable_name Value
auto_incrememt_increment 100
auto_increment_increment 100
auto_increment_offset 10
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
insert into t1 values (NULL),(5),(NULL);

View File

@ -115,14 +115,6 @@ foo: loop
set @x=2;
end loop bar|
ERROR 42000: End-label bar without match
create procedure foo(out x int)
begin
declare y int;
set x = y;
end|
Warnings:
Warning 1311 Referring to uninitialized variable y
drop procedure foo|
create procedure foo()
return 42|
ERROR 42000: RETURN is only allowed in a FUNCTION
@ -235,9 +227,6 @@ ERROR 24000: Cursor is not open
drop procedure p|
alter procedure bar3 sql security invoker|
ERROR 42000: PROCEDURE test.bar3 does not exist
alter procedure bar3 name
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
ERROR 42000: Identifier name 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' is too long
drop table t1|
drop table if exists t1|
create table t1 (val int, x float)|

View File

@ -107,13 +107,20 @@ s1
0
2
2
alter procedure p modifies sql data;
drop procedure p;
alter procedure q modifies sql data;
ERROR 42000: Access denied; you are not the procedure/function definer of 'db2.q'
drop procedure q;
ERROR 42000: Access denied; you are not the procedure/function definer of 'db2.q'
use db2;
alter procedure q modifies sql data;
drop procedure q;
use test;
select type,db,name from mysql.proc;
type db name
FUNCTION db1_secret db
PROCEDURE db1_secret stamp
PROCEDURE db2 p
PROCEDURE db2 q
drop database db1_secret;
drop database db2;
select type,db,name from mysql.proc;

View File

@ -893,15 +893,15 @@ select * from t1|
id data
chistics 1
delete from t1|
alter procedure chistics sql security invoker name chistics2|
show create procedure chistics2|
alter procedure chistics sql security invoker|
show create procedure chistics|
Procedure sql_mode Create Procedure
chistics2 CREATE PROCEDURE `test`.`chistics2`()
chistics CREATE PROCEDURE `test`.`chistics`()
MODIFIES SQL DATA
SQL SECURITY INVOKER
COMMENT 'Characteristics procedure test'
insert into t1 values ("chistics", 1)
drop procedure chistics2|
drop procedure chistics|
create function chistics() returns int
language sql
deterministic
@ -918,18 +918,18 @@ return 42
select chistics()|
chistics()
42
alter function chistics name chistics2
alter function chistics
no sql
comment 'Characteristics function test'|
show create function chistics2|
show create function chistics|
Function sql_mode Create Function
chistics2 CREATE FUNCTION `test`.`chistics2`() RETURNS int
chistics CREATE FUNCTION `test`.`chistics`() RETURNS int
NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
COMMENT 'Characteristics function test'
return 42
drop function chistics2|
drop function chistics|
insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)|
set @@sql_mode = 'ANSI'|
create procedure modes(out c1 int, out c2 int)
@ -1853,13 +1853,9 @@ begin
declare v char;
return v;
end|
Warnings:
Warning 1311 Referring to uninitialized variable v
select bug4487()|
bug4487()
NULL
Warnings:
Warning 1311 Referring to uninitialized variable v
drop function bug4487|
drop procedure if exists bug4941|
create procedure bug4941(out x int)
@ -1948,6 +1944,39 @@ s1
1
drop procedure bug4905|
drop table t3|
drop function if exists bug6022|
create function bug6022(x int) returns int
begin
if x < 0 then
return 0;
else
return bug6022(x-1);
end if;
end|
select bug6022(5)|
bug6022(5)
0
drop function bug6022|
drop procedure if exists bug6029|
create procedure bug6029()
begin
declare exit handler for 1136 select '1136';
declare exit handler for sqlstate '23000' select 'sqlstate 23000';
declare continue handler for sqlexception select 'sqlexception';
insert into t3 values (1);
insert into t3 values (1,2);
end|
create table t3 (s1 int, primary key (s1))|
insert into t3 values (1)|
call bug6029()|
sqlstate 23000
sqlstate 23000
delete from t3|
call bug6029()|
1136
1136
drop procedure bug6029|
drop table t3|
drop table if exists fac|
create table fac (n int unsigned not null primary key, f bigint unsigned)|
create procedure ifac(n int unsigned)
@ -2146,8 +2175,8 @@ insert into test.t1 values (x, y)|
show procedure status like 'bar'|
Db Name Type Definer Modified Created Security_type Comment
test bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 INVOKER 111111111111
alter procedure bar name bar2 comment "2222222222" sql security definer|
alter procedure bar2 name bar comment "3333333333"|
alter procedure bar comment "2222222222" sql security definer|
alter procedure bar comment "3333333333"|
alter procedure bar|
show create procedure bar|
Procedure sql_mode Create Procedure

View File

@ -991,8 +991,6 @@ drop view v1;
create view v1 (a,a) as select 'a','a';
ERROR 42S21: Duplicate column name 'a'
create procedure p1 () begin declare v int; create view v1 as select v; end;//
Warnings:
Warning 1311 Referring to uninitialized variable v
call p1();
ERROR HY000: View's SELECT contains a variable or parameter
drop procedure p1;
@ -1467,7 +1465,7 @@ v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a`
alter algorithm=undefined view v1 as select * from t1 with check option;
show create view v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH LOCAL CHECK OPTION
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH CASCADED CHECK OPTION
alter algorithm=merge view v1 as select * from t1 with cascaded check option;
show create view v1;
View Create View
@ -1517,3 +1515,114 @@ s1
deallocate prepare stmt1;
drop view v2;
drop table t1, t2;
create table t1 (t time);
create view v1 as select substring_index(t,':',2) as t from t1;
insert into t1 (t) values ('12:24:10');
select substring_index(t,':',2) from t1;
substring_index(t,':',2)
12:24
select substring_index(t,':',2) from v1;
substring_index(t,':',2)
12:24
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0 with local check option;
create view v2 as select * from v1 with cascaded check option;
insert into v2 values (0);
ERROR HY000: CHECK OPTION failed 'test.v2'
drop view v2, v1;
drop table t1;
create table t1 (s1 int);
create view v1 as select * from t1 where s1 < 5 with check option;
insert ignore into v1 values (6);
ERROR HY000: CHECK OPTION failed 'test.v1'
insert ignore into v1 values (6),(3);
Warnings:
Error 1369 CHECK OPTION failed 'test.v1'
select * from t1;
s1
3
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create trigger t1_bi before insert on t1 for each row set new.s1 = 500;
create view v1 as select * from t1 where s1 <> 127 with check option;
insert into v1 values (0);
ERROR HY000: CHECK OPTION failed 'test.v1'
select * from v1;
s1
select * from t1;
s1
drop trigger t1.t1_bi;
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0;
create view v2 as select * from v1 where s1 <> 1 with cascaded check option;
insert into v2 values (0);
ERROR HY000: CHECK OPTION failed 'test.v2'
select * from v2;
s1
select * from t1;
s1
drop view v2, v1;
drop table t1;
create table t1 (a int, b char(10));
create view v1 as select * from t1 where a != 0 with check option;
load data infile '../../std_data/loaddata3.dat' into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
ERROR HY000: CHECK OPTION failed 'test.v1'
select * from t1;
a b
1 row 1
2 row 2
select * from v1;
a b
1 row 1
2 row 2
delete from t1;
load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 3
Error 1369 CHECK OPTION failed 'test.v1'
Warning 1264 Out of range value adjusted for column 'a' at row 4
Error 1369 CHECK OPTION failed 'test.v1'
select * from t1;
a b
1 row 1
2 row 2
3 row 3
select * from v1;
a b
1 row 1
2 row 2
3 row 3
drop view v1;
drop table t1;
create table t1 (a text, b text);
create view v1 as select * from t1 where a <> 'Field A' with check option;
load data infile '../../std_data/loaddata2.dat' into table v1 fields terminated by ',' enclosed by '''';
ERROR HY000: CHECK OPTION failed 'test.v1'
select concat('|',a,'|'), concat('|',b,'|') from t1;
concat('|',a,'|') concat('|',b,'|')
select concat('|',a,'|'), concat('|',b,'|') from v1;
concat('|',a,'|') concat('|',b,'|')
delete from t1;
load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by '''';
Warnings:
Error 1369 CHECK OPTION failed 'test.v1'
Warning 1261 Row 2 doesn't contain data for all columns
select concat('|',a,'|'), concat('|',b,'|') from t1;
concat('|',a,'|') concat('|',b,'|')
|Field 1| |Field 2'
Field 3,'Field 4|
|Field 5' ,'Field 6| NULL
|Field 6| | 'Field 7'|
select concat('|',a,'|'), concat('|',b,'|') from v1;
concat('|',a,'|') concat('|',b,'|')
|Field 1| |Field 2'
Field 3,'Field 4|
|Field 5' ,'Field 6| NULL
|Field 6| | 'Field 7'|
drop view v1;
drop table t1;

View File

@ -156,14 +156,6 @@ foo: loop
set @x=2;
end loop bar|
# Referring to undef variable
create procedure foo(out x int)
begin
declare y int;
set x = y;
end|
drop procedure foo|
# RETURN in FUNCTION only
--error 1313
create procedure foo()
@ -307,9 +299,6 @@ drop procedure p|
--error 1305
alter procedure bar3 sql security invoker|
--error 1059
alter procedure bar3 name
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
drop table t1|

View File

@ -180,8 +180,32 @@ use db2;
call q();
select * from t2;
# Clean up
#
# BUG#6030: Stored procedure has no appropriate DROP privilege
# (or ALTER for that matter)
# still connection con2user1 in db2
# This should work:
alter procedure p modifies sql data;
drop procedure p;
# This should NOT work
--error 1370
alter procedure q modifies sql data;
--error 1370
drop procedure q;
connection con1root;
use db2;
# But root always can
alter procedure q modifies sql data;
drop procedure q;
# Clean up
#Still connection con1root;
use test;
select type,db,name from mysql.proc;
drop database db1_secret;

View File

@ -990,9 +990,9 @@ show create procedure chistics|
call chistics()|
select * from t1|
delete from t1|
alter procedure chistics sql security invoker name chistics2|
show create procedure chistics2|
drop procedure chistics2|
alter procedure chistics sql security invoker|
show create procedure chistics|
drop procedure chistics|
create function chistics() returns int
language sql
@ -1004,11 +1004,11 @@ create function chistics() returns int
show create function chistics|
# Call it, just to make sure.
select chistics()|
alter function chistics name chistics2
alter function chistics
no sql
comment 'Characteristics function test'|
show create function chistics2|
drop function chistics2|
show create function chistics|
drop function chistics|
# Check mode settings
@ -2105,6 +2105,51 @@ select * from t3|
drop procedure bug4905|
drop table t3|
#
# BUG#6022: Stored procedure shutdown problem with self-calling function.
#
--disable_warnings
drop function if exists bug6022|
--enable_warnings
create function bug6022(x int) returns int
begin
if x < 0 then
return 0;
else
return bug6022(x-1);
end if;
end|
select bug6022(5)|
drop function bug6022|
#
# BUG#6029: Stored procedure specific handlers should have priority
#
--disable_warnings
drop procedure if exists bug6029|
--enable_warnings
create procedure bug6029()
begin
declare exit handler for 1136 select '1136';
declare exit handler for sqlstate '23000' select 'sqlstate 23000';
declare continue handler for sqlexception select 'sqlexception';
insert into t3 values (1);
insert into t3 values (1,2);
end|
create table t3 (s1 int, primary key (s1))|
insert into t3 values (1)|
call bug6029()|
delete from t3|
call bug6029()|
drop procedure bug6029|
drop table t3|
#
# Some "real" examples
@ -2283,8 +2328,8 @@ create procedure bar(x char(16), y int)
insert into test.t1 values (x, y)|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like 'bar'|
alter procedure bar name bar2 comment "2222222222" sql security definer|
alter procedure bar2 name bar comment "3333333333"|
alter procedure bar comment "2222222222" sql security definer|
alter procedure bar comment "3333333333"|
alter procedure bar|
show create procedure bar|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'

View File

@ -1460,3 +1460,97 @@ execute stmt1;
deallocate prepare stmt1;
drop view v2;
drop table t1, t2;
#
# test of substring_index with view
#
create table t1 (t time);
create view v1 as select substring_index(t,':',2) as t from t1;
insert into t1 (t) values ('12:24:10');
select substring_index(t,':',2) from t1;
select substring_index(t,':',2) from v1;
drop view v1;
drop table t1;
#
# test of cascaded check option for whiew without WHERE clause
#
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0 with local check option;
create view v2 as select * from v1 with cascaded check option;
-- error 1369
insert into v2 values (0);
drop view v2, v1;
drop table t1;
#
# inserting single value with check option failed always get error
#
create table t1 (s1 int);
create view v1 as select * from t1 where s1 < 5 with check option;
#single value
-- error 1369
insert ignore into v1 values (6);
#several values
insert ignore into v1 values (6),(3);
select * from t1;
drop view v1;
drop table t1;
#
# changing value by trigger and CHECK OPTION
#
create table t1 (s1 tinyint);
create trigger t1_bi before insert on t1 for each row set new.s1 = 500;
create view v1 as select * from t1 where s1 <> 127 with check option;
-- error 1369
insert into v1 values (0);
select * from v1;
select * from t1;
drop trigger t1.t1_bi;
drop view v1;
drop table t1;
#
# CASCADED should be used for all underlaying VIEWs
#
create table t1 (s1 tinyint);
create view v1 as select * from t1 where s1 <> 0;
create view v2 as select * from v1 where s1 <> 1 with cascaded check option;
-- error 1369
insert into v2 values (0);
select * from v2;
select * from t1;
drop view v2, v1;
drop table t1;
#
# LOAD DATA with view and CHECK OPTION
#
# fixed length fields
create table t1 (a int, b char(10));
create view v1 as select * from t1 where a != 0 with check option;
-- error 1369
load data infile '../../std_data/loaddata3.dat' into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
select * from t1;
select * from v1;
delete from t1;
load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines;
select * from t1;
select * from v1;
drop view v1;
drop table t1;
# variable length fields
create table t1 (a text, b text);
create view v1 as select * from t1 where a <> 'Field A' with check option;
-- error 1369
load data infile '../../std_data/loaddata2.dat' into table v1 fields terminated by ',' enclosed by '''';
select concat('|',a,'|'), concat('|',b,'|') from t1;
select concat('|',a,'|'), concat('|',b,'|') from v1;
delete from t1;
load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by '''';
select concat('|',a,'|'), concat('|',b,'|') from t1;
select concat('|',a,'|'), concat('|',b,'|') from v1;
drop view v1;
drop table t1;

View File

@ -1004,12 +1004,12 @@ next_insert_id(ulonglong nr,struct system_variables *variables)
The next row will be given the id
next_insert_id(next_insert_id)
The idea is the generated auto_increment values are predicatable and
The idea is that generated auto_increment values are predictable and
independent of the column values in the table. This is needed to be
able to replicate into a table that alread has rows with a higher
able to replicate into a table that already has rows with a higher
auto-increment value than the one that is inserted.
After we have already generated an auto-increment number and the users
After we have already generated an auto-increment number and the user
inserts a column with a higher value than the last used one, we will
start counting from the inserted value.
@ -1035,7 +1035,7 @@ void handler::update_auto_increment()
{
/* Clear flag for next row */
table->auto_increment_field_not_null= FALSE;
/* Mark that we didn't generated a new value **/
/* Mark that we didn't generate a new value **/
auto_increment_column_changed=0;
/* Update next_insert_id if we have already generated a value */
@ -1076,7 +1076,7 @@ void handler::update_auto_increment()
/*
We can't set next_insert_id if the auto-increment key is not the
first key part, as there is no gurantee that the first parts will be in
first key part, as there is no guarantee that the first parts will be in
sequence
*/
if (!table->next_number_key_offset)

View File

@ -1081,7 +1081,7 @@ public:
{ return fields.head()->collation.collation; }
};
class COND_EQUAL
class COND_EQUAL: public Sql_alloc
{
public:
uint max_members; /* max number of members the current level

View File

@ -218,7 +218,7 @@ public:
Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr_index"; }
const char *func_name() const { return "substring_index"; }
};

View File

@ -2548,7 +2548,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
thd->net.pkt_nr = net->pkt_nr;
}
if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0,
TL_WRITE))
TL_WRITE, 0))
thd->query_error = 1;
if (thd->cuted_fields)
{

View File

@ -838,9 +838,10 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
bool eval_const_cond(COND *cond);
/* sql_load.cc */
bool mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates,
bool local_file,thr_lock_type lock_type);
bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates,
bool local_file, thr_lock_type lock_type,
bool ignore_check_option_errors);
int write_record(THD *thd, TABLE *table, COPY_INFO *info);
/* sql_manager.cc */

View File

@ -7564,6 +7564,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::init()
else
max_functions_it= NULL;
}
else
min_max_ranges.elements= 0;
return 0;
}
@ -7656,7 +7658,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
max_used_key_length= real_prefix_len;
if (min_max_ranges.elements > 0)
{
QUICK_RANGE *cur_range;
QUICK_RANGE *cur_range= 0;
if (have_min)
{ /* Check if the right-most range has a lower boundary. */
get_dynamic(&min_max_ranges, (gptr)&cur_range,

View File

@ -632,7 +632,7 @@ sys_var *sys_variables[]=
*/
struct show_var_st init_vars[]= {
{"auto_incrememt_increment", (char*) &sys_auto_increment_increment, SHOW_SYS},
{"auto_increment_increment", (char*) &sys_auto_increment_increment, SHOW_SYS},
{"auto_increment_offset", (char*) &sys_auto_increment_offset, SHOW_SYS},
{"back_log", (char*) &back_log, SHOW_LONG},
{"basedir", mysql_home, SHOW_CHAR},

View File

@ -398,6 +398,7 @@ character-set=latin2
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -389,6 +389,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -398,6 +398,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -391,6 +391,7 @@ character-set=latin7
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -399,6 +399,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=greek
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -391,6 +391,7 @@ character-set=latin2
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -390,6 +390,7 @@ character-set=ujis
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=euckr
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -388,6 +388,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -388,6 +388,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -391,6 +391,7 @@ character-set=latin2
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -388,6 +388,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -391,6 +391,7 @@ character-set=latin2
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -391,6 +391,7 @@ character-set=koi8r
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION ÄÌÑ ÎÅÏÂÎÏ×ÌÑÅÍÏÇÏ VIEW '%-.64s.%-.64s'"
"ÐÒÏ×ÅÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÐÒÏ×ÁÌÉÌÁÓØ"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -379,6 +379,7 @@ character-set=cp1250
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -394,6 +394,7 @@ character-set=latin2
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -390,6 +390,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -386,6 +386,7 @@ character-set=latin1
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION on non-updatable view '%-.64s.%-.64s'"
"CHECK OPTION failed '%-.64s.%-.64s'"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -392,6 +392,7 @@ character-set=koi8u
"Illegal %s '%-.64s' value found during parsing",
"CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÝÏ ÎÅ ÍÏÖÅ ÂÕÔÉ ÏÎÏ×ÌÅÎÎÉÍ"
"ÐÅÒÅצÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÎÅ ÐÒÏÊÛÌÁ"
"Access denied; you are not the procedure/function definer of '%s'"
"Failed purging old relay logs: %s"
"Password hash should be a %d-digit hexadecimal number"
"Target log not found in binlog index"

View File

@ -442,9 +442,7 @@ db_drop_routine(THD *thd, int type, sp_name *name)
static int
db_update_routine(THD *thd, int type, sp_name *name,
char *newname, uint newnamelen,
st_sp_chistics *chistics)
db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
{
TABLE *table;
int ret;
@ -462,10 +460,6 @@ db_update_routine(THD *thd, int type, sp_name *name,
if (chistics->suid != SP_IS_DEFAULT_SUID)
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
store((longlong)chistics->suid);
if (newname)
table->field[MYSQL_PROC_FIELD_NAME]->store(newname,
newnamelen,
system_charset_info);
if (chistics->daccess != SP_DEFAULT_ACCESS)
table->field[MYSQL_PROC_FIELD_ACCESS]->
store((longlong)chistics->daccess);
@ -772,9 +766,7 @@ sp_drop_procedure(THD *thd, sp_name *name)
int
sp_update_procedure(THD *thd, sp_name *name,
char *newname, uint newnamelen,
st_sp_chistics *chistics)
sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
{
int ret;
bool found;
@ -782,8 +774,7 @@ sp_update_procedure(THD *thd, sp_name *name,
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_proc_cache, name);
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name,
newname, newnamelen, chistics);
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics);
if (!found && !ret)
sp_cache_invalidate();
DBUG_RETURN(ret);
@ -870,9 +861,7 @@ sp_drop_function(THD *thd, sp_name *name)
int
sp_update_function(THD *thd, sp_name *name,
char *newname, uint newnamelen,
st_sp_chistics *chistics)
sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics)
{
int ret;
bool found;
@ -880,8 +869,7 @@ sp_update_function(THD *thd, sp_name *name,
DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
found= sp_cache_remove(&thd->sp_func_cache, name);
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name,
newname, newnamelen, chistics);
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics);
if (!found && !ret)
sp_cache_invalidate();
DBUG_RETURN(ret);
@ -1002,12 +990,12 @@ sp_cache_functions(THD *thd, LEX *lex)
if (db_find_routine(thd, TYPE_ENUM_FUNCTION, &name, &sp)
== SP_OK)
{
sp_cache_insert(&thd->sp_func_cache, sp);
ret= sp_cache_functions(thd, newlex);
delete newlex;
thd->lex= oldlex;
if (ret)
break;
sp_cache_insert(&thd->sp_func_cache, sp);
}
else
{

View File

@ -44,9 +44,7 @@ sp_drop_procedure(THD *thd, sp_name *name);
int
sp_update_procedure(THD *thd, sp_name *name,
char *newname, uint newnamelen,
st_sp_chistics *chistics);
sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics);
int
sp_show_create_procedure(THD *thd, sp_name *name);
@ -64,9 +62,7 @@ int
sp_drop_function(THD *thd, sp_name *name);
int
sp_update_function(THD *thd, sp_name *name,
char *newname, uint newnamelen,
st_sp_chistics *chistics);
sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics);
int
sp_show_create_function(THD *thd, sp_name *name);

View File

@ -56,7 +56,7 @@ sp_rcontext::set_item_eval(uint idx, Item *i, enum_field_types type)
}
}
int
bool
sp_rcontext::find_handler(uint sql_errno,
MYSQL_ERROR::enum_warning_level level)
{
@ -66,9 +66,9 @@ sp_rcontext::find_handler(uint sql_errno,
return 1; // Already got one
const char *sqlstate= mysql_errno_to_sqlstate(sql_errno);
int i= m_hcount, found= 0;
int i= m_hcount, found= -1;
while (!found && i--)
while (i--)
{
sp_cond_type_t *cond= m_handler[i].cond;
@ -76,31 +76,36 @@ sp_rcontext::find_handler(uint sql_errno,
{
case sp_cond_type_t::number:
if (sql_errno == cond->mysqlerr)
found= 1;
found= i; // Always the most specific
break;
case sp_cond_type_t::state:
if (strcmp(sqlstate, cond->sqlstate) == 0)
found= 1;
if (strcmp(sqlstate, cond->sqlstate) == 0 &&
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::number))
found= i;
break;
case sp_cond_type_t::warning:
if (sqlstate[0] == '0' && sqlstate[1] == '1' ||
level == MYSQL_ERROR::WARN_LEVEL_WARN)
found= 1;
if ((sqlstate[0] == '0' && sqlstate[1] == '1' ||
level == MYSQL_ERROR::WARN_LEVEL_WARN) &&
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::state))
found= i;
break;
case sp_cond_type_t::notfound:
if (sqlstate[0] == '0' && sqlstate[1] == '2')
found= 1;
if (sqlstate[0] == '0' && sqlstate[1] == '2' &&
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::state))
found= i;
break;
case sp_cond_type_t::exception:
if (sqlstate[0] != '0' || sqlstate[1] > '2' ||
level == MYSQL_ERROR::WARN_LEVEL_ERROR)
found= 1;
if ((sqlstate[0] != '0' || sqlstate[1] > '2' ||
level == MYSQL_ERROR::WARN_LEVEL_ERROR) &&
(found < 0 || m_handler[found].cond->type > sp_cond_type_t::state))
found= i;
break;
}
}
if (found)
m_hfound= i;
return found;
if (found < 0)
return FALSE;
m_hfound= found;
return TRUE;
}
void

View File

@ -122,7 +122,7 @@ class sp_rcontext : public Sql_alloc
}
// Returns 1 if a handler was found, 0 otherwise.
int
bool
find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level);
// Returns handler type and sets *ip to location if one was found

View File

@ -2696,7 +2696,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds)
table->keys_in_use_for_query.subtract(map);
}
table->used_keys.intersect(table->keys_in_use_for_query);
if (table_list->ancestor && table_list->setup_ancestor(thd, conds))
if (table_list->ancestor &&
table_list->setup_ancestor(thd, conds,
table_list->effective_with_check))
DBUG_RETURN(1);
}
if (tablenr > MAX_TABLES)

View File

@ -331,14 +331,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
break;
}
}
if ((res= table_list->view_check_option(thd, ignore_err)) ==
VIEW_CHECK_SKIP)
continue;
else if (res == VIEW_CHECK_ERROR)
{
error= 1;
break;
}
/*
FIXME: Actually we should do this before
@ -348,6 +340,17 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_BEFORE);
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
0 :
ignore_err))) ==
VIEW_CHECK_SKIP)
continue;
else if (res == VIEW_CHECK_ERROR)
{
error= 1;
break;
}
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
{

View File

@ -1616,6 +1616,7 @@ bool st_lex::can_use_merged()
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_LOAD:
return TRUE;
default:
return FALSE;

View File

@ -71,16 +71,19 @@ public:
void set_io_cache_arg(void* arg) { cache.arg = arg; }
};
static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
ulong skip_lines);
static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
ulong skip_lines,
bool ignore_check_option_errors);
static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
String &enclosed, ulong skip_lines);
String &enclosed, ulong skip_lines,
bool ignore_check_option_errors);
bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates,
bool read_file_from_client,thr_lock_type lock_type)
bool read_file_from_client,thr_lock_type lock_type,
bool ignore_check_option_errors)
{
char name[FN_REFLEN];
File file;
@ -88,6 +91,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
int error;
String *field_term=ex->field_term,*escaped=ex->escaped;
String *enclosed=ex->enclosed;
Item *unused_conds;
bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info;
@ -117,8 +121,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table_list->lock_type= lock_type;
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
/* TODO: add key check when we will support VIEWs in LOAD */
if (!table_list->updatable)
if (setup_tables(thd, table_list, &unused_conds))
DBUG_RETURN(-1);
if (!table_list->updatable || check_key_in_view(thd, table_list))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
DBUG_RETURN(TRUE);
@ -294,11 +299,12 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MODE_STRICT_ALL_TABLES)));
if (!field_term->length() && !enclosed->length())
error=read_fixed_length(thd,info,table,fields,read_info,
skip_lines);
error= read_fixed_length(thd, info, table_list, fields,read_info,
skip_lines, ignore_check_option_errors);
else
error=read_sep_field(thd,info,table,fields,read_info,*enclosed,
skip_lines);
error= read_sep_field(thd, info, table_list, fields, read_info,
*enclosed, skip_lines,
ignore_check_option_errors);
if (table->file->end_bulk_insert())
error=1; /* purecov: inspected */
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@ -401,11 +407,13 @@ err:
****************************************************************************/
static int
read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
READ_INFO &read_info, ulong skip_lines)
read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info, ulong skip_lines,
bool ignore_check_option_errors)
{
List_iterator_fast<Item> it(fields);
Item_field *sql_field;
TABLE *table= table_list->table;
ulonglong id;
bool no_trans_update;
DBUG_ENTER("read_fixed_length");
@ -472,6 +480,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER_WARN_TOO_MANY_RECORDS,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
}
switch(table_list->view_check_option(thd,
ignore_check_option_errors))
{
case VIEW_CHECK_SKIP:
read_info.next_line();
goto continue_loop;
case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
if (thd->killed || write_record(thd,table,&info))
DBUG_RETURN(1);
thd->no_trans_update= no_trans_update;
@ -496,6 +515,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
}
thd->row_count++;
continue_loop:;
}
if (id && !read_info.error)
thd->insert_id(id); // For binary/update log
@ -505,12 +525,14 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
static int
read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
String &enclosed, ulong skip_lines)
String &enclosed, ulong skip_lines,
bool ignore_check_option_errors)
{
List_iterator_fast<Item> it(fields);
Item_field *sql_field;
TABLE *table= table_list->table;
uint enclosed_length;
ulonglong id;
bool no_trans_update;
@ -580,6 +602,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
}
}
switch(table_list->view_check_option(thd,
ignore_check_option_errors))
{
case VIEW_CHECK_SKIP:
read_info.next_line();
goto continue_loop;
case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
if (thd->killed || write_record(thd, table, &info))
DBUG_RETURN(1);
/*
@ -605,6 +639,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
DBUG_RETURN(1);
}
thd->row_count++;
continue_loop:;
}
if (id && !read_info.error)
thd->insert_id(id); // For binary/update log

View File

@ -69,6 +69,7 @@ static void remove_escape(char *name);
static void refresh_status(void);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
static bool check_sp_definer_access(THD *thd, sp_head *sp);
const char *any_db="*any*"; // Special symbol for check_access
@ -3110,7 +3111,8 @@ create_error:
goto error;
}
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
lex->duplicates, (bool) lex->local_file, lex->lock_option);
lex->duplicates, (bool) lex->local_file,
lex->lock_option, lex->duplicates == DUP_IGNORE);
break;
}
@ -3722,21 +3724,27 @@ create_error:
case SQLCOM_ALTER_FUNCTION:
{
int result;
uint newname_len= 0;
if (lex->name)
newname_len= strlen(lex->name);
if (newname_len > NAME_LEN)
{
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->name);
goto error;
}
sp_head *sp;
st_sp_chistics chistics;
memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname,
lex->name, newname_len, &lex->sp_chistics);
sp= sp_find_procedure(thd, lex->spname);
else
result= sp_update_function(thd, lex->spname,
lex->name, newname_len, &lex->sp_chistics);
res= result;
sp= sp_find_function(thd, lex->spname);
mysql_reset_errors(thd);
if (! sp)
result= SP_KEY_NOT_FOUND;
else
{
if (check_sp_definer_access(thd, sp))
goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
}
switch (result)
{
case SP_OK:
@ -3756,29 +3764,43 @@ create_error:
case SQLCOM_DROP_PROCEDURE:
case SQLCOM_DROP_FUNCTION:
{
sp_head *sp;
int result;
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
result= sp_drop_procedure(thd, lex->spname);
sp= sp_find_procedure(thd, lex->spname);
else
sp= sp_find_function(thd, lex->spname);
mysql_reset_errors(thd);
if (! sp)
result= SP_KEY_NOT_FOUND;
else
{
result= sp_drop_function(thd, lex->spname);
#ifdef HAVE_DLOPEN
if (result == SP_KEY_NOT_FOUND)
if (check_sp_definer_access(thd, sp))
goto error;
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
result= sp_drop_procedure(thd, lex->spname);
else
{
udf_func *udf = find_udf(lex->spname->m_name.str,
lex->spname->m_name.length);
if (udf)
result= sp_drop_function(thd, lex->spname);
#ifdef HAVE_DLOPEN
if (result == SP_KEY_NOT_FOUND)
{
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
goto error;
if (!(result = mysql_drop_function(thd,&lex->spname->m_name)))
udf_func *udf = find_udf(lex->spname->m_name.str,
lex->spname->m_name.length);
if (udf)
{
send_ok(thd);
break;
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
goto error;
if (!(res = mysql_drop_function(thd,&lex->spname->m_name)))
{
send_ok(thd);
break;
}
}
}
}
#endif
}
}
res= result;
switch (result)
@ -4220,6 +4242,41 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables)
return FALSE;
}
/*
Check if the given SP is owned by thd->priv_user/host, or priv_user is root.
QQ This is not quite complete, but it will do as a basic security check
for now. The question is exactly which rights should 'root' have?
Should root have access regardless of host for instance?
SYNOPSIS
check_sp_definer_access()
thd Thread handler
sp The SP pointer
RETURN
0 ok
1 error Error message has been sent
*/
static bool
check_sp_definer_access(THD *thd, sp_head *sp)
{
LEX_STRING *usr, *hst;
if (strcmp("root", thd->priv_user) == 0)
return FALSE; /* QQ Any root is ok now */
usr= &sp->m_definer_user;
hst= &sp->m_definer_host;
if (strncmp(thd->priv_user, usr->str, usr->length) == 0 &&
strncmp(thd->priv_host, hst->str, hst->length) == 0)
return FALSE; /* Both user and host must match */
my_error(ER_SP_ACCESS_DENIED_ERROR, MYF(0), sp->m_qname.str);
return TRUE; /* Not definer or root */
}
/****************************************************************************
Check stack size; Send error if there isn't enough stack to continue
****************************************************************************/

View File

@ -789,7 +789,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_extended_describe
prepare prepare_src execute deallocate
statement sp_suid opt_view_list view_list or_replace algorithm
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic sp_a_chistic
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmt
@ -1371,7 +1371,7 @@ create_function_tail:
sp_a_chistics:
/* Empty */ {}
| sp_a_chistics sp_a_chistic {}
| sp_a_chistics sp_chistic {}
;
sp_c_chistics:
@ -1397,12 +1397,6 @@ sp_chistic:
{ }
;
/* Alter characteristics */
sp_a_chistic:
sp_chistic { }
| NAME_SYM ident { Lex->name= $2.str; }
;
/* Create characteristics */
sp_c_chistic:
sp_chistic { }
@ -3197,7 +3191,6 @@ alter:
LEX *lex= Lex;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->name= 0;
}
sp_a_chistics
{
@ -3212,7 +3205,6 @@ alter:
LEX *lex= Lex;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->name= 0;
}
sp_a_chistics
{
@ -6500,12 +6492,6 @@ simple_ident:
if (spc && (spv = spc->find_pvar(&$1)))
{ /* We're compiling a stored procedure and found a variable */
if (lex->sql_command != SQLCOM_CALL && ! spv->isset)
{
push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SP_UNINIT_VAR, ER(ER_SP_UNINIT_VAR),
$1.str);
}
$$ = (Item*) new Item_splocal($1, spv->offset);
lex->variables_used= 1;
lex->safe_to_cache_query=0;
@ -7917,7 +7903,7 @@ check_option:
/* empty */
{ Lex->create_view_check= VIEW_CHECK_NONE; }
| WITH CHECK_SYM OPTION
{ Lex->create_view_check= VIEW_CHECK_LOCAL; }
{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
| WITH CASCADED CHECK_SYM OPTION
{ Lex->create_view_check= VIEW_CHECK_CASCADED; }
| WITH LOCAL_SYM CHECK_SYM OPTION

View File

@ -1497,8 +1497,10 @@ void st_table_list::set_ancestor()
SYNOPSIS
st_table_list::setup_ancestor()
thd - thread handler
conds - condition of this JOIN
thd - thread handler
conds - condition of this JOIN
check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
DESCRIPTION
It is:
@ -1513,7 +1515,8 @@ void st_table_list::set_ancestor()
1 - error
*/
bool st_table_list::setup_ancestor(THD *thd, Item **conds)
bool st_table_list::setup_ancestor(THD *thd, Item **conds,
uint8 check_opt_type)
{
Item **transl;
SELECT_LEX *select= &view->select_lex;
@ -1527,7 +1530,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor &&
ancestor->setup_ancestor(thd, conds))
ancestor->setup_ancestor(thd, conds,
(check_opt_type == VIEW_CHECK_CASCADED ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
DBUG_RETURN(1);
if (field_translation)
@ -1586,23 +1592,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
field_translation= transl;
/* TODO: sort this list? Use hash for big number of fields */
if (where)
if (where ||
(check_opt_type == VIEW_CHECK_CASCADED &&
ancestor->check_option))
{
Item_arena *arena= thd->current_arena, backup;
TABLE_LIST *tbl= this;
if (arena->is_conventional())
arena= 0; // For easier test
if (!where->fixed && where->fix_fields(thd, ancestor, &where))
if (where && !where->fixed && where->fix_fields(thd, ancestor, &where))
goto err;
if (arena)
thd->set_n_backup_item_arena(arena, &backup);
if (effective_with_check)
if (check_opt_type)
{
check_option= where->copy_andor_structure(thd);
if (effective_with_check == VIEW_CHECK_CASCADED)
if (where)
check_option= where->copy_andor_structure(thd);
if (check_opt_type == VIEW_CHECK_CASCADED)
{
check_option= and_conds(check_option, ancestor->check_option);
}
@ -1612,7 +1621,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
check that it is not VIEW in which we insert with INSERT SELECT
(in this case we can't add view WHERE condition to main SELECT_LEX)
*/
if (!no_where_clause)
if (where && !no_where_clause)
{
/* Go up to join tree and try to find left join */
for (; tbl; tbl= tbl->embedding)

View File

@ -283,7 +283,7 @@ typedef struct st_table_list
void calc_md5(char *buffer);
void set_ancestor();
int view_check_option(THD *thd, bool ignore_failure);
bool setup_ancestor(THD *thd, Item **conds);
bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
bool placeholder() {return derived || view; }
void print(THD *thd, String *str);
inline st_table_list *next_independent()