Skip to content

Commit

Permalink
feat: add new restore flag RestoreCreateTableWithoutDefaultOption (pi…
Browse files Browse the repository at this point in the history
  • Loading branch information
rebelice authored Mar 1, 2023
1 parent b41f6f3 commit 81c8ec0
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 11 deletions.
16 changes: 16 additions & 0 deletions parser/ast/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,9 @@ func (n *CreateTableStmt) Restore(ctx *format.RestoreCtx) error {
}

for i, option := range n.Options {
if ctx.Flags.HasRestoreCreateTableWithoutDefaultOptionFlag() && option.IsDefaultOption() {
continue
}
ctx.WritePlain(" ")
if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt TableOption: [%v]", i)
Expand Down Expand Up @@ -2149,6 +2152,19 @@ type TableOption struct {
TableNames []*TableName
}

func (n *TableOption) IsDefaultOption() bool {
switch n.Tp {
case TableOptionEngine:
return n.StrValue == "InnoDB"
case TableOptionCharset:
return n.UintValue == TableOptionCharsetWithoutConvertTo && n.StrValue == "utf8mb4"
case TableOptionCollate:
return n.StrValue == "utf8mb4_general_ci"
default:
return false
}
}

func (n *TableOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case TableOptionEngine:
Expand Down
34 changes: 34 additions & 0 deletions parser/ast/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -905,3 +905,37 @@ func TestRestorePrettyFormat(t *testing.T) {
runNodeRestoreTestWithFlagsStmtChange(t, testCases, "%s", extractNodeFunc, f)
}
}

func TestRestoreCreateTableWithoutDefaultOption(t *testing.T) {
f := format.DefaultRestoreFlags | format.RestoreCreateTableWithoutDefaultOption | format.RestoreStringWithoutCharset | format.RestorePrettyFormat
cases := []struct {
sourceSQL string
expectSQL string
}{
{
sourceSQL: "CREATE TABLE t1(id BIGINT NOT NULL AUTO_INCREMENT, `schema` mediumtext NOT NULL, namespace text NOT NULL, sequence BIGINT UNSIGNED NOT NULL, created_ts BIGINT NOT NULL, PRIMARY KEY(id)," +
"UNIQUE KEY `bytebase_idx_unique_migration_history_namespace_sequence` (`namespace`(256),`sequence`),KEY `bytebase_idx_migration_history_namespace_created` (`namespace`(256),`created_ts`))" +
"ENGINE=InnoDB DEFAULT CHARACTER SET=UTF8MB4 DEFAULT COLLATE=UTF8MB4_GENERAL_CI;",
expectSQL: "CREATE TABLE `t1` (\n" +
" `id` BIGINT NOT NULL AUTO_INCREMENT,\n" +
" `schema` MEDIUMTEXT NOT NULL,\n" +
" `namespace` TEXT NOT NULL,\n" +
" `sequence` BIGINT UNSIGNED NOT NULL,\n" +
" `created_ts` BIGINT NOT NULL,\n" +
" PRIMARY KEY (`id`),\n" +
" UNIQUE `bytebase_idx_unique_migration_history_namespace_sequence` (`namespace`(256), `sequence`),\n" +
" INDEX `bytebase_idx_migration_history_namespace_created` (`namespace`(256), `created_ts`)\n" +
")",
},
}
extractNodeFunc := func(node Node) Node {
return node
}

for _, ca := range cases {
testCases := []NodeRestoreTestCase{
{ca.sourceSQL, ca.expectSQL},
}
runNodeRestoreTestWithFlagsStmtChange(t, testCases, "%s", extractNodeFunc, f)
}
}
39 changes: 28 additions & 11 deletions parser/format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,28 @@ var replace = map[rune]string{
// nest. The Formatter writes to io.Writer 'w' and inserts one 'indent'
// string per current indent level value.
// Behaviour of commands reaching negative indent levels is undefined.
// IndentFormatter(os.Stdout, "\t").Format("abc%d%%e%i\nx\ny\n%uz\n", 3)
//
// IndentFormatter(os.Stdout, "\t").Format("abc%d%%e%i\nx\ny\n%uz\n", 3)
//
// output:
// abc3%e
// x
// y
// z
//
// abc3%e
// x
// y
// z
//
// The Go quoted string literal form of the above is:
// "abc%%e\n\tx\n\tx\nz\n"
//
// "abc%%e\n\tx\n\tx\nz\n"
//
// The commands can be scattered between separate invocations of Format(),
// i.e. the formatter keeps track of the indent level and knows if it is
// positioned on start of a line and should emit indentation(s).
// The same output as above can be produced by e.g.:
// f := IndentFormatter(os.Stdout, " ")
// f.Format("abc%d%%e%i\nx\n", 3)
// f.Format("y\n%uz\n")
//
// f := IndentFormatter(os.Stdout, " ")
// f.Format("abc%d%%e%i\nx\n", 3)
// f.Format("y\n%uz\n")
func IndentFormatter(w io.Writer, indent string) Formatter {
return &indentFormatter{w, []byte(indent), 0, stBOL}
}
Expand Down Expand Up @@ -169,9 +176,12 @@ type flatFormatter indentFormatter
//
// The FlatFormatter is intended for flattening of normally nested structure textual representation to
// a one top level structure per line form.
// FlatFormatter(os.Stdout, " ").Format("abc%d%%e%i\nx\ny\n%uz\n", 3)
//
// FlatFormatter(os.Stdout, " ").Format("abc%d%%e%i\nx\ny\n%uz\n", 3)
//
// output in the form of a Go quoted string literal:
// "abc3%%e x y z\n"
//
// "abc3%%e x y z\n"
func FlatFormatter(w io.Writer) Formatter {
return (*flatFormatter)(IndentFormatter(w, "").(*indentFormatter))
}
Expand Down Expand Up @@ -228,6 +238,9 @@ const (

// RestorePrettyFormat is used to pretty print the CREATE TABLE statement and CREATE VIEW statement.
RestorePrettyFormat

// RestoreCreateTableWithoutDefaultOption is used to restore CREATE TABLE without default options.
RestoreCreateTableWithoutDefaultOption
)

const (
Expand Down Expand Up @@ -318,6 +331,10 @@ func (rf RestoreFlags) HasPrettyFormatFlag() bool {
return rf.has(RestorePrettyFormat)
}

func (rf RestoreFlags) HasRestoreCreateTableWithoutDefaultOptionFlag() bool {
return rf.has(RestoreCreateTableWithoutDefaultOption)
}

// RestoreCtx is `Restore` context to hold flags and writer.
type RestoreCtx struct {
Flags RestoreFlags
Expand Down

0 comments on commit 81c8ec0

Please sign in to comment.