kevingurney commented on code in PR #46885:
URL: https://github.com/apache/arrow/pull/46885#discussion_r2162238825


##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,

Review Comment:
   Maybe just to clarify here, we could add a comment like:
   
   "The MATLAB client code that calls this function is responsible for 
pre-validating that this function is called with at least one RecordBatch."



##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,
+  // so this should be safe.
+  auto schema = record_batches[0]->schema();
+  // We've already validated the schemas are consistent.

Review Comment:
   ```suggestion
     // The MATLAB client code should have already validated that the schemas 
are consistent.
   ```



##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,
+  // so this should be safe.
+  auto schema = record_batches[0]->schema();
+  // We've already validated the schemas are consistent.
+  // Just create a vector of columns.
+  size_t num_columns = schema->num_fields();
+  std::vector<std::shared_ptr<ChunkedArray>> columns(num_columns);
+
+  size_t num_batches = record_batches.size();
+
+  for (size_t i = 0; i < num_columns; ++i) {
+    std::vector<std::shared_ptr<Array>> column_arrays(num_batches);
+    for (size_t j = 0; j < num_batches; ++j) {
+      column_arrays[j] = record_batches[j]->column(i);
+    }
+    columns[i] = std::make_shared<ChunkedArray>(column_arrays, 
schema->field(i)->type());
+  }
+  const auto table = arrow::Table::Make(std::move(schema), std::move(columns), 
num_rows);
+  return std::make_shared<TableProxy>(table);
+}
+}  // anonymous namespace
+
+libmexclass::proxy::MakeResult Table::make(
+    const libmexclass::proxy::FunctionArguments& constructor_arguments) {
+  mda::StructArray opts = constructor_arguments[0];
+  const mda::StringArray method = opts[0]["Method"];
+
+  if (method[0] == u"FromArrays") {
+    return from_arrays(opts);
+  } else if (method[0] == u"FromRecordBatches") {

Review Comment:
   ```suggestion
     } else if (method[0] == u"from_record_batches") {
   ```



##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,
+  // so this should be safe.
+  auto schema = record_batches[0]->schema();
+  // We've already validated the schemas are consistent.
+  // Just create a vector of columns.

Review Comment:
   ```suggestion
     // Create a vector of columns.
   ```



##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,
+  // so this should be safe.
+  auto schema = record_batches[0]->schema();
+  // We've already validated the schemas are consistent.
+  // Just create a vector of columns.
+  size_t num_columns = schema->num_fields();
+  std::vector<std::shared_ptr<ChunkedArray>> columns(num_columns);
+
+  size_t num_batches = record_batches.size();
+
+  for (size_t i = 0; i < num_columns; ++i) {
+    std::vector<std::shared_ptr<Array>> column_arrays(num_batches);
+    for (size_t j = 0; j < num_batches; ++j) {
+      column_arrays[j] = record_batches[j]->column(i);
+    }
+    columns[i] = std::make_shared<ChunkedArray>(column_arrays, 
schema->field(i)->type());
+  }
+  const auto table = arrow::Table::Make(std::move(schema), std::move(columns), 
num_rows);
+  return std::make_shared<TableProxy>(table);
+}
+}  // anonymous namespace
+
+libmexclass::proxy::MakeResult Table::make(
+    const libmexclass::proxy::FunctionArguments& constructor_arguments) {
+  mda::StructArray opts = constructor_arguments[0];
+  const mda::StringArray method = opts[0]["Method"];
+
+  if (method[0] == u"FromArrays") {
+    return from_arrays(opts);
+  } else if (method[0] == u"FromRecordBatches") {
+    return from_record_batches(opts);
+  } else {
+    const std::string error_msg = "Unknown method";
+    return 
libmexclass::error::Error{error::TABLE_NUMERIC_INDEX_WITH_EMPTY_TABLE,

Review Comment:
   I believe this error message needs to be updated.



##########
matlab/test/arrow/tabular/tTable.m:
##########
@@ -664,6 +664,55 @@ function TestIsEqualFalse(testCase)
             testCase.verifyFalse(isequal(t1, t2, t3, t4));
         end
 
+        function FromRecordBatchesZeroInputsError(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % throws an exception if called with zero input arguments.

Review Comment:
   ```suggestion
               % throws an `arrow:Table:FromRecordBatches:ZeroBatches` 
exception if called with zero input arguments.
   ```



##########
matlab/src/matlab/+arrow/+tabular/Table.m:
##########
@@ -139,7 +139,38 @@ function displayScalarObject(obj)
             validateColumnNames(opts.ColumnNames, numColumns);
 
             arrayProxyIDs = getArrayProxyIDs(arrowArrays);
-            args = struct(ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            args = struct(Method="FromArrays", ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            proxyName = "arrow.tabular.proxy.Table";
+            proxy = arrow.internal.proxy.create(proxyName, args);
+            arrowTable = arrow.tabular.Table(proxy);
+        end
+
+        function arrowTable = fromRecordBatches(batches)
+            arguments(Repeating)
+                batches(1, 1) arrow.tabular.RecordBatch
+            end
+            if numel(batches) == 0
+                msg = "Must supply at least one RecordBatch.";
+                error("arrow:Table:FromRecordBatches:ZeroBatches", msg);
+            elseif numel(batches) > 1
+                % Verify the RecordBatches have consistent Schema values.
+                firstSchema = batches{1}.Schema;
+                otherSchemas = cellfun(@(rb) rb.Schema, batches(2:end), 
UniformOutput=false);
+                idx = cellfun(@(other) ~isequal(firstSchema, other), 
otherSchemas, UniformOutput=true);
+                badIndex = find(idx, 1,"first");
+                if ~isempty(badIndex)
+                    badIndex = badIndex + 1;
+                    expectedSchema = 
arrow.tabular.internal.display.getSchemaString(firstSchema);
+                    unexpectedSchema = 
arrow.tabular.internal.display.getSchemaString(batches{badIndex}.Schema);
+                    msg = "Schema of RecordBatch %d is\n\n\t%s\n\nExpected 
RecordBatch Schema to be\n\n\t%s";
+                    msg = compose(msg, badIndex, unexpectedSchema, 
expectedSchema);
+                    error("arrow:Table:FromRecordBatches:InconsistentSchema", 
msg);
+                end
+            end
+
+            % TODO: Rename getArrayProxyIDs to getProxyIDs
+            proxyIDs = arrow.array.internal.getArrayProxyIDs(batches);
+            args = struct(Method="FromRecordBatches", 
RecordBatchProxyIDs=proxyIDs);

Review Comment:
   ```suggestion
               args = struct(Method="from_record_batches", 
RecordBatchProxyIDs=proxyIDs);
   ```



##########
matlab/test/arrow/tabular/tTable.m:
##########
@@ -664,6 +664,55 @@ function TestIsEqualFalse(testCase)
             testCase.verifyFalse(isequal(t1, t2, t3, t4));
         end
 
+        function FromRecordBatchesZeroInputsError(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % throws an exception if called with zero input arguments.
+            import arrow.tabular.Table
+            fcn = @() Table.fromRecordBatches();
+            testCase.verifyError(fcn, 
"arrow:Table:FromRecordBatches:ZeroBatches");
+        end
+
+        function FromRecordBatchesOneInput(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % returns the expected arrow.tabular.Table instance when 
+            % provided a single RecordBatch as input.
+            import arrow.tabular.Table
+            matlabTable = table([1; 2], ["A"; "B"], VariableNames=["Number" 
"Letter"]);
+            recordBatch = arrow.recordBatch(matlabTable);
+            arrowTable = Table.fromRecordBatches(recordBatch);
+            testCase.verifyTable(arrowTable, ["Number", "Letter"], 
["arrow.type.Float64Type", "arrow.type.StringType"], matlabTable);
+        end
+
+        function FromRecordBatchesMultipleInputs(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % returns the expected arrow.tabular.Table instance when 
+            % provided mulitple RecordBatches as input.
+            import arrow.tabular.Table
+            matlabTable1 = table([1; 2], ["A"; "B"], VariableNames=["Number" 
"Letter"]);
+            matlabTable2 = table([10; 20; 30], ["A1"; "B1"; "C1"], 
VariableNames=["Number" "Letter"]);
+            matlabTable3 = table([100; 200], ["A2"; "B2"], 
VariableNames=["Number" "Letter"]);
+
+            recordBatch1 = arrow.recordBatch(matlabTable1);
+            recordBatch2 = arrow.recordBatch(matlabTable2);
+            recordBatch3 = arrow.recordBatch(matlabTable3);
+
+            arrowTable = Table.fromRecordBatches(recordBatch1, recordBatch2, 
recordBatch3);
+            testCase.verifyTable(arrowTable, ["Number", "Letter"], 
["arrow.type.Float64Type", "arrow.type.StringType"], [matlabTable1; 
matlabTable2; matlabTable3]);
+        end
+
+        function FromRecordBatchesInconsistentSchemaError(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % throws an exception if the Schemas of the provided 

Review Comment:
   ```suggestion
               % throws an `arrow:Table:FromRecordBatches:InconsistentSchem` 
exception if the Schemas of the provided 
   ```



##########
matlab/src/matlab/+arrow/+tabular/Table.m:
##########
@@ -139,7 +139,38 @@ function displayScalarObject(obj)
             validateColumnNames(opts.ColumnNames, numColumns);
 
             arrayProxyIDs = getArrayProxyIDs(arrowArrays);
-            args = struct(ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            args = struct(Method="FromArrays", ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            proxyName = "arrow.tabular.proxy.Table";
+            proxy = arrow.internal.proxy.create(proxyName, args);
+            arrowTable = arrow.tabular.Table(proxy);
+        end
+
+        function arrowTable = fromRecordBatches(batches)
+            arguments(Repeating)
+                batches(1, 1) arrow.tabular.RecordBatch
+            end
+            if numel(batches) == 0
+                msg = "Must supply at least one RecordBatch.";

Review Comment:
   ```suggestion
                   msg = "The fromRecordBatches method requires at least one 
RecordBatch to be supplied.";
   ```



##########
matlab/src/matlab/+arrow/+tabular/Table.m:
##########
@@ -139,7 +139,38 @@ function displayScalarObject(obj)
             validateColumnNames(opts.ColumnNames, numColumns);
 
             arrayProxyIDs = getArrayProxyIDs(arrowArrays);
-            args = struct(ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            args = struct(Method="FromArrays", ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            proxyName = "arrow.tabular.proxy.Table";
+            proxy = arrow.internal.proxy.create(proxyName, args);
+            arrowTable = arrow.tabular.Table(proxy);
+        end
+
+        function arrowTable = fromRecordBatches(batches)
+            arguments(Repeating)
+                batches(1, 1) arrow.tabular.RecordBatch
+            end
+            if numel(batches) == 0
+                msg = "Must supply at least one RecordBatch.";
+                error("arrow:Table:FromRecordBatches:ZeroBatches", msg);
+            elseif numel(batches) > 1
+                % Verify the RecordBatches have consistent Schema values.
+                firstSchema = batches{1}.Schema;
+                otherSchemas = cellfun(@(rb) rb.Schema, batches(2:end), 
UniformOutput=false);
+                idx = cellfun(@(other) ~isequal(firstSchema, other), 
otherSchemas, UniformOutput=true);
+                badIndex = find(idx, 1,"first");

Review Comment:
   ```suggestion
                   inconsistentSchemaIndex = find(idx, 1,"first");
   ```



##########
matlab/src/matlab/+arrow/+tabular/Table.m:
##########
@@ -139,7 +139,38 @@ function displayScalarObject(obj)
             validateColumnNames(opts.ColumnNames, numColumns);
 
             arrayProxyIDs = getArrayProxyIDs(arrowArrays);
-            args = struct(ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            args = struct(Method="FromArrays", ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            proxyName = "arrow.tabular.proxy.Table";
+            proxy = arrow.internal.proxy.create(proxyName, args);
+            arrowTable = arrow.tabular.Table(proxy);
+        end
+
+        function arrowTable = fromRecordBatches(batches)
+            arguments(Repeating)
+                batches(1, 1) arrow.tabular.RecordBatch
+            end
+            if numel(batches) == 0
+                msg = "Must supply at least one RecordBatch.";
+                error("arrow:Table:FromRecordBatches:ZeroBatches", msg);
+            elseif numel(batches) > 1
+                % Verify the RecordBatches have consistent Schema values.

Review Comment:
   ```suggestion
                   % Verify that all supplied RecordBatches have a consistent 
Schema.
   ```



##########
matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc:
##########
@@ -114,9 +116,63 @@ libmexclass::proxy::MakeResult Table::make(
                          error::SCHEMA_BUILDER_FINISH_ERROR_ID);
   const auto num_rows = arrow_arrays.size() == 0 ? 0 : 
arrow_arrays[0]->length();
   const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows);
-  auto table_proxy = std::make_shared<TableProxy>(table);
+  return std::make_shared<TableProxy>(table);
+}
 
-  return table_proxy;
+libmexclass::proxy::MakeResult from_record_batches(const mda::StructArray& 
opts) {
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+  using TableProxy = arrow::matlab::tabular::proxy::Table;
+
+  size_t num_rows = 0;
+  const mda::TypedArray<uint64_t> record_batch_proxy_ids = 
opts[0]["RecordBatchProxyIDs"];
+
+  std::vector<std::shared_ptr<arrow::RecordBatch>> record_batches;
+  // Retrieve all of the Arrow RecordBatch Proxy instances from the libmexclass
+  // ProxyManager.
+  for (const auto& proxy_id : record_batch_proxy_ids) {
+    auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);
+    auto record_batch_proxy = std::static_pointer_cast<RecordBatch>(proxy);
+    auto record_batch = record_batch_proxy->unwrap();
+    record_batches.push_back(record_batch);
+    num_rows += record_batches.back()->num_rows();
+  }
+
+  // This function can only be invoked if there's at least 1 RecordBatch,
+  // so this should be safe.
+  auto schema = record_batches[0]->schema();
+  // We've already validated the schemas are consistent.
+  // Just create a vector of columns.
+  size_t num_columns = schema->num_fields();
+  std::vector<std::shared_ptr<ChunkedArray>> columns(num_columns);
+
+  size_t num_batches = record_batches.size();
+
+  for (size_t i = 0; i < num_columns; ++i) {
+    std::vector<std::shared_ptr<Array>> column_arrays(num_batches);
+    for (size_t j = 0; j < num_batches; ++j) {
+      column_arrays[j] = record_batches[j]->column(i);
+    }
+    columns[i] = std::make_shared<ChunkedArray>(column_arrays, 
schema->field(i)->type());
+  }
+  const auto table = arrow::Table::Make(std::move(schema), std::move(columns), 
num_rows);
+  return std::make_shared<TableProxy>(table);
+}
+}  // anonymous namespace
+
+libmexclass::proxy::MakeResult Table::make(
+    const libmexclass::proxy::FunctionArguments& constructor_arguments) {
+  mda::StructArray opts = constructor_arguments[0];
+  const mda::StringArray method = opts[0]["Method"];
+
+  if (method[0] == u"FromArrays") {

Review Comment:
   ```suggestion
     if (method[0] == u"from_arrays") {
   ```



##########
matlab/test/arrow/tabular/tTable.m:
##########
@@ -664,6 +664,55 @@ function TestIsEqualFalse(testCase)
             testCase.verifyFalse(isequal(t1, t2, t3, t4));
         end
 
+        function FromRecordBatchesZeroInputsError(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % throws an exception if called with zero input arguments.
+            import arrow.tabular.Table
+            fcn = @() Table.fromRecordBatches();
+            testCase.verifyError(fcn, 
"arrow:Table:FromRecordBatches:ZeroBatches");
+        end
+
+        function FromRecordBatchesOneInput(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % returns the expected arrow.tabular.Table instance when 
+            % provided a single RecordBatch as input.
+            import arrow.tabular.Table
+            matlabTable = table([1; 2], ["A"; "B"], VariableNames=["Number" 
"Letter"]);
+            recordBatch = arrow.recordBatch(matlabTable);
+            arrowTable = Table.fromRecordBatches(recordBatch);
+            testCase.verifyTable(arrowTable, ["Number", "Letter"], 
["arrow.type.Float64Type", "arrow.type.StringType"], matlabTable);
+        end
+
+        function FromRecordBatchesMultipleInputs(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % returns the expected arrow.tabular.Table instance when 
+            % provided mulitple RecordBatches as input.
+            import arrow.tabular.Table
+            matlabTable1 = table([1; 2], ["A"; "B"], VariableNames=["Number" 
"Letter"]);
+            matlabTable2 = table([10; 20; 30], ["A1"; "B1"; "C1"], 
VariableNames=["Number" "Letter"]);
+            matlabTable3 = table([100; 200], ["A2"; "B2"], 
VariableNames=["Number" "Letter"]);
+
+            recordBatch1 = arrow.recordBatch(matlabTable1);
+            recordBatch2 = arrow.recordBatch(matlabTable2);
+            recordBatch3 = arrow.recordBatch(matlabTable3);
+
+            arrowTable = Table.fromRecordBatches(recordBatch1, recordBatch2, 
recordBatch3);
+            testCase.verifyTable(arrowTable, ["Number", "Letter"], 
["arrow.type.Float64Type", "arrow.type.StringType"], [matlabTable1; 
matlabTable2; matlabTable3]);
+        end
+
+        function FromRecordBatchesInconsistentSchemaError(testCase)
+            % Verify the arrow.tabular.Table.fromRecordBatches function
+            % throws an exception if the Schemas of the provided 
+            % RecordBatches are not consistent.

Review Comment:
   ```suggestion
               % RecordBatches are inconsistent
   ```



##########
matlab/src/matlab/+arrow/+tabular/Table.m:
##########
@@ -139,7 +139,38 @@ function displayScalarObject(obj)
             validateColumnNames(opts.ColumnNames, numColumns);
 
             arrayProxyIDs = getArrayProxyIDs(arrowArrays);
-            args = struct(ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            args = struct(Method="FromArrays", ArrayProxyIDs=arrayProxyIDs, 
ColumnNames=opts.ColumnNames);
+            proxyName = "arrow.tabular.proxy.Table";
+            proxy = arrow.internal.proxy.create(proxyName, args);
+            arrowTable = arrow.tabular.Table(proxy);
+        end
+
+        function arrowTable = fromRecordBatches(batches)
+            arguments(Repeating)
+                batches(1, 1) arrow.tabular.RecordBatch
+            end
+            if numel(batches) == 0
+                msg = "Must supply at least one RecordBatch.";
+                error("arrow:Table:FromRecordBatches:ZeroBatches", msg);
+            elseif numel(batches) > 1
+                % Verify the RecordBatches have consistent Schema values.
+                firstSchema = batches{1}.Schema;
+                otherSchemas = cellfun(@(rb) rb.Schema, batches(2:end), 
UniformOutput=false);
+                idx = cellfun(@(other) ~isequal(firstSchema, other), 
otherSchemas, UniformOutput=true);
+                badIndex = find(idx, 1,"first");
+                if ~isempty(badIndex)
+                    badIndex = badIndex + 1;
+                    expectedSchema = 
arrow.tabular.internal.display.getSchemaString(firstSchema);
+                    unexpectedSchema = 
arrow.tabular.internal.display.getSchemaString(batches{badIndex}.Schema);

Review Comment:
   ```suggestion
                       inconsistentSchema = 
arrow.tabular.internal.display.getSchemaString(batches{inconsistentSchemaIndex 
}.Schema);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to