summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Didriksen <tor.didriksen@oracle.com>2013-03-19 17:09:17 +0100
committerTor Didriksen <tor.didriksen@oracle.com>2013-03-19 17:09:17 +0100
commit9b5fab5892e21c80b05f3f6ab4171e0d1a8520be (patch)
tree18e5595a49953878f32ba1f07e159dfb83e7dc27
parent30e2a543872915353b9d4b1e45e51c8d793965bf (diff)
downloadmariadb-git-9b5fab5892e21c80b05f3f6ab4171e0d1a8520be.tar.gz
Bug#13009341 CRASH IN STR_TO_DATETIME AFTER MISBEHAVING "BLOB" VALUE COMPARISON
The range optimizer uses 'save_in_field_no_warnings()' to verify properties of 'value <cmp> field' expressions. If this execution yields an error, it should abort.
-rw-r--r--sql/opt_range.cc52
1 files changed, 31 insertions, 21 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c078d9ac85b..9604ed1e3b3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -671,6 +671,15 @@ public:
/* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
uint alloced_sel_args;
+
+ bool statement_should_be_aborted() const
+ {
+ return
+ thd->is_fatal_error ||
+ thd->is_error() ||
+ alloced_sel_args > SEL_ARG::MAX_SEL_ARGS;
+ }
+
};
class PARAM : public RANGE_OPT_PARAM
@@ -5541,34 +5550,35 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
- tree=0;
+ tree= NULL;
Item *item;
while ((item=li++))
{
- SEL_TREE *new_tree=get_mm_tree(param,item);
- if (param->thd->is_fatal_error ||
- param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
- DBUG_RETURN(0); // out of memory
- tree=tree_and(param,tree,new_tree);
- if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
- break;
+ SEL_TREE *new_tree= get_mm_tree(param,item);
+ if (param->statement_should_be_aborted())
+ DBUG_RETURN(NULL);
+ tree= tree_and(param,tree,new_tree);
+ if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
+ break;
}
}
else
- { // COND OR
- tree=get_mm_tree(param,li++);
+ { // COND OR
+ tree= get_mm_tree(param,li++);
+ if (param->statement_should_be_aborted())
+ DBUG_RETURN(NULL);
if (tree)
{
- Item *item;
- while ((item=li++))
- {
- SEL_TREE *new_tree=get_mm_tree(param,item);
- if (!new_tree)
- DBUG_RETURN(0); // out of memory
- tree=tree_or(param,tree,new_tree);
- if (!tree || tree->type == SEL_TREE::ALWAYS)
- break;
- }
+ Item *item;
+ while ((item=li++))
+ {
+ SEL_TREE *new_tree=get_mm_tree(param,item);
+ if (new_tree == NULL || param->statement_should_be_aborted())
+ DBUG_RETURN(NULL);
+ tree= tree_or(param,tree,new_tree);
+ if (tree == NULL || tree->type == SEL_TREE::ALWAYS)
+ break;
+ }
}
}
DBUG_RETURN(tree);