Skip to content

Do not allow duplicate field in object when evaluating list list comprehension#100

Merged
edsilfer merged 1 commit intomasterfrom
edgar/fix-duplicate-field-on-list-comprehension
Nov 9, 2020
Merged

Do not allow duplicate field in object when evaluating list list comprehension#100
edsilfer merged 1 commit intomasterfrom
edgar/fix-duplicate-field-on-list-comprehension

Conversation

@edsilfer
Copy link
Copy Markdown
Contributor

@edsilfer edsilfer commented Nov 9, 2020

What changes are proposed in this pull request?

This PR fixes issue 99 by issuing an error in case an Expr.Str is matching with an Expr.ForSpec with a value greater than 1. This condition denotes that the Expr.Str field value would be overridden in each interaction of the Expr.ForSpec

How is this tested?

  • Two new unit test with a positive and negative scenario emulating the issue
  • Run ./mill "sjsonnet[2.13.3].jvm.test.testLocal" to make sure that all the tests are still passing
@edsilfer edsilfer self-assigned this Nov 9, 2020
@edsilfer edsilfer force-pushed the edgar/fix-duplicate-field-on-list-comprehension branch from 230693f to 5259355 Compare November 9, 2020 12:01
Copy link
Copy Markdown
Contributor

@lihaoyi-databricks lihaoyi-databricks left a comment

Choose a reason for hiding this comment

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

One small nit, but otherwise looks good

@edsilfer edsilfer force-pushed the edgar/fix-duplicate-field-on-list-comprehension branch from 5259355 to a893c6f Compare November 9, 2020 12:59
@edsilfer edsilfer merged commit 1143556 into master Nov 9, 2020
@stephenamar-db stephenamar-db deleted the edgar/fix-duplicate-field-on-list-comprehension branch April 18, 2025 06:40
stephenamar-db pushed a commit that referenced this pull request Aug 21, 2025
…#470)

This PR fixes a bug in the detection of duplicate fields:

Official `jsonnet` and `go-jsonnet` both detect and fail on duplicate
field names even when the field names are dynamically computed via
[field name
expression](https://jsonnet.org/ref/language.html#field-name-expressions):

```jsonnet
{ k: 1, ["k"]: 2 }
```

produces

```
Error: RUNTIME ERROR: Duplicate field name: "k"
	example1.jsonnet:1:1-19	$
	During evaluation	
```

However, sjsonnet currently accepts this and outputs 

```
{"k" : 2}
```

with a last-assignment-wins policy.

sjsonnet already correctly detects _literal_ field name duplication [at
parse
time](https://github.com/databricks/sjsonnet/blob/0.5.4/sjsonnet/src/sjsonnet/Parser.scala#L401-L413)
(e.g. `{k: 1, k: 2}`) and detects field name duplication in object
comprehensions at both
[parse](https://github.com/databricks/sjsonnet/blob/0.5.4/sjsonnet/src/sjsonnet/Parser.scala#L472-L497)
and
[evaluation](https://github.com/databricks/sjsonnet/blob/0.5.4/sjsonnet/src/sjsonnet/Evaluator.scala#L771-L788)
time (see #100 and #156).

This PR adds duplicate field name detection at normal object evaluation
time. The core check is simple and cheap: when adding a member to the
object's fields hashmap, check the `put()` return value and fail if we
detect that a duplicate key has been inserted.

One subtlety to handle involves sjsonnet's static object optimizations:
it's possible that we might detect duplicates during static optimization
because a dynamic field expression might be constant-folded / statically
optimized into a fixed literal. Even though we can detect this at
optimization time, we must defer the throwing of an error until the
object is actually evaluated or accessed during program execution: this
is necessary in order to faithfully preserve lazy evaluation semantics.
I chose to handle this by rendering such objects ineligible for static
optimization: they will remain as `MemberList`s.

I added new regression tests in EvaluatorSuite to cover this bug and
confirmed that the expected behavior matches the jsonnet and go-jsonnet
implementations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants