{"record":{"id":"ccfbb355c051a9a9","repo":"vitessio/vitess","slug":"unsupported-qualifier-for-column-v","errorCode":null,"errorMessage":"unsupported qualifier for column: %v","messagePattern":"unsupported qualifier for column: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":458,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"expression needs an alias: %v\", sqlparser.String(aliased))\n\t\t}\n\t}\n\tcexpr := &colExpr{\n\t\tcolName:    as,\n\t\treferences: make(map[string]bool),\n\t}\n\tif expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok {\n\t\t// Here we find the actual column name in the convert, in case\n\t\t// this is a column rename and the AS is the new column.\n\t\t// For example, in convert(c1 using utf8mb4) as c2, we want to find\n\t\t// c1, because c1 exists in the current table whereas c2 is the renamed column\n\t\t// in the desired table.\n\t\tvar colName sqlparser.IdentifierCI\n\t\terr := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) {\n\t\t\tswitch node := node.(type) {\n\t\t\tcase *sqlparser.ColName:\n\t\t\t\tif !node.Qualifier.IsEmpty() {\n\t\t\t\t\treturn false, fmt.Errorf(\"unsupported qualifier for column: %v\", sqlparser.String(node))\n\t\t\t\t}\n\t\t\t\tcolName = node.Name\n\t\t\t}\n\t\t\treturn true, nil\n\t\t}, aliased.Expr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to find column name for convert using expression: %v, %v\", sqlparser.String(aliased.Expr), err)\n\t\t}\n\t\tselExpr := &sqlparser.ConvertUsingExpr{\n\t\t\tType: \"utf8mb4\",\n\t\t\tExpr: &sqlparser.ColName{Name: colName},\n\t\t}\n\t\tcexpr.expr = expr\n\t\tcexpr.operation = opExpr\n\t\ttpb.sendSelect.AddSelectExpr(&sqlparser.AliasedExpr{Expr: selExpr, As: as})\n\t\tcexpr.references[as.String()] = true\n\t\treturn cexpr, nil\n\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L440-L476","documentation":"When walking a CONVERT(...) USING style expression, the builder collects the single column being converted. Any column reference with a qualifier (e.g. `t.col`) is rejected because the generated plan rewrites the expression against one fixed table and qualified names would not resolve there.","triggerScenarios":"A select expression like `CONVERT(t.name USING utf8mb4)` — the inner ColName carries a table qualifier.","commonSituations":"Copy-pasted queries from application SQL that qualify columns; generated plans where the source query used aliases.","solutions":["Remove the table qualifier inside CONVERT USING: use `CONVERT(name USING utf8mb4)`","Ensure the CONVERT USING expression references exactly one unqualified column","Regenerate the filter rule after editing"],"exampleFix":"// before\nSELECT CONVERT(t.name USING utf8mb4) AS name FROM t\n// after\nSELECT CONVERT(name USING utf8mb4) AS name FROM t","handlingStrategy":"validation","validationCode":"sqlparser.Walk(func(n sqlparser.SQLNode) (bool, error) {\n    if cn, ok := n.(*sqlparser.ColName); ok && !cn.Qualifier.IsEmpty() {\n        return false, fmt.Errorf(\"qualified column %v not allowed\", sqlparser.String(cn))\n    }\n    return true, nil\n}, aliased.Expr)","typeGuard":"func unqualifiedOnly(expr sqlparser.Expr) bool {\n    err := sqlparser.Walk(func(n sqlparser.SQLNode) (bool, error) {\n        if cn, ok := n.(*sqlparser.ColName); ok && !cn.Qualifier.IsEmpty() {\n            return false, fmt.Errorf(\"qualified\")\n        }\n        return true, nil\n    }, expr)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Strip table qualifiers when authoring CONVERT USING filter expressions","Keep filter SQL single-table so qualifiers are unnecessary","Test filter rules against the plan builder in CI"],"tags":["sqlparser","vreplication","convert-using","column-qualifier"],"backgroundTag":"unsupported-column-qualifier","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}