Repository: cloudspannerecosystem/memefish
Pull request #234 (2024-12-19 03:06:41)

Pretty print only CREATE TABLE
This PR changes `(*CreateTable).SQL()`(and `(*Cluster).SQL() and `(*CreateRowDeletionPolicy).SQL()``) to pretty print style.

Input( `testdata/input/ddl/create_table_for_format_test.sql`)

```sql

create table if not exists foo (
    foo int64,
    bar float64 not null,
    baz string(255) not null options(allow_commit_timestamp = null),
    qux string(255) not null as (concat(baz, "a")) stored,
    foreign key (foo) references t2 (t2key1),
    constraint fkname foreign key (foo, bar) references t2 (t2key1, t2key2),
    check (foo > 0),
    constraint cname check (bar > 0),
    corge timestamp not null default (current_timestamp())
) primary key (foo),
  interleave in parent foobar,
  row deletion policy ( older_than ( baz, INTERVAL 30 DAY ) )
```

Parse-Unparsed 

```sql
CREATE TABLE IF NOT EXISTS foo (
    foo INT64,
    bar FLOAT64 NOT NULL,
    baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null),
    qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED,
    corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()),
    FOREIGN KEY (foo) REFERENCES t2 (t2key1),
    CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2),
    CHECK (foo > 0),
    CONSTRAINT cname CHECK (bar > 0)
) PRIMARY KEY (foo),
INTERLEAVE IN PARENT foobar,
ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
```

Related issues

- part of #233


Patch:
diff --git a/ast/sql.go b/ast/sql.go
index 19fc07e..2a3fb4a 100644
--- a/ast/sql.go
+++ b/ast/sql.go
@@ -7,6 +7,14 @@ import (
 	"github.com/cloudspannerecosystem/memefish/token"
 )
 
+// indentLevel is the whitespace indentation level.
+// Currently, memefish does not perform pretty printing in general, it is only used by CreateTable.
+const indentLevel = 4
+
+// indent is a whitespace indentation of indentLevel width.
+// You should use this rather than using indentLevel directly.
+var indent = strings.Repeat(" ", indentLevel)
+
 // ================================================================================
 //
 // Helper functions for SQL()
@@ -748,11 +756,11 @@ func (d *DropProtoBundle) SQL() string { return "DROP PROTO BUNDLE" }
 func (c *CreateTable) SQL() string {
 	return "CREATE TABLE " +
 		strOpt(c.IfNotExists, "IF NOT EXISTS ") +
-		c.Name.SQL() + " (" +
-		sqlJoin(c.Columns, ", ") + strOpt(len(c.Columns) > 0 && (len(c.TableConstraints) > 0 || len(c.Synonyms) > 0), ", ") +
-		sqlJoin(c.TableConstraints, ", ") + strOpt(len(c.TableConstraints) > 0 && len(c.Synonyms) > 0, ", ") +
-		sqlJoin(c.Synonyms, ", ") +
-		") PRIMARY KEY (" + sqlJoin(c.PrimaryKeys, ", ") + ")" +
+		c.Name.SQL() + " (\n" +
+		indent + sqlJoin(c.Columns, ",\n"+indent) + strOpt(len(c.Columns) > 0 && (len(c.TableConstraints) > 0 || len(c.Synonyms) > 0), ",\n") +
+		strOpt(len(c.TableConstraints) > 0, indent) + sqlJoin(c.TableConstraints, ",\n"+indent) + strOpt(len(c.TableConstraints) > 0 && len(c.Synonyms) > 0, ",\n") +
+		strOpt(len(c.Synonyms) > 0, indent) + sqlJoin(c.Synonyms, ",\n") +
+		"\n) PRIMARY KEY (" + sqlJoin(c.PrimaryKeys, ", ") + ")" +
 		sqlOpt("", c.Cluster, "") +
 		sqlOpt("", c.RowDeletionPolicy, "")
 }
@@ -812,12 +820,12 @@ func (i *IndexKey) SQL() string {
 }
 
 func (c *Cluster) SQL() string {
-	return ", INTERLEAVE IN PARENT " + c.TableName.SQL() +
+	return ",\nINTERLEAVE IN PARENT " + c.TableName.SQL() +
 		strOpt(c.OnDelete != "", " "+string(c.OnDelete))
 }
 
 func (c *CreateRowDeletionPolicy) SQL() string {
-	return ", " + c.RowDeletionPolicy.SQL()
+	return ",\n" + c.RowDeletionPolicy.SQL()
 }
 
 func (r *RowDeletionPolicy) SQL() string {


Test patch:
diff --git a/parse_helpers_test.go b/parse_helpers_test.go
index 12291b9..90a6abb 100644
--- a/parse_helpers_test.go
+++ b/parse_helpers_test.go
@@ -2,7 +2,9 @@ package memefish_test
 
 import (
 	"fmt"
+
 	"github.com/MakeNowJust/heredoc/v2"
+
 	"github.com/cloudspannerecosystem/memefish"
 )
 
@@ -84,7 +86,10 @@ func ExampleParseDDL() {
 	fmt.Println(ddl.SQL())
 
 	// Output:
-	// CREATE TABLE foo (x INT64, y INT64) PRIMARY KEY (x)
+	// CREATE TABLE foo (
+	//     x INT64,
+	//     y INT64
+	// ) PRIMARY KEY (x)
 }
 
 func ExampleParseDDLs() {
@@ -108,8 +113,15 @@ func ExampleParseDDLs() {
 	}
 
 	// Output:
-	// CREATE TABLE foo (x INT64, y INT64) PRIMARY KEY (x);
-	// CREATE TABLE bar (x INT64, z INT64) PRIMARY KEY (x, z), INTERLEAVE IN PARENT foo;
+	// CREATE TABLE foo (
+	//     x INT64,
+	//     y INT64
+	// ) PRIMARY KEY (x);
+	// CREATE TABLE bar (
+	//     x INT64,
+	//     z INT64
+	// ) PRIMARY KEY (x, z),
+	// INTERLEAVE IN PARENT foo;
 }
 
 func ExampleParseDML() {
diff --git a/testdata/input/ddl/create_table_for_format_test.sql b/testdata/input/ddl/create_table_for_format_test.sql
new file mode 100644
index 0000000..f6364c8
--- /dev/null
+++ b/testdata/input/ddl/create_table_for_format_test.sql
@@ -0,0 +1,13 @@
+create table if not exists foo (
+    foo int64,
+    bar float64 not null,
+    baz string(255) not null options(allow_commit_timestamp = null),
+    qux string(255) not null as (concat(baz, "a")) stored,
+    foreign key (foo) references t2 (t2key1),
+    constraint fkname foreign key (foo, bar) references t2 (t2key1, t2key2),
+    check (foo > 0),
+    constraint cname check (bar > 0),
+    corge timestamp not null default (current_timestamp())
+) primary key (foo),
+  interleave in parent foobar,
+  row deletion policy ( older_than ( baz, INTERVAL 30 DAY ) )
diff --git a/testdata/result/ddl/create_table.sql.txt b/testdata/result/ddl/create_table.sql.txt
index f3d84cd..5908b4d 100644
--- a/testdata/result/ddl/create_table.sql.txt
+++ b/testdata/result/ddl/create_table.sql.txt
@@ -392,4 +392,17 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar FLOAT64 NOT NULL, baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null), qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED, quux JSON, corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()), FOREIGN KEY (foo) REFERENCES t2 (t2key1), FOREIGN KEY (bar) REFERENCES t2 (t2key2) ON DELETE CASCADE, FOREIGN KEY (baz) REFERENCES t2 (t2key3) ON DELETE NO ACTION, CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2), CHECK (foo > 0), CONSTRAINT cname CHECK (bar > 0)) PRIMARY KEY (foo, bar)
+CREATE TABLE foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL,
+    baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null),
+    qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED,
+    quux JSON,
+    corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()),
+    FOREIGN KEY (foo) REFERENCES t2 (t2key1),
+    FOREIGN KEY (bar) REFERENCES t2 (t2key2) ON DELETE CASCADE,
+    FOREIGN KEY (baz) REFERENCES t2 (t2key3) ON DELETE NO ACTION,
+    CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2),
+    CHECK (foo > 0),
+    CONSTRAINT cname CHECK (bar > 0)
+) PRIMARY KEY (foo, bar)
diff --git a/testdata/result/ddl/create_table_cluster.sql.txt b/testdata/result/ddl/create_table_cluster.sql.txt
index bacaadc..1563ab4 100644
--- a/testdata/result/ddl/create_table_cluster.sql.txt
+++ b/testdata/result/ddl/create_table_cluster.sql.txt
@@ -61,4 +61,8 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64) PRIMARY KEY (), INTERLEAVE IN PARENT foobar
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64
+) PRIMARY KEY (),
+INTERLEAVE IN PARENT foobar
diff --git a/testdata/result/ddl/create_table_cluster_and_row_deletion_policy.sql.txt b/testdata/result/ddl/create_table_cluster_and_row_deletion_policy.sql.txt
index 0f37325..b89f742 100644
--- a/testdata/result/ddl/create_table_cluster_and_row_deletion_policy.sql.txt
+++ b/testdata/result/ddl/create_table_cluster_and_row_deletion_policy.sql.txt
@@ -94,4 +94,10 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64, baz TIMESTAMP) PRIMARY KEY (), INTERLEAVE IN PARENT foobar, ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64,
+    baz TIMESTAMP
+) PRIMARY KEY (),
+INTERLEAVE IN PARENT foobar,
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/ddl/create_table_cluster_on_delete_no_action.sql.txt b/testdata/result/ddl/create_table_cluster_on_delete_no_action.sql.txt
index 393b098..76894d0 100644
--- a/testdata/result/ddl/create_table_cluster_on_delete_no_action.sql.txt
+++ b/testdata/result/ddl/create_table_cluster_on_delete_no_action.sql.txt
@@ -58,4 +58,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64) PRIMARY KEY (foo), INTERLEAVE IN PARENT foobar ON DELETE NO ACTION
+CREATE TABLE foo (
+    foo INT64
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar ON DELETE NO ACTION
diff --git a/testdata/result/ddl/create_table_cluster_set_on_delete.sql.txt b/testdata/result/ddl/create_table_cluster_set_on_delete.sql.txt
index 8f8605c..4c8d811 100644
--- a/testdata/result/ddl/create_table_cluster_set_on_delete.sql.txt
+++ b/testdata/result/ddl/create_table_cluster_set_on_delete.sql.txt
@@ -58,4 +58,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64) PRIMARY KEY (foo), INTERLEAVE IN PARENT foobar ON DELETE CASCADE
+CREATE TABLE foo (
+    foo INT64
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar ON DELETE CASCADE
diff --git a/testdata/result/ddl/create_table_for_format_test.sql.txt b/testdata/result/ddl/create_table_for_format_test.sql.txt
new file mode 100644
index 0000000..2900c38
--- /dev/null
+++ b/testdata/result/ddl/create_table_for_format_test.sql.txt
@@ -0,0 +1,353 @@
+--- create_table_for_format_test.sql
+create table if not exists foo (
+    foo int64,
+    bar float64 not null,
+    baz string(255) not null options(allow_commit_timestamp = null),
+    qux string(255) not null as (concat(baz, "a")) stored,
+    foreign key (foo) references t2 (t2key1),
+    constraint fkname foreign key (foo, bar) references t2 (t2key1, t2key2),
+    check (foo > 0),
+    constraint cname check (bar > 0),
+    corge timestamp not null default (current_timestamp())
+) primary key (foo),
+  interleave in parent foobar,
+  row deletion policy ( older_than ( baz, INTERVAL 30 DAY ) )
+
+--- AST
+&ast.CreateTable{
+  Rparen:      461,
+  IfNotExists: true,
+  Name:        &ast.Path{
+    Idents: []*ast.Ident{
+      &ast.Ident{
+        NamePos: 27,
+        NameEnd: 30,
+        Name:    "foo",
+      },
+    },
+  },
+  Columns: []*ast.ColumnDef{
+    &ast.ColumnDef{
+      Null: -1,
+      Name: &ast.Ident{
+        NamePos: 37,
+        NameEnd: 40,
+        Name:    "foo",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 41,
+        Name:    "INT64",
+      },
+      Hidden: -1,
+    },
+    &ast.ColumnDef{
+      Null: 68,
+      Name: &ast.Ident{
+        NamePos: 52,
+        NameEnd: 55,
+        Name:    "bar",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 56,
+        Name:    "FLOAT64",
+      },
+      NotNull: true,
+      Hidden:  -1,
+    },
+    &ast.ColumnDef{
+      Null: 98,
+      Name: &ast.Ident{
+        NamePos: 78,
+        NameEnd: 81,
+        Name:    "baz",
+      },
+      Type: &ast.SizedSchemaType{
+        NamePos: 82,
+        Rparen:  92,
+        Name:    "STRING",
+        Size:    &ast.IntLiteral{
+          ValuePos: 89,
+          ValueEnd: 92,
+          Base:     10,
+          Value:    "255",
+        },
+      },
+      NotNull: true,
+      Hidden:  -1,
+      Options: &ast.Options{
+        Options: 103,
+        Rparen:  140,
+        Records: []*ast.OptionsDef{
+          &ast.OptionsDef{
+            Name: &ast.Ident{
+              NamePos: 111,
+              NameEnd: 133,
+              Name:    "allow_commit_timestamp",
+            },
+            Value: &ast.NullLiteral{
+              Null: 136,
+            },
+          },
+        },
+      },
+    },
+    &ast.ColumnDef{
+      Null: 167,
+      Name: &ast.Ident{
+        NamePos: 147,
+        NameEnd: 150,
+        Name:    "qux",
+      },
+      Type: &ast.SizedSchemaType{
+        NamePos: 151,
+        Rparen:  161,
+        Name:    "STRING",
+        Size:    &ast.IntLiteral{
+          ValuePos: 158,
+          ValueEnd: 161,
+          Base:     10,
+          Value:    "255",
+        },
+      },
+      NotNull:       true,
+      GeneratedExpr: &ast.GeneratedColumnExpr{
+        As:     172,
+        Stored: 194,
+        Rparen: 192,
+        Expr:   &ast.CallExpr{
+          Rparen: 191,
+          Func:   &ast.Ident{
+            NamePos: 176,
+            NameEnd: 182,
+            Name:    "concat",
+          },
+          Args: []ast.Arg{
+            &ast.ExprArg{
+              Expr: &ast.Ident{
+                NamePos: 183,
+                NameEnd: 186,
+                Name:    "baz",
+              },
+            },
+            &ast.ExprArg{
+              Expr: &ast.StringLiteral{
+                ValuePos: 188,
+                ValueEnd: 191,
+                Value:    "a",
+              },
+            },
+          },
+        },
+      },
+      Hidden: -1,
+    },
+    &ast.ColumnDef{
+      Null: 408,
+      Name: &ast.Ident{
+        NamePos: 388,
+        NameEnd: 393,
+        Name:    "corge",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 394,
+        Name:    "TIMESTAMP",
+      },
+      NotNull:     true,
+      DefaultExpr: &ast.ColumnDefaultExpr{
+        Default: 413,
+        Rparen:  441,
+        Expr:    &ast.CallExpr{
+          Rparen: 440,
+          Func:   &ast.Ident{
+            NamePos: 422,
+            NameEnd: 439,
+            Name:    "current_timestamp",
+          },
+        },
+      },
+      Hidden: -1,
+    },
+  },
+  TableConstraints: []*ast.TableConstraint{
+    &ast.TableConstraint{
+      ConstraintPos: -1,
+      Constraint:    &ast.ForeignKey{
+        Foreign:     206,
+        Rparen:      245,
+        OnDeleteEnd: -1,
+        Columns:     []*ast.Ident{
+          &ast.Ident{
+            NamePos: 219,
+            NameEnd: 222,
+            Name:    "foo",
+          },
+        },
+        ReferenceTable: &ast.Path{
+          Idents: []*ast.Ident{
+            &ast.Ident{
+              NamePos: 235,
+              NameEnd: 237,
+              Name:    "t2",
+            },
+          },
+        },
+        ReferenceColumns: []*ast.Ident{
+          &ast.Ident{
+            NamePos: 239,
+            NameEnd: 245,
+            Name:    "t2key1",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: 252,
+      Name:          &ast.Ident{
+        NamePos: 263,
+        NameEnd: 269,
+        Name:    "fkname",
+      },
+      Constraint: &ast.ForeignKey{
+        Foreign:     270,
+        Rparen:      322,
+        OnDeleteEnd: -1,
+        Columns:     []*ast.Ident{
+          &ast.Ident{
+            NamePos: 283,
+            NameEnd: 286,
+            Name:    "foo",
+          },
+          &ast.Ident{
+            NamePos: 288,
+            NameEnd: 291,
+            Name:    "bar",
+          },
+        },
+        ReferenceTable: &ast.Path{
+          Idents: []*ast.Ident{
+            &ast.Ident{
+              NamePos: 304,
+              NameEnd: 306,
+              Name:    "t2",
+            },
+          },
+        },
+        ReferenceColumns: []*ast.Ident{
+          &ast.Ident{
+            NamePos: 308,
+            NameEnd: 314,
+            Name:    "t2key1",
+          },
+          &ast.Ident{
+            NamePos: 316,
+            NameEnd: 322,
+            Name:    "t2key2",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: -1,
+      Constraint:    &ast.Check{
+        Check:  329,
+        Rparen: 343,
+        Expr:   &ast.BinaryExpr{
+          Op:   ">",
+          Left: &ast.Ident{
+            NamePos: 336,
+            NameEnd: 339,
+            Name:    "foo",
+          },
+          Right: &ast.IntLiteral{
+            ValuePos: 342,
+            ValueEnd: 343,
+            Base:     10,
+            Value:    "0",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: 350,
+      Name:          &ast.Ident{
+        NamePos: 361,
+        NameEnd: 366,
+        Name:    "cname",
+      },
+      Constraint: &ast.Check{
+        Check:  367,
+        Rparen: 381,
+        Expr:   &ast.BinaryExpr{
+          Op:   ">",
+          Left: &ast.Ident{
+            NamePos: 374,
+            NameEnd: 377,
+            Name:    "bar",
+          },
+          Right: &ast.IntLiteral{
+            ValuePos: 380,
+            ValueEnd: 381,
+            Base:     10,
+            Value:    "0",
+          },
+        },
+      },
+    },
+  },
+  PrimaryKeys: []*ast.IndexKey{
+    &ast.IndexKey{
+      DirPos: -1,
+      Name:   &ast.Ident{
+        NamePos: 458,
+        NameEnd: 461,
+        Name:    "foo",
+      },
+    },
+  },
+  Cluster: &ast.Cluster{
+    Comma:       462,
+    OnDeleteEnd: -1,
+    TableName:   &ast.Path{
+      Idents: []*ast.Ident{
+        &ast.Ident{
+          NamePos: 487,
+          NameEnd: 493,
+          Name:    "foobar",
+        },
+      },
+    },
+  },
+  RowDeletionPolicy: &ast.CreateRowDeletionPolicy{
+    Comma:             493,
+    RowDeletionPolicy: &ast.RowDeletionPolicy{
+      Row:        497,
+      Rparen:     555,
+      ColumnName: &ast.Ident{
+        NamePos: 532,
+        NameEnd: 535,
+        Name:    "baz",
+      },
+      NumDays: &ast.IntLiteral{
+        ValuePos: 546,
+        ValueEnd: 548,
+        Base:     10,
+        Value:    "30",
+      },
+    },
+  },
+}
+
+--- SQL
+CREATE TABLE IF NOT EXISTS foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL,
+    baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null),
+    qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED,
+    corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()),
+    FOREIGN KEY (foo) REFERENCES t2 (t2key1),
+    CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2),
+    CHECK (foo > 0),
+    CONSTRAINT cname CHECK (bar > 0)
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar,
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/ddl/create_table_fulltext_albums.sql.txt b/testdata/result/ddl/create_table_fulltext_albums.sql.txt
index 7f90a44..e119e9a 100644
--- a/testdata/result/ddl/create_table_fulltext_albums.sql.txt
+++ b/testdata/result/ddl/create_table_fulltext_albums.sql.txt
@@ -179,4 +179,12 @@ CREATE TABLE Albums (
 }
 
 --- SQL
-CREATE TABLE Albums (AlbumId STRING(MAX) NOT NULL, SingerId INT64 NOT NULL, ReleaseTimestamp INT64 NOT NULL, AlbumTitle STRING(MAX), Rating FLOAT64, AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN) PRIMARY KEY (AlbumId)
+CREATE TABLE Albums (
+    AlbumId STRING(MAX) NOT NULL,
+    SingerId INT64 NOT NULL,
+    ReleaseTimestamp INT64 NOT NULL,
+    AlbumTitle STRING(MAX),
+    Rating FLOAT64,
+    AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
+    Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN
+) PRIMARY KEY (AlbumId)
diff --git a/testdata/result/ddl/create_table_if_not_exists.sql.txt b/testdata/result/ddl/create_table_if_not_exists.sql.txt
index b7b5244..9da7dcf 100644
--- a/testdata/result/ddl/create_table_if_not_exists.sql.txt
+++ b/testdata/result/ddl/create_table_if_not_exists.sql.txt
@@ -67,4 +67,7 @@ create table if not exists foo (
 }
 
 --- SQL
-CREATE TABLE IF NOT EXISTS foo (foo INT64, bar FLOAT64 NOT NULL) PRIMARY KEY (foo, bar)
+CREATE TABLE IF NOT EXISTS foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL
+) PRIMARY KEY (foo, bar)
diff --git a/testdata/result/ddl/create_table_row_deletion_policy.sql.txt b/testdata/result/ddl/create_table_row_deletion_policy.sql.txt
index 047b3cf..12140d3 100644
--- a/testdata/result/ddl/create_table_row_deletion_policy.sql.txt
+++ b/testdata/result/ddl/create_table_row_deletion_policy.sql.txt
@@ -80,4 +80,9 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64, baz TIMESTAMP) PRIMARY KEY (), ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64,
+    baz TIMESTAMP
+) PRIMARY KEY (),
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/ddl/create_table_synonyms.sql.txt b/testdata/result/ddl/create_table_synonyms.sql.txt
index 1346e7d..53f8a65 100644
--- a/testdata/result/ddl/create_table_synonyms.sql.txt
+++ b/testdata/result/ddl/create_table_synonyms.sql.txt
@@ -76,4 +76,8 @@ CREATE TABLE Singers (
 }
 
 --- SQL
-CREATE TABLE Singers (SingerId INT64 NOT NULL, SingerName STRING(1024), SYNONYM (Artists)) PRIMARY KEY (SingerId)
+CREATE TABLE Singers (
+    SingerId INT64 NOT NULL,
+    SingerName STRING(1024),
+    SYNONYM (Artists)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/ddl/create_table_synonyms_abnormal.sql.txt b/testdata/result/ddl/create_table_synonyms_abnormal.sql.txt
index 43efa24..f19a226 100644
--- a/testdata/result/ddl/create_table_synonyms_abnormal.sql.txt
+++ b/testdata/result/ddl/create_table_synonyms_abnormal.sql.txt
@@ -88,4 +88,9 @@ CREATE TABLE Singers (
 }
 
 --- SQL
-CREATE TABLE Singers (SingerId INT64 NOT NULL, SingerName STRING(1024), SYNONYM (Ignored), SYNONYM (Artists)) PRIMARY KEY (SingerId)
+CREATE TABLE Singers (
+    SingerId INT64 NOT NULL,
+    SingerName STRING(1024),
+    SYNONYM (Ignored),
+SYNONYM (Artists)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/ddl/create_table_trailing_comma.sql.txt b/testdata/result/ddl/create_table_trailing_comma.sql.txt
index 0e7ddcd..ec470f4 100644
--- a/testdata/result/ddl/create_table_trailing_comma.sql.txt
+++ b/testdata/result/ddl/create_table_trailing_comma.sql.txt
@@ -70,4 +70,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64) PRIMARY KEY (foo ASC, bar DESC)
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64
+) PRIMARY KEY (foo ASC, bar DESC)
diff --git a/testdata/result/ddl/create_table_types.sql.txt b/testdata/result/ddl/create_table_types.sql.txt
index 0dd7056..134b4e4 100644
--- a/testdata/result/ddl/create_table_types.sql.txt
+++ b/testdata/result/ddl/create_table_types.sql.txt
@@ -285,4 +285,19 @@ create table types (
 }
 
 --- SQL
-CREATE TABLE types (b BOOL, i INT64, f32 FLOAT32, f FLOAT64, d DATE, t TIMESTAMP, s STRING(256), smax STRING(MAX), bs BYTES(256), bsmax BYTES(MAX), ab ARRAY<BOOL>, abs ARRAY<BYTES(MAX)>, p examples.ProtoType, af32vl ARRAY<FLOAT32>(vector_length => 128)) PRIMARY KEY (i)
+CREATE TABLE types (
+    b BOOL,
+    i INT64,
+    f32 FLOAT32,
+    f FLOAT64,
+    d DATE,
+    t TIMESTAMP,
+    s STRING(256),
+    smax STRING(MAX),
+    bs BYTES(256),
+    bsmax BYTES(MAX),
+    ab ARRAY<BOOL>,
+    abs ARRAY<BYTES(MAX)>,
+    p examples.ProtoType,
+    af32vl ARRAY<FLOAT32>(vector_length => 128)
+) PRIMARY KEY (i)
diff --git a/testdata/result/ddl/create_table_with_sequence_function.sql.txt b/testdata/result/ddl/create_table_with_sequence_function.sql.txt
index cb4bd4d..8f80ac2 100644
--- a/testdata/result/ddl/create_table_with_sequence_function.sql.txt
+++ b/testdata/result/ddl/create_table_with_sequence_function.sql.txt
@@ -96,4 +96,8 @@ CREATE TABLE foo
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE foo_sequence)), bar STRING(MAX), id INT64) PRIMARY KEY (id)
+CREATE TABLE foo (
+    foo INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE foo_sequence)),
+    bar STRING(MAX),
+    id INT64
+) PRIMARY KEY (id)
diff --git a/testdata/result/ddl/named_schema_create_table_backquoted.sql.txt b/testdata/result/ddl/named_schema_create_table_backquoted.sql.txt
index f2c9bff..570b3c9 100644
--- a/testdata/result/ddl/named_schema_create_table_backquoted.sql.txt
+++ b/testdata/result/ddl/named_schema_create_table_backquoted.sql.txt
@@ -45,4 +45,6 @@ CREATE TABLE `ORDER`.`ORDER`(PK INT64) PRIMARY KEY(PK)
 }
 
 --- SQL
-CREATE TABLE `ORDER`.`ORDER` (PK INT64) PRIMARY KEY (PK)
+CREATE TABLE `ORDER`.`ORDER` (
+    PK INT64
+) PRIMARY KEY (PK)
diff --git a/testdata/result/ddl/named_schemas_create_table.sql.txt b/testdata/result/ddl/named_schemas_create_table.sql.txt
index beb9447..fa1ad15 100644
--- a/testdata/result/ddl/named_schemas_create_table.sql.txt
+++ b/testdata/result/ddl/named_schemas_create_table.sql.txt
@@ -106,4 +106,9 @@ CREATE TABLE sch1.Singers (
 }
 
 --- SQL
-CREATE TABLE sch1.Singers (SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX)) PRIMARY KEY (SingerId)
+CREATE TABLE sch1.Singers (
+    SingerId INT64 NOT NULL,
+    FirstName STRING(1024),
+    LastName STRING(1024),
+    SingerInfo BYTES(MAX)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/ddl/named_schemas_create_table_foreign_key.sql.txt b/testdata/result/ddl/named_schemas_create_table_foreign_key.sql.txt
index deb384e..f88321e 100644
--- a/testdata/result/ddl/named_schemas_create_table_foreign_key.sql.txt
+++ b/testdata/result/ddl/named_schemas_create_table_foreign_key.sql.txt
@@ -136,4 +136,9 @@ CREATE TABLE sch1.ShoppingCarts (
 }
 
 --- SQL
-CREATE TABLE sch1.ShoppingCarts (CartId INT64 NOT NULL, CustomerId INT64 NOT NULL, CustomerName STRING(MAX) NOT NULL, CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY (CustomerId, CustomerName) REFERENCES sch1.Customers (CustomerId, CustomerName) ON DELETE CASCADE) PRIMARY KEY (CartId)
+CREATE TABLE sch1.ShoppingCarts (
+    CartId INT64 NOT NULL,
+    CustomerId INT64 NOT NULL,
+    CustomerName STRING(MAX) NOT NULL,
+    CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY (CustomerId, CustomerName) REFERENCES sch1.Customers (CustomerId, CustomerName) ON DELETE CASCADE
+) PRIMARY KEY (CartId)
diff --git a/testdata/result/ddl/named_schemas_create_table_interleave.sql.txt b/testdata/result/ddl/named_schemas_create_table_interleave.sql.txt
index 82983cd..b9fad9b 100644
--- a/testdata/result/ddl/named_schemas_create_table_interleave.sql.txt
+++ b/testdata/result/ddl/named_schemas_create_table_interleave.sql.txt
@@ -107,4 +107,9 @@ CREATE TABLE sch1.Albums (
 }
 
 --- SQL
-CREATE TABLE sch1.Albums (SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX)) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT sch1.Singers ON DELETE CASCADE
+CREATE TABLE sch1.Albums (
+    SingerId INT64 NOT NULL,
+    AlbumId INT64 NOT NULL,
+    AlbumTitle STRING(MAX)
+) PRIMARY KEY (SingerId, AlbumId),
+INTERLEAVE IN PARENT sch1.Singers ON DELETE CASCADE
diff --git a/testdata/result/statement/create_table.sql.txt b/testdata/result/statement/create_table.sql.txt
index f3d84cd..5908b4d 100644
--- a/testdata/result/statement/create_table.sql.txt
+++ b/testdata/result/statement/create_table.sql.txt
@@ -392,4 +392,17 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar FLOAT64 NOT NULL, baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null), qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED, quux JSON, corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()), FOREIGN KEY (foo) REFERENCES t2 (t2key1), FOREIGN KEY (bar) REFERENCES t2 (t2key2) ON DELETE CASCADE, FOREIGN KEY (baz) REFERENCES t2 (t2key3) ON DELETE NO ACTION, CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2), CHECK (foo > 0), CONSTRAINT cname CHECK (bar > 0)) PRIMARY KEY (foo, bar)
+CREATE TABLE foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL,
+    baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null),
+    qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED,
+    quux JSON,
+    corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()),
+    FOREIGN KEY (foo) REFERENCES t2 (t2key1),
+    FOREIGN KEY (bar) REFERENCES t2 (t2key2) ON DELETE CASCADE,
+    FOREIGN KEY (baz) REFERENCES t2 (t2key3) ON DELETE NO ACTION,
+    CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2),
+    CHECK (foo > 0),
+    CONSTRAINT cname CHECK (bar > 0)
+) PRIMARY KEY (foo, bar)
diff --git a/testdata/result/statement/create_table_cluster.sql.txt b/testdata/result/statement/create_table_cluster.sql.txt
index bacaadc..1563ab4 100644
--- a/testdata/result/statement/create_table_cluster.sql.txt
+++ b/testdata/result/statement/create_table_cluster.sql.txt
@@ -61,4 +61,8 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64) PRIMARY KEY (), INTERLEAVE IN PARENT foobar
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64
+) PRIMARY KEY (),
+INTERLEAVE IN PARENT foobar
diff --git a/testdata/result/statement/create_table_cluster_and_row_deletion_policy.sql.txt b/testdata/result/statement/create_table_cluster_and_row_deletion_policy.sql.txt
index 0f37325..b89f742 100644
--- a/testdata/result/statement/create_table_cluster_and_row_deletion_policy.sql.txt
+++ b/testdata/result/statement/create_table_cluster_and_row_deletion_policy.sql.txt
@@ -94,4 +94,10 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64, baz TIMESTAMP) PRIMARY KEY (), INTERLEAVE IN PARENT foobar, ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64,
+    baz TIMESTAMP
+) PRIMARY KEY (),
+INTERLEAVE IN PARENT foobar,
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/statement/create_table_cluster_on_delete_no_action.sql.txt b/testdata/result/statement/create_table_cluster_on_delete_no_action.sql.txt
index 393b098..76894d0 100644
--- a/testdata/result/statement/create_table_cluster_on_delete_no_action.sql.txt
+++ b/testdata/result/statement/create_table_cluster_on_delete_no_action.sql.txt
@@ -58,4 +58,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64) PRIMARY KEY (foo), INTERLEAVE IN PARENT foobar ON DELETE NO ACTION
+CREATE TABLE foo (
+    foo INT64
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar ON DELETE NO ACTION
diff --git a/testdata/result/statement/create_table_cluster_set_on_delete.sql.txt b/testdata/result/statement/create_table_cluster_set_on_delete.sql.txt
index 8f8605c..4c8d811 100644
--- a/testdata/result/statement/create_table_cluster_set_on_delete.sql.txt
+++ b/testdata/result/statement/create_table_cluster_set_on_delete.sql.txt
@@ -58,4 +58,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64) PRIMARY KEY (foo), INTERLEAVE IN PARENT foobar ON DELETE CASCADE
+CREATE TABLE foo (
+    foo INT64
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar ON DELETE CASCADE
diff --git a/testdata/result/statement/create_table_for_format_test.sql.txt b/testdata/result/statement/create_table_for_format_test.sql.txt
new file mode 100644
index 0000000..2900c38
--- /dev/null
+++ b/testdata/result/statement/create_table_for_format_test.sql.txt
@@ -0,0 +1,353 @@
+--- create_table_for_format_test.sql
+create table if not exists foo (
+    foo int64,
+    bar float64 not null,
+    baz string(255) not null options(allow_commit_timestamp = null),
+    qux string(255) not null as (concat(baz, "a")) stored,
+    foreign key (foo) references t2 (t2key1),
+    constraint fkname foreign key (foo, bar) references t2 (t2key1, t2key2),
+    check (foo > 0),
+    constraint cname check (bar > 0),
+    corge timestamp not null default (current_timestamp())
+) primary key (foo),
+  interleave in parent foobar,
+  row deletion policy ( older_than ( baz, INTERVAL 30 DAY ) )
+
+--- AST
+&ast.CreateTable{
+  Rparen:      461,
+  IfNotExists: true,
+  Name:        &ast.Path{
+    Idents: []*ast.Ident{
+      &ast.Ident{
+        NamePos: 27,
+        NameEnd: 30,
+        Name:    "foo",
+      },
+    },
+  },
+  Columns: []*ast.ColumnDef{
+    &ast.ColumnDef{
+      Null: -1,
+      Name: &ast.Ident{
+        NamePos: 37,
+        NameEnd: 40,
+        Name:    "foo",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 41,
+        Name:    "INT64",
+      },
+      Hidden: -1,
+    },
+    &ast.ColumnDef{
+      Null: 68,
+      Name: &ast.Ident{
+        NamePos: 52,
+        NameEnd: 55,
+        Name:    "bar",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 56,
+        Name:    "FLOAT64",
+      },
+      NotNull: true,
+      Hidden:  -1,
+    },
+    &ast.ColumnDef{
+      Null: 98,
+      Name: &ast.Ident{
+        NamePos: 78,
+        NameEnd: 81,
+        Name:    "baz",
+      },
+      Type: &ast.SizedSchemaType{
+        NamePos: 82,
+        Rparen:  92,
+        Name:    "STRING",
+        Size:    &ast.IntLiteral{
+          ValuePos: 89,
+          ValueEnd: 92,
+          Base:     10,
+          Value:    "255",
+        },
+      },
+      NotNull: true,
+      Hidden:  -1,
+      Options: &ast.Options{
+        Options: 103,
+        Rparen:  140,
+        Records: []*ast.OptionsDef{
+          &ast.OptionsDef{
+            Name: &ast.Ident{
+              NamePos: 111,
+              NameEnd: 133,
+              Name:    "allow_commit_timestamp",
+            },
+            Value: &ast.NullLiteral{
+              Null: 136,
+            },
+          },
+        },
+      },
+    },
+    &ast.ColumnDef{
+      Null: 167,
+      Name: &ast.Ident{
+        NamePos: 147,
+        NameEnd: 150,
+        Name:    "qux",
+      },
+      Type: &ast.SizedSchemaType{
+        NamePos: 151,
+        Rparen:  161,
+        Name:    "STRING",
+        Size:    &ast.IntLiteral{
+          ValuePos: 158,
+          ValueEnd: 161,
+          Base:     10,
+          Value:    "255",
+        },
+      },
+      NotNull:       true,
+      GeneratedExpr: &ast.GeneratedColumnExpr{
+        As:     172,
+        Stored: 194,
+        Rparen: 192,
+        Expr:   &ast.CallExpr{
+          Rparen: 191,
+          Func:   &ast.Ident{
+            NamePos: 176,
+            NameEnd: 182,
+            Name:    "concat",
+          },
+          Args: []ast.Arg{
+            &ast.ExprArg{
+              Expr: &ast.Ident{
+                NamePos: 183,
+                NameEnd: 186,
+                Name:    "baz",
+              },
+            },
+            &ast.ExprArg{
+              Expr: &ast.StringLiteral{
+                ValuePos: 188,
+                ValueEnd: 191,
+                Value:    "a",
+              },
+            },
+          },
+        },
+      },
+      Hidden: -1,
+    },
+    &ast.ColumnDef{
+      Null: 408,
+      Name: &ast.Ident{
+        NamePos: 388,
+        NameEnd: 393,
+        Name:    "corge",
+      },
+      Type: &ast.ScalarSchemaType{
+        NamePos: 394,
+        Name:    "TIMESTAMP",
+      },
+      NotNull:     true,
+      DefaultExpr: &ast.ColumnDefaultExpr{
+        Default: 413,
+        Rparen:  441,
+        Expr:    &ast.CallExpr{
+          Rparen: 440,
+          Func:   &ast.Ident{
+            NamePos: 422,
+            NameEnd: 439,
+            Name:    "current_timestamp",
+          },
+        },
+      },
+      Hidden: -1,
+    },
+  },
+  TableConstraints: []*ast.TableConstraint{
+    &ast.TableConstraint{
+      ConstraintPos: -1,
+      Constraint:    &ast.ForeignKey{
+        Foreign:     206,
+        Rparen:      245,
+        OnDeleteEnd: -1,
+        Columns:     []*ast.Ident{
+          &ast.Ident{
+            NamePos: 219,
+            NameEnd: 222,
+            Name:    "foo",
+          },
+        },
+        ReferenceTable: &ast.Path{
+          Idents: []*ast.Ident{
+            &ast.Ident{
+              NamePos: 235,
+              NameEnd: 237,
+              Name:    "t2",
+            },
+          },
+        },
+        ReferenceColumns: []*ast.Ident{
+          &ast.Ident{
+            NamePos: 239,
+            NameEnd: 245,
+            Name:    "t2key1",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: 252,
+      Name:          &ast.Ident{
+        NamePos: 263,
+        NameEnd: 269,
+        Name:    "fkname",
+      },
+      Constraint: &ast.ForeignKey{
+        Foreign:     270,
+        Rparen:      322,
+        OnDeleteEnd: -1,
+        Columns:     []*ast.Ident{
+          &ast.Ident{
+            NamePos: 283,
+            NameEnd: 286,
+            Name:    "foo",
+          },
+          &ast.Ident{
+            NamePos: 288,
+            NameEnd: 291,
+            Name:    "bar",
+          },
+        },
+        ReferenceTable: &ast.Path{
+          Idents: []*ast.Ident{
+            &ast.Ident{
+              NamePos: 304,
+              NameEnd: 306,
+              Name:    "t2",
+            },
+          },
+        },
+        ReferenceColumns: []*ast.Ident{
+          &ast.Ident{
+            NamePos: 308,
+            NameEnd: 314,
+            Name:    "t2key1",
+          },
+          &ast.Ident{
+            NamePos: 316,
+            NameEnd: 322,
+            Name:    "t2key2",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: -1,
+      Constraint:    &ast.Check{
+        Check:  329,
+        Rparen: 343,
+        Expr:   &ast.BinaryExpr{
+          Op:   ">",
+          Left: &ast.Ident{
+            NamePos: 336,
+            NameEnd: 339,
+            Name:    "foo",
+          },
+          Right: &ast.IntLiteral{
+            ValuePos: 342,
+            ValueEnd: 343,
+            Base:     10,
+            Value:    "0",
+          },
+        },
+      },
+    },
+    &ast.TableConstraint{
+      ConstraintPos: 350,
+      Name:          &ast.Ident{
+        NamePos: 361,
+        NameEnd: 366,
+        Name:    "cname",
+      },
+      Constraint: &ast.Check{
+        Check:  367,
+        Rparen: 381,
+        Expr:   &ast.BinaryExpr{
+          Op:   ">",
+          Left: &ast.Ident{
+            NamePos: 374,
+            NameEnd: 377,
+            Name:    "bar",
+          },
+          Right: &ast.IntLiteral{
+            ValuePos: 380,
+            ValueEnd: 381,
+            Base:     10,
+            Value:    "0",
+          },
+        },
+      },
+    },
+  },
+  PrimaryKeys: []*ast.IndexKey{
+    &ast.IndexKey{
+      DirPos: -1,
+      Name:   &ast.Ident{
+        NamePos: 458,
+        NameEnd: 461,
+        Name:    "foo",
+      },
+    },
+  },
+  Cluster: &ast.Cluster{
+    Comma:       462,
+    OnDeleteEnd: -1,
+    TableName:   &ast.Path{
+      Idents: []*ast.Ident{
+        &ast.Ident{
+          NamePos: 487,
+          NameEnd: 493,
+          Name:    "foobar",
+        },
+      },
+    },
+  },
+  RowDeletionPolicy: &ast.CreateRowDeletionPolicy{
+    Comma:             493,
+    RowDeletionPolicy: &ast.RowDeletionPolicy{
+      Row:        497,
+      Rparen:     555,
+      ColumnName: &ast.Ident{
+        NamePos: 532,
+        NameEnd: 535,
+        Name:    "baz",
+      },
+      NumDays: &ast.IntLiteral{
+        ValuePos: 546,
+        ValueEnd: 548,
+        Base:     10,
+        Value:    "30",
+      },
+    },
+  },
+}
+
+--- SQL
+CREATE TABLE IF NOT EXISTS foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL,
+    baz STRING(255) NOT NULL OPTIONS (allow_commit_timestamp = null),
+    qux STRING(255) NOT NULL AS (concat(baz, "a")) STORED,
+    corge TIMESTAMP NOT NULL DEFAULT (current_timestamp()),
+    FOREIGN KEY (foo) REFERENCES t2 (t2key1),
+    CONSTRAINT fkname FOREIGN KEY (foo, bar) REFERENCES t2 (t2key1, t2key2),
+    CHECK (foo > 0),
+    CONSTRAINT cname CHECK (bar > 0)
+) PRIMARY KEY (foo),
+INTERLEAVE IN PARENT foobar,
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/statement/create_table_fulltext_albums.sql.txt b/testdata/result/statement/create_table_fulltext_albums.sql.txt
index 7f90a44..e119e9a 100644
--- a/testdata/result/statement/create_table_fulltext_albums.sql.txt
+++ b/testdata/result/statement/create_table_fulltext_albums.sql.txt
@@ -179,4 +179,12 @@ CREATE TABLE Albums (
 }
 
 --- SQL
-CREATE TABLE Albums (AlbumId STRING(MAX) NOT NULL, SingerId INT64 NOT NULL, ReleaseTimestamp INT64 NOT NULL, AlbumTitle STRING(MAX), Rating FLOAT64, AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN) PRIMARY KEY (AlbumId)
+CREATE TABLE Albums (
+    AlbumId STRING(MAX) NOT NULL,
+    SingerId INT64 NOT NULL,
+    ReleaseTimestamp INT64 NOT NULL,
+    AlbumTitle STRING(MAX),
+    Rating FLOAT64,
+    AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
+    Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN
+) PRIMARY KEY (AlbumId)
diff --git a/testdata/result/statement/create_table_if_not_exists.sql.txt b/testdata/result/statement/create_table_if_not_exists.sql.txt
index b7b5244..9da7dcf 100644
--- a/testdata/result/statement/create_table_if_not_exists.sql.txt
+++ b/testdata/result/statement/create_table_if_not_exists.sql.txt
@@ -67,4 +67,7 @@ create table if not exists foo (
 }
 
 --- SQL
-CREATE TABLE IF NOT EXISTS foo (foo INT64, bar FLOAT64 NOT NULL) PRIMARY KEY (foo, bar)
+CREATE TABLE IF NOT EXISTS foo (
+    foo INT64,
+    bar FLOAT64 NOT NULL
+) PRIMARY KEY (foo, bar)
diff --git a/testdata/result/statement/create_table_row_deletion_policy.sql.txt b/testdata/result/statement/create_table_row_deletion_policy.sql.txt
index 047b3cf..12140d3 100644
--- a/testdata/result/statement/create_table_row_deletion_policy.sql.txt
+++ b/testdata/result/statement/create_table_row_deletion_policy.sql.txt
@@ -80,4 +80,9 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64, baz TIMESTAMP) PRIMARY KEY (), ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64,
+    baz TIMESTAMP
+) PRIMARY KEY (),
+ROW DELETION POLICY ( OLDER_THAN ( baz, INTERVAL 30 DAY ))
diff --git a/testdata/result/statement/create_table_synonyms.sql.txt b/testdata/result/statement/create_table_synonyms.sql.txt
index 1346e7d..53f8a65 100644
--- a/testdata/result/statement/create_table_synonyms.sql.txt
+++ b/testdata/result/statement/create_table_synonyms.sql.txt
@@ -76,4 +76,8 @@ CREATE TABLE Singers (
 }
 
 --- SQL
-CREATE TABLE Singers (SingerId INT64 NOT NULL, SingerName STRING(1024), SYNONYM (Artists)) PRIMARY KEY (SingerId)
+CREATE TABLE Singers (
+    SingerId INT64 NOT NULL,
+    SingerName STRING(1024),
+    SYNONYM (Artists)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/statement/create_table_synonyms_abnormal.sql.txt b/testdata/result/statement/create_table_synonyms_abnormal.sql.txt
index 43efa24..f19a226 100644
--- a/testdata/result/statement/create_table_synonyms_abnormal.sql.txt
+++ b/testdata/result/statement/create_table_synonyms_abnormal.sql.txt
@@ -88,4 +88,9 @@ CREATE TABLE Singers (
 }
 
 --- SQL
-CREATE TABLE Singers (SingerId INT64 NOT NULL, SingerName STRING(1024), SYNONYM (Ignored), SYNONYM (Artists)) PRIMARY KEY (SingerId)
+CREATE TABLE Singers (
+    SingerId INT64 NOT NULL,
+    SingerName STRING(1024),
+    SYNONYM (Ignored),
+SYNONYM (Artists)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/statement/create_table_trailing_comma.sql.txt b/testdata/result/statement/create_table_trailing_comma.sql.txt
index 0e7ddcd..ec470f4 100644
--- a/testdata/result/statement/create_table_trailing_comma.sql.txt
+++ b/testdata/result/statement/create_table_trailing_comma.sql.txt
@@ -70,4 +70,7 @@ create table foo (
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64, bar INT64) PRIMARY KEY (foo ASC, bar DESC)
+CREATE TABLE foo (
+    foo INT64,
+    bar INT64
+) PRIMARY KEY (foo ASC, bar DESC)
diff --git a/testdata/result/statement/create_table_types.sql.txt b/testdata/result/statement/create_table_types.sql.txt
index 0dd7056..134b4e4 100644
--- a/testdata/result/statement/create_table_types.sql.txt
+++ b/testdata/result/statement/create_table_types.sql.txt
@@ -285,4 +285,19 @@ create table types (
 }
 
 --- SQL
-CREATE TABLE types (b BOOL, i INT64, f32 FLOAT32, f FLOAT64, d DATE, t TIMESTAMP, s STRING(256), smax STRING(MAX), bs BYTES(256), bsmax BYTES(MAX), ab ARRAY<BOOL>, abs ARRAY<BYTES(MAX)>, p examples.ProtoType, af32vl ARRAY<FLOAT32>(vector_length => 128)) PRIMARY KEY (i)
+CREATE TABLE types (
+    b BOOL,
+    i INT64,
+    f32 FLOAT32,
+    f FLOAT64,
+    d DATE,
+    t TIMESTAMP,
+    s STRING(256),
+    smax STRING(MAX),
+    bs BYTES(256),
+    bsmax BYTES(MAX),
+    ab ARRAY<BOOL>,
+    abs ARRAY<BYTES(MAX)>,
+    p examples.ProtoType,
+    af32vl ARRAY<FLOAT32>(vector_length => 128)
+) PRIMARY KEY (i)
diff --git a/testdata/result/statement/create_table_with_sequence_function.sql.txt b/testdata/result/statement/create_table_with_sequence_function.sql.txt
index cb4bd4d..8f80ac2 100644
--- a/testdata/result/statement/create_table_with_sequence_function.sql.txt
+++ b/testdata/result/statement/create_table_with_sequence_function.sql.txt
@@ -96,4 +96,8 @@ CREATE TABLE foo
 }
 
 --- SQL
-CREATE TABLE foo (foo INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE foo_sequence)), bar STRING(MAX), id INT64) PRIMARY KEY (id)
+CREATE TABLE foo (
+    foo INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE foo_sequence)),
+    bar STRING(MAX),
+    id INT64
+) PRIMARY KEY (id)
diff --git a/testdata/result/statement/named_schema_create_table_backquoted.sql.txt b/testdata/result/statement/named_schema_create_table_backquoted.sql.txt
index f2c9bff..570b3c9 100644
--- a/testdata/result/statement/named_schema_create_table_backquoted.sql.txt
+++ b/testdata/result/statement/named_schema_create_table_backquoted.sql.txt
@@ -45,4 +45,6 @@ CREATE TABLE `ORDER`.`ORDER`(PK INT64) PRIMARY KEY(PK)
 }
 
 --- SQL
-CREATE TABLE `ORDER`.`ORDER` (PK INT64) PRIMARY KEY (PK)
+CREATE TABLE `ORDER`.`ORDER` (
+    PK INT64
+) PRIMARY KEY (PK)
diff --git a/testdata/result/statement/named_schemas_create_table.sql.txt b/testdata/result/statement/named_schemas_create_table.sql.txt
index beb9447..fa1ad15 100644
--- a/testdata/result/statement/named_schemas_create_table.sql.txt
+++ b/testdata/result/statement/named_schemas_create_table.sql.txt
@@ -106,4 +106,9 @@ CREATE TABLE sch1.Singers (
 }
 
 --- SQL
-CREATE TABLE sch1.Singers (SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX)) PRIMARY KEY (SingerId)
+CREATE TABLE sch1.Singers (
+    SingerId INT64 NOT NULL,
+    FirstName STRING(1024),
+    LastName STRING(1024),
+    SingerInfo BYTES(MAX)
+) PRIMARY KEY (SingerId)
diff --git a/testdata/result/statement/named_schemas_create_table_foreign_key.sql.txt b/testdata/result/statement/named_schemas_create_table_foreign_key.sql.txt
index deb384e..f88321e 100644
--- a/testdata/result/statement/named_schemas_create_table_foreign_key.sql.txt
+++ b/testdata/result/statement/named_schemas_create_table_foreign_key.sql.txt
@@ -136,4 +136,9 @@ CREATE TABLE sch1.ShoppingCarts (
 }
 
 --- SQL
-CREATE TABLE sch1.ShoppingCarts (CartId INT64 NOT NULL, CustomerId INT64 NOT NULL, CustomerName STRING(MAX) NOT NULL, CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY (CustomerId, CustomerName) REFERENCES sch1.Customers (CustomerId, CustomerName) ON DELETE CASCADE) PRIMARY KEY (CartId)
+CREATE TABLE sch1.ShoppingCarts (
+    CartId INT64 NOT NULL,
+    CustomerId INT64 NOT NULL,
+    CustomerName STRING(MAX) NOT NULL,
+    CONSTRAINT FKShoppingCartsCustomers FOREIGN KEY (CustomerId, CustomerName) REFERENCES sch1.Customers (CustomerId, CustomerName) ON DELETE CASCADE
+) PRIMARY KEY (CartId)
diff --git a/testdata/result/statement/named_schemas_create_table_interleave.sql.txt b/testdata/result/statement/named_schemas_create_table_interleave.sql.txt
index 82983cd..b9fad9b 100644
--- a/testdata/result/statement/named_schemas_create_table_interleave.sql.txt
+++ b/testdata/result/statement/named_schemas_create_table_interleave.sql.txt
@@ -107,4 +107,9 @@ CREATE TABLE sch1.Albums (
 }
 
 --- SQL
-CREATE TABLE sch1.Albums (SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX)) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT sch1.Singers ON DELETE CASCADE
+CREATE TABLE sch1.Albums (
+    SingerId INT64 NOT NULL,
+    AlbumId INT64 NOT NULL,
+    AlbumTitle STRING(MAX)
+) PRIMARY KEY (SingerId, AlbumId),
+INTERLEAVE IN PARENT sch1.Singers ON DELETE CASCADE