message: Issue ArgMinMax Template Madness
  Fix non-inlining of templates for older compilers.
diff: namespace duckdb {
  -template <class A, class B>
  -struct ArgMinMaxState {
  - using ARG_TYPE = A;
  - using BY_TYPE = B;
  +struct ArgMinMaxStateBase {
  + ArgMinMaxStateBase() : is_initialized(false) {
  + }
  - ARG_TYPE arg;
  - BY_TYPE value;
  - bool is_initialized;
  + template <class T>
  + static inline void CreateValue(T &value) {
  + }
  - ArgMinMaxState() : is_initialized(false) {
  + template <class T>
  + static inline void DestroyValue(T &value) {
  }
  - ~ArgMinMaxState() {
  - if (is_initialized) {
  - DestroyValue(arg);
  - DestroyValue(value);
  - is_initialized = false;
  + template <class T>
  + static inline void AssignValue(T &target, T new_value, bool is_initialized) {
  + target = new_value;
  }
  +
  + template <typename T>
  + static inline void ReadValue(Vector &result, T &arg, T *target, idx_t idx) {
  + target[idx] = arg;
  }
  - template <class T>
  - static void DestroyValue(T value) {
  + bool is_initialized;
  +};
  +
  +// Out-of-line specialisations
  +template <>
  +void ArgMinMaxStateBase::CreateValue(Vector *&value) {
  + value = nullptr;
  }
  template <>
  - void DestroyValue(string_t value) {
  +void ArgMinMaxStateBase::DestroyValue(string_t &value) {
  if (!value.IsInlined()) {
  delete[] value.GetDataUnsafe();
  }
  }
  template <>
  - void DestroyValue(Vector *value) {
  +void ArgMinMaxStateBase::DestroyValue(Vector *&value) {
  delete value;
  - }
  -
  - template <class T>
  - static void AssignValue(T &target, T new_value, bool is_initialized) {
  - target = new_value;
  + value = nullptr;
  }
  template <>
  - void AssignValue(string_t &target, string_t new_value, bool is_initialized) {
  +void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value, bool is_initialized) {
  if (is_initialized) {
  DestroyValue(target);
  }
  @@ -65,15 +68,31 @@ struct ArgMinMaxState {
  }
  }
  - template <typename T>
  - static void ReadValue(Vector &result, T &arg, T *target, idx_t idx) {
  - target[idx] = arg;
  - }
  -
  template <>
  - static void ReadValue(Vector &result, string_t &arg, string_t *target, idx_t idx) {
  +void ArgMinMaxStateBase::ReadValue(Vector &result, string_t &arg, string_t *target, idx_t idx) {
  target[idx] = StringVector::AddStringOrBlob(result, arg);
  }
  +
  +template <class A, class B>
  +struct ArgMinMaxState : public ArgMinMaxStateBase {
  + using ARG_TYPE = A;
  + using BY_TYPE = B;
  +
  + ARG_TYPE arg;
  + BY_TYPE value;
  +
  + ArgMinMaxState() {
  + CreateValue(arg);
  + CreateValue(value);
  + }
  +
  + ~ArgMinMaxState() {
  + if (is_initialized) {
  + DestroyValue(arg);
  + DestroyValue(value);
  + is_initialized = false;
  + }
  + }
  };
  template <class COMPARATOR>
  @@ -211,7 +230,7 @@ struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR> {
  ConstantVector::SetNull(result, true);
  break;
  default:
  - throw InternalException("Invalid result vector type for nested min/max");
  + throw InternalException("Invalid result vector type for nested arg_min/max");
  }
  } else {
  VectorOperations::Copy(*state->arg, result, 1, 0, idx);
  