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  }