From 4b12aa52f8aaf5b873bda0e2b615ce9dce05fc77 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Wed, 10 Jun 2026 16:31:10 -0600 Subject: [PATCH] Fix NcML DataType conversion in old NetcdfDataset API When using NcML to redefine coordinate variable type, the old NetcdfDataset API was falling back to the original variable datatype. This behavior seems to be OK in the old API datapath as long as the old and new data types are consistently numeric (or not), as enhancements will "do the rigth thing", but otherwise not (e.g. int to String conversion using NcML). Fixes Unidata/netcdf-java#1540. --- .../java/ucar/nc2/dataset/VariableDS.java | 9 +++- .../test/data/ncml/coords/nc/string_coord.nc | Bin 0 -> 6152 bytes .../test/data/ncml/coords/string_coord.ncml | 8 ++++ .../dataset/TestCoordinateAxisDataType.java | 45 ++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 cdm/core/src/test/data/ncml/coords/nc/string_coord.nc create mode 100644 cdm/core/src/test/data/ncml/coords/string_coord.ncml create mode 100644 cdm/core/src/test/java/ucar/nc2/dataset/TestCoordinateAxisDataType.java diff --git a/cdm/core/src/main/java/ucar/nc2/dataset/VariableDS.java b/cdm/core/src/main/java/ucar/nc2/dataset/VariableDS.java index a57ece8994..dc82c774f5 100644 --- a/cdm/core/src/main/java/ucar/nc2/dataset/VariableDS.java +++ b/cdm/core/src/main/java/ucar/nc2/dataset/VariableDS.java @@ -1,7 +1,8 @@ /* - * Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata + * Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata * See LICENSE for license information. */ + package ucar.nc2.dataset; import com.google.common.collect.ImmutableList; @@ -239,7 +240,11 @@ public void enhance(Set enhancements) { // So, we need to reset to default before we process this new set. // LOOK this seems bogus if (orgDataType != null) { - setDataType(orgDataType); + // only reset if original DataType and current DataType are compatible (both + // are numeric or both are not numeric). + if (orgDataType.isNumeric() == dataType.isNumeric()) { + setDataType(orgDataType); + } } createEnhancements(); diff --git a/cdm/core/src/test/data/ncml/coords/nc/string_coord.nc b/cdm/core/src/test/data/ncml/coords/nc/string_coord.nc new file mode 100644 index 0000000000000000000000000000000000000000..56d8e8d2991a556f681874857e0c39eaf0b97a2b GIT binary patch literal 6152 zcmeH~Pm9w~5WpwNb_pT7ty-=Bz_>?uDQ#WFOTm(+w%Df9^rVN9HCZ;$rb`nSJt=|* z#e?`gy!i?AJBZMeCy$C}L1*5}Yu9Dhv%(viynpj%=KW^+N?*2{tu^DKq3Sva`IU)& zp3hXWh40VXYQNnasOEchgUxAbwj{P3Z4DI^QdvDmZ)JtvBw7$nzVYs2jVaRFfj_&R z89sX%Xpg4AQOjanD3F;_X4#_w$vSTizhAe%&RO_tw-lvFE2^R>;sm1AiWKpwt5=v~ z01HYwl%Aq?j-5p_xW^Y7xBZqkAR=8kF;a7rR5e%yoow6PhUdWkQTqeCX5rGZ)H zY>S-jXt}@fI7)_3_Cto6;-b_zaS~1tpV{Te@|ZOAzRXy+;|<{gYEm*w_^_SFIA=j* z$EE(O`S?=bZr>F|L|qFa=9p?mgFIBo + + + + 0 1 + + \ No newline at end of file diff --git a/cdm/core/src/test/java/ucar/nc2/dataset/TestCoordinateAxisDataType.java b/cdm/core/src/test/java/ucar/nc2/dataset/TestCoordinateAxisDataType.java new file mode 100644 index 0000000000..d78a07f630 --- /dev/null +++ b/cdm/core/src/test/java/ucar/nc2/dataset/TestCoordinateAxisDataType.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 University Corporation for Atmospheric Research/Unidata + * See LICENSE for license information. + */ + +package ucar.nc2.dataset; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.IOException; + +import org.junit.Test; +import ucar.ma2.DataType; +import ucar.nc2.Variable; +import ucar.unidata.util.test.TestDir; + +public class TestCoordinateAxisDataType { + + String testFile = TestDir.cdmLocalTestDataDir + "/ncml/coords/string_coord.ncml"; + + @Test + public void testDataTypeChangeOldApi() throws IOException { + try (NetcdfDataset ncdOld = NetcdfDataset.openDataset(testFile)) { + checkDataType(ncdOld); + } + } + + @Test + public void testDataTypeChangeNewApi() throws IOException { + String testFile = TestDir.cdmLocalTestDataDir + "/ncml/coords/string_coord.ncml"; + try (NetcdfDataset ncdNew = NetcdfDatasets.openDataset(testFile)) { + checkDataType(ncdNew); + } + } + + private void checkDataType(NetcdfDataset ncd) { + Variable var = ncd.findVariable("var"); + assertThat(var != null).isTrue(); + CoordinateAxis1D axis = (CoordinateAxis1D) var; + assertThat(axis.getOriginalDataType()).isEqualTo(DataType.INT); + assertThat(axis.getDataType()).isEqualTo(DataType.STRING); + assertThat(axis.isNumeric()).isFalse(); + } + +}