{"record":{"id":"75ef9045edc18995","repo":"vitessio/vitess","slug":"failed-to-find-column-name-for-convert-using-expre","errorCode":null,"errorMessage":"failed to find column name for convert using expression: %v, %v","messagePattern":"failed to find column name for convert using expression: (.+?), (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":465,"sourceCode":"\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}\n\tif expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok {\n\t\tswitch fname := expr.Name.Lowered(); fname {\n\t\tcase \"keyspace_id\":\n\t\t\tif len(expr.Exprs) != 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported multiple keyspace_id expressions: %v\", sqlparser.String(expr))\n\t\t\t}\n","sourceCodeStart":447,"sourceCodeEnd":483,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L447-L483","documentation":"For a ConvertUsingExpr, the builder walks the expression to find exactly one inner column name. If the walk returns an error (no column found, or the walk aborted on a qualifier error from the ColName case), the builder wraps it into this error because it cannot construct the rewritten CONVERT expression.","triggerScenarios":"`CONVERT USING` expression whose inner expression is not a simple column (e.g. a literal, function call, or qualified name that aborted the walk).","commonSituations":"Charset-conversion filter rules written against literals or complex expressions instead of a single column.","solutions":["Make the CONVERT USING operand a single unqualified column name","Validate the expression parses as CONVERT(col USING utf8mb4) before applying the rule","Fall back to replicating the raw column and converting downstream"],"exampleFix":"// before\nSELECT CONVERT('literal' USING utf8mb4) AS c FROM t\n// after\nSELECT CONVERT(col USING utf8mb4) AS c FROM t","handlingStrategy":"type-guard","validationCode":"cu, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr)\nif !ok { return nil }\nif _, ok := cu.Expr.(*sqlparser.ColName); !ok {\n    return errors.New(\"CONVERT USING operand must be a single column\")\n}","typeGuard":"func isConvertUsingSingleCol(expr sqlparser.Expr) (*sqlparser.ColName, bool) {\n    cu, ok := expr.(*sqlparser.ConvertUsingExpr)\n    if !ok { return nil, false }\n    col, ok := cu.Expr.(*sqlparser.ColName)\n    if !ok || !col.Qualifier.IsEmpty() { return nil, false }\n    return col, true\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"convert using expression\") {\n    log.Warn(\"CONVERT USING must wrap one unqualified column; rewriting rule\")\n}","preventionTips":["Only write CONVERT(col USING charset) forms in filters","Validate filter SQL with sqlparser before applying","Avoid literals/functions inside CONVERT USING for replication rules"],"tags":["sqlparser","vreplication","convert-using","plan-builder"],"backgroundTag":"unsupported-sql-construct","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}