github.com/walf443/mgr@v0.0.0-20150203144449-6f7a3a548462/sqlparser/mysql/parser_test.go (about) 1 package mysql 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 func TestParseDropTableStatement(t *testing.T) { 9 testStatement(t, "DROP TABLE hoge", &DropTableStatement{TableNames: []TableNameIdentifier{TableNameIdentifier{Name: "hoge"}}}) 10 testStatement(t, "drop table hoge,fuga", &DropTableStatement{TableNames: []TableNameIdentifier{TableNameIdentifier{Name: "fuga"}, TableNameIdentifier{Name: "hoge"}}}) 11 testStatement(t, "drop table `TABLE`", &DropTableStatement{TableNames: []TableNameIdentifier{TableNameIdentifier{Name: "TABLE"}}}) 12 testStatement(t, "drop table hoge.fuga", &DropTableStatement{TableNames: []TableNameIdentifier{TableNameIdentifier{Database: "hoge", Name: "fuga"}}}) 13 } 14 15 func TestParseDropDatabaseStatement(t *testing.T) { 16 testStatement(t, "DROP DATABASE hoge", &DropDatabaseStatement{DatabaseNameIdentifier{Name: "hoge"}}) 17 testStatement(t, "drop database `hoge`", &DropDatabaseStatement{DatabaseNameIdentifier{Name: "hoge"}}) 18 } 19 20 func TestParseCreateDatabaseStatement(t *testing.T) { 21 testStatement(t, "CREATE DATABASE hoge", &CreateDatabaseStatement{DatabaseNameIdentifier{Name: "hoge"}}) 22 testStatement(t, "create database `hoge`", &CreateDatabaseStatement{DatabaseNameIdentifier{Name: "hoge"}}) 23 } 24 25 func TestCreateTableStatement(t *testing.T) { 26 testStatement(t, "CREATE TABLE hoge ( id INT(10) UNSIGNED NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB", &CreateTableStatement{TableNameIdentifier{"hoge", ""}, []CreateDefinition{ 27 &CreateDefinitionColumn{ColumnNameIdentifier{"id"}, ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, false}, false, false, &DefaultDefinitionEmpty{}}}, 28 &CreateDefinitionPrimaryIndex{[]ColumnNameIdentifier{ColumnNameIdentifier{"id"}}}, 29 }, []TableOption{TableOption{"ENGINE", "InnoDB"}}}) 30 testStatement(t, "CREATE TABLE hoge ( id INT(10) UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id, name), UNIQUE INDEX name (name), INDEX (id) )", &CreateTableStatement{TableNameIdentifier{"hoge", ""}, []CreateDefinition{ 31 &CreateDefinitionColumn{ColumnNameIdentifier{"id"}, ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, false}, false, false, &DefaultDefinitionEmpty{}}}, 32 &CreateDefinitionColumn{ColumnNameIdentifier{"name"}, ColumnDefinition{&DataTypeDefinitionString{DATATYPE_VARCHAR, 255, "", ""}, false, false, &DefaultDefinitionEmpty{}}}, 33 &CreateDefinitionPrimaryIndex{[]ColumnNameIdentifier{ColumnNameIdentifier{"id"}, ColumnNameIdentifier{"name"}}}, 34 &CreateDefinitionUniqueIndex{IndexNameIdentifier{"name"}, []ColumnNameIdentifier{ColumnNameIdentifier{"name"}}}, 35 &CreateDefinitionIndex{IndexNameIdentifier{""}, []ColumnNameIdentifier{ColumnNameIdentifier{"id"}}}, 36 }, []TableOption{}}) 37 } 38 39 func TestParseAlterTableStatement(t *testing.T) { 40 testStatement(t, "ALTER TABLE hoge", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, nil}) 41 testStatement(t, "alter table `hoge`", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, nil}) 42 43 testStatement(t, "alter table `hoge` DROP COLUMN fuga", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationDropColumn{ColumnNameIdentifier{Name: "fuga"}}}}) 44 testStatement(t, "alter table `hoge` DROP `fuga`, DROP `bar`", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{ 45 &AlterSpecificationDropColumn{ColumnNameIdentifier{Name: "fuga"}}, 46 &AlterSpecificationDropColumn{ColumnNameIdentifier{Name: "bar"}}, 47 }}) 48 49 testStatement(t, "alter table `hoge` DROP KEY `fuga`", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationDropIndex{IndexNameIdentifier{Name: "fuga"}}}}) 50 testStatement(t, "alter table `hoge` DROP INDEX `fuga`", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationDropIndex{IndexNameIdentifier{Name: "fuga"}}}}) 51 52 testStatement(t, "alter table `hoge` ADD COLUMN `fuga` INT", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationAddColumn{ColumnNameIdentifier{Name: "fuga"}, ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}}}}) 53 54 testStatement(t, "alter table `hoge` ADD INDEX `fuga` (foo, bar)", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationAddIndex{IndexNameIdentifier{Name: "fuga"}, []ColumnNameIdentifier{ColumnNameIdentifier{"foo"}, ColumnNameIdentifier{"bar"}}, false}}}) 55 testStatement(t, "alter table `hoge` ADD INDEX (foo, bar)", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationAddIndex{IndexNameIdentifier{Name: ""}, []ColumnNameIdentifier{ColumnNameIdentifier{"foo"}, ColumnNameIdentifier{"bar"}}, false}}}) 56 testStatement(t, "alter table `hoge` ADD UNIQUE INDEX `fuga` (foo, bar)", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationAddIndex{IndexNameIdentifier{Name: "fuga"}, []ColumnNameIdentifier{ColumnNameIdentifier{"foo"}, ColumnNameIdentifier{"bar"}}, true}}}) 57 testStatement(t, "alter table `hoge` ADD UNIQUE INDEX (foo, bar)", &AlterTableStatement{TableNameIdentifier{Name: "hoge"}, []AlterSpecification{&AlterSpecificationAddIndex{IndexNameIdentifier{Name: ""}, []ColumnNameIdentifier{ColumnNameIdentifier{"foo"}, ColumnNameIdentifier{"bar"}}, true}}}) 58 } 59 60 func TestParseCommentStatement(t *testing.T) { 61 testStatement(t, "/* hoge */", &CommentStatement{" hoge "}) 62 testStatement(t, "/* あいうえお */", &CommentStatement{" あいうえお "}) 63 testStatement(t, "/* SELECT * FROM hoge; */", &CommentStatement{" SELECT * FROM hoge; "}) 64 } 65 66 func TestParseColumnDefinition(t *testing.T) { 67 testColumnDefinition(t, "BIT", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_BIT}, true, false, &DefaultDefinitionEmpty{}}) 68 testColumnDefinition(t, "bit", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_BIT}, true, false, &DefaultDefinitionEmpty{}}) 69 testColumnDefinition(t, "TINYINT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_TINYINT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 70 testColumnDefinition(t, "SMALLINT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_SMALLINT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 71 testColumnDefinition(t, "MEDIUMINT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_MEDIUMINT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 72 testColumnDefinition(t, "INT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 73 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, true, false, &DefaultDefinitionEmpty{}}) 74 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, false, true, &DefaultDefinitionEmpty{}}) 75 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL NOT NULL DEFAULT 100 AUTO_INCREMENT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, false, true, &DefaultDefinitionString{"100"}}) 76 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL NOT NULL DEFAULT '100' AUTO_INCREMENT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, false, true, &DefaultDefinitionString{"100"}}) 77 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL NOT NULL DEFAULT \"100\" AUTO_INCREMENT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, false, true, &DefaultDefinitionString{"100"}}) 78 testColumnDefinition(t, "INT(10) UNSIGNED ZEROFILL DEFAULT NULL", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 10, true, true}, true, false, &DefaultDefinitionNull{}}) 79 testColumnDefinition(t, "INTEGER", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_INT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 80 testColumnDefinition(t, "BIGINT", ColumnDefinition{&DataTypeDefinitionNumber{DATATYPE_BIGINT, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 81 testColumnDefinition(t, "REAL", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_REAL, 0, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 82 testColumnDefinition(t, "DOUBLE", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_DOUBLE, 0, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 83 testColumnDefinition(t, "FLOAT", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_FLOAT, 0, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 84 testColumnDefinition(t, "FLOAT(10, 2) UNSIGNED ZEROFILL", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_FLOAT, 10, 2, true, true}, true, false, &DefaultDefinitionEmpty{}}) 85 testColumnDefinition(t, "DECIMAL", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_DECIMAL, 0, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 86 testColumnDefinition(t, "DECIMAL(10, 2) UNSIGNED ZEROFILL", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_DECIMAL, 10, 2, true, true}, true, false, &DefaultDefinitionEmpty{}}) 87 testColumnDefinition(t, "DECIMAL(10) ZEROFILL", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_DECIMAL, 10, 0, false, true}, true, false, &DefaultDefinitionEmpty{}}) 88 testColumnDefinition(t, "NUMERIC", ColumnDefinition{&DataTypeDefinitionFraction{DATATYPE_NUMERIC, 0, 0, false, false}, true, false, &DefaultDefinitionEmpty{}}) 89 testColumnDefinition(t, "DATE", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_DATE}, true, false, &DefaultDefinitionEmpty{}}) 90 testColumnDefinition(t, "TIME", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_TIME}, true, false, &DefaultDefinitionEmpty{}}) 91 testColumnDefinition(t, "TIMESTAMP", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_TIMESTAMP}, true, false, &DefaultDefinitionEmpty{}}) 92 testColumnDefinition(t, "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_TIMESTAMP}, true, false, &DefaultDefinitionCurrentTimestamp{false}}) 93 testColumnDefinition(t, "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_TIMESTAMP}, true, false, &DefaultDefinitionCurrentTimestamp{true}}) 94 testColumnDefinition(t, "DATETIME", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_DATETIME}, true, false, &DefaultDefinitionEmpty{}}) 95 testColumnDefinition(t, "YEAR", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_YEAR}, true, false, &DefaultDefinitionEmpty{}}) 96 testColumnDefinition(t, "CHAR", ColumnDefinition{&DataTypeDefinitionString{DATATYPE_CHAR, 0, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 97 testColumnDefinition(t, "CHAR(255)", ColumnDefinition{&DataTypeDefinitionString{DATATYPE_CHAR, 255, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 98 testColumnDefinition(t, "VARCHAR", ColumnDefinition{&DataTypeDefinitionString{DATATYPE_VARCHAR, 0, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 99 testColumnDefinition(t, "VARCHAR(255)", ColumnDefinition{&DataTypeDefinitionString{DATATYPE_VARCHAR, 255, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 100 testColumnDefinition(t, "BINARY", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_BINARY}, true, false, &DefaultDefinitionEmpty{}}) 101 testColumnDefinition(t, "VARBINARY", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_VARBINARY}, true, false, &DefaultDefinitionEmpty{}}) 102 testColumnDefinition(t, "TINYBLOB", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_TINYBLOB}, true, false, &DefaultDefinitionEmpty{}}) 103 testColumnDefinition(t, "BLOB", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_BLOB}, true, false, &DefaultDefinitionEmpty{}}) 104 testColumnDefinition(t, "MEDIUMBLOB", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_MEDIUMBLOB}, true, false, &DefaultDefinitionEmpty{}}) 105 testColumnDefinition(t, "LONGBLOB", ColumnDefinition{&DataTypeDefinitionSimple{DATATYPE_LONGBLOB}, true, false, &DefaultDefinitionEmpty{}}) 106 testColumnDefinition(t, "TINYTEXT", ColumnDefinition{&DataTypeDefinitionTextBlob{DATATYPE_TINYTEXT, false, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 107 testColumnDefinition(t, "TEXT", ColumnDefinition{&DataTypeDefinitionTextBlob{DATATYPE_TEXT, false, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 108 testColumnDefinition(t, "MEDIUMTEXT", ColumnDefinition{&DataTypeDefinitionTextBlob{DATATYPE_MEDIUMTEXT, false, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 109 testColumnDefinition(t, "LONGTEXT", ColumnDefinition{&DataTypeDefinitionTextBlob{DATATYPE_LONGTEXT, false, "", ""}, true, false, &DefaultDefinitionEmpty{}}) 110 } 111 112 func testStatement(t *testing.T, src string, expect interface{}) { 113 s := new(Scanner) 114 s.Init(src + ";") 115 statements, err := Parse(s) 116 if err != nil { 117 t.Errorf("Parse failed %s", err) 118 return 119 } 120 if len(statements) != 1 { 121 t.Errorf("Expect %q to be parsed, but %+#v", src, statements) 122 return 123 } 124 if !reflect.DeepEqual(statements[0], expect) { 125 t.Errorf("Test failed about \"%s\":\n\tExpect\t: %+#v, \n\tBut Got\t: %+#v", src, expect, statements[0]) 126 return 127 } 128 } 129 130 func testColumnDefinition(t *testing.T, src string, expect interface{}) { 131 s := new(Scanner) 132 s.Init("ALTER TABLE hoge ADD COLUMN fuga " + src + ";") 133 statements, err := Parse(s) 134 if err != nil { 135 t.Errorf("Parse failed %s", err) 136 return 137 } 138 if len(statements) != 1 { 139 t.Errorf("Expect %q to be parsed, but %+#v", src, statements) 140 return 141 } 142 if v, ok := statements[0].(*AlterTableStatement); ok { 143 if len(v.AlterSpecifications) == 1 { 144 if v, ok := v.AlterSpecifications[0].(*AlterSpecificationAddColumn); ok { 145 if !reflect.DeepEqual(v.ColumnDefinition, expect) { 146 t.Errorf("Test failed about \"%s\":\n\tExpect\t: %+#v, \n\tBut Got\t: %+#v", src, expect, v.ColumnDefinition) 147 } 148 } else { 149 t.Errorf("Expect %q to be parsed, but %+#v", src, v) 150 } 151 } else { 152 t.Errorf("Expect %q to be parsed, but %+#v", src, v) 153 } 154 } else { 155 t.Errorf("statement should be AlterTableStatement\n") 156 } 157 }