Skip to content

Commit

Permalink
OGRLayer::GetArrowStream(): when DATETIME_AS_STRING=YES, expose "GDAL…
Browse files Browse the repository at this point in the history
…:OGR:type":"DateTime" metadata in the ArrowSchema of DateTime fields
  • Loading branch information
rouault committed Nov 7, 2024
1 parent ad41bb8 commit d881e74
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion autotest/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ gdal_standard_includes(gdal_unit_test)
target_compile_options(gdal_unit_test PRIVATE ${GDAL_CXX_WARNING_FLAGS})
target_compile_definitions(gdal_unit_test PRIVATE -DGDAL_TEST_ROOT_DIR="${GDAL_ROOT_TEST_DIR}")
target_include_directories(
gdal_unit_test PRIVATE $<TARGET_PROPERTY:appslib,SOURCE_DIR> $<TARGET_PROPERTY:gdal_vrt,SOURCE_DIR>)
gdal_unit_test PRIVATE $<TARGET_PROPERTY:appslib,SOURCE_DIR> $<TARGET_PROPERTY:gdal_vrt,SOURCE_DIR> $<TARGET_PROPERTY:ogrsf_generic,SOURCE_DIR>)
if (GDAL_USE_SQLITE3)
target_compile_definitions(gdal_unit_test PRIVATE -DHAVE_SQLITE3)
target_include_directories(
Expand Down
40 changes: 40 additions & 0 deletions autotest/cpp/test_ogr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ogrsf_frmts.h"
#include "../../ogr/ogrsf_frmts/osm/gpb.h"
#include "ogr_recordbatch.h"
#include "ogrlayerarrow.h"

#include <string>
#include <algorithm>
Expand Down Expand Up @@ -4444,4 +4445,43 @@ TEST_F(test_ogr, OGRFeature_SetGeomField)
poFeatureDefn->Release();
}

TEST_F(test_ogr, GetArrowStream_DateTime_As_String)
{
auto poDS = std::unique_ptr<GDALDataset>(
GetGDALDriverManager()->GetDriverByName("Memory")->Create(
"", 0, 0, 0, GDT_Unknown, nullptr));
auto poLayer = poDS->CreateLayer("test", nullptr, wkbNone);
OGRFieldDefn oFieldDefn("dt", OFTDateTime);
poLayer->CreateField(&oFieldDefn);
struct ArrowArrayStream stream;
CPLStringList aosOptions;
aosOptions.SetNameValue("INCLUDE_FID", "NO");
aosOptions.SetNameValue("DATETIME_AS_STRING", "YES");
ASSERT_TRUE(poLayer->GetArrowStream(&stream, aosOptions.List()));
struct ArrowSchema schema;
memset(&schema, 0, sizeof(schema));
EXPECT_EQ(stream.get_schema(&stream, &schema), 0);
EXPECT_TRUE(schema.n_children == 1 &&
strcmp(schema.children[0]->format, "u") == 0)
<< schema.n_children;
if (schema.n_children == 1 && strcmp(schema.children[0]->format, "u") == 0)
{
EXPECT_TRUE(schema.children[0]->metadata != nullptr);
if (schema.children[0]->metadata)
{
auto oMapKeyValue =
OGRParseArrowMetadata(schema.children[0]->metadata);
EXPECT_EQ(oMapKeyValue.size(), 1);
if (oMapKeyValue.size() == 1)
{
EXPECT_STREQ(oMapKeyValue.begin()->first.c_str(),
"GDAL:OGR:type");
EXPECT_STREQ(oMapKeyValue.begin()->second.c_str(), "DateTime");
}
}
}
schema.release(&schema);
stream.release(&stream);
}

} // namespace
14 changes: 14 additions & 0 deletions ogr/ogrsf_frmts/generic/ogrlayerarrow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <utility>
#include <set>

constexpr const char *MD_GDAL_OGR_TYPE = "GDAL:OGR:type";
constexpr const char *MD_GDAL_OGR_ALTERNATIVE_NAME =
"GDAL:OGR:alternative_name";
constexpr const char *MD_GDAL_OGR_COMMENT = "GDAL:OGR:comment";
Expand Down Expand Up @@ -579,6 +580,13 @@ int OGRLayer::GetArrowSchema(struct ArrowArrayStream *,
}

std::vector<std::pair<std::string, std::string>> oMetadata;

if (eType == OFTDateTime && bDateTimeAsString)
{
oMetadata.emplace_back(
std::pair(MD_GDAL_OGR_TYPE, OGR_GetFieldTypeName(eType)));
}

const char *pszAlternativeName = poFieldDefn->GetAlternativeNameRef();
if (pszAlternativeName && pszAlternativeName[0])
oMetadata.emplace_back(
Expand Down Expand Up @@ -2472,6 +2480,9 @@ const char *OGRLayer::GetLastErrorArrowArrayStream(struct ArrowArrayStream *)
* Starting with GDAL 3.8, the ArrowSchema::metadata field filled by the
* get_schema() callback may be set with the potential following items:
* <ul>
* <li>"GDAL:OGR:type": value of OGRFieldDefn::GetType(): (added in 3.11)
* Only used for DateTime fields when the DATETIME_AS_STRING=YES option is
* specified.</li>
* <li>"GDAL:OGR:alternative_name": value of
* OGRFieldDefn::GetAlternativeNameRef()</li>
* <li>"GDAL:OGR:comment": value of OGRFieldDefn::GetComment()</li>
Expand Down Expand Up @@ -2674,6 +2685,9 @@ bool OGRLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
* Starting with GDAL 3.8, the ArrowSchema::metadata field filled by the
* get_schema() callback may be set with the potential following items:
* <ul>
* <li>"GDAL:OGR:type": value of OGRFieldDefn::GetType(): (added in 3.11)
* Only used for DateTime fields when the DATETIME_AS_STRING=YES option is
* specified.</li>
* <li>"GDAL:OGR:alternative_name": value of
* OGRFieldDefn::GetAlternativeNameRef()</li>
* <li>"GDAL:OGR:comment": value of OGRFieldDefn::GetComment()</li>
Expand Down

0 comments on commit d881e74

Please sign in to comment.