Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the JSON.MERGE command #1852

Merged
merged 18 commits into from
Nov 10, 2023

Conversation

2rueSid
Copy link
Contributor

@2rueSid 2rueSid commented Oct 24, 2023

support JSON.MERGE, this closes #1815

JSON.MERGE

It's a bit messy, so I added comments. (After review I may remove them)

handling of the null value is a bit tricky so I utilize these commands to do this:

Also here is info about mergepatch

Mostly for references I used the original command: JSON.MERGE

please review @mapleFU @PragmaTwice @torwig

@2rueSid 2rueSid marked this pull request as draft October 24, 2023 00:51
@2rueSid 2rueSid marked this pull request as ready for review October 27, 2023 01:14
src/types/json.h Outdated Show resolved Hide resolved
src/types/json.h Outdated Show resolved Hide resolved
src/types/json.h Outdated
Comment on lines 274 to 292
static jsoncons::json GenerateJsonFromPath(const std::string &path, const jsoncons::json &value) {
std::vector<std::string> parts;
std::stringstream ss(path);
std::string part;

while (std::getline(ss, part, '.')) {
if (part != "$") {
parts.push_back(part);
}
}

jsoncons::json result = value;
for (auto it = parts.rbegin(); it != parts.rend(); ++it) {
jsoncons::json obj;
obj[*it] = result;
result = obj;
}

return result;
Copy link
Member

@PragmaTwice PragmaTwice Oct 27, 2023

Choose a reason for hiding this comment

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

Seems it is not general enough, e.g. it cannot process path like $[0], $["hello"] or $..a.
I think here we can just use Get.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I was busy the last couple of days. Now, I can finally finish it.

What exactly do you mean by I think here we can just use Get.?
I was thinking about extracting keys from a string and using jsonpointer to create an object. However, it still won't handle all possible grammar.

Copy link
Member

Choose a reason for hiding this comment

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

I mean maybe we can just use jsonpath::json_query here (as well as JsonValue::Get).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A brief update: I have researched a bit, and it appears that we might require the path parser.

The function jsonpath::json_query can return a normalized path instead of a value, but only if a value exists at that path. The same applies to jsonpath::json_replace—it operates only when a value exists.

Moreover, the parser could be beneficial for the Set function, as it currently cannot process the following expression:

127.0.0.1:6666> JSON.SET doc $ '{"a":2}'
OK
127.0.0.1:6666> JSON.SET doc $.b '8'
OK
127.0.0.1:6666> JSON.GET doc $
"[{\"a\":2}]"

Ideally, in the Merge() function, we should invoke the Set() function for this case, I presume.

I will also reach out to the maintainer of jsoncons to check whether there is a more elegant implementation of this.

Copy link
Member

@PragmaTwice PragmaTwice Nov 3, 2023

Choose a reason for hiding this comment

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

Oh, I check the document of JSON.MERGE and now get your point.

I think currently you can just implement the one that is supported by jsoncons (specifically, the case when a value exists in the jsonpath provided by the user, which can be handled by json_query) and return some error message in other cases. (you can add a TODO comment in the code.)

And after this PR being merged, you can try to cover more cases if you are interested.

And of course it is a great idea to open a discussion or issue in the jsoncons community to address this problem : )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the method slightly and added a TODO comment. I've also initiated a discussion danielaparker/jsoncons#468

I will attempt to implement this in a separate pull request, as it could be quite complex.

src/types/redis_json.cc Outdated Show resolved Hide resolved
Co-authored-by: Twice <twice@apache.org>
@PragmaTwice
Copy link
Member

Seems you also need to change the method declaration to make it pass the compiler.

src/types/json.h Outdated Show resolved Hide resolved
@2rueSid
Copy link
Contributor Author

2rueSid commented Nov 6, 2023

Is a SonarCloud analysis required for a PR to pass? It seems to display a duplication error for C++ test cases, although there are no duplicates.

@PragmaTwice

@PragmaTwice
Copy link
Member

PragmaTwice commented Nov 8, 2023

Is a SonarCloud analysis required for a PR to pass? It seems to display a duplication error for C++ test cases, although there are no duplicates.

@PragmaTwice

Nope. It is fine to leave it alone.

@git-hulk Do you have free time to help review and merge this PR?

@git-hulk
Copy link
Member

git-hulk commented Nov 9, 2023

Is a SonarCloud analysis required for a PR to pass? It seems to display a duplication error for C++ test cases, although there are no duplicates.
@PragmaTwice

Nope. It is fine to leave it alone.

@git-hulk Do you have free time to help review and merge this PR?

Sure, I would take a look soon.

Copy link

sonarcloud bot commented Nov 10, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 2 Code Smells

No Coverage information No Coverage information
8.8% 8.8% Duplication

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint

@git-hulk git-hulk merged commit 78f87c4 into apache:unstable Nov 10, 2023
29 of 30 checks passed
@git-hulk
Copy link
Member

Thank you! @2rueSid

@PragmaTwice
Copy link
Member

Hi @2rueSid , in the new version of jsoncons, some new features have been added for removing nodes.

Refer to danielaparker/jsoncons#467 (comment).

Are you willing to improve this MERGE command using that?

@2rueSid
Copy link
Contributor Author

2rueSid commented Dec 4, 2023

Hi @2rueSid , in the new version of jsoncons, some new features have been added for removing nodes.

Refer to danielaparker/jsoncons#467 (comment).

Are you willing to improve this MERGE command using that?

Hello. Yes for sure! I will take a look tomorrow.

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.

Add support for the JSON.MERGE command
3 participants