1515// specific language governing permissions and limitations
1616// under the License.
1717
18+ #include < arrow/api.h>
19+ #include < cctz/time_zone.h>
1820#include < gtest/gtest-message.h>
1921#include < gtest/gtest-test-part.h>
2022#include < gtest/gtest.h>
@@ -221,4 +223,66 @@ TEST_F(DataTypeDateTimeV2SerDeTest, serdes) {
221223 test_func (*serde_time_v2_0, column_time_v2_0);
222224}
223225
224- } // namespace doris::vectorized
226+ // Run with UBSan enabled to catch misalignment errors.
227+ TEST_F (DataTypeDateTimeV2SerDeTest, ArrowMemNotAlignedDate) {
228+ // 1.Prepare the data.
229+ std::vector<int32_t > dates = {0 , 365 , 1000 , 5000 , 10000 };
230+ const int64_t num_elements = dates.size ();
231+ const int64_t element_size = sizeof (int32_t );
232+
233+ // 2.Create an unaligned memory buffer.
234+ std::vector<uint8_t > data_storage (num_elements * element_size + 10 );
235+ uint8_t * unaligned_data = data_storage.data () + 1 ;
236+
237+ // 3.Copy data to unaligned memory
238+ for (size_t i = 0 ; i < dates.size (); ++i) {
239+ memcpy (unaligned_data + i * element_size, &dates[i], element_size);
240+ }
241+
242+ // 4. Create Arrow array with unaligned memory
243+ auto unaligned_buffer = arrow::Buffer::Wrap (unaligned_data, num_elements * element_size);
244+ auto arr = std::make_shared<arrow::Date32Array>(num_elements, unaligned_buffer);
245+ const auto * raw_values_ptr = arr->raw_values ();
246+ uintptr_t address = reinterpret_cast <uintptr_t >(raw_values_ptr);
247+ EXPECT_EQ (address % 4 , 1 );
248+
249+ // 5.Test read_column_from_arrow
250+ cctz::time_zone tz;
251+ auto st = serde_date_v2->read_column_from_arrow (*column_date_v2, arr.get (), 0 , 1 , tz);
252+ EXPECT_TRUE (st.ok ());
253+ }
254+
255+ // Run with UBSan enabled to catch misalignment errors.
256+ TEST_F (DataTypeDateTimeV2SerDeTest, ArrowMemNotAlignedDateTime) {
257+ // 1.Prepare the data.
258+ std::vector<int64_t > timestamps = {0 , 86400000000 , 31536000000000 , 100000000000 , 500000000000 };
259+ const int64_t num_elements = timestamps.size ();
260+ const int64_t element_size = sizeof (int64_t );
261+
262+ // 2.Create an unaligned memory buffer.
263+ std::vector<uint8_t > data_storage (num_elements * element_size + 10 );
264+ uint8_t * unaligned_data = data_storage.data () + 1 ;
265+
266+ // 3. Copy data to unaligned memory
267+ for (size_t i = 0 ; i < timestamps.size (); ++i) {
268+ memcpy (unaligned_data + i * element_size, ×tamps[i], element_size);
269+ }
270+
271+ // 4. Create Arrow array with unaligned memory
272+ auto unaligned_buffer = arrow::Buffer::Wrap (unaligned_data, num_elements * element_size);
273+ auto timestamp_type = arrow::timestamp (arrow::TimeUnit::MICRO);
274+ auto arr =
275+ std::make_shared<arrow::TimestampArray>(timestamp_type, num_elements, unaligned_buffer);
276+
277+ const auto * raw_values_ptr = arr->raw_values ();
278+ uintptr_t address = reinterpret_cast <uintptr_t >(raw_values_ptr);
279+ EXPECT_EQ (address % 4 , 1 );
280+
281+ // 5.Test read_column_from_arrow
282+ cctz::time_zone tz;
283+ auto st =
284+ serde_datetime_v2_6->read_column_from_arrow (*column_datetime_v2_6, arr.get (), 0 , 1 , tz);
285+ EXPECT_TRUE (st.ok ());
286+ }
287+
288+ } // namespace doris::vectorized
0 commit comments