diff --git a/r/tests/testthat/test-schema.R b/r/tests/testthat/test-schema.R index 6dd86d817..364a36eb7 100644 --- a/r/tests/testthat/test-schema.R +++ b/r/tests/testthat/test-schema.R @@ -280,9 +280,10 @@ test_that("schema modify can modify name", { test_that("schema modify can modify flags", { schema <- na_int32() + expect_identical(schema$flags, 2L) - schema2 <- nanoarrow_schema_modify(schema, list(flags = 1)) - expect_identical(schema2$flags, 1L) + schema2 <- nanoarrow_schema_modify(schema, list(flags = 0)) + expect_identical(schema2$flags, 0L) expect_identical(schema2$format, schema$format) expect_identical(schema2$name, schema$name) diff --git a/src/nanoarrow/nanoarrow_testing_test.cc b/src/nanoarrow/nanoarrow_testing_test.cc index f0e9ff3c5..ce1e873e3 100644 --- a/src/nanoarrow/nanoarrow_testing_test.cc +++ b/src/nanoarrow/nanoarrow_testing_test.cc @@ -1370,9 +1370,9 @@ TEST(NanoarrowTestingTest, NanoarrowTestingTestSchemaComparison) { AssertSchemasCompareEqual(actual.get(), expected.get()); // With different top-level flags - actual->flags = ARROW_FLAG_MAP_KEYS_SORTED; + actual->flags = 0; AssertSchemasCompareUnequal(actual.get(), expected.get(), /*num_differences*/ 1, - "Path: \n- .flags: 4\n+ .flags: 2\n\n"); + "Path: \n- .flags: 0\n+ .flags: 2\n\n"); actual->flags = expected->flags; // With different top-level metadata diff --git a/src/nanoarrow/nanoarrow_types.h b/src/nanoarrow/nanoarrow_types.h index 41ddd1dce..fcad91dd7 100644 --- a/src/nanoarrow/nanoarrow_types.h +++ b/src/nanoarrow/nanoarrow_types.h @@ -209,6 +209,11 @@ typedef int ArrowErrorCode; #define ArrowErrorCode NANOARROW_CHECK_RETURN_ATTRIBUTE ArrowErrorCode #endif +/// \brief Flags supported by ArrowSchemaViewInit() +/// \ingroup nanoarrow-schema-view +#define NANOARROW_FLAG_ALL_SUPPORTED \ + (ARROW_FLAG_DICTIONARY_ORDERED | ARROW_FLAG_NULLABLE | ARROW_FLAG_MAP_KEYS_SORTED) + /// \brief Error type containing a UTF-8 encoded message. /// \ingroup nanoarrow-errors struct ArrowError { diff --git a/src/nanoarrow/schema.c b/src/nanoarrow/schema.c index dd5edb420..215645074 100644 --- a/src/nanoarrow/schema.c +++ b/src/nanoarrow/schema.c @@ -1178,16 +1178,31 @@ ArrowErrorCode ArrowSchemaViewInit(struct ArrowSchemaView* schema_view, schema_view->type = NANOARROW_TYPE_DICTIONARY; } - result = ArrowSchemaViewValidate(schema_view, schema_view->storage_type, error); - if (result != NANOARROW_OK) { - return result; - } + NANOARROW_RETURN_NOT_OK( + ArrowSchemaViewValidate(schema_view, schema_view->storage_type, error)); if (schema_view->storage_type != schema_view->type) { - result = ArrowSchemaViewValidate(schema_view, schema_view->type, error); - if (result != NANOARROW_OK) { - return result; - } + NANOARROW_RETURN_NOT_OK( + ArrowSchemaViewValidate(schema_view, schema_view->type, error)); + } + + int64_t unknown_flags = schema->flags & ~NANOARROW_FLAG_ALL_SUPPORTED; + if (unknown_flags != 0) { + ArrowErrorSet(error, "Unknown ArrowSchema flag"); + return EINVAL; + } + + if (schema->flags & ARROW_FLAG_DICTIONARY_ORDERED && + schema_view->type != NANOARROW_TYPE_DICTIONARY) { + ArrowErrorSet(error, + "ARROW_FLAG_DICTIONARY_ORDERED is only relevant for dictionaries"); + return EINVAL; + } + + if (schema->flags & ARROW_FLAG_MAP_KEYS_SORTED && + schema_view->type != NANOARROW_TYPE_MAP) { + ArrowErrorSet(error, "ARROW_FLAG_MAP_KEYS_SORTED is only relevant for a map type"); + return EINVAL; } ArrowLayoutInit(&schema_view->layout, schema_view->storage_type); diff --git a/src/nanoarrow/schema_test.cc b/src/nanoarrow/schema_test.cc index d8bfd3c4b..acafb3a2c 100644 --- a/src/nanoarrow/schema_test.cc +++ b/src/nanoarrow/schema_test.cc @@ -574,6 +574,24 @@ TEST(SchemaViewTest, SchemaViewInitErrors) { EXPECT_STREQ(ArrowErrorMessage(&error), "Error parsing schema->format 'n*': parsed 1/2 characters"); + ASSERT_EQ(ArrowSchemaSetFormat(&schema, "n"), NANOARROW_OK); + schema.flags = 0; + schema.flags |= ARROW_FLAG_DICTIONARY_ORDERED; + EXPECT_EQ(ArrowSchemaViewInit(&schema_view, &schema, &error), EINVAL); + EXPECT_STREQ(ArrowErrorMessage(&error), + "ARROW_FLAG_DICTIONARY_ORDERED is only relevant for dictionaries"); + + schema.flags = 0; + schema.flags |= ARROW_FLAG_MAP_KEYS_SORTED; + EXPECT_EQ(ArrowSchemaViewInit(&schema_view, &schema, &error), EINVAL); + EXPECT_STREQ(ArrowErrorMessage(&error), + "ARROW_FLAG_MAP_KEYS_SORTED is only relevant for a map type"); + + schema.flags = 0; + schema.flags |= ~NANOARROW_FLAG_ALL_SUPPORTED; + EXPECT_EQ(ArrowSchemaViewInit(&schema_view, &schema, &error), EINVAL); + EXPECT_STREQ(ArrowErrorMessage(&error), "Unknown ArrowSchema flag"); + ArrowSchemaRelease(&schema); }