vitessio/vitess · error

error parsing vschema statement `%s`: not a ddl statement

Error message

error parsing vschema statement `%s`: not a ddl statement

What it means

The statement parsed successfully but is not an *sqlparser.AlterVschema node, so ApplyVSchemaDDL cannot process it. Only `ALTER VSCHEMA ...` statements are valid for this command path. This guards the type-asserted DDL before mutating the keyspace VSchema.

Source

Thrown at go/vt/vtctl/vtctl.go:3379

		return errors.New("one of the --sql, --sql_file, --vschema, or --vschema_file flags must be specified when calling the ApplyVSchema command")
	}

	if sqlMode {
		if *sqlFile != "" {
			sqlBytes, err := os.ReadFile(*sqlFile)
			if err != nil {
				return err
			}
			*sql = string(sqlBytes)
		}

		stmt, err := wr.SQLParser().Parse(*sql)
		if err != nil {
			return fmt.Errorf("error parsing vschema statement `%s`: %v", *sql, err)
		}
		ddl, ok := stmt.(*sqlparser.AlterVschema)
		if !ok {
			return fmt.Errorf("error parsing vschema statement `%s`: not a ddl statement", *sql)
		}

		ksvs, err = topotools.ApplyVSchemaDDL(ctx, keyspace, wr.TopoServer(), ddl)
		if err != nil {
			return err
		}
	} else {
		// json mode
		var schema []byte
		if *vschemaFile != "" {
			var err error
			schema, err = os.ReadFile(*vschemaFile)
			if err != nil {
				return err
			}
		} else {
			schema = []byte(*vschema)
		}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Rewrite the statement to start with `ALTER VSCHEMA`
  2. Convert legacy `CREATE VINDEX`/`ADD VINDEX` statements to the `ALTER VSCHEMA ADD VINDEX` form
  3. Use the JSON vschema format via the topo directly if you need non-DDL updates

Example fix

// before
sql := `CREATE VINDEX hash USING hash WITH num_buckets=8`
// after
sql := `ALTER VSCHEMA ADD VINDEX hash USING hash WITH num_buckets=8`
Defensive patterns

Strategy: type-guard

Validate before calling

stmt, err := sqlparser.Parse(sql)
if err != nil { return err }
if _, ok := stmt.(*sqlparser.AlterVschema); !ok {
	return errors.New("statement must be ALTER VSCHEMA ...")
}

Type guard

func isAlterVschema(stmt sqlparser.Statement) bool {
	_, ok := stmt.(*sqlparser.AlterVschema)
	return ok
}

Try / catch

if err := applyVSchema(sql); err != nil {
	if strings.HasSuffix(err.Error(), "not a ddl statement") {
		return fmt.Errorf("rewrite %q as ALTER VSCHEMA ...", sql)
	}
	return err
}

Prevention

When it happens

Trigger: Passing a valid SQL statement that is not `ALTER VSCHEMA` (e.g. `CREATE TABLE`, `SELECT`, or `ALTER KEYSPACE`) to a vschema update command.

Common situations: Copy-pasting normal MySQL DDL into the vschema editor; using `CREATE VINDEX` syntax from older Vitess instead of the current `ALTER VSCHEMA ADD VINDEX` form.

Related errors


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