vitessio/vitess · error

did not compile?

Error message

did not compile?

What it means

Panic in the arithmetic expression compiler (`compile`). After merging the compile-time types of both operands, the result `ct.Type` must have been resolved to a concrete numeric type; if it is still 0, the compiler produced no type, which the code assumes is impossible — hence `panic("did not compile?")`. It flags a hole in the arithmetic type-coercion table.

Source

Thrown at go/vt/vtgate/evalengine/expr_arithmetic.go:218

		c.asm.Sub_ff()
		ct.Type = sqltypes.Float64
	case sqltypes.Decimal:
		switch rt.Type {
		case sqltypes.Float64:
			c.compileToFloat(lt, 2)
			c.asm.Sub_ff()
			ct.Type = sqltypes.Float64
		default:
			c.compileToDecimal(rt, 1)
			c.asm.Sub_dd()
			ct.Type = sqltypes.Decimal
			ct.Size = max(lt.Size, rt.Size)
			ct.Scale = max(lt.Scale, rt.Scale)
		}
	}

	if ct.Type == 0 {
		panic("did not compile?")
	}

	c.asm.jumpDestination(skip1, skip2)
	return ct, nil
}

func (op *opArithMul) eval(left, right eval) (eval, error) {
	return multiplyNumericWithError(left, right)
}

func (op *opArithMul) String() string { return "*" }

func (op *opArithMul) compile(c *compiler, left, right IR) (ctype, error) {
	lt, err := left.compile(c)
	if err != nil {
		return ctype{}, err
	}
	skip1 := c.compileNullCheck1(lt)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Identify the operand type combination from the query and add the missing coercion rule in expr_arithmetic.go
  2. Return a clear vterrors error instead of panicking so the query fails gracefully
  3. Add a regression test for the type combination
  4. Upgrade to a Vitess release with the fix

Example fix

// before
if ct.Type == 0 {
    panic("did not compile?")
}
// after
if ct.Type == 0 {
    return ctype{}, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "arithmetic compile produced no type")
Defensive patterns

Strategy: type-guard

Validate before calling

if ct.Type == 0 {
    return ctype{}, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "arithmetic type unresolved for operands %v/%v", lt.Type, rt.Type)
}

Type guard

func isResolvedNumeric(t sqltypes.Type) bool {
    switch t {
    case sqltypes.Int8, sqltypes.Int16, sqltypes.Int24, sqltypes.Int32, sqltypes.Int64,
        sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint24, sqltypes.Uint32, sqltypes.Uint64,
        sqltypes.Float32, sqltypes.Float64, sqltypes.Decimal:
        return true
    }
    return false
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "arithmetic compile panic: %v", r)
    }
}()

Prevention

When it happens

Trigger: Compiling an arithmetic expression (+,-,*,/) whose operand types fall through the coercion logic so that no result type is assigned (ct.Type == 0).

Common situations: Seen during Vitess development when new sqltypes are added to the arithmetic matrix without a covering rule, or when a refactor drops a coercion branch. Rare on released versions; would surface as a vtgate crash on a specific query.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/b5d856489daf7ed2. Report an issue: GitHub.