summaryrefslogtreecommitdiff
path: root/sql/sql_join_cache.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2011-10-25 14:18:19 -0700
committerIgor Babaev <igor@askmonty.org>2011-10-25 14:18:19 -0700
commita8f7c03c1e46dd556aa57d45bbd078101c68ec9e (patch)
treeee053f0bcb2ace114196d49125dfc87517c1497a /sql/sql_join_cache.cc
parentc0a1bd1ed63bb9e0064e99e654b3b57dd3f0c5f4 (diff)
downloadmariadb-git-a8f7c03c1e46dd556aa57d45bbd078101c68ec9e.tar.gz
Fixed LP bug #881318.
If a materialized derived table / view is empty then for this table the value of file->ref is 0. This was not taken into account by the function JOIN_CACHE::write_record_data. As a result a query using an empty materialized derived tables as inner tables of outer joins and IN subqueries in WHERE conditions could cause server crashes when the optimizer employed join caches and duplicate elimination for semi-joins.
Diffstat (limited to 'sql/sql_join_cache.cc')
-rw-r--r--sql/sql_join_cache.cc19
1 files changed, 18 insertions, 1 deletions
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index c8933fe69ee..f53bf738b86 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -1413,12 +1413,22 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
TABLE *table= (TABLE *) copy->str;
copy->str= table->file->ref;
copy->length= table->file->ref_length;
+ if (!copy->str)
+ {
+ /*
+ If table is an empty inner table of an outer join and it is
+ a materialized derived table then table->file->ref == NULL.
+ */
+ cp+= copy->length;
+ break;
+ }
}
/* fall through */
default:
/* Copy the entire image of the field from the record buffer */
DBUG_ASSERT(cp + copy->length <= buff + buff_size);
- memcpy(cp, copy->str, copy->length);
+ if (copy->str)
+ memcpy(cp, copy->str, copy->length);
cp+= copy->length;
}
}
@@ -1811,6 +1821,13 @@ uint JOIN_CACHE::read_record_field(CACHE_FIELD *copy, bool blob_in_rec_buff)
memset(copy->str+len, ' ', copy->length-len);
len+= 2;
break;
+ case CACHE_ROWID:
+ if (!copy->str)
+ {
+ len= copy->length;
+ break;
+ }
+ /* fall through */
default:
/* Copy the entire image of the field from the record buffer */
len= copy->length;