You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by al...@apache.org on 2021/12/10 18:00:42 UTC

[kudu] branch master updated: [client] KUDU-2623 Expose table as public in WriteOp

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

alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new 370e58c  [client] KUDU-2623 Expose table as public in WriteOp
370e58c is described below

commit 370e58c2fa4169e72dc4857dee5318d5c4d49bda
Author: Zoltan Chovan <zc...@cloudera.com>
AuthorDate: Tue Dec 7 15:25:33 2021 +0100

    [client] KUDU-2623 Expose table as public in WriteOp
    
    Making KuduWriteOperation::table() method public to enable identification
    of the problematic table when an error happens.
    
    Change-Id: Idbfff6e931304cce7826bc272811155f57a5c4e5
    Reviewed-on: http://gerrit.cloudera.org:8080/18075
    Tested-by: Kudu Jenkins
    Reviewed-by: Alexey Serbin <as...@cloudera.com>
    Reviewed-by: Attila Bukor <ab...@apache.org>
---
 src/kudu/client/client-test.cc | 31 +++++++++++++++++++++++++++++++
 src/kudu/client/write_op.h     |  5 +++--
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/kudu/client/client-test.cc b/src/kudu/client/client-test.cc
index 8eec04b..fc9c768 100644
--- a/src/kudu/client/client-test.cc
+++ b/src/kudu/client/client-test.cc
@@ -3532,6 +3532,37 @@ TEST_F(ClientTest, TestBatchWithPartialErrorOfAllRowsFailed) {
             "int32 non_null_with_default=12345)", rows[1]);
 }
 
+TEST_F(ClientTest, TestInsertDuplicateKeys) {
+  shared_ptr<KuduSession> session = client_->NewSession();
+  ASSERT_OK(session->SetFlushMode(KuduSession::AUTO_FLUSH_BACKGROUND));
+
+  constexpr const char* kTable2Name = "client-testtb2";
+  shared_ptr<KuduTable> second_table;
+  NO_FATALS(CreateTable(kTable2Name, 1, {}, {}, &second_table));
+
+  // Insert initial rows
+  ASSERT_OK(ApplyInsertToSession(session.get(), client_table_, 1, 1, "one"));
+  ASSERT_OK(ApplyInsertToSession(session.get(), second_table, 1, 1, "one"));
+  FlushSessionOrDie(session);
+
+  // Try to insert a row with duplicate key and two valid rows
+  ASSERT_OK(ApplyInsertToSession(session.get(), client_table_, 2, 1, "Should suceed"));
+  ASSERT_OK(ApplyInsertToSession(session.get(), second_table, 1, 1, "Attempted dup"));
+  ASSERT_OK(ApplyInsertToSession(session.get(), second_table, 2, 1, "Should succeed"));
+  Status s = session->Flush();
+  ASSERT_TRUE(s.IsIOError()) << s.ToString();
+  ASSERT_STR_CONTAINS(s.ToString(),
+                      "failed to flush data: error details are available "
+                      "via KuduSession::GetPendingErrors()");
+  // Fetch and verify the reported errors.
+  vector<KuduError*> errors;
+  ElementDeleter d(&errors);
+  session->GetPendingErrors(&errors, nullptr);
+  // Should be able to determine the table the error belongs to
+  ASSERT_EQ(1, errors.size());
+  ASSERT_EQ(errors[0]->failed_op().table()->name(), second_table->name());
+}
+
 void ClientTest::DoTestWriteWithDeadServer(WhichServerToKill which) {
   shared_ptr<KuduSession> session = client_->NewSession();
   session->SetTimeoutMillis(1000);
diff --git a/src/kudu/client/write_op.h b/src/kudu/client/write_op.h
index 243aca8..a1e9e30 100644
--- a/src/kudu/client/write_op.h
+++ b/src/kudu/client/write_op.h
@@ -93,6 +93,9 @@ class KUDU_EXPORT KuduWriteOperation {
   /// @note this method does note redact row values. The
   ///   caller must handle redaction themselves, if necessary.
   virtual std::string ToString() const = 0;
+
+  const KuduTable* table() const { return table_.get(); }
+
  protected:
   /// @cond PROTECTED_MEMBERS_DOCUMENTED
 
@@ -121,8 +124,6 @@ class KUDU_EXPORT KuduWriteOperation {
   friend class internal::ErrorCollector;
   friend class KuduSession;
 
-  const KuduTable* table() const { return table_.get(); }
-
   // Return the number of bytes required to buffer this operation,
   // including direct and indirect data. Once called, the result is cached
   // so subsequent calls will return the size previously computed.