vitessio/vitess · error

expected a CREATE TABLE statement

Error message

expected a CREATE TABLE statement

What it means

ErrExpectedCreateTable is returned when code requires a CREATE TABLE statement but receives a different statement type. Shared by DiffCreateTablesQueries, NewCreateTableEntityFromSQL, NewCreateViewEntityFromSQL, and getCreateTableStatement when statement-type expectations are violated.

Source

Thrown at go/vt/schemadiff/errors.go:33

*/

package schemadiff

import (
	"errors"
	"fmt"
	"strings"

	"vitess.io/vitess/go/sqlescape"
	"vitess.io/vitess/go/vt/sqlparser"
)

var (
	ErrEntityTypeMismatch             = errors.New("mismatched entity type")
	ErrStrictIndexOrderingUnsupported = errors.New("strict index ordering is unsupported")
	ErrUnexpectedDiffAction           = errors.New("unexpected diff action")
	ErrUnexpectedTableSpec            = errors.New("unexpected table spec")
	ErrExpectedCreateTable            = errors.New("expected a CREATE TABLE statement")
	ErrExpectedCreateView             = errors.New("expected a CREATE VIEW statement")
)

type ImpossibleApplyDiffOrderError struct {
	UnorderedDiffs   []EntityDiff
	ConflictingDiffs []EntityDiff
}

func (e *ImpossibleApplyDiffOrderError) Error() string {
	var b strings.Builder
	conflictingStatements := e.ConflictingStatements()
	fmt.Fprintf(&b, "no valid applicable order for diffs. %d diffs found conflicting:", len(conflictingStatements))
	for _, s := range conflictingStatements {
		b.WriteString("\n")
		b.WriteString(s)
	}
	return b.String()
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass only CREATE TABLE statements to table-entity APIs
  2. Use NewCreateViewEntityFromSQL / DiffCreateViewsQueries for view statements
  3. Verify the SQL being loaded actually parses as CREATE TABLE before calling schemadiff

Example fix

// before
entity, err := schemadiff.NewCreateTableEntityFromSQL("CREATE VIEW v1 AS SELECT 1") // expected a CREATE TABLE statement
// after
entity, err := schemadiff.NewCreateViewEntityFromSQL("CREATE VIEW v1 AS SELECT 1")
Defensive patterns

Strategy: type-guard

Validate before calling

stmt, err := sqlparser.Parse(ddl)
if _, ok := stmt.(*sqlparser.CreateTable); !ok {
	return fmt.Errorf("not a CREATE TABLE: %T", stmt)
}

Type guard

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

Try / catch

if err != nil {
	if errors.Is(err, schemadiff.ErrExpectedCreateTable) {
		// route to view handling or reject input
	}
}

Prevention

When it happens

Trigger: Passing a CREATE VIEW / ALTER / non-DDL statement to NewCreateTableEntityFromSQL or getCreateTableStatement; DiffCreateTablesQueries receiving entity diffs whose statements are not CREATE TABLE.

Common situations: Mixing table and view DDL files when loading a keyspace schema; off-by-one slicing of SQL files that concatenates statements incorrectly.

Related errors


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