bytebase/bytebase · error

failed to resolve positional column reference $%s

Error message

failed to resolve positional column reference $%s

What it means

Before indexing into the positional columns, resolvePositionalRef must fetch the fields of the qualified (or unqualified) FROM table or outer CTE. If that lookup fails — e.g. no matching table for the qualifier — the underlying error is wrapped with this message.

Source

Thrown at backend/plugin/parser/snowflake/query_span_extractor.go:1403

// resolvePositionalRef resolves a positional column reference $N (optionally
// qualified, d.$1) to the N-th column of the FROM scope (or of the qualified
// relation), mirroring the legacy DOLLAR/Column_position branch: errors on a
// non-numeric, < 1, or out-of-range position.
func (q *querySpanExtractor) resolvePositionalRef(dollar *ast.DollarRef) (base.QuerySpanResult, error) {
	position, err := strconv.Atoi(dollar.Name)
	if err != nil {
		return base.QuerySpanResult{}, errors.Wrapf(err, "failed to parse column position %q to integer", dollar.Name)
	}
	if position < 1 {
		return base.QuerySpanResult{}, errors.Errorf("column position %d is invalid because it is less than 1", position)
	}
	var normalizedDatabaseName, normalizedSchemaName, normalizedTableName string
	if dollar.Qualifier != nil {
		normalizedDatabaseName, normalizedSchemaName, normalizedTableName = normalizeSnowflakeObjectName(dollar.Qualifier, "", "")
	}
	left, err := q.getAllFieldsOfTableInFromOrOuterCTE(normalizedDatabaseName, normalizedSchemaName, normalizedTableName)
	if err != nil {
		return base.QuerySpanResult{}, errors.Wrapf(err, "failed to resolve positional column reference $%s", dollar.Name)
	}
	if position > len(left) {
		return base.QuerySpanResult{}, errors.Errorf("column position $%d is invalid: the FROM clause only returns %d columns", position, len(left))
	}
	return left[position-1], nil
}

// applyStarRenames applies the `SELECT * RENAME (col AS alias, ...)` transform
// to a star expansion: the matching result columns keep their lineage but take
// the alias as their output name (Snowflake returns the renamed column).
// Matching uses normalized identifiers, like the rest of the resolver.
func applyStarRenames(columns []base.QuerySpanResult, renames []ast.StarRename) []base.QuerySpanResult {
	if len(renames) == 0 {
		return columns
	}
	aliasByColumn := make(map[string]string, len(renames))
	for _, r := range renames {
		aliasByColumn[normalizeSnowflakeIdentifier(r.Col)] = normalizeSnowflakeIdentifier(r.Alias)

View on GitHub (pinned to 1870550677)

Solutions

  1. Correct or drop the qualifier on the $n reference so it binds to an in-scope table
  2. Ensure the referenced table/CTE alias matches exactly (case after normalization)
  3. Inspect the wrapped cause ('no matching table ...') to identify which qualifier failed

Example fix

// before: SELECT o.$1 FROM orders -- alias 'o' undeclared
SELECT orders.$1 FROM orders
// after (or unqualified)
SELECT $1 FROM orders
Defensive patterns

Strategy: try-catch

Validate before calling

if qualifier != nil && !scopeHasTable(qualifier) {
  return errors.New("positional ref qualifier not in FROM scope")
}

Try / catch

res, err := extractor.ExtractQuerySpan(stmt)
var serr *SpanError
if errors.As(err, &serr) && strings.Contains(err.Error(), "failed to resolve positional column reference") {
  // fall back to unqualified $n or skip the column
}

Prevention

When it happens

Trigger: A qualified positional reference like t.$1 where table t is not in the FROM clause or outer CTE scope, producing the inner 'no matching table' error.

Common situations: Qualifying $1 with an alias that does not exist; referencing an outer CTE that is not visible at this nesting level.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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