bytebase/bytebase · error
left and right query span result length mismatch: %d != %d
Error message
left and right query span result length mismatch: %d != %d
What it means
Set operations (UNION, INTERSECT, MINUS) require both branches to yield the same number of output columns; mergeOmniSetTableSources throws when the left and right QuerySpanResult lists differ in length. This mirrors Oracle's ORA-01789 class of errors at the lineage-analysis level.
Source
Thrown at backend/plugin/parser/plsql/query_span_extractor_omni.go:364
}
right, err := q.extractOmniSelect(stmt.Rarg)
if err != nil {
return nil, err
}
return mergeOmniSetTableSources(left, right)
}
func mergeOmniSetTableSources(left, right base.TableSource) (base.TableSource, error) {
if left == nil {
return right, nil
}
if right == nil {
return left, nil
}
leftResults := left.GetQuerySpanResult()
rightResults := right.GetQuerySpanResult()
if len(leftResults) != len(rightResults) {
return nil, errors.Errorf("left and right query span result length mismatch: %d != %d", len(leftResults), len(rightResults))
}
result := make([]base.QuerySpanResult, 0, len(leftResults))
for i, leftResult := range leftResults {
sourceColumns, _ := base.MergeSourceColumnSet(leftResult.SourceColumns, rightResults[i].SourceColumns)
result = append(result, base.QuerySpanResult{
Name: leftResult.Name,
SourceColumns: sourceColumns,
IsPlainField: false,
})
}
return &base.PseudoTable{Columns: result}, nil
}
func (q *omniQuerySpanExtractor) extractOmniCTE(cte *oracleast.CTE) (*base.PseudoTable, error) {
if cte == nil {
return nil, nil
}
name := cte.NameView on GitHub (pinned to 1870550677)
Solutions
- Fix the SQL so both set-operation branches select the same number of columns
- Replace SELECT * in union branches with explicit, aligned column lists
- Re-check the referenced table schemas — a recent column addition may have desynchronized the branches
- If analysis-side, validate branch arity before merging and emit a user-facing SQL error instead of an internal one
Example fix
// before SELECT id, name FROM a UNION SELECT id FROM b // after SELECT id, name FROM a UNION SELECT id, name FROM b
Defensive patterns
Strategy: validation
Validate before calling
if len(leftResults) != len(rightResults) { return errors.New("union branches must have equal column counts") } Try / catch
src, err := extractor.GetQuerySpan(ctx, sql)
if err != nil && strings.Contains(err.Error(), "result length mismatch") {
return nil, fmt.Errorf("set-operation branches differ in column count: %w", err)
} Prevention
- Use explicit column lists in UNION/INTERSECT/MINUS branches
- Re-verify union arity after any referenced-table schema change
- Add a pre-flight query linter that checks set-operation column counts
When it happens
Trigger: extractOmniSetSelect or extractOmniCTE analyzing a UNION/UNION ALL/INTERSECT/MINUS whose left and right SELECT lists have different column counts — often after * expansion resolves to different widths on each side.
Common situations: Hand-written UNION queries with mismatched SELECT lists; SELECT * on tables whose schemas diverged (column added to one table only); dynamically generated SQL assembling branches independently.
Related errors
- MySQL UNION operator left has %d fields, right has %d fields
- no parse results
- no DML statement found in extracted SQL
- MySQL CTE column list should have the same length, but got %
- failed to prepare transformation
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/424940bc6ff2a718.
Report an issue: GitHub.