Skip to content

Commit 92de9a3

Browse files
zeroshadekou
andauthored
GH-37635: [Format][C++][Go] Add app_metadata to FlightInfo and FlightEndpoint (#37679)
### Rationale for this change As suggested here: #37635 (comment) this just adds an `app_metadata` field to FlightInfo and FlightEndpoint ### What changes are included in this PR? Just the updated proto file and the generated Go code from the proto ### Are there any user-facing changes? Yes. **This PR includes breaking changes to public APIs.** * Closes: #37635 Lead-authored-by: Matt Topol <zotthewizard@gmail.com> Co-authored-by: Sutou Kouhei <kou@clear-code.com> Signed-off-by: Matt Topol <zotthewizard@gmail.com>
1 parent f6afc33 commit 92de9a3

18 files changed

Lines changed: 803 additions & 450 deletions

File tree

cpp/src/arrow/flight/flight_internals_test.cc

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -191,33 +191,33 @@ TEST(FlightTypes, FlightEndpoint) {
191191
Timestamp expiration_time(
192192
std::chrono::duration_cast<Timestamp::duration>(expiration_time_duration));
193193
std::vector<FlightEndpoint> values = {
194-
{{""}, {}, std::nullopt},
195-
{{"foo"}, {}, std::nullopt},
196-
{{"bar"}, {}, std::nullopt},
197-
{{"foo"}, {}, expiration_time},
198-
{{"foo"}, {location1}, std::nullopt},
199-
{{"bar"}, {location1}, std::nullopt},
200-
{{"foo"}, {location2}, std::nullopt},
201-
{{"foo"}, {location1, location2}, std::nullopt},
194+
{{""}, {}, std::nullopt, {}},
195+
{{"foo"}, {}, std::nullopt, {}},
196+
{{"bar"}, {}, std::nullopt, {"\xDE\xAD\xBE\xEF"}},
197+
{{"foo"}, {}, expiration_time, {}},
198+
{{"foo"}, {location1}, std::nullopt, {}},
199+
{{"bar"}, {location1}, std::nullopt, {}},
200+
{{"foo"}, {location2}, std::nullopt, {}},
201+
{{"foo"}, {location1, location2}, std::nullopt, {"\xba\xdd\xca\xfe"}},
202202
};
203203
std::vector<std::string> reprs = {
204204
"<FlightEndpoint ticket=<Ticket ticket=''> locations=[] "
205-
"expiration_time=null>",
205+
"expiration_time=null app_metadata=''>",
206206
"<FlightEndpoint ticket=<Ticket ticket='foo'> locations=[] "
207-
"expiration_time=null>",
207+
"expiration_time=null app_metadata=''>",
208208
"<FlightEndpoint ticket=<Ticket ticket='bar'> locations=[] "
209-
"expiration_time=null>",
209+
"expiration_time=null app_metadata='DEADBEEF'>",
210210
"<FlightEndpoint ticket=<Ticket ticket='foo'> locations=[] "
211-
"expiration_time=2023-06-19 03:14:06.004339000>",
211+
"expiration_time=2023-06-19 03:14:06.004339000 app_metadata=''>",
212212
"<FlightEndpoint ticket=<Ticket ticket='foo'> locations="
213-
"[grpc+tcp://localhost:1024] expiration_time=null>",
213+
"[grpc+tcp://localhost:1024] expiration_time=null app_metadata=''>",
214214
"<FlightEndpoint ticket=<Ticket ticket='bar'> locations="
215-
"[grpc+tcp://localhost:1024] expiration_time=null>",
215+
"[grpc+tcp://localhost:1024] expiration_time=null app_metadata=''>",
216216
"<FlightEndpoint ticket=<Ticket ticket='foo'> locations="
217-
"[grpc+tls://localhost:1024] expiration_time=null>",
217+
"[grpc+tls://localhost:1024] expiration_time=null app_metadata=''>",
218218
"<FlightEndpoint ticket=<Ticket ticket='foo'> locations="
219219
"[grpc+tcp://localhost:1024, grpc+tls://localhost:1024] "
220-
"expiration_time=null>",
220+
"expiration_time=null app_metadata='BADDCAFE'>",
221221
};
222222

223223
ASSERT_NO_FATAL_FAILURE(TestRoundtrip<pb::FlightEndpoint>(values, reprs));
@@ -229,30 +229,35 @@ TEST(FlightTypes, FlightInfo) {
229229
Schema schema2({});
230230
auto desc1 = FlightDescriptor::Command("foo");
231231
auto desc2 = FlightDescriptor::Command("bar");
232-
auto endpoint1 = FlightEndpoint{Ticket{"foo"}, {}, std::nullopt};
233-
auto endpoint2 = FlightEndpoint{Ticket{"foo"}, {location}, std::nullopt};
232+
auto endpoint1 = FlightEndpoint{Ticket{"foo"}, {}, std::nullopt, ""};
233+
auto endpoint2 =
234+
FlightEndpoint{Ticket{"foo"}, {location}, std::nullopt, "\xCA\xFE\xD0\x0D"};
234235
std::vector<FlightInfo> values = {
235-
MakeFlightInfo(schema1, desc1, {}, -1, -1, false),
236-
MakeFlightInfo(schema1, desc2, {}, -1, -1, true),
237-
MakeFlightInfo(schema2, desc1, {}, -1, -1, false),
238-
MakeFlightInfo(schema1, desc1, {endpoint1}, -1, 42, true),
239-
MakeFlightInfo(schema1, desc2, {endpoint1, endpoint2}, 64, -1, false),
236+
MakeFlightInfo(schema1, desc1, {}, -1, -1, false, ""),
237+
MakeFlightInfo(schema1, desc2, {}, -1, -1, true, ""),
238+
MakeFlightInfo(schema2, desc1, {}, -1, -1, false, ""),
239+
MakeFlightInfo(schema1, desc1, {endpoint1}, -1, 42, true, ""),
240+
MakeFlightInfo(schema1, desc2, {endpoint1, endpoint2}, 64, -1, false,
241+
"\xDE\xAD\xC0\xDE"),
240242
};
241243
std::vector<std::string> reprs = {
242244
"<FlightInfo schema=(serialized) descriptor=<FlightDescriptor cmd='foo'> "
243-
"endpoints=[] total_records=-1 total_bytes=-1 ordered=false>",
245+
"endpoints=[] total_records=-1 total_bytes=-1 ordered=false app_metadata=''>",
244246
"<FlightInfo schema=(serialized) descriptor=<FlightDescriptor cmd='bar'> "
245-
"endpoints=[] total_records=-1 total_bytes=-1 ordered=true>",
247+
"endpoints=[] total_records=-1 total_bytes=-1 ordered=true app_metadata=''>",
246248
"<FlightInfo schema=(serialized) descriptor=<FlightDescriptor cmd='foo'> "
247-
"endpoints=[] total_records=-1 total_bytes=-1 ordered=false>",
249+
"endpoints=[] total_records=-1 total_bytes=-1 ordered=false app_metadata=''>",
248250
"<FlightInfo schema=(serialized) descriptor=<FlightDescriptor cmd='foo'> "
249251
"endpoints=[<FlightEndpoint ticket=<Ticket ticket='foo'> locations=[] "
250-
"expiration_time=null>] total_records=-1 total_bytes=42 ordered=true>",
252+
"expiration_time=null app_metadata=''>] total_records=-1 total_bytes=42 "
253+
"ordered=true app_metadata=''>",
251254
"<FlightInfo schema=(serialized) descriptor=<FlightDescriptor cmd='bar'> "
252255
"endpoints=[<FlightEndpoint ticket=<Ticket ticket='foo'> locations=[] "
253-
"expiration_time=null>, <FlightEndpoint ticket=<Ticket ticket='foo'> "
254-
"locations=[grpc+tcp://localhost:1234] expiration_time=null>] "
255-
"total_records=64 total_bytes=-1 ordered=false>",
256+
"expiration_time=null app_metadata=''>, <FlightEndpoint ticket=<Ticket "
257+
"ticket='foo'> "
258+
"locations=[grpc+tcp://localhost:1234] expiration_time=null "
259+
"app_metadata='CAFED00D'>] "
260+
"total_records=64 total_bytes=-1 ordered=false app_metadata='DEADC0DE'>",
256261
};
257262

258263
ASSERT_NO_FATAL_FAILURE(TestRoundtrip<pb::FlightInfo>(values, reprs));
@@ -262,8 +267,8 @@ TEST(FlightTypes, PollInfo) {
262267
ASSERT_OK_AND_ASSIGN(auto location, Location::ForGrpcTcp("localhost", 1234));
263268
Schema schema({field("ints", int64())});
264269
auto desc = FlightDescriptor::Command("foo");
265-
auto endpoint = FlightEndpoint{Ticket{"foo"}, {}, std::nullopt};
266-
auto info = MakeFlightInfo(schema, desc, {endpoint}, -1, 42, true);
270+
auto endpoint = FlightEndpoint{Ticket{"foo"}, {}, std::nullopt, ""};
271+
auto info = MakeFlightInfo(schema, desc, {endpoint}, -1, 42, true, "");
267272
// 2023-06-19 03:14:06.004330100
268273
// We must use microsecond resolution here for portability.
269274
// std::chrono::system_clock::time_point may not provide nanosecond

cpp/src/arrow/flight/integration_tests/flight_integration_test.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ TEST(FlightIntegration, ExpirationTimeRenewFlightEndpoint) {
7373

7474
TEST(FlightIntegration, PollFlightInfo) { ASSERT_OK(RunScenario("poll_flight_info")); }
7575

76+
TEST(FlightIntegration, AppMetadataFlightInfoEndpoint) {
77+
ASSERT_OK(RunScenario("app_metadata_flight_info_endpoint"));
78+
}
79+
7680
TEST(FlightIntegration, FlightSql) { ASSERT_OK(RunScenario("flight_sql")); }
7781

7882
TEST(FlightIntegration, FlightSqlExtension) {

cpp/src/arrow/flight/integration_tests/test_integration.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,64 @@ class PollFlightInfoScenario : public Scenario {
815815
}
816816
};
817817

818+
/// \brief The server used for testing app_metadata in FlightInfo and FlightEndpoint
819+
class AppMetadataFlightInfoEndpointServer : public FlightServerBase {
820+
public:
821+
AppMetadataFlightInfoEndpointServer() : FlightServerBase() {}
822+
823+
Status GetFlightInfo(const ServerCallContext& context, const FlightDescriptor& request,
824+
std::unique_ptr<FlightInfo>* info) override {
825+
if (request.type != FlightDescriptor::CMD) {
826+
return Status::Invalid("request descriptor should be of type CMD");
827+
}
828+
829+
auto schema = arrow::schema({arrow::field("number", arrow::uint32(), false)});
830+
std::vector<FlightEndpoint> endpoints = {
831+
FlightEndpoint{{}, {}, std::nullopt, request.cmd}};
832+
ARROW_ASSIGN_OR_RAISE(auto result, FlightInfo::Make(*schema, request, endpoints, -1,
833+
-1, false, request.cmd));
834+
*info = std::make_unique<FlightInfo>(std::move(result));
835+
return Status::OK();
836+
}
837+
};
838+
839+
/// \brief The AppMetadataFlightInfoEndpoint scenario.
840+
///
841+
/// This tests that the client can receive and use the `app_metadata` field in
842+
/// the FlightInfo and FlightEndpoint messages.
843+
///
844+
/// The server only implements GetFlightInfo and will return a FlightInfo with a non-
845+
/// empty app_metadata value that should match the app_metadata field in the
846+
/// included FlightEndpoint. The value should be the same as the cmd bytes passed
847+
/// in the call to GetFlightInfo by the client.
848+
class AppMetadataFlightInfoEndpointScenario : public Scenario {
849+
Status MakeServer(std::unique_ptr<FlightServerBase>* server,
850+
FlightServerOptions* options) override {
851+
*server = std::make_unique<AppMetadataFlightInfoEndpointServer>();
852+
return Status::OK();
853+
}
854+
855+
Status MakeClient(FlightClientOptions* options) override { return Status::OK(); }
856+
857+
Status RunClient(std::unique_ptr<FlightClient> client) override {
858+
ARROW_ASSIGN_OR_RAISE(auto info,
859+
client->GetFlightInfo(FlightDescriptor::Command("foobar")));
860+
if (info->app_metadata() != "foobar") {
861+
return Status::Invalid("app_metadata should have been 'foobar', got: ",
862+
info->app_metadata());
863+
}
864+
if (info->endpoints().size() != 1) {
865+
return Status::Invalid("should have gotten exactly one FlightEndpoint back, got: ",
866+
info->endpoints().size());
867+
}
868+
if (info->endpoints()[0].app_metadata != "foobar") {
869+
return Status::Invalid("FlightEndpoint app_metadata should be 'foobar', got: ",
870+
info->endpoints()[0].app_metadata);
871+
}
872+
return Status::OK();
873+
}
874+
};
875+
818876
/// \brief Schema to be returned for mocking the statement/prepared statement results.
819877
///
820878
/// Must be the same across all languages.
@@ -1897,6 +1955,9 @@ Status GetScenario(const std::string& scenario_name, std::shared_ptr<Scenario>*
18971955
} else if (scenario_name == "poll_flight_info") {
18981956
*out = std::make_shared<PollFlightInfoScenario>();
18991957
return Status::OK();
1958+
} else if (scenario_name == "app_metadata_flight_info_endpoint") {
1959+
*out = std::make_shared<AppMetadataFlightInfoEndpointScenario>();
1960+
return Status::OK();
19001961
} else if (scenario_name == "flight_sql") {
19011962
*out = std::make_shared<FlightSqlScenario>();
19021963
return Status::OK();

cpp/src/arrow/flight/perf_server.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class FlightPerfServer : public FlightServerBase {
196196
perf_request.stream_count() * perf_request.records_per_stream();
197197

198198
*info = std::make_unique<FlightInfo>(
199-
MakeFlightInfo(*perf_schema_, request, endpoints, total_records, -1, false));
199+
MakeFlightInfo(*perf_schema_, request, endpoints, total_records, -1, false, ""));
200200
return Status::OK();
201201
}
202202

cpp/src/arrow/flight/serialization_internal.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ Status FromProto(const pb::FlightEndpoint& pb_endpoint, FlightEndpoint* endpoint
177177
RETURN_NOT_OK(FromProto(pb_endpoint.expiration_time(), &expiration_time));
178178
endpoint->expiration_time = std::move(expiration_time);
179179
}
180+
endpoint->app_metadata = pb_endpoint.app_metadata();
180181
return Status::OK();
181182
}
182183

@@ -190,6 +191,7 @@ Status ToProto(const FlightEndpoint& endpoint, pb::FlightEndpoint* pb_endpoint)
190191
RETURN_NOT_OK(ToProto(endpoint.expiration_time.value(),
191192
pb_endpoint->mutable_expiration_time()));
192193
}
194+
pb_endpoint->set_app_metadata(endpoint.app_metadata);
193195
return Status::OK();
194196
}
195197

@@ -255,6 +257,7 @@ arrow::Result<FlightInfo> FromProto(const pb::FlightInfo& pb_info) {
255257
info.total_records = pb_info.total_records();
256258
info.total_bytes = pb_info.total_bytes();
257259
info.ordered = pb_info.ordered();
260+
info.app_metadata = pb_info.app_metadata();
258261
return FlightInfo(std::move(info));
259262
}
260263

@@ -296,6 +299,7 @@ Status ToProto(const FlightInfo& info, pb::FlightInfo* pb_info) {
296299
pb_info->set_total_records(info.total_records());
297300
pb_info->set_total_bytes(info.total_bytes());
298301
pb_info->set_ordered(info.ordered());
302+
pb_info->set_app_metadata(info.app_metadata());
299303
return Status::OK();
300304
}
301305

cpp/src/arrow/flight/sql/server.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ arrow::Result<std::unique_ptr<FlightInfo>> FlightSqlServerBase::GetFlightInfoSql
930930
}
931931

932932
std::vector<FlightEndpoint> endpoints{
933-
FlightEndpoint{{descriptor.cmd}, {}, std::nullopt}};
933+
FlightEndpoint{{descriptor.cmd}, {}, std::nullopt, {}}};
934934
ARROW_ASSIGN_OR_RAISE(
935935
auto result, FlightInfo::Make(*SqlSchema::GetSqlInfoSchema(), descriptor, endpoints,
936936
-1, -1, false))

cpp/src/arrow/flight/test_util.cc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,11 @@ std::unique_ptr<FlightServerBase> ExampleTestServer() {
531531

532532
FlightInfo MakeFlightInfo(const Schema& schema, const FlightDescriptor& descriptor,
533533
const std::vector<FlightEndpoint>& endpoints,
534-
int64_t total_records, int64_t total_bytes, bool ordered) {
535-
EXPECT_OK_AND_ASSIGN(auto info, FlightInfo::Make(schema, descriptor, endpoints,
536-
total_records, total_bytes, ordered));
534+
int64_t total_records, int64_t total_bytes, bool ordered,
535+
std::string app_metadata) {
536+
EXPECT_OK_AND_ASSIGN(auto info,
537+
FlightInfo::Make(schema, descriptor, endpoints, total_records,
538+
total_bytes, ordered, std::move(app_metadata)));
537539
return info;
538540
}
539541

@@ -602,11 +604,11 @@ std::vector<FlightInfo> ExampleFlightInfo() {
602604
Location location4 = *Location::ForGrpcTcp("foo4.bar.com", 12345);
603605
Location location5 = *Location::ForGrpcTcp("foo5.bar.com", 12345);
604606

605-
FlightEndpoint endpoint1({{"ticket-ints-1"}, {location1}, std::nullopt});
606-
FlightEndpoint endpoint2({{"ticket-ints-2"}, {location2}, std::nullopt});
607-
FlightEndpoint endpoint3({{"ticket-cmd"}, {location3}, std::nullopt});
608-
FlightEndpoint endpoint4({{"ticket-dicts-1"}, {location4}, std::nullopt});
609-
FlightEndpoint endpoint5({{"ticket-floats-1"}, {location5}, std::nullopt});
607+
FlightEndpoint endpoint1({{"ticket-ints-1"}, {location1}, std::nullopt, {}});
608+
FlightEndpoint endpoint2({{"ticket-ints-2"}, {location2}, std::nullopt, {}});
609+
FlightEndpoint endpoint3({{"ticket-cmd"}, {location3}, std::nullopt, {}});
610+
FlightEndpoint endpoint4({{"ticket-dicts-1"}, {location4}, std::nullopt, {}});
611+
FlightEndpoint endpoint5({{"ticket-floats-1"}, {location5}, std::nullopt, {}});
610612

611613
FlightDescriptor descr1{FlightDescriptor::PATH, "", {"examples", "ints"}};
612614
FlightDescriptor descr2{FlightDescriptor::CMD, "my_command", {}};
@@ -619,10 +621,10 @@ std::vector<FlightInfo> ExampleFlightInfo() {
619621
auto schema4 = ExampleFloatSchema();
620622

621623
return {
622-
MakeFlightInfo(*schema1, descr1, {endpoint1, endpoint2}, 1000, 100000, false),
623-
MakeFlightInfo(*schema2, descr2, {endpoint3}, 1000, 100000, false),
624-
MakeFlightInfo(*schema3, descr3, {endpoint4}, -1, -1, false),
625-
MakeFlightInfo(*schema4, descr4, {endpoint5}, 1000, 100000, false),
624+
MakeFlightInfo(*schema1, descr1, {endpoint1, endpoint2}, 1000, 100000, false, ""),
625+
MakeFlightInfo(*schema2, descr2, {endpoint3}, 1000, 100000, false, ""),
626+
MakeFlightInfo(*schema3, descr3, {endpoint4}, -1, -1, false, ""),
627+
MakeFlightInfo(*schema4, descr4, {endpoint5}, 1000, 100000, false, ""),
626628
};
627629
}
628630

cpp/src/arrow/flight/test_util.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ std::vector<ActionType> ExampleActionTypes();
192192
ARROW_FLIGHT_EXPORT
193193
FlightInfo MakeFlightInfo(const Schema& schema, const FlightDescriptor& descriptor,
194194
const std::vector<FlightEndpoint>& endpoints,
195-
int64_t total_records, int64_t total_bytes, bool ordered);
195+
int64_t total_records, int64_t total_bytes, bool ordered,
196+
std::string app_metadata);
196197

197198
// ----------------------------------------------------------------------
198199
// A pair of authentication handlers that check for a predefined password

cpp/src/arrow/flight/types.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,13 +260,14 @@ arrow::Result<FlightInfo> FlightInfo::Make(const Schema& schema,
260260
const FlightDescriptor& descriptor,
261261
const std::vector<FlightEndpoint>& endpoints,
262262
int64_t total_records, int64_t total_bytes,
263-
bool ordered) {
263+
bool ordered, std::string app_metadata) {
264264
FlightInfo::Data data;
265265
data.descriptor = descriptor;
266266
data.endpoints = endpoints;
267267
data.total_records = total_records;
268268
data.total_bytes = total_bytes;
269269
data.ordered = ordered;
270+
data.app_metadata = std::move(app_metadata);
270271
RETURN_NOT_OK(internal::SchemaToString(schema, &data.schema));
271272
return FlightInfo(data);
272273
}
@@ -328,6 +329,7 @@ std::string FlightInfo::ToString() const {
328329
ss << "] total_records=" << data_.total_records;
329330
ss << " total_bytes=" << data_.total_bytes;
330331
ss << " ordered=" << (data_.ordered ? "true" : "false");
332+
ss << " app_metadata='" << HexEncode(data_.app_metadata) << "'";
331333
ss << '>';
332334
return ss.str();
333335
}
@@ -338,7 +340,8 @@ bool FlightInfo::Equals(const FlightInfo& other) const {
338340
data_.endpoints == other.data_.endpoints &&
339341
data_.total_records == other.data_.total_records &&
340342
data_.total_bytes == other.data_.total_bytes &&
341-
data_.ordered == other.data_.ordered;
343+
data_.ordered == other.data_.ordered &&
344+
data_.app_metadata == other.data_.app_metadata;
342345
}
343346

344347
arrow::Result<std::string> PollInfo::SerializeToString() const {
@@ -535,6 +538,7 @@ std::string FlightEndpoint::ToString() const {
535538
} else {
536539
ss << "null";
537540
}
541+
ss << " app_metadata='" << HexEncode(app_metadata) << "'";
538542
ss << ">";
539543
return ss.str();
540544
}
@@ -554,6 +558,9 @@ bool FlightEndpoint::Equals(const FlightEndpoint& other) const {
554558
return false;
555559
}
556560
}
561+
if (app_metadata != other.app_metadata) {
562+
return false;
563+
}
557564
return true;
558565
}
559566

cpp/src/arrow/flight/types.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ struct ARROW_FLIGHT_EXPORT FlightEndpoint {
481481
/// retrying DoGet requests.
482482
std::optional<Timestamp> expiration_time;
483483

484+
/// Opaque Application-defined metadata
485+
std::string app_metadata;
486+
484487
std::string ToString() const;
485488
bool Equals(const FlightEndpoint& other) const;
486489

@@ -583,6 +586,7 @@ class ARROW_FLIGHT_EXPORT FlightInfo {
583586
int64_t total_records = -1;
584587
int64_t total_bytes = -1;
585588
bool ordered = false;
589+
std::string app_metadata;
586590
};
587591

588592
explicit FlightInfo(Data data) : data_(std::move(data)), reconstructed_schema_(false) {}
@@ -592,7 +596,8 @@ class ARROW_FLIGHT_EXPORT FlightInfo {
592596
const FlightDescriptor& descriptor,
593597
const std::vector<FlightEndpoint>& endpoints,
594598
int64_t total_records, int64_t total_bytes,
595-
bool ordered = false);
599+
bool ordered = false,
600+
std::string app_metadata = "");
596601

597602
/// \brief Deserialize the Arrow schema of the dataset. Populate any
598603
/// dictionary encoded fields into a DictionaryMemo for
@@ -621,6 +626,9 @@ class ARROW_FLIGHT_EXPORT FlightInfo {
621626
/// Whether endpoints are in the same order as the data.
622627
bool ordered() const { return data_.ordered; }
623628

629+
/// Application-defined opaque metadata
630+
const std::string& app_metadata() const { return data_.app_metadata; }
631+
624632
/// \brief Get the wire-format representation of this type.
625633
///
626634
/// Useful when interoperating with non-Flight systems (e.g. REST

0 commit comments

Comments
 (0)