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