github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/lightning/mydump/parser_test.go (about)

     1  // Copyright 2019 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package mydump_test
    15  
    16  import (
    17  	"context"
    18  	"io"
    19  
    20  	. "github.com/pingcap/check"
    21  	"github.com/pingcap/errors"
    22  	"github.com/pingcap/parser/mysql"
    23  	"github.com/pingcap/tidb/types"
    24  
    25  	"github.com/pingcap/br/pkg/lightning/config"
    26  	"github.com/pingcap/br/pkg/lightning/mydump"
    27  	"github.com/pingcap/br/pkg/lightning/worker"
    28  )
    29  
    30  var _ = Suite(&testMydumpParserSuite{})
    31  
    32  type testMydumpParserSuite struct {
    33  	ioWorkers *worker.Pool
    34  }
    35  
    36  func (s *testMydumpParserSuite) SetUpSuite(c *C) {
    37  	s.ioWorkers = worker.NewPool(context.Background(), 5, "test_sql")
    38  }
    39  func (s *testMydumpParserSuite) TearDownSuite(c *C) {}
    40  
    41  func (s *testMydumpParserSuite) runTestCases(c *C, mode mysql.SQLMode, blockBufSize int64, cases []testCase) {
    42  	for _, tc := range cases {
    43  		parser := mydump.NewChunkParser(mode, mydump.NewStringReader(tc.input), blockBufSize, s.ioWorkers)
    44  		for i, row := range tc.expected {
    45  			e := parser.ReadRow()
    46  			comment := Commentf("input = %q, row = %d, err = %s", tc.input, i+1, errors.ErrorStack(e))
    47  			c.Assert(e, IsNil, comment)
    48  			c.Assert(parser.LastRow().RowID, DeepEquals, int64(i)+1)
    49  			c.Assert(parser.LastRow().Row, DeepEquals, row)
    50  		}
    51  		c.Assert(errors.Cause(parser.ReadRow()), Equals, io.EOF, Commentf("input = %q", tc.input))
    52  	}
    53  }
    54  
    55  func (s *testMydumpParserSuite) runFailingTestCases(c *C, mode mysql.SQLMode, blockBufSize int64, cases []string) {
    56  	for _, tc := range cases {
    57  		parser := mydump.NewChunkParser(mode, mydump.NewStringReader(tc), blockBufSize, s.ioWorkers)
    58  		c.Assert(parser.ReadRow(), ErrorMatches, "syntax error.*", Commentf("input = %q", tc))
    59  	}
    60  }
    61  
    62  func (s *testMydumpParserSuite) TestReadRow(c *C) {
    63  	reader := mydump.NewStringReader(
    64  		"/* whatever pragmas */;" +
    65  			"INSERT INTO `namespaced`.`table` (columns, more, columns) VALUES (1,-2, 3),\n(4,5., 6);" +
    66  			"INSERT `namespaced`.`table` (x,y,z) VALUES (7,8,9);" +
    67  			"insert another_table values (10,11e1,12, '(13)', '(', 14, ')');",
    68  	)
    69  
    70  	parser := mydump.NewChunkParser(mysql.ModeNone, reader, int64(config.ReadBlockSize), s.ioWorkers)
    71  
    72  	c.Assert(parser.ReadRow(), IsNil)
    73  	c.Assert(parser.LastRow(), DeepEquals, mydump.Row{
    74  		RowID: 1,
    75  		Row: []types.Datum{
    76  			types.NewUintDatum(1),
    77  			types.NewIntDatum(-2),
    78  			types.NewUintDatum(3),
    79  		},
    80  		Length: 62,
    81  	})
    82  	c.Assert(parser.Columns(), DeepEquals, []string{"columns", "more", "columns"})
    83  	offset, rowID := parser.Pos()
    84  	c.Assert(offset, Equals, int64(97))
    85  	c.Assert(rowID, Equals, int64(1))
    86  
    87  	c.Assert(parser.ReadRow(), IsNil)
    88  	c.Assert(parser.LastRow(), DeepEquals, mydump.Row{
    89  		RowID: 2,
    90  		Row: []types.Datum{
    91  			types.NewUintDatum(4),
    92  			types.NewStringDatum("5."),
    93  			types.NewUintDatum(6),
    94  		},
    95  		Length: 6,
    96  	})
    97  	c.Assert(parser.Columns(), DeepEquals, []string{"columns", "more", "columns"})
    98  	offset, rowID = parser.Pos()
    99  	c.Assert(offset, Equals, int64(108))
   100  	c.Assert(rowID, Equals, int64(2))
   101  
   102  	c.Assert(parser.ReadRow(), IsNil)
   103  	c.Assert(parser.LastRow(), DeepEquals, mydump.Row{
   104  		RowID: 3,
   105  		Row: []types.Datum{
   106  			types.NewUintDatum(7),
   107  			types.NewUintDatum(8),
   108  			types.NewUintDatum(9),
   109  		},
   110  		Length: 42,
   111  	})
   112  	c.Assert(parser.Columns(), DeepEquals, []string{"x", "y", "z"})
   113  	offset, rowID = parser.Pos()
   114  	c.Assert(offset, Equals, int64(159))
   115  	c.Assert(rowID, Equals, int64(3))
   116  
   117  	c.Assert(parser.ReadRow(), IsNil)
   118  	c.Assert(parser.LastRow(), DeepEquals, mydump.Row{
   119  		RowID: 4,
   120  		Row: []types.Datum{
   121  			types.NewUintDatum(10),
   122  			types.NewStringDatum("11e1"),
   123  			types.NewUintDatum(12),
   124  			types.NewStringDatum("(13)"),
   125  			types.NewStringDatum("("),
   126  			types.NewUintDatum(14),
   127  			types.NewStringDatum(")"),
   128  		},
   129  		Length: 49,
   130  	})
   131  	c.Assert(parser.Columns(), IsNil)
   132  	offset, rowID = parser.Pos()
   133  	c.Assert(offset, Equals, int64(222))
   134  	c.Assert(rowID, Equals, int64(4))
   135  
   136  	c.Assert(errors.Cause(parser.ReadRow()), Equals, io.EOF)
   137  }
   138  
   139  func (s *testMydumpParserSuite) TestReadChunks(c *C) {
   140  	reader := mydump.NewStringReader(`
   141  		INSERT foo VALUES (1,2,3,4),(5,6,7,8),(9,10,11,12);
   142  		INSERT foo VALUES (13,14,15,16),(17,18,19,20),(21,22,23,24),(25,26,27,28);
   143  		INSERT foo VALUES (29,30,31,32),(33,34,35,36);
   144  	`)
   145  
   146  	parser := mydump.NewChunkParser(mysql.ModeNone, reader, int64(config.ReadBlockSize), s.ioWorkers)
   147  
   148  	chunks, err := mydump.ReadChunks(parser, 32)
   149  	c.Assert(err, IsNil)
   150  	c.Assert(chunks, DeepEquals, []mydump.Chunk{
   151  		{
   152  			Offset:       0,
   153  			EndOffset:    40,
   154  			PrevRowIDMax: 0,
   155  			RowIDMax:     2,
   156  		},
   157  		{
   158  			Offset:       40,
   159  			EndOffset:    88,
   160  			PrevRowIDMax: 2,
   161  			RowIDMax:     4,
   162  		},
   163  		{
   164  			Offset:       88,
   165  			EndOffset:    130,
   166  			PrevRowIDMax: 4,
   167  			RowIDMax:     7,
   168  		},
   169  		{
   170  			Offset:       130,
   171  			EndOffset:    165,
   172  			PrevRowIDMax: 7,
   173  			RowIDMax:     8,
   174  		},
   175  		{
   176  			Offset:       165,
   177  			EndOffset:    179,
   178  			PrevRowIDMax: 8,
   179  			RowIDMax:     9,
   180  		},
   181  	})
   182  }
   183  
   184  func (s *testMydumpParserSuite) TestNestedRow(c *C) {
   185  	reader := mydump.NewStringReader(`
   186  		INSERT INTO exam_detail VALUES
   187  		("123",CONVERT("{}" USING UTF8MB4)),
   188  		("456",CONVERT("{\"a\":4}" USING UTF8MB4)),
   189  		("789",CONVERT("[]" USING UTF8MB4));
   190  	`)
   191  
   192  	parser := mydump.NewChunkParser(mysql.ModeNone, reader, int64(config.ReadBlockSize), s.ioWorkers)
   193  	chunks, err := mydump.ReadChunks(parser, 96)
   194  
   195  	c.Assert(err, IsNil)
   196  	c.Assert(chunks, DeepEquals, []mydump.Chunk{
   197  		{
   198  			Offset:       0,
   199  			EndOffset:    117,
   200  			PrevRowIDMax: 0,
   201  			RowIDMax:     2,
   202  		},
   203  		{
   204  			Offset:       117,
   205  			EndOffset:    156,
   206  			PrevRowIDMax: 2,
   207  			RowIDMax:     3,
   208  		},
   209  	})
   210  }
   211  
   212  func (s *testMydumpParserSuite) TestVariousSyntax(c *C) {
   213  	testCases := []testCase{
   214  		{
   215  			input:    "INSERT INTO foobar VALUES (1, 2);",
   216  			expected: [][]types.Datum{{types.NewUintDatum(1), types.NewUintDatum(2)}},
   217  		},
   218  		{
   219  			input:    "INSERT INTO `foobar` VALUES (3, 4);",
   220  			expected: [][]types.Datum{{types.NewUintDatum(3), types.NewUintDatum(4)}},
   221  		},
   222  		{
   223  			input:    `INSERT INTO "foobar" VALUES (5, 6);`,
   224  			expected: [][]types.Datum{{types.NewUintDatum(5), types.NewUintDatum(6)}},
   225  		},
   226  		{
   227  			input: `(7, -8, Null, '9'), (b'10', 0b11, 0x12, x'13'), ("14", True, False, 0)`,
   228  			expected: [][]types.Datum{
   229  				{
   230  					types.NewUintDatum(7),
   231  					types.NewIntDatum(-8),
   232  					nullDatum,
   233  					types.NewStringDatum("9"),
   234  				},
   235  				{
   236  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{2})),
   237  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{3})),
   238  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x12})),
   239  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x13})),
   240  				},
   241  				{
   242  					types.NewStringDatum("14"),
   243  					types.NewIntDatum(1),
   244  					types.NewIntDatum(0),
   245  					types.NewUintDatum(0),
   246  				},
   247  			},
   248  		},
   249  		{
   250  			input: `
   251  				(.15, 1.6, 17.),
   252  				(.18e1, 1.9e1, 20.e1), (.21e-1, 2.2e-1, 23.e-1), (.24e+1, 2.5e+1, 26.e+1),
   253  				(-.27, -2.8, -29.),
   254  				(-.30e1, -3.1e1, -32.e1), (-.33e-1, -3.4e-1, -35.e-1), (-.36e+1, -3.7e+1, -38.e+1),
   255  				(1e39, 1e-40, 1e+41),
   256  				(.42E1, 4.3E1, 44.E1), (.45E-1, 4.6E-1, 47.E-1), (.48E+1, 4.9E+1, 50.E+1),
   257  				(-.51E1, -5.2E1, -53.E1), (-.54E-1, -5.5E-1, -56.E-1), (-.57E+1, -5.8E+1, -59.E+1),
   258  				(1E60, 1E-61, 1E+62),
   259  				(6.33333333333333333333333333333333333333333333, -6.44444444444444444444444444444444444444444444, -0.0),
   260  				(65555555555555555555555555555555555555555555.5, -66666666666666666666666666666666666666666666.6, 0.0)
   261  			`,
   262  			expected: [][]types.Datum{
   263  				{types.NewStringDatum(".15"), types.NewStringDatum("1.6"), types.NewStringDatum("17.")},
   264  				{types.NewStringDatum(".18e1"), types.NewStringDatum("1.9e1"), types.NewStringDatum("20.e1")},
   265  				{types.NewStringDatum(".21e-1"), types.NewStringDatum("2.2e-1"), types.NewStringDatum("23.e-1")},
   266  				{types.NewStringDatum(".24e+1"), types.NewStringDatum("2.5e+1"), types.NewStringDatum("26.e+1")},
   267  				{types.NewStringDatum("-.27"), types.NewStringDatum("-2.8"), types.NewStringDatum("-29.")},
   268  				{types.NewStringDatum("-.30e1"), types.NewStringDatum("-3.1e1"), types.NewStringDatum("-32.e1")},
   269  				{types.NewStringDatum("-.33e-1"), types.NewStringDatum("-3.4e-1"), types.NewStringDatum("-35.e-1")},
   270  				{types.NewStringDatum("-.36e+1"), types.NewStringDatum("-3.7e+1"), types.NewStringDatum("-38.e+1")},
   271  				{types.NewStringDatum("1e39"), types.NewStringDatum("1e-40"), types.NewStringDatum("1e+41")},
   272  				{types.NewStringDatum(".42E1"), types.NewStringDatum("4.3E1"), types.NewStringDatum("44.E1")},
   273  				{types.NewStringDatum(".45E-1"), types.NewStringDatum("4.6E-1"), types.NewStringDatum("47.E-1")},
   274  				{types.NewStringDatum(".48E+1"), types.NewStringDatum("4.9E+1"), types.NewStringDatum("50.E+1")},
   275  				{types.NewStringDatum("-.51E1"), types.NewStringDatum("-5.2E1"), types.NewStringDatum("-53.E1")},
   276  				{types.NewStringDatum("-.54E-1"), types.NewStringDatum("-5.5E-1"), types.NewStringDatum("-56.E-1")},
   277  				{types.NewStringDatum("-.57E+1"), types.NewStringDatum("-5.8E+1"), types.NewStringDatum("-59.E+1")},
   278  				{types.NewStringDatum("1E60"), types.NewStringDatum("1E-61"), types.NewStringDatum("1E+62")},
   279  				{
   280  					types.NewStringDatum("6.33333333333333333333333333333333333333333333"),
   281  					types.NewStringDatum("-6.44444444444444444444444444444444444444444444"),
   282  					types.NewStringDatum("-0.0"),
   283  				},
   284  				{
   285  					types.NewStringDatum("65555555555555555555555555555555555555555555.5"),
   286  					types.NewStringDatum("-66666666666666666666666666666666666666666666.6"),
   287  					types.NewStringDatum("0.0"),
   288  				},
   289  			},
   290  		},
   291  		{
   292  			input: `
   293  				(0x123456ABCDEFabcdef, 0xABCDEF123456, 0xabcdef123456, 0x123),
   294  				(x'123456ABCDEFabcdef', x'ABCDEF123456', x'abcdef123456', x''),
   295  				(X'123456ABCDEFabcdef', X'ABCDEF123456', X'abcdef123456', X''),
   296  				(
   297  					0b101010101010101010101010101010101010101010101010101010101010101010,
   298  					b'010101010101010101010101010101010101010101010101010101010101010101',
   299  					B'110011001100110011001100110011001100110011001100110011001100',
   300  					b'',
   301  					B''
   302  				)
   303  			`,
   304  			expected: [][]types.Datum{
   305  				{
   306  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x12, 0x34, 0x56, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef})),
   307  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   308  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   309  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x01, 0x23})),
   310  				},
   311  				{
   312  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x12, 0x34, 0x56, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef})),
   313  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   314  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   315  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{})),
   316  				},
   317  				{
   318  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x12, 0x34, 0x56, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef})),
   319  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   320  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0xab, 0xcd, 0xef, 0x12, 0x34, 0x56})),
   321  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{})),
   322  				},
   323  				{
   324  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x02, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa})),
   325  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55})),
   326  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc})),
   327  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{})),
   328  					types.NewBinaryLiteralDatum(types.BinaryLiteral([]byte{})),
   329  				},
   330  			},
   331  		},
   332  		{
   333  			input:    "/* comment */; -- comment",
   334  			expected: [][]types.Datum{},
   335  		},
   336  		{
   337  			input: `
   338  				-- comment /* ...
   339  				insert into xxx -- comment
   340  				values -- comment
   341  				(true, false), -- comment
   342  				(null, 00000); -- comment ... */
   343  			`,
   344  			expected: [][]types.Datum{
   345  				{types.NewIntDatum(1), types.NewIntDatum(0)},
   346  				{nullDatum, types.NewUintDatum(0)},
   347  			},
   348  		},
   349  		{
   350  			input:    `('\0\b\n\r\t\Z\'\a')`,
   351  			expected: [][]types.Datum{{types.NewStringDatum("\x00\b\n\r\t\x1a'a")}},
   352  		},
   353  		{
   354  			input:    `(CONVERT("[1,2,3]" USING UTF8MB4))`,
   355  			expected: [][]types.Datum{{types.NewStringDatum("[1,2,3]")}},
   356  		},
   357  	}
   358  
   359  	s.runTestCases(c, mysql.ModeNone, int64(config.ReadBlockSize), testCases)
   360  }
   361  
   362  func (s *testMydumpParserSuite) TestContinuation(c *C) {
   363  	testCases := []testCase{
   364  		{
   365  			input: `
   366  				('FUZNtcGYegeXwnMRKtYnXtFhgnAMTzQHEBUTBehAFBQdPsnjHhRwRZhZLtEBsIDUFduzftskgxkYkPmEgvoirfIZRsARXjsdKwOc')
   367  			`,
   368  			expected: [][]types.Datum{
   369  				{types.NewStringDatum("FUZNtcGYegeXwnMRKtYnXtFhgnAMTzQHEBUTBehAFBQdPsnjHhRwRZhZLtEBsIDUFduzftskgxkYkPmEgvoirfIZRsARXjsdKwOc")},
   370  			},
   371  		},
   372  		{
   373  			input: "INSERT INTO `report_case_high_risk` VALUES (2,'4','6',8,10);",
   374  			expected: [][]types.Datum{
   375  				{types.NewUintDatum(2), types.NewStringDatum("4"), types.NewStringDatum("6"), types.NewUintDatum(8), types.NewUintDatum(10)},
   376  			},
   377  		},
   378  	}
   379  
   380  	s.runTestCases(c, mysql.ModeNone, 1, testCases)
   381  }
   382  
   383  func (s *testMydumpParserSuite) TestPseudoKeywords(c *C) {
   384  	reader := mydump.NewStringReader(`
   385  		INSERT INTO t (
   386  			c, C,
   387  			co, CO,
   388  			con, CON,
   389  			conv, CONV,
   390  			conve, CONVE,
   391  			conver, CONVER,
   392  			convert, CONVERT,
   393  			u, U,
   394  			us, US,
   395  			usi, USI,
   396  			usin, USIN,
   397  			ut, UT,
   398  			utf, UTF,
   399  			utf8, UTF8,
   400  			utf8m, UTF8M,
   401  			utf8mb, UTF8MB,
   402  			utf8mb4, UTF8MB4,
   403  			t, T,
   404  			tr, TR,
   405  			tru, TRU,
   406  			f, F,
   407  			fa, FA,
   408  			fal, FAL,
   409  			fals, FALS,
   410  			n, N,
   411  			nu, NU,
   412  			nul, NUL,
   413  			v, V,
   414  			va, VA,
   415  			val, VAL,
   416  			valu, VALU,
   417  			value, VALUE,
   418  			i, I,
   419  			ins, INS,
   420  			inse, INSE,
   421  			inser, INSER,
   422  		) VALUES ();
   423  	`)
   424  
   425  	parser := mydump.NewChunkParser(mysql.ModeNone, reader, int64(config.ReadBlockSize), s.ioWorkers)
   426  	c.Assert(parser.ReadRow(), IsNil)
   427  	c.Assert(parser.Columns(), DeepEquals, []string{
   428  		"c", "c",
   429  		"co", "co",
   430  		"con", "con",
   431  		"conv", "conv",
   432  		"conve", "conve",
   433  		"conver", "conver",
   434  		"convert", "convert",
   435  		"u", "u",
   436  		"us", "us",
   437  		"usi", "usi",
   438  		"usin", "usin",
   439  		"ut", "ut",
   440  		"utf", "utf",
   441  		"utf8", "utf8",
   442  		"utf8m", "utf8m",
   443  		"utf8mb", "utf8mb",
   444  		"utf8mb4", "utf8mb4",
   445  		"t", "t",
   446  		"tr", "tr",
   447  		"tru", "tru",
   448  		"f", "f",
   449  		"fa", "fa",
   450  		"fal", "fal",
   451  		"fals", "fals",
   452  		"n", "n",
   453  		"nu", "nu",
   454  		"nul", "nul",
   455  		"v", "v",
   456  		"va", "va",
   457  		"val", "val",
   458  		"valu", "valu",
   459  		"value", "value",
   460  		"i", "i",
   461  		"ins", "ins",
   462  		"inse", "inse",
   463  		"inser", "inser",
   464  	})
   465  }
   466  
   467  func (s *testMydumpParserSuite) TestSyntaxError(c *C) {
   468  	inputs := []string{
   469  		"('xxx)",
   470  		`("xxx)`,
   471  		"(`xxx)",
   472  		"(/* xxx)",
   473  		`('\')`,
   474  		`("\")`,
   475  		`('\)`,
   476  		`("\)`,
   477  		"(",
   478  		"(1",
   479  		"(1,",
   480  		"(values)",
   481  		"insert into e (f",
   482  		"insert into e (3) values (4)",
   483  		"insert into e ('3') values (4)",
   484  		"insert into e (0x3) values (4)",
   485  		"insert into e (x'3') values (4)",
   486  		"insert into e (b'3') values (4)",
   487  		"3",
   488  		"(`values`)",
   489  		"/* ...",
   490  	}
   491  
   492  	s.runFailingTestCases(c, mysql.ModeNone, int64(config.ReadBlockSize), inputs)
   493  }
   494  
   495  // Various syntax error cases collected via fuzzing.
   496  // These cover most of the tokenizer branches.
   497  
   498  func (s *testMydumpParserSuite) TestMoreSyntaxError(c *C) {
   499  	inputs := []string{
   500  		" usin0",
   501  		"- ",
   502  		"-,",
   503  		"-;",
   504  		"-",
   505  		"-(",
   506  		"-/",
   507  		"-\"",
   508  		"-`",
   509  		", '0\\0",
   510  		",/*000",
   511  		"; con0",
   512  		";CONV0",
   513  		";using UTF0",
   514  		"''",
   515  		"'",
   516  		"'\\",
   517  		"'\\\\",
   518  		"'0''00",
   519  		"'0'",
   520  		"'0\\",
   521  		"(''''0",
   522  		"(''0'0",
   523  		"(fals0",
   524  		"(x'000",
   525  		"*",
   526  		"/",
   527  		"/**",
   528  		"/***",
   529  		"/**0",
   530  		"/*00*0",
   531  		"/0",
   532  		"\"",
   533  		"\"\"",
   534  		"\"\"\"0\\0",
   535  		"\"\\",
   536  		"\"\\\\",
   537  		"\"0\"",
   538  		"\"0\"\x00\"0",
   539  		"\"0\\",
   540  		"\"0000\"\"\"\"\"0",
   541  		"\"00000",
   542  		"\x00;",
   543  		"\xd9/",
   544  		"\xde0 b'0",
   545  		"\xed00000",
   546  		"``",
   547  		"`````0",
   548  		"0 ",
   549  		"0-\"",
   550  		"0,",
   551  		"0;",
   552  		"0",
   553  		"0/",
   554  		"0\"",
   555  		"0\x00 CONVERT0",
   556  		"0\x00\"\"C0",
   557  		"0\x03\fFa0",
   558  		"0`",
   559  		"00 ",
   560  		"00/",
   561  		"00\"",
   562  		"00`",
   563  		"000\xf1/0",
   564  		"00a t0",
   565  		"00b b0",
   566  		"00d f0",
   567  		"00e u0",
   568  		"00l 00",
   569  		"00l v0",
   570  		"00n -0",
   571  		"00n Using UTF8M0",
   572  		"00t using 0",
   573  		"00t x0",
   574  		"0a VA0",
   575  		"0b ",
   576  		"0b;",
   577  		"0b'",
   578  		"0b",
   579  		"0b/",
   580  		"0b\"",
   581  		"0b`",
   582  		"0b0000",
   583  		"0by",
   584  		"0O,CO0",
   585  		"0r tr0",
   586  		"0s us0",
   587  		"0T``CONVER0",
   588  		"0u\vnu0",
   589  		"0x ",
   590  		"0x;",
   591  		"0x",
   592  		"0x/",
   593  		"0x\"",
   594  		"0x\n",
   595  		"0x\x00",
   596  		"0x`",
   597  		"0x0000",
   598  		"6;",
   599  		"a`00`0",
   600  		"b ",
   601  		"b,",
   602  		"B;",
   603  		"b'",
   604  		"b",
   605  		"b/",
   606  		"b\"",
   607  		"B\f",
   608  		"b`",
   609  		"b0",
   610  		"C ",
   611  		"C;",
   612  		"C",
   613  		"C/",
   614  		"C\"",
   615  		"C\n",
   616  		"C`",
   617  		"C0",
   618  		"CO ",
   619  		"CO;",
   620  		"CO",
   621  		"CO/",
   622  		"CO\"",
   623  		"CO\v",
   624  		"CO`",
   625  		"CON ",
   626  		"CON;",
   627  		"CON",
   628  		"CON/",
   629  		"CON\"",
   630  		"CON\v",
   631  		"CON`",
   632  		"CON0",
   633  		"CONV ",
   634  		"CONV;",
   635  		"CONv",
   636  		"CONV/",
   637  		"CONV\"",
   638  		"CONV\v",
   639  		"CONV`",
   640  		"CONV0",
   641  		"CONVE ",
   642  		"CONVE;",
   643  		"CONVE",
   644  		"CONVE/",
   645  		"CONVE\"",
   646  		"CONVE\v",
   647  		"CONVE`",
   648  		"CONVE0",
   649  		"CONVER ",
   650  		"CONVER;",
   651  		"CONVER",
   652  		"CONVER/",
   653  		"CONVER\"",
   654  		"CONVER\n",
   655  		"CONVER`",
   656  		"CONVER0",
   657  		"CONVERT ",
   658  		"CONVERT;",
   659  		"CONVERT",
   660  		"CONVERT/",
   661  		"CONVERT\"",
   662  		"CONVERT\n",
   663  		"CONVERT`",
   664  		"CONVERT0",
   665  		"e tru0",
   666  		"f ",
   667  		"f;",
   668  		"F/",
   669  		"f\"",
   670  		"F\f",
   671  		"f`",
   672  		"fa ",
   673  		"Fa;",
   674  		"fa",
   675  		"FA/",
   676  		"FA\"",
   677  		"Fa\f",
   678  		"FA`",
   679  		"fa0",
   680  		"fal ",
   681  		"fal;",
   682  		"Fal",
   683  		"fal/",
   684  		"FAL\"",
   685  		"FAL\n",
   686  		"FAl`",
   687  		"fal0",
   688  		"fals ",
   689  		"fals;",
   690  		"fals",
   691  		"fals/",
   692  		"fals\"",
   693  		"fals\n",
   694  		"fals`",
   695  		"FALS0",
   696  		"FALSE",
   697  		"g Using UT0",
   698  		"N ",
   699  		"N NUL0",
   700  		"n;",
   701  		"N",
   702  		"N/",
   703  		"n\"",
   704  		"n\v",
   705  		"n`",
   706  		"N0",
   707  		"n00\vn0",
   708  		"nu ",
   709  		"nu;",
   710  		"nu",
   711  		"nu/",
   712  		"nU\"",
   713  		"nu\v",
   714  		"nu`",
   715  		"nu0",
   716  		"NUL ",
   717  		"nuL;",
   718  		"nul",
   719  		"NuL/",
   720  		"NUL\"",
   721  		"NUL\f",
   722  		"nul`",
   723  		"nul0",
   724  		"NULL",
   725  		"O",
   726  		"R FAL0",
   727  		"t n(50",
   728  		"t usi0",
   729  		"t using UTF80",
   730  		"t using UTF8M",
   731  		"t;",
   732  		"t",
   733  		"t/",
   734  		"t\"",
   735  		"t\f",
   736  		"t`",
   737  		"t0 USING U0",
   738  		"t0",
   739  		"tr ",
   740  		"Tr;",
   741  		"tr",
   742  		"tr/",
   743  		"tr\"",
   744  		"tr\f",
   745  		"tr`",
   746  		"tr0",
   747  		"tru ",
   748  		"trU;",
   749  		"TRU",
   750  		"TrU/",
   751  		"tru\"",
   752  		"tru\f",
   753  		"tru`",
   754  		"TRU0",
   755  		"TRUE",
   756  		"u ",
   757  		"u;",
   758  		"u",
   759  		"u/",
   760  		"U\"",
   761  		"u\t",
   762  		"u`",
   763  		"us ",
   764  		"us;",
   765  		"us",
   766  		"us/",
   767  		"US\"",
   768  		"us\t",
   769  		"us`",
   770  		"us0",
   771  		"usi ",
   772  		"usi;",
   773  		"usi",
   774  		"usi/",
   775  		"usi\"",
   776  		"usi\t",
   777  		"usi`",
   778  		"usi0",
   779  		"usin ",
   780  		"usiN;",
   781  		"USIN",
   782  		"usin/",
   783  		"usin\"",
   784  		"usin\t",
   785  		"usin`",
   786  		"USIN0",
   787  		"using ",
   788  		"using 0",
   789  		"using u",
   790  		"USING U",
   791  		"USING U0",
   792  		"USING Ut",
   793  		"using UT0",
   794  		"using utF",
   795  		"using UTf",
   796  		"using utF0",
   797  		"using utf8",
   798  		"using UTF80",
   799  		"using UTF8m",
   800  		"Using UTF8M0",
   801  		"Using UTF8MB",
   802  		"Using utf8mb",
   803  		"using,",
   804  		"using;",
   805  		"using",
   806  		"USING",
   807  		"using/",
   808  		"using\"",
   809  		"using\v",
   810  		"using`",
   811  		"using0",
   812  		"v ",
   813  		"v;",
   814  		"v",
   815  		"V/",
   816  		"V\"",
   817  		"v\v",
   818  		"v`",
   819  		"v0",
   820  		"va ",
   821  		"va;",
   822  		"va",
   823  		"va/",
   824  		"Va\"",
   825  		"va\v",
   826  		"va`",
   827  		"va0",
   828  		"val ",
   829  		"val;",
   830  		"val",
   831  		"val/",
   832  		"Val\"",
   833  		"VAL\v",
   834  		"val`",
   835  		"val0",
   836  		"valu ",
   837  		"valu;",
   838  		"valu",
   839  		"valu/",
   840  		"valu\"",
   841  		"VALU\t",
   842  		"VALU`",
   843  		"valu0",
   844  		"value ",
   845  		"value;",
   846  		"value",
   847  		"Value/",
   848  		"Value\"",
   849  		"VALUE\v",
   850  		"value`",
   851  		"value0",
   852  		"x ",
   853  		"x val0",
   854  		"x;",
   855  		"x'",
   856  		"x'x",
   857  		"x",
   858  		"x/",
   859  		"x\"",
   860  		"X\r",
   861  		"x`",
   862  		"x00`0`Valu0",
   863  	}
   864  
   865  	s.runFailingTestCases(c, mysql.ModeNone, 1, inputs)
   866  	s.runFailingTestCases(c, mysql.ModeNoBackslashEscapes, 1, inputs)
   867  }
   868  
   869  func (s *testMydumpParserSuite) TestMoreEmptyFiles(c *C) {
   870  	testCases := []testCase{
   871  		{input: ""},
   872  		{input: "--\t"},
   873  		{input: "--\""},
   874  		{input: "-- 000"},
   875  		{input: "--;"},
   876  		{input: "--,"},
   877  		{input: "--0"},
   878  		{input: "--`"},
   879  		{input: "--"},
   880  		{input: "--0000"},
   881  		{input: "--\n"},
   882  		{input: "--/"},
   883  		{input: "--\"\r"},
   884  		{input: "--\r"},
   885  	}
   886  
   887  	s.runTestCases(c, mysql.ModeNone, 1, testCases)
   888  	s.runTestCases(c, mysql.ModeNoBackslashEscapes, 1, testCases)
   889  }