-
Notifications
You must be signed in to change notification settings - Fork 1k
Store prepared statements field definitions #1073
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,13 @@ import ( | |
| "github.com/go-mysql-org/go-mysql/utils" | ||
| ) | ||
|
|
||
| // StmtFieldsProvider is an optional interface that prepared statement contexts can implement | ||
| // to provide field definitions for proxy passthrough scenarios. | ||
| type StmtFieldsProvider interface { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to verify why we need this interface? If the only reason is to cast
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you suggesting that we create something like and then use it in |
||
| GetParamFields() []*mysql.Field | ||
| GetColumnFields() []*mysql.Field | ||
| } | ||
|
|
||
| // Handler is what a server needs to implement the client-server protocol | ||
| type Handler interface { | ||
| // handle COM_INIT_DB command, you can check whether the dbName is valid, or other. | ||
|
|
@@ -112,6 +119,12 @@ func (c *Conn) dispatch(data []byte) interface{} { | |
| if st.Params, st.Columns, st.Context, err = c.h.HandleStmtPrepare(st.Query); err != nil { | ||
| return err | ||
| } else { | ||
| // If context provides field definitions (e.g., from a backend prepared statement), | ||
| // use them for accurate metadata passthrough in proxy scenarios. | ||
| if provider, ok := st.Context.(StmtFieldsProvider); ok { | ||
| st.ParamFields = provider.GetParamFields() | ||
| st.ColumnFields = provider.GetColumnFields() | ||
| } | ||
| st.ResetParams() | ||
| c.stmts[c.stmtID] = st | ||
| return st | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,10 @@ type Stmt struct { | |
| Args []interface{} | ||
|
|
||
| Context interface{} | ||
|
|
||
| // Field definitions for proxy passthrough (optional, uses dummy fields if nil) | ||
| ParamFields []*mysql.Field | ||
| ColumnFields []*mysql.Field | ||
| } | ||
|
|
||
| func (s *Stmt) Rest(params int, columns int, context interface{}) { | ||
|
|
@@ -61,7 +65,11 @@ func (c *Conn) writePrepare(s *Stmt) error { | |
| if s.Params > 0 { | ||
| for i := 0; i < s.Params; i++ { | ||
| data = data[0:4] | ||
| data = append(data, paramFieldData...) | ||
| if s.ParamFields != nil && i < len(s.ParamFields) { | ||
| data = append(data, s.ParamFields[i].Dump()...) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems no need to parse it? We can only forward the raw value.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The rationale was that for a high-level library that users can use to inspect fields metadata, it makes sense that they don't have to parse the bytes themselves. But for a pure proxy use-case, yeah, the raw value would be better. Both work for me! |
||
| } else { | ||
| data = append(data, paramFieldData...) | ||
| } | ||
|
|
||
| if err := c.WritePacket(data); err != nil { | ||
| return errors.Trace(err) | ||
|
|
@@ -76,7 +84,11 @@ func (c *Conn) writePrepare(s *Stmt) error { | |
| if s.Columns > 0 { | ||
| for i := 0; i < s.Columns; i++ { | ||
| data = data[0:4] | ||
| data = append(data, columnFieldData...) | ||
| if s.ColumnFields != nil && i < len(s.ColumnFields) { | ||
| data = append(data, s.ColumnFields[i].Dump()...) | ||
| } else { | ||
| data = append(data, columnFieldData...) | ||
| } | ||
|
|
||
| if err := c.WritePacket(data); err != nil { | ||
| return errors.Trace(err) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.