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]

Reply via email to