Skip to content

fix: various custom operator conformance fixes#1778

Open
toddbaert wants to merge 3 commits intomainfrom
chore/update-test-harness
Open

fix: various custom operator conformance fixes#1778
toddbaert wants to merge 3 commits intomainfrom
chore/update-test-harness

Conversation

@toddbaert
Copy link
Copy Markdown
Member

@toddbaert toddbaert commented Apr 21, 2026

fix: various custom operator conformance fixes

  • support v/V prefix in semver
  • support partial versions in semver
  • support numeric context values in semver
  • return null on errors
  • fix fractional single-entry flattening

⚠️ wait until flagd/RPC is updated to merge.

Fixes: #1774


Related:

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several improvements to the flagd core evaluation logic, including enhanced type handling for context values, more robust SemVer parsing with support for partial versions and numeric coercion, and fixes for fractional evaluation edge cases. I have provided a suggestion to optimize the fractional evaluation logic by using List operations instead of manual array copying to improve performance.

Comment on lines +44 to +59
Object[] source = arguments.toArray();
distributions = Arrays.copyOfRange(source, 1, source.length);
Object[] remaining = Arrays.copyOfRange(source, 1, source.length);

// json-logic pre-evaluation flattens a single-entry fractional
// e.g. [["single",1]] becomes ["single", 1]; detect and re-wrap
if (remaining.length > 0 && !(remaining[0] instanceof List)) {
List<Object> wrapped = new ArrayList<>();
wrapped.add(arg1);
for (Object r : remaining) {
wrapped.add(r);
}
distributions = new ArrayList<>();
distributions.add(wrapped);
} else {
distributions = Arrays.asList(remaining);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation performs multiple array copies and manual list building, which can be inefficient as this code is executed during every flag evaluation. Using List.subList and List.addAll is more efficient and idiomatic for this purpose.

            List<Object> remaining = arguments.subList(1, arguments.size());

            // json-logic pre-evaluation flattens a single-entry fractional
            // e.g. [["single",1]] becomes ["single", 1]; detect and re-wrap
            if (!remaining.isEmpty() && !(remaining.get(0) instanceof List)) {
                List<Object> wrapped = new ArrayList<>(remaining.size() + 1);
                wrapped.add(arg1);
                wrapped.addAll(remaining);
                distributions = Arrays.asList((Object) wrapped);
            } else {
                distributions = remaining;
            }

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Fixed. Also made improvements around the $ref replace.

@toddbaert toddbaert marked this pull request as draft April 21, 2026 00:37
@toddbaert toddbaert force-pushed the chore/update-test-harness branch from 7c5c7cd to 6977314 Compare April 21, 2026 16:57
@toddbaert toddbaert changed the title Chore/update test harness fix: various custom operator conformance fixes Apr 21, 2026
@toddbaert toddbaert force-pushed the chore/update-test-harness branch 2 times, most recently from d4dbb57 to 436d041 Compare April 22, 2026 16:36
* support v/V prefix in semver
* support partial versions in semver
* support numeric context values in semver
* return null on errors
* fix fractional single-entry flattening

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
@toddbaert toddbaert force-pushed the chore/update-test-harness branch 2 times, most recently from 529b1d1 to 6f64b40 Compare April 22, 2026 17:32
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
@toddbaert toddbaert force-pushed the chore/update-test-harness branch from 6f64b40 to d7c20b4 Compare April 22, 2026 17:33
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
@toddbaert toddbaert marked this pull request as ready for review April 24, 2026 15:26
@@ -51,7 +61,7 @@ public Object evaluate(List arguments, Object data, String jsonPath) throws Json
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also need to check for flattening here for single-entry fractionals? Or does that not happen here because the pre-evaluation doesn't "get confused" by 2 different list entry types?

// bucket key is a null var result (simulated by being a non-string, non-list)
List.of("one", 50), List.of("two", 50));

// targeting key is null, so fractional falls back to flagKey + targetingKey
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit-pick, do you mean "bucketing key is null"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update flagd-testbed to v3.6.2 and fix in-process evaluation edge cases

7 participants