You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by la...@apache.org on 2023/05/26 04:04:28 UTC
[kudu] branch branch-1.17.x updated (476aaa995 -> b68bbf66f)
This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a change to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
from 476aaa995 KUDU-1945 Update docs with non-unique PK
new 9f90e2389 [client] fix API non-compliance in KuduUpsertIgnore
new 27e85acf7 [Python] Add support for comment in ColumnSchema
new b68bbf66f KUDU-1945 Add C++ example for non-unique PK
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
examples/cpp/CMakeLists.txt | 4 +
examples/cpp/non_unique_primary_key.cc | 375 ++++++++++++++++++++++++++++++++
python/kudu/libkudu_client.pxd | 2 +
python/kudu/schema.pyx | 26 ++-
python/kudu/tests/common.py | 2 +-
python/kudu/tests/test_client.py | 13 +-
python/kudu/tests/test_schema.py | 15 ++
src/kudu/client/CMakeLists.txt | 1 +
src/kudu/client/client_examples-test.sh | 1 +
src/kudu/client/write_op.h | 6 +-
10 files changed, 438 insertions(+), 7 deletions(-)
create mode 100644 examples/cpp/non_unique_primary_key.cc
[kudu] 03/03: KUDU-1945 Add C++ example for non-unique PK
Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit b68bbf66f4281bbab986e2a3e113bbd930fff00a
Author: Marton Greber <gr...@gmail.com>
AuthorDate: Thu Mar 30 17:32:52 2023 +0000
KUDU-1945 Add C++ example for non-unique PK
This patch adds an example based on Kudu C++ client API to showcase the
main operations performed on a table having a non-unique primary key.
STDOUT of the example:
Created a client connection
Created the schema:
(
non_unique_key INT32 NOT NULL,
auto_incrementing_id INT64 NOT NULL,
int_val INT32 NOT NULL,
PRIMARY KEY (non_unique_key, auto_incrementing_id)
)
Created the table
Inserted some row(s) into the table:
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=2, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=2, int64 auto_incrementing_id=5, int32 int_val=1)
(int32 non_unique_key=2, int64 auto_incrementing_id=6, int32 int_val=2)
Demonstrating scanning ...
Scanned some row(s) WHERE non_unique_key = 1:
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=2)
Demonstrating UPDATE ...
Updated row(s) WHERE non_unique_key = 1 AND int_val = 2 to int_val = 98
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
(int32 non_unique_key=2, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=2, int64 auto_incrementing_id=5, int32 int_val=1)
(int32 non_unique_key=2, int64 auto_incrementing_id=6, int32 int_val=2)
Updated row(s) WHERE non_unique_key = 2 to int_val = 99
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
(int32 non_unique_key=2, int64 auto_incrementing_id=4, int32 int_val=99)
(int32 non_unique_key=2, int64 auto_incrementing_id=5, int32 int_val=99)
(int32 non_unique_key=2, int64 auto_incrementing_id=6, int32 int_val=99)
Updated row(s) WHERE non_unique_key = 2 AND auto_incrementing_id = 5 to\
int_val = 100
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
(int32 non_unique_key=2, int64 auto_incrementing_id=4, int32 int_val=99)
(int32 non_unique_key=2, int64 auto_incrementing_id=5, int32 int_val=\
100)
(int32 non_unique_key=2, int64 auto_incrementing_id=6, int32 int_val=99)
Demonstrating DELETE ...
Deleted row(s) WHERE non_unique_key = 3 AND int_val = 1
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
(int32 non_unique_key=2, int64 auto_incrementing_id=4, int32 int_val=99)
(int32 non_unique_key=2, int64 auto_incrementing_id=5, int32 int_val=\
100)
(int32 non_unique_key=2, int64 auto_incrementing_id=6, int32 int_val=99)
Deleted row(s) WHERE non_unique_key = 2
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=3, int64 auto_incrementing_id=3, int32 int_val=2)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
Deleted row(s) WHERE non_unique_key = 3 AND auto_incrementing_id = 3
(int32 non_unique_key=3, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=4, int64 auto_incrementing_id=4, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=1, int32 int_val=0)
(int32 non_unique_key=1, int64 auto_incrementing_id=2, int32 int_val=1)
(int32 non_unique_key=1, int64 auto_incrementing_id=3, int32 int_val=98)
Deleted the table
Done
Change-Id: I8c6be6bece56788dc858468d1fcccff6955836ec
Reviewed-on: http://gerrit.cloudera.org:8080/19690
Tested-by: Alexey Serbin <al...@apache.org>
Reviewed-by: Alexey Serbin <al...@apache.org>
Reviewed-on: http://gerrit.cloudera.org:8080/19920
Tested-by: Kudu Jenkins
Reviewed-by: Marton Greber <gr...@gmail.com>
Reviewed-by: Yingchun Lai <la...@apache.org>
---
examples/cpp/CMakeLists.txt | 4 +
examples/cpp/non_unique_primary_key.cc | 375 ++++++++++++++++++++++++++++++++
src/kudu/client/CMakeLists.txt | 1 +
src/kudu/client/client_examples-test.sh | 1 +
4 files changed, 381 insertions(+)
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 62bc177d6..688aaf149 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -18,9 +18,13 @@
# Client API example executables
cmake_minimum_required(VERSION 2.8)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(kuduClient REQUIRED)
include_directories(${KUDU_CLIENT_INCLUDE_DIR})
add_executable(example example.cc)
target_link_libraries(example kudu_client)
+
+add_executable(non_unique_primary_key non_unique_primary_key.cc)
+target_link_libraries(non_unique_primary_key kudu_client)
diff --git a/examples/cpp/non_unique_primary_key.cc b/examples/cpp/non_unique_primary_key.cc
new file mode 100644
index 000000000..8b8271a2f
--- /dev/null
+++ b/examples/cpp/non_unique_primary_key.cc
@@ -0,0 +1,375 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <ctime>
+#include <iostream>
+#include <sstream>
+#include <memory>
+
+#include "kudu/client/client.h"
+#include "kudu/client/row_result.h"
+#include "kudu/client/stubs.h"
+#include "kudu/client/value.h"
+#include "kudu/client/write_op.h"
+#include "kudu/common/partial_row.h"
+#include "kudu/util/monotime.h"
+
+using kudu::client::KuduClient;
+using kudu::client::KuduClientBuilder;
+using kudu::client::KuduColumnSchema;
+using kudu::client::KuduDelete;
+using kudu::client::KuduError;
+using kudu::client::KuduInsert;
+using kudu::client::KuduPredicate;
+using kudu::client::KuduScanBatch;
+using kudu::client::KuduScanner;
+using kudu::client::KuduSchema;
+using kudu::client::KuduSchemaBuilder;
+using kudu::client::KuduSession;
+using kudu::client::KuduTable;
+using kudu::client::KuduTableAlterer;
+using kudu::client::KuduTableCreator;
+using kudu::client::KuduUpdate;
+using kudu::client::KuduValue;
+using kudu::client::KuduWriteOperation;
+using kudu::client::sp::shared_ptr;
+using kudu::KuduPartialRow;
+using kudu::MonoDelta;
+using kudu::Status;
+
+using std::ostringstream;
+using std::string;
+using std::vector;
+using std::unique_ptr;
+
+static Status CreateClient(const vector<string>& master_addrs,
+ shared_ptr<KuduClient>* client) {
+ return KuduClientBuilder()
+ .master_server_addrs(master_addrs)
+ .default_admin_operation_timeout(MonoDelta::FromSeconds(20))
+ .Build(client);
+}
+
+static KuduSchema CreateSchema() {
+ KuduSchema schema;
+ KuduSchemaBuilder b;
+ // Columns which are not uniquely identifiable can still be used as primary keys by
+ // specifying them as non-unique primary key.
+ b.AddColumn("non_unique_key")->Type(KuduColumnSchema::INT32)->NotNull()->NonUniquePrimaryKey();
+ b.AddColumn("int_val")->Type(KuduColumnSchema::INT32)->NotNull();
+ KUDU_CHECK_OK(b.Build(&schema));
+ return schema;
+}
+
+static Status CreateTable(const shared_ptr<KuduClient>& client,
+ const string& table_name,
+ const KuduSchema& schema) {
+ vector<string> column_names;
+ // Use the non-unique key column for hash partitioning. The column at index 0 in the schema refers
+ // to the non-unique key column specified above. The auto-incrementing column is always inserted as
+ // the last key column.
+ column_names.push_back(schema.Column(0).name());
+ unique_ptr<KuduTableCreator> table_creator(client->NewTableCreator());
+ table_creator->table_name(table_name)
+ .schema(&schema)
+ .add_hash_partitions(column_names, 2);
+ Status s = table_creator->Create();
+ return s;
+}
+
+static Status InsertStaleCounterRows(const shared_ptr<KuduTable>& table, int num_rows,
+ int divisor) {
+ shared_ptr<KuduSession> session = table->client()->NewSession();
+ KUDU_RETURN_NOT_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
+
+ int stale_counter = 0;
+ for (int i = 0; i < num_rows; i++) {
+ if (i % divisor == 0) {
+ stale_counter++;
+ }
+ unique_ptr<KuduInsert> new_insert(table->NewInsert());
+ KuduPartialRow* row = new_insert->mutable_row();
+ // The auto-incrementing column is populated on the server-side automatically.
+ KUDU_CHECK_OK(row->SetInt32("non_unique_key", stale_counter));
+ KUDU_CHECK_OK(row->SetInt32("int_val", i % divisor));
+ KUDU_CHECK_OK(session->Apply(new_insert.release()));
+ }
+
+ KUDU_RETURN_NOT_OK(session->Flush());
+ return session->Close();
+}
+
+static Status ScanRows(const shared_ptr<KuduTable>& table, vector<KuduPredicate*> predicates) {
+ KuduScanner scanner(table.get());
+ for (int i = 0; i < predicates.size(); i++) {
+ KUDU_RETURN_NOT_OK(scanner.AddConjunctPredicate(predicates[i]));
+ }
+ KUDU_RETURN_NOT_OK(scanner.Open());
+
+ KuduScanBatch batch;
+ while (scanner.HasMoreRows()) {
+ KUDU_RETURN_NOT_OK(scanner.NextBatch(&batch));
+ for (KuduScanBatch::const_iterator it = batch.begin(); it != batch.end(); ++it) {
+ KuduScanBatch::RowPtr row(*it);
+ // The row contains the auto-incrementing column. If one doesn't requre it, it can be
+ // discarded through a projection.
+ KUDU_LOG(INFO) << row.ToString();
+ }
+ }
+ return Status::OK();
+}
+
+static Status UpdateRows(const shared_ptr<KuduTable>& table,
+ vector<KuduPredicate*> predicates, int new_val){
+ // It's necessary to specify the entire set of key columns when updating a particular row.
+ // An auto-incrementing column is auto-populated at the server side, and one way to retrieve
+ // its values is scanning the table with a projection that includes the auto-incrementing column.
+ KuduScanner scanner(table.get());
+ for (int i = 0; i < predicates.size(); i++) {
+ KUDU_RETURN_NOT_OK(scanner.AddConjunctPredicate(predicates[i]));
+ }
+ KUDU_RETURN_NOT_OK(scanner.Open());
+
+ shared_ptr<KuduSession> session = table->client()->NewSession();
+ KUDU_RETURN_NOT_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
+
+ while (scanner.HasMoreRows()) {
+ KuduScanBatch batch;
+ KUDU_RETURN_NOT_OK(scanner.NextBatch(&batch));
+ for (KuduScanBatch::const_iterator it = batch.begin(); it != batch.end(); ++it) {
+ KuduScanBatch::RowPtr row(*it);
+ int64_t auto_incrementing_counter;
+ int32_t non_unique_key, val;
+
+ KUDU_RETURN_NOT_OK(row.GetInt32("non_unique_key", &non_unique_key));
+ KUDU_RETURN_NOT_OK(row.GetInt64(KuduSchema::GetAutoIncrementingColumnName(),
+ &auto_incrementing_counter));
+ KUDU_RETURN_NOT_OK(row.GetInt32("int_val", &val));
+
+ unique_ptr<KuduUpdate> new_update(table->NewUpdate());
+ KuduPartialRow* update_row = new_update->mutable_row();
+ KUDU_RETURN_NOT_OK(update_row->SetInt32("non_unique_key", non_unique_key));
+ KUDU_RETURN_NOT_OK(update_row->SetInt64(KuduSchema::GetAutoIncrementingColumnName(),
+ auto_incrementing_counter));
+ KUDU_RETURN_NOT_OK(update_row->SetInt32("int_val", new_val));
+ KUDU_RETURN_NOT_OK(session->Apply(new_update.release()));
+ }
+ }
+
+ KUDU_RETURN_NOT_OK(session->Flush());
+ return session->Close();
+}
+
+static Status DeleteRows(const shared_ptr<KuduTable>& table,
+ vector<KuduPredicate*> predicates){
+ // It's necessary to specify the entire set of key columns when updating a particular row.
+ // An auto-incrementing column is auto-populated at the server side, and one way to retrieve
+ // its values is scanning the table with a projection that includes the auto-incrementing column.
+ KuduScanner scanner(table.get());
+ for (int i = 0; i < predicates.size(); i++) {
+ KUDU_RETURN_NOT_OK(scanner.AddConjunctPredicate(predicates[i]));
+ }
+ KUDU_RETURN_NOT_OK(scanner.Open());
+ KuduScanBatch batch;
+
+ shared_ptr<KuduSession> session = table->client()->NewSession();
+ KUDU_RETURN_NOT_OK(session->SetFlushMode(KuduSession::MANUAL_FLUSH));
+
+ while (scanner.HasMoreRows()) {
+ KUDU_RETURN_NOT_OK(scanner.NextBatch(&batch));
+ for (KuduScanBatch::const_iterator it = batch.begin(); it != batch.end(); ++it) {
+ KuduScanBatch::RowPtr row(*it);
+ int64_t auto_incrementing_counter;
+ int32_t non_unique_key;
+
+ KUDU_RETURN_NOT_OK(row.GetInt64(KuduSchema::GetAutoIncrementingColumnName(),
+ &auto_incrementing_counter));
+ KUDU_RETURN_NOT_OK(row.GetInt32("non_unique_key", &non_unique_key));
+
+ unique_ptr<KuduDelete> new_delete(table->NewDelete());
+ KuduPartialRow* delete_row = new_delete->mutable_row();
+ KUDU_RETURN_NOT_OK(delete_row->SetInt32("non_unique_key", non_unique_key));
+ KUDU_RETURN_NOT_OK(delete_row->SetInt64(KuduSchema::GetAutoIncrementingColumnName(),
+ auto_incrementing_counter));
+ KUDU_RETURN_NOT_OK(session->Apply(new_delete.release()));
+ }
+ }
+
+ KUDU_RETURN_NOT_OK(session->Flush());
+ return session->Close();
+}
+
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ KUDU_LOG(ERROR) << "usage: " << argv[0] << " <master host> ...";
+ return -1;
+ }
+ vector<string> master_addrs;
+ for (int i = 1; i < argc; i++) {
+ master_addrs.push_back(argv[i]);
+ }
+ const string kTableName = "non_unique_primary_key_test_table";
+
+ shared_ptr<KuduClient> client;
+ KUDU_CHECK_OK(CreateClient(master_addrs, &client));
+ KUDU_LOG(INFO) << "Created a client connection";
+
+ // Create a schema with non-unique primary key.
+ KuduSchema schema(CreateSchema());
+ KUDU_LOG(INFO) << "Created the schema:";
+ // The schema stringification shows the presence of the auto-incrementing column,
+ // and the resulting composite primary key.
+ KUDU_LOG(INFO) << schema.ToString();
+
+ KUDU_CHECK_OK(CreateTable(client, kTableName, schema));
+ KUDU_LOG(INFO) << "Created the table";
+
+ // Insert some rows into the table.
+ shared_ptr<KuduTable> table;
+ KUDU_CHECK_OK(client->OpenTable(kTableName, &table));
+ int divisor = 3;
+ int num_rows = 10;
+ KUDU_CHECK_OK(InsertStaleCounterRows(table, num_rows, divisor));
+ KUDU_LOG(INFO) << "Inserted some row(s) into the table:";
+ KUDU_CHECK_OK(ScanRows(table, {}));
+
+ KUDU_LOG(INFO) << "Demonstrating scanning ...";
+ {
+ int non_unique_key_equals = 1;
+ KUDU_LOG(INFO) << "Scanned some row(s) WHERE non_unique_key = "
+ << non_unique_key_equals << ":";
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ KUDU_CHECK_OK(ScanRows(table, predicates));
+ }
+
+ KUDU_LOG(INFO) << "Demonstrating UPDATE ...";
+ // Updating based upon a predicate on a non-unique PK and on a non-PK column
+ {
+ int non_unique_key_equals = 1;
+ int int_val_equals = 2;
+ int new_val = 98;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ p = table->NewComparisonPredicate(
+ "int_val", KuduPredicate::EQUAL, KuduValue::FromInt(int_val_equals));
+ predicates.emplace_back(p);
+ // Update row(s)
+ KUDU_CHECK_OK(UpdateRows(table, predicates, new_val));
+ KUDU_LOG(INFO) << "Updated row(s) WHERE non_unique_key = " << non_unique_key_equals
+ << " AND int_val = " << int_val_equals << " to int_val = " << new_val;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ // Updating based upon a predicate on a non-unique PK
+ {
+ int non_unique_key_equals = 2;
+ int new_val = 99;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ // Update row(s)
+ KUDU_CHECK_OK(UpdateRows(table, predicates, new_val));
+ KUDU_LOG(INFO) << "Updated row(s) WHERE non_unique_key = " << non_unique_key_equals
+ << " to int_val = " << new_val;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ // Updating based upon a predicate on a non-unique PK and on the auto-incrementing column
+ {
+ int non_unique_key_equals = 2;
+ int auto_incrementin_counter_val = 5;
+ int new_val = 100;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ p = table->NewComparisonPredicate(
+ KuduSchema::GetAutoIncrementingColumnName(), KuduPredicate::EQUAL,
+ KuduValue::FromInt(auto_incrementin_counter_val));
+ predicates.emplace_back(p);
+ // Update row(s)
+ KUDU_CHECK_OK(UpdateRows(table, predicates, new_val));
+ KUDU_LOG(INFO) << "Updated row(s) WHERE non_unique_key = " << non_unique_key_equals <<
+ " AND " << KuduSchema::GetAutoIncrementingColumnName() << " = " <<
+ auto_incrementin_counter_val << " to int_val = " << new_val;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ KUDU_LOG(INFO) << "Demonstrating DELETE ...";
+ // Deleting based upon a predicate on a non-unique PK and on a non-PK column
+ {
+ int non_unique_key_equals = 3;
+ int int_val_equals = 1;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ p = table->NewComparisonPredicate(
+ "int_val", KuduPredicate::EQUAL, KuduValue::FromInt(int_val_equals));
+ predicates.emplace_back(p);
+ // Delete row(s)
+ KUDU_CHECK_OK(DeleteRows(table, predicates));
+ KUDU_LOG(INFO) << "Deleted row(s) WHERE non_unique_key = " << non_unique_key_equals
+ << " AND int_val = " << int_val_equals;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ // Deleting based upon a predicate on a non-unique PK
+ {
+ int non_unique_key_equals = 2;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ // Delete row(s)
+ KUDU_CHECK_OK(DeleteRows(table, predicates));
+ KUDU_LOG(INFO) << "Deleted row(s) WHERE non_unique_key = " << non_unique_key_equals;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ // Deleting based upon a predicate on a non-unique PK and on the auto-incrementing column
+ {
+ int non_unique_key_equals = 3;
+ int auto_incrementin_counter_val = 3;
+ vector<KuduPredicate*> predicates;
+ KuduPredicate* p = table->NewComparisonPredicate(
+ "non_unique_key", KuduPredicate::EQUAL, KuduValue::FromInt(non_unique_key_equals));
+ predicates.emplace_back(p);
+ p = table->NewComparisonPredicate(
+ KuduSchema::GetAutoIncrementingColumnName(), KuduPredicate::EQUAL,
+ KuduValue::FromInt(auto_incrementin_counter_val));
+ predicates.emplace_back(p);
+ // Delete row(s)
+ KUDU_CHECK_OK(DeleteRows(table, predicates));
+ KUDU_LOG(INFO) << "Deleted row(s) WHERE non_unique_key = " << non_unique_key_equals <<
+ " AND " << KuduSchema::GetAutoIncrementingColumnName() << " = " <<
+ auto_incrementin_counter_val;
+ KUDU_CHECK_OK(ScanRows(table, {}));
+ }
+
+ KUDU_CHECK_OK(client->DeleteTable(kTableName));
+ KUDU_LOG(INFO) << "Deleted the table";
+ KUDU_LOG(INFO) << "Done";
+ return 0;
+}
diff --git a/src/kudu/client/CMakeLists.txt b/src/kudu/client/CMakeLists.txt
index 65821b3d7..3cc2ab18f 100644
--- a/src/kudu/client/CMakeLists.txt
+++ b/src/kudu/client/CMakeLists.txt
@@ -218,6 +218,7 @@ install(FILES
install(FILES
../../../examples/cpp/CMakeLists.txt
../../../examples/cpp/example.cc
+ ../../../examples/cpp/non_unique_primary_key.cc
DESTINATION ${CMAKE_INSTALL_DATADIR}/doc/kuduClient/examples)
# Exported cmake file for just the library's targets.
diff --git a/src/kudu/client/client_examples-test.sh b/src/kudu/client/client_examples-test.sh
index 562bd1d82..226701fe2 100755
--- a/src/kudu/client/client_examples-test.sh
+++ b/src/kudu/client/client_examples-test.sh
@@ -229,3 +229,4 @@ fi
# Run the examples.
"$EXAMPLES_DIR/example" $LOCALHOST_IP
+"$EXAMPLES_DIR/non_unique_primary_key" $LOCALHOST_IP
[kudu] 01/03: [client] fix API non-compliance in KuduUpsertIgnore
Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 9f90e2389767459b27ba6c6554d36cef35143eeb
Author: Alexey Serbin <al...@apache.org>
AuthorDate: Tue Apr 18 16:49:27 2023 -0700
[client] fix API non-compliance in KuduUpsertIgnore
Kudu C++ client API is still assumed to be C++98 compatible. That's
an invariant that has been in place in the very beginning of 1.x version
history, so it should be kept as-is unless changing the major version.
Prior to this patch, client_examples-test.sh would fail while checking
a standalone compilation of kudu/client/write_op.h
This is a follow-up to ec3a9f75b6924a70ecbf08e3805228ad9b92b9f0.
Change-Id: I83f4e65bc3811ac701f5908beb480b39ad413641
Reviewed-on: http://gerrit.cloudera.org:8080/19765
Reviewed-by: Abhishek Chennaka <ac...@cloudera.com>
Tested-by: Alexey Serbin <al...@apache.org>
Reviewed-on: http://gerrit.cloudera.org:8080/19922
Tested-by: Kudu Jenkins
Reviewed-by: Yingchun Lai <la...@apache.org>
Reviewed-by: Alexey Serbin <al...@apache.org>
---
src/kudu/client/write_op.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/kudu/client/write_op.h b/src/kudu/client/write_op.h
index ea30d8a12..32cfa5b55 100644
--- a/src/kudu/client/write_op.h
+++ b/src/kudu/client/write_op.h
@@ -222,16 +222,16 @@ class KUDU_EXPORT KuduUpsert : public KuduWriteOperation {
/// See KuduUpsert for more details.
class KUDU_EXPORT KuduUpsertIgnore : public KuduWriteOperation {
public:
- ~KuduUpsertIgnore() override;
+ ~KuduUpsertIgnore() OVERRIDE;
/// @copydoc KuduWriteOperation::ToString()
- std::string ToString() const override { return "UPSERT IGNORE " + row_.ToString(); }
+ std::string ToString() const OVERRIDE { return "UPSERT IGNORE " + row_.ToString(); }
protected:
/// @cond PROTECTED_MEMBERS_DOCUMENTED
/// @copydoc KuduWriteOperation::type()
- Type type() const override {
+ Type type() const OVERRIDE {
return UPSERT_IGNORE;
}
[kudu] 02/03: [Python] Add support for comment in ColumnSchema
Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 27e85acf735944be833ce810dc3bb0dc0796a503
Author: Marton Greber <gr...@gmail.com>
AuthorDate: Sat Mar 4 10:08:59 2023 +0000
[Python] Add support for comment in ColumnSchema
This change adds support for column comments in the Python client.
It is a followup change to: e2870925f9a07da43658447248a4e64acde398b4.
Change-Id: I28a9f650bd1bf686244070151419d0a93b9a499c
Reviewed-on: http://gerrit.cloudera.org:8080/19581
Tested-by: Kudu Jenkins
Reviewed-by: Alexey Serbin <al...@apache.org>
Reviewed-on: http://gerrit.cloudera.org:8080/19694
Reviewed-by: Marton Greber <gr...@gmail.com>
Reviewed-by: Yingchun Lai <la...@apache.org>
---
python/kudu/libkudu_client.pxd | 2 ++
python/kudu/schema.pyx | 26 +++++++++++++++++++++++++-
python/kudu/tests/common.py | 2 +-
python/kudu/tests/test_client.py | 13 +++++++++++--
python/kudu/tests/test_schema.py | 15 +++++++++++++++
5 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/python/kudu/libkudu_client.pxd b/python/kudu/libkudu_client.pxd
index 4766dc6c2..671aca067 100644
--- a/python/kudu/libkudu_client.pxd
+++ b/python/kudu/libkudu_client.pxd
@@ -175,6 +175,7 @@ cdef extern from "kudu/client/schema.h" namespace "kudu::client" nogil:
DataType type()
c_bool is_immutable()
KuduColumnTypeAttributes type_attributes()
+ string& comment()
c_bool Equals(KuduColumnSchema& other)
void CopyFrom(KuduColumnSchema& other)
@@ -217,6 +218,7 @@ cdef extern from "kudu/client/schema.h" namespace "kudu::client" nogil:
KuduColumnSpec* Length(uint16_t length);
KuduColumnSpec* RenameTo(const string& new_name)
+ KuduColumnSpec* Comment(const string& comment)
cdef cppclass KuduSchemaBuilder:
diff --git a/python/kudu/schema.pyx b/python/kudu/schema.pyx
index d19e6d3dd..00394e2b4 100644
--- a/python/kudu/schema.pyx
+++ b/python/kudu/schema.pyx
@@ -256,6 +256,10 @@ cdef class ColumnSchema:
result.type_attributes = new KuduColumnTypeAttributes(self.schema.type_attributes())
return result
+ property comment:
+ def __get__(self):
+ return frombytes(self.schema.comment())
+
def equals(self, other):
if not isinstance(other, ColumnSchema):
return False
@@ -503,6 +507,21 @@ cdef class ColumnSpec:
self.spec.RenameTo(tobytes(new_name))
return self
+ def comment(self, comment):
+ """
+ The comment for the column.
+
+ Parameters
+ ----------
+ comment : str
+
+ Retruns
+ -------
+ self : ColumnSpec
+ """
+ self.spec.Comment(tobytes(comment))
+ return self
+
def block_size(self, block_size):
"""
Set the target block size for the column.
@@ -556,7 +575,7 @@ cdef class SchemaBuilder:
def add_column(self, name, type_=None, nullable=None, compression=None, encoding=None,
primary_key=False, non_unique_primary_key=False, block_size=None, default=None,
- precision=None, scale=None, length=None):
+ precision=None, scale=None, length=None, comment=None):
"""
Add a new column to the schema. Returns a ColumnSpec object for further
configuration and use in a fluid programming style.
@@ -589,6 +608,8 @@ cdef class SchemaBuilder:
Use this scale for the decimal column
length : int
Use this length for the varchar column
+ comment : string, default ''
+ Comment of the column schema
Examples
--------
@@ -627,6 +648,9 @@ cdef class SchemaBuilder:
if length is not None:
result.length(length)
+ if comment is not None:
+ result.comment(comment)
+
if primary_key:
result.primary_key()
diff --git a/python/kudu/tests/common.py b/python/kudu/tests/common.py
index 3841edab7..4087832b6 100644
--- a/python/kudu/tests/common.py
+++ b/python/kudu/tests/common.py
@@ -126,7 +126,7 @@ class KuduTestBase(object):
@classmethod
def example_schema(cls):
builder = kudu.schema_builder()
- builder.add_column('key', kudu.int32, nullable=False)
+ builder.add_column('key', kudu.int32, nullable=False, comment='key_comment')
builder.add_column('int_val', kudu.int32)
builder.add_column('string_val', kudu.string, default=None)
builder.add_column('unixtime_micros_val', kudu.unixtime_micros)
diff --git a/python/kudu/tests/test_client.py b/python/kudu/tests/test_client.py
index 7b78fa888..ce76a87d3 100755
--- a/python/kudu/tests/test_client.py
+++ b/python/kudu/tests/test_client.py
@@ -661,6 +661,14 @@ class TestClient(KuduTestBase, unittest.TestCase):
# Confirm column rename
col = table['string_val_renamed']
+ # Check if existing comment can be altered, and new comment can be specified
+ alterer = self.client.new_table_alterer(table)
+ alterer.alter_column('key').comment('new_key_comment')
+ alterer.alter_column('int_val').comment('int_val_comment')
+ table = alterer.alter()
+
+ assert table['key'].spec.comment == 'new_key_comment'
+ assert table['int_val'].spec.comment == 'int_val_comment'
finally:
self.client.delete_table('alter-column')
@@ -844,8 +852,9 @@ class TestClient(KuduTestBase, unittest.TestCase):
alterer.alter_column(col_name).compression('none')
alterer.alter()
- # TODO(martongreber): once column comments are added to the python client
- # check whether the auto-incrementing column's comment can be altered.
+ alterer = self.client.new_table_alterer(table)
+ alterer.alter_column(col_name).comment('new_comment')
+ alterer.alter()
finally:
try:
diff --git a/python/kudu/tests/test_schema.py b/python/kudu/tests/test_schema.py
index f5045fd33..069201f64 100644
--- a/python/kudu/tests/test_schema.py
+++ b/python/kudu/tests/test_schema.py
@@ -305,6 +305,21 @@ class TestSchema(unittest.TestCase):
assert schema[1].mutable
assert not schema[2].mutable
+ def test_column_comment(self):
+ comment = "test_comment"
+ builder = kudu.schema_builder()
+ (builder.add_column('key', 'int64', nullable=False)
+ .primary_key()
+ .comment(comment))
+
+ builder.add_column('data1', 'double').nullable(True)
+ schema = builder.build()
+ assert isinstance(schema[0].comment, str)
+ assert len(schema[0].comment) > 0
+ assert schema[0].comment == comment
+ assert isinstance(schema[1].comment, str)
+ assert len(schema[1].comment) == 0
+
def test_auto_incrementing_column_name(self):
name = Schema.get_auto_incrementing_column_name()
assert isinstance(name, str)