This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch branch-1.2-lts in repository https://gitbox.apache.org/repos/asf/doris.git
commit c7c2358354b94c7641939f8e073c7d4f901cb4c3 Author: yongkang.zhong <[email protected]> AuthorDate: Thu Mar 23 18:49:50 2023 +0800 [Fix](SAP Hana External Table) fix that SAP Hana external table can not insert batch values (#17957) In the batch insertion scenario, sap hana database does not support syntax insert into tables values (...),(...); what it supports is: ```sql INSERT INTO table(col1,col2) SELECT c1v1, c2v1 FROM dummy UNION ALL SELECT c1v2, c2v2 FROM dummy; ``` --- be/src/exec/table_connector.cpp | 39 +++++++++++++++++++++++++++++++++++++++ be/src/exec/table_connector.h | 8 ++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/be/src/exec/table_connector.cpp b/be/src/exec/table_connector.cpp index 534c463571..00114adee8 100644 --- a/be/src/exec/table_connector.cpp +++ b/be/src/exec/table_connector.cpp @@ -173,6 +173,13 @@ Status TableConnector::append(const std::string& table_name, vectorized::Block* // Translate utf8 string to utf16 to use unicode encoding insert_stmt = utf8_to_u16string(_insert_stmt_buffer.data(), _insert_stmt_buffer.data() + _insert_stmt_buffer.size()); + } else if (table_type == TOdbcTableType::SAP_HANA) { + SCOPED_TIMER(_convert_tuple_timer); + sap_hana_type_append(table_name, block, output_vexpr_ctxs, start_send_row, num_rows_sent, + table_type); + // Translate utf8 string to utf16 to use unicode encoding + insert_stmt = utf8_to_u16string(_insert_stmt_buffer.data(), + _insert_stmt_buffer.data() + _insert_stmt_buffer.size()); } else { SCOPED_TIMER(_convert_tuple_timer); fmt::format_to(_insert_stmt_buffer, "INSERT INTO {} VALUES (", table_name); @@ -242,6 +249,38 @@ Status TableConnector::oracle_type_append( return Status::OK(); } +Status TableConnector::sap_hana_type_append( + const std::string& table_name, vectorized::Block* block, + const std::vector<vectorized::VExprContext*>& output_vexpr_ctxs, uint32_t start_send_row, + uint32_t* num_rows_sent, TOdbcTableType::type table_type) { + fmt::format_to(_insert_stmt_buffer, "INSERT INTO {} ", table_name); + int num_rows = block->rows(); + int num_columns = block->columns(); + for (int i = start_send_row; i < num_rows; ++i) { + (*num_rows_sent)++; + fmt::format_to(_insert_stmt_buffer, "SELECT "); + // Construct insert statement of odbc/jdbc table + for (int j = 0; j < num_columns; ++j) { + if (j != 0) { + fmt::format_to(_insert_stmt_buffer, "{}", ", "); + } + auto& column_ptr = block->get_by_position(j).column; + auto& type_ptr = block->get_by_position(j).type; + RETURN_IF_ERROR(convert_column_data( + column_ptr, type_ptr, output_vexpr_ctxs[j]->root()->type(), i, table_type)); + } + + if (i < num_rows - 1 && _insert_stmt_buffer.size() < INSERT_BUFFER_SIZE) { + fmt::format_to(_insert_stmt_buffer, "{}", " FROM dummy UNION ALL "); + } else { + // batch exhausted or _insert_stmt_buffer is full, need to do real insert stmt + fmt::format_to(_insert_stmt_buffer, "{}", " FROM dummy"); + break; + } + } + return Status::OK(); +} + Status TableConnector::convert_column_data(const vectorized::ColumnPtr& column_ptr, const vectorized::DataTypePtr& type_ptr, const TypeDescriptor& type, int row, diff --git a/be/src/exec/table_connector.h b/be/src/exec/table_connector.h index 3fe0ec5721..87e23e4618 100644 --- a/be/src/exec/table_connector.h +++ b/be/src/exec/table_connector.h @@ -89,13 +89,17 @@ protected: RuntimeProfile::Counter* _sent_rows_counter = nullptr; private: - // Because Oracle database do not support + // Because Oracle and SAP Hana database do not support // insert into tables values (...),(...); - // Here we do something special for Oracle. + // Here we do something special for Oracle and SAP Hana. Status oracle_type_append(const std::string& table_name, vectorized::Block* block, const std::vector<vectorized::VExprContext*>& output_vexpr_ctxs, uint32_t start_send_row, uint32_t* num_rows_sent, TOdbcTableType::type table_type); + Status sap_hana_type_append(const std::string& table_name, vectorized::Block* block, + const std::vector<vectorized::VExprContext*>& output_vexpr_ctxs, + uint32_t start_send_row, uint32_t* num_rows_sent, + TOdbcTableType::type table_type); }; } // namespace doris --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
