(ctx *sql.Context, n sql.Node, conn *stdsql.Conn)
| 219 | // isStandaloneVectorConversion routes SELECT STRING_TO_VECTOR(...) without a |
| 220 | // data table through DuckDB's guarded UDF. The selected GMS version panics when |
| 221 | // its own scalar evaluator encodes an empty vector. |
| 222 | func isStandaloneVectorConversion(ctx *sql.Context, n sql.Node) bool { |
| 223 | c := &tableAndFuncCollector{ctx: ctx} |
| 224 | transform.Walk(c, n) |
| 225 | |
| 226 | for _, table := range c.tables { |
| 227 | if !plan.IsDualTable(table.UnderlyingTable()) { |
| 228 | return false |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | found := false |
| 233 | for _, fn := range c.functions { |
| 234 | if _, ok := fn.(*vectorfn.StringToVector); !ok { |
| 235 | return false |
| 236 | } |
| 237 | found = true |
| 238 | } |
| 239 | return found |
| 240 | } |
| 241 | |
| 242 | func (b *DuckBuilder) executeExpressioner(ctx *sql.Context, n sql.Expressioner, conn *stdsql.Conn) (sql.RowIter, error) { |
| 243 | node := n.(sql.Node) |
| 244 | switch n := n.(type) { |
| 245 | case *plan.InsertInto: |
| 246 | if n.Returning != nil { |
| 247 | return b.executeQuery(ctx, node, conn) |
| 248 | } |
| 249 | return b.executeDML(ctx, node, conn) |
| 250 | case *plan.Update: |
| 251 | if n.Returning == nil { |
| 252 | n.Child = withMySQLOkResultSchema(n.Child) |
| 253 | } |
| 254 | return b.executeDML(ctx, node, conn) |
| 255 | default: |
| 256 | return b.executeQuery(ctx, node, conn) |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | func (b *DuckBuilder) executeQuery(ctx *sql.Context, n sql.Node, conn *stdsql.Conn) (sql.RowIter, error) { |
| 261 | ctx.GetLogger().Trace("Executing Query...") |
| 262 | |
| 263 | var ( |
| 264 | duckSQL string |
| 265 | err error |
| 266 | ) |
| 267 | |
| 268 | // Translate the MySQL query to a DuckDB query |
| 269 | switch n := n.(type) { |
| 270 | case *plan.ShowTables: |
| 271 | duckSQL = ctx.Query() |
| 272 | case *plan.ResolvedTable: |
no test coverage detected