Skip to content

Port StatementRewrite::rewrite_simple_prepared to the new parser#1158

Open
sgrif wants to merge 1 commit into
mainfrom
sg-port-simple-prepared
Open

Port StatementRewrite::rewrite_simple_prepared to the new parser#1158
sgrif wants to merge 1 commit into
mainfrom
sg-port-simple-prepared

Conversation

@sgrif

@sgrif sgrif commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

I'm trying something new with this function, I'm intentionally using a silly form of cfg'ing the old code out to force those lines to have an indentation change, as this causes the diff to interpret the new code as changed lines and the old code as an addition. This will result in less churn in the long run (since the old code is getting deleted), and gives way nicer diffs for review

I'm trying something new with this function, I'm intentionally using a
silly form of cfg'ing the old code out to force those lines to have an
indentation change, as this causes the diff to interpret the new code
as changed lines and the old code as an addition. This will result in
less churn in the long run (since the old code is getting deleted), and
gives way nicer diffs for review
@sgrif sgrif requested a review from levkk July 7, 2026 12:34
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.49123% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...router/parser/rewrite/statement/simple_prepared.rs 96.49% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment on lines +134 to +136
self.stmt.stmts = pg_query::parse(pg_raw_parse::deparse(node.as_ref())?.as_str())?
.protobuf
.stmts;

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.

can you help understand this? do we need to update stmt just to push the modified version to self and provide the compatibility with old parser types? and for old parser it's not required because we do the in-place mutation of stmt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Correct. I'm parsing these functions in relatively small pieces, so some of the other functions called here modify or read from self.stmt instead of node. So any time a function modifies self.stmt we deparse and reparse into node, and any time we modify node, we need to deparse and reparse into self.stmt. Once everything in StatementRewrite is ported, this will no longer be necessary and I will cfg out the stmt field.

let global_name = parse.name().to_string();
let statement = parse.query().to_string();
stmt.name = global_name.clone();
stmt.set_name(Some(mem.copy_string(&global_name)));

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.

I'm sorry for asking probably a dumb question, but I'm still at the start of my journey to understand the new parser. But could the set_name be simplified to not juggle with explicit mem operation to copy the data? I mean could the set_name handle it's by itself in its internals? I think the mem token is not yet stored on NodeMut, but probably we can store it or get the proper mem context somehow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You never need to apologize for asking questions. Part of the reason for code review is to spread knowledge 😄

But could the set_name be simplified to not juggle with explicit mem operation to copy the data? I mean could the set_name handle it's by itself in its internals?

We do this in constructor functions, but not setters. This is because the node doesn't have a reference to the memory context.

I think the mem token is not yet stored on NodeMut, but probably we can store it or get the proper mem context somehow?

We intentionally avoid keeping anything on Node/NodeMut other than a single pointer or zero-sized types. We want the node structs to be layout compatible with the C versions, and we want Node/NodeMut/&SomeNode/SomeNodeMut to all be layout identical to a *mut raw::Node, so that the conversion cost is nothing more than a pointer cast. (There's some caveats with Node/NodeMut that I'm happy to go into if you'd like but aren't relevant to this question)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Shorter version of the answer: I don't see having to write mem.copy_string(s) as any different than having to write s.clone(). The only difference here is that we're using PG's allocator instead of the global one.

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.

2 participants