MCPcopy Create free account
hub / github.com/apecloud/myduckserver / ComPrepareParsed

Method ComPrepareParsed

pgserver/duck_handler.go:133–233  ·  view source on GitHub ↗

ComPrepareParsed implements the Handler interface.

(ctx context.Context, c *mysql.Conn, query string, parsed tree.Statement)

Source from the content-addressed store, hash-verified

131
132 return err
133}
134
135// ComPrepareParsed implements the Handler interface.
136func (h *DuckHandler) ComPrepareParsed(ctx context.Context, c *mysql.Conn, query string, parsed tree.Statement) (*duckdb.Stmt, []uint32, []pgproto3.FieldDescription, error) {
137 if err := h.rejectReadOnly(ConvertedStatement{String: query, AST: parsed}); err != nil {
138 return nil, nil, nil, err
139 }
140 // DuckDB's official Go binding exposes prepared statement parameter types but not result types.
141 // 1. For SELECT statements, we will supply all NULL values as parameters
142 // to execute the query with a LIMIT 0 to get the result types.
143 // 2. For SHOW/CALL/PRAGMA statements, we will just execute the query and get the result types
144 // because they usually don't have parameters and are efficient to execute.
145 // 3. For other statements (DDLs and DMLs), we just return the "affected rows" field.
146 sqlCtx, err := h.sm.NewContextWithQuery(ctx, c, query)
147 if err != nil {
148 return nil, nil, nil, err
149 }
150
151 conn, err := adapter.GetConn(sqlCtx)
152 if err != nil {
153 return nil, nil, nil, err
154 }
155
156 var (
157 stmt *duckdb.Stmt
158 stmtType duckdb.StmtType
159 paramTypes []duckdb.Type
160 )
161 // This is a bit of a hack to get DuckDB's underlying prepared statement.
162 // But we know that the connection is a DuckDB connection and it is kept alive.
163 err = conn.Raw(func(driverConn interface{}) error {
164 dc := driverConn.(*duckdb.Conn)
165 s, err := dc.PrepareContext(sqlCtx, query)
166 if err != nil {
167 return err
168 }
169 n := s.NumInput()
170 stmt = s.(*duckdb.Stmt)
171 stmtType, err = stmt.StatementType()
172 if err != nil {
173 return err
174 }
175 paramTypes = make([]duckdb.Type, n)
176 for i := 0; i < n; i++ {
177 paramTypes[i], err = stmt.ParamType(i + 1) // 1-based index
178 if err != nil {
179 return err
180 }
181 }
182 return nil
183 })
184 if err != nil {
185 logrus.WithField("query", query).Errorf("unable to prepare query: %s", err.Error())
186 return nil, nil, nil, err
187 }
188
189 paramOIDs := make([]uint32, len(paramTypes))
190 for i, t := range paramTypes {

Callers

nothing calls this directly

Calls 5

GetConnFunction · 0.92
InferSchemaFunction · 0.92
QueryContextMethod · 0.80
CloseMethod · 0.65

Tested by

no test coverage detected