Empty results from resolve can be incorrectly sized #31
Labels
No labels
bug
duplicate
enhancement/documentation
enhancement/feature
enhancement/organization
question
rejected
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
UserCurt/mpath#31
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
There are circumstances where
resolveshould return an empty result. However, the size of the returned array can be incorrect. There are two main circumstances:First, if the supplied input is empty,
resolvewill always return a 0×0Second, if the supplied input is not empty but the path yields no results,
resolvewill always return either a:DotSetandDotGlobwhere the N is the length of theDotSetmost closest to but preceding the firstDotGlobBoth circumstances can violate the contract where repeated application of
resolveshould not effect result if all or all but the first use the defaultBundlingAlgorithm="shrink".In this example, the size of
r1is expected to be 2×0, and the size ofr2is expected to match the size ofr1.Additional examples, each expected 2×0:
This issue report may involve two related bugs
resolveshould be zero along dimensions corresponding to segments failing to produce matchesresolveshould retain the original size if emptyIn the current implementation,
reshapeResolvedResultspecially treats all-null data-derived matcher results viaemptyAllNullDataMatcherResult. That helper does not run the normal dimension assignment logic and currently only special-cases the firstDotGloband a precedingDotSet, so it cannot express general empty shape semantics.This issue was partially addressed by
220f030. This commit fixes degenerate cases involving multi-member matching dot operations (e.g.,DotSet,DotGlob):/A/*/*,/A/{X,Y}/*,/A/*/{X,Y}(with or without explicit#dimensions). Some things were not addressed:DotExactselecting members that do not existlistLengthis zero.Regarding
DotExact, a few options are considered:0x1when there are not matches forDotExact.DotExactsegments as dimension-bearing (either automatically with lower priority or by the user). These will behave similar to multi-member matching dot operations where they will be non-zero in size if they match a member and zero in size if they do not. A drawback is that if the user has a typo early on in a long path containing manyDotExactinstances, the result will contain many degenerate dimensions.DotExactwill be the degenerate empty dimension, and dimensions of subsequent instances dimensions will remain singleton. This should be equivalent to making the first unassigned singleton dimension zero in size and would be similar to a middle ground between the two.This issue has been partially addressed even further by
5d4208d. This commit fixed an incorrect assumption made on chunk validity which had ramifications on output shaping.In this commit, missing
DotExactbehavior is now closer to expected. EachDotExactis assigned a dimension but using a lower priority than other operations, which will rarely present itself to users except in degenerate cases. WithMissingPolicy="omit", the corresponding dimension to eachDotExactwill be size 1 if it exists or size 0 if it does not exist. If theMissingPolicyis"missing"or"retain", the size will remain 1.Remaining work to tackle for addressing this issue:
listLengthreturning 0This issue was further partially addressed by
ae4bc50. All-null shape no longer uses first degenerate column as dictator of shape but now considers each branch independently.Example:
/Bexists only in the/Abranch but not the/Xbranch, while/Cexists in neither branch. This previously returned 2×0×0, while it now returns the expected 2×1×0.Additional shaping issues
There same additional circumstance identified as returning an invalid shape when the result is empty.
Leading data-derived matcher
CSL selector before an all-null suffix
This issue does not present itself with select-all CSL selectors.
Non-traversable parent types
The intended behavior may depend on decided semantics on attempts to traverse parents that are non-traversable, which is considered in issue #32.
Remaining cases to be addressed
listLengthCommit
b2c3296further continues to address this issue. Behavior used to differ whether a data-derived matcher was leading segment or not, where leading segments would fallback to returning0×1result. Now both leading and non-leading are handled by the same code.For example:
Further progress with commit
6a23455: Metadata is now used for the case where there is valid scalar CSL selectors before a later all-null suffix rather than having a special case early exit. This change is intentionally limited to scalar selectors that are concrete on every aligned branch.Remaining work:
listLengthDotExactnot existing)Much of the remaining work has been addressed now in
05aca75: Empty-result shaping now handles zerolistLengthand also unresolved, out-of-range, or partially concrete CSL selectors. Implicit (generated) singleton CSL boundaries stay non-shaping.What remains to tackle is non-traversable paths and is coupled to issue #32.
Further addressed by
9c247dcwhere empty CSL selection andDotSetnow give correct empty shape rather than 0×1.Completed by
af551a2. Final hardcoded 0×1 fallback has been removed. Code now distinguishes reached failures from unreached nominal suffixes for empty shapes.