vitessio/vitess · error
failed to find column name for convert using expression: %v,
Error message
failed to find column name for convert using expression: %v, %v
What it means
When processing a convert_tz expression, analyzeExpr walks the expression tree to discover which column it applies to; if the walk returns an error (typically the 'unsupported qualifier for column' error above), this message wraps it, and if no column is found, findColumn also fails into this wrapper, reporting the full expression and the underlying error.
Source
Thrown at go/vt/vttablet/tabletserver/vstreamer/planbuilder.go:939
case *sqlparser.ConvertUsingExpr:
// Here we find the actual column name in the convert, in case
// this is a column rename and the AS is the new column.
// For example, in convert(c1 using utf8mb4) as c2, we want to find
// c1, because c1 exists in the current table whereas c2 is the renamed column
// in the desired table.
var colName sqlparser.IdentifierCI
err := sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) {
switch node := node.(type) {
case *sqlparser.ColName:
if !node.Qualifier.IsEmpty() {
return false, fmt.Errorf("unsupported qualifier for column: %v", sqlparser.String(node))
}
colName = node.Name
}
return true, nil
}, aliased.Expr)
if err != nil {
return ColExpr{}, fmt.Errorf("failed to find column name for convert using expression: %v, %v", sqlparser.String(aliased.Expr), err)
}
colnum, err := findColumn(plan.Table, colName)
if err != nil {
return ColExpr{}, err
}
field := plan.Table.Fields[colnum]
plan.setConvertColumnUsingUTF8(field.Name)
return ColExpr{
ColNum: colnum,
Field: field,
}, nil
default:
log.Info(fmt.Sprintf("Unsupported expression: %v", inner))
return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(aliased.Expr))
}
}
// analyzeInKeyRange allows the following constructs: "in_keyrange('-80')",View on GitHub (pinned to 01a25a7d17)
Solutions
- Use an unqualified column inside convert_tz: convert_tz(ts, '%s', ...) as ts.
- Alias the expression (as <column_name>) so findColumn can locate it in the table's fields.
- Verify the aliased name matches a real column of the streamed table.
Example fix
// before select convert_tz(t.ts, '+00:00', '+05:30') as ts from t // after select convert_tz(ts, '+00:00', '+05:30') as ts from t
Defensive patterns
Strategy: validation
Validate before calling
// ensure convert_tz args contain an unqualified column and the expr is aliased to a real column
if !strings.Contains(expr, "convert_tz") {
return nil
}
if hasQualifier(expr) {
return fmt.Errorf("convert_tz must reference an unqualified column: %s", expr)
}
if aliasedTo, ok := aliasOf(expr); !ok || !columnExists(table, aliasedTo) {
return fmt.Errorf("convert_tz expression must be aliased to an existing column")
} Type guard
func isAliasedConvertTz(expr string) (string, bool) {
parts := strings.Split(expr, " as ")
if len(parts) == 2 && strings.Contains(parts[0], "convert_tz") {
return strings.TrimSpace(parts[1]), true
}
return "", false
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to find column name for convert using expression") {
return fmt.Errorf("make convert_tz reference an unqualified, aliased column: %w", err)
} Prevention
- Alias convert_tz expressions to the target column name
- Use unqualified columns inside convert_tz
- Verify the alias matches an actual field of the streamed table
When it happens
Trigger: A convert_tz(...) select expression whose inner column reference is qualified (e.g. convert_tz(t.ts, ...) as ts) so the walk errors before assigning colName.
Common situations: Qualified columns inside convert_tz in vstream selects; copy-pasted queries with table qualifiers into a vstreamer-based conversion flow.
Related errors
- unsupported function: %v
- VStreamer is not open
- only integer literals are supported
- only the integer literal 1 is supported
- VStreamer is not open
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/145fd24bcd6f96e4.
Report an issue: GitHub.