From 6ebc98d254a52764358d8f8774aa3279b79d15a1 Mon Sep 17 00:00:00 2001 From: Russ Rew Date: Mon, 22 Apr 2013 22:34:21 +0000 Subject: [PATCH] Fix NCF-247 bug, and add test for bug fix. --- libsrc4/nc4file.c | 2 +- libsrc4/nc4hdf.c | 22 +++++++++++++++++++--- nc_test4/tst_coords2.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/libsrc4/nc4file.c b/libsrc4/nc4file.c index d6d6f80e9..2f7cc5ab6 100644 --- a/libsrc4/nc4file.c +++ b/libsrc4/nc4file.c @@ -3001,7 +3001,7 @@ sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5) int bad_coord_order = 0; /* if detected, propagate to all groups to consistently store dimids */ if ((retval = nc4_rec_write_types(h5->root_grp))) return retval; - if ((retval = nc4_rec_detect_bad_coord_order(h5->root_grp, &bad_coord_order))) + if ((retval = nc4_rec_detect_need_to_preserve_dimids(h5->root_grp, &bad_coord_order))) return retval; if ((retval = nc4_rec_write_metadata(h5->root_grp, bad_coord_order))) return retval; diff --git a/libsrc4/nc4hdf.c b/libsrc4/nc4hdf.c index ede5e957b..606466666 100644 --- a/libsrc4/nc4hdf.c +++ b/libsrc4/nc4hdf.c @@ -2427,9 +2427,12 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid) /* Recursively determine if there is a mismatch between order of * coordinate creation and associated dimensions in this group or any - * subgroups, to find out if we have to handle that situation. */ + * subgroups, to find out if we have to handle that situation. Also + * check if there are any multidimensional coordinate variables + * defined, which require the same treatment to fix a potential bug + * when such variables occur in subgroups. */ int -nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp) +nc4_rec_detect_need_to_preserve_dimids(NC_GRP_INFO_T *grp, int *bad_coord_orderp) { NC_DIM_INFO_T *dim; NC_VAR_INFO_T *var; @@ -2455,6 +2458,19 @@ nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp) } } + /* If there are multidimensional coordinate variables defined, then + * it's also necessary to preserve dimension IDs when the file is + * reopened ... */ + for (var = grp->var; var; var = var->next) + { + LOG((5, "checking %s for multidimensional coord var", var->name)); + if (var->ndims > 1 && var->dimscale) + { + *bad_coord_orderp = 1; + return NC_NOERR; + } + } + /* Did the user define a dimension, end define mode, reenter define * mode, and then define a coordinate variable for that dimension? * If so, dimensions will be out of order. */ @@ -2470,7 +2486,7 @@ nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp) /* If there are any child groups, check them also for this condition. */ for (child_grp = grp->children; child_grp; child_grp = child_grp->next) - if ((retval = nc4_rec_detect_bad_coord_order(child_grp, bad_coord_orderp))) + if ((retval = nc4_rec_detect_need_to_preserve_dimids(child_grp, bad_coord_orderp))) return retval; return NC_NOERR; diff --git a/nc_test4/tst_coords2.c b/nc_test4/tst_coords2.c index 6687dc822..de93cd436 100644 --- a/nc_test4/tst_coords2.c +++ b/nc_test4/tst_coords2.c @@ -139,6 +139,46 @@ main(int argc, char **argv) if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; + printf("**** testing example from bug NCF-247, multidimensional coord variable in subgroup ..."); + { +#define GRPNAME "g1" +#define DIM0NAME "dim0" +#define DIM1NAME "dim1" +#define DIM2NAME "coord" +#define DIM3NAME "dim3" +#define VARNAME DIM2NAME +#define VARRANK 2 + int ncid, grpid, varid, var_dims[VARRANK], var_dims_in[VARRANK]; + char name2[NC_MAX_NAME], name3[NC_MAX_NAME]; + int dim0_dim, dim1_dim, dim2_dim, dim3_dim; + size_t dim0_len = 3, dim1_len = 2, dim2_len = 5, dim3_len = 7; + + if (nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR; + if (nc_def_grp(ncid, GRPNAME, &grpid)) ERR; + + if (nc_def_dim(ncid, DIM0NAME, dim0_len, &dim0_dim)) ERR; + if (nc_def_dim(ncid, DIM1NAME, dim1_len, &dim1_dim)) ERR; + if (nc_def_dim(grpid, DIM2NAME, dim2_len, &dim2_dim)) ERR; + if (nc_def_dim(grpid, DIM3NAME, dim3_len, &dim3_dim)) ERR; + + var_dims[0] = dim2_dim; + var_dims[1] = dim3_dim; + if (nc_def_var(grpid, VARNAME, NC_INT, VARRANK, var_dims, &varid)) ERR; + + if (nc_close(ncid)) ERR; + + if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; + + if (nc_inq_grp_ncid(ncid, GRPNAME, &grpid)) ERR; + + if (nc_inq_varid(grpid, VARNAME, &varid)) ERR; + if (nc_inq_vardimid(grpid, varid, var_dims_in)) ERR; + if (nc_inq_dimname(grpid, var_dims_in[0], name2)) ERR; + if (nc_inq_dimname(grpid, var_dims_in[1], name3)) ERR; + if (strcmp(name2, DIM2NAME) != 0 || strcmp(name3, DIM3NAME) != 0) ERR; + if (nc_close(ncid)) ERR; + } + SUMMARIZE_ERR; FINAL_RESULTS; }