зеркало из https://github.com/github/vitess-gh.git
use a more predictable scheme of obtaining field info for selects
This commit is contained in:
Родитель
8c198382d4
Коммит
4dab186aca
|
@ -99,6 +99,9 @@ type ExecPlan struct {
|
|||
Reason ReasonType
|
||||
TableName string
|
||||
|
||||
// Query to fetch field info
|
||||
FieldQuery *ParsedQuery
|
||||
|
||||
// PLAN_PASS_*
|
||||
FullQuery *ParsedQuery
|
||||
|
||||
|
@ -217,7 +220,7 @@ func (node *Node) execAnalyzeSql(getTable TableGetter) (plan *ExecPlan) {
|
|||
|
||||
func (node *Node) execAnalyzeSelect(getTable TableGetter) (plan *ExecPlan) {
|
||||
// Default plan
|
||||
plan = &ExecPlan{PlanId: PLAN_PASS_SELECT, FullQuery: node.GenerateSelectLimitQuery()}
|
||||
plan = &ExecPlan{PlanId: PLAN_PASS_SELECT, FieldQuery: node.GenerateFieldQuery(), FullQuery: node.GenerateSelectLimitQuery()}
|
||||
|
||||
if !node.execAnalyzeSelectStructure() {
|
||||
plan.Reason = REASON_SELECT
|
||||
|
@ -908,6 +911,29 @@ func (node *Node) GenerateFullQuery() *ParsedQuery {
|
|||
return NewParsedQuery(buf)
|
||||
}
|
||||
|
||||
func (node *Node) GenerateFieldQuery() *ParsedQuery {
|
||||
buf := NewTrackedBuffer()
|
||||
node.generateImpossibleQuery(buf)
|
||||
if len(buf.bind_locations) != 0 {
|
||||
panic(NewParserError("Syntax error: Bind variables not allowed in select expressions"))
|
||||
}
|
||||
return NewParsedQuery(buf)
|
||||
}
|
||||
|
||||
func (node *Node) generateImpossibleQuery(buf *TrackedBuffer) {
|
||||
switch node.Type {
|
||||
case UNION, UNION_ALL, MINUS, EXCEPT:
|
||||
node.At(0).generateImpossibleQuery(buf)
|
||||
fmt.Fprintf(buf, " %s ", node.Value)
|
||||
node.At(1).generateImpossibleQuery(buf)
|
||||
case SELECT:
|
||||
Fprintf(buf, "select %v from %v where 1 != 1",
|
||||
node.At(SELECT_EXPR_OFFSET),
|
||||
node.At(SELECT_FROM_OFFSET),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (node *Node) GenerateSelectLimitQuery() *ParsedQuery {
|
||||
buf := NewTrackedBuffer()
|
||||
if node.Type == SELECT {
|
||||
|
|
|
@ -37,7 +37,7 @@ func NewParsedQuery(buf *TrackedBuffer) *ParsedQuery {
|
|||
type EncoderFunc func(value interface{}) ([]byte, error)
|
||||
|
||||
func (self *ParsedQuery) GenerateQuery(bindVariables map[string]interface{}, listVariables []sqltypes.Value) ([]byte, error) {
|
||||
if bindVariables == nil || len(self.BindLocations) == 0 {
|
||||
if len(self.BindLocations) == 0 {
|
||||
return []byte(self.Query), nil
|
||||
}
|
||||
buf := bytes.NewBuffer(make([]byte, 0, len(self.Query)))
|
||||
|
|
|
@ -4,6 +4,7 @@ select * from a union select * from b
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "SELECT",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a where 1 != 1 union select * from b where 1 != 1",
|
||||
"FullQuery": "select * from a union select * from b",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -22,6 +23,7 @@ select distinct * from a
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "SELECT",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select distinct * from a limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -40,6 +42,7 @@ select * from a group by b
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "SELECT",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a group by b limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -58,6 +61,7 @@ select * from a having b=1
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "SELECT",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a having b = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -76,6 +80,7 @@ select * from a limit 5
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a limit 5",
|
||||
"OuterQuery": "select eid, id, name, foo from a limit 5",
|
||||
"Subquery": null,
|
||||
|
@ -99,6 +104,7 @@ select * from a,b
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "TABLE",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a, b where 1 != 1",
|
||||
"FullQuery": "select * from a, b limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -117,6 +123,7 @@ select * from a join b
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "TABLE",
|
||||
"TableName": "",
|
||||
"FieldQuery": "select * from a join b where 1 != 1",
|
||||
"FullQuery": "select * from a join b limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -135,6 +142,7 @@ select * from b
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "NOCACHE",
|
||||
"TableName": "b",
|
||||
"FieldQuery": "select * from b where 1 != 1",
|
||||
"FullQuery": "select * from b limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -153,6 +161,7 @@ select eid+1 from a
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "SELECT_LIST",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select eid+1 from a where 1 != 1",
|
||||
"FullQuery": "select eid+1 from a limit :_vtMaxResultSize",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -171,6 +180,7 @@ select eid from a
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select eid from a where 1 != 1",
|
||||
"FullQuery": "select eid from a limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -191,6 +201,7 @@ select * from a
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -214,6 +225,7 @@ select c.eid from a as c
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select c.eid from a as c where 1 != 1",
|
||||
"FullQuery": "select c.eid from a as c limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a as c limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -234,6 +246,7 @@ select (eid) from a as c
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select eid from a as c where 1 != 1",
|
||||
"FullQuery": "select eid from a as c limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a as c limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -254,6 +267,7 @@ select eid from a for update
|
|||
"PlanId": "PASS_SELECT",
|
||||
"Reason": "FOR_UPDATE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select eid from a where 1 != 1",
|
||||
"FullQuery": "select eid from a limit :_vtMaxResultSize for update",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -272,6 +286,7 @@ select * from a where eid=1
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid = 1 limit :_vtMaxResultSize",
|
||||
|
@ -295,6 +310,7 @@ select * from a where eid+1 = 1
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid+1 = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid+1 = 1 limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -318,6 +334,7 @@ select * from a where eid = id
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = id limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = id limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -341,6 +358,7 @@ select * from a where eid=1 and foo='b'
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "PKINDEX",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and foo = 'b' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = 1 and foo = 'b' limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -364,6 +382,7 @@ select * from a where (eid=1)
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where (eid = 1) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where (eid = 1) limit :_vtMaxResultSize",
|
||||
|
@ -387,6 +406,7 @@ select * from a where eid=1 and id=1
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -413,6 +433,7 @@ select * from d where name='foo'
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "d",
|
||||
"FieldQuery": "select * from d where 1 != 1",
|
||||
"FullQuery": "select * from d where name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select name, id from d where name = :0",
|
||||
"Subquery": null,
|
||||
|
@ -436,6 +457,7 @@ select * from a where eid=1 and id in (1, 2)
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id in (1, 2) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -465,6 +487,7 @@ select * from a where eid=1 and id in (:a, :b)
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id in (:a, :b) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -494,6 +517,7 @@ select * from a where eid=1 and id in (1)
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id in (1) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -522,6 +546,7 @@ select * from a where eid in (1) and id in (1, 2)
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid in (1) and id in (1, 2) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid in (1) and id in (1, 2) limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -545,6 +570,7 @@ select * from a where eid in (1, 2) and id in (1, 2)
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid in (1, 2) and id in (1, 2) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid in (1, 2) and id in (1, 2) limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -568,6 +594,7 @@ select * from a where (eid, id) in ((1, 1), (2, 2))
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where (eid, id) in ((1, 1), (2, 2)) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -600,6 +627,7 @@ select * from a where eid=1 and id in (:a)
|
|||
"PlanId": "SELECT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id in (:a) limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": null,
|
||||
|
@ -628,6 +656,7 @@ select * from a where eid=1 and id>1
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "PKINDEX",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id \u003e 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = 1 and id \u003e 1 limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -651,6 +680,7 @@ select * from a where eid=1 and name='foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid = 1 and name = 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -674,6 +704,7 @@ select * from a where eid=1 and name='foo' limit 10
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and name = 'foo' limit 10",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid = 1 and name = 'foo' limit 10",
|
||||
|
@ -697,6 +728,7 @@ select * from a where foo='bar'
|
|||
"PlanId":"SELECT_CACHE_RESULT",
|
||||
"Reason":"NOINDEX_MATCH",
|
||||
"TableName":"a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery":"select * from a where foo = 'bar' limit :_vtMaxResultSize",
|
||||
"OuterQuery":"select eid, id, name, foo from a where foo = 'bar' limit :_vtMaxResultSize",
|
||||
"Subquery":null,
|
||||
|
@ -720,6 +752,7 @@ select * from a where name = 'foo' and id = 1
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where name = 'foo' and id = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (b_name) where name = 'foo' and id = 1 limit :_vtMaxResultSize",
|
||||
|
@ -743,6 +776,7 @@ select * from a as c where c.eid=1 and name='foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a as c where 1 != 1",
|
||||
"FullQuery": "select * from a as c where c.eid = 1 and name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a as c where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a as c use index (a_name) where c.eid = 1 and name = 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -766,6 +800,7 @@ select * from a where eid=1 and name<'foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and name \u003c 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid = 1 and name \u003c 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -789,6 +824,7 @@ select * from a where eid in (1, 2) and name='foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid in (1, 2) and name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid in (1, 2) and name = 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -812,6 +848,7 @@ select * from a where eid in (1, id) and name='foo'
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid in (1, id) and name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid in (1, id) and name = 'foo' limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -835,6 +872,7 @@ select * from a where eid between 1 and 2 and name='foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid between 1 and 2 and name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid between 1 and 2 and name = 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -858,6 +896,7 @@ select * from a where eid=1 and id=1 order by name
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "PKINDEX",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 and id = 1 order by name asc limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = 1 and id = 1 order by name asc limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -881,6 +920,7 @@ select * from a where eid=1 order by name
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where eid = 1 order by name asc limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (a_name) where eid = 1 order by name asc limit :_vtMaxResultSize",
|
||||
|
@ -904,6 +944,7 @@ select * from a where name='foo'
|
|||
"PlanId": "SELECT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a where 1 != 1",
|
||||
"FullQuery": "select * from a where name = 'foo' limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a use index (b_name) where name = 'foo' limit :_vtMaxResultSize",
|
||||
|
@ -927,6 +968,7 @@ select * from a use index(a_name) where eid = 1
|
|||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "HAS_HINTS",
|
||||
"TableName": "a",
|
||||
"FieldQuery": "select * from a use index (a_name) where 1 != 1",
|
||||
"FullQuery": "select * from a use index (a_name) where eid = 1 limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a use index (a_name) where eid = 1 limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
|
@ -950,6 +992,7 @@ insert into a (eid, id) values (1, :a)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(eid, id) values (1, :a)",
|
||||
"OuterQuery": "insert into a(eid, id) values (1, :a)",
|
||||
"Subquery": null,
|
||||
|
@ -971,6 +1014,7 @@ insert into a (id) values (1)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(id) values (1)",
|
||||
"OuterQuery": "insert into a(id) values (1)",
|
||||
"Subquery": null,
|
||||
|
@ -992,6 +1036,7 @@ insert into d(id) values(1)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "d",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into d(id) values (1)",
|
||||
"OuterQuery": "insert into d(id) values (1)",
|
||||
"Subquery": null,
|
||||
|
@ -1016,6 +1061,7 @@ insert into a (eid, id) values (-1, 2)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(eid, id) values (-1, 2)",
|
||||
"OuterQuery": "insert into a(eid, id) values (-1, 2)",
|
||||
"Subquery": null,
|
||||
|
@ -1037,6 +1083,7 @@ insert into a (eid, id) values (+1, 2)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(eid, id) values (1, 2)",
|
||||
"OuterQuery": "insert into a(eid, id) values (1, 2)",
|
||||
"Subquery": null,
|
||||
|
@ -1058,6 +1105,7 @@ insert into a (eid, id) values (~1, 2)
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(eid, id) values (~1, 2)",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1076,6 +1124,7 @@ insert into a (eid, id) values (1+1, 2)
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a(eid, id) values (1+1, 2)",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1094,6 +1143,7 @@ insert into c (eid, id) values (1, 2)
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "TABLE_NOINDEX",
|
||||
"TableName": "c",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into c(eid, id) values (1, 2)",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1112,6 +1162,7 @@ insert into a values (1, 2)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into a values (1, 2)",
|
||||
"OuterQuery": "insert into a values (1, 2)",
|
||||
"Subquery": null,
|
||||
|
@ -1133,6 +1184,7 @@ insert into b (eid, id) values (1, 2) on duplicate key update name = values(a)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into b(eid, id) values (1, 2) on duplicate key update name = values(a)",
|
||||
"OuterQuery": "insert into b(eid, id) values (1, 2) on duplicate key update name = values(a)",
|
||||
"Subquery": null,
|
||||
|
@ -1154,6 +1206,7 @@ insert into b (eid, id) values (1, 2) on duplicate key update eid = 2
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into b(eid, id) values (1, 2) on duplicate key update eid = 2",
|
||||
"OuterQuery": "insert into b(eid, id) values (1, 2) on duplicate key update eid = 2",
|
||||
"Subquery": null,
|
||||
|
@ -1178,6 +1231,7 @@ insert into b (id, eid) values (1, 2) on duplicate key update eid = values(a)
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "PK_CHANGE",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into b(id, eid) values (1, 2) on duplicate key update eid = values(a)",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1196,6 +1250,7 @@ insert into b (eid, id) select * from a
|
|||
"PlanId": "INSERT_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into b(eid, id) select * from a",
|
||||
"OuterQuery": "insert into b(eid, id) values :_rowValues",
|
||||
"Subquery": "select * from a limit :_vtMaxResultSize",
|
||||
|
@ -1220,6 +1275,7 @@ insert into b (eid, id) values (1, 2), (3, 4)
|
|||
"PlanId": "INSERT_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "insert into b(eid, id) values (1, 2), (3, 4)",
|
||||
"OuterQuery": "insert into b(eid, id) values (1, 2), (3, 4)",
|
||||
"Subquery": null,
|
||||
|
@ -1247,6 +1303,7 @@ update b set eid=1
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update b set eid = 1",
|
||||
"OuterQuery": "update b set eid = 1 where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from b limit :_vtMaxResultSize for update",
|
||||
|
@ -1268,6 +1325,7 @@ update b set eid=foo()
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "PK_CHANGE",
|
||||
"TableName": "b",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update b set eid = foo()",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1285,6 +1343,7 @@ update a set name='foo'
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo'",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a limit :_vtMaxResultSize for update",
|
||||
|
@ -1302,6 +1361,7 @@ update a set name='foo' where eid+1=1
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo' where eid+1 = 1",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid+1 = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1320,6 +1380,7 @@ update a set name='foo' where eid=1 and id=1
|
|||
"PlanId": "DML_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo' where eid = 1 and id = 1",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = 1 and id = 1",
|
||||
"Subquery": "select eid, id from a where eid = 1 and id = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1341,6 +1402,7 @@ update a set name='foo' where eid=1
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo' where eid = 1",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1359,6 +1421,7 @@ update a set name='foo' where eid=1 limit 10
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo' where eid = 1 limit 10",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid = 1 limit 10 for update",
|
||||
|
@ -1377,6 +1440,7 @@ update a set name='foo' where eid=1 and name='foo'
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update a set name = 'foo' where eid = 1 and name = 'foo'",
|
||||
"OuterQuery": "update a set name = 'foo' where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid = 1 and name = 'foo' limit :_vtMaxResultSize for update",
|
||||
|
@ -1395,6 +1459,7 @@ update c set eid=1
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "TABLE_NOINDEX",
|
||||
"TableName": "c",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "update c set eid = 1",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1412,6 +1477,7 @@ delete from a
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from a",
|
||||
"OuterQuery": "delete from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a limit :_vtMaxResultSize for update",
|
||||
|
@ -1429,6 +1495,7 @@ delete from a where eid+1=1
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "WHERE",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from a where eid+1 = 1",
|
||||
"OuterQuery": "delete from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid+1 = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1447,6 +1514,7 @@ delete from a where eid=1 and id=1
|
|||
"PlanId": "DML_PK",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from a where eid = 1 and id = 1",
|
||||
"OuterQuery": "delete from a where eid = 1 and id = 1",
|
||||
"Subquery": "select eid, id from a where eid = 1 and id = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1468,6 +1536,7 @@ delete from a where eid=1
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from a where eid = 1",
|
||||
"OuterQuery": "delete from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid = 1 limit :_vtMaxResultSize for update",
|
||||
|
@ -1486,6 +1555,7 @@ delete from a where eid=1 and name='foo'
|
|||
"PlanId": "DML_SUBQUERY",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "a",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from a where eid = 1 and name = 'foo'",
|
||||
"OuterQuery": "delete from a where eid = :0 and id = :1",
|
||||
"Subquery": "select eid, id from a where eid = 1 and name = 'foo' limit :_vtMaxResultSize for update",
|
||||
|
@ -1504,6 +1574,7 @@ delete from c
|
|||
"PlanId": "PASS_DML",
|
||||
"Reason": "TABLE_NOINDEX",
|
||||
"TableName": "c",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "delete from c",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1522,6 +1593,7 @@ set a=1
|
|||
"PlanId": "SET",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "set a = 1",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1540,6 +1612,7 @@ set a='b'
|
|||
"PlanId": "SET",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "set a = 'b'",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
@ -1558,6 +1631,7 @@ set a=1, b=2
|
|||
"PlanId": "SET",
|
||||
"Reason": "DEFAULT",
|
||||
"TableName": "",
|
||||
"FieldQuery": null,
|
||||
"FullQuery": "set a = 1, b = 2",
|
||||
"OuterQuery": null,
|
||||
"Subquery": null,
|
||||
|
|
|
@ -24,6 +24,7 @@ func init() {
|
|||
type PoolConnection interface {
|
||||
ExecuteFetch(query []byte, maxrows int, wantfields bool) (*proto.QueryResult, error)
|
||||
ExecuteStreamFetch(query []byte, callback func(interface{}) error, streamBufferSize int) error
|
||||
VerifyStrict() bool
|
||||
Id() int64
|
||||
Close()
|
||||
IsClosed() bool
|
||||
|
|
|
@ -65,7 +65,7 @@ type CacheInvalidator interface {
|
|||
func NewQueryEngine(config Config) *QueryEngine {
|
||||
qe := &QueryEngine{}
|
||||
qe.cachePool = NewCachePool(config.CachePoolCap, time.Duration(config.QueryTimeout*1e9), time.Duration(config.IdleTimeout*1e9))
|
||||
qe.schemaInfo = NewSchemaInfo(config.QueryCacheSize, time.Duration(config.SchemaReloadTime*1e9))
|
||||
qe.schemaInfo = NewSchemaInfo(config.QueryCacheSize, time.Duration(config.SchemaReloadTime*1e9), time.Duration(config.IdleTimeout*1e9))
|
||||
qe.connPool = NewConnectionPool(config.PoolSize, time.Duration(config.IdleTimeout*1e9))
|
||||
qe.streamConnPool = NewConnectionPool(config.StreamPoolSize, time.Duration(config.IdleTimeout*1e9))
|
||||
qe.reservedPool = NewReservedPool()
|
||||
|
@ -196,7 +196,7 @@ func (qe *QueryEngine) Execute(logStats *sqlQueryStats, query *proto.Query) (rep
|
|||
logStats.OriginalSql = query.Sql
|
||||
// cheap hack: strip trailing comment into a special bind var
|
||||
stripTrailing(query)
|
||||
basePlan := qe.schemaInfo.GetPlan(query.Sql, len(query.BindVariables) != 0)
|
||||
basePlan := qe.schemaInfo.GetPlan(logStats, query.Sql)
|
||||
if basePlan.PlanId == sqlparser.PLAN_DDL {
|
||||
defer queryStats.Record("DDL", time.Now())
|
||||
return qe.execDDL(logStats, query.Sql)
|
||||
|
@ -240,6 +240,20 @@ func (qe *QueryEngine) Execute(logStats *sqlQueryStats, query *proto.Query) (rep
|
|||
defer queryStats.Record("PASS_SELECT", time.Now())
|
||||
reply = qe.fullFetch(logStats, conn, plan.FullQuery, plan.BindVars, nil, nil)
|
||||
}
|
||||
} else if plan.ConnectionId != 0 {
|
||||
conn := qe.reservedPool.Get(plan.ConnectionId)
|
||||
defer conn.Recycle()
|
||||
if plan.PlanId.IsSelect() {
|
||||
logStats.PlanType = "PASS_SELECT"
|
||||
defer queryStats.Record("PASS_SELECT", time.Now())
|
||||
reply = qe.fullFetch(logStats, conn, plan.FullQuery, plan.BindVars, nil, nil)
|
||||
} else if plan.PlanId == sqlparser.PLAN_SET {
|
||||
logStats.PlanType = "SET"
|
||||
defer queryStats.Record("SET", time.Now())
|
||||
reply = qe.fullFetch(logStats, conn, plan.FullQuery, plan.BindVars, nil, nil)
|
||||
} else {
|
||||
panic(NewTabletError(FAIL, "DMLs not allowed outside of transactions"))
|
||||
}
|
||||
} else {
|
||||
switch plan.PlanId {
|
||||
case sqlparser.PLAN_PASS_SELECT:
|
||||
|
@ -263,9 +277,13 @@ func (qe *QueryEngine) Execute(logStats *sqlQueryStats, query *proto.Query) (rep
|
|||
// It may not be worth caching the results. So, just pass through.
|
||||
reply = qe.execSelect(logStats, plan)
|
||||
case sqlparser.PLAN_SET:
|
||||
waitingForConnectionStart := time.Now()
|
||||
conn := qe.connPool.Get()
|
||||
logStats.WaitingForConnection += time.Now().Sub(waitingForConnectionStart)
|
||||
defer conn.Recycle()
|
||||
logStats.PlanType = "SET"
|
||||
defer queryStats.Record("SET", time.Now())
|
||||
reply = qe.execSet(logStats, plan)
|
||||
reply = qe.execSet(logStats, conn, plan)
|
||||
default:
|
||||
panic(NewTabletError(FAIL, "DMLs not allowed outside of transactions"))
|
||||
}
|
||||
|
@ -399,9 +417,6 @@ func (qe *QueryEngine) execSubquery(logStats *sqlQueryStats, plan *CompiledPlan)
|
|||
func (qe *QueryEngine) fetchPKRows(logStats *sqlQueryStats, plan *CompiledPlan, pkRows [][]sqltypes.Value) (result *mproto.QueryResult) {
|
||||
result = &mproto.QueryResult{}
|
||||
tableInfo := plan.TableInfo
|
||||
if plan.Fields == nil {
|
||||
panic("unexpected")
|
||||
}
|
||||
result.Fields = plan.Fields
|
||||
rows := make([][]sqltypes.Value, 0, len(pkRows))
|
||||
var hits, absent, misses int64
|
||||
|
@ -466,23 +481,9 @@ func (qe *QueryEngine) compareRow(logStats *sqlQueryStats, plan *CompiledPlan, c
|
|||
}
|
||||
|
||||
func (qe *QueryEngine) execSelect(logStats *sqlQueryStats, plan *CompiledPlan) (result *mproto.QueryResult) {
|
||||
if plan.Fields != nil {
|
||||
result = qe.qFetch(logStats, plan, plan.FullQuery, nil)
|
||||
result.Fields = plan.Fields
|
||||
return
|
||||
}
|
||||
var conn PoolConnection
|
||||
waitingForConnectionStart := time.Now()
|
||||
if plan.ConnectionId != 0 {
|
||||
conn = qe.reservedPool.Get(plan.ConnectionId)
|
||||
} else {
|
||||
conn = qe.connPool.Get()
|
||||
}
|
||||
logStats.WaitingForConnection += time.Now().Sub(waitingForConnectionStart)
|
||||
defer conn.Recycle()
|
||||
result = qe.fullFetch(logStats, conn, plan.FullQuery, plan.BindVars, nil, nil)
|
||||
qe.schemaInfo.SetFields(plan.Query, plan.ExecPlan, result.Fields)
|
||||
return result
|
||||
result = qe.qFetch(logStats, plan, plan.FullQuery, nil)
|
||||
result.Fields = plan.Fields
|
||||
return
|
||||
}
|
||||
|
||||
func (qe *QueryEngine) execInsertPK(logStats *sqlQueryStats, conn PoolConnection, plan *CompiledPlan, invalidator CacheInvalidator) (result *mproto.QueryResult) {
|
||||
|
@ -563,7 +564,7 @@ func (qe *QueryEngine) execDMLPKRows(logStats *sqlQueryStats, conn PoolConnectio
|
|||
return &mproto.QueryResult{RowsAffected: rowsAffected}
|
||||
}
|
||||
|
||||
func (qe *QueryEngine) execSet(logStats *sqlQueryStats, plan *CompiledPlan) (result *mproto.QueryResult) {
|
||||
func (qe *QueryEngine) execSet(logStats *sqlQueryStats, conn PoolConnection, plan *CompiledPlan) (result *mproto.QueryResult) {
|
||||
switch plan.SetKey {
|
||||
case "vt_pool_size":
|
||||
qe.connPool.SetCapacity(int(plan.SetValue.(float64)))
|
||||
|
@ -608,20 +609,15 @@ func (qe *QueryEngine) execSet(logStats *sqlQueryStats, plan *CompiledPlan) (res
|
|||
qe.activePool.SetIdleTimeout(time.Duration(t))
|
||||
return &mproto.QueryResult{}
|
||||
}
|
||||
return qe.qFetch(logStats, plan, plan.FullQuery, nil)
|
||||
return qe.fullFetch(logStats, conn, plan.FullQuery, plan.BindVars, nil, nil)
|
||||
}
|
||||
|
||||
func (qe *QueryEngine) qFetch(logStats *sqlQueryStats, plan *CompiledPlan, parsed_query *sqlparser.ParsedQuery, listVars []sqltypes.Value) (result *mproto.QueryResult) {
|
||||
sql := qe.generateFinalSql(parsed_query, plan.BindVars, listVars, nil)
|
||||
q, ok := qe.consolidator.Create(string(sql))
|
||||
if ok {
|
||||
var conn PoolConnection
|
||||
waitingForConnectionStart := time.Now()
|
||||
if plan.ConnectionId != 0 {
|
||||
conn = qe.reservedPool.Get(plan.ConnectionId)
|
||||
} else {
|
||||
conn = qe.connPool.Get()
|
||||
}
|
||||
conn := qe.connPool.Get()
|
||||
logStats.WaitingForConnection += time.Now().Sub(waitingForConnectionStart)
|
||||
defer conn.Recycle()
|
||||
q.Result, q.Err = qe.executeSql(logStats, conn, sql, false)
|
||||
|
|
|
@ -38,16 +38,17 @@ type SchemaInfo struct {
|
|||
tables map[string]*TableInfo
|
||||
queryCacheSize int
|
||||
queries *cache.LRUCache
|
||||
connFactory CreateConnectionFunc
|
||||
connPool *ConnectionPool
|
||||
cachePool *CachePool
|
||||
reloadTime time.Duration
|
||||
lastChange time.Time
|
||||
ticks *timer.Timer
|
||||
}
|
||||
|
||||
func NewSchemaInfo(queryCacheSize int, reloadTime time.Duration) *SchemaInfo {
|
||||
func NewSchemaInfo(queryCacheSize int, reloadTime time.Duration, idleTimeout time.Duration) *SchemaInfo {
|
||||
si := &SchemaInfo{
|
||||
queryCacheSize: queryCacheSize,
|
||||
connPool: NewConnectionPool(2, idleTimeout),
|
||||
reloadTime: reloadTime,
|
||||
ticks: timer.NewTimer(reloadTime),
|
||||
}
|
||||
|
@ -56,11 +57,9 @@ func NewSchemaInfo(queryCacheSize int, reloadTime time.Duration) *SchemaInfo {
|
|||
}
|
||||
|
||||
func (si *SchemaInfo) Open(connFactory CreateConnectionFunc, cachePool *CachePool) {
|
||||
conn, err := connFactory()
|
||||
if err != nil {
|
||||
panic(NewTabletError(FATAL, "Could not get connection: %v", err))
|
||||
}
|
||||
defer conn.Close()
|
||||
si.connPool.Open(connFactory)
|
||||
conn := si.connPool.Get()
|
||||
defer conn.Recycle()
|
||||
|
||||
if !conn.VerifyStrict() {
|
||||
panic(NewTabletError(FATAL, "Could not verify strict mode"))
|
||||
|
@ -90,7 +89,6 @@ func (si *SchemaInfo) Open(connFactory CreateConnectionFunc, cachePool *CachePoo
|
|||
si.tables[tableName] = tableInfo
|
||||
}
|
||||
si.queries = cache.NewLRUCache(uint64(si.queryCacheSize))
|
||||
si.connFactory = connFactory
|
||||
si.ticks.Start(func() { si.Reload() })
|
||||
}
|
||||
|
||||
|
@ -110,18 +108,14 @@ func (si *SchemaInfo) updateLastChange(createTime sqltypes.Value) {
|
|||
|
||||
func (si *SchemaInfo) Close() {
|
||||
si.ticks.Stop()
|
||||
si.connPool.Close()
|
||||
si.tables = nil
|
||||
si.queries = nil
|
||||
si.connFactory = nil
|
||||
}
|
||||
|
||||
func (si *SchemaInfo) Reload() {
|
||||
conn, err := si.connFactory()
|
||||
if err != nil {
|
||||
relog.Error("Could not get connection for reload: %v", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
conn := si.connPool.Get()
|
||||
defer conn.Recycle()
|
||||
tables, err := conn.ExecuteFetch([]byte(fmt.Sprintf("%s and unix_timestamp(create_time) > %v", base_show_tables, si.lastChange.Unix())), 1000, false)
|
||||
if err != nil {
|
||||
relog.Warning("Could not get table list for reload: %v", err)
|
||||
|
@ -147,15 +141,12 @@ func (si *SchemaInfo) triggerReload() {
|
|||
}
|
||||
|
||||
func (si *SchemaInfo) CreateTable(tableName string) {
|
||||
conn, err := si.connFactory()
|
||||
if err != nil {
|
||||
panic(NewTabletError(FATAL, "Could not get connection for create table %s: %v", tableName, err))
|
||||
}
|
||||
defer conn.Close()
|
||||
conn := si.connPool.Get()
|
||||
defer conn.Recycle()
|
||||
si.createTable(conn, tableName)
|
||||
}
|
||||
|
||||
func (si *SchemaInfo) createTable(conn *DBConnection, tableName string) {
|
||||
func (si *SchemaInfo) createTable(conn PoolConnection, tableName string) {
|
||||
tables, err := conn.ExecuteFetch([]byte(fmt.Sprintf("%s and table_name = '%s'", base_show_tables, tableName)), 1, false)
|
||||
if err != nil {
|
||||
panic(NewTabletError(FAIL, "Error fetching table %s: %v", tableName, err))
|
||||
|
@ -195,7 +186,7 @@ func (si *SchemaInfo) DropTable(tableName string) {
|
|||
relog.Info("Table %s forgotten", tableName)
|
||||
}
|
||||
|
||||
func (si *SchemaInfo) GetPlan(sql string, mustCache bool) (plan *ExecPlan) {
|
||||
func (si *SchemaInfo) GetPlan(logStats *sqlQueryStats, sql string) (plan *ExecPlan) {
|
||||
si.mu.Lock()
|
||||
defer si.mu.Unlock()
|
||||
if plan := si.getQuery(sql); plan != nil {
|
||||
|
@ -215,15 +206,22 @@ func (si *SchemaInfo) GetPlan(sql string, mustCache bool) (plan *ExecPlan) {
|
|||
panic(NewTabletError(FAIL, "%s", err))
|
||||
}
|
||||
plan = &ExecPlan{splan, tableInfo, nil}
|
||||
if plan.PlanId.IsSelect() && plan.ColumnNumbers != nil {
|
||||
plan.Fields = applyFieldFilter(plan.ColumnNumbers, tableInfo.Fields)
|
||||
}
|
||||
if plan.PlanId == sqlparser.PLAN_DDL {
|
||||
if plan.PlanId.IsSelect() {
|
||||
conn := si.connPool.Get()
|
||||
defer conn.Recycle()
|
||||
sql := []byte(plan.FieldQuery.Query)
|
||||
r, err := conn.ExecuteFetch(sql, 1, true)
|
||||
logStats.QuerySources |= QUERY_SOURCE_MYSQL
|
||||
logStats.NumberOfQueries += 1
|
||||
logStats.AddRewrittenSql(sql)
|
||||
if err != nil {
|
||||
panic(NewTabletError(FAIL, "Error fetching fields: %v", err))
|
||||
}
|
||||
plan.Fields = r.Fields
|
||||
} else if plan.PlanId == sqlparser.PLAN_DDL || plan.PlanId == sqlparser.PLAN_SET {
|
||||
return plan
|
||||
}
|
||||
if mustCache {
|
||||
si.queries.Set(sql, plan)
|
||||
}
|
||||
si.queries.Set(sql, plan)
|
||||
return plan
|
||||
}
|
||||
|
||||
|
@ -237,13 +235,6 @@ func (si *SchemaInfo) GetStreamPlan(sql string) *sqlparser.ParsedQuery {
|
|||
return fullQuery
|
||||
}
|
||||
|
||||
func (si *SchemaInfo) SetFields(sql string, plan *ExecPlan, fields []mproto.Field) {
|
||||
si.mu.Lock()
|
||||
defer si.mu.Unlock()
|
||||
newPlan := &ExecPlan{plan.ExecPlan, plan.TableInfo, fields}
|
||||
si.queries.Set(sql, newPlan)
|
||||
}
|
||||
|
||||
func (si *SchemaInfo) GetTable(tableName string) *TableInfo {
|
||||
si.mu.Lock()
|
||||
defer si.mu.Unlock()
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"code.google.com/p/vitess/go/mysql/proto"
|
||||
"code.google.com/p/vitess/go/relog"
|
||||
"code.google.com/p/vitess/go/sqltypes"
|
||||
"code.google.com/p/vitess/go/vt/schema"
|
||||
|
@ -24,13 +23,12 @@ var hashRegistry map[string]string = make(map[string]string)
|
|||
|
||||
type TableInfo struct {
|
||||
*schema.Table
|
||||
Cache *RowCache
|
||||
Fields []proto.Field
|
||||
Cache *RowCache
|
||||
// stats updated by sqlquery.go
|
||||
hits, absent, misses, invalidations int64
|
||||
}
|
||||
|
||||
func NewTableInfo(conn *DBConnection, tableName string, tableType string, createTime sqltypes.Value, comment string, cachePool *CachePool) (self *TableInfo) {
|
||||
func NewTableInfo(conn PoolConnection, tableName string, tableType string, createTime sqltypes.Value, comment string, cachePool *CachePool) (self *TableInfo) {
|
||||
if tableName == "dual" {
|
||||
return &TableInfo{Table: schema.NewTable(tableName)}
|
||||
}
|
||||
|
@ -39,7 +37,7 @@ func NewTableInfo(conn *DBConnection, tableName string, tableType string, create
|
|||
return self
|
||||
}
|
||||
|
||||
func loadTableInfo(conn *DBConnection, tableName string) (self *TableInfo) {
|
||||
func loadTableInfo(conn PoolConnection, tableName string) (self *TableInfo) {
|
||||
self = &TableInfo{Table: schema.NewTable(tableName)}
|
||||
if !self.fetchColumns(conn) {
|
||||
return nil
|
||||
|
@ -50,7 +48,7 @@ func loadTableInfo(conn *DBConnection, tableName string) (self *TableInfo) {
|
|||
return self
|
||||
}
|
||||
|
||||
func (self *TableInfo) fetchColumns(conn *DBConnection) bool {
|
||||
func (self *TableInfo) fetchColumns(conn PoolConnection) bool {
|
||||
columns, err := conn.ExecuteFetch([]byte(fmt.Sprintf("describe %s", self.Name)), 10000, false)
|
||||
if err != nil {
|
||||
relog.Warning("%s", err.Error())
|
||||
|
@ -62,7 +60,7 @@ func (self *TableInfo) fetchColumns(conn *DBConnection) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (self *TableInfo) fetchIndexes(conn *DBConnection) bool {
|
||||
func (self *TableInfo) fetchIndexes(conn PoolConnection) bool {
|
||||
indexes, err := conn.ExecuteFetch([]byte(fmt.Sprintf("show index from %s", self.Name)), 10000, false)
|
||||
if err != nil {
|
||||
relog.Warning("%s", err.Error())
|
||||
|
@ -107,7 +105,7 @@ func (self *TableInfo) fetchIndexes(conn *DBConnection) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (self *TableInfo) initRowCache(conn *DBConnection, tableType string, createTime sqltypes.Value, comment string, cachePool *CachePool) {
|
||||
func (self *TableInfo) initRowCache(conn PoolConnection, tableType string, createTime sqltypes.Value, comment string, cachePool *CachePool) {
|
||||
if cachePool.IsClosed() {
|
||||
return
|
||||
}
|
||||
|
@ -133,24 +131,18 @@ func (self *TableInfo) initRowCache(conn *DBConnection, tableType string, create
|
|||
}
|
||||
}
|
||||
|
||||
rowInfo, err := conn.ExecuteFetch([]byte(fmt.Sprintf("select * from %s where 1!=1", self.Name)), 10000, true)
|
||||
if err != nil {
|
||||
relog.Warning("Failed to fetch column info for %s, table will not be cached: %s", self.Name, err.Error())
|
||||
return
|
||||
}
|
||||
thash := self.computePrefix(conn, createTime)
|
||||
if thash == "" {
|
||||
return
|
||||
}
|
||||
|
||||
self.Fields = rowInfo.Fields
|
||||
self.CacheType = 1
|
||||
self.Cache = NewRowCache(self, thash, cachePool)
|
||||
}
|
||||
|
||||
var autoIncr = regexp.MustCompile("auto_increment=\\d+")
|
||||
|
||||
func (self *TableInfo) computePrefix(conn *DBConnection, createTime sqltypes.Value) string {
|
||||
func (self *TableInfo) computePrefix(conn PoolConnection, createTime sqltypes.Value) string {
|
||||
if createTime.IsNull() {
|
||||
relog.Warning("%s has no time stamp. Will not be cached.", self.Name)
|
||||
return ""
|
||||
|
|
|
@ -10,14 +10,18 @@ cases = [
|
|||
sql="select * from vtocc_cached where eid = 2 and bid = %(bid)s",
|
||||
bindings={"bid": None},
|
||||
result=[],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = null",
|
||||
rewritten=[
|
||||
"select * from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = null"],
|
||||
cache_absent=1),
|
||||
|
||||
Case(doc="SELECT_PK (empty cache)",
|
||||
query_plan="SELECT_PK",
|
||||
sql="select * from vtocc_cached where eid = 2 and bid = 'foo'",
|
||||
result=[(2, 'foo', 'abcd2', 'efgh')],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = 'foo'",
|
||||
rewritten=[
|
||||
"select * from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = 'foo'"],
|
||||
cache_misses=1),
|
||||
# (2.foo) is in cache
|
||||
|
||||
|
@ -25,7 +29,7 @@ cases = [
|
|||
query_plan="SELECT_PK",
|
||||
sql="select bid, eid, name, foo from vtocc_cached where eid = 2 and bid = 'foo'",
|
||||
result=[('foo', 2, 'abcd2', 'efgh')],
|
||||
rewritten=[],
|
||||
rewritten=["select bid, eid, name, foo from vtocc_cached where 1 != 1"],
|
||||
cache_hits=1),
|
||||
# (2.foo) is in cache
|
||||
|
||||
|
@ -33,7 +37,9 @@ cases = [
|
|||
query_plan="SELECT_PK",
|
||||
sql="select bid, eid, name, foo from vtocc_cached where eid = 3 and bid = 'foo'",
|
||||
result=[],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 3 and bid = 'foo'",
|
||||
rewritten=[
|
||||
"select bid, eid, name, foo from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 3 and bid = 'foo'"],
|
||||
cache_absent=1),
|
||||
# (2.foo)
|
||||
|
||||
|
@ -41,8 +47,9 @@ cases = [
|
|||
sql="select * from vtocc_cached where eid = 2 and name = 'abcd2'",
|
||||
result=[(2L, 'bar', 'abcd2', 'efgh'), (2L, 'foo', 'abcd2', 'efgh')],
|
||||
rewritten=[
|
||||
"select eid, bid from vtocc_cached use index (aname) where eid = 2 and name = 'abcd2' limit 10001",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = 'bar'"],
|
||||
"select * from vtocc_cached where 1 != 1",
|
||||
"select eid, bid from vtocc_cached use index (aname) where eid = 2 and name = 'abcd2' limit 10001",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 2 and bid = 'bar'"],
|
||||
cache_hits=1,
|
||||
cache_misses=1),
|
||||
# (2.bar, 2.foo)
|
||||
|
@ -57,7 +64,9 @@ cases = [
|
|||
Case(doc="out of order columns list",
|
||||
sql="select bid, eid from vtocc_cached where eid = 1 and bid = 'foo'",
|
||||
result=[('foo', 1)],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'foo'",
|
||||
rewritten=[
|
||||
"select bid, eid from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'foo'"],
|
||||
cache_misses=1),
|
||||
# (1.foo, 2.bar, 2.foo)
|
||||
|
||||
|
@ -73,7 +82,9 @@ cases = [
|
|||
['select * from vtocc_cached',
|
||||
Case(query_plan="SELECT_CACHE_RESULT",
|
||||
sql="select eid, bid, name, foo from vtocc_cached",
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached limit 10001",
|
||||
rewritten=[
|
||||
"select eid, bid, name, foo from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached limit 10001"],
|
||||
cache_hits=0,
|
||||
cache_misses=0,
|
||||
cache_absent=0,
|
||||
|
@ -84,7 +95,9 @@ cases = [
|
|||
Case(doc="verify 1.bar is not cached",
|
||||
sql="select bid, eid from vtocc_cached where eid = 1 and bid = 'bar'",
|
||||
result=[('bar', 1)],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'bar'",
|
||||
rewritten=[
|
||||
"select bid, eid from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'bar'"],
|
||||
cache_misses=1),
|
||||
# (1.foo, 1.bar, 2.foo, 2.bar)
|
||||
|
||||
|
@ -163,7 +176,7 @@ cases = [
|
|||
Case(doc="Verify 1.foo is in cache",
|
||||
sql="select * from vtocc_cached where eid = 1 and bid = 'foo'",
|
||||
result=[(1, 'foo', 'abcd1', 'efgh')],
|
||||
rewritten=[],
|
||||
rewritten=["select * from vtocc_cached where 1 != 1"],
|
||||
cache_hits=1),
|
||||
# (1.foo) is in cache
|
||||
|
||||
|
@ -173,7 +186,9 @@ cases = [
|
|||
Case(doc="Verify cache is empty after DDL",
|
||||
sql="select * from vtocc_cached where eid = 1 and bid = 'foo'",
|
||||
result=[(1, 'foo', 'abcd1', 'efgh')],
|
||||
rewritten="select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'foo'",
|
||||
rewritten=[
|
||||
"select * from vtocc_cached where 1 != 1",
|
||||
"select eid, bid, name, foo from vtocc_cached where eid = 1 and bid = 'foo'"],
|
||||
cache_misses=1),
|
||||
|
||||
# (1.foo)
|
||||
|
@ -194,7 +209,9 @@ cases = [
|
|||
'commit',
|
||||
Case(sql="select * from vtocc_ints where tiny = -128",
|
||||
result=[(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648L, 4294967295L, -9223372036854775808L, 18446744073709551615L, 2012)],
|
||||
rewritten="select tiny, tinyu, small, smallu, medium, mediumu, normal, normalu, big, bigu, y from vtocc_ints where tiny = -128"),
|
||||
rewritten=[
|
||||
"select * from vtocc_ints where 1 != 1",
|
||||
"select tiny, tinyu, small, smallu, medium, mediumu, normal, normalu, big, bigu, y from vtocc_ints where tiny = -128"]),
|
||||
Case(sql="select * from vtocc_ints where tiny = -128",
|
||||
result=[(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648L, 4294967295L, -9223372036854775808L, 18446744073709551615L, 2012)],
|
||||
rewritten=[]),
|
||||
|
@ -217,7 +234,9 @@ cases = [
|
|||
'commit',
|
||||
Case(sql="select * from vtocc_fracts where id = 1",
|
||||
result=[(1L, Decimal('1.99'), Decimal('2.99'), 3.9900000000000002, 4.9900000000000002)],
|
||||
rewritten="select id, deci, num, f, d from vtocc_fracts where id = 1"),
|
||||
rewritten=[
|
||||
"select * from vtocc_fracts where 1 != 1",
|
||||
"select id, deci, num, f, d from vtocc_fracts where id = 1"]),
|
||||
Case(sql="select * from vtocc_fracts where id = 1",
|
||||
result=[(1L, Decimal('1.99'), Decimal('2.99'), 3.9900000000000002, 4.9900000000000002)],
|
||||
rewritten=[]),
|
||||
|
@ -240,7 +259,9 @@ cases = [
|
|||
'commit',
|
||||
Case(sql="select * from vtocc_strings where vb = 'a'",
|
||||
result=[('a', 'b', 'c', 'd\x00\x00\x00', 'e', 'f', 'g', 'h', 'a', 'a,b')],
|
||||
rewritten="select vb, c, vc, b, tb, bl, ttx, tx, en, s from vtocc_strings where vb = 'a'"),
|
||||
rewritten=[
|
||||
"select * from vtocc_strings where 1 != 1",
|
||||
"select vb, c, vc, b, tb, bl, ttx, tx, en, s from vtocc_strings where vb = 'a'"]),
|
||||
Case(sql="select * from vtocc_strings where vb = 'a'",
|
||||
result=[('a', 'b', 'c', 'd\x00\x00\x00', 'e', 'f', 'g', 'h', 'a', 'a,b')],
|
||||
rewritten=[]),
|
||||
|
@ -263,7 +284,9 @@ cases = [
|
|||
'commit',
|
||||
Case(sql="select * from vtocc_misc where id = 1",
|
||||
result=[(1L, '\x01', datetime.date(2012, 1, 1), datetime.datetime(2012, 1, 1, 15, 45, 45), datetime.timedelta(0, 56745))],
|
||||
rewritten="select id, b, d, dt, t from vtocc_misc where id = 1"),
|
||||
rewritten=[
|
||||
"select * from vtocc_misc where 1 != 1",
|
||||
"select id, b, d, dt, t from vtocc_misc where id = 1"]),
|
||||
Case(sql="select * from vtocc_misc where id = 1",
|
||||
result=[(1L, '\x01', datetime.date(2012, 1, 1), datetime.datetime(2012, 1, 1, 15, 45, 45), datetime.timedelta(0, 56745))],
|
||||
rewritten=[]),
|
||||
|
|
|
@ -4,100 +4,142 @@ cases = [
|
|||
Case(doc='union',
|
||||
sql='select /* union */ eid, id from vtocc_a union select eid, id from vtocc_b',
|
||||
result=[(1L, 1L), (1L, 2L)],
|
||||
rewritten='select /* union */ eid, id from vtocc_a union select eid, id from vtocc_b'),
|
||||
rewritten=[
|
||||
'select eid, id from vtocc_a where 1 != 1 union select eid, id from vtocc_b where 1 != 1',
|
||||
'select /* union */ eid, id from vtocc_a union select eid, id from vtocc_b']),
|
||||
|
||||
Case(doc='double union',
|
||||
sql='select /* double union */ eid, id from vtocc_a union select eid, id from vtocc_b union select eid, id from vtocc_d',
|
||||
result=[(1L, 1L), (1L, 2L)],
|
||||
rewritten=[
|
||||
'select eid, id from vtocc_a where 1 != 1 union select eid, id from vtocc_b where 1 != 1 union select eid, id from vtocc_d where 1 != 1',
|
||||
'select /* double union */ eid, id from vtocc_a union select eid, id from vtocc_b union select eid, id from vtocc_d']),
|
||||
|
||||
Case(doc="distinct",
|
||||
sql='select /* distinct */ distinct * from vtocc_a',
|
||||
result=[(1L, 1L, 'abcd', 'efgh'), (1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* distinct */ distinct * from vtocc_a limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* distinct */ distinct * from vtocc_a limit 10001']),
|
||||
|
||||
Case(doc='group by',
|
||||
sql='select /* group by */ eid, sum(id) from vtocc_a group by eid',
|
||||
result=[(1L, 3L)],
|
||||
rewritten='select /* group by */ eid, sum(id) from vtocc_a group by eid limit 10001'),
|
||||
rewritten=[
|
||||
'select eid, sum(id) from vtocc_a where 1 != 1',
|
||||
'select /* group by */ eid, sum(id) from vtocc_a group by eid limit 10001']),
|
||||
Case(doc='having',
|
||||
sql='select /* having */ sum(id) from vtocc_a having sum(id) = 3',
|
||||
result=[(3L,)],
|
||||
rewritten='select /* having */ sum(id) from vtocc_a having sum(id) = 3 limit 10001',),
|
||||
rewritten=[
|
||||
'select sum(id) from vtocc_a where 1 != 1',
|
||||
'select /* having */ sum(id) from vtocc_a having sum(id) = 3 limit 10001']),
|
||||
|
||||
Case(doc='limit',
|
||||
sql='select /* limit */ eid, id from vtocc_a limit %(a)s',
|
||||
bindings={"a": 1},
|
||||
result=[(1L, 1L)],
|
||||
rewritten='select /* limit */ eid, id from vtocc_a limit 1'),
|
||||
rewritten=[
|
||||
'select eid, id from vtocc_a where 1 != 1',
|
||||
'select /* limit */ eid, id from vtocc_a limit 1']),
|
||||
Case(doc='multi-table',
|
||||
sql='select /* multi-table */ a.eid, a.id, b.eid, b.id from vtocc_a as a, vtocc_b as b',
|
||||
result=[(1L, 1L, 1L, 1L), (1L, 2L, 1L, 1L), (1L, 1L, 1L, 2L), (1L, 2L, 1L, 2L)],
|
||||
rewritten='select /* multi-table */ a.eid, a.id, b.eid, b.id from vtocc_a as a, vtocc_b as b limit 10001'),
|
||||
rewritten=[
|
||||
'select a.eid, a.id, b.eid, b.id from vtocc_a as a, vtocc_b as b where 1 != 1',
|
||||
'select /* multi-table */ a.eid, a.id, b.eid, b.id from vtocc_a as a, vtocc_b as b limit 10001']),
|
||||
|
||||
Case(doc='multi-table join',
|
||||
sql='select /* multi-table join */ a.eid, a.id, b.eid, b.id from vtocc_a as a join vtocc_b as b on a.eid = b.eid and a.id = b.id',
|
||||
result=[(1L, 1L, 1L, 1L), (1L, 2L, 1L, 2L)],
|
||||
rewritten='select /* multi-table join */ a.eid, a.id, b.eid, b.id from vtocc_a as a join vtocc_b as b on a.eid = b.eid and a.id = b.id limit 10001'),
|
||||
rewritten=[
|
||||
'select a.eid, a.id, b.eid, b.id from vtocc_a as a join vtocc_b as b on a.eid = b.eid and a.id = b.id where 1 != 1',
|
||||
'select /* multi-table join */ a.eid, a.id, b.eid, b.id from vtocc_a as a join vtocc_b as b on a.eid = b.eid and a.id = b.id limit 10001']),
|
||||
|
||||
|
||||
Case(doc='complex select list',
|
||||
sql='select /* complex select list */ eid+1, id from vtocc_a',
|
||||
result=[(2L, 1L), (2L, 2L)],
|
||||
rewritten='select /* complex select list */ eid+1, id from vtocc_a limit 10001'),
|
||||
rewritten=[
|
||||
'select eid+1, id from vtocc_a where 1 != 1',
|
||||
'select /* complex select list */ eid+1, id from vtocc_a limit 10001']),
|
||||
Case(doc="*",
|
||||
sql='select /* * */ * from vtocc_a',
|
||||
result=[(1L, 1L, 'abcd', 'efgh'), (1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* * */ * from vtocc_a limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* * */ * from vtocc_a limit 10001']),
|
||||
|
||||
Case(doc='table alias',
|
||||
sql='select /* table alias */ a.eid from vtocc_a as a where a.eid=1',
|
||||
result=[(1L,), (1L,)],
|
||||
rewritten='select /* table alias */ a.eid from vtocc_a as a where a.eid = 1 limit 10001'),
|
||||
rewritten=[
|
||||
'select a.eid from vtocc_a as a where 1 != 1',
|
||||
'select /* table alias */ a.eid from vtocc_a as a where a.eid = 1 limit 10001']),
|
||||
|
||||
Case(doc='parenthesised col',
|
||||
sql='select /* parenthesised col */ (eid) from vtocc_a where eid = 1 and id = 1',
|
||||
result=[(1L,)],
|
||||
rewritten='select /* parenthesised col */ eid from vtocc_a where eid = 1 and id = 1 limit 10001'),
|
||||
rewritten=[
|
||||
'select eid from vtocc_a where 1 != 1',
|
||||
'select /* parenthesised col */ eid from vtocc_a where eid = 1 and id = 1 limit 10001']),
|
||||
|
||||
MultiCase('for update',
|
||||
['begin',
|
||||
Case(sql='select /* for update */ eid from vtocc_a where eid = 1 and id = 1 for update',
|
||||
result=[(1L,)],
|
||||
rewritten='select /* for update */ eid from vtocc_a where eid = 1 and id = 1 limit 10001 for update'),
|
||||
rewritten=[
|
||||
'select eid from vtocc_a where 1 != 1',
|
||||
'select /* for update */ eid from vtocc_a where eid = 1 and id = 1 limit 10001 for update']),
|
||||
'commit']),
|
||||
|
||||
Case(doc='complex where',
|
||||
sql='select /* complex where */ id from vtocc_a where id+1 = 2',
|
||||
result=[(1L,)],
|
||||
rewritten='select /* complex where */ id from vtocc_a where id+1 = 2 limit 10001'),
|
||||
rewritten=[
|
||||
'select id from vtocc_a where 1 != 1',
|
||||
'select /* complex where */ id from vtocc_a where id+1 = 2 limit 10001']),
|
||||
|
||||
Case(doc='complex where (non-value operand)',
|
||||
sql='select /* complex where (non-value operand) */ eid, id from vtocc_a where eid = id',
|
||||
result=[(1L, 1L)],
|
||||
rewritten='select /* complex where (non-value operand) */ eid, id from vtocc_a where eid = id limit 10001'),
|
||||
rewritten=[
|
||||
'select eid, id from vtocc_a where 1 != 1',
|
||||
'select /* complex where (non-value operand) */ eid, id from vtocc_a where eid = id limit 10001']),
|
||||
|
||||
Case(doc='(condition)',
|
||||
sql='select /* (condition) */ * from vtocc_a where (eid = 1)',
|
||||
result=[(1L, 1L, 'abcd', 'efgh'), (1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* (condition) */ * from vtocc_a where (eid = 1) limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* (condition) */ * from vtocc_a where (eid = 1) limit 10001']),
|
||||
|
||||
Case(doc='inequality',
|
||||
sql='select /* inequality */ * from vtocc_a where id > 1',
|
||||
result=[(1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* inequality */ * from vtocc_a where id > 1 limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* inequality */ * from vtocc_a where id > 1 limit 10001']),
|
||||
Case(doc='in',
|
||||
sql='select /* in */ * from vtocc_a where id in (1, 2)',
|
||||
result=[(1L, 1L, 'abcd', 'efgh'), (1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* in */ * from vtocc_a where id in (1, 2) limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* in */ * from vtocc_a where id in (1, 2) limit 10001']),
|
||||
|
||||
Case(doc='between',
|
||||
sql='select /* between */ * from vtocc_a where id between 1 and 2',
|
||||
result=[(1L, 1L, 'abcd', 'efgh'), (1L, 2L, 'bcde', 'fghi')],
|
||||
rewritten='select /* between */ * from vtocc_a where id between 1 and 2 limit 10001'),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* between */ * from vtocc_a where id between 1 and 2 limit 10001']),
|
||||
|
||||
Case(doc='order',
|
||||
sql='select /* order */ * from vtocc_a order by id desc',
|
||||
result=[(1L, 2L, 'bcde', 'fghi'), (1L, 1L, 'abcd', 'efgh')],
|
||||
rewritten='select /* order */ * from vtocc_a order by id desc limit 10001'),
|
||||
Case(doc='string in bindings are not shown in logs',
|
||||
sql='select /* limit */ %(somestring)s, eid, id from vtocc_a limit %(a)s',
|
||||
bindings={"somestring": "Ala ma kota.", "a": 1}),
|
||||
rewritten=[
|
||||
'select * from vtocc_a where 1 != 1',
|
||||
'select /* order */ * from vtocc_a order by id desc limit 10001']),
|
||||
|
||||
MultiCase(
|
||||
'simple insert',
|
||||
|
|
|
@ -202,6 +202,11 @@ class TestNocache(framework.TestCase):
|
|||
self.assertEqual(vend.Voltron.QueryCache.Length, 2)
|
||||
self.assertEqual(vend.Voltron.QueryCache.Size, 2)
|
||||
self.assertEqual(vend.Voltron.QueryCache.Capacity, 5000)
|
||||
self.env.execute("select * from vtocc_test where intval=1")
|
||||
vend = self.env.debug_vars()
|
||||
self.assertEqual(vend.Voltron.QueryCache.Length, 3)
|
||||
self.assertEqual(vend.Voltron.QueryCache.Size, 3)
|
||||
self.assertEqual(vend.Voltron.QueryCache.Capacity, 5000)
|
||||
|
||||
def test_schema_reload_time(self):
|
||||
mcu = self.env.mysql_conn.cursor()
|
||||
|
@ -306,6 +311,14 @@ class TestNocache(framework.TestCase):
|
|||
results = self.env.conn._execute_batch(queries, bvars)
|
||||
self.assertEqual(results, [([(1L, 2L, 'bcde', 'fghi')], 1, 0, [('eid', 8), ('id', 3), ('name', 253), ('foo', 253)]), ([(1L, 2L)], 1, 0, [('eid', 8), ('id', 3)])])
|
||||
|
||||
def test_bind_in_select(self):
|
||||
try:
|
||||
bv = {}
|
||||
bv['bv'] = 1
|
||||
self.env.execute('select %(bv)s from vtocc_test', bv)
|
||||
except (db.MySQLErrors.DatabaseError, db.dbexceptions.OperationalError), e:
|
||||
self.assertContains(e[1], "error: Syntax error")
|
||||
|
||||
def test_types(self):
|
||||
self._verify_mismatch("insert into vtocc_ints(tiny) values('str')")
|
||||
self._verify_mismatch("insert into vtocc_ints(tiny) values(%(str)s)", {"str": "str"})
|
||||
|
|
Загрузка…
Ссылка в новой задаче