Skip to content

Add MySql LOCAL INFILE functionality#2738

Closed
ghost wants to merge 19 commits into
mainfrom
unknown repository
Closed

Add MySql LOCAL INFILE functionality#2738
ghost wants to merge 19 commits into
mainfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Sep 7, 2023

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
Copy Markdown
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.

Comment thread sqlx-mysql/src/connection/infile.rs Outdated
@ghost ghost requested a review from abonander September 15, 2023 13:00
@ghost
Copy link
Copy Markdown
Author

ghost commented Oct 6, 2023

@abonander could you look at the changes I made?

Comment thread sqlx-mysql/src/connection/infile.rs Outdated
Comment thread sqlx-mysql/src/connection/infile.rs Outdated
Comment thread sqlx-mysql/src/connection/infile.rs Outdated
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
Copy Markdown
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
Copy Markdown

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@pingiun my feedback was to not bypass the connection's internal buffer.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For copying from an AsyncRead type, you can include a read_from method similar to PgCopyIn: https://docs.rs/sqlx/latest/sqlx/postgres/struct.PgCopyIn.html#method.read_from

The trait situation isn't great there, fixing it depends on having async I/O traits in std, traits which I was told were coming more than two years ago and still haven't materialized: #1669 (comment)

@ghost
Copy link
Copy Markdown
Author

ghost commented Oct 12, 2023

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

pingiun 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>
@ghost ghost requested a review from abonander October 16, 2023 07:47
@ghost
Copy link
Copy Markdown
Author

ghost commented Feb 7, 2024

@abonander what is needed to get this merged?

ready!(socket.poll_write_ready(cx))?;
}
Ok(written) => {
this.buf.drain(..written);
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.

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

Copy link
Copy Markdown

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
Copy Markdown
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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is another reason not to reinvent the wheel with buffering here. The connection already has a buffer that doesn't have this problem.

@ghost ghost closed this by deleting the head repository May 2, 2025
This pull request was closed.
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

4 participants