Skip to content

Commit d4f85c8

Browse files
authored
Add get_lock() and key_column_usage table (#1437)
Parsed but ignored. This is used for Ruby's activerecord migrations.
1 parent 387f9d3 commit d4f85c8

File tree

8 files changed

+77
-2
lines changed

8 files changed

+77
-2
lines changed

evaluator/builtin.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ var Funcs = map[string]Func{
120120
"ifnull": {builtinIfNull, 2, 2},
121121
"nullif": {builtinNullIf, 2, 2},
122122

123+
// miscellaneous functions
124+
// get_lock() and release_lock() is parsed but do nothing.
125+
// It is used for preventing error in Ruby's activerecord migrations.
126+
"get_lock": {builtinLock, 2, 2},
127+
"release_lock": {builtinReleaseLock, 1, 1},
128+
123129
// only used by new plan
124130
ast.AndAnd: {builtinAndAnd, 2, 2},
125131
ast.OrOr: {builtinOrOr, 2, 2},

evaluator/builtin_other.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,3 +484,17 @@ func builtinGetVar(args []types.Datum, ctx context.Context) (types.Datum, error)
484484
}
485485
return types.Datum{}, nil
486486
}
487+
488+
// The lock function will do nothing.
489+
// Warning: get_lock() function is parsed but ignored.
490+
func builtinLock(args []types.Datum, _ context.Context) (d types.Datum, err error) {
491+
d.SetInt64(1)
492+
return d, nil
493+
}
494+
495+
// The release lock function will do nothing.
496+
// Warning: release_lock() function is parsed but ignored.
497+
func builtinReleaseLock(args []types.Datum, _ context.Context) (d types.Datum, err error) {
498+
d.SetInt64(1)
499+
return d, nil
500+
}

evaluator/builtin_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,19 @@ func (s *testEvaluatorSuite) TestIsNullFunc(c *C) {
8181
c.Assert(err, IsNil)
8282
c.Assert(v.GetInt64(), Equals, int64(1))
8383
}
84+
85+
func (s *testEvaluatorSuite) TestLock(c *C) {
86+
defer testleak.AfterTest(c)()
87+
88+
v, err := builtinLock(types.MakeDatums(1), nil)
89+
c.Assert(err, IsNil)
90+
c.Assert(v.GetInt64(), Equals, int64(1))
91+
92+
v, err = builtinLock(types.MakeDatums(nil), nil)
93+
c.Assert(err, IsNil)
94+
c.Assert(v.GetInt64(), Equals, int64(1))
95+
96+
v, err = builtinReleaseLock(types.MakeDatums(1), nil)
97+
c.Assert(err, IsNil)
98+
c.Assert(v.GetInt64(), Equals, int64(1))
99+
}

infoschema/tables.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
catalogVal = "def"
3838
tableProfiling = "PROFILING"
3939
tablePartitions = "PARTITIONS"
40+
tableKeyColumm = "KEY_COLUMN_USAGE"
4041
)
4142

4243
type columnInfo struct {
@@ -197,6 +198,21 @@ var collationsCols = []columnInfo{
197198
{"SORTLEN", mysql.TypeLonglong, 3, 0, nil, nil},
198199
}
199200

201+
var keyColumnUsageCols = []columnInfo{
202+
{"CONSTRAINT_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
203+
{"CONSTRAINT_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
204+
{"CONSTRAINT_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
205+
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
206+
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
207+
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
208+
{"COLUMN_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
209+
{"ORDINAL_POSITION", mysql.TypeLonglong, 10, mysql.NotNullFlag, nil, nil},
210+
{"POSITION_IN_UNIQUE_CONSTRAINT", mysql.TypeLonglong, 10, 0, nil, nil},
211+
{"REFERENCED_TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
212+
{"REFERENCED_TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
213+
{"REFERENCED_COLUMN_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
214+
}
215+
200216
// See https://dev.mysql.com/doc/refman/5.7/en/partitions-table.html
201217
var partitionsCols = []columnInfo{
202218
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
@@ -481,6 +497,7 @@ var tableNameToColumns = map[string]([]columnInfo){
481497
tableFiles: filesCols,
482498
tableProfiling: profilingCols,
483499
tablePartitions: partitionsCols,
500+
tableKeyColumm: keyColumnUsageCols,
484501
}
485502

486503
func createMemoryTable(meta *model.TableInfo, alloc autoid.Allocator) (table.Table, error) {

parser/parser.y

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ import (
164164
full "FULL"
165165
fulltext "FULLTEXT"
166166
ge ">="
167+
getLock "GET_LOCK"
167168
global "GLOBAL"
168169
grant "GRANT"
169170
grants "GRANTS"
@@ -247,6 +248,7 @@ import (
247248
redundant "REDUNDANT"
248249
references "REFERENCES"
249250
regexpKwd "REGEXP"
251+
releaseLock "RELEASE_LOCK"
250252
repeat "REPEAT"
251253
repeatable "REPEATABLE"
252254
replace "REPLACE"
@@ -1966,7 +1968,7 @@ NotKeywordToken:
19661968
| "IFNULL" | "ISNULL" | "LAST_INSERT_ID" | "LCASE" | "LENGTH" | "LOCATE" | "LOWER" | "LTRIM" | "MAX" | "MICROSECOND" | "MIN"
19671969
| "MINUTE" | "NULLIF" | "MONTH" | "MONTHNAME" | "NOW" | "POW" | "POWER" | "RAND" | "SECOND" | "SQL_CALC_FOUND_ROWS" | "SUBDATE"
19681970
| "SUBSTRING" %prec lowerThanLeftParen | "SUBSTRING_INDEX" | "SUM" | "TRIM" | "RTRIM" | "UCASE" | "UPPER" | "VERSION"
1969-
| "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK" | "ROUND" | "STATS_PERSISTENT"
1971+
| "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK" | "ROUND" | "STATS_PERSISTENT" | "GET_LOCK" | "RELEASE_LOCK"
19701972

19711973
/************************************************************************************
19721974
*
@@ -2765,6 +2767,14 @@ FunctionCallNonKeyword:
27652767
{
27662768
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)}
27672769
}
2770+
| "GET_LOCK" '(' Expression ',' Expression ')'
2771+
{
2772+
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}}
2773+
}
2774+
| "RELEASE_LOCK" '(' Expression ')'
2775+
{
2776+
$$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}}
2777+
}
27682778

27692779
DateArithOpt:
27702780
"DATE_ADD"

parser/parser_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (s *testParserSuite) TestSimple(c *C) {
4848
"delay_key_write", "isolation", "repeatable", "committed", "uncommitted", "only", "serializable", "level",
4949
"curtime", "variables", "dayname", "version", "btree", "hash", "row_format", "dynamic", "fixed", "compressed",
5050
"compact", "redundant", "sql_no_cache sql_no_cache", "sql_cache sql_cache", "action", "round",
51-
"enable", "disable", "reverse", "space", "privileges",
51+
"enable", "disable", "reverse", "space", "privileges", "get_lock", "release_lock",
5252
}
5353
for _, kw := range unreservedKws {
5454
src := fmt.Sprintf("SELECT %s FROM tbl;", kw)
@@ -618,6 +618,10 @@ func (s *testParserSuite) TestBuiltin(c *C) {
618618
{`select adddate("2011-11-11 10:10:10.123456", 10)`, true},
619619
{`select adddate("2011-11-11 10:10:10.123456", 0.10)`, true},
620620
{`select adddate("2011-11-11 10:10:10.123456", "11,11")`, true},
621+
622+
// For misc functions
623+
{`SELECT GET_LOCK('lock1',10);`, true},
624+
{`SELECT RELEASE_LOCK('lock1');`, true},
621625
}
622626
s.RunTest(c, table)
623627
}

parser/scanner.l

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ found_rows {f}{o}{u}{n}{d}_{r}{o}{w}{s}
378378
from {f}{r}{o}{m}
379379
full {f}{u}{l}{l}
380380
fulltext {f}{u}{l}{l}{t}{e}{x}{t}
381+
get_lock {g}{e}{t}_{l}{o}{c}{k}
381382
global {g}{l}{o}{b}{a}{l}
382383
grant {g}{r}{a}{n}{t}
383384
grants {g}{r}{a}{n}{t}{s}
@@ -447,6 +448,7 @@ quarter {q}{u}{a}{r}{t}{e}{r}
447448
quick {q}{u}{i}{c}{k}
448449
rand {r}{a}{n}{d}
449450
read {r}{e}{a}{d}
451+
release_lock {r}{e}{l}{e}{a}{s}{e}_{l}{o}{c}{k}
450452
repeat {r}{e}{p}{e}{a}{t}
451453
repeatable {r}{e}{p}{e}{a}{t}{a}{b}{l}{e}
452454
references {r}{e}{f}{e}{r}{e}{n}{c}{e}{s}
@@ -985,11 +987,15 @@ redundant lval.item = string(l.val)
985987
return statsPersistent
986988
{status} lval.item = string(l.val)
987989
return status
990+
{get_lock} lval.item = string(l.val)
991+
return getLock
988992
{global} lval.item = string(l.val)
989993
return global
990994
{rand} lval.item = string(l.val)
991995
return rand
992996
{read} return read
997+
{release_lock} lval.item = string(l.val)
998+
return releaseLock
993999
{repeat} lval.item = string(l.val)
9941000
return repeat
9951001
{repeatable} lval.item = string(l.val)

plan/typeinferer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ func (v *typeInferrer) handleFuncCallExpr(x *ast.FuncCallExpr) {
298298
// expr2 or expr3 returns a floating-point value floating-point
299299
// expr2 or expr3 returns an integer integer
300300
tp = x.Args[1].GetType()
301+
case "get_lock", "release_lock":
302+
tp = types.NewFieldType(mysql.TypeLonglong)
301303
default:
302304
tp = types.NewFieldType(mysql.TypeUnspecified)
303305
}

0 commit comments

Comments
 (0)