1 | /* |
2 | Copyright (c) 2000, 2010, Oracle and/or its affiliates. |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | |
18 | /* Mallocs for used in threads */ |
19 | |
20 | #include "mariadb.h" |
21 | #include "sql_priv.h" |
22 | #include "unireg.h" |
23 | #include "thr_malloc.h" |
24 | #include "sql_class.h" |
25 | |
26 | extern "C" { |
27 | void sql_alloc_error_handler(void) |
28 | { |
29 | THD *thd= current_thd; |
30 | if (likely(thd)) |
31 | { |
32 | if (! thd->is_error()) |
33 | { |
34 | /* |
35 | This thread is Out Of Memory. |
36 | An OOM condition is a fatal error. |
37 | It should not be caught by error handlers in stored procedures. |
38 | Also, recording that SQL condition in the condition area could |
39 | cause more memory allocations, which in turn could raise more |
40 | OOM conditions, causing recursion in the error handling code itself. |
41 | As a result, my_error() should not be invoked, and the |
42 | thread diagnostics area is set to an error status directly. |
43 | Note that Diagnostics_area::set_error_status() is safe, |
44 | since it does not call any memory allocation routines. |
45 | The visible result for a client application will be: |
46 | - a query fails with an ER_OUT_OF_RESOURCES error, |
47 | returned in the error packet. |
48 | - SHOW ERROR/SHOW WARNINGS may be empty. |
49 | */ |
50 | thd->get_stmt_da()->set_error_status(ER_OUT_OF_RESOURCES); |
51 | } |
52 | } |
53 | |
54 | /* Skip writing to the error log to avoid mtr complaints */ |
55 | DBUG_EXECUTE_IF("simulate_out_of_memory" , return;); |
56 | |
57 | sql_print_error("%s" , ER_THD_OR_DEFAULT(thd, ER_OUT_OF_RESOURCES)); |
58 | } |
59 | } |
60 | |
61 | void init_sql_alloc(MEM_ROOT *mem_root, |
62 | const char *area_name __attribute__((unused)), |
63 | uint block_size, uint pre_alloc, myf my_flags) |
64 | { |
65 | init_alloc_root(mem_root, area_name, block_size, pre_alloc, my_flags); |
66 | mem_root->error_handler=sql_alloc_error_handler; |
67 | } |
68 | |
69 | |
70 | char *sql_strmake_with_convert(THD *thd, const char *str, size_t arg_length, |
71 | CHARSET_INFO *from_cs, |
72 | size_t max_res_length, |
73 | CHARSET_INFO *to_cs, size_t *result_length) |
74 | { |
75 | char *pos; |
76 | size_t new_length= to_cs->mbmaxlen*arg_length; |
77 | max_res_length--; // Reserve place for end null |
78 | |
79 | set_if_smaller(new_length, max_res_length); |
80 | if (!(pos= (char*) thd->alloc(new_length + 1))) |
81 | return pos; // Error |
82 | |
83 | if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin)) |
84 | { |
85 | // Safety if to_cs->mbmaxlen > 0 |
86 | new_length= MY_MIN(arg_length, max_res_length); |
87 | memcpy(pos, str, new_length); |
88 | } |
89 | else |
90 | { |
91 | uint dummy_errors; |
92 | new_length= copy_and_convert((char*) pos, new_length, to_cs, str, |
93 | arg_length, from_cs, &dummy_errors); |
94 | } |
95 | pos[new_length]= 0; |
96 | *result_length= new_length; |
97 | return pos; |
98 | } |
99 | |
100 | |