On Sun, Jan 14, 2024 at 07:48:48PM +0000, Klemens Nanni wrote:
> On Mon, Nov 06, 2023 at 10:03:22AM +0000, Stuart Henderson wrote:
> > Tried it before, this update breaks mariadb.
> 
> libfmt is still behind, perhaps we want to stick to mariadb's 8.0.1 bundle?
> It'd be a downgrade from ports 8.1.1, but mariadb builds and libfmt could
> be updated.
> 
> Just a tiny .cmake patch and usual DISTFILES goo.
> 
> Builds, but I don't use MariaDB.
> Thoughts?

This should fix building with newer fmt. Only build tested with the
in tree version.


Index: Makefile
===================================================================
RCS file: /home/cvs/ports/databases/mariadb/Makefile,v
diff -u -p -u -p -r1.143 Makefile
--- Makefile    20 Sep 2023 13:30:06 -0000      1.143
+++ Makefile    15 Jan 2024 02:22:18 -0000
@@ -5,6 +5,7 @@ COMMENT-tests=  multithreaded SQL databas
 VERSION=       10.9.6
 DISTNAME=      mariadb-${VERSION}
 PKGNAME-main=  mariadb-client-${VERSION}
+REVISION-server= 0
 EPOCH=         1
 CATEGORIES=    databases
 SITES=         https://downloads.mariadb.com/MariaDB/${DISTNAME}/source/ \
Index: patches/patch-cmake_libfmt_cmake
===================================================================
RCS file: patches/patch-cmake_libfmt_cmake
diff -N patches/patch-cmake_libfmt_cmake
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-cmake_libfmt_cmake    15 Jan 2024 01:15:46 -0000
@@ -0,0 +1,21 @@
+MDEV-31963 cmake: fix libfmt usage
+
+`fmt::detail::make_arg` does not accept temporaries, so the code snippet
+checking system libfmt needs to be adjusted.
+
+f4cec369a392c8a6056207012992ad4a5639965a
+
+Index: cmake/libfmt.cmake
+--- cmake/libfmt.cmake.orig
++++ cmake/libfmt.cmake
+@@ -33,8 +33,9 @@ MACRO (CHECK_LIBFMT)
+      #include <fmt/format-inl.h>
+      #include <iostream>
+      int main() {
++       int answer= 42;
+        fmt::format_args::format_arg arg=
+-         fmt::detail::make_arg<fmt::format_context>(42);
++         fmt::detail::make_arg<fmt::format_context>(answer);
+          std::cout << fmt::vformat(\"The answer is {}.\",
+                                    fmt::format_args(&arg, 1));
+      }" HAVE_SYSTEM_LIBFMT)
Index: patches/patch-sql_item_strfunc_cc
===================================================================
RCS file: patches/patch-sql_item_strfunc_cc
diff -N patches/patch-sql_item_strfunc_cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-sql_item_strfunc_cc   15 Jan 2024 01:16:26 -0000
@@ -0,0 +1,98 @@
+[PATCH] MDEV-31963 Fix libfmt usage in SFORMAT
+
+`fmt::detail::make_arg` does not accept temporaries. Make it happy by
+storing the format arg values in a temporary array first.
+
+cd5808eb8da13c5626d4bdeb452cef6ada29cb1d
+
+Index: sql/item_strfunc.cc
+--- sql/item_strfunc.cc.orig
++++ sql/item_strfunc.cc
+@@ -1382,11 +1382,24 @@ namespace fmt {
+ */
+ String *Item_func_sformat::val_str(String *res)
+ {
++  /*
++    A union that stores a numeric format arg value.
++    fmt::detail::make_arg does not accept temporaries, so all of its numeric
++    args are temporarily stored in the fmt_args array.
++    See: https://github.com/fmtlib/fmt/issues/3596
++  */
++  union Format_arg_store {
++    longlong val_int;
++    float    val_float;
++    double   val_double;
++  };
++
+   DBUG_ASSERT(fixed());
+-  using                         ctx=     fmt::format_context;
+-  String                       *fmt_arg= NULL;
+-  String                       *parg=    NULL;
+-  fmt::format_args::format_arg *vargs=   NULL;
++  using                         ctx=      fmt::format_context;
++  String                       *fmt_arg=  NULL;
++  String                       *parg=     NULL;
++  fmt::format_args::format_arg *vargs=    NULL;
++  Format_arg_store             *fmt_args= NULL;
+ 
+   null_value= true;
+   if (!(fmt_arg= args[0]->val_str(res)))
+@@ -1395,25 +1408,39 @@ String *Item_func_sformat::val_str(String *res)
+   if (!(vargs= new fmt::format_args::format_arg[arg_count - 1]))
+     return NULL;
+ 
++  if (!(fmt_args= new Format_arg_store[arg_count - 1]))
++  {
++    delete [] vargs;
++    return NULL;
++  }
++
+   /* Creates the array of arguments for vformat */
+   for (uint carg= 1; carg < arg_count; carg++)
+   {
+     switch (args[carg]->result_type())
+     {
+     case INT_RESULT:
+-      vargs[carg-1]= fmt::detail::make_arg<ctx>(args[carg]->val_int());
++      fmt_args[carg-1].val_int= args[carg]->val_int();
++      vargs[carg-1]= fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_int);
+       break;
+     case DECIMAL_RESULT: // TODO
+     case REAL_RESULT:
+       if (args[carg]->field_type() == MYSQL_TYPE_FLOAT)
+-        vargs[carg-1]= 
fmt::detail::make_arg<ctx>((float)args[carg]->val_real());
++      {
++        fmt_args[carg-1].val_float= (float)args[carg]->val_real();
++        vargs[carg-1]= fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_float);
++      }
+       else
+-        vargs[carg-1]= fmt::detail::make_arg<ctx>(args[carg]->val_real());
++      {
++        fmt_args[carg-1].val_double= args[carg]->val_real();
++        vargs[carg-1]= 
fmt::detail::make_arg<ctx>(fmt_args[carg-1].val_double);
++      }
+       break;
+     case STRING_RESULT:
+       if (!(parg= args[carg]->val_str(&val_arg[carg-1])))
+       {
+         delete [] vargs;
++        delete [] fmt_args;
+         return NULL;
+       }
+       vargs[carg-1]= fmt::detail::make_arg<ctx>(*parg);
+@@ -1423,6 +1450,7 @@ String *Item_func_sformat::val_str(String *res)
+     default:
+       DBUG_ASSERT(0);
+       delete [] vargs;
++      delete [] fmt_args;
+       return NULL;
+     }
+   }
+@@ -1446,6 +1474,7 @@ String *Item_func_sformat::val_str(String *res)
+     null_value= true;
+   }
+   delete [] vargs;
++  delete [] fmt_args;
+   return null_value ? NULL : res;
+ }
+ 

Reply via email to