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 MySql LOCAL INFILE functionality #2738

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

jelle-bigbridge
Copy link

Fixes #1766

I've added a test which confirms this functionality. I was unsure about the function name local_infile_statement and the trait name MySqlExecutorInfileExt. Please tell me if you want to have different names

@grooverdan
Copy link
Contributor

I like the functionality of LocalInfileHandler that doesn't tie the local implementation to a local file, just a handler to push data. This should mitigate the risks of enabling localinfile as default in the protocol.

sqlx-mysql/src/connection/infile.rs Outdated Show resolved Hide resolved
@jelle-bigbridge jelle-bigbridge force-pushed the add-local-infile branch 4 times, most recently from 03a7c85 to 7f016e8 Compare September 26, 2023 09:01
@jelle-bigbridge
Copy link
Author

@abonander could you look at the changes I made?

sqlx-mysql/src/connection/infile.rs Outdated Show resolved Hide resolved
sqlx-mysql/src/connection/infile.rs Outdated Show resolved Hide resolved
sqlx-mysql/src/connection/infile.rs Outdated Show resolved Hide resolved
let mut send = SendPacket::new(buf, self.stream.sequence_id);
self.stream.sequence_id = self.stream.sequence_id.wrapping_add(1);
// Try to poll the send future right now
match Pin::new(&mut send).poll_send(cx, self.stream.socket_mut()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are you bypassing the connection's internal buffer?

Copy link

Choose a reason for hiding this comment

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

My idea was that you either use the "easy" way of calling MySqlLocalInfile::send a couple times, which does buffering, or you want to do a different style of buffering so you need a "direct" API. In my own usage, I wrap the "direct" writer with my own BufWriter to provide buffering of infile packets.

Copy link
Collaborator

Choose a reason for hiding this comment

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

My thought is, we already have a perfectly buffer in the connection. Why force the user to allocate another?

Copy link
Contributor

Choose a reason for hiding this comment

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

@jelle-bigbridge Do you plan to get back to working on this PR? This feature would be very useful for us, if you're busy I could pick it up.

Copy link

Choose a reason for hiding this comment

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

I need feedback from the maintainers to finish this to be quite honest. If this direct mode needs to be reworked I can do it, but I need some direction to take this in. I don't want to go and make changes myself without knowing if it will help to get it merged

@jelle-bigbridge
Copy link
Author

Sorry for answering with my personal account @pingiun. I plan to migrate my work account to personal in the future.

jelle-bigbridge and others added 4 commits October 12, 2023 09:22
Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
@jelle-bigbridge
Copy link
Author

@abonander what is needed to get this merged?

ready!(socket.poll_write_ready(cx))?;
}
Ok(written) => {
this.buf.drain(..written);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is going to copy contents of the buffer on every poll

Copy link

Choose a reason for hiding this comment

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

From the docs it doesn't seem like drain should copy the contents of the buffer, can you explain?

Copy link
Contributor

Choose a reason for hiding this comment

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

drain removes specified range of elements. But Vec<_> cannot have holes, so when you remove elements, it will move remaining elements in order to fill the hole.

In this case, buf could be 1 MB for example. May be socket only managed to write 10 KB (written = 10_000). When we call buf.drain(..10_000) it'll remove the first 10_000 bytes from the vector by moving the remaining 990_000 bytes to the beginning of the vector.

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.

Support LOAD DATA LOCAL INFILE command for MySQL
5 participants