summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-12-03 15:20:57 +0400
committerAlexander Barkov <bar@mariadb.org>2015-12-03 15:20:57 +0400
commit8eefe57c91fd6ca43649af18949ebbb572ffc437 (patch)
treed0d41bf53f1a740d6c5f351d61c545a6204bd5e4 /sql/sp_head.cc
parentf3ff8b35299855b9e89696c73bcdd9945a4311fc (diff)
downloadmariadb-git-8eefe57c91fd6ca43649af18949ebbb572ffc437.tar.gz
Fixing DBUG_ASSERT() introduced in e3fed3b9b4f488e9ad1afa57333ae80249e6cb17
(a change adding a helper method Column_definition::make_field()) to take into account the EXECUTE stage of a prepared statement. This DBUG_ASSERT() caused crashes in a few tests when running "mtr --ps".
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc39
1 files changed, 38 insertions, 1 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0b95123c7d9..ce4ec09bede 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -845,7 +845,44 @@ sp_head::create_result_field(uint field_max_length, const char *field_name,
DBUG_ENTER("sp_head::create_result_field");
- DBUG_ASSERT(field_max_length <= m_return_field_def.length);
+ /*
+ m_return_field_def.length is always set to the field length calculated
+ by the parser, according to the RETURNS clause. See prepare_create_field()
+ in sql_table.cc. Value examples, depending on data type:
+ - 11 for INT (character representation length)
+ - 20 for BIGINT (character representation length)
+ - 22 for DOUBLE (character representation length)
+ - N for CHAR(N) CHARACTER SET latin1 (octet length)
+ - 3*N for CHAR(N) CHARACTER SET utf8 (octet length)
+ - 8 for blob-alike data types (packed length !!!)
+
+ field_max_length is also set according to the data type in the RETURNS
+ clause but can have different values depending on the execution stage:
+
+ 1. During direct execution:
+ field_max_length is 0, because Item_func_sp::fix_length_and_dec() has
+ not been called yet, so Item_func_sp::max_length is 0 by default.
+
+ 2a. During PREPARE:
+ field_max_length is 0, because Item_func_sp::fix_length_and_dec()
+ has not been called yet. It's called after create_result_field().
+
+ 2b. During EXEC:
+ field_max_length is set to the maximum possible octet length of the
+ RETURNS data type.
+ - N for CHAR(N) CHARACTER SET latin1 (octet length)
+ - 3*N for CHAR(N) CHARACTER SET utf8 (octet length)
+ - 255 for TINYBLOB (octet length, not packed length !!!)
+
+ Perhaps we should refactor prepare_create_field() to set
+ Create_field::length to maximum octet length for BLOBs,
+ instead of packed length).
+ */
+ DBUG_ASSERT(field_max_length <= m_return_field_def.length ||
+ (current_thd->stmt_arena->is_stmt_execute() &&
+ m_return_field_def.length == 8 &&
+ (m_return_field_def.pack_flag &
+ (FIELDFLAG_BLOB|FIELDFLAG_GEOM))));
field= m_return_field_def.make_field(table->s, /* TABLE_SHARE ptr */
table->in_use->mem_root,