Skip to content

Commit 371cb91

Browse files
BUG#24595581: NULL POINTER DEREFERENCE WHILE USING LONGTEXT
FUNCTION IN SUBQUERY ANALYSIS: ========= Server runs into null pointer dereferencing when a deterministic function returning longtext is used in a subquery. Item::const_item() is 'true' for all items having no table reference bits set. So it is 'true' for subqueries and deterministic functions that do not reference any tables. However, we cannot always consider items to be constant based on the referenced table bits. In this scenario, a deterministic function is considered a const item. Hence the resolver tries to evaluate the function in the preparation phase. At this phase, the query tables are open but not locked. After the evaluation, all the tables in the outer query block are closed. Later during the execution phase, when we try to lock the query tables, the TABLE object will be unused, thus leading to a null pointer dereference. FIX: ==== We are overriding the function 'fix_after_pullout' in the 'Item_func_sp' class where we are not considering deterministic functions as const items based on their table reference, thus preventing the resolver from evaluating the function in the preparation phase.
1 parent 8a6192a commit 371cb91

File tree

4 files changed

+59
-38
lines changed

4 files changed

+59
-38
lines changed

mysql-test/suite/opt_trace/r/general_no_prot_all.result

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8233,15 +8233,15 @@ select * from t6 where d in (select f1() from t2 where s="c") {
82338233
"steps": [
82348234
{
82358235
"transformation": "equality_propagation",
8236-
"resulting_condition": "(1 and multiple equal('c', `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
8236+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal('c', `t2`.`s`))"
82378237
},
82388238
{
82398239
"transformation": "constant_propagation",
8240-
"resulting_condition": "(1 and multiple equal('c', `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
8240+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal('c', `t2`.`s`))"
82418241
},
82428242
{
82438243
"transformation": "trivial_condition_removal",
8244-
"resulting_condition": "(multiple equal('c', `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
8244+
"resulting_condition": "((`t6`.`d` = `f1`()) and multiple equal('c', `t2`.`s`))"
82458245
}
82468246
] /* steps */
82478247
} /* condition_processing */
@@ -8305,13 +8305,13 @@ select * from t6 where d in (select f1() from t2 where s="c") {
83058305
{
83068306
"rows_to_scan": 4,
83078307
"access_type": "scan",
8308-
"resulting_rows": 1,
8308+
"resulting_rows": 4,
83098309
"cost": 2.8068,
83108310
"chosen": true
83118311
}
83128312
] /* considered_access_paths */
83138313
} /* best_access_path */,
8314-
"condition_filtering_pct": 100,
8314+
"condition_filtering_pct": 25,
83158315
"rows_for_plan": 1,
83168316
"cost_for_plan": 2.8068,
83178317
"semijoin_strategy_choice": [
@@ -8426,7 +8426,7 @@ select * from t6 where d in (select f1() from t2 where s="c") {
84268426
},
84278427
{
84288428
"attaching_conditions_to_tables": {
8429-
"original_condition": "((`t6`.`d` = `f1`()) and (`t2`.`s` = 'c'))",
8429+
"original_condition": "((`t2`.`s` = 'c') and (`t6`.`d` = `f1`()))",
84308430
"attached_conditions_computation": [
84318431
] /* attached_conditions_computation */,
84328432
"attached_conditions_summary": [
@@ -8436,7 +8436,7 @@ select * from t6 where d in (select f1() from t2 where s="c") {
84368436
},
84378437
{
84388438
"table": "`t2`",
8439-
"attached": "((`t6`.`d` = `f1`()) and (`t2`.`s` = 'c'))"
8439+
"attached": "((`t2`.`s` = 'c') and (`t6`.`d` = `f1`()))"
84408440
}
84418441
] /* attached_conditions_summary */
84428442
} /* attaching_conditions_to_tables */
@@ -9167,15 +9167,15 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
91679167
"steps": [
91689168
{
91699169
"transformation": "equality_propagation",
9170-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9170+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
91719171
},
91729172
{
91739173
"transformation": "constant_propagation",
9174-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9174+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
91759175
},
91769176
{
91779177
"transformation": "trivial_condition_removal",
9178-
"resulting_condition": "(multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9178+
"resulting_condition": "((`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
91799179
}
91809180
] /* steps */
91819181
} /* condition_processing */
@@ -9239,13 +9239,13 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
92399239
{
92409240
"rows_to_scan": 4,
92419241
"access_type": "scan",
9242-
"resulting_rows": 1,
9242+
"resulting_rows": 4,
92439243
"cost": 2.8068,
92449244
"chosen": true
92459245
}
92469246
] /* considered_access_paths */
92479247
} /* best_access_path */,
9248-
"condition_filtering_pct": 100,
9248+
"condition_filtering_pct": 25,
92499249
"rows_for_plan": 1,
92509250
"cost_for_plan": 2.8068,
92519251
"semijoin_strategy_choice": [
@@ -9360,7 +9360,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
93609360
},
93619361
{
93629362
"attaching_conditions_to_tables": {
9363-
"original_condition": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))",
9363+
"original_condition": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))",
93649364
"attached_conditions_computation": [
93659365
] /* attached_conditions_computation */,
93669366
"attached_conditions_summary": [
@@ -9370,7 +9370,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
93709370
},
93719371
{
93729372
"table": "`t2`",
9373-
"attached": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))"
9373+
"attached": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))"
93749374
}
93759375
] /* attached_conditions_summary */
93769376
} /* attaching_conditions_to_tables */
@@ -11083,15 +11083,15 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1108311083
"steps": [
1108411084
{
1108511085
"transformation": "equality_propagation",
11086-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
11086+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1108711087
},
1108811088
{
1108911089
"transformation": "constant_propagation",
11090-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
11090+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1109111091
},
1109211092
{
1109311093
"transformation": "trivial_condition_removal",
11094-
"resulting_condition": "(multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
11094+
"resulting_condition": "((`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1109511095
}
1109611096
] /* steps */
1109711097
} /* condition_processing */
@@ -11185,13 +11185,13 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1118511185
{
1118611186
"rows_to_scan": 4,
1118711187
"access_type": "scan",
11188-
"resulting_rows": 1,
11188+
"resulting_rows": 4,
1118911189
"cost": 2.8068,
1119011190
"chosen": true
1119111191
}
1119211192
] /* considered_access_paths */
1119311193
} /* best_access_path */,
11194-
"condition_filtering_pct": 100,
11194+
"condition_filtering_pct": 25,
1119511195
"rows_for_plan": 1,
1119611196
"cost_for_plan": 2.8068,
1119711197
"semijoin_strategy_choice": [
@@ -11317,7 +11317,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1131711317
},
1131811318
{
1131911319
"attaching_conditions_to_tables": {
11320-
"original_condition": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))",
11320+
"original_condition": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))",
1132111321
"attached_conditions_computation": [
1132211322
] /* attached_conditions_computation */,
1132311323
"attached_conditions_summary": [
@@ -11327,7 +11327,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1132711327
},
1132811328
{
1132911329
"table": "`t2`",
11330-
"attached": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))"
11330+
"attached": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))"
1133111331
}
1133211332
] /* attached_conditions_summary */
1133311333
} /* attaching_conditions_to_tables */

mysql-test/suite/opt_trace/r/general_ps_prot_all.result

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9025,15 +9025,15 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
90259025
"steps": [
90269026
{
90279027
"transformation": "equality_propagation",
9028-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9028+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
90299029
},
90309030
{
90319031
"transformation": "constant_propagation",
9032-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9032+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
90339033
},
90349034
{
90359035
"transformation": "trivial_condition_removal",
9036-
"resulting_condition": "(multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
9036+
"resulting_condition": "((`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
90379037
}
90389038
] /* steps */
90399039
} /* condition_processing */
@@ -9097,13 +9097,13 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
90979097
{
90989098
"rows_to_scan": 4,
90999099
"access_type": "scan",
9100-
"resulting_rows": 1,
9100+
"resulting_rows": 4,
91019101
"cost": 2.8068,
91029102
"chosen": true
91039103
}
91049104
] /* considered_access_paths */
91059105
} /* best_access_path */,
9106-
"condition_filtering_pct": 100,
9106+
"condition_filtering_pct": 25,
91079107
"rows_for_plan": 1,
91089108
"cost_for_plan": 2.8068,
91099109
"semijoin_strategy_choice": [
@@ -9218,7 +9218,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
92189218
},
92199219
{
92209220
"attaching_conditions_to_tables": {
9221-
"original_condition": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))",
9221+
"original_condition": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))",
92229222
"attached_conditions_computation": [
92239223
] /* attached_conditions_computation */,
92249224
"attached_conditions_summary": [
@@ -9228,7 +9228,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
92289228
},
92299229
{
92309230
"table": "`t2`",
9231-
"attached": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))"
9231+
"attached": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))"
92329232
}
92339233
] /* attached_conditions_summary */
92349234
} /* attaching_conditions_to_tables */
@@ -10955,15 +10955,15 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1095510955
"steps": [
1095610956
{
1095710957
"transformation": "equality_propagation",
10958-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
10958+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1095910959
},
1096010960
{
1096110961
"transformation": "constant_propagation",
10962-
"resulting_condition": "(1 and multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
10962+
"resulting_condition": "(1 and (`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1096310963
},
1096410964
{
1096510965
"transformation": "trivial_condition_removal",
10966-
"resulting_condition": "(multiple equal(arg@0, `t2`.`s`) and multiple equal(`f1`(), `t6`.`d`))"
10966+
"resulting_condition": "((`t6`.`d` = `f1`()) and multiple equal(arg@0, `t2`.`s`))"
1096710967
}
1096810968
] /* steps */
1096910969
} /* condition_processing */
@@ -11057,13 +11057,13 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1105711057
{
1105811058
"rows_to_scan": 4,
1105911059
"access_type": "scan",
11060-
"resulting_rows": 1,
11060+
"resulting_rows": 4,
1106111061
"cost": 2.8068,
1106211062
"chosen": true
1106311063
}
1106411064
] /* considered_access_paths */
1106511065
} /* best_access_path */,
11066-
"condition_filtering_pct": 100,
11066+
"condition_filtering_pct": 25,
1106711067
"rows_for_plan": 1,
1106811068
"cost_for_plan": 2.8068,
1106911069
"semijoin_strategy_choice": [
@@ -11189,7 +11189,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1118911189
},
1119011190
{
1119111191
"attaching_conditions_to_tables": {
11192-
"original_condition": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))",
11192+
"original_condition": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))",
1119311193
"attached_conditions_computation": [
1119411194
] /* attached_conditions_computation */,
1119511195
"attached_conditions_summary": [
@@ -11199,7 +11199,7 @@ select d into res from t6 where d in (select f1() from t2 where s=arg) {
1119911199
},
1120011200
{
1120111201
"table": "`t2`",
11202-
"attached": "((`t6`.`d` = `f1`()) and (`t2`.`s` = arg@0))"
11202+
"attached": "((`t2`.`s` = arg@0) and (`t6`.`d` = `f1`()))"
1120311203
}
1120411204
] /* attached_conditions_summary */
1120511205
} /* attaching_conditions_to_tables */

sql/item_func.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,24 @@ void Item_func::update_used_tables()
480480
}
481481

482482

483+
void Item_func_sp::fix_after_pullout(SELECT_LEX *parent_select,
484+
SELECT_LEX *removed_select)
485+
{
486+
Item_func::fix_after_pullout(parent_select, removed_select);
487+
488+
/*
489+
Prevents function from being evaluated before it is locked.
490+
@todo - make this dependent on READS SQL or MODIFIES SQL.
491+
Due to a limitation in how functions are evaluated, we need to
492+
ensure that we are in a prelocked mode even though the function
493+
doesn't reference any tables.
494+
*/
495+
used_tables_cache|= PARAM_TABLE_BIT;
496+
497+
const_item_cache= used_tables_cache == 0;
498+
}
499+
500+
483501
table_map Item_func::used_tables() const
484502
{
485503
return used_tables_cache;

sql/item_func.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef ITEM_FUNC_INCLUDED
22
#define ITEM_FUNC_INCLUDED
33

4-
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
4+
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
55
66
This program is free software; you can redistribute it and/or modify
77
it under the terms of the GNU General Public License as published by
@@ -193,8 +193,8 @@ class Item_func :public Item_result_field
193193

194194
bool fix_fields(THD *, Item **ref);
195195
bool fix_func_arg(THD *, Item **arg);
196-
void fix_after_pullout(st_select_lex *parent_select,
197-
st_select_lex *removed_select);
196+
virtual void fix_after_pullout(st_select_lex *parent_select,
197+
st_select_lex *removed_select);
198198
table_map used_tables() const;
199199
/**
200200
Returns the pseudo tables depended upon in order to evaluate this
@@ -2718,6 +2718,9 @@ class Item_func_sp :public Item_func
27182718
table_map get_initial_pseudo_tables() const;
27192719
void update_used_tables();
27202720

2721+
virtual void fix_after_pullout(st_select_lex *parent_select,
2722+
st_select_lex *removed_select);
2723+
27212724
void cleanup();
27222725

27232726
const char *func_name() const;

0 commit comments

Comments
 (0)