bytebase/bytebase · error

column alias count %d does not match column count %d

Error message

column alias count %d does not match column count %d

What it means

applyColumnAliases applies an explicit column alias list (e.g. the parenthesized list after a derived table, VALUES table, subquery, or table-valued function) positionally. If the alias list length differs from the number of columns the table expression produced, it errors because aliases would map onto the wrong columns.

Source

Thrown at backend/plugin/parser/tsql/query_span_extractor_omni.go:906

		Name:    sel.IntoTable.Object,
		Columns: columns,
	}
}

func xmlNodesColumns(cols []string) []base.QuerySpanResult {
	out := make([]base.QuerySpanResult, 0, len(cols))
	for _, c := range cols {
		out = append(out, base.QuerySpanResult{Name: c})
	}
	return out
}

func applyColumnAliases(cols []base.QuerySpanResult, aliases []string) error {
	if len(aliases) == 0 {
		return nil
	}
	if len(aliases) != len(cols) {
		return errors.Errorf("column alias count %d does not match column count %d", len(aliases), len(cols))
	}
	for i, name := range aliases {
		cols[i].Name = normIdent(name)
	}
	return nil
}

func (q *omniQuerySpanExtractor) cloneForSubquery() *omniQuerySpanExtractor {
	clone := &omniQuerySpanExtractor{
		querySpanExtractor: &querySpanExtractor{
			ctx:                 q.ctx,
			defaultDatabase:     q.defaultDatabase,
			defaultSchema:       q.defaultSchema,
			ignoreCaseSensitive: q.ignoreCaseSensitive,
			gCtx:                q.gCtx,
			ctes:                append([]*base.PseudoTable{}, q.ctes...),
			outerTableSources:   append(append([]base.TableSource{}, q.outerTableSources...), q.tableSourcesFrom...),
			predicateColumns:    make(base.SourceColumnSet),

View on GitHub (pinned to 1870550677)

Solutions

  1. Provide exactly one alias per column of the inner expression
  2. Alias columns inline in the inner SELECT and drop the outer alias list
  3. Check the table-valued function's actual return columns and update the alias list

Example fix

// before
FROM (SELECT a, b FROM t) dt(x)
// after
FROM (SELECT a, b FROM t) dt(x, y)
Defensive patterns

Strategy: validation

Validate before calling

// Validate derived-table alias count before extraction:
func checkAliasCount(aliases []string, colCount int) error {
	if len(aliases) != 0 && len(aliases) != colCount {
		return fmt.Errorf("%d aliases for %d columns", len(aliases), colCount)
	}
	return nil
}

Prevention

When it happens

Trigger: FROM (SELECT a, b FROM t) dt(x) — one alias for two columns; or FROM fn() f(a, b, c) where fn returns two columns; or FROM (VALUES ...) v(a, b) with mismatched arity.

Common situations: SQL edited so the inner SELECT list changed without updating the derived table's alias list; generated SQL templates with fixed alias headers and dynamic inner queries.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/c582057b8d1b4aa4. Report an issue: GitHub.