From 3a3e674ba529e6252c0c3cf648edf08a28dfdf70 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Wed, 11 Dec 2024 17:59:10 +0000 Subject: [PATCH] HPCC-33116 Suppress file check if invalid @compressedSize(0) Signed-off-by: Jake Smith --- dali/base/dadfs.cpp | 33 +++++++++++++++++++ dali/base/dadfs.hpp | 4 +++ ecl/hthor/hthor.cpp | 10 ++---- .../activities/diskread/thdiskreadslave.cpp | 10 ++---- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/dali/base/dadfs.cpp b/dali/base/dadfs.cpp index 7b008f187b4..fe390b2aa2c 100644 --- a/dali/base/dadfs.cpp +++ b/dali/base/dadfs.cpp @@ -13807,6 +13807,39 @@ void configurePreferredPlanes() } } +static bool doesPhysicalMatchMeta(IPropertyTree &partProps, IFile &iFile, offset_t &expectedSize, offset_t &actualSize) +{ + // NB: temporary workaround for 'narrow' files publishing extra empty parts with the wrong @compressedSize(0) + // causing a new check introduced in HPCC-33064 to be hit (fixed in HPCC-33113, but will continue to affect exiting files) + unsigned __int64 size = partProps.getPropInt64("@size", (unsigned __int64)-1); + unsigned __int64 compressedSize = partProps.getPropInt64("@compressedSize", (unsigned __int64)-1); + if ((0 == size) && (0 == compressedSize)) + return true; + + if (expectedSize != unknownFileSize) + { + actualSize = iFile.size(); + if (actualSize != expectedSize) + return false; + } + return true; +} + +bool doesPhysicalMatchMeta(IPartDescriptor &partDesc, IFile &iFile, offset_t &expectedSize, offset_t &actualSize) +{ + IPropertyTree &partProps = partDesc.queryProperties(); + expectedSize = partDesc.getDiskSize(false, false); + return doesPhysicalMatchMeta(partProps, iFile, expectedSize, actualSize); +} + +bool doesPhysicalMatchMeta(IDistributedFilePart &part, IFile &iFile, offset_t &expectedSize, offset_t &actualSize) +{ + IPropertyTree &partProps = part.queryAttributes(); + expectedSize = part.getDiskSize(false, false); + return doesPhysicalMatchMeta(partProps, iFile, expectedSize, actualSize); +} + + #ifdef _USE_CPPUNIT /* * This method removes files only logically. removeEntry() used to do that, but the only diff --git a/dali/base/dadfs.hpp b/dali/base/dadfs.hpp index 6cde9f34875..4e3f5fd2124 100644 --- a/dali/base/dadfs.hpp +++ b/dali/base/dadfs.hpp @@ -925,4 +925,8 @@ inline cost_type getLegacyWriteCost(const IPropertyTree & fileAttr, Source sourc else return 0; } + +extern da_decl bool doesPhysicalMatchMeta(IPartDescriptor &partDesc, IFile &iFile, offset_t &expectedSize, offset_t &actualSize); +extern da_decl bool doesPhysicalMatchMeta(IDistributedFilePart &partDesc, IFile &iFile, offset_t &expectedSize, offset_t &actualSize); + #endif diff --git a/ecl/hthor/hthor.cpp b/ecl/hthor/hthor.cpp index 06267a4908d..24d6f9027bc 100644 --- a/ecl/hthor/hthor.cpp +++ b/ecl/hthor/hthor.cpp @@ -8737,13 +8737,9 @@ bool CHThorDiskReadBaseActivity::openNext() if (curPart) { - offset_t expectedSize = curPart->getDiskSize(false, false); - if (expectedSize != unknownFileSize) - { - offset_t actualSize = inputfile->size(); - if(actualSize != expectedSize) - throw MakeStringException(0, "File size mismatch: file %s was supposed to be %" I64F "d bytes but appears to be %" I64F "d bytes", inputfile->queryFilename(), expectedSize, actualSize); - } + offset_t expectedSize, actualSize; + if (!doesPhysicalMatchMeta(*curPart, *inputfile, expectedSize, actualSize)) + throw makeStringExceptionV(0, "File size mismatch: file %s was supposed to be %" I64F "d bytes but appears to be %" I64F "d bytes", inputfile->queryFilename(), expectedSize, actualSize); } if (compressed) diff --git a/thorlcr/activities/diskread/thdiskreadslave.cpp b/thorlcr/activities/diskread/thdiskreadslave.cpp index c09718a041d..dd244fc6c5a 100644 --- a/thorlcr/activities/diskread/thdiskreadslave.cpp +++ b/thorlcr/activities/diskread/thdiskreadslave.cpp @@ -366,13 +366,9 @@ void CDiskRecordPartHandler::open() rwFlags |= DEFAULT_RWFLAGS; - offset_t expectedSize = partDesc->getDiskSize(false, false); - if (expectedSize != unknownFileSize) - { - offset_t actualSize = iFile->size(); - if(actualSize != expectedSize) - throw MakeStringException(0, "File size mismatch: file %s was supposed to be %" I64F "d bytes but appears to be %" I64F "d bytes", iFile->queryFilename(), expectedSize, actualSize); - } + offset_t expectedSize, actualSize; + if (!doesPhysicalMatchMeta(*partDesc, *iFile, expectedSize, actualSize)) + throw MakeActivityException(&activity, 0, "File size mismatch: file %s was supposed to be %" I64F "d bytes but appears to be %" I64F "d bytes", iFile->queryFilename(), expectedSize, actualSize); if (compressed) {