Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parser: add syntax for ttl option in ddl #39277

Merged
merged 3 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 81 additions & 7 deletions parser/ast/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,13 @@ func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) {
}
n.Partition = node.(*PartitionOptions)
}
for i, option := range n.Options {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it required by the PR? I think it is right to visit all the Options for CreateTableStmt.Accept. But I'm not sure why we did not do it before, maybe just because forgot it?

Copy link
Member Author

@YangKeao YangKeao Nov 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it required by the PR?

Yes. The parser_test.go requires to visit all ExprNode to reset the offset. Without it, we cannot use the unit test utilities. This PR adds a ExprNode field to the option, so it's needed to visit the options.

node, ok = option.Accept(v)
if !ok {
return n, false
}
n.Options[i] = node.(*TableOption)
}

return v.Leave(n)
}
Expand Down Expand Up @@ -2074,6 +2081,9 @@ const (
TableOptionTableCheckSum
TableOptionUnion
TableOptionEncryption
TableOptionTTL
TableOptionTTLEnable
TableOptionNoTTL
TableOptionPlacementPolicy = TableOptionType(PlacementOptionPolicy)
TableOptionStatsBuckets = TableOptionType(StatsOptionBuckets)
TableOptionStatsTopN = TableOptionType(StatsOptionTopN)
Expand Down Expand Up @@ -2120,13 +2130,17 @@ const (

// TableOption is used for parsing table option from SQL.
type TableOption struct {
Tp TableOptionType
Default bool
StrValue string
UintValue uint64
BoolValue bool
Value ValueExpr
TableNames []*TableName
node
Tp TableOptionType
Default bool
StrValue string
UintValue uint64
BoolValue bool
TimeUnitValue *TimeUnitExpr
Value ValueExpr
Expression ExprNode
TableNames []*TableName
ColumnName *ColumnName
}

func (n *TableOption) Restore(ctx *format.RestoreCtx) error {
Expand Down Expand Up @@ -2405,12 +2419,65 @@ func (n *TableOption) Restore(ctx *format.RestoreCtx) error {
} else {
ctx.WriteString(n.StrValue)
}
case TableOptionTTL:
_ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error {
ctx.WriteKeyWord("TTL ")
ctx.WritePlain("= ")
ctx.WriteName(n.ColumnName.Name.String())
ctx.WritePlain(" + INTERVAL ")
err := n.Expression.Restore(ctx)
ctx.WritePlain(" ")
if err != nil {
return err
}
return n.TimeUnitValue.Restore(ctx)
})
case TableOptionTTLEnable:
_ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error {
ctx.WriteKeyWord("TTL_ENABLE ")
ctx.WritePlain("= ")
if n.BoolValue {
ctx.WriteString("ON")
} else {
ctx.WriteString("OFF")
}
return nil
})
case TableOptionNoTTL:
_ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error {
ctx.WriteKeyWord("NO_TTL")
return nil
})
default:
return errors.Errorf("invalid TableOption: %d", n.Tp)
}
return nil
}

// Accept implements Node Accept interface.
func (n *TableOption) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableOption)
if n.Expression != nil {
node, ok := n.Expression.Accept(v)
if !ok {
return n, false
}
n.Expression = node.(ExprNode)
}
if n.TimeUnitValue != nil {
node, ok := n.TimeUnitValue.Accept(v)
if !ok {
return n, false
}
n.TimeUnitValue = node.(*TimeUnitExpr)
}
return v.Leave(n)
}

// SequenceOptionType is the type for SequenceOption
type SequenceOptionType int

Expand Down Expand Up @@ -3344,6 +3411,13 @@ func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) {
}
n.Partition = node.(*PartitionOptions)
}
for i, option := range n.Options {
node, ok := option.Accept(v)
if !ok {
return n, false
}
n.Options[i] = node.(*TableOption)
}
for _, def := range n.PartDefinitions {
if !def.acceptInPlace(v) {
return n, false
Expand Down
29 changes: 29 additions & 0 deletions parser/ast/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -840,3 +840,32 @@ func TestFlashBackDatabaseRestore(t *testing.T) {
}
runNodeRestoreTest(t, testCases, "%s", extractNodeFunc)
}

func TestTableOptionTTLRestore(t *testing.T) {
sourceSQL1 := "create table t (created_at datetime) ttl = created_at + INTERVAL 1 YEAR"
sourceSQL2 := "alter table t ttl_enable = 'OFF'"
sourceSQL3 := "alter table t no_ttl"
cases := []struct {
sourceSQL string
flags format.RestoreFlags
expectSQL string
}{
{sourceSQL1, format.DefaultRestoreFlags, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR"},
{sourceSQL1, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "CREATE TABLE `t` (`created_at` DATETIME) /*T![ttl] TTL = `created_at` + INTERVAL 1 YEAR */"},
{sourceSQL2, format.DefaultRestoreFlags, "ALTER TABLE `t` TTL_ENABLE = 'OFF'"},
{sourceSQL2, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "ALTER TABLE `t` /*T![ttl] TTL_ENABLE = 'OFF' */"},
{sourceSQL3, format.DefaultRestoreFlags, "ALTER TABLE `t` NO_TTL"},
{sourceSQL3, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "ALTER TABLE `t` /*T![ttl] NO_TTL */"},
}

extractNodeFunc := func(node Node) Node {
return node
}

for _, ca := range cases {
testCases := []NodeRestoreTestCase{
{ca.sourceSQL, ca.expectSQL},
}
runNodeRestoreTestWithFlags(t, testCases, "%s", extractNodeFunc, ca.flags)
}
}
3 changes: 3 additions & 0 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,9 @@ var tokenMap = map[string]int{
"TRUE": trueKwd,
"TRUNCATE": truncate,
"TRUE_CARD_COST": trueCardCost,
"TTL": ttl,
"TTL_ENABLE": ttlEnable,
"NO_TTL": nottl,
"TYPE": tp,
"UNBOUNDED": unbounded,
"UNCOMMITTED": uncommitted,
Expand Down
Loading