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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2fc20fe  ARROW-8372: [C++] Migrate Table and RecordBatch APIs to 
Result<T>
2fc20fe is described below

commit 2fc20fe5e1d12f6a6188f027f6cb1bd82d3660c3
Author: Antoine Pitrou <[email protected]>
AuthorDate: Wed Apr 8 14:45:17 2020 -0500

    ARROW-8372: [C++] Migrate Table and RecordBatch APIs to Result<T>
    
    Closes #6876 from pitrou/ARROW-8372-result-batch-apis
    
    Authored-by: Antoine Pitrou <[email protected]>
    Signed-off-by: Wes McKinney <[email protected]>
---
 c_glib/arrow-glib/record-batch.cpp            |  14 +--
 c_glib/arrow-glib/schema.cpp                  |  21 ++--
 c_glib/arrow-glib/table.cpp                   |  64 +++++------
 cpp/src/arrow/adapters/orc/adapter.cc         |   2 +-
 cpp/src/arrow/c/bridge.cc                     |   3 +-
 cpp/src/arrow/dataset/scanner.cc              |   4 +-
 cpp/src/arrow/dataset/scanner_test.cc         |   3 +-
 cpp/src/arrow/flight/types.cc                 |   2 +-
 cpp/src/arrow/ipc/feather.cc                  |   8 +-
 cpp/src/arrow/ipc/feather_test.cc             |  15 +--
 cpp/src/arrow/json/reader.cc                  |   2 +-
 cpp/src/arrow/json/reader_test.cc             |   3 +-
 cpp/src/arrow/record_batch.cc                 |  66 ++++++-----
 cpp/src/arrow/record_batch.h                  |  46 +++++---
 cpp/src/arrow/stl.h                           |   6 +-
 cpp/src/arrow/stl_test.cc                     |   3 +-
 cpp/src/arrow/table.cc                        | 143 +++++++++++++++---------
 cpp/src/arrow/table.h                         |  72 ++++++++----
 cpp/src/arrow/table_test.cc                   | 155 +++++++++++---------------
 cpp/src/arrow/testing/generator.h             |   8 +-
 cpp/src/arrow/testing/gtest_util.cc           |  19 +---
 cpp/src/parquet/arrow/generate_fuzz_corpus.cc |   3 +-
 python/pyarrow/includes/libarrow.pxd          |  27 ++---
 python/pyarrow/ipc.pxi                        |   4 +-
 python/pyarrow/table.pxi                      |  26 ++---
 r/src/recordbatch.cpp                         |   4 +-
 r/src/recordbatchreader.cpp                   |  10 +-
 r/src/table.cpp                               |   8 +-
 28 files changed, 379 insertions(+), 362 deletions(-)

diff --git a/c_glib/arrow-glib/record-batch.cpp 
b/c_glib/arrow-glib/record-batch.cpp
index 3766585..8db0eee 100644
--- a/c_glib/arrow-glib/record-batch.cpp
+++ b/c_glib/arrow-glib/record-batch.cpp
@@ -373,10 +373,9 @@ garrow_record_batch_add_column(GArrowRecordBatch 
*record_batch,
   const auto arrow_record_batch = garrow_record_batch_get_raw(record_batch);
   const auto arrow_field = garrow_field_get_raw(field);
   const auto arrow_column = garrow_array_get_raw(column);
-  std::shared_ptr<arrow::RecordBatch> arrow_new_record_batch;
-  auto status = arrow_record_batch->AddColumn(i, arrow_field, arrow_column, 
&arrow_new_record_batch);
-  if (garrow_error_check(error, status, "[record-batch][add-column]")) {
-    return garrow_record_batch_new_raw(&arrow_new_record_batch);
+  auto maybe_new_batch = arrow_record_batch->AddColumn(i, arrow_field, 
arrow_column);
+  if (garrow::check(error, maybe_new_batch, "[record-batch][add-column]")) {
+    return garrow_record_batch_new_raw(&(*maybe_new_batch));
   } else {
     return NULL;
   }
@@ -399,10 +398,9 @@ garrow_record_batch_remove_column(GArrowRecordBatch 
*record_batch,
                                   GError **error)
 {
   const auto arrow_record_batch = garrow_record_batch_get_raw(record_batch);
-  std::shared_ptr<arrow::RecordBatch> arrow_new_record_batch;
-  auto status = arrow_record_batch->RemoveColumn(i, &arrow_new_record_batch);
-  if (garrow_error_check(error, status, "[record-batch][remove-column]")) {
-    return garrow_record_batch_new_raw(&arrow_new_record_batch);
+  auto maybe_new_batch = arrow_record_batch->RemoveColumn(i);
+  if (garrow::check(error, maybe_new_batch, "[record-batch][remove-column]")) {
+    return garrow_record_batch_new_raw(&(*maybe_new_batch));
   } else {
     return NULL;
   }
diff --git a/c_glib/arrow-glib/schema.cpp b/c_glib/arrow-glib/schema.cpp
index 5a4613e..62a36de 100644
--- a/c_glib/arrow-glib/schema.cpp
+++ b/c_glib/arrow-glib/schema.cpp
@@ -298,10 +298,9 @@ garrow_schema_add_field(GArrowSchema *schema,
 {
   const auto arrow_schema = garrow_schema_get_raw(schema);
   const auto arrow_field = garrow_field_get_raw(field);
-  std::shared_ptr<arrow::Schema> arrow_new_schema;
-  auto status = arrow_schema->AddField(i, arrow_field, &arrow_new_schema);
-  if (garrow_error_check(error, status, "[schema][add-field]")) {
-    return garrow_schema_new_raw(&arrow_new_schema);
+  auto maybe_new_schema = arrow_schema->AddField(i, arrow_field);
+  if (garrow::check(error, maybe_new_schema, "[schema][add-field]")) {
+    return garrow_schema_new_raw(&(*maybe_new_schema));
   } else {
     return NULL;
   }
@@ -324,10 +323,9 @@ garrow_schema_remove_field(GArrowSchema *schema,
                            GError **error)
 {
   const auto arrow_schema = garrow_schema_get_raw(schema);
-  std::shared_ptr<arrow::Schema> arrow_new_schema;
-  auto status = arrow_schema->RemoveField(i, &arrow_new_schema);
-  if (garrow_error_check(error, status, "[schema][remove-field]")) {
-    return garrow_schema_new_raw(&arrow_new_schema);
+  auto maybe_new_schema = arrow_schema->RemoveField(i);
+  if (garrow::check(error, maybe_new_schema, "[schema][remove-field]")) {
+    return garrow_schema_new_raw(&(*maybe_new_schema));
   } else {
     return NULL;
   }
@@ -353,10 +351,9 @@ garrow_schema_replace_field(GArrowSchema *schema,
 {
   const auto arrow_schema = garrow_schema_get_raw(schema);
   const auto arrow_field = garrow_field_get_raw(field);
-  std::shared_ptr<arrow::Schema> arrow_new_schema;
-  auto status = arrow_schema->SetField(i, arrow_field, &arrow_new_schema);
-  if (garrow_error_check(error, status, "[schema][replace-field]")) {
-    return garrow_schema_new_raw(&arrow_new_schema);
+  auto maybe_new_schema = arrow_schema->SetField(i, arrow_field);
+  if (garrow::check(error, maybe_new_schema, "[schema][replace-field]")) {
+    return garrow_schema_new_raw(&(*maybe_new_schema));
   } else {
     return NULL;
   }
diff --git a/c_glib/arrow-glib/table.cpp b/c_glib/arrow-glib/table.cpp
index f0d6a01..24e5842 100644
--- a/c_glib/arrow-glib/table.cpp
+++ b/c_glib/arrow-glib/table.cpp
@@ -203,7 +203,8 @@ garrow_table_new_values(GArrowSchema *schema,
   }
 
   if (!arrow_chunked_arrays.empty()) {
-    auto arrow_table = arrow::Table::Make(arrow_schema, arrow_chunked_arrays);
+    auto arrow_table = arrow::Table::Make(arrow_schema,
+                                          std::move(arrow_chunked_arrays));
     auto status = arrow_table->Validate();
     if (garrow_error_check(error, status, context)) {
       return garrow_table_new_raw(&arrow_table);
@@ -211,7 +212,7 @@ garrow_table_new_values(GArrowSchema *schema,
       return NULL;
     }
   } else if (!arrow_arrays.empty()) {
-    auto arrow_table = arrow::Table::Make(arrow_schema, arrow_arrays);
+    auto arrow_table = arrow::Table::Make(arrow_schema, 
std::move(arrow_arrays));
     auto status = arrow_table->Validate();
     if (garrow_error_check(error, status, context)) {
       return garrow_table_new_raw(&arrow_table);
@@ -219,12 +220,10 @@ garrow_table_new_values(GArrowSchema *schema,
       return NULL;
     }
   } else {
-    std::shared_ptr<arrow::Table> arrow_table;
-    auto status = arrow::Table::FromRecordBatches(arrow_schema,
-                                                  arrow_record_batches,
-                                                  &arrow_table);
-    if (garrow_error_check(error, status, context)) {
-      return garrow_table_new_raw(&arrow_table);
+    auto maybe_table = arrow::Table::FromRecordBatches(
+      arrow_schema, std::move(arrow_record_batches));
+    if (garrow::check(error, maybe_table, context)) {
+      return garrow_table_new_raw(&(*maybe_table));
     } else {
       return NULL;
     }
@@ -322,12 +321,10 @@ garrow_table_new_record_batches(GArrowSchema *schema,
     arrow_record_batches.push_back(arrow_record_batch);
   }
 
-  std::shared_ptr<arrow::Table> arrow_table;
-  auto status = arrow::Table::FromRecordBatches(arrow_schema,
-                                                arrow_record_batches,
-                                                &arrow_table);
-  if (garrow_error_check(error, status, "[table][new][record-batches]")) {
-    return garrow_table_new_raw(&arrow_table);
+  auto maybe_table = arrow::Table::FromRecordBatches(arrow_schema,
+                                                     arrow_record_batches);
+  if (garrow::check(error, maybe_table, "[table][new][record-batches]")) {
+    return garrow_table_new_raw(&(*maybe_table));
   } else {
     return NULL;
   }
@@ -458,13 +455,11 @@ garrow_table_add_column(GArrowTable *table,
   const auto arrow_table = garrow_table_get_raw(table);
   const auto arrow_field = garrow_field_get_raw(field);
   const auto arrow_chunked_array = garrow_chunked_array_get_raw(chunked_array);
-  std::shared_ptr<arrow::Table> arrow_new_table;
-  auto status = arrow_table->AddColumn(i,
-                                       arrow_field,
-                                       arrow_chunked_array,
-                                       &arrow_new_table);
-  if (garrow_error_check(error, status, "[table][add-column]")) {
-    return garrow_table_new_raw(&arrow_new_table);
+  auto maybe_new_table = arrow_table->AddColumn(i,
+                                                arrow_field,
+                                                arrow_chunked_array);
+  if (garrow::check(error, maybe_new_table, "[table][add-column]")) {
+    return garrow_table_new_raw(&(*maybe_new_table));
   } else {
     return NULL;
   }
@@ -487,10 +482,9 @@ garrow_table_remove_column(GArrowTable *table,
                            GError **error)
 {
   const auto arrow_table = garrow_table_get_raw(table);
-  std::shared_ptr<arrow::Table> arrow_new_table;
-  auto status = arrow_table->RemoveColumn(i, &arrow_new_table);
-  if (garrow_error_check(error, status, "[table][remove-column]")) {
-    return garrow_table_new_raw(&arrow_new_table);
+  auto maybe_new_table = arrow_table->RemoveColumn(i);
+  if (garrow::check(error, maybe_new_table, "[table][remove-column]")) {
+    return garrow_table_new_raw(&(*maybe_new_table));
   } else {
     return NULL;
   }
@@ -520,13 +514,11 @@ garrow_table_replace_column(GArrowTable *table,
   const auto arrow_table = garrow_table_get_raw(table);
   const auto arrow_field = garrow_field_get_raw(field);
   const auto arrow_chunked_array = garrow_chunked_array_get_raw(chunked_array);
-  std::shared_ptr<arrow::Table> arrow_new_table;
-  auto status = arrow_table->SetColumn(i,
-                                       arrow_field,
-                                       arrow_chunked_array,
-                                       &arrow_new_table);
-  if (garrow_error_check(error, status, "[table][replace-column]")) {
-    return garrow_table_new_raw(&arrow_new_table);
+  auto maybe_new_table = arrow_table->SetColumn(i,
+                                                arrow_field,
+                                                arrow_chunked_array);
+  if (garrow::check(error, maybe_new_table, "[table][replace-column]")) {
+    return garrow_table_new_raw(&(*maybe_new_table));
   } else {
     return NULL;
   }
@@ -630,11 +622,9 @@ garrow_table_combine_chunks(GArrowTable *table,
 {
   const auto arrow_table = garrow_table_get_raw(table);
 
-  std::shared_ptr<arrow::Table> arrow_combined_table;
-  auto status = arrow_table->CombineChunks(arrow::default_memory_pool(),
-                                           &arrow_combined_table);
-  if (garrow_error_check(error, status, "[table][combine-chunks]")) {
-    return garrow_table_new_raw(&arrow_combined_table);
+  auto maybe_new_table = arrow_table->CombineChunks();
+  if (garrow::check(error, maybe_new_table, "[table][combine-chunks]")) {
+    return garrow_table_new_raw(&(*maybe_new_table));
   } else {
     return NULL;
   }
diff --git a/cpp/src/arrow/adapters/orc/adapter.cc 
b/cpp/src/arrow/adapters/orc/adapter.cc
index b3ecc2e..2c61f89 100644
--- a/cpp/src/arrow/adapters/orc/adapter.cc
+++ b/cpp/src/arrow/adapters/orc/adapter.cc
@@ -334,7 +334,7 @@ class ORCFileReader::Impl {
       opts.range(stripes_[stripe].offset, stripes_[stripe].length);
       RETURN_NOT_OK(ReadBatch(opts, schema, stripes_[stripe].num_rows, 
&batches[stripe]));
     }
-    return Table::FromRecordBatches(schema, batches, out);
+    return Table::FromRecordBatches(schema, std::move(batches)).Value(out);
   }
 
   Status ReadBatch(const liborc::RowReaderOptions& opts,
diff --git a/cpp/src/arrow/c/bridge.cc b/cpp/src/arrow/c/bridge.cc
index 8fd13ad..9d973ef 100644
--- a/cpp/src/arrow/c/bridge.cc
+++ b/cpp/src/arrow/c/bridge.cc
@@ -590,9 +590,8 @@ Status ExportArray(const Array& array, struct ArrowArray* 
out,
 
 Status ExportRecordBatch(const RecordBatch& batch, struct ArrowArray* out,
                          struct ArrowSchema* out_schema) {
-  std::shared_ptr<Array> array;
   // XXX perhaps bypass ToStructArray() for speed?
-  RETURN_NOT_OK(batch.ToStructArray(&array));
+  ARROW_ASSIGN_OR_RAISE(auto array, batch.ToStructArray());
 
   SchemaExportGuard guard(out_schema);
   if (out_schema != nullptr) {
diff --git a/cpp/src/arrow/dataset/scanner.cc b/cpp/src/arrow/dataset/scanner.cc
index 346150e..701d900 100644
--- a/cpp/src/arrow/dataset/scanner.cc
+++ b/cpp/src/arrow/dataset/scanner.cc
@@ -182,9 +182,7 @@ Result<std::shared_ptr<Table>> Scanner::ToTable() {
   // Wait for all tasks to complete, or the first error.
   RETURN_NOT_OK(task_group->Finish());
 
-  std::shared_ptr<Table> out;
-  RETURN_NOT_OK(Table::FromRecordBatches(scan_options_->schema(), batches, 
&out));
-  return out;
+  return Table::FromRecordBatches(scan_options_->schema(), std::move(batches));
 }
 
 }  // namespace dataset
diff --git a/cpp/src/arrow/dataset/scanner_test.cc 
b/cpp/src/arrow/dataset/scanner_test.cc
index 1fa1811..19b22cb 100644
--- a/cpp/src/arrow/dataset/scanner_test.cc
+++ b/cpp/src/arrow/dataset/scanner_test.cc
@@ -131,8 +131,7 @@ TEST_F(TestScanner, ToTable) {
   std::vector<std::shared_ptr<RecordBatch>> batches{kNumberBatches * 
kNumberChildDatasets,
                                                     batch};
 
-  std::shared_ptr<Table> expected;
-  ASSERT_OK(Table::FromRecordBatches(batches, &expected));
+  ASSERT_OK_AND_ASSIGN(auto expected, Table::FromRecordBatches(batches));
 
   auto scanner = MakeScanner(batch);
   std::shared_ptr<Table> actual;
diff --git a/cpp/src/arrow/flight/types.cc b/cpp/src/arrow/flight/types.cc
index 157afec..5365a79 100644
--- a/cpp/src/arrow/flight/types.cc
+++ b/cpp/src/arrow/flight/types.cc
@@ -268,7 +268,7 @@ Status MetadataRecordBatchReader::ReadAll(
 Status MetadataRecordBatchReader::ReadAll(std::shared_ptr<Table>* table) {
   std::vector<std::shared_ptr<RecordBatch>> batches;
   RETURN_NOT_OK(ReadAll(&batches));
-  return Table::FromRecordBatches(schema(), batches, table);
+  return Table::FromRecordBatches(schema(), std::move(batches)).Value(table);
 }
 
 SimpleFlightListing::SimpleFlightListing(const std::vector<FlightInfo>& 
flights)
diff --git a/cpp/src/arrow/ipc/feather.cc b/cpp/src/arrow/ipc/feather.cc
index 4af2abb..bf408a1 100644
--- a/cpp/src/arrow/ipc/feather.cc
+++ b/cpp/src/arrow/ipc/feather.cc
@@ -716,11 +716,9 @@ class ReaderV2 : public Reader {
 
   Status Read(const IpcReadOptions& options, std::shared_ptr<Table>* out) {
     ARROW_ASSIGN_OR_RAISE(auto reader, RecordBatchFileReader::Open(source_, 
options));
-    std::vector<std::shared_ptr<RecordBatch>> batches;
+    std::vector<std::shared_ptr<RecordBatch>> 
batches(reader->num_record_batches());
     for (int i = 0; i < reader->num_record_batches(); ++i) {
-      std::shared_ptr<RecordBatch> batch;
-      RETURN_NOT_OK(reader->ReadRecordBatch(i, &batch));
-      batches.emplace_back(batch);
+      RETURN_NOT_OK(reader->ReadRecordBatch(i, &batches[i]));
     }
 
     // XXX: Handle included_fields in RecordBatchFileReader::schema
@@ -735,7 +733,7 @@ class ReaderV2 : public Reader {
       }
       out_schema = ::arrow::schema(fields, out_schema->metadata());
     }
-    return Table::FromRecordBatches(out_schema, batches, out);
+    return Table::FromRecordBatches(std::move(out_schema), 
std::move(batches)).Value(out);
   }
 
   Status Read(std::shared_ptr<Table>* out) override {
diff --git a/cpp/src/arrow/ipc/feather_test.cc 
b/cpp/src/arrow/ipc/feather_test.cc
index 28c4d3f..31a1d24 100644
--- a/cpp/src/arrow/ipc/feather_test.cc
+++ b/cpp/src/arrow/ipc/feather_test.cc
@@ -83,8 +83,7 @@ class TestFeather : public 
::testing::TestWithParam<TestParam> {
 
   void CheckSlice(std::shared_ptr<RecordBatch> batch, int start, int size) {
     batch = batch->Slice(start, size);
-    std::shared_ptr<Table> table;
-    ASSERT_OK(Table::FromRecordBatches({batch}, &table));
+    ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches({batch}));
 
     DoWrite(*table);
     std::shared_ptr<Table> result;
@@ -108,9 +107,8 @@ class TestFeather : public 
::testing::TestWithParam<TestParam> {
   }
 
   void CheckRoundtrip(std::shared_ptr<RecordBatch> batch) {
-    std::shared_ptr<Table> table;
     std::vector<std::shared_ptr<RecordBatch>> batches = {batch};
-    ASSERT_OK(Table::FromRecordBatches(batches, &table));
+    ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches(batches));
 
     DoWrite(*table);
 
@@ -139,8 +137,7 @@ TEST_P(TestFeather, ReadIndicesOrNames) {
   std::shared_ptr<RecordBatch> batch1;
   ASSERT_OK(ipc::test::MakeIntRecordBatch(&batch1));
 
-  std::shared_ptr<Table> table;
-  ASSERT_OK(Table::FromRecordBatches({batch1}, &table));
+  ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches({batch1}));
 
   DoWrite(*table);
 
@@ -181,8 +178,7 @@ TEST_P(TestFeather, PrimitiveRoundTrip) {
   std::shared_ptr<RecordBatch> batch;
   ASSERT_OK(ipc::test::MakeIntRecordBatch(&batch));
 
-  std::shared_ptr<Table> table;
-  ASSERT_OK(Table::FromRecordBatches({batch}, &table));
+  ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches({batch}));
 
   DoWrite(*table);
 
@@ -253,8 +249,7 @@ TEST_P(TestFeather, PrimitiveNullRoundTrip) {
   std::shared_ptr<RecordBatch> batch;
   ASSERT_OK(ipc::test::MakeNullRecordBatch(&batch));
 
-  std::shared_ptr<Table> table;
-  ASSERT_OK(Table::FromRecordBatches({batch}, &table));
+  ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches({batch}));
 
   DoWrite(*table);
 
diff --git a/cpp/src/arrow/json/reader.cc b/cpp/src/arrow/json/reader.cc
index 4f4ac21..f6ac90a 100644
--- a/cpp/src/arrow/json/reader.cc
+++ b/cpp/src/arrow/json/reader.cc
@@ -108,7 +108,7 @@ class TableReaderImpl : public TableReader,
 
     std::shared_ptr<ChunkedArray> array;
     RETURN_NOT_OK(builder_->Finish(&array));
-    return Table::FromChunkedStructArray(array, out);
+    return Table::FromChunkedStructArray(array).Value(out);
   }
 
  private:
diff --git a/cpp/src/arrow/json/reader_test.cc 
b/cpp/src/arrow/json/reader_test.cc
index 0754c11..f3f0e64 100644
--- a/cpp/src/arrow/json/reader_test.cc
+++ b/cpp/src/arrow/json/reader_test.cc
@@ -269,8 +269,7 @@ TEST(ReaderTest, ListArrayWithFewValues) {
         {"a": [1], "b": {"c": true, "d": "1991-02-03"}},
         {"a": [], "b": {"c": false, "d": "2019-04-01"}}
       ])");
-  std::shared_ptr<Table> expected_table;
-  ASSERT_OK(Table::FromRecordBatches({expected_batch}, &expected_table));
+  ASSERT_OK_AND_ASSIGN(auto expected_table, 
Table::FromRecordBatches({expected_batch}));
 
   std::string json = R"({"a": [1], "b": {"c": true, "d": "1991-02-03"}}
 {"a": [], "b": {"c": false, "d": "2019-04-01"}}
diff --git a/cpp/src/arrow/record_batch.cc b/cpp/src/arrow/record_batch.cc
index 8863ce6..c3e6c08 100644
--- a/cpp/src/arrow/record_batch.cc
+++ b/cpp/src/arrow/record_batch.cc
@@ -36,11 +36,26 @@
 
 namespace arrow {
 
-Status RecordBatch::AddColumn(int i, const std::string& field_name,
+Result<std::shared_ptr<RecordBatch>> RecordBatch::AddColumn(
+    int i, std::string field_name, const std::shared_ptr<Array>& column) const 
{
+  auto field = ::arrow::field(std::move(field_name), column->type());
+  return AddColumn(i, field, column);
+}
+
+Status RecordBatch::AddColumn(int i, std::string field_name,
+                              const std::shared_ptr<Array>& column,
+                              std::shared_ptr<RecordBatch>* out) const {
+  return AddColumn(i, std::move(field_name), column).Value(out);
+}
+
+Status RecordBatch::AddColumn(int i, const std::shared_ptr<Field>& field,
                               const std::shared_ptr<Array>& column,
                               std::shared_ptr<RecordBatch>* out) const {
-  auto field = ::arrow::field(field_name, column->type());
-  return AddColumn(i, field, column, out);
+  return AddColumn(i, field, column).Value(out);
+}
+
+Status RecordBatch::RemoveColumn(int i, std::shared_ptr<RecordBatch>* out) 
const {
+  return RemoveColumn(i).Value(out);
 }
 
 std::shared_ptr<Array> RecordBatch::GetColumnByName(const std::string& name) 
const {
@@ -82,9 +97,9 @@ class SimpleRecordBatch : public RecordBatch {
 
   ArrayDataVector column_data() const override { return columns_; }
 
-  Status AddColumn(int i, const std::shared_ptr<Field>& field,
-                   const std::shared_ptr<Array>& column,
-                   std::shared_ptr<RecordBatch>* out) const override {
+  Result<std::shared_ptr<RecordBatch>> AddColumn(
+      int i, const std::shared_ptr<Field>& field,
+      const std::shared_ptr<Array>& column) const override {
     ARROW_CHECK(field != nullptr);
     ARROW_CHECK(column != nullptr);
 
@@ -100,17 +115,15 @@ class SimpleRecordBatch : public RecordBatch {
 
     ARROW_ASSIGN_OR_RAISE(auto new_schema, schema_->AddField(i, field));
 
-    *out = RecordBatch::Make(new_schema, num_rows_,
+    return RecordBatch::Make(new_schema, num_rows_,
                              internal::AddVectorElement(columns_, i, 
column->data()));
-    return Status::OK();
   }
 
-  Status RemoveColumn(int i, std::shared_ptr<RecordBatch>* out) const override 
{
+  Result<std::shared_ptr<RecordBatch>> RemoveColumn(int i) const override {
     ARROW_ASSIGN_OR_RAISE(auto new_schema, schema_->RemoveField(i));
 
-    *out = RecordBatch::Make(new_schema, num_rows_,
+    return RecordBatch::Make(new_schema, num_rows_,
                              internal::DeleteVectorElement(columns_, i));
-    return Status::OK();
   }
 
   std::shared_ptr<RecordBatch> ReplaceSchemaMetadata(
@@ -168,21 +181,19 @@ std::shared_ptr<RecordBatch> RecordBatch::Make(
                                              std::move(columns));
 }
 
-Status RecordBatch::FromStructArray(const std::shared_ptr<Array>& array,
-                                    std::shared_ptr<RecordBatch>* out) {
+Result<std::shared_ptr<RecordBatch>> RecordBatch::FromStructArray(
+    const std::shared_ptr<Array>& array) {
   // TODO fail if null_count != 0?
   if (array->type_id() != Type::STRUCT) {
     return Status::Invalid("Cannot construct record batch from array of type ",
                            *array->type());
   }
-  *out = Make(arrow::schema(array->type()->children()), array->length(),
+  return Make(arrow::schema(array->type()->children()), array->length(),
               array->data()->child_data);
-  return Status::OK();
 }
 
-Status RecordBatch::ToStructArray(std::shared_ptr<Array>* out) const {
-  ARROW_ASSIGN_OR_RAISE(*out, StructArray::Make(columns(), 
schema()->fields()));
-  return Status::OK();
+Result<std::shared_ptr<Array>> RecordBatch::ToStructArray() const {
+  return StructArray::Make(columns(), schema()->fields());
 }
 
 std::vector<std::shared_ptr<Array>> RecordBatch::columns() const {
@@ -280,7 +291,7 @@ Status 
RecordBatchReader::ReadAll(std::vector<std::shared_ptr<RecordBatch>>* bat
 Status RecordBatchReader::ReadAll(std::shared_ptr<Table>* table) {
   std::vector<std::shared_ptr<RecordBatch>> batches;
   RETURN_NOT_OK(ReadAll(&batches));
-  return Table::FromRecordBatches(schema(), batches, table);
+  return Table::FromRecordBatches(schema(), std::move(batches)).Value(table);
 }
 
 class SimpleRecordBatchReader : public RecordBatchReader {
@@ -289,9 +300,9 @@ class SimpleRecordBatchReader : public RecordBatchReader {
                           std::shared_ptr<Schema> schema)
       : schema_(schema), it_(std::move(it)) {}
 
-  SimpleRecordBatchReader(const std::vector<std::shared_ptr<RecordBatch>>& 
batches,
+  SimpleRecordBatchReader(std::vector<std::shared_ptr<RecordBatch>> batches,
                           std::shared_ptr<Schema> schema)
-      : schema_(schema), it_(MakeVectorIterator(batches)) {}
+      : schema_(schema), it_(MakeVectorIterator(std::move(batches))) {}
 
   Status ReadNext(std::shared_ptr<RecordBatch>* batch) override {
     return it_.Next().Value(batch);
@@ -304,9 +315,8 @@ class SimpleRecordBatchReader : public RecordBatchReader {
   Iterator<std::shared_ptr<RecordBatch>> it_;
 };
 
-Status MakeRecordBatchReader(const std::vector<std::shared_ptr<RecordBatch>>& 
batches,
-                             std::shared_ptr<Schema> schema,
-                             std::shared_ptr<RecordBatchReader>* out) {
+Result<std::shared_ptr<RecordBatchReader>> MakeRecordBatchReader(
+    std::vector<std::shared_ptr<RecordBatch>> batches, std::shared_ptr<Schema> 
schema) {
   if (schema == nullptr) {
     if (batches.size() == 0 || batches[0] == nullptr) {
       return Status::Invalid("Cannot infer schema from empty vector or 
nullptr");
@@ -315,9 +325,13 @@ Status MakeRecordBatchReader(const 
std::vector<std::shared_ptr<RecordBatch>>& ba
     schema = batches[0]->schema();
   }
 
-  *out = std::make_shared<SimpleRecordBatchReader>(batches, schema);
+  return std::make_shared<SimpleRecordBatchReader>(std::move(batches), schema);
+}
 
-  return Status::OK();
+Status MakeRecordBatchReader(std::vector<std::shared_ptr<RecordBatch>> batches,
+                             std::shared_ptr<Schema> schema,
+                             std::shared_ptr<RecordBatchReader>* out) {
+  return MakeRecordBatchReader(std::move(batches), 
std::move(schema)).Value(out);
 }
 
 }  // namespace arrow
diff --git a/cpp/src/arrow/record_batch.h b/cpp/src/arrow/record_batch.h
index 1d5adb8..060d636 100644
--- a/cpp/src/arrow/record_batch.h
+++ b/cpp/src/arrow/record_batch.h
@@ -65,6 +65,9 @@ class ARROW_EXPORT RecordBatch {
   /// Create a struct array whose child arrays are the record batch's columns.
   /// Note that the record batch's top-level field metadata cannot be reflected
   /// in the resulting struct array.
+  Result<std::shared_ptr<Array>> ToStructArray() const;
+
+  ARROW_DEPRECATED("Use Result-returning version")
   Status ToStructArray(std::shared_ptr<Array>* out) const;
 
   /// \brief Construct record batch from struct array
@@ -72,6 +75,10 @@ class ARROW_EXPORT RecordBatch {
   /// This constructs a record batch using the child arrays of the given
   /// array, which must be a struct array.  Note that the struct array's own
   /// null bitmap is not reflected in the resulting record batch.
+  static Result<std::shared_ptr<RecordBatch>> FromStructArray(
+      const std::shared_ptr<Array>& array);
+
+  ARROW_DEPRECATED("Use Result-returning version")
   static Status FromStructArray(const std::shared_ptr<Array>& array,
                                 std::shared_ptr<RecordBatch>* out);
 
@@ -115,10 +122,14 @@ class ARROW_EXPORT RecordBatch {
   /// \param[in] i field index, which will be boundschecked
   /// \param[in] field field to be added
   /// \param[in] column column to be added
-  /// \param[out] out record batch with column added
-  virtual Status AddColumn(int i, const std::shared_ptr<Field>& field,
-                           const std::shared_ptr<Array>& column,
-                           std::shared_ptr<RecordBatch>* out) const = 0;
+  virtual Result<std::shared_ptr<RecordBatch>> AddColumn(
+      int i, const std::shared_ptr<Field>& field,
+      const std::shared_ptr<Array>& column) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status AddColumn(int i, const std::shared_ptr<Field>& field,
+                   const std::shared_ptr<Array>& column,
+                   std::shared_ptr<RecordBatch>* out) const;
 
   /// \brief Add new nullable column to the record batch, producing a new
   /// RecordBatch.
@@ -128,16 +139,20 @@ class ARROW_EXPORT RecordBatch {
   /// \param[in] i field index, which will be boundschecked
   /// \param[in] field_name name of field to be added
   /// \param[in] column column to be added
-  /// \param[out] out record batch with column added
-  virtual Status AddColumn(int i, const std::string& field_name,
-                           const std::shared_ptr<Array>& column,
-                           std::shared_ptr<RecordBatch>* out) const;
+  virtual Result<std::shared_ptr<RecordBatch>> AddColumn(
+      int i, std::string field_name, const std::shared_ptr<Array>& column) 
const;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status AddColumn(int i, std::string field_name, const 
std::shared_ptr<Array>& column,
+                   std::shared_ptr<RecordBatch>* out) const;
 
   /// \brief Remove column from the record batch, producing a new RecordBatch
   ///
   /// \param[in] i field index, does boundscheck
-  /// \param[out] out record batch with column removed
-  virtual Status RemoveColumn(int i, std::shared_ptr<RecordBatch>* out) const 
= 0;
+  virtual Result<std::shared_ptr<RecordBatch>> RemoveColumn(int i) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status RemoveColumn(int i, std::shared_ptr<RecordBatch>* out) const;
 
   virtual std::shared_ptr<RecordBatch> ReplaceSchemaMetadata(
       const std::shared_ptr<const KeyValueMetadata>& metadata) const = 0;
@@ -222,10 +237,13 @@ class ARROW_EXPORT RecordBatchReader {
 /// \param[in] batches the vector of RecordBatch to read from
 /// \param[in] schema schema to conform to. Will be inferred from the first
 ///            element if not provided.
-/// \param[out] out output pointer to store the RecordBatchReader to.
-/// \returns Status
+ARROW_EXPORT Result<std::shared_ptr<RecordBatchReader>> MakeRecordBatchReader(
+    std::vector<std::shared_ptr<RecordBatch>> batches,
+    std::shared_ptr<Schema> schema = NULLPTR);
+
+ARROW_DEPRECATED("Use Result-returning version")
 ARROW_EXPORT Status MakeRecordBatchReader(
-    const std::vector<std::shared_ptr<RecordBatch>>& batches,
-    std::shared_ptr<Schema> schema, std::shared_ptr<RecordBatchReader>* out);
+    std::vector<std::shared_ptr<RecordBatch>> batches, std::shared_ptr<Schema> 
schema,
+    std::shared_ptr<RecordBatchReader>* out);
 
 }  // namespace arrow
diff --git a/cpp/src/arrow/stl.h b/cpp/src/arrow/stl.h
index e89e7f1..67fffa5 100644
--- a/cpp/src/arrow/stl.h
+++ b/cpp/src/arrow/stl.h
@@ -350,8 +350,8 @@ struct EnsureColumnTypes {
       ARROW_RETURN_NOT_OK(compute::Cast(ctx, compute::Datum(table.column(N - 
1)),
                                         expected_type, cast_options, &casted));
       auto new_field = table.schema()->field(N - 1)->WithType(expected_type);
-      ARROW_RETURN_NOT_OK(
-          table.SetColumn(N - 1, new_field, casted.chunked_array(), 
table_owner));
+      ARROW_ASSIGN_OR_RAISE(*table_owner,
+                            table.SetColumn(N - 1, new_field, 
casted.chunked_array()));
       *result = **table_owner;
     }
 
@@ -362,7 +362,7 @@ struct EnsureColumnTypes {
 
 template <typename Tuple>
 struct EnsureColumnTypes<Tuple, 0> {
-  static Status Cast(const Table& table, std::shared_ptr<Table>* table_ownder,
+  static Status Cast(const Table& table, std::shared_ptr<Table>* table_owner,
                      const compute::CastOptions& cast_options,
                      compute::FunctionContext* ctx,
                      std::reference_wrapper<const ::arrow::Table>* result) {
diff --git a/cpp/src/arrow/stl_test.cc b/cpp/src/arrow/stl_test.cc
index a16e0f6..7ec09e7 100644
--- a/cpp/src/arrow/stl_test.cc
+++ b/cpp/src/arrow/stl_test.cc
@@ -456,8 +456,7 @@ TEST(TestTupleVectorFromTable, PrimitiveTypes) {
   ASSERT_RAISES(Invalid, TupleRangeFromTable(*table, cast_options, &ctx, 
&too_few_rows));
 
   // The number of columns must match
-  std::shared_ptr<Table> corrupt_table;
-  ASSERT_OK(table->RemoveColumn(0, &corrupt_table));
+  ASSERT_OK_AND_ASSIGN(auto corrupt_table, table->RemoveColumn(0));
   ASSERT_RAISES(Invalid, TupleRangeFromTable(*corrupt_table, cast_options, 
&ctx, &rows));
 }
 
diff --git a/cpp/src/arrow/table.cc b/cpp/src/arrow/table.cc
index 774ccdf..8ea3d0f 100644
--- a/cpp/src/arrow/table.cc
+++ b/cpp/src/arrow/table.cc
@@ -258,25 +258,24 @@ bool MultipleChunkIterator::Next(std::shared_ptr<Array>* 
next_left,
 /// \brief A basic, non-lazy in-memory table, like SimpleRecordBatch
 class SimpleTable : public Table {
  public:
-  SimpleTable(const std::shared_ptr<Schema>& schema,
-              const std::vector<std::shared_ptr<ChunkedArray>>& columns,
-              int64_t num_rows = -1)
-      : columns_(columns) {
-    schema_ = schema;
+  SimpleTable(std::shared_ptr<Schema> schema,
+              std::vector<std::shared_ptr<ChunkedArray>> columns, int64_t 
num_rows = -1)
+      : columns_(std::move(columns)) {
+    schema_ = std::move(schema);
     if (num_rows < 0) {
-      if (columns.size() == 0) {
+      if (columns_.size() == 0) {
         num_rows_ = 0;
       } else {
-        num_rows_ = columns[0]->length();
+        num_rows_ = columns_[0]->length();
       }
     } else {
       num_rows_ = num_rows;
     }
   }
 
-  SimpleTable(const std::shared_ptr<Schema>& schema,
+  SimpleTable(std::shared_ptr<Schema> schema,
               const std::vector<std::shared_ptr<Array>>& columns, int64_t 
num_rows = -1) {
-    schema_ = schema;
+    schema_ = std::move(schema);
     if (num_rows < 0) {
       if (columns.size() == 0) {
         num_rows_ = 0;
@@ -305,17 +304,16 @@ class SimpleTable : public Table {
     return Table::Make(schema_, sliced, num_rows);
   }
 
-  Status RemoveColumn(int i, std::shared_ptr<Table>* out) const override {
+  Result<std::shared_ptr<Table>> RemoveColumn(int i) const override {
     ARROW_ASSIGN_OR_RAISE(auto new_schema, schema_->RemoveField(i));
 
-    *out = Table::Make(new_schema, internal::DeleteVectorElement(columns_, i),
+    return Table::Make(new_schema, internal::DeleteVectorElement(columns_, i),
                        this->num_rows());
-    return Status::OK();
   }
 
-  Status AddColumn(int i, std::shared_ptr<Field> field_arg,
-                   std::shared_ptr<ChunkedArray> col,
-                   std::shared_ptr<Table>* out) const override {
+  Result<std::shared_ptr<Table>> AddColumn(
+      int i, std::shared_ptr<Field> field_arg,
+      std::shared_ptr<ChunkedArray> col) const override {
     DCHECK(col != nullptr);
 
     if (col->length() != num_rows_) {
@@ -330,14 +328,13 @@ class SimpleTable : public Table {
 
     ARROW_ASSIGN_OR_RAISE(auto new_schema, schema_->AddField(i, field_arg));
 
-    *out =
-        Table::Make(new_schema, internal::AddVectorElement(columns_, i, 
std::move(col)));
-    return Status::OK();
+    return Table::Make(new_schema,
+                       internal::AddVectorElement(columns_, i, 
std::move(col)));
   }
 
-  Status SetColumn(int i, std::shared_ptr<Field> field_arg,
-                   std::shared_ptr<ChunkedArray> col,
-                   std::shared_ptr<Table>* out) const override {
+  Result<std::shared_ptr<Table>> SetColumn(
+      int i, std::shared_ptr<Field> field_arg,
+      std::shared_ptr<ChunkedArray> col) const override {
     DCHECK(col != nullptr);
 
     if (col->length() != num_rows_) {
@@ -351,9 +348,8 @@ class SimpleTable : public Table {
     }
 
     ARROW_ASSIGN_OR_RAISE(auto new_schema, schema_->SetField(i, field_arg));
-    *out = Table::Make(new_schema,
+    return Table::Make(new_schema,
                        internal::ReplaceVectorElement(columns_, i, 
std::move(col)));
-    return Status::OK();
   }
 
   std::shared_ptr<Table> ReplaceSchemaMetadata(
@@ -362,7 +358,7 @@ class SimpleTable : public Table {
     return Table::Make(new_schema, columns_);
   }
 
-  Status Flatten(MemoryPool* pool, std::shared_ptr<Table>* out) const override 
{
+  Result<std::shared_ptr<Table>> Flatten(MemoryPool* pool) const override {
     std::vector<std::shared_ptr<Field>> flattened_fields;
     std::vector<std::shared_ptr<ChunkedArray>> flattened_columns;
     for (int i = 0; i < num_columns(); ++i) {
@@ -375,9 +371,8 @@ class SimpleTable : public Table {
       }
     }
     auto flattened_schema =
-        std::make_shared<Schema>(flattened_fields, schema_->metadata());
-    *out = Table::Make(flattened_schema, flattened_columns);
-    return Status::OK();
+        std::make_shared<Schema>(std::move(flattened_fields), 
schema_->metadata());
+    return Table::Make(std::move(flattened_schema), 
std::move(flattened_columns));
   }
 
   Status Validate() const override {
@@ -466,21 +461,21 @@ std::vector<std::shared_ptr<Field>> Table::fields() const 
{
   return result;
 }
 
-std::shared_ptr<Table> Table::Make(
-    const std::shared_ptr<Schema>& schema,
-    const std::vector<std::shared_ptr<ChunkedArray>>& columns, int64_t 
num_rows) {
-  return std::make_shared<SimpleTable>(schema, columns, num_rows);
+std::shared_ptr<Table> Table::Make(std::shared_ptr<Schema> schema,
+                                   std::vector<std::shared_ptr<ChunkedArray>> 
columns,
+                                   int64_t num_rows) {
+  return std::make_shared<SimpleTable>(std::move(schema), std::move(columns), 
num_rows);
 }
 
-std::shared_ptr<Table> Table::Make(const std::shared_ptr<Schema>& schema,
+std::shared_ptr<Table> Table::Make(std::shared_ptr<Schema> schema,
                                    const std::vector<std::shared_ptr<Array>>& 
arrays,
                                    int64_t num_rows) {
-  return std::make_shared<SimpleTable>(schema, arrays, num_rows);
+  return std::make_shared<SimpleTable>(std::move(schema), arrays, num_rows);
 }
 
-Status Table::FromRecordBatches(const std::shared_ptr<Schema>& schema,
-                                const 
std::vector<std::shared_ptr<RecordBatch>>& batches,
-                                std::shared_ptr<Table>* table) {
+Result<std::shared_ptr<Table>> Table::FromRecordBatches(
+    std::shared_ptr<Schema> schema,
+    const std::vector<std::shared_ptr<RecordBatch>>& batches) {
   const int nbatches = static_cast<int>(batches.size());
   const int ncolumns = static_cast<int>(schema->num_fields());
 
@@ -504,21 +499,31 @@ Status Table::FromRecordBatches(const 
std::shared_ptr<Schema>& schema,
     columns[i] = std::make_shared<ChunkedArray>(column_arrays, 
schema->field(i)->type());
   }
 
-  *table = Table::Make(schema, columns, num_rows);
-  return Status::OK();
+  return Table::Make(std::move(schema), std::move(columns), num_rows);
 }
 
-Status Table::FromRecordBatches(const 
std::vector<std::shared_ptr<RecordBatch>>& batches,
+Status Table::FromRecordBatches(std::shared_ptr<Schema> schema,
+                                const 
std::vector<std::shared_ptr<RecordBatch>>& batches,
                                 std::shared_ptr<Table>* table) {
+  return FromRecordBatches(std::move(schema), batches).Value(table);
+}
+
+Result<std::shared_ptr<Table>> Table::FromRecordBatches(
+    const std::vector<std::shared_ptr<RecordBatch>>& batches) {
   if (batches.size() == 0) {
-    return Status::Invalid("Must pass at least one record batch");
+    return Status::Invalid("Must pass at least one record batch or an explicit 
Schema");
   }
 
-  return FromRecordBatches(batches[0]->schema(), batches, table);
+  return FromRecordBatches(batches[0]->schema(), batches);
 }
 
-Status Table::FromChunkedStructArray(const std::shared_ptr<ChunkedArray>& 
array,
-                                     std::shared_ptr<Table>* table) {
+Status Table::FromRecordBatches(const 
std::vector<std::shared_ptr<RecordBatch>>& batches,
+                                std::shared_ptr<Table>* table) {
+  return FromRecordBatches(batches).Value(table);
+}
+
+Result<std::shared_ptr<Table>> Table::FromChunkedStructArray(
+    const std::shared_ptr<ChunkedArray>& array) {
   auto type = array->type();
   if (type->id() != Type::STRUCT) {
     return Status::Invalid("Expected a chunked struct array, got ", *type);
@@ -534,11 +539,32 @@ Status Table::FromChunkedStructArray(const 
std::shared_ptr<ChunkedArray>& array,
                    [i](const std::shared_ptr<Array>& struct_chunk) {
                      return static_cast<const 
StructArray&>(*struct_chunk).field(i);
                    });
-    columns[i] = std::make_shared<ChunkedArray>(chunks);
+    columns[i] = std::make_shared<ChunkedArray>(std::move(chunks));
   }
 
-  *table = Table::Make(::arrow::schema(type->children()), columns, 
array->length());
-  return Status::OK();
+  return Table::Make(::arrow::schema(type->children()), std::move(columns),
+                     array->length());
+}
+
+Status Table::FromChunkedStructArray(const std::shared_ptr<ChunkedArray>& 
array,
+                                     std::shared_ptr<Table>* table) {
+  return FromChunkedStructArray(array).Value(table);
+}
+
+Status Table::RemoveColumn(int i, std::shared_ptr<Table>* out) const {
+  return RemoveColumn(i).Value(out);
+}
+
+Status Table::AddColumn(int i, std::shared_ptr<Field> field_arg,
+                        std::shared_ptr<ChunkedArray> column,
+                        std::shared_ptr<Table>* out) const {
+  return AddColumn(i, std::move(field_arg), std::move(column)).Value(out);
+}
+
+Status Table::SetColumn(int i, std::shared_ptr<Field> field_arg,
+                        std::shared_ptr<ChunkedArray> column,
+                        std::shared_ptr<Table>* out) const {
+  return SetColumn(i, std::move(field_arg), std::move(column)).Value(out);
 }
 
 std::vector<std::string> Table::ColumnNames() const {
@@ -549,8 +575,8 @@ std::vector<std::string> Table::ColumnNames() const {
   return names;
 }
 
-Status Table::RenameColumns(const std::vector<std::string>& names,
-                            std::shared_ptr<Table>* out) const {
+Result<std::shared_ptr<Table>> Table::RenameColumns(
+    const std::vector<std::string>& names) const {
   if (names.size() != static_cast<size_t>(num_columns())) {
     return Status::Invalid("tried to rename a table of ", num_columns(),
                            " columns but only ", names.size(), " names were 
provided");
@@ -561,8 +587,16 @@ Status Table::RenameColumns(const 
std::vector<std::string>& names,
     columns[i] = column(i);
     fields[i] = field(i)->WithName(names[i]);
   }
-  *out = Table::Make(::arrow::schema(std::move(fields)), std::move(columns), 
num_rows());
-  return Status::OK();
+  return Table::Make(::arrow::schema(std::move(fields)), std::move(columns), 
num_rows());
+}
+
+Status Table::RenameColumns(const std::vector<std::string>& names,
+                            std::shared_ptr<Table>* out) const {
+  return RenameColumns(names).Value(out);
+}
+
+Status Table::Flatten(MemoryPool* pool, std::shared_ptr<Table>* out) const {
+  return Flatten(pool).Value(out);
 }
 
 Result<std::shared_ptr<Table>> ConcatenateTables(
@@ -711,7 +745,7 @@ bool Table::Equals(const Table& other, bool check_metadata) 
const {
   return true;
 }
 
-Status Table::CombineChunks(MemoryPool* pool, std::shared_ptr<Table>* out) 
const {
+Result<std::shared_ptr<Table>> Table::CombineChunks(MemoryPool* pool) const {
   const int ncolumns = num_columns();
   std::vector<std::shared_ptr<ChunkedArray>> compacted_columns(ncolumns);
   for (int i = 0; i < ncolumns; ++i) {
@@ -724,8 +758,11 @@ Status Table::CombineChunks(MemoryPool* pool, 
std::shared_ptr<Table>* out) const
       compacted_columns[i] = std::make_shared<ChunkedArray>(compacted);
     }
   }
-  *out = Table::Make(schema(), compacted_columns);
-  return Status::OK();
+  return Table::Make(schema(), std::move(compacted_columns));
+}
+
+Status Table::CombineChunks(MemoryPool* pool, std::shared_ptr<Table>* out) 
const {
+  return CombineChunks(pool).Value(out);
 }
 
 // ----------------------------------------------------------------------
diff --git a/cpp/src/arrow/table.h b/cpp/src/arrow/table.h
index fc5d499..a94b952 100644
--- a/cpp/src/arrow/table.h
+++ b/cpp/src/arrow/table.h
@@ -224,15 +224,15 @@ class ARROW_EXPORT Table {
   /// \param schema The table schema (column types)
   /// \param columns The table's columns as chunked arrays
   /// \param num_rows number of rows in table, -1 (default) to infer from 
columns
-  static std::shared_ptr<Table> Make(
-      const std::shared_ptr<Schema>& schema,
-      const std::vector<std::shared_ptr<ChunkedArray>>& columns, int64_t 
num_rows = -1);
+  static std::shared_ptr<Table> Make(std::shared_ptr<Schema> schema,
+                                     
std::vector<std::shared_ptr<ChunkedArray>> columns,
+                                     int64_t num_rows = -1);
 
   /// \brief Construct a Table from schema and arrays
   /// \param schema The table schema (column types)
   /// \param arrays The table's columns as arrays
   /// \param num_rows number of rows in table, -1 (default) to infer from 
columns
-  static std::shared_ptr<Table> Make(const std::shared_ptr<Schema>& schema,
+  static std::shared_ptr<Table> Make(std::shared_ptr<Schema> schema,
                                      const 
std::vector<std::shared_ptr<Array>>& arrays,
                                      int64_t num_rows = -1);
 
@@ -240,8 +240,10 @@ class ARROW_EXPORT Table {
   /// RecordBatch.
   ///
   /// \param[in] batches a std::vector of record batches
-  /// \param[out] table the returned table
-  /// \return Status Returns Status::Invalid if there is some problem
+  static Result<std::shared_ptr<Table>> FromRecordBatches(
+      const std::vector<std::shared_ptr<RecordBatch>>& batches);
+
+  ARROW_DEPRECATED("Use Result-returning version")
   static Status FromRecordBatches(
       const std::vector<std::shared_ptr<RecordBatch>>& batches,
       std::shared_ptr<Table>* table);
@@ -251,10 +253,13 @@ class ARROW_EXPORT Table {
   ///
   /// \param[in] schema the arrow::Schema for each batch
   /// \param[in] batches a std::vector of record batches
-  /// \param[out] table the returned table
-  /// \return Status
+  static Result<std::shared_ptr<Table>> FromRecordBatches(
+      std::shared_ptr<Schema> schema,
+      const std::vector<std::shared_ptr<RecordBatch>>& batches);
+
+  ARROW_DEPRECATED("Use Result-returning version")
   static Status FromRecordBatches(
-      const std::shared_ptr<Schema>& schema,
+      std::shared_ptr<Schema> schema,
       const std::vector<std::shared_ptr<RecordBatch>>& batches,
       std::shared_ptr<Table>* table);
 
@@ -262,8 +267,10 @@ class ARROW_EXPORT Table {
   /// for each field of the StructArray.
   ///
   /// \param[in] array a chunked StructArray
-  /// \param[out] table the returned table
-  /// \return Status
+  static Result<std::shared_ptr<Table>> FromChunkedStructArray(
+      const std::shared_ptr<ChunkedArray>& array);
+
+  ARROW_DEPRECATED("Use Result-returning version")
   static Status FromChunkedStructArray(const std::shared_ptr<ChunkedArray>& 
array,
                                        std::shared_ptr<Table>* table);
 
@@ -305,22 +312,39 @@ class ARROW_EXPORT Table {
   }
 
   /// \brief Remove column from the table, producing a new Table
-  virtual Status RemoveColumn(int i, std::shared_ptr<Table>* out) const = 0;
+  virtual Result<std::shared_ptr<Table>> RemoveColumn(int i) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status RemoveColumn(int i, std::shared_ptr<Table>* out) const;
 
   /// \brief Add column to the table, producing a new Table
-  virtual Status AddColumn(int i, std::shared_ptr<Field> field_arg,
-                           std::shared_ptr<ChunkedArray> column,
-                           std::shared_ptr<Table>* out) const = 0;
+  virtual Result<std::shared_ptr<Table>> AddColumn(
+      int i, std::shared_ptr<Field> field_arg,
+      std::shared_ptr<ChunkedArray> column) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status AddColumn(int i, std::shared_ptr<Field> field_arg,
+                   std::shared_ptr<ChunkedArray> column,
+                   std::shared_ptr<Table>* out) const;
 
   /// \brief Replace a column in the table, producing a new Table
-  virtual Status SetColumn(int i, std::shared_ptr<Field> field_arg,
-                           std::shared_ptr<ChunkedArray> column,
-                           std::shared_ptr<Table>* out) const = 0;
+  virtual Result<std::shared_ptr<Table>> SetColumn(
+      int i, std::shared_ptr<Field> field_arg,
+      std::shared_ptr<ChunkedArray> column) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status SetColumn(int i, std::shared_ptr<Field> field_arg,
+                   std::shared_ptr<ChunkedArray> column,
+                   std::shared_ptr<Table>* out) const;
 
   /// \brief Return names of all columns
   std::vector<std::string> ColumnNames() const;
 
   /// \brief Rename columns with provided names
+  Result<std::shared_ptr<Table>> RenameColumns(
+      const std::vector<std::string>& names) const;
+
+  ARROW_DEPRECATED("Use Result-returning version")
   Status RenameColumns(const std::vector<std::string>& names,
                        std::shared_ptr<Table>* out) const;
 
@@ -336,8 +360,11 @@ class ARROW_EXPORT Table {
   /// struct type will be flattened into multiple columns
   ///
   /// \param[in] pool The pool for buffer allocations, if any
-  /// \param[out] out The returned table
-  virtual Status Flatten(MemoryPool* pool, std::shared_ptr<Table>* out) const 
= 0;
+  virtual Result<std::shared_ptr<Table>> Flatten(
+      MemoryPool* pool = default_memory_pool()) const = 0;
+
+  ARROW_DEPRECATED("Use Result-returning version")
+  Status Flatten(MemoryPool* pool, std::shared_ptr<Table>* out) const;
 
   /// \brief Perform cheap validation checks to determine obvious 
inconsistencies
   /// within the table's schema and internal data.
@@ -375,7 +402,10 @@ class ARROW_EXPORT Table {
   /// concatenated into zero or one chunk.
   ///
   /// \param[in] pool The pool for buffer allocations
-  /// \param[out] out The table with chunks combined
+  Result<std::shared_ptr<Table>> CombineChunks(
+      MemoryPool* pool = default_memory_pool()) const;
+
+  ARROW_DEPRECATED("Use Result-returning version")
   Status CombineChunks(MemoryPool* pool, std::shared_ptr<Table>* out) const;
 
  protected:
diff --git a/cpp/src/arrow/table_test.cc b/cpp/src/arrow/table_test.cc
index 652d690..c0a3ff2 100644
--- a/cpp/src/arrow/table_test.cc
+++ b/cpp/src/arrow/table_test.cc
@@ -346,10 +346,9 @@ TEST_F(TestTable, FromRecordBatches) {
 
   auto batch1 = RecordBatch::Make(schema_, length, arrays_);
 
-  std::shared_ptr<Table> result, expected;
-  ASSERT_OK(Table::FromRecordBatches({batch1}, &result));
+  ASSERT_OK_AND_ASSIGN(auto result, Table::FromRecordBatches({batch1}));
 
-  expected = Table::Make(schema_, columns_);
+  auto expected = Table::Make(schema_, columns_);
   ASSERT_TRUE(result->Equals(*expected));
 
   std::vector<std::shared_ptr<ChunkedArray>> other_columns;
@@ -358,27 +357,26 @@ TEST_F(TestTable, FromRecordBatches) {
     other_columns.push_back(std::make_shared<ChunkedArray>(col_arrays));
   }
 
-  ASSERT_OK(Table::FromRecordBatches({batch1, batch1}, &result));
+  ASSERT_OK_AND_ASSIGN(result, Table::FromRecordBatches({batch1, batch1}));
   expected = Table::Make(schema_, other_columns);
   ASSERT_TRUE(result->Equals(*expected));
 
   // Error states
   std::vector<std::shared_ptr<RecordBatch>> empty_batches;
-  ASSERT_RAISES(Invalid, Table::FromRecordBatches(empty_batches, &result));
+  ASSERT_RAISES(Invalid, Table::FromRecordBatches(empty_batches));
 
   auto other_schema = ::arrow::schema({schema_->field(0), schema_->field(1)});
 
   std::vector<std::shared_ptr<Array>> other_arrays = {arrays_[0], arrays_[1]};
   auto batch2 = RecordBatch::Make(other_schema, length, other_arrays);
-  ASSERT_RAISES(Invalid, Table::FromRecordBatches({batch1, batch2}, &result));
+  ASSERT_RAISES(Invalid, Table::FromRecordBatches({batch1, batch2}));
 }
 
 TEST_F(TestTable, FromRecordBatchesZeroLength) {
   // ARROW-2307
   MakeExample1(10);
 
-  std::shared_ptr<Table> result;
-  ASSERT_OK(Table::FromRecordBatches(schema_, {}, &result));
+  ASSERT_OK_AND_ASSIGN(auto result, Table::FromRecordBatches(schema_, {}));
 
   ASSERT_EQ(0, result->num_rows());
   ASSERT_TRUE(result->schema()->Equals(*schema_));
@@ -387,12 +385,10 @@ TEST_F(TestTable, FromRecordBatchesZeroLength) {
 TEST_F(TestTable, CombineChunksEmptyTable) {
   MakeExample1(10);
 
-  std::shared_ptr<Table> table;
-  ASSERT_OK(Table::FromRecordBatches(schema_, {}, &table));
+  ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches(schema_, {}));
   ASSERT_EQ(0, table->num_rows());
 
-  std::shared_ptr<Table> compacted;
-  ASSERT_OK(table->CombineChunks(default_memory_pool(), &compacted));
+  ASSERT_OK_AND_ASSIGN(auto compacted, table->CombineChunks());
 
   EXPECT_TRUE(compacted->Equals(*table));
 }
@@ -404,14 +400,12 @@ TEST_F(TestTable, CombineChunks) {
   MakeExample1(15);
   auto batch2 = RecordBatch::Make(schema_, 15, arrays_);
 
-  std::shared_ptr<Table> table;
-  ASSERT_OK(Table::FromRecordBatches({batch1, batch2}, &table));
+  ASSERT_OK_AND_ASSIGN(auto table, Table::FromRecordBatches({batch1, batch2}));
   for (int i = 0; i < table->num_columns(); ++i) {
     ASSERT_EQ(2, table->column(i)->num_chunks());
   }
 
-  std::shared_ptr<Table> compacted;
-  ASSERT_OK(table->CombineChunks(default_memory_pool(), &compacted));
+  ASSERT_OK_AND_ASSIGN(auto compacted, table->CombineChunks());
 
   EXPECT_TRUE(compacted->Equals(*table));
   for (int i = 0; i < compacted->num_columns(); ++i) {
@@ -429,12 +423,11 @@ TEST_F(TestTable, ConcatenateTables) {
   MakeExample1(length);
   auto batch2 = RecordBatch::Make(schema_, length, arrays_);
 
-  std::shared_ptr<Table> t1, t2, t3, result, expected;
-  ASSERT_OK(Table::FromRecordBatches({batch1}, &t1));
-  ASSERT_OK(Table::FromRecordBatches({batch2}, &t2));
+  ASSERT_OK_AND_ASSIGN(auto t1, Table::FromRecordBatches({batch1}));
+  ASSERT_OK_AND_ASSIGN(auto t2, Table::FromRecordBatches({batch2}));
 
-  ASSERT_OK_AND_ASSIGN(result, ConcatenateTables({t1, t2}));
-  ASSERT_OK(Table::FromRecordBatches({batch1, batch2}, &expected));
+  ASSERT_OK_AND_ASSIGN(auto result, ConcatenateTables({t1, t2}));
+  ASSERT_OK_AND_ASSIGN(auto expected, Table::FromRecordBatches({batch1, 
batch2}));
   AssertTablesEqual(*expected, *result);
 
   // Error states
@@ -445,7 +438,7 @@ TEST_F(TestTable, ConcatenateTables) {
 
   std::vector<std::shared_ptr<Array>> other_arrays = {arrays_[0], arrays_[1]};
   auto batch3 = RecordBatch::Make(other_schema, length, other_arrays);
-  ASSERT_OK(Table::FromRecordBatches({batch3}, &t3));
+  ASSERT_OK_AND_ASSIGN(auto t3, Table::FromRecordBatches({batch3}));
 
   ASSERT_RAISES(Invalid, ConcatenateTables({t1, t3}));
 }
@@ -612,13 +605,12 @@ TEST_F(ConcatenateTablesWithPromotionTest, Simple) {
   auto batch2_null_filled =
       RecordBatch::Make(batch1->schema(), length, {arrays_[0], f1_nulls, 
f2_nulls});
 
-  std::shared_ptr<Table> t1, t2, t3, result, expected;
-  ASSERT_OK(Table::FromRecordBatches({batch1}, &t1));
-  ASSERT_OK(Table::FromRecordBatches({batch2}, &t2));
-  ASSERT_OK(Table::FromRecordBatches({batch2_null_filled}, &t3));
+  ASSERT_OK_AND_ASSIGN(auto t1, Table::FromRecordBatches({batch1}));
+  ASSERT_OK_AND_ASSIGN(auto t2, Table::FromRecordBatches({batch2}));
+  ASSERT_OK_AND_ASSIGN(auto t3, 
Table::FromRecordBatches({batch2_null_filled}));
 
-  ASSERT_OK_AND_ASSIGN(result, ConcatenateTables({t1, t2}, GetOptions()));
-  ASSERT_OK_AND_ASSIGN(expected, ConcatenateTables({t1, t3}));
+  ASSERT_OK_AND_ASSIGN(auto result, ConcatenateTables({t1, t2}, GetOptions()));
+  ASSERT_OK_AND_ASSIGN(auto expected, ConcatenateTables({t1, t3}));
   AssertTablesEqualUnorderedFields(*expected, *result);
 
   ASSERT_OK_AND_ASSIGN(result, ConcatenateTables({t2, t1}, GetOptions()));
@@ -632,10 +624,9 @@ TEST_F(TestTable, Slice) {
   MakeExample1(length);
   auto batch = RecordBatch::Make(schema_, length, arrays_);
 
-  std::shared_ptr<Table> half, whole, three;
-  ASSERT_OK(Table::FromRecordBatches({batch}, &half));
-  ASSERT_OK(Table::FromRecordBatches({batch, batch}, &whole));
-  ASSERT_OK(Table::FromRecordBatches({batch, batch, batch}, &three));
+  ASSERT_OK_AND_ASSIGN(auto half, Table::FromRecordBatches({batch}));
+  ASSERT_OK_AND_ASSIGN(auto whole, Table::FromRecordBatches({batch, batch}));
+  ASSERT_OK_AND_ASSIGN(auto three, Table::FromRecordBatches({batch, batch, 
batch}));
 
   AssertTablesEqual(*whole->Slice(0, length), *half);
   AssertTablesEqual(*whole->Slice(length), *half);
@@ -650,8 +641,7 @@ TEST_F(TestTable, RemoveColumn) {
   auto table_sp = Table::Make(schema_, columns_);
   const Table& table = *table_sp;
 
-  std::shared_ptr<Table> result;
-  ASSERT_OK(table.RemoveColumn(0, &result));
+  ASSERT_OK_AND_ASSIGN(auto result, table.RemoveColumn(0));
 
   auto ex_schema = ::arrow::schema({schema_->field(1), schema_->field(2)});
   std::vector<std::shared_ptr<ChunkedArray>> ex_columns = {table.column(1),
@@ -660,14 +650,14 @@ TEST_F(TestTable, RemoveColumn) {
   auto expected = Table::Make(ex_schema, ex_columns);
   ASSERT_TRUE(result->Equals(*expected));
 
-  ASSERT_OK(table.RemoveColumn(1, &result));
+  ASSERT_OK_AND_ASSIGN(result, table.RemoveColumn(1));
   ex_schema = ::arrow::schema({schema_->field(0), schema_->field(2)});
   ex_columns = {table.column(0), table.column(2)};
 
   expected = Table::Make(ex_schema, ex_columns);
   ASSERT_TRUE(result->Equals(*expected));
 
-  ASSERT_OK(table.RemoveColumn(2, &result));
+  ASSERT_OK_AND_ASSIGN(result, table.RemoveColumn(2));
   ex_schema = ::arrow::schema({schema_->field(0), schema_->field(1)});
   ex_columns = {table.column(0), table.column(1)};
   expected = Table::Make(ex_schema, ex_columns);
@@ -681,8 +671,8 @@ TEST_F(TestTable, SetColumn) {
   auto table_sp = Table::Make(schema_, columns_);
   const Table& table = *table_sp;
 
-  std::shared_ptr<Table> result;
-  ASSERT_OK(table.SetColumn(0, schema_->field(1), table.column(1), &result));
+  ASSERT_OK_AND_ASSIGN(auto result,
+                       table.SetColumn(0, schema_->field(1), table.column(1)));
 
   auto ex_schema =
       ::arrow::schema({schema_->field(1), schema_->field(1), 
schema_->field(2)});
@@ -697,12 +687,11 @@ TEST_F(TestTable, RenameColumns) {
   auto table = Table::Make(schema_, columns_);
   EXPECT_THAT(table->ColumnNames(), testing::ElementsAre("f0", "f1", "f2"));
 
-  std::shared_ptr<Table> renamed;
-  ASSERT_OK(table->RenameColumns({"zero", "one", "two"}, &renamed));
+  ASSERT_OK_AND_ASSIGN(auto renamed, table->RenameColumns({"zero", "one", 
"two"}));
   EXPECT_THAT(renamed->ColumnNames(), testing::ElementsAre("zero", "one", 
"two"));
   ASSERT_OK(renamed->ValidateFull());
 
-  ASSERT_RAISES(Invalid, table->RenameColumns({"hello", "world"}, &renamed));
+  ASSERT_RAISES(Invalid, table->RenameColumns({"hello", "world"}));
 }
 
 TEST_F(TestTable, RemoveColumnEmpty) {
@@ -715,13 +704,11 @@ TEST_F(TestTable, RemoveColumnEmpty) {
 
   auto table = Table::Make(schema, {std::make_shared<ChunkedArray>(a0)});
 
-  std::shared_ptr<Table> empty;
-  ASSERT_OK(table->RemoveColumn(0, &empty));
+  ASSERT_OK_AND_ASSIGN(auto empty, table->RemoveColumn(0));
 
   ASSERT_EQ(table->num_rows(), empty->num_rows());
 
-  std::shared_ptr<Table> added;
-  ASSERT_OK(empty->AddColumn(0, f0, table->column(0), &added));
+  ASSERT_OK_AND_ASSIGN(auto added, empty->AddColumn(0, f0, table->column(0)));
   ASSERT_EQ(table->num_rows(), added->num_rows());
 }
 
@@ -734,23 +721,18 @@ TEST_F(TestTable, AddColumn) {
 
   auto f0 = schema_->field(0);
 
-  std::shared_ptr<Table> result;
   // Some negative tests with invalid index
-  Status status = table.AddColumn(10, f0, columns_[0], &result);
-  ASSERT_TRUE(status.IsInvalid());
-  status = table.AddColumn(4, f0, columns_[0], &result);
-  ASSERT_TRUE(status.IsInvalid());
-  status = table.AddColumn(-1, f0, columns_[0], &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, table.AddColumn(10, f0, columns_[0]));
+  ASSERT_RAISES(Invalid, table.AddColumn(4, f0, columns_[0]));
+  ASSERT_RAISES(Invalid, table.AddColumn(-1, f0, columns_[0]));
 
   // Add column with wrong length
   auto longer_col =
       std::make_shared<ChunkedArray>(MakeRandomArray<Int32Array>(length + 1));
-  status = table.AddColumn(0, f0, longer_col, &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, table.AddColumn(0, f0, longer_col));
 
   // Add column 0 in different places
-  ASSERT_OK(table.AddColumn(0, f0, columns_[0], &result));
+  ASSERT_OK_AND_ASSIGN(auto result, table.AddColumn(0, f0, columns_[0]));
   auto ex_schema = ::arrow::schema(
       {schema_->field(0), schema_->field(0), schema_->field(1), 
schema_->field(2)});
 
@@ -758,7 +740,7 @@ TEST_F(TestTable, AddColumn) {
       ex_schema, {table.column(0), table.column(0), table.column(1), 
table.column(2)});
   ASSERT_TRUE(result->Equals(*expected));
 
-  ASSERT_OK(table.AddColumn(1, f0, columns_[0], &result));
+  ASSERT_OK_AND_ASSIGN(result, table.AddColumn(1, f0, columns_[0]));
   ex_schema = ::arrow::schema(
       {schema_->field(0), schema_->field(0), schema_->field(1), 
schema_->field(2)});
 
@@ -766,14 +748,14 @@ TEST_F(TestTable, AddColumn) {
       ex_schema, {table.column(0), table.column(0), table.column(1), 
table.column(2)});
   ASSERT_TRUE(result->Equals(*expected));
 
-  ASSERT_OK(table.AddColumn(2, f0, columns_[0], &result));
+  ASSERT_OK_AND_ASSIGN(result, table.AddColumn(2, f0, columns_[0]));
   ex_schema = ::arrow::schema(
       {schema_->field(0), schema_->field(1), schema_->field(0), 
schema_->field(2)});
   expected = Table::Make(
       ex_schema, {table.column(0), table.column(1), table.column(0), 
table.column(2)});
   ASSERT_TRUE(result->Equals(*expected));
 
-  ASSERT_OK(table.AddColumn(3, f0, columns_[0], &result));
+  ASSERT_OK_AND_ASSIGN(result, table.AddColumn(3, f0, columns_[0]));
   ex_schema = ::arrow::schema(
       {schema_->field(0), schema_->field(1), schema_->field(2), 
schema_->field(0)});
   expected = Table::Make(
@@ -890,36 +872,29 @@ TEST_F(TestRecordBatch, AddColumn) {
   auto batch3 = RecordBatch::Make(schema3, length, {array2});
 
   const RecordBatch& batch = *batch3;
-  std::shared_ptr<RecordBatch> result;
 
   // Negative tests with invalid index
-  Status status = batch.AddColumn(5, field1, array1, &result);
-  ASSERT_TRUE(status.IsInvalid());
-  status = batch.AddColumn(2, field1, array1, &result);
-  ASSERT_TRUE(status.IsInvalid());
-  status = batch.AddColumn(-1, field1, array1, &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, batch.AddColumn(5, field1, array1));
+  ASSERT_RAISES(Invalid, batch.AddColumn(2, field1, array1));
+  ASSERT_RAISES(Invalid, batch.AddColumn(-1, field1, array1));
 
   // Negative test with wrong length
   auto longer_col = MakeRandomArray<Int32Array>(length + 1);
-  status = batch.AddColumn(0, field1, longer_col, &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, batch.AddColumn(0, field1, longer_col));
 
   // Negative test with mismatch type
-  status = batch.AddColumn(0, field1, array2, &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, batch.AddColumn(0, field1, array2));
 
-  ASSERT_OK(batch.AddColumn(0, field1, array1, &result));
-  ASSERT_TRUE(result->Equals(*batch1));
+  ASSERT_OK_AND_ASSIGN(auto new_batch, batch.AddColumn(0, field1, array1));
+  AssertBatchesEqual(*new_batch, *batch1);
 
-  ASSERT_OK(batch.AddColumn(1, field3, array3, &result));
-  ASSERT_TRUE(result->Equals(*batch2));
+  ASSERT_OK_AND_ASSIGN(new_batch, batch.AddColumn(1, field3, array3));
+  AssertBatchesEqual(*new_batch, *batch2);
 
-  std::shared_ptr<RecordBatch> result2;
-  ASSERT_OK(batch.AddColumn(1, "f3", array3, &result2));
-  ASSERT_TRUE(result2->Equals(*result));
+  ASSERT_OK_AND_ASSIGN(auto new_batch2, batch.AddColumn(1, "f3", array3));
+  AssertBatchesEqual(*new_batch2, *new_batch);
 
-  ASSERT_TRUE(result2->schema()->field(1)->nullable());
+  ASSERT_TRUE(new_batch2->schema()->field(1)->nullable());
 }
 
 TEST_F(TestRecordBatch, RemoveColumn) {
@@ -947,19 +922,17 @@ TEST_F(TestRecordBatch, RemoveColumn) {
   std::shared_ptr<RecordBatch> result;
 
   // Negative tests with invalid index
-  Status status = batch.RemoveColumn(3, &result);
-  ASSERT_TRUE(status.IsInvalid());
-  status = batch.RemoveColumn(-1, &result);
-  ASSERT_TRUE(status.IsInvalid());
+  ASSERT_RAISES(Invalid, batch.RemoveColumn(3));
+  ASSERT_RAISES(Invalid, batch.RemoveColumn(-1));
 
-  ASSERT_OK(batch.RemoveColumn(0, &result));
-  ASSERT_TRUE(result->Equals(*batch2));
+  ASSERT_OK_AND_ASSIGN(auto new_batch, batch.RemoveColumn(0));
+  AssertBatchesEqual(*new_batch, *batch2);
 
-  ASSERT_OK(batch.RemoveColumn(1, &result));
-  ASSERT_TRUE(result->Equals(*batch3));
+  ASSERT_OK_AND_ASSIGN(new_batch, batch.RemoveColumn(1));
+  AssertBatchesEqual(*new_batch, *batch3);
 
-  ASSERT_OK(batch.RemoveColumn(2, &result));
-  ASSERT_TRUE(result->Equals(*batch4));
+  ASSERT_OK_AND_ASSIGN(new_batch, batch.RemoveColumn(2));
+  AssertBatchesEqual(*new_batch, *batch4);
 }
 
 TEST_F(TestRecordBatch, RemoveColumnEmpty) {
@@ -970,13 +943,11 @@ TEST_F(TestRecordBatch, RemoveColumnEmpty) {
   auto array1 = MakeRandomArray<Int32Array>(length);
   auto batch1 = RecordBatch::Make(schema1, length, {array1});
 
-  std::shared_ptr<RecordBatch> empty;
-  ASSERT_OK(batch1->RemoveColumn(0, &empty));
+  ASSERT_OK_AND_ASSIGN(auto empty, batch1->RemoveColumn(0));
   ASSERT_EQ(batch1->num_rows(), empty->num_rows());
 
-  std::shared_ptr<RecordBatch> added;
-  ASSERT_OK(empty->AddColumn(0, field1, array1, &added));
-  ASSERT_TRUE(added->Equals(*batch1));
+  ASSERT_OK_AND_ASSIGN(auto added, empty->AddColumn(0, field1, array1));
+  AssertBatchesEqual(*added, *batch1);
 }
 
 class TestTableBatchReader : public TestBase {};
diff --git a/cpp/src/arrow/testing/generator.h 
b/cpp/src/arrow/testing/generator.h
index b43cec1..2066629 100644
--- a/cpp/src/arrow/testing/generator.h
+++ b/cpp/src/arrow/testing/generator.h
@@ -222,11 +222,9 @@ class ARROW_EXPORT ConstantArrayGenerator {
   /// \return a generated RecordBatchReader
   static std::shared_ptr<arrow::RecordBatchReader> Repeat(
       int64_t n_batch, const std::shared_ptr<RecordBatch> batch) {
-    std::vector<std::shared_ptr<RecordBatch>> 
batches{static_cast<size_t>(n_batch),
-                                                      batch};
-    std::shared_ptr<RecordBatchReader> reader;
-    ARROW_EXPECT_OK(MakeRecordBatchReader(batches, nullptr, &reader));
-    return reader;
+    std::vector<std::shared_ptr<RecordBatch>> 
batches(static_cast<size_t>(n_batch),
+                                                      batch);
+    return *MakeRecordBatchReader(batches);
   }
 
   /// \brief Generates a RecordBatchReader of zeroes batches
diff --git a/cpp/src/arrow/testing/gtest_util.cc 
b/cpp/src/arrow/testing/gtest_util.cc
index e758b81..d36456a 100644
--- a/cpp/src/arrow/testing/gtest_util.cc
+++ b/cpp/src/arrow/testing/gtest_util.cc
@@ -239,15 +239,12 @@ std::shared_ptr<ChunkedArray> ChunkedArrayFromJSON(const 
std::shared_ptr<DataTyp
 
 std::shared_ptr<RecordBatch> RecordBatchFromJSON(const 
std::shared_ptr<Schema>& schema,
                                                  util::string_view json) {
-  // Parses as a StructArray
+  // Parse as a StructArray
   auto struct_type = struct_(schema->fields());
   std::shared_ptr<Array> struct_array = ArrayFromJSON(struct_type, json);
 
-  // Converts StructArray to RecordBatch
-  std::shared_ptr<RecordBatch> record_batch;
-  ABORT_NOT_OK(RecordBatch::FromStructArray(struct_array, &record_batch));
-
-  return record_batch;
+  // Convert StructArray to RecordBatch
+  return *RecordBatch::FromStructArray(struct_array);
 }
 
 std::shared_ptr<Table> TableFromJSON(const std::shared_ptr<Schema>& schema,
@@ -256,10 +253,7 @@ std::shared_ptr<Table> TableFromJSON(const 
std::shared_ptr<Schema>& schema,
   for (const std::string& batch_json : json) {
     batches.push_back(RecordBatchFromJSON(schema, batch_json));
   }
-  std::shared_ptr<Table> table;
-  ABORT_NOT_OK(Table::FromRecordBatches(schema, batches, &table));
-
-  return table;
+  return *Table::FromRecordBatches(schema, std::move(batches));
 }
 
 void AssertTablesEqual(const Table& expected, const Table& actual, bool 
same_chunk_layout,
@@ -268,9 +262,8 @@ void AssertTablesEqual(const Table& expected, const Table& 
actual, bool same_chu
 
   if (combine_chunks) {
     auto pool = default_memory_pool();
-    std::shared_ptr<Table> new_expected, new_actual;
-    ASSERT_OK(expected.CombineChunks(pool, &new_expected));
-    ASSERT_OK(actual.CombineChunks(pool, &new_actual));
+    ASSERT_OK_AND_ASSIGN(auto new_expected, expected.CombineChunks(pool));
+    ASSERT_OK_AND_ASSIGN(auto new_actual, actual.CombineChunks(pool));
 
     AssertTablesEqual(*new_expected, *new_actual, false, false);
     return;
diff --git a/cpp/src/parquet/arrow/generate_fuzz_corpus.cc 
b/cpp/src/parquet/arrow/generate_fuzz_corpus.cc
index e5d8660..f2a1b22 100644
--- a/cpp/src/parquet/arrow/generate_fuzz_corpus.cc
+++ b/cpp/src/parquet/arrow/generate_fuzz_corpus.cc
@@ -98,8 +98,7 @@ Status DoMain(const std::string& out_dir) {
 
   for (const auto& batch : batches) {
     RETURN_NOT_OK(batch->ValidateFull());
-    std::shared_ptr<Table> table;
-    RETURN_NOT_OK(Table::FromRecordBatches({batch}, &table));
+    ARROW_ASSIGN_OR_RAISE(auto table, Table::FromRecordBatches({batch}));
 
     ARROW_ASSIGN_OR_RAISE(auto sample_fn, dir_fn.Join(sample_name()));
     std::cerr << sample_fn.ToString() << std::endl;
diff --git a/python/pyarrow/includes/libarrow.pxd 
b/python/pyarrow/includes/libarrow.pxd
index 61f2a6d..a7fe4cf 100644
--- a/python/pyarrow/includes/libarrow.pxd
+++ b/python/pyarrow/includes/libarrow.pxd
@@ -658,8 +658,8 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:
             const vector[shared_ptr[CArray]]& columns)
 
         @staticmethod
-        CStatus FromStructArray(const shared_ptr[CArray]& array,
-                                shared_ptr[CRecordBatch]* out)
+        CResult[shared_ptr[CRecordBatch]] FromStructArray(
+            const shared_ptr[CArray]& array)
 
         c_bool Equals(const CRecordBatch& other, c_bool check_metadata)
 
@@ -696,10 +696,9 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:
             const vector[shared_ptr[CArray]]& arrays)
 
         @staticmethod
-        CStatus FromRecordBatches(
+        CResult[shared_ptr[CTable]] FromRecordBatches(
             const shared_ptr[CSchema]& schema,
-            const vector[shared_ptr[CRecordBatch]]& batches,
-            shared_ptr[CTable]* table)
+            const vector[shared_ptr[CRecordBatch]]& batches)
 
         int num_columns()
         int64_t num_rows()
@@ -710,20 +709,18 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:
         shared_ptr[CChunkedArray] column(int i)
         shared_ptr[CField] field(int i)
 
-        CStatus AddColumn(int i, shared_ptr[CField] field,
-                          shared_ptr[CChunkedArray] column,
-                          shared_ptr[CTable]* out)
-        CStatus RemoveColumn(int i, shared_ptr[CTable]* out)
-        CStatus SetColumn(int i, shared_ptr[CField] field,
-                          shared_ptr[CChunkedArray] column,
-                          shared_ptr[CTable]* out)
+        CResult[shared_ptr[CTable]] AddColumn(
+            int i, shared_ptr[CField] field, shared_ptr[CChunkedArray] column)
+        CResult[shared_ptr[CTable]] RemoveColumn(int i)
+        CResult[shared_ptr[CTable]] SetColumn(
+            int i, shared_ptr[CField] field, shared_ptr[CChunkedArray] column)
 
         vector[c_string] ColumnNames()
-        CStatus RenameColumns(const vector[c_string]&, shared_ptr[CTable]* out)
+        CResult[shared_ptr[CTable]] RenameColumns(const vector[c_string]&)
 
-        CStatus Flatten(CMemoryPool* pool, shared_ptr[CTable]* out)
+        CResult[shared_ptr[CTable]] Flatten(CMemoryPool* pool)
 
-        CStatus CombineChunks(CMemoryPool* pool, shared_ptr[CTable]* out)
+        CResult[shared_ptr[CTable]] CombineChunks(CMemoryPool* pool)
 
         CStatus Validate() const
         CStatus ValidateFull() const
diff --git a/python/pyarrow/ipc.pxi b/python/pyarrow/ipc.pxi
index cba8ea2..c21a877 100644
--- a/python/pyarrow/ipc.pxi
+++ b/python/pyarrow/ipc.pxi
@@ -443,8 +443,8 @@ cdef class _RecordBatchFileReader:
         with nogil:
             for i in range(nbatches):
                 check_status(self.reader.get().ReadRecordBatch(i, &batches[i]))
-            check_status(CTable.FromRecordBatches(self.schema.sp_schema,
-                                                  batches, &table))
+            table = GetResultValue(
+                CTable.FromRecordBatches(self.schema.sp_schema, move(batches)))
 
         return pyarrow_wrap_table(table)
 
diff --git a/python/pyarrow/table.pxi b/python/pyarrow/table.pxi
index 1976dde..e29e94a 100644
--- a/python/pyarrow/table.pxi
+++ b/python/pyarrow/table.pxi
@@ -1013,8 +1013,8 @@ cdef class RecordBatch(_PandasConvertible):
         cdef:
             shared_ptr[CRecordBatch] c_record_batch
         with nogil:
-            check_status(CRecordBatch.FromStructArray(struct_array.sp_array,
-                                                      &c_record_batch))
+            c_record_batch = GetResultValue(
+                CRecordBatch.FromStructArray(struct_array.sp_array))
         return pyarrow_wrap_batch(c_record_batch)
 
     def _export_to_c(self, uintptr_t out_ptr, uintptr_t out_schema_ptr=0):
@@ -1294,7 +1294,7 @@ cdef class Table(_PandasConvertible):
             CMemoryPool* pool = maybe_unbox_memory_pool(memory_pool)
 
         with nogil:
-            check_status(self.table.Flatten(pool, &flattened))
+            flattened = GetResultValue(self.table.Flatten(pool))
 
         return pyarrow_wrap_table(flattened)
 
@@ -1319,7 +1319,7 @@ cdef class Table(_PandasConvertible):
             CMemoryPool* pool = maybe_unbox_memory_pool(memory_pool)
 
         with nogil:
-            check_status(self.table.CombineChunks(pool, &combined))
+            combined = GetResultValue(self.table.CombineChunks(pool))
 
         return pyarrow_wrap_table(combined)
 
@@ -1585,8 +1585,8 @@ cdef class Table(_PandasConvertible):
             c_schema = schema.sp_schema
 
         with nogil:
-            check_status(CTable.FromRecordBatches(c_schema, c_batches,
-                                                  &c_table))
+            c_table = GetResultValue(
+                CTable.FromRecordBatches(c_schema, move(c_batches)))
 
         return pyarrow_wrap_table(c_table)
 
@@ -1849,9 +1849,8 @@ cdef class Table(_PandasConvertible):
             c_field = field(field_, c_arr.type)
 
         with nogil:
-            check_status(self.table.AddColumn(i, c_field.sp_field,
-                                              c_arr.sp_chunked_array,
-                                              &c_table))
+            c_table = GetResultValue(self.table.AddColumn(
+                i, c_field.sp_field, c_arr.sp_chunked_array))
 
         return pyarrow_wrap_table(c_table)
 
@@ -1891,7 +1890,7 @@ cdef class Table(_PandasConvertible):
         cdef shared_ptr[CTable] c_table
 
         with nogil:
-            check_status(self.table.RemoveColumn(i, &c_table))
+            c_table = GetResultValue(self.table.RemoveColumn(i))
 
         return pyarrow_wrap_table(c_table)
 
@@ -1930,9 +1929,8 @@ cdef class Table(_PandasConvertible):
             c_field = field(field_, c_arr.type)
 
         with nogil:
-            check_status(self.table.SetColumn(i, c_field.sp_field,
-                                              c_arr.sp_chunked_array,
-                                              &c_table))
+            c_table = GetResultValue(self.table.SetColumn(
+                i, c_field.sp_field, c_arr.sp_chunked_array))
 
         return pyarrow_wrap_table(c_table)
 
@@ -1956,7 +1954,7 @@ cdef class Table(_PandasConvertible):
             c_names.push_back(tobytes(name))
 
         with nogil:
-            check_status(self.table.RenameColumns(c_names, &c_table))
+            c_table = GetResultValue(self.table.RenameColumns(move(c_names)))
 
         return pyarrow_wrap_table(c_table)
 
diff --git a/r/src/recordbatch.cpp b/r/src/recordbatch.cpp
index b0011e1..eb375c5 100644
--- a/r/src/recordbatch.cpp
+++ b/r/src/recordbatch.cpp
@@ -112,9 +112,7 @@ bool RecordBatch__Equals(const 
std::shared_ptr<arrow::RecordBatch>& self,
 std::shared_ptr<arrow::RecordBatch> RecordBatch__RemoveColumn(
     const std::shared_ptr<arrow::RecordBatch>& batch, int i) {
   arrow::r::validate_index(i, batch->num_columns());
-  std::shared_ptr<arrow::RecordBatch> res;
-  STOP_IF_NOT_OK(batch->RemoveColumn(i, &res));
-  return res;
+  return VALUE_OR_STOP(batch->RemoveColumn(i));
 }
 
 // [[arrow::export]]
diff --git a/r/src/recordbatchreader.cpp b/r/src/recordbatchreader.cpp
index 1a161ba..d29f59c 100644
--- a/r/src/recordbatchreader.cpp
+++ b/r/src/recordbatchreader.cpp
@@ -98,10 +98,7 @@ std::shared_ptr<arrow::Table> 
Table__from_RecordBatchFileReader(
     STOP_IF_NOT_OK(reader->ReadRecordBatch(i, &batches[i]));
   }
 
-  std::shared_ptr<arrow::Table> table;
-  STOP_IF_NOT_OK(arrow::Table::FromRecordBatches(std::move(batches), &table));
-
-  return table;
+  return VALUE_OR_STOP(arrow::Table::FromRecordBatches(std::move(batches)));
 }
 
 // [[arrow::export]]
@@ -115,10 +112,7 @@ std::shared_ptr<arrow::Table> 
Table__from_RecordBatchStreamReader(
     batches.push_back(batch);
   }
 
-  std::shared_ptr<arrow::Table> table;
-  STOP_IF_NOT_OK(arrow::Table::FromRecordBatches(std::move(batches), &table));
-
-  return table;
+  return VALUE_OR_STOP(arrow::Table::FromRecordBatches(std::move(batches)));
 }
 
 // [[arrow::export]]
diff --git a/r/src/table.cpp b/r/src/table.cpp
index 48549bf..2b9fc4f 100644
--- a/r/src/table.cpp
+++ b/r/src/table.cpp
@@ -28,9 +28,7 @@ using Rcpp::DataFrame;
 std::shared_ptr<arrow::Table> Table__from_dataframe(DataFrame tbl) {
   auto rb = RecordBatch__from_dataframe(tbl);
 
-  std::shared_ptr<arrow::Table> out;
-  STOP_IF_NOT_OK(arrow::Table::FromRecordBatches({std::move(rb)}, &out));
-  return out;
+  return VALUE_OR_STOP(arrow::Table::FromRecordBatches({std::move(rb)}));
 }
 
 // [[arrow::export]]
@@ -152,9 +150,9 @@ std::shared_ptr<arrow::Table> Table__from_dots(SEXP lst, 
SEXP schema_sxp) {
 
     if (Rf_inherits(schema_sxp, "Schema")) {
       auto schema = arrow::r::extract<arrow::Schema>(schema_sxp);
-      STOP_IF_NOT_OK(arrow::Table::FromRecordBatches(schema, batches, &tab));
+      tab = VALUE_OR_STOP(arrow::Table::FromRecordBatches(schema, 
std::move(batches)));
     } else {
-      STOP_IF_NOT_OK(arrow::Table::FromRecordBatches(batches, &tab));
+      tab = VALUE_OR_STOP(arrow::Table::FromRecordBatches(std::move(batches)));
     }
     return tab;
   }

Reply via email to