TiDB has no concept like mysql's "table cache" and "open table" For simplicity, we just return an empty result with the same structure as MySQL's SHOW OPEN TABLES
478 lines
21 KiB
Go
478 lines
21 KiB
Go
// Copyright 2016 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package executor_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
. "github.com/pingcap/check"
|
|
"github.com/pingcap/errors"
|
|
"github.com/pingcap/parser/auth"
|
|
"github.com/pingcap/parser/model"
|
|
"github.com/pingcap/parser/mysql"
|
|
"github.com/pingcap/tidb/domain"
|
|
"github.com/pingcap/tidb/executor"
|
|
plannercore "github.com/pingcap/tidb/planner/core"
|
|
"github.com/pingcap/tidb/session"
|
|
"github.com/pingcap/tidb/sessionctx"
|
|
"github.com/pingcap/tidb/util/testkit"
|
|
"github.com/pingcap/tidb/util/testutil"
|
|
)
|
|
|
|
func (s *testSuite2) TestShowVisibility(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("create database showdatabase")
|
|
tk.MustExec("use showdatabase")
|
|
tk.MustExec("create table t1 (id int)")
|
|
tk.MustExec("create table t2 (id int)")
|
|
tk.MustExec(`create user 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
|
|
tk1 := testkit.NewTestKit(c, s.store)
|
|
se, err := session.CreateSession4Test(s.store)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(se.Auth(&auth.UserIdentity{Username: "show", Hostname: "%"}, nil, nil), IsTrue)
|
|
tk1.Se = se
|
|
|
|
// No ShowDatabases privilege, this user would see nothing except INFORMATION_SCHEMA.
|
|
tk.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA"))
|
|
|
|
// After grant, the user can see the database.
|
|
tk.MustExec(`grant select on showdatabase.t1 to 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
tk1.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA", "showdatabase"))
|
|
|
|
// The user can see t1 but not t2.
|
|
tk1.MustExec("use showdatabase")
|
|
tk1.MustQuery("show tables").Check(testkit.Rows("t1"))
|
|
|
|
// After revoke, show database result should be just except INFORMATION_SCHEMA.
|
|
tk.MustExec(`revoke select on showdatabase.t1 from 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
tk1.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA"))
|
|
|
|
// Grant any global privilege would make show databases available.
|
|
tk.MustExec(`grant CREATE on *.* to 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
rows := tk1.MustQuery("show databases").Rows()
|
|
c.Assert(len(rows), GreaterEqual, 2) // At least INFORMATION_SCHEMA and showdatabase
|
|
|
|
tk.MustExec(`drop user 'show'@'%'`)
|
|
tk.MustExec("drop database showdatabase")
|
|
}
|
|
|
|
func (s *testSuite2) TestShowDatabasesInfoSchemaFirst(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA"))
|
|
tk.MustExec(`create user 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
|
|
tk.MustExec(`create database AAAA`)
|
|
tk.MustExec(`create database BBBB`)
|
|
tk.MustExec(`grant select on AAAA.* to 'show'@'%'`)
|
|
tk.MustExec(`grant select on BBBB.* to 'show'@'%'`)
|
|
tk.MustExec(`flush privileges`)
|
|
|
|
tk1 := testkit.NewTestKit(c, s.store)
|
|
se, err := session.CreateSession4Test(s.store)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(se.Auth(&auth.UserIdentity{Username: "show", Hostname: "%"}, nil, nil), IsTrue)
|
|
tk1.Se = se
|
|
tk1.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA", "AAAA", "BBBB"))
|
|
|
|
tk.MustExec(`drop user 'show'@'%'`)
|
|
tk.MustExec(`drop database AAAA`)
|
|
tk.MustExec(`drop database BBBB`)
|
|
}
|
|
|
|
// mockSessionManager is a mocked session manager that wraps one session
|
|
// it returns only this session's current process info as processlist for test.
|
|
type mockSessionManager struct {
|
|
session.Session
|
|
}
|
|
|
|
// Kill implements the SessionManager.Kill interface.
|
|
func (msm *mockSessionManager) Kill(cid uint64, query bool) {
|
|
}
|
|
|
|
func (s *testSuite2) TestShowWarnings(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
testSQL := `create table if not exists show_warnings (a int)`
|
|
tk.MustExec(testSQL)
|
|
tk.MustExec("set @@sql_mode=''")
|
|
tk.MustExec("insert show_warnings values ('a')")
|
|
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(1))
|
|
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1265|Data Truncated"))
|
|
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0))
|
|
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1265|Data Truncated"))
|
|
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0))
|
|
|
|
// Test Warning level 'Error'
|
|
testSQL = `create table show_warnings (a int)`
|
|
tk.Exec(testSQL)
|
|
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(1))
|
|
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Error|1050|Table 'test.show_warnings' already exists"))
|
|
tk.MustQuery("select @@error_count").Check(testutil.RowsWithSep("|", "1"))
|
|
|
|
// Test Warning level 'Note'
|
|
testSQL = `create table show_warnings_2 (a int)`
|
|
tk.MustExec(testSQL)
|
|
testSQL = `create table if not exists show_warnings_2 like show_warnings`
|
|
tk.Exec(testSQL)
|
|
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(1))
|
|
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Note|1050|Table 'test.show_warnings_2' already exists"))
|
|
tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "1"))
|
|
tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "0"))
|
|
}
|
|
|
|
func (s *testSuite2) TestShowErrors(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
testSQL := `create table if not exists show_errors (a int)`
|
|
tk.MustExec(testSQL)
|
|
testSQL = `create table show_errors (a int)`
|
|
tk.Exec(testSQL)
|
|
|
|
tk.MustQuery("show errors").Check(testutil.RowsWithSep("|", "Error|1050|Table 'test.show_errors' already exists"))
|
|
}
|
|
|
|
func (s *testSuite2) TestIssue3641(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
_, err := tk.Exec("show tables;")
|
|
c.Assert(err.Error(), Equals, plannercore.ErrNoDB.Error())
|
|
_, err = tk.Exec("show table status;")
|
|
c.Assert(err.Error(), Equals, plannercore.ErrNoDB.Error())
|
|
}
|
|
|
|
// TestShow2 is moved from session_test
|
|
func (s *testSuite2) TestShow2(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
|
|
tk.MustExec("set global autocommit=0")
|
|
tk1 := testkit.NewTestKit(c, s.store)
|
|
tk1.MustQuery("show global variables where variable_name = 'autocommit'").Check(testkit.Rows("autocommit 0"))
|
|
tk.MustExec("set global autocommit = 1")
|
|
tk2 := testkit.NewTestKit(c, s.store)
|
|
// TODO: In MySQL, the result is "autocommit ON".
|
|
tk2.MustQuery("show global variables where variable_name = 'autocommit'").Check(testkit.Rows("autocommit 1"))
|
|
|
|
// TODO: Specifying the charset for national char/varchar should not be supported.
|
|
tk.MustExec("drop table if exists test_full_column")
|
|
tk.MustExec(`create table test_full_column(
|
|
c_int int,
|
|
c_float float,
|
|
c_bit bit,
|
|
c_bool bool,
|
|
c_char char(1) charset ascii collate ascii_bin,
|
|
c_nchar national char(1) charset ascii collate ascii_bin,
|
|
c_binary binary,
|
|
c_varchar varchar(1) charset ascii collate ascii_bin,
|
|
c_nvarchar national varchar(1) charset ascii collate ascii_bin,
|
|
c_varbinary varbinary(1),
|
|
c_year year,
|
|
c_date date,
|
|
c_time time,
|
|
c_datetime datetime,
|
|
c_timestamp timestamp,
|
|
c_blob blob,
|
|
c_tinyblob tinyblob,
|
|
c_mediumblob mediumblob,
|
|
c_longblob longblob,
|
|
c_text text charset ascii collate ascii_bin,
|
|
c_tinytext tinytext charset ascii collate ascii_bin,
|
|
c_mediumtext mediumtext charset ascii collate ascii_bin,
|
|
c_longtext longtext charset ascii collate ascii_bin,
|
|
c_json json,
|
|
c_enum enum('1') charset ascii collate ascii_bin,
|
|
c_set set('1') charset ascii collate ascii_bin
|
|
);`)
|
|
|
|
tk.MustQuery(`show full columns from test_full_column`).Check(testkit.Rows(
|
|
"" +
|
|
"c_int int(11) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_float float <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_bit bit(1) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_bool tinyint(1) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_char char(1) ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_nchar char(1) ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_binary binary(1) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_varchar varchar(1) ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_nvarchar varchar(1) ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_varbinary varbinary(1) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_year year(4) <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_date date <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_time time <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_datetime datetime <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_timestamp timestamp <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_blob blob <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_tinyblob tinyblob <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_mediumblob mediumblob <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_longblob longblob <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_text text ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_tinytext tinytext ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_mediumtext mediumtext ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_longtext longtext ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_json json <nil> YES <nil> select,insert,update,references ]\n" +
|
|
"[c_enum enum('1') ascii_bin YES <nil> select,insert,update,references ]\n" +
|
|
"[c_set set('1') ascii_bin YES <nil> select,insert,update,references "))
|
|
|
|
tk.MustExec("drop table if exists test_full_column")
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec(`create table if not exists t (c int) comment '注释'`)
|
|
tk.MustExec("create or replace definer='root'@'localhost' view v as select * from t")
|
|
tk.MustQuery(`show columns from t`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
|
tk.MustQuery(`describe t`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
|
tk.MustQuery(`show columns from v`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
|
tk.MustQuery(`describe v`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
|
tk.MustQuery("show collation where Charset = 'utf8' and Collation = 'utf8_bin'").Check(testutil.RowsWithSep(",", "utf8_bin,utf8,83,,Yes,1"))
|
|
tk.MustQuery("show tables").Check(testkit.Rows("t", "v"))
|
|
tk.MustQuery("show full tables").Check(testkit.Rows("t BASE TABLE", "v VIEW"))
|
|
ctx := tk.Se.(sessionctx.Context)
|
|
is := domain.GetDomain(ctx).InfoSchema()
|
|
tblInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
|
|
c.Assert(err, IsNil)
|
|
createTime := model.TSConvert2Time(tblInfo.Meta().UpdateTS).Format("2006-01-02 15:04:05")
|
|
|
|
// The Hostname is the actual host
|
|
tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "192.168.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
|
|
|
|
r := tk.MustQuery("show table status from test like 't'")
|
|
r.Check(testkit.Rows(fmt.Sprintf("t InnoDB 10 Compact 0 0 0 0 0 0 0 %s <nil> <nil> utf8mb4_bin 注释", createTime)))
|
|
|
|
tk.MustQuery("show databases like 'test'").Check(testkit.Rows("test"))
|
|
|
|
tk.MustExec(`grant all on *.* to 'root'@'%'`)
|
|
tk.MustQuery("show grants").Check(testkit.Rows(`GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'`))
|
|
|
|
tk.MustQuery("show grants for current_user()").Check(testkit.Rows(`GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'`))
|
|
tk.MustQuery("show grants for current_user").Check(testkit.Rows(`GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'`))
|
|
}
|
|
|
|
func (s *testSuite2) TestShow3(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
// Create a new user.
|
|
tk.MustExec(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED BY 'root';`)
|
|
tk.MustQuery("show create user 'test_show_create_user'@'%'").
|
|
Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK`))
|
|
|
|
tk.MustExec(`CREATE USER 'test_show_create_user'@'localhost' IDENTIFIED BY 'test';`)
|
|
tk.MustQuery("show create user 'test_show_create_user'@'localhost';").
|
|
Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK`))
|
|
|
|
// Case: the user exists but the host portion doesn't match
|
|
err := tk.QueryToErr("show create user 'test_show_create_user'@'asdf';")
|
|
c.Assert(err.Error(), Equals, executor.ErrCannotUser.GenWithStackByArgs("SHOW CREATE USER", "'test_show_create_user'@'asdf'").Error())
|
|
|
|
// Case: a user that doesn't exist
|
|
err = tk.QueryToErr("show create user 'aaa'@'localhost';")
|
|
c.Assert(err.Error(), Equals, executor.ErrCannotUser.GenWithStackByArgs("SHOW CREATE USER", "'aaa'@'localhost'").Error())
|
|
}
|
|
|
|
func (s *testSuite2) TestUnprivilegedShow(c *C) {
|
|
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("CREATE DATABASE testshow")
|
|
tk.MustExec("USE testshow")
|
|
tk.MustExec("CREATE TABLE t1 (a int)")
|
|
tk.MustExec("CREATE TABLE t2 (a int)")
|
|
|
|
tk.MustExec(`CREATE USER 'lowprivuser'`) // no grants
|
|
tk.MustExec(`FLUSH PRIVILEGES`)
|
|
|
|
tk.Se.Auth(&auth.UserIdentity{Username: "lowprivuser", Hostname: "192.168.0.1", AuthUsername: "lowprivuser", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
|
|
rs, err := tk.Exec("SHOW TABLE STATUS FROM testshow")
|
|
c.Assert(err, IsNil)
|
|
c.Assert(rs, NotNil)
|
|
|
|
tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "192.168.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
|
|
tk.MustExec("GRANT ALL ON testshow.t1 TO 'lowprivuser'")
|
|
tk.MustExec(`FLUSH PRIVILEGES`)
|
|
tk.Se.Auth(&auth.UserIdentity{Username: "lowprivuser", Hostname: "192.168.0.1", AuthUsername: "lowprivuser", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
|
|
|
|
ctx := tk.Se.(sessionctx.Context)
|
|
is := domain.GetDomain(ctx).InfoSchema()
|
|
tblInfo, err := is.TableByName(model.NewCIStr("testshow"), model.NewCIStr("t1"))
|
|
c.Assert(err, IsNil)
|
|
createTime := model.TSConvert2Time(tblInfo.Meta().UpdateTS).Format("2006-01-02 15:04:05")
|
|
|
|
tk.MustQuery("show table status from testshow").Check(testkit.Rows(fmt.Sprintf("t1 InnoDB 10 Compact 0 0 0 0 0 0 0 %s <nil> <nil> utf8mb4_bin ", createTime)))
|
|
|
|
}
|
|
|
|
func (s *testSuite2) TestCollation(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
|
|
rs, err := tk.Exec("show collation;")
|
|
c.Assert(err, IsNil)
|
|
fields := rs.Fields()
|
|
c.Assert(fields[0].Column.Tp, Equals, mysql.TypeVarchar)
|
|
c.Assert(fields[1].Column.Tp, Equals, mysql.TypeVarchar)
|
|
c.Assert(fields[2].Column.Tp, Equals, mysql.TypeLonglong)
|
|
c.Assert(fields[3].Column.Tp, Equals, mysql.TypeVarchar)
|
|
c.Assert(fields[4].Column.Tp, Equals, mysql.TypeVarchar)
|
|
c.Assert(fields[5].Column.Tp, Equals, mysql.TypeLonglong)
|
|
}
|
|
|
|
func (s *testSuite2) TestShowTableStatus(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`drop table if exists t;`)
|
|
tk.MustExec(`create table t(a bigint);`)
|
|
|
|
tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "192.168.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
|
|
|
|
// It's not easy to test the result contents because every time the test runs, "Create_time" changed.
|
|
tk.MustExec("show table status;")
|
|
rs, err := tk.Exec("show table status;")
|
|
c.Assert(errors.ErrorStack(err), Equals, "")
|
|
c.Assert(rs, NotNil)
|
|
rows, err := session.GetRows4Test(context.Background(), tk.Se, rs)
|
|
c.Assert(errors.ErrorStack(err), Equals, "")
|
|
err = rs.Close()
|
|
c.Assert(errors.ErrorStack(err), Equals, "")
|
|
|
|
for i := range rows {
|
|
row := rows[i]
|
|
c.Assert(row.GetString(0), Equals, "t")
|
|
c.Assert(row.GetString(1), Equals, "InnoDB")
|
|
c.Assert(row.GetInt64(2), Equals, int64(10))
|
|
c.Assert(row.GetString(3), Equals, "Compact")
|
|
}
|
|
tk.MustExec(`drop table if exists tp;`)
|
|
tk.MustExec(`create table tp (a int)
|
|
partition by range(a)
|
|
( partition p0 values less than (10),
|
|
partition p1 values less than (20),
|
|
partition p2 values less than (maxvalue)
|
|
);`)
|
|
rs, err = tk.Exec("show table status from test like 'tp';")
|
|
c.Assert(errors.ErrorStack(err), Equals, "")
|
|
rows, err = session.GetRows4Test(context.Background(), tk.Se, rs)
|
|
c.Assert(errors.ErrorStack(err), Equals, "")
|
|
c.Assert(rows[0].GetString(16), Equals, "partitioned")
|
|
}
|
|
|
|
func (s *testSuite2) TestShowSlow(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
// The test result is volatile, because
|
|
// 1. Slow queries is stored in domain, which may be affected by other tests.
|
|
// 2. Collecting slow queries is a asynchronous process, check immediately may not get the expected result.
|
|
// 3. Make slow query like "select sleep(1)" would slow the CI.
|
|
// So, we just cover the code but do not check the result.
|
|
tk.MustQuery(`admin show slow recent 3`)
|
|
tk.MustQuery(`admin show slow top 3`)
|
|
tk.MustQuery(`admin show slow top internal 3`)
|
|
tk.MustQuery(`admin show slow top all 3`)
|
|
}
|
|
|
|
func (s *testSuite2) TestShowOpenTables(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustQuery("show open tables")
|
|
tk.MustQuery("show open tables in test")
|
|
}
|
|
|
|
func (s *testSuite2) TestShowCreateTable(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t1(a int,b int)")
|
|
tk.MustExec("drop view if exists v1")
|
|
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v1 as select * from t1")
|
|
tk.MustQuery("show create table v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS select * from t1 "))
|
|
tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS select * from t1 "))
|
|
tk.MustExec("drop view v1")
|
|
tk.MustExec("drop table t1")
|
|
|
|
tk.MustExec("drop view if exists v")
|
|
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v as select JSON_MERGE('{}', '{}') as col;")
|
|
tk.MustQuery("show create view v").Check(testutil.RowsWithSep("|", "v|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v` (`col`) AS select JSON_MERGE('{}', '{}') as col; "))
|
|
tk.MustExec("drop view if exists v")
|
|
|
|
// For issue #9211
|
|
tk.MustExec("create table t(c int, b int as (c + 1))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
|
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"t CREATE TABLE `t` (\n"+
|
|
" `c` int(11) DEFAULT NULL,\n"+
|
|
" `b` int(11) GENERATED ALWAYS AS (`c` + 1) VIRTUAL\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
|
|
tk.MustExec("drop table t")
|
|
tk.MustExec("create table t(c int, b int as (c + 1) not null)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
|
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"t CREATE TABLE `t` (\n"+
|
|
" `c` int(11) DEFAULT NULL,\n"+
|
|
" `b` int(11) GENERATED ALWAYS AS (`c` + 1) VIRTUAL NOT NULL\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
tk.MustExec("drop table t")
|
|
tk.MustExec("create table t ( a char(10) charset utf8 collate utf8_bin, b char(10) as (rtrim(a)));")
|
|
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"t CREATE TABLE `t` (\n"+
|
|
" `a` char(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n"+
|
|
" `b` char(10) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
tk.MustExec("drop table t")
|
|
|
|
tk.MustExec(`drop table if exists different_charset`)
|
|
tk.MustExec(`create table different_charset(ch1 varchar(10) charset utf8, ch2 varchar(10) charset binary);`)
|
|
tk.MustQuery(`show create table different_charset`).Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"different_charset CREATE TABLE `different_charset` (\n"+
|
|
" `ch1` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n"+
|
|
" `ch2` varbinary(10) DEFAULT NULL\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
}
|
|
|
|
func (s *testSuite2) TestShowEscape(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists `t``abl\"e`")
|
|
tk.MustExec("create table `t``abl\"e`(`c``olum\"n` int(11) primary key)")
|
|
tk.MustQuery("show create table `t``abl\"e`").Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"t`abl\"e CREATE TABLE `t``abl\"e` (\n"+
|
|
" `c``olum\"n` int(11) NOT NULL,\n"+
|
|
" PRIMARY KEY (`c``olum\"n`)\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
|
|
// ANSI_QUOTES will change the SHOW output
|
|
tk.MustExec("set @old_sql_mode=@@sql_mode")
|
|
tk.MustExec("set sql_mode=ansi_quotes")
|
|
tk.MustQuery("show create table \"t`abl\"\"e\"").Check(testutil.RowsWithSep("|",
|
|
""+
|
|
"t`abl\"e CREATE TABLE \"t`abl\"\"e\" (\n"+
|
|
" \"c`olum\"\"n\" int(11) NOT NULL,\n"+
|
|
" PRIMARY KEY (\"c`olum\"\"n\")\n"+
|
|
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
|
))
|
|
|
|
tk.MustExec("rename table \"t`abl\"\"e\" to t")
|
|
tk.MustExec("set sql_mode=@old_sql_mode")
|
|
}
|