mariadb: fix compilation with newer fmt
[feed/packages.git] / utils / mariadb / patches / 110-fmt.patch
1 From c657a1973e274b16db0631dc3862e276ab354564 Mon Sep 17 00:00:00 2001
2 From: Ruoyu Zhong <zhongruoyu@outlook.com>
3 Date: Sat, 19 Aug 2023 22:48:16 +0800
4 Subject: [PATCH 1/2] MDEV-31963 cmake: fix libfmt usage
5
6 `fmt::detail::make_arg` does not accept temporaries, so the code snippet
7 checking system libfmt needs to be adjusted.
8
9 Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
10 ---
11 cmake/libfmt.cmake | 3 ++-
12 1 file changed, 2 insertions(+), 1 deletion(-)
13
14 --- a/cmake/libfmt.cmake
15 +++ b/cmake/libfmt.cmake
16 @@ -33,8 +33,9 @@ MACRO (CHECK_LIBFMT)
17 #include <fmt/format-inl.h>
18 #include <iostream>
19 int main() {
20 + int answer= 42;
21 fmt::format_args::format_arg arg=
22 - fmt::detail::make_arg<fmt::format_context>(42);
23 + fmt::detail::make_arg<fmt::format_context>(answer);
24 std::cout << fmt::vformat(\"The answer is {}.\",
25 fmt::format_args(&arg, 1));
26 }" HAVE_SYSTEM_LIBFMT)
27 --- a/sql/item_strfunc.cc
28 +++ b/sql/item_strfunc.cc
29 @@ -1382,11 +1382,24 @@ namespace fmt {
30 */
31 String *Item_func_sformat::val_str(String *res)
32 {
33 + /*
34 + A union that stores a numeric format arg value.
35 + fmt::detail::make_arg does not accept temporaries, so all of its numeric
36 + args are temporarily stored in the fmt_args array.
37 + See: https://github.com/fmtlib/fmt/issues/3596
38 + */
39 + union Format_arg_store {
40 + longlong val_int;
41 + float val_float;
42 + double val_double;
43 + };
44 +
45 DBUG_ASSERT(fixed());
46 - using ctx= fmt::format_context;
47 - String *fmt_arg= NULL;
48 - String *parg= NULL;
49 - fmt::format_args::format_arg *vargs= NULL;
50 + using ctx= fmt::format_context;
51 + String *fmt_arg= NULL;
52 + String *parg= NULL;
53 + fmt::format_args::format_arg *vargs= NULL;
54 + Format_arg_store *fmt_args= NULL;
55
56 null_value= true;
57 if (!(fmt_arg= args[0]->val_str(res)))
58 @@ -1395,25 +1408,39 @@ String *Item_func_sformat::val_str(Strin
59 if (!(vargs= new fmt::format_args::format_arg[arg_count - 1]))
60 return NULL;
61
62 + if (!(fmt_args= new Format_arg_store[arg_count - 1]))
63 + {
64 + delete [] vargs;
65 + return NULL;
66 + }
67 +
68 /* Creates the array of arguments for vformat */
69 for (uint carg= 1; carg < arg_count; carg++)
70 {
71 switch (args[carg]->result_type())
72 {
73 case INT_RESULT:
74 - vargs[carg-1]= fmt::detail::make_arg<ctx>(args[carg]->val_int());
75 + fmt_args[carg-1].val_int= args[carg]->val_int();
76 + vargs[carg-1]= fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_int);
77 break;
78 case DECIMAL_RESULT: // TODO
79 case REAL_RESULT:
80 if (args[carg]->field_type() == MYSQL_TYPE_FLOAT)
81 - vargs[carg-1]= fmt::detail::make_arg<ctx>((float)args[carg]->val_real());
82 + {
83 + fmt_args[carg-1].val_float= (float)args[carg]->val_real();
84 + vargs[carg-1]= fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_float);
85 + }
86 else
87 - vargs[carg-1]= fmt::detail::make_arg<ctx>(args[carg]->val_real());
88 + {
89 + fmt_args[carg-1].val_double= args[carg]->val_real();
90 + vargs[carg-1]= fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_double);
91 + }
92 break;
93 case STRING_RESULT:
94 if (!(parg= args[carg]->val_str(&val_arg[carg-1])))
95 {
96 delete [] vargs;
97 + delete [] fmt_args;
98 return NULL;
99 }
100 vargs[carg-1]= fmt::detail::make_arg<ctx>(*parg);
101 @@ -1423,6 +1450,7 @@ String *Item_func_sformat::val_str(Strin
102 default:
103 DBUG_ASSERT(0);
104 delete [] vargs;
105 + delete [] fmt_args;
106 return NULL;
107 }
108 }
109 @@ -1446,6 +1474,7 @@ String *Item_func_sformat::val_str(Strin
110 null_value= true;
111 }
112 delete [] vargs;
113 + delete [] fmt_args;
114 return null_value ? NULL : res;
115 }
116