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

fix: ensure no nulls in postgres. Fixes #13711 #14004

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

isubasinghe
Copy link
Member

@isubasinghe isubasinghe commented Dec 16, 2024

Motivation

Unfortunately postgres does not handle NULL bytes in the json, this is as a result of a non-compliant implementation of JSON that exists in postgres. See more details about this limitation here.

Modifications

This is arguably hacky solution, but this fix attempts to resolve this by mutating the workflow.

Verification

This has tests and additionally been verified by checking postgres.

@isubasinghe isubasinghe changed the title fix: ensure no nulls in postgres fix: ensure no nulls in postgres. Fixes #13711 Dec 16, 2024
@isubasinghe
Copy link
Member Author

/retest

1 similar comment
@isubasinghe
Copy link
Member Author

/retest

@isubasinghe isubasinghe marked this pull request as ready for review December 17, 2024 02:33
Comment on lines +11 to +19
case string:
ms, err := json.Marshal(v)
if err != nil {
return nil, err
}
tmp := string(ms)
tmp = tmp[1:]
tmp = tmp[:len(tmp)-1]
m[k] = string(tmp)
Copy link
Member Author

Choose a reason for hiding this comment

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

Horrible horrible hackiness

@isubasinghe
Copy link
Member Author

I have a couple of questions before we merge this.

What are opinions on a serialize to []byte and then remove nulls approach instead? It seems saner.
Should this be opt in via an environment variable, we are after all mutating the workflow.

@isubasinghe isubasinghe requested a review from Joibel December 17, 2024 06:25
@tooptoop4
Copy link
Contributor

please don't remove the nulls, we use them in our bash script

@isubasinghe
Copy link
Member Author

please don't remove the nulls, we use them in our bash script

This doesn't remove nulls from workflows, it escapes to \u0000 when persisting to postgres.

Your workflow wouldn't persist to postgres anyway if it had nulls.

We can make this optional if you want ?

@tooptoop4
Copy link
Contributor

just want to be able to run a workflow containing null character

@isubasinghe
Copy link
Member Author

just want to be able to run a workflow containing null character

This fix doesn't break this so you got nothing to worry about there.

@MasonM
Copy link
Contributor

MasonM commented Dec 18, 2024

AFAICT we don't have any automated tests for the PostgreSQL-specific logic in persist/sqldb/workflow_archive.go, and it seems like we should considering how tricky these edge cases can get. I entered #14011 to have the CI run the API tests (which exercise the archiving logic) on PostgreSQL, and #14012 with some optimizations.

var workflow []byte
var err error
if r.dbType == Postgres {
workflow, err = jsonMarshallRawStrings(wf)
Copy link
Contributor

@tooptoop4 tooptoop4 Dec 22, 2024

Choose a reason for hiding this comment

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

would be good to ensure the new marshalled json is the same as the old way (with exception of the null char), could there be some if condition that compares them? otherwise there is risk that null character gets solved but other characters start being represented differently

Copy link
Contributor

Choose a reason for hiding this comment

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

My PR has a test for this: #14011

Copy link
Contributor

Choose a reason for hiding this comment

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

@MasonM that is only for 1 tiny workflow, in the wild there are all kinds of workflows with various funky characters. i think a runtime check to ensure correctness is better than risk of a different/incorrect workflow being archived/retried

Copy link
Member Author

Choose a reason for hiding this comment

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

@tooptoop4 @MasonM sounds like maybe its better to serialize first and then remove null bytes instead of working at this layer? I was hoping to avoid that but perhaps that is indeed better.

@isubasinghe
Copy link
Member Author

I have another fix that works on the byte level and is able to restore the original workflow. I think I want that to go in instead.

@isubasinghe isubasinghe marked this pull request as draft December 23, 2024 11:56
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.

3 participants