mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Merge sinisa@work.mysql.com:/home/bk/mysql-4.1
into sinisa.nasamreza.org:/mnt/work/mysql-4.1
This commit is contained in:
commit
de74434a52
8 changed files with 145 additions and 19 deletions
|
@ -52,6 +52,14 @@ row_mysql_read_var_ref_noninline(
|
|||
ulint* len, /* out: variable-length field length */
|
||||
byte* field); /* in: field */
|
||||
/***********************************************************************
|
||||
Frees the blob heap in prebuilt when no longer needed. */
|
||||
|
||||
void
|
||||
row_mysql_prebuilt_free_blob_heap(
|
||||
/*==============================*/
|
||||
row_prebuilt_t* prebuilt); /* in: prebuilt struct of a
|
||||
ha_innobase:: table handle */
|
||||
/***********************************************************************
|
||||
Stores a reference to a BLOB in the MySQL format. */
|
||||
|
||||
void
|
||||
|
|
|
@ -115,7 +115,8 @@ row_search_for_mysql(
|
|||
/*=================*/
|
||||
/* out: DB_SUCCESS,
|
||||
DB_RECORD_NOT_FOUND,
|
||||
DB_END_OF_INDEX, or DB_DEADLOCK */
|
||||
DB_END_OF_INDEX, DB_DEADLOCK,
|
||||
or DB_TOO_BIG_RECORD */
|
||||
byte* buf, /* in/out: buffer for the fetched
|
||||
row in the MySQL format */
|
||||
ulint mode, /* in: search mode PAGE_CUR_L, ... */
|
||||
|
|
|
@ -50,6 +50,16 @@ ut_malloc(
|
|||
/* out, own: allocated memory */
|
||||
ulint n); /* in: number of bytes to allocate */
|
||||
/**************************************************************************
|
||||
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
|
||||
out. It cannot be used if we want to return an error message. Prints to
|
||||
stderr a message if fails. */
|
||||
|
||||
ibool
|
||||
ut_test_malloc(
|
||||
/*===========*/
|
||||
/* out: TRUE if succeeded */
|
||||
ulint n); /* in: try to allocate this many bytes */
|
||||
/**************************************************************************
|
||||
Frees a memory bloock allocated with ut_malloc. */
|
||||
|
||||
void
|
||||
|
|
|
@ -58,6 +58,19 @@ row_mysql_read_var_ref_noninline(
|
|||
return(row_mysql_read_var_ref(len, field));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Frees the blob heap in prebuilt when no longer needed. */
|
||||
|
||||
void
|
||||
row_mysql_prebuilt_free_blob_heap(
|
||||
/*==============================*/
|
||||
row_prebuilt_t* prebuilt) /* in: prebuilt struct of a
|
||||
ha_innobase:: table handle */
|
||||
{
|
||||
mem_heap_free(prebuilt->blob_heap);
|
||||
prebuilt->blob_heap = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Stores a reference to a BLOB in the MySQL format. */
|
||||
|
||||
|
|
|
@ -2039,9 +2039,12 @@ Note that the template in prebuilt may advise us to copy only a few
|
|||
columns to mysql_rec, other columns are left blank. All columns may not
|
||||
be needed in the query. */
|
||||
static
|
||||
void
|
||||
ibool
|
||||
row_sel_store_mysql_rec(
|
||||
/*====================*/
|
||||
/* out: TRUE if success, FALSE
|
||||
if could not allocate memory for a
|
||||
BLOB */
|
||||
byte* mysql_rec, /* out: row in the MySQL format */
|
||||
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
|
||||
rec_t* rec) /* in: Innobase record in the index
|
||||
|
@ -2092,7 +2095,19 @@ row_sel_store_mysql_rec(
|
|||
if (templ->type == DATA_BLOB) {
|
||||
|
||||
ut_a(prebuilt->templ_contains_blob);
|
||||
|
||||
|
||||
/* A heuristic test that we can allocate
|
||||
the memory for a big BLOB. We have a safety
|
||||
margin of 1000000 bytes. Since the test
|
||||
takes some CPU time, we do not use for small
|
||||
BLOBs. */
|
||||
|
||||
if (len > 2000000
|
||||
&& !ut_test_malloc(len + 1000000)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Copy the BLOB data to the BLOB
|
||||
heap of prebuilt */
|
||||
|
||||
|
@ -2142,6 +2157,8 @@ row_sel_store_mysql_rec(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -2526,7 +2543,8 @@ row_search_for_mysql(
|
|||
/*=================*/
|
||||
/* out: DB_SUCCESS,
|
||||
DB_RECORD_NOT_FOUND,
|
||||
DB_END_OF_INDEX, or DB_DEADLOCK */
|
||||
DB_END_OF_INDEX, DB_DEADLOCK,
|
||||
or DB_TOO_BIG_RECORD */
|
||||
byte* buf, /* in/out: buffer for the fetched
|
||||
row in the MySQL format */
|
||||
ulint mode, /* in: search mode PAGE_CUR_L, ... */
|
||||
|
@ -2758,7 +2776,12 @@ row_search_for_mysql(
|
|||
#ifdef UNIV_SEARCH_DEBUG
|
||||
ut_a(0 == cmp_dtuple_rec(search_tuple, rec));
|
||||
#endif
|
||||
row_sel_store_mysql_rec(buf, prebuilt, rec);
|
||||
if (!row_sel_store_mysql_rec(buf, prebuilt,
|
||||
rec)) {
|
||||
err = DB_TOO_BIG_RECORD;
|
||||
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
|
@ -3200,7 +3223,11 @@ rec_loop:
|
|||
rec_get_size(rec));
|
||||
mach_write_to_4(buf, rec_get_extra_size(rec) + 4);
|
||||
} else {
|
||||
row_sel_store_mysql_rec(buf, prebuilt, rec);
|
||||
if (!row_sel_store_mysql_rec(buf, prebuilt, rec)) {
|
||||
err = DB_TOO_BIG_RECORD;
|
||||
|
||||
goto lock_wait_or_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (prebuilt->clust_index_was_generated) {
|
||||
|
|
|
@ -77,8 +77,9 @@ ut_malloc_low(
|
|||
ret = malloc(n + sizeof(ut_mem_block_t));
|
||||
|
||||
if (ret == NULL) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Fatal error: cannot allocate %lu bytes of\n"
|
||||
" InnoDB: Fatal error: cannot allocate %lu bytes of\n"
|
||||
"InnoDB: memory with malloc! Total allocated memory\n"
|
||||
"InnoDB: by InnoDB %lu bytes. Operating system errno: %d\n"
|
||||
"InnoDB: Cannot continue operation!\n"
|
||||
|
@ -134,6 +135,40 @@ ut_malloc(
|
|||
return(ut_malloc_low(n, TRUE));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
|
||||
out. It cannot be used if we want to return an error message. Prints to
|
||||
stderr a message if fails. */
|
||||
|
||||
ibool
|
||||
ut_test_malloc(
|
||||
/*===========*/
|
||||
/* out: TRUE if succeeded */
|
||||
ulint n) /* in: try to allocate this many bytes */
|
||||
{
|
||||
void* ret;
|
||||
|
||||
ret = malloc(n);
|
||||
|
||||
if (ret == NULL) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: cannot allocate %lu bytes of memory for\n"
|
||||
"InnoDB: a BLOB with malloc! Total allocated memory\n"
|
||||
"InnoDB: by InnoDB %lu bytes. Operating system errno: %d\n"
|
||||
"InnoDB: Check if you should increase the swap file or\n"
|
||||
"InnoDB: ulimits of your operating system.\n"
|
||||
"InnoDB: On FreeBSD check you have compiled the OS with\n"
|
||||
"InnoDB: a big enough maximum process size.\n",
|
||||
n, ut_total_allocated_memory, errno);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
free(ret);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Frees a memory block allocated with ut_malloc. */
|
||||
|
||||
|
|
|
@ -1624,6 +1624,12 @@ build_template(
|
|||
}
|
||||
|
||||
if (prebuilt->select_lock_type == LOCK_X) {
|
||||
/* In versions < 3.23.50 we always retrieved the clustered
|
||||
index record if prebuilt->select_lock_type == LOCK_S,
|
||||
but there is really not need for that, and in some cases
|
||||
performance could be seriously degraded because the MySQL
|
||||
optimizer did not know about our convention! */
|
||||
|
||||
/* We always retrieve the whole clustered index record if we
|
||||
use exclusive row level locks, for example, if the read is
|
||||
done in an UPDATE statement. */
|
||||
|
@ -1632,12 +1638,6 @@ build_template(
|
|||
}
|
||||
|
||||
if (templ_type == ROW_MYSQL_REC_FIELDS) {
|
||||
/* In versions < 3.23.50 we always retrieved the clustered
|
||||
index record if prebuilt->select_lock_type == LOCK_S,
|
||||
but there is really not need for that, and in some cases
|
||||
performance could be seriously degraded because the MySQL
|
||||
optimizer did not know about our convention! */
|
||||
|
||||
index = prebuilt->index;
|
||||
} else {
|
||||
index = clust_index;
|
||||
|
@ -2506,11 +2506,13 @@ ha_innobase::change_active_index(
|
|||
dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
|
||||
prebuilt->index->n_fields);
|
||||
|
||||
/* Maybe MySQL changes the active index for a handle also
|
||||
during some queries, we do not know: then it is safest to build
|
||||
the template such that all columns will be fetched */
|
||||
/* MySQL changes the active index for a handle also during some
|
||||
queries, for example SELECT MAX(a), SUM(a) first retrieves the MAX()
|
||||
and then calculates te sum. Previously we played safe and used
|
||||
the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
|
||||
copying. Starting from MySQL-4.1 we use a more efficient flag here. */
|
||||
|
||||
build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
|
||||
build_template(prebuilt, user_thd, table, ROW_MYSQL_REC_FIELDS);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -3742,8 +3744,18 @@ ha_innobase::extra(
|
|||
obsolete! */
|
||||
|
||||
switch (operation) {
|
||||
case HA_EXTRA_FLUSH:
|
||||
if (prebuilt->blob_heap) {
|
||||
row_mysql_prebuilt_free_blob_heap(prebuilt);
|
||||
}
|
||||
break;
|
||||
case HA_EXTRA_RESET:
|
||||
case HA_EXTRA_RESET_STATE:
|
||||
if (prebuilt->blob_heap) {
|
||||
row_mysql_prebuilt_free_blob_heap(prebuilt);
|
||||
}
|
||||
prebuilt->read_just_key = 0;
|
||||
break;
|
||||
case HA_EXTRA_RESET_STATE:
|
||||
prebuilt->read_just_key = 0;
|
||||
break;
|
||||
case HA_EXTRA_NO_KEYREAD:
|
||||
|
|
|
@ -628,7 +628,7 @@ static bool parse_prepare_query(PREP_STMT *stmt,
|
|||
Initialize parameter items in statement
|
||||
*/
|
||||
|
||||
static bool init_param_items( PREP_STMT *stmt)
|
||||
static bool init_param_items(PREP_STMT *stmt)
|
||||
{
|
||||
List<Item> ¶ms= stmt->thd->lex.param_list;
|
||||
Item_param **to;
|
||||
|
@ -642,6 +642,24 @@ static bool init_param_items( PREP_STMT *stmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Initialize stmt execution
|
||||
*/
|
||||
|
||||
static void init_stmt_execute(PREP_STMT *stmt)
|
||||
{
|
||||
THD *thd= stmt->thd;
|
||||
TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select_lex.table_list.first;
|
||||
|
||||
/*
|
||||
TODO: When the new table structure is ready, then have a status bit
|
||||
to indicate the table is altered, and re-do the setup_*
|
||||
and open the tables back.
|
||||
*/
|
||||
if (tables)
|
||||
tables->table=0; //safety - nasty init
|
||||
}
|
||||
|
||||
/*
|
||||
Parse the query and send the total number of parameters
|
||||
and resultset metadata information back to client (if any),
|
||||
|
@ -722,6 +740,8 @@ void mysql_stmt_execute(THD *thd, char *packet)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
init_stmt_execute(stmt);
|
||||
|
||||
if (stmt->param_count && setup_params_data(stmt))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue