This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 8a768a15f14 branch-4.0: [fix](field) implement move constructor #56803 
(#56975)
8a768a15f14 is described below

commit 8a768a15f140abf054723c64d47b766be7795a8b
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Oct 16 09:55:18 2025 +0800

    branch-4.0: [fix](field) implement move constructor #56803 (#56975)
    
    Cherry-picked from #56803
    
    Co-authored-by: Sun Chenyang <[email protected]>
---
 be/src/vec/core/field.cpp                   | 261 +++++++++++++++++++++++++++-
 be/src/vec/core/field.h                     |   7 +-
 be/test/vec/columns/column_variant_test.cpp |   2 +-
 be/test/vec/core/field_test.cpp             |  88 ++++++++++
 4 files changed, 354 insertions(+), 4 deletions(-)

diff --git a/be/src/vec/core/field.cpp b/be/src/vec/core/field.cpp
index 382bc5fc0e1..6fb0af9cec3 100644
--- a/be/src/vec/core/field.cpp
+++ b/be/src/vec/core/field.cpp
@@ -96,7 +96,7 @@ void Field::create_concrete(typename 
PrimitiveTypeTraits<Type>::NearestFieldType
     // we must initialize the entire wide stored type, and not just the
     // nominal type.
     using StorageType = typename PrimitiveTypeTraits<Type>::NearestFieldType;
-    new (&storage) StorageType(x);
+    new (&storage) StorageType(std::move(x));
     type = Type;
     DCHECK_NE(type, PrimitiveType::INVALID_TYPE);
 }
@@ -114,6 +114,132 @@ void Field::create_concrete(const typename 
PrimitiveTypeTraits<Type>::NearestFie
     DCHECK_NE(type, PrimitiveType::INVALID_TYPE);
 }
 
+void Field::create(Field&& field) {
+    switch (field.type) {
+    case PrimitiveType::TYPE_NULL:
+        create_concrete<TYPE_NULL>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_NULL>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATETIMEV2:
+        create_concrete<TYPE_DATETIMEV2>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DATETIMEV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATEV2:
+        create_concrete<TYPE_DATEV2>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_DATEV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATETIME:
+    case PrimitiveType::TYPE_DATE:
+    case PrimitiveType::TYPE_BOOLEAN:
+    case PrimitiveType::TYPE_TINYINT:
+    case PrimitiveType::TYPE_SMALLINT:
+    case PrimitiveType::TYPE_INT:
+    case PrimitiveType::TYPE_BIGINT:
+        create_concrete<TYPE_BIGINT>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_BIGINT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_LARGEINT:
+        create_concrete<TYPE_LARGEINT>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_LARGEINT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_IPV4:
+        create_concrete<TYPE_IPV4>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_IPV4>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_IPV6:
+        create_concrete<TYPE_IPV6>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_IPV6>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_FLOAT:
+    case PrimitiveType::TYPE_TIMEV2:
+    case PrimitiveType::TYPE_DOUBLE:
+        create_concrete<TYPE_DOUBLE>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_DOUBLE>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_STRING:
+        create_concrete<TYPE_STRING>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_STRING>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_CHAR:
+        create_concrete<TYPE_CHAR>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_CHAR>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARCHAR:
+        create_concrete<TYPE_VARCHAR>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARCHAR>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_JSONB:
+        create_concrete<TYPE_JSONB>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_JSONB>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_ARRAY:
+        create_concrete<TYPE_ARRAY>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_ARRAY>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_STRUCT:
+        create_concrete<TYPE_STRUCT>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_STRUCT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_MAP:
+        create_concrete<TYPE_MAP>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_MAP>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL32:
+        create_concrete<TYPE_DECIMAL32>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL32>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL64:
+        create_concrete<TYPE_DECIMAL64>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL64>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMALV2:
+        create_concrete<TYPE_DECIMALV2>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMALV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL128I:
+        create_concrete<TYPE_DECIMAL128I>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL128I>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL256:
+        create_concrete<TYPE_DECIMAL256>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL256>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARIANT:
+        create_concrete<TYPE_VARIANT>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARIANT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_BITMAP:
+        create_concrete<TYPE_BITMAP>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_BITMAP>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_HLL:
+        create_concrete<TYPE_HLL>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_HLL>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_QUANTILE_STATE:
+        create_concrete<TYPE_QUANTILE_STATE>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_QUANTILE_STATE>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARBINARY:
+        create_concrete<TYPE_VARBINARY>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARBINARY>::NearestFieldType>()));
+        return;
+    default:
+        throw Exception(Status::FatalError("type not supported, type={}", 
field.get_type_name()));
+    }
+}
+
 void Field::create(const Field& field) {
     switch (field.type) {
     case PrimitiveType::TYPE_NULL:
@@ -292,6 +418,137 @@ void Field::destroy() {
             TYPE_NULL; /// for exception safety in subsequent calls to destroy 
and create, when create fails.
 }
 
+void Field::assign(Field&& field) {
+    switch (field.type) {
+    case PrimitiveType::TYPE_NULL:
+        assign_concrete<TYPE_NULL>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_NULL>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATETIMEV2:
+        assign_concrete<TYPE_DATETIMEV2>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DATETIMEV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATETIME:
+        assign_concrete<TYPE_DATETIME>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DATETIME>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATE:
+        assign_concrete<TYPE_DATE>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_DATE>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DATEV2:
+        assign_concrete<TYPE_DATEV2>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_DATEV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_BOOLEAN:
+    case PrimitiveType::TYPE_TINYINT:
+    case PrimitiveType::TYPE_SMALLINT:
+    case PrimitiveType::TYPE_INT:
+    case PrimitiveType::TYPE_BIGINT:
+        assign_concrete<TYPE_BIGINT>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_BIGINT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_LARGEINT:
+        assign_concrete<TYPE_LARGEINT>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_LARGEINT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_IPV4:
+        assign_concrete<TYPE_IPV4>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_IPV4>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_IPV6:
+        assign_concrete<TYPE_IPV6>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_IPV6>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DOUBLE:
+        assign_concrete<TYPE_DOUBLE>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_DOUBLE>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_STRING:
+        assign_concrete<TYPE_STRING>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_STRING>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_CHAR:
+        assign_concrete<TYPE_CHAR>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_CHAR>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARCHAR:
+        assign_concrete<TYPE_VARCHAR>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARCHAR>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_JSONB:
+        assign_concrete<TYPE_JSONB>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_JSONB>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_ARRAY:
+        assign_concrete<TYPE_ARRAY>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_ARRAY>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_STRUCT:
+        assign_concrete<TYPE_STRUCT>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_STRUCT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_MAP:
+        assign_concrete<TYPE_MAP>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_MAP>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL32:
+        assign_concrete<TYPE_DECIMAL32>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL32>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL64:
+        assign_concrete<TYPE_DECIMAL64>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL64>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMALV2:
+        assign_concrete<TYPE_DECIMALV2>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMALV2>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL128I:
+        assign_concrete<TYPE_DECIMAL128I>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL128I>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_DECIMAL256:
+        assign_concrete<TYPE_DECIMAL256>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_DECIMAL256>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARIANT:
+        assign_concrete<TYPE_VARIANT>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARIANT>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_BITMAP:
+        assign_concrete<TYPE_BITMAP>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_BITMAP>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_HLL:
+        assign_concrete<TYPE_HLL>(std::move(
+                field.template get<typename 
PrimitiveTypeTraits<TYPE_HLL>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_QUANTILE_STATE:
+        assign_concrete<TYPE_QUANTILE_STATE>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_QUANTILE_STATE>::NearestFieldType>()));
+        return;
+    case PrimitiveType::TYPE_VARBINARY:
+        assign_concrete<TYPE_VARBINARY>(
+                std::move(field.template get<
+                          typename 
PrimitiveTypeTraits<TYPE_VARBINARY>::NearestFieldType>()));
+        return;
+    default:
+        throw Exception(Status::FatalError("type not supported, type={}", 
field.get_type_name()));
+    }
+}
+
 void Field::assign(const Field& field) {
     switch (field.type) {
     case PrimitiveType::TYPE_NULL:
@@ -544,6 +801,8 @@ std::string_view Field::as_string_view() const {
             typename PrimitiveTypeTraits<TYPE_VARCHAR>::NearestFieldType && 
rhs);            \
     template void Field::FUNC_NAME<TYPE_STRING>(                               
              \
             typename PrimitiveTypeTraits<TYPE_STRING>::NearestFieldType && 
rhs);             \
+    template void Field::FUNC_NAME<TYPE_VARBINARY>(                            
              \
+            typename PrimitiveTypeTraits<TYPE_VARBINARY>::NearestFieldType && 
rhs);          \
     template void Field::FUNC_NAME<TYPE_HLL>(                                  
              \
             typename PrimitiveTypeTraits<TYPE_HLL>::NearestFieldType && rhs);  
              \
     template void Field::FUNC_NAME<TYPE_VARIANT>(                              
              \
diff --git a/be/src/vec/core/field.h b/be/src/vec/core/field.h
index 349be64cba3..1131ecfc4f7 100644
--- a/be/src/vec/core/field.h
+++ b/be/src/vec/core/field.h
@@ -272,9 +272,10 @@ public:
         return f;
     }
     template <PrimitiveType T>
-    static Field create_field(const typename 
PrimitiveTypeTraits<T>::NearestFieldType&& data) {
+    static Field create_field(typename 
PrimitiveTypeTraits<T>::NearestFieldType&& data) {
         auto f = Field(PrimitiveTypeTraits<T>::NearestPrimitiveType);
-        f.template 
create_concrete<PrimitiveTypeTraits<T>::NearestPrimitiveType>(data);
+        f.template 
create_concrete<PrimitiveTypeTraits<T>::NearestPrimitiveType>(
+                std::forward<typename 
PrimitiveTypeTraits<T>::NearestFieldType>(data));
         return f;
     }
 
@@ -506,8 +507,10 @@ private:
     void assign_concrete(const typename 
PrimitiveTypeTraits<Type>::NearestFieldType& x);
 
     void create(const Field& field);
+    void create(Field&& field);
 
     void assign(const Field& x);
+    void assign(Field&& x);
 
     void destroy();
 
diff --git a/be/test/vec/columns/column_variant_test.cpp 
b/be/test/vec/columns/column_variant_test.cpp
index dad019d500f..a99bc3a2be9 100644
--- a/be/test/vec/columns/column_variant_test.cpp
+++ b/be/test/vec/columns/column_variant_test.cpp
@@ -3078,7 +3078,7 @@ EXPECT_EQ(info.num_dimensions, 2);
 
     Field array = Field::create_field<TYPE_ARRAY>(Array());
     
array.get<Array>().push_back(Field::create_field<TYPE_JSONB>(std::move(field)));
-    
array.get<Array>().push_back(Field::create_field<TYPE_JSONB>(std::move(JsonbField())));
+    
array.get<Array>().push_back(Field::create_field<TYPE_JSONB>(JsonbField()));
     FieldInfo info;
     schema_util::get_field_info(array, &info);
     // which should support ??!!
diff --git a/be/test/vec/core/field_test.cpp b/be/test/vec/core/field_test.cpp
index bdb3eb7a3fe..260e5ace6c5 100644
--- a/be/test/vec/core/field_test.cpp
+++ b/be/test/vec/core/field_test.cpp
@@ -184,4 +184,92 @@ TEST(VFieldTest, jsonb_field_io) {
     }
 }
 
+TEST(VFieldTest, field_create) {
+    Field string_f = Field::create_field<TYPE_STRING>(String {"Hello, world 
(1)"});
+    Field string_copy = Field::create_field<TYPE_STRING>(String {"Hello, world 
(1)"});
+
+    string_copy = std::move(string_f);
+    string_copy = string_f;
+
+    Field int_f = Field::create_field<TYPE_INT>(1);
+    Field int_copy = Field::create_field<TYPE_INT>(1);
+    int_copy = std::move(int_f);
+    int_copy = int_f;
+
+    Field jsonb = Field::create_field<TYPE_JSONB>(JsonbField {R"({ "key": 
"value" })", 13});
+    Field jsonb_copy = Field::create_field<TYPE_JSONB>(JsonbField {R"({ "key": 
"value" })", 13});
+    jsonb_copy = std::move(jsonb);
+    jsonb_copy = jsonb;
+
+    Field double_f = Field::create_field<TYPE_DOUBLE>(1.0);
+    Field double_copy = Field::create_field<TYPE_DOUBLE>(1.0);
+    double_copy = std::move(double_f);
+    double_copy = double_f;
+
+    Field largeint = Field::create_field<TYPE_LARGEINT>(Int128(1));
+    Field largeint_copy = Field::create_field<TYPE_LARGEINT>(Int128(1));
+    largeint_copy = std::move(largeint);
+    largeint_copy = largeint;
+
+    Field array_f = Field::create_field<TYPE_ARRAY>(Array {int_f});
+    Field array_copy = Field::create_field<TYPE_ARRAY>(Array {int_f});
+    array_copy = std::move(array_f);
+    array_copy = array_f;
+
+    Field map_f = Field::create_field<TYPE_MAP>(Map {int_f, string_f});
+    Field map_copy = Field::create_field<TYPE_MAP>(Map {int_f, string_f});
+    map_copy = std::move(map_f);
+    map_copy = map_f;
+
+    Field ipv4_f = Field::create_field<TYPE_IPV4>(IPv4(1));
+    Field ipv4_copy = Field::create_field<TYPE_IPV4>(IPv4(1));
+    ipv4_copy = std::move(ipv4_f);
+    ipv4_copy = ipv4_f;
+
+    Field ipv6_f = Field::create_field<TYPE_IPV6>(IPv6(1));
+    Field ipv6_copy = Field::create_field<TYPE_IPV6>(IPv6(1));
+    ipv6_copy = std::move(ipv6_f);
+    ipv6_copy = ipv6_f;
+
+    Field decimal32_f = Field::create_field<TYPE_DECIMAL32>(Decimal32(1));
+    Field decimal32_copy = Field::create_field<TYPE_DECIMAL32>(Decimal32(1));
+    decimal32_copy = std::move(decimal32_f);
+    decimal32_copy = decimal32_f;
+
+    Field decimal64_f = Field::create_field<TYPE_DECIMAL64>(Decimal64(1));
+    Field decimal64_copy = Field::create_field<TYPE_DECIMAL64>(Decimal64(1));
+    decimal64_copy = std::move(decimal64_f);
+    decimal64_copy = decimal64_f;
+
+    Field decimal128_f = 
Field::create_field<TYPE_DECIMAL128I>(Decimal128V3(1));
+    Field decimal128_copy = 
Field::create_field<TYPE_DECIMAL128I>(Decimal128V3(1));
+    decimal128_copy = std::move(decimal128_f);
+    decimal128_copy = decimal128_f;
+
+    Field decimal256_f = Field::create_field<TYPE_DECIMAL256>(Decimal256(1));
+    Field decimal256_copy = 
Field::create_field<TYPE_DECIMAL256>(Decimal256(1));
+    decimal256_copy = std::move(decimal256_f);
+    decimal256_copy = decimal256_f;
+
+    Field bitmap_f = Field::create_field<TYPE_BITMAP>(BitmapValue(1));
+    Field bitmap_copy = Field::create_field<TYPE_BITMAP>(BitmapValue(1));
+    bitmap_copy = std::move(bitmap_f);
+    bitmap_copy = bitmap_f;
+
+    Field hll_f = Field::create_field<TYPE_HLL>(HyperLogLog(1));
+    Field hll_copy = Field::create_field<TYPE_HLL>(HyperLogLog(1));
+    hll_copy = std::move(hll_f);
+    hll_copy = hll_f;
+
+    Field quantile_state_f = 
Field::create_field<TYPE_QUANTILE_STATE>(QuantileState(1));
+    Field quantile_state_copy = 
Field::create_field<TYPE_QUANTILE_STATE>(QuantileState(1));
+    quantile_state_copy = std::move(quantile_state_f);
+    quantile_state_copy = quantile_state_f;
+
+    Field bitmap_value_f = Field::create_field<TYPE_BITMAP>(BitmapValue(1));
+    Field bitmap_value_copy = Field::create_field<TYPE_BITMAP>(BitmapValue(1));
+    bitmap_value_copy = std::move(bitmap_value_f);
+    bitmap_value_copy = bitmap_value_f;
+}
+
 } // namespace doris::vectorized


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to