diff --git a/be/src/olap/schema_change.cpp b/be/src/olap/schema_change.cpp index 475a0bac93..8a3f900832 100644 --- a/be/src/olap/schema_change.cpp +++ b/be/src/olap/schema_change.cpp @@ -337,6 +337,7 @@ bool RowBlockChanger::change_row_block( } } } else if ((newtype == OLAP_FIELD_TYPE_DATE && reftype == OLAP_FIELD_TYPE_DATETIME) + || (newtype == OLAP_FIELD_TYPE_DATETIME && reftype == OLAP_FIELD_TYPE_DATE) || (newtype == OLAP_FIELD_TYPE_DOUBLE && reftype == OLAP_FIELD_TYPE_FLOAT)) { for (size_t row_index = 0, new_row_index = 0; row_index < ref_block->row_block_info().row_num; ++row_index) { diff --git a/be/src/olap/types.h b/be/src/olap/types.h index 711c48ae60..08ba052543 100644 --- a/be/src/olap/types.h +++ b/be/src/olap/types.h @@ -523,6 +523,19 @@ struct FieldTypeTraits : public BaseFieldtypeTraits
    type() == FieldType::OLAP_FIELD_TYPE_DATE) { + using SrcType = typename CppTypeTraits::CppType; + auto value = *reinterpret_cast(src); + int day = static_cast(value & 31); + int mon = static_cast(value >> 5 & 15); + int year = static_cast(value >> 9); + *reinterpret_cast(dest) = (year * 10000L + mon * 100L + day) * 1000000; + return OLAPStatus::OLAP_SUCCESS; + } + return OLAPStatus::OLAP_ERR_INVALID_SCHEMA; + } static void set_to_max(void* buf) { // 设置为最大时间,其含义为:9999-12-31 23:59:59 *reinterpret_cast(buf) = 99991231235959L; diff --git a/be/test/olap/schema_change_test.cpp b/be/test/olap/schema_change_test.cpp index 4efc2984a9..871228b18d 100644 --- a/be/test/olap/schema_change_test.cpp +++ b/be/test/olap/schema_change_test.cpp @@ -377,6 +377,69 @@ TEST_F(TestColumn, ConvertDatetimeToDate) { ASSERT_TRUE( st == OLAP_ERR_INVALID_SCHEMA); } +TEST_F(TestColumn, ConvertDateToDatetime) { + AddColumn( + "DateColumn", + "DATE", + "REPLACE", + 3, + false, + true); + AddColumn( + "DateTimeColumn", + "DATETIME", + "REPLACE", + 8, + false, + false); + + TabletSchema tablet_schema; + InitTablet(&tablet_schema); + CreateColumnWriter(tablet_schema); + + RowCursor write_row; + write_row.init(tablet_schema); + + RowBlock block(&tablet_schema); + RowBlockInfo block_info; + block_info.row_num = 10000; + block.init(block_info); + + std::vector val_string_array; + std::string origin_val = "2019-12-04"; + std::string convert_val = "2019-12-04 00:00:00"; + val_string_array.emplace_back(origin_val); + val_string_array.emplace_back(convert_val); + OlapTuple tuple(val_string_array); + write_row.from_tuple(tuple); + block.set_row(0, write_row); + block.finalize(1); + ASSERT_EQ(_column_writer->write_batch(&block, &write_row), OLAP_SUCCESS); + + ColumnDataHeaderMessage header_message; + ASSERT_EQ(_column_writer->finalize(&header_message), OLAP_SUCCESS); + + CreateColumnReader(tablet_schema); + RowCursor read_row; + read_row.init(tablet_schema); + _col_vector.reset(new ColumnVector()); + ASSERT_EQ(_column_reader->next_vector( + _col_vector.get(), 1, _mem_pool.get()), OLAP_SUCCESS); + char* data = reinterpret_cast(_col_vector->col_data()); + read_row.set_field_content(0, data, _mem_pool.get()); + char* src = read_row.cell_ptr(0); + const Field* src_field = read_row.column_schema(0); + read_row.convert_from(1, src, src_field->type_info(), _mem_pool.get()); + read_row.cell_ptr(1); + std::string dest_string = read_row.column_schema(1)->to_string(read_row.cell_ptr(1)); + ASSERT_TRUE(dest_string.compare(convert_val) == 0); + + //test not support type + TypeInfo* tp = get_type_info(OLAP_FIELD_TYPE_HLL); + OLAPStatus st = read_row.convert_from(1, src, tp, _mem_pool.get()); + ASSERT_TRUE( st == OLAP_ERR_INVALID_SCHEMA); +} + } int main(int argc, char** argv) { diff --git a/fe/src/main/java/org/apache/doris/catalog/ColumnType.java b/fe/src/main/java/org/apache/doris/catalog/ColumnType.java index 0f30e4a518..ef6403278d 100644 --- a/fe/src/main/java/org/apache/doris/catalog/ColumnType.java +++ b/fe/src/main/java/org/apache/doris/catalog/ColumnType.java @@ -65,6 +65,7 @@ public abstract class ColumnType { schemaChangeMatrix[PrimitiveType.DATETIME.ordinal()][PrimitiveType.DATE.ordinal()] = true; schemaChangeMatrix[PrimitiveType.FLOAT.ordinal()][PrimitiveType.DOUBLE.ordinal()] = true; + schemaChangeMatrix[PrimitiveType.DATE.ordinal()][PrimitiveType.DATETIME.ordinal()] = true; } static boolean isSchemaChangeAllowed(Type lhs, Type rhs) {