Merge remote-tracking branch 'origin/master' into mvcc
This commit is contained in:
@ -75,6 +75,7 @@ var Funcs = map[string]Func{
|
||||
"month": {builtinMonth, 1, 1, true, false},
|
||||
"now": {builtinNow, 0, 1, false, false},
|
||||
"second": {builtinSecond, 1, 1, true, false},
|
||||
"sysdate": {builtinSysDate, 0, 1, false, false},
|
||||
"week": {builtinWeek, 1, 2, true, false},
|
||||
"weekday": {builtinWeekDay, 1, 1, true, false},
|
||||
"weekofyear": {builtinWeekOfYear, 1, 1, true, false},
|
||||
|
||||
@ -142,18 +142,14 @@ func builtinMonth(args []interface{}, ctx map[interface{}]interface{}) (interfac
|
||||
}
|
||||
|
||||
func builtinNow(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) {
|
||||
fsp := int64(0)
|
||||
// TODO: if NOW is used in stored function or trigger, NOW will return the beginning time
|
||||
// of the execution.
|
||||
fsp := 0
|
||||
if len(args) == 1 {
|
||||
var err error
|
||||
fsp, err = types.ToInt64(args[0])
|
||||
if err != nil {
|
||||
if fsp, err = checkFsp(args[0]); err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
if int(fsp) > mysql.MaxFsp {
|
||||
return nil, errors.Errorf("Too big precision %d specified. Maximum is 6.", fsp)
|
||||
} else if fsp < 0 {
|
||||
return nil, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
|
||||
}
|
||||
}
|
||||
|
||||
t := mysql.Time{
|
||||
@ -297,3 +293,23 @@ func builtinYearWeek(args []interface{}, ctx map[interface{}]interface{}) (inter
|
||||
year, week := t.ISOWeek()
|
||||
return int64(year*100 + week), nil
|
||||
}
|
||||
|
||||
func builtinSysDate(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) {
|
||||
// SYSDATE is not the same as NOW if NOW is used in a stored function or trigger.
|
||||
// But here we can just think they are the same because we don't support stored function
|
||||
// and trigger now.
|
||||
return builtinNow(args, ctx)
|
||||
}
|
||||
|
||||
func checkFsp(arg interface{}) (int, error) {
|
||||
fsp, err := types.ToInt64(arg)
|
||||
if err != nil {
|
||||
return 0, errors.Trace(err)
|
||||
}
|
||||
if int(fsp) > mysql.MaxFsp {
|
||||
return 0, errors.Errorf("Too big precision %d specified. Maximum is 6.", fsp)
|
||||
} else if fsp < 0 {
|
||||
return 0, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
|
||||
}
|
||||
return int(fsp), nil
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ package builtin
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/pingcap/check"
|
||||
mysql "github.com/pingcap/tidb/mysqldef"
|
||||
@ -247,3 +248,21 @@ func (s *testBuiltinSuite) TestNow(c *C) {
|
||||
_, err = builtinNow([]interface{}{-2}, nil)
|
||||
c.Assert(err, NotNil)
|
||||
}
|
||||
|
||||
func (s *testBuiltinSuite) TestSysDate(c *C) {
|
||||
last := time.Now()
|
||||
v, err := builtinSysDate(nil, nil)
|
||||
c.Assert(err, IsNil)
|
||||
n, ok := v.(mysql.Time)
|
||||
c.Assert(ok, IsTrue)
|
||||
c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat))
|
||||
|
||||
v, err = builtinSysDate([]interface{}{6}, nil)
|
||||
c.Assert(err, IsNil)
|
||||
n, ok = v.(mysql.Time)
|
||||
c.Assert(ok, IsTrue)
|
||||
c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat))
|
||||
|
||||
_, err = builtinSysDate([]interface{}{-2}, nil)
|
||||
c.Assert(err, NotNil)
|
||||
}
|
||||
|
||||
@ -116,6 +116,7 @@ import (
|
||||
div "DIV"
|
||||
do "DO"
|
||||
drop "DROP"
|
||||
dual "DUAL"
|
||||
duplicate "DUPLICATE"
|
||||
elseKwd "ELSE"
|
||||
end "END"
|
||||
@ -209,6 +210,7 @@ import (
|
||||
substring "SUBSTRING"
|
||||
sum "SUM"
|
||||
sysVar "SYS_VAR"
|
||||
sysDate "SYSDATE"
|
||||
tableKwd "TABLE"
|
||||
tables "TABLES"
|
||||
then "THEN"
|
||||
@ -325,7 +327,6 @@ import (
|
||||
ConstraintKeywordOpt "Constraint Keyword or empty"
|
||||
ConstraintOpt "optional column value constraint"
|
||||
ConstraintOpts "optional column value constraints"
|
||||
CreateDatabase "Create {DATABASE | SCHEMA}"
|
||||
CreateDatabaseStmt "Create Database Statement"
|
||||
CreateIndexStmt "CREATE INDEX statement"
|
||||
CreateIndexStmtUnique "CREATE INDEX optional UNIQUE clause"
|
||||
@ -335,6 +336,7 @@ import (
|
||||
CreateTableStmt "CREATE TABLE statement"
|
||||
CreateUserStmt "CREATE User statement"
|
||||
CrossOpt "Cross join option"
|
||||
DatabaseSym "DATABASE or SCHEMA"
|
||||
DBName "Database Name"
|
||||
DeallocateSym "Deallocate or drop"
|
||||
DeallocateStmt "Deallocate prepared statement"
|
||||
@ -975,9 +977,9 @@ IndexColNameList:
|
||||
* | [DEFAULT] COLLATE [=] collation_name
|
||||
*******************************************************************/
|
||||
CreateDatabaseStmt:
|
||||
CreateDatabase IfNotExists DBName CreateSpecListOpt
|
||||
"CREATE" DatabaseSym IfNotExists DBName CreateSpecListOpt
|
||||
{
|
||||
opts := $4.([]*coldef.DatabaseOpt)
|
||||
opts := $5.([]*coldef.DatabaseOpt)
|
||||
//compose charset from x
|
||||
var cs, co string
|
||||
for _, x := range opts {
|
||||
@ -994,8 +996,8 @@ CreateDatabaseStmt:
|
||||
dbopt := &coldef.CharsetOpt{Chs: cs, Col: co}
|
||||
|
||||
$$ = &stmts.CreateDatabaseStmt{
|
||||
IfNotExists: $2.(bool),
|
||||
Name: $3.(string),
|
||||
IfNotExists: $3.(bool),
|
||||
Name: $4.(string),
|
||||
Opt: dbopt}
|
||||
|
||||
if yylex.(*lexer).root {
|
||||
@ -1003,14 +1005,6 @@ CreateDatabaseStmt:
|
||||
}
|
||||
}
|
||||
|
||||
CreateDatabase:
|
||||
"CREATE" "DATABASE"
|
||||
{
|
||||
}
|
||||
| "CREATE" "SCHEMA"
|
||||
{
|
||||
}
|
||||
|
||||
DBName:
|
||||
Identifier
|
||||
|
||||
@ -1137,6 +1131,7 @@ DefaultOpt:
|
||||
DefaultKwdOpt:
|
||||
{}
|
||||
| "DEFAULT"
|
||||
|
||||
/******************************************************************
|
||||
* Do statement
|
||||
* See: https://dev.mysql.com/doc/refman/5.7/en/do.html
|
||||
@ -1220,10 +1215,12 @@ DeleteFromStmt:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DatabaseSym:
|
||||
"DATABASE" | "SCHEMA"
|
||||
|
||||
DropDatabaseStmt:
|
||||
"DROP" "DATABASE" IfExists Identifier
|
||||
"DROP" DatabaseSym IfExists DBName
|
||||
{
|
||||
$$ = &stmts.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)}
|
||||
if yylex.(*lexer).root {
|
||||
@ -2257,6 +2254,20 @@ FunctionCallNonKeyword:
|
||||
Len: $7.(expression.Expression),
|
||||
}
|
||||
}
|
||||
| "SYSDATE" '(' ExpressionOpt ')'
|
||||
{
|
||||
args := []expression.Expression{}
|
||||
if $3 != nil {
|
||||
args = append(args, $3.(expression.Expression))
|
||||
}
|
||||
var err error
|
||||
$$, err = expression.NewCall($1.(string), args, false)
|
||||
if err != nil {
|
||||
l := yylex.(*lexer)
|
||||
l.err(err)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
| "WEEKDAY" '(' Expression ')'
|
||||
{
|
||||
args := []expression.Expression{$3.(expression.Expression)}
|
||||
@ -2694,13 +2705,13 @@ RollbackStmt:
|
||||
}
|
||||
|
||||
SelectStmt:
|
||||
"SELECT" SelectStmtOpts SelectStmtFieldList SelectStmtLimit SelectLockOpt
|
||||
"SELECT" SelectStmtOpts SelectStmtFieldList FromDual SelectStmtLimit SelectLockOpt
|
||||
{
|
||||
$$ = &stmts.SelectStmt {
|
||||
Distinct: $2.(bool),
|
||||
Fields: $3.([]*field.Field),
|
||||
From: nil,
|
||||
Lock: $5.(coldef.LockType),
|
||||
Lock: $6.(coldef.LockType),
|
||||
}
|
||||
}
|
||||
| "SELECT" SelectStmtOpts SelectStmtFieldList "FROM"
|
||||
@ -2739,6 +2750,11 @@ SelectStmt:
|
||||
$$ = st
|
||||
}
|
||||
|
||||
FromDual:
|
||||
/* Empty */
|
||||
| "FROM" "DUAL"
|
||||
|
||||
|
||||
FromClause:
|
||||
TableRefs
|
||||
{
|
||||
|
||||
@ -354,6 +354,20 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
{"show collation like 'utf8%'", true},
|
||||
{"show collation where Charset = 'utf8' and Collation = 'utf8_bin'", true},
|
||||
|
||||
// For drop datbase/schema
|
||||
{"create database xxx", true},
|
||||
{"create database if exists xxx", false},
|
||||
{"create database if not exists xxx", true},
|
||||
{"create schema xxx", true},
|
||||
{"create schema if exists xxx", false},
|
||||
{"create schema if not exists xxx", true},
|
||||
{"drop database xxx", true},
|
||||
{"drop database if exists xxx", true},
|
||||
{"drop database if not exists xxx", false},
|
||||
{"drop schema xxx", true},
|
||||
{"drop schema if exists xxx", true},
|
||||
{"drop schema if not exists xxx", false},
|
||||
|
||||
// For issue 224
|
||||
{`SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;`, true},
|
||||
|
||||
@ -363,6 +377,11 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
{"select current_timestamp(6)", true},
|
||||
{"select now()", true},
|
||||
{"select now(6)", true},
|
||||
{"select sysdate(), sysdate(6)", true},
|
||||
|
||||
// For dual
|
||||
{"select 1 from dual", true},
|
||||
{"select 1 from dual limit 1", true},
|
||||
}
|
||||
|
||||
for _, t := range table {
|
||||
|
||||
@ -279,6 +279,7 @@ describe {d}{e}{s}{c}{r}{i}{b}{e}
|
||||
distinct {d}{i}{s}{t}{i}{n}{c}{t}
|
||||
div {d}{i}{v}
|
||||
do {d}{o}
|
||||
dual {d}{u}{a}{l}
|
||||
duplicate {d}{u}{p}{l}{i}{c}{a}{t}{e}
|
||||
else {e}{l}{s}{e}
|
||||
end {e}{n}{d}
|
||||
@ -354,6 +355,7 @@ some {s}{o}{m}{e}
|
||||
start {s}{t}{a}{r}{t}
|
||||
substring {s}{u}{b}{s}{t}{r}{i}{n}{g}
|
||||
sum {s}{u}{m}
|
||||
sysdate {s}{y}{s}{d}{a}{t}{e}
|
||||
table {t}{a}{b}{l}{e}
|
||||
tables {t}{a}{b}{l}{e}{s}
|
||||
then {t}{h}{e}{n}
|
||||
@ -567,6 +569,7 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
{div} return div
|
||||
{do} lval.item = string(l.val)
|
||||
return do
|
||||
{dual} return dual
|
||||
{duplicate} lval.item = string(l.val)
|
||||
return duplicate
|
||||
{else} return elseKwd
|
||||
@ -689,6 +692,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
|
||||
return substring
|
||||
{sum} lval.item = string(l.val)
|
||||
return sum
|
||||
{sysdate} lval.item = string(l.val)
|
||||
return sysDate
|
||||
{table} return tableKwd
|
||||
{tables} lval.item = string(l.val)
|
||||
return tables
|
||||
|
||||
@ -30,7 +30,7 @@ import (
|
||||
|
||||
var (
|
||||
_ plan.Plan = (*SelectFieldsDefaultPlan)(nil)
|
||||
_ plan.Plan = (*SelectEmptyFieldListPlan)(nil)
|
||||
_ plan.Plan = (*SelectFromDualPlan)(nil)
|
||||
)
|
||||
|
||||
// SelectFieldsDefaultPlan extracts specific fields from Src Plan.
|
||||
@ -94,19 +94,19 @@ func (r *SelectFieldsDefaultPlan) Close() error {
|
||||
return r.Src.Close()
|
||||
}
|
||||
|
||||
// SelectEmptyFieldListPlan is the plan for "select expr, expr, ..."" with no FROM.
|
||||
type SelectEmptyFieldListPlan struct {
|
||||
// SelectFromDualPlan is the plan for "select expr, expr, ..."" or "select expr, expr, ... from dual".
|
||||
type SelectFromDualPlan struct {
|
||||
Fields []*field.Field
|
||||
done bool
|
||||
}
|
||||
|
||||
// Explain implements the plan.Plan Explain interface.
|
||||
func (s *SelectEmptyFieldListPlan) Explain(w format.Formatter) {
|
||||
func (s *SelectFromDualPlan) Explain(w format.Formatter) {
|
||||
// TODO: finish this
|
||||
}
|
||||
|
||||
// GetFields implements the plan.Plan GetFields interface.
|
||||
func (s *SelectEmptyFieldListPlan) GetFields() []*field.ResultField {
|
||||
func (s *SelectFromDualPlan) GetFields() []*field.ResultField {
|
||||
ans := make([]*field.ResultField, 0, len(s.Fields))
|
||||
if len(s.Fields) > 0 {
|
||||
for _, f := range s.Fields {
|
||||
@ -119,12 +119,12 @@ func (s *SelectEmptyFieldListPlan) GetFields() []*field.ResultField {
|
||||
}
|
||||
|
||||
// Filter implements the plan.Plan Filter interface.
|
||||
func (s *SelectEmptyFieldListPlan) Filter(ctx context.Context, expr expression.Expression) (plan.Plan, bool, error) {
|
||||
func (s *SelectFromDualPlan) Filter(ctx context.Context, expr expression.Expression) (plan.Plan, bool, error) {
|
||||
return s, false, nil
|
||||
}
|
||||
|
||||
// Next implements plan.Plan Next interface.
|
||||
func (s *SelectEmptyFieldListPlan) Next(ctx context.Context) (row *plan.Row, err error) {
|
||||
func (s *SelectFromDualPlan) Next(ctx context.Context) (row *plan.Row, err error) {
|
||||
if s.done {
|
||||
return
|
||||
}
|
||||
@ -138,7 +138,7 @@ func (s *SelectEmptyFieldListPlan) Next(ctx context.Context) (row *plan.Row, err
|
||||
}
|
||||
|
||||
// Close implements plan.Plan Close interface.
|
||||
func (s *SelectEmptyFieldListPlan) Close() error {
|
||||
func (s *SelectFromDualPlan) Close() error {
|
||||
s.done = false
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ func (s *testFieldsSuit) TestDefaultFieldsPlan(c *C) {
|
||||
}
|
||||
|
||||
func (s *testFieldsSuit) TestSelectExprPlan(c *C) {
|
||||
pln := &plans.SelectEmptyFieldListPlan{
|
||||
pln := &plans.SelectFromDualPlan{
|
||||
Fields: []*field.Field{
|
||||
{
|
||||
Expr: &expression.Value{
|
||||
|
||||
@ -101,8 +101,8 @@ func (s *ShowPlan) GetFields() []*field.ResultField {
|
||||
names = []string{"Variable_name", "Value"}
|
||||
case stmt.ShowCollation:
|
||||
names = []string{"Collation", "Charset", "Id", "Default", "Compiled", "Sortlen"}
|
||||
types = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLong,
|
||||
mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLong}
|
||||
types = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong,
|
||||
mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong}
|
||||
}
|
||||
fields := make([]*field.ResultField, 0, len(names))
|
||||
for i, name := range names {
|
||||
|
||||
@ -156,7 +156,7 @@ func (p *testShowSuit) TestShowCollation(c *C) {
|
||||
pln.Target = stmt.ShowCollation
|
||||
fls := pln.GetFields()
|
||||
c.Assert(fls, HasLen, 6)
|
||||
c.Assert(fls[2].Col.Tp, Equals, mysql.TypeLong)
|
||||
c.Assert(fls[2].Col.Tp, Equals, mysql.TypeLonglong)
|
||||
|
||||
pln.Pattern = &expression.PatternLike{
|
||||
Pattern: &expression.Value{
|
||||
|
||||
@ -29,7 +29,7 @@ import (
|
||||
|
||||
var (
|
||||
_ plan.Planner = (*SelectFieldsRset)(nil)
|
||||
_ plan.Planner = (*FieldRset)(nil)
|
||||
_ plan.Planner = (*SelectFromDualRset)(nil)
|
||||
)
|
||||
|
||||
// SelectFieldsRset is record set to select fields.
|
||||
@ -80,12 +80,12 @@ func (r *SelectFieldsRset) Plan(ctx context.Context) (plan.Plan, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// FieldRset is Recordset for select expression, like `select 1, 1+1`.
|
||||
type FieldRset struct {
|
||||
// SelectFromDualRset is Recordset for select from dual, like `select 1, 1+1` or `select 1 from dual`.
|
||||
type SelectFromDualRset struct {
|
||||
Fields []*field.Field
|
||||
}
|
||||
|
||||
// Plan gets SelectExprPlan.
|
||||
func (r *FieldRset) Plan(ctx context.Context) (plan.Plan, error) {
|
||||
return &plans.SelectEmptyFieldListPlan{Fields: r.Fields}, nil
|
||||
func (r *SelectFromDualRset) Plan(ctx context.Context) (plan.Plan, error) {
|
||||
return &plans.SelectFromDualPlan{Fields: r.Fields}, nil
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ var _ = Suite(&testSelectFieldsPlannerSuite{})
|
||||
|
||||
type testSelectFieldsPlannerSuite struct {
|
||||
sr *SelectFieldsRset
|
||||
fr *FieldRset
|
||||
fr *SelectFromDualRset
|
||||
}
|
||||
|
||||
func (s *testSelectFieldsPlannerSuite) SetUpSuite(c *C) {
|
||||
@ -47,7 +47,7 @@ func (s *testSelectFieldsPlannerSuite) SetUpSuite(c *C) {
|
||||
}
|
||||
|
||||
s.sr = &SelectFieldsRset{Src: tblPlan, SelectList: selectList}
|
||||
s.fr = &FieldRset{Fields: fields}
|
||||
s.fr = &SelectFromDualRset{Fields: fields}
|
||||
}
|
||||
|
||||
func (s *testSelectFieldsPlannerSuite) TestDistinctPlanner(c *C) {
|
||||
@ -106,6 +106,6 @@ func (s *testSelectFieldsPlannerSuite) TestFieldPlanner(c *C) {
|
||||
p, err := s.fr.Plan(nil)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
_, ok := p.(*plans.SelectEmptyFieldListPlan)
|
||||
_, ok := p.(*plans.SelectFromDualPlan)
|
||||
c.Assert(ok, IsTrue)
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ func (s *SelectStmt) Plan(ctx context.Context) (plan.Plan, error) {
|
||||
}
|
||||
} else if s.Fields != nil {
|
||||
// Only evaluate fields values.
|
||||
fr := &rsets.FieldRset{Fields: s.Fields}
|
||||
fr := &rsets.SelectFromDualRset{Fields: s.Fields}
|
||||
r, err = fr.Plan(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -17,8 +17,8 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/juju/errors"
|
||||
"github.com/ngaut/bolt"
|
||||
"github.com/ngaut/log"
|
||||
"github.com/pingcap/tidb/store/localstore/engine"
|
||||
)
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/ngaut/bolt"
|
||||
"github.com/boltdb/bolt"
|
||||
. "github.com/pingcap/check"
|
||||
"github.com/pingcap/tidb/store/localstore/engine"
|
||||
)
|
||||
|
||||
35
tidb_test.go
35
tidb_test.go
@ -785,6 +785,16 @@ func (s *testSessionSuite) TestSelect(c *C) {
|
||||
|
||||
_, err = se.Execute("select * from t as a join (select 1) as a")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
r := mustExecSQL(c, se, "select 1, 2 from dual")
|
||||
row, err := r.FirstRow()
|
||||
c.Assert(err, IsNil)
|
||||
match(c, row, 1, 2)
|
||||
|
||||
r = mustExecSQL(c, se, "select 1, 2")
|
||||
row, err = r.FirstRow()
|
||||
c.Assert(err, IsNil)
|
||||
match(c, row, 1, 2)
|
||||
}
|
||||
|
||||
func (s *testSessionSuite) TestSubQuery(c *C) {
|
||||
@ -847,7 +857,7 @@ func (s *testSessionSuite) TestTimeFunc(c *C) {
|
||||
se := newSession(c, store, s.dbName)
|
||||
|
||||
last := time.Now().Format(mysql.TimeFormat)
|
||||
r := mustExecSQL(c, se, "select now(), now(6), current_timestamp, current_timestamp(), current_timestamp(6)")
|
||||
r := mustExecSQL(c, se, "select now(), now(6), current_timestamp, current_timestamp(), current_timestamp(6), sysdate(), sysdate(6)")
|
||||
row, err := r.FirstRow()
|
||||
c.Assert(err, IsNil)
|
||||
for _, t := range row {
|
||||
@ -884,6 +894,29 @@ func (s *testSessionSuite) TestBootstrap(c *C) {
|
||||
mustExecSQL(c, se, "USE test;")
|
||||
}
|
||||
|
||||
func (s *testSessionSuite) TestDatabase(c *C) {
|
||||
store := newStore(c, s.dbName)
|
||||
se := newSession(c, store, s.dbName)
|
||||
|
||||
// Test database.
|
||||
mustExecSQL(c, se, "create database xxx")
|
||||
mustExecSQL(c, se, "drop database xxx")
|
||||
|
||||
mustExecSQL(c, se, "drop database if exists xxx")
|
||||
mustExecSQL(c, se, "create database xxx")
|
||||
mustExecSQL(c, se, "create database if not exists xxx")
|
||||
mustExecSQL(c, se, "drop database if exists xxx")
|
||||
|
||||
// Test schema.
|
||||
mustExecSQL(c, se, "create schema xxx")
|
||||
mustExecSQL(c, se, "drop schema xxx")
|
||||
|
||||
mustExecSQL(c, se, "drop schema if exists xxx")
|
||||
mustExecSQL(c, se, "create schema xxx")
|
||||
mustExecSQL(c, se, "create schema if not exists xxx")
|
||||
mustExecSQL(c, se, "drop schema if exists xxx")
|
||||
}
|
||||
|
||||
func newSession(c *C, store kv.Storage, dbName string) Session {
|
||||
se, err := CreateSession(store)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
Reference in New Issue
Block a user