github.com/walf443/mgr@v0.0.0-20150203144449-6f7a3a548462/sqlparser/mysql/parser.go.y (about)

     1  // vim: noet sw=8 sts=8
     2  %{
     3  package mysql
     4  
     5  import (
     6      "fmt"
     7      "strconv"
     8      "errors"
     9  )
    10  
    11  type Token struct {
    12      tok int
    13      lit string
    14      pos Position
    15  }
    16  
    17  %}
    18  
    19  %union{
    20      statements []Statement
    21      statement Statement
    22      table_names []TableNameIdentifier
    23      table_name TableNameIdentifier
    24      table_options []TableOption
    25      table_option TableOption
    26      database_name DatabaseNameIdentifier
    27      column_name ColumnNameIdentifier
    28      column_names []ColumnNameIdentifier
    29      index_name IndexNameIdentifier
    30      column_definition ColumnDefinition
    31      alter_specifications []AlterSpecification
    32      alter_specification AlterSpecification
    33      data_type DataTypeDefinition
    34      create_definitions []CreateDefinition
    35      create_definition CreateDefinition
    36      bool bool
    37      data_type_type DataType
    38      default_definition DefaultDefinition
    39      uint uint
    40      fraction_option [2]uint
    41      tok       Token
    42      str string
    43  }
    44  
    45  %type<statements> statements
    46  %type<statement> statement
    47  %type<table_names> table_names
    48  %type<table_name> table_name
    49  %type<database_name> database_name
    50  %type<column_name> column_name
    51  %type<column_names> index_column_names
    52  %type<index_name> index_name skipable_index_name
    53  %type<column_definition> column_definition
    54  %type<alter_specifications> alter_specifications
    55  %type<alter_specification> alter_specification
    56  %type<create_definition> create_definition
    57  %type<create_definitions> create_definitions
    58  %type<data_type> data_type
    59  %type<data_type_type> data_type_number data_type_fraction data_type_decimal
    60  %type<bool> unsigned_option zerofill_option nullable autoincrement
    61  %type<uint> length_option
    62  %type<fraction_option> fraction_option decimal_option
    63  %type<default_definition> default
    64  %type<table_option> table_option
    65  %type<table_options> skipable_table_options
    66  %type<str> storage_engine_name string
    67  
    68  %token<tok> IDENT NUMBER RAW COMMENT_START COMMENT_FINISH
    69  %token<tok> DROP CREATE ALTER ADD
    70  %token<tok> TABLE COLUMN DATABASE INDEX KEY NOT NULL AUTO_INCREMENT DEFAULT CURRENT_TIMESTAMP ON UPDATE PRIMARY UNIQUE
    71  %token<tok> USING BTREE HASH CHARSET CHARACTER SET COLLATE
    72  %token<tok> ENGINE AVG_ROW_LENGTH CHECKSUM COMMENT KEY_BLOCK_SIZE MAX_ROWS MIN_ROWS ROW_FORMAT DYNAMIC FIXED COMPRESSED REDUNDANT COMPACT
    73  %token<tok> BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT REAL DOUBLE FLOAT DECIMAL NUMERIC DATE TIME TIMESTAMP DATETIME YEAR CHAR VARCHAR BINARY VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB TINYTEXT TEXT MEDIUMTEXT LONGTEXT UNSIGNED ZEROFILL
    74  
    75  %%
    76  
    77  statements
    78      :
    79      {
    80          $$ = nil
    81          if l, isLexerWrapper := yylex.(*LexerWrapper); isLexerWrapper {
    82              l.statements = $$
    83          }
    84      }
    85      | statements statement
    86      {
    87          $$ = append($1, $2)
    88          if l, isLexerWrapper := yylex.(*LexerWrapper); isLexerWrapper {
    89              l.statements = $$
    90          }
    91      }
    92  
    93  statement
    94      : DROP TABLE table_names ';'
    95      {
    96          $$ = &DropTableStatement{TableNames: $3}
    97      }
    98      | DROP DATABASE database_name ';'
    99      {
   100          $$ = &DropDatabaseStatement{DatabaseName: $3}
   101      }
   102      | CREATE DATABASE database_name ';'
   103      {
   104          $$ = &CreateDatabaseStatement{DatabaseName: $3}
   105      }
   106      | CREATE TABLE table_name '(' create_definitions ')' skipable_table_options optional_statement_finish
   107      {
   108          $$ = &CreateTableStatement{TableName: $3, CreateDefinitions: $5, TableOptions: $7}
   109      }
   110      | ALTER TABLE table_name alter_specifications ';'
   111      {
   112          $$ = &AlterTableStatement{TableName: $3, AlterSpecifications: $4}
   113      }
   114      | COMMENT_START RAW COMMENT_FINISH ';'
   115      {
   116          $$ = &CommentStatement{$2.lit}
   117      }
   118  
   119  optional_statement_finish
   120      :
   121      | ';'
   122  
   123  create_definitions
   124      : create_definition
   125      {
   126          $$ = []CreateDefinition{$1}
   127      }
   128      | create_definitions ',' create_definition
   129      {
   130          $$ = append($1, $3)
   131      }
   132  
   133  create_definition
   134      : column_name column_definition
   135      {
   136          $$ = &CreateDefinitionColumn{ColumnName: $1, ColumnDefinition: $2}
   137      }
   138      | PRIMARY KEY skipable_index_type '(' index_column_names ')'
   139      {
   140          $$ = &CreateDefinitionPrimaryIndex{Columns: $5}
   141      }
   142      | index_or_key skipable_index_name skipable_index_type '(' index_column_names ')' skipable_index_type
   143      {
   144          $$ = &CreateDefinitionIndex{Name: $2, Columns: $5}
   145      }
   146      | UNIQUE index_or_key skipable_index_name skipable_index_type '(' index_column_names ')'
   147      {
   148          $$ = &CreateDefinitionUniqueIndex{Name: $3, Columns: $6}
   149      }
   150  
   151  skipable_table_options
   152   :
   153   {
   154      $$ = []TableOption{}
   155   }
   156   | skipable_table_options table_option
   157   {
   158      $$ = append($1, $2)
   159   }
   160  
   161  table_option
   162      : ENGINE skipable_equal storage_engine_name
   163      {
   164          var option TableOption
   165          option.Key = "ENGINE"
   166          option.Value = $3
   167          $$ = option
   168      }
   169      | AUTO_INCREMENT skipable_equal NUMBER
   170      {
   171          var option TableOption
   172          option.Key = "AUTO_INCREMENT"
   173          option.Value = $3.lit
   174          $$ = option
   175      }
   176      | AVG_ROW_LENGTH skipable_equal NUMBER
   177      {
   178          var option TableOption
   179          option.Key = "AVG_ROW_LENGTH"
   180          option.Value = $3.lit
   181          $$ = option
   182      }
   183      | CHECKSUM skipable_equal NUMBER
   184      {
   185          var option TableOption
   186          option.Key = "CHECKSUM"
   187          option.Value = $3.lit
   188          $$ = option
   189      }
   190      | COMMENT skipable_equal '\'' RAW '\''
   191      {
   192          var option TableOption
   193          option.Key = "COMMENT"
   194          option.Value = $4.lit
   195          $$ = option
   196      }
   197      | KEY_BLOCK_SIZE skipable_equal NUMBER
   198      {
   199          var option TableOption
   200          option.Key = "KEY_BLOCK_SIZE"
   201          option.Value = $3.lit
   202          $$ = option
   203      }
   204      | MAX_ROWS skipable_equal NUMBER
   205      {
   206          var option TableOption
   207          option.Key = "MAX_ROWS"
   208          option.Value = $3.lit
   209          $$ = option
   210      }
   211      | MIN_ROWS skipable_equal NUMBER
   212      {
   213          var option TableOption
   214          option.Key = "MIN_ROWS"
   215          option.Value = $3.lit
   216          $$ = option
   217      }
   218      | ROW_FORMAT skipable_equal storage_engine_name
   219      {
   220          var option TableOption
   221          option.Key = "ROW_FORMAT"
   222          option.Value = $3
   223          $$ = option
   224      }
   225      | DEFAULT CHARSET skipable_equal string
   226      {
   227          var option TableOption
   228          option.Key = "DEFAULT CHARACTER SET"
   229          option.Value = $4
   230          $$ = option
   231      }
   232      | COLLATE skipable_equal string
   233      {
   234          var option TableOption
   235          option.Key = "COLLATE"
   236          option.Value = $3
   237          $$ = option
   238      }
   239  
   240  charset_or_character_set
   241      : CHARSET
   242      | CHARACTER SET
   243  
   244  skipable_equal
   245      :
   246      | '='
   247  
   248  index_column_names
   249      : column_name
   250      {
   251          result := []ColumnNameIdentifier{}
   252          result = append(result, $1)
   253          $$ = result
   254      }
   255      | index_column_names ',' column_name
   256      {
   257          result := append($1, $3)
   258          $$ = result
   259      }
   260  
   261  skipable_index_type
   262      :
   263      | USING BTREE
   264      | USING HASH
   265  
   266  table_names
   267      : table_name
   268      {
   269          $$ = []TableNameIdentifier{$1}
   270      }
   271      | table_names ',' table_name
   272      {
   273          $$ = append([]TableNameIdentifier{$3}, $1...)
   274      }
   275  
   276  table_name
   277      : IDENT
   278      {
   279          $$ = TableNameIdentifier{Name: $1.lit}
   280      }
   281      | '`' RAW '`'
   282      {
   283          $$ = TableNameIdentifier{Name: $2.lit}
   284      }
   285      | IDENT '.' IDENT
   286      {
   287          $$ = TableNameIdentifier{Database: $1.lit, Name: $3.lit}
   288      }
   289  
   290  database_name
   291      : IDENT
   292      {
   293          $$ = DatabaseNameIdentifier{Name: $1.lit}
   294      }
   295      | '`' RAW '`'
   296      {
   297          $$ = DatabaseNameIdentifier{Name: $2.lit}
   298      }
   299  
   300  alter_specifications
   301      :
   302      {
   303          $$ = nil
   304      }
   305      | alter_specification
   306      {
   307          $$ = []AlterSpecification{$1}
   308      }
   309      | alter_specifications ',' alter_specification
   310      {
   311          $$ = append($1, $3)
   312      }
   313  
   314  alter_specification
   315      : ADD skipable_column column_name column_definition
   316      {
   317          $$ = &AlterSpecificationAddColumn{ColumnName: $3, ColumnDefinition: $4}
   318      }
   319      | ADD index_or_key skipable_index_name skipable_index_type '(' index_column_names ')'
   320      {
   321          $$ = &AlterSpecificationAddIndex{Name: $3, Columns: $6, Unique: false}
   322      }
   323      | ADD UNIQUE index_or_key skipable_index_name skipable_index_type '(' index_column_names ')'
   324      {
   325          $$ = &AlterSpecificationAddIndex{Name: $4, Columns: $7, Unique: true}
   326      }
   327      | DROP index_or_key index_name
   328      {
   329          $$ = &AlterSpecificationDropIndex{Name: $3}
   330      }
   331      | DROP skipable_column column_name
   332      {
   333          $$ = &AlterSpecificationDropColumn{ColumnName: $3}
   334      }
   335  
   336  skipable_column
   337      :
   338      | COLUMN
   339  
   340  column_definition
   341      : data_type nullable default autoincrement key_options column_comment
   342      {
   343          $$ = ColumnDefinition{$1, $2, $4, $3}
   344      }
   345  
   346  nullable
   347      :
   348      {
   349          $$ = true
   350      }
   351      | NULL
   352      {
   353          $$ = true
   354      }
   355      | NOT NULL
   356      {
   357          $$ = false
   358      }
   359  
   360  default
   361      :
   362      {
   363          $$ = &DefaultDefinitionEmpty{}
   364      }
   365      | DEFAULT NULL
   366      {
   367          $$ = &DefaultDefinitionNull{}
   368      }
   369      | DEFAULT NUMBER
   370      {
   371          value := DefaultDefinitionString{}
   372          value.Value = $2.lit
   373          $$ = &value
   374      }
   375      | DEFAULT '"' RAW '"'
   376      {
   377          value := DefaultDefinitionString{}
   378          value.Value = $3.lit
   379          $$ = &value
   380      }
   381      | DEFAULT '\'' RAW '\''
   382      {
   383          value := DefaultDefinitionString{}
   384          value.Value = $3.lit
   385          $$ = &value
   386      }
   387      | DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
   388      {
   389          $$ = &DefaultDefinitionCurrentTimestamp{true}
   390      }
   391      | DEFAULT CURRENT_TIMESTAMP
   392      {
   393          $$ = &DefaultDefinitionCurrentTimestamp{false}
   394      }
   395  
   396  string
   397      : IDENT
   398      {
   399          $$ = $1.lit
   400      }
   401      | '\'' RAW '\''
   402      {
   403          $$ = $2.lit
   404      }
   405      | '"' RAW '"'
   406      {
   407          $$ = $2.lit
   408      }
   409  
   410  autoincrement
   411      :
   412      {
   413          $$ = false
   414      }
   415      | AUTO_INCREMENT
   416      {
   417          $$ = true
   418      }
   419  
   420  key_options
   421      :
   422  
   423  column_comment
   424      :
   425      | COMMENT string
   426  
   427  data_type
   428      : BIT
   429      {
   430          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_BIT }
   431      }
   432      | data_type_number length_option unsigned_option zerofill_option
   433      {
   434          $$ = &DataTypeDefinitionNumber{Type: $1, Length: $2, Unsigned: $3, Zerofill: $4 }
   435      }
   436      | data_type_fraction fraction_option unsigned_option zerofill_option
   437      {
   438          fraction := $2
   439          $$ = &DataTypeDefinitionFraction{Type: $1, Length: fraction[0], Decimals: fraction[1], Unsigned: $3, Zerofill: $4 }
   440      }
   441      | data_type_decimal decimal_option unsigned_option zerofill_option
   442      {
   443          fraction := $2
   444          $$ = &DataTypeDefinitionFraction{Type: $1, Length: fraction[0], Decimals: fraction[1], Unsigned: $3, Zerofill: $4 }
   445      }
   446      | DATE
   447      {
   448          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_DATE }
   449      }
   450      | TIME
   451      {
   452          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_TIME }
   453      }
   454      | TIMESTAMP
   455      {
   456          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_TIMESTAMP }
   457      }
   458      | DATETIME
   459      {
   460          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_DATETIME }
   461      }
   462      | YEAR
   463      {
   464          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_YEAR }
   465      }
   466      | CHAR length_option optional_character_set optional_collate
   467      {
   468          $$ = &DataTypeDefinitionString{Type: DATATYPE_CHAR, Length: $2 }
   469      }
   470      | VARCHAR length_option optional_character_set optional_collate
   471      {
   472          $$ = &DataTypeDefinitionString{Type: DATATYPE_VARCHAR, Length: $2 }
   473      }
   474      | BINARY
   475      {
   476          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_BINARY }
   477      }
   478      | VARBINARY
   479      {
   480          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_VARBINARY }
   481      }
   482      | TINYBLOB
   483      {
   484          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_TINYBLOB }
   485      }
   486      | BLOB
   487      {
   488          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_BLOB }
   489      }
   490      | MEDIUMBLOB
   491      {
   492          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_MEDIUMBLOB }
   493      }
   494      | LONGBLOB
   495      {
   496          $$ = &DataTypeDefinitionSimple{Type: DATATYPE_LONGBLOB }
   497      }
   498      | TINYTEXT
   499      {
   500          $$ = &DataTypeDefinitionTextBlob{Type: DATATYPE_TINYTEXT }
   501      }
   502      | TEXT optional_character_set optional_collate
   503      {
   504          $$ = &DataTypeDefinitionTextBlob{Type: DATATYPE_TEXT }
   505      }
   506      | MEDIUMTEXT optional_character_set optional_collate
   507      {
   508          $$ = &DataTypeDefinitionTextBlob{Type: DATATYPE_MEDIUMTEXT }
   509      }
   510      | LONGTEXT optional_character_set optional_collate
   511      {
   512          $$ = &DataTypeDefinitionTextBlob{Type: DATATYPE_LONGTEXT }
   513      }
   514  
   515  data_type_number
   516      : TINYINT
   517      {
   518          $$ = DATATYPE_TINYINT
   519      }
   520      | SMALLINT
   521      {
   522          $$ = DATATYPE_SMALLINT
   523      }
   524      | MEDIUMINT
   525      {
   526          $$ = DATATYPE_MEDIUMINT
   527      }
   528      | INT
   529      {
   530          $$ = DATATYPE_INT
   531      }
   532      | INTEGER
   533      {
   534          $$ = DATATYPE_INT
   535      }
   536      | BIGINT
   537      {
   538          $$ = DATATYPE_BIGINT
   539      }
   540  
   541  data_type_fraction
   542      : REAL
   543      {
   544          $$ = DATATYPE_REAL
   545      }
   546      | DOUBLE
   547      {
   548          $$ = DATATYPE_DOUBLE
   549      }
   550      | FLOAT
   551      {
   552          $$ = DATATYPE_FLOAT
   553      }
   554  
   555  data_type_decimal
   556      : DECIMAL
   557      {
   558          $$ = DATATYPE_DECIMAL
   559      }
   560      | NUMERIC
   561      {
   562          $$ = DATATYPE_NUMERIC
   563      }
   564  
   565  length_option
   566      :
   567      {
   568          $$ = 0
   569      }
   570      | '(' NUMBER ')'
   571      {
   572          num, err := strconv.Atoi($2.lit)
   573          if err != nil {
   574              num = 0
   575          }
   576          $$ = uint(num)
   577      }
   578  
   579  fraction_option
   580      :
   581      {
   582          $$ = [2]uint{0, 0}
   583      }
   584      | '(' NUMBER ',' NUMBER ')'
   585      {
   586          num1, err := strconv.Atoi($2.lit)
   587          if err != nil {
   588              num1 = 0
   589          }
   590          num2, err := strconv.Atoi($4.lit)
   591          if err != nil {
   592              num2 = 0
   593          }
   594          result := [2]uint{0, 0}
   595          result[0] = uint(num1)
   596          result[1] = uint(num2)
   597          $$ = result
   598      }
   599  
   600  optional_character_set
   601      :
   602      | CHARACTER SET string
   603  
   604  optional_collate
   605      :
   606      | COLLATE string
   607  
   608  decimal_option
   609      :
   610      {
   611          $$ = [2]uint{0, 0}
   612      }
   613      | '(' NUMBER ')'
   614      {
   615          result := [2]uint{0, 0}
   616          num1, err := strconv.Atoi($2.lit)
   617          if err != nil {
   618              num1 = 0
   619          }
   620          result[0] = uint(num1)
   621          $$ = result
   622      }
   623      | '(' NUMBER ',' NUMBER ')'
   624      {
   625          num1, err := strconv.Atoi($2.lit)
   626          if err != nil {
   627              num1 = 0
   628          }
   629          num2, err := strconv.Atoi($4.lit)
   630          if err != nil {
   631              num2 = 0
   632          }
   633          result := [2]uint{0, 0}
   634          result[0] = uint(num1)
   635          result[1] = uint(num2)
   636          $$ = result
   637      }
   638  
   639  unsigned_option
   640      :
   641      {
   642          $$ = false
   643      }
   644      | UNSIGNED
   645      {
   646          $$ = true
   647      }
   648  
   649  zerofill_option
   650      :
   651      {
   652          $$ = false
   653      }
   654      | ZEROFILL
   655      {
   656          $$ = true
   657      }
   658  
   659  
   660  index_or_key
   661      : INDEX
   662      | KEY
   663  
   664  column_name
   665      : IDENT
   666      {
   667          $$ = ColumnNameIdentifier{Name: $1.lit}
   668      }
   669      | '`' RAW '`'
   670      {
   671          $$ = ColumnNameIdentifier{Name: $2.lit}
   672      }
   673  
   674  skipable_index_name
   675      :
   676      {
   677          $$ = IndexNameIdentifier{Name: ""}
   678      }
   679      | index_name
   680      {
   681          $$ = $1
   682      }
   683  
   684  index_name
   685      : IDENT
   686      {
   687          $$ = IndexNameIdentifier{Name: $1.lit}
   688      }
   689      | '`' RAW '`'
   690      {
   691          $$ = IndexNameIdentifier{Name: $2.lit}
   692      }
   693  
   694  storage_engine_name
   695      : IDENT
   696      {
   697          $$ = $1.lit
   698      }
   699      | '\'' IDENT '\''
   700      {
   701          $$ = $2.lit
   702      }
   703      | '"' IDENT '\''
   704      {
   705          $$ = $2.lit
   706      }
   707  
   708  skipable_default
   709      :
   710      | DEFAULT
   711  
   712  %%
   713  
   714  type LexerWrapper struct {
   715      scanner *Scanner
   716      recentLit   string
   717      recentPos   Position
   718      statements []Statement
   719  }
   720  
   721  func (l *LexerWrapper) Lex(lval *yySymType) int {
   722      tok, lit, pos := l.scanner.Scan()
   723      if tok == EOF {
   724          return 0
   725      }
   726      lval.tok = Token{tok: tok, lit: lit, pos: pos}
   727      l.recentLit = lit
   728      l.recentPos = pos
   729      return tok
   730  }
   731  
   732  func (l *LexerWrapper) Error(e string) {
   733  }
   734  
   735  func (l *LexerWrapper) GetError(e string) error {
   736      result := fmt.Sprintf("%s while processing near %q line %d, col: %d\n", e, l.recentLit, l.recentPos.Line, l.recentPos.Column)
   737      result += fmt.Sprintf("%s\n", l.scanner.CurrentLine())
   738      for i := 0; i < l.recentPos.Column-1; i++ {
   739          result += fmt.Sprintf(" ")
   740      }
   741      result += fmt.Sprintf("^\n")
   742      return errors.New(result)
   743  }
   744  
   745  func Parse(s *Scanner) ([]Statement, error) {
   746      l := LexerWrapper{scanner: s}
   747      if yyParse(&l) != 0 {
   748          return []Statement{}, l.GetError("syntax error")
   749      }
   750      return l.statements, nil
   751  }