Merge branch 'master' of github.com:youtube/vitess

This commit is contained in:
Alain Jobart 2014-05-07 09:58:35 -07:00
Родитель 51a0a02e65 7f8cd915a7
Коммит b4bbc9a41e
17 изменённых файлов: 765 добавлений и 295 удалений

Просмотреть файл

@ -9,4 +9,5 @@ alter table a rename to b#{"Action": "RENAME", "TableName": "a", "NewTable": "b"
create view a asdasd#{"Action": "CREATE", "NewName": "a"}
alter view c alter foo#{"Action": "ALTER", "TableName": "c", "NewTable": "c"}
drop view b#{"Action": "DROP", "TableName": "b"}
select * from a#{"Action": "NONE"}
syntax error#{"Action": "NONE"}

Просмотреть файл

@ -163,6 +163,26 @@ select * from a join b
"SetValue": null
}
# multi-table (right join)
select * from a right join b
{
"PlanId": "PASS_SELECT",
"Reason": "TABLE",
"TableName": "",
"DisplayQuery": "select * from a right join b",
"FieldQuery": "select * from a right join b on 1 != 1 where 1 != 1",
"FullQuery": "select * from a right join b limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": null,
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# table not cached
select * from b
{
@ -285,6 +305,28 @@ select eid from a
"SetValue": null
}
# as
select eid as foo from a
{
"PlanId": "PASS_SELECT",
"Reason": "WHERE",
"TableName": "a",
"DisplayQuery": "select eid as foo from a",
"FieldQuery": "select eid as foo from a where 1 != 1",
"FullQuery": "select eid as foo from a limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": [
0
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# *
select * from a
{
@ -650,6 +692,31 @@ select * from a where eid=1 and id=1
"SetValue": null
}
# disjoint index match
select * from d where bar='foo' and id=1
{
"PlanId": "PASS_SELECT",
"Reason": "NOINDEX_MATCH",
"TableName": "d",
"DisplayQuery": "select * from d where bar = ? and id = ?",
"FieldQuery": "select * from d where 1 != 1",
"FullQuery": "select * from d where bar = 'foo' and id = 1 limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": [
0,
1,
2,
3
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# string pk match
select * from d where name='foo'
{
@ -702,6 +769,31 @@ select * from d where name='foo' limit 1
"SetValue": null
}
# reversed conditions with and clause
select * from d where 'foo'=name and eid=1
{
"PlanId": "PASS_SELECT",
"Reason": "WHERE",
"TableName": "d",
"DisplayQuery": "select * from d where ? = name and eid = ?",
"FieldQuery": "select * from d where 1 != 1",
"FullQuery": "select * from d where 'foo' = name and eid = 1 limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": [
0,
1,
2,
3
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# pk IN
select * from d where name in ('foo', 'bar')
{
@ -1014,6 +1106,56 @@ select * from d where id between 1 and 2
"SetValue": null
}
# non-column between
select * from d where 1 between 1 and 2
{
"PlanId": "PASS_SELECT",
"Reason": "WHERE",
"TableName": "d",
"DisplayQuery": "select * from d where ? between ? and ?",
"FieldQuery": "select * from d where 1 != 1",
"FullQuery": "select * from d where 1 between 1 and 2 limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": [
0,
1,
2,
3
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# complex predicate
select * from d where name is not null
{
"PlanId": "PASS_SELECT",
"Reason": "WHERE",
"TableName": "d",
"DisplayQuery": "select * from d where name is not null",
"FieldQuery": "select * from d where 1 != 1",
"FullQuery": "select * from d where name is not null limit :_vtMaxResultSize",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": [
0,
1,
2,
3
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "",
"SetValue": null
}
# order by
select * from a where eid=1 and id=1 order by name
{
@ -1114,6 +1256,10 @@ select * from d force index(d_bar_never) where bar = 'foo'
"SetValue": null
}
# column not found
select missing from a
"column missing not found in table a"
# insert cross-db
insert into b.a (eid, id) values (1, :a)
{
@ -1227,7 +1373,7 @@ insert into d(id) values(1)
# mismatch
insert into a (eid, id) values (1)
"Column count doesn't match value count"
"column count doesn't match value count"
# negative number
insert into a (eid, id) values (-1, 2)
@ -1444,6 +1590,32 @@ insert into b (eid, id) select * from a
"SetValue": null
}
# subquery with no column list
insert into b select * from a
{
"PlanId": "INSERT_SUBQUERY",
"Reason": "DEFAULT",
"TableName": "b",
"DisplayQuery": "insert into b select * from a",
"FieldQuery": null,
"FullQuery": "insert into b select * from a",
"OuterQuery": "insert into b values :_rowValues",
"Subquery": "select * from a limit :_vtMaxResultSize",
"IndexUsed": "",
"ColumnNumbers": [
0,
1
],
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": [
0,
1
],
"SetKey": "",
"SetValue": null
}
# multi-row
insert into b (eid, id) values (1, 2), (3, 4)
{
@ -1516,6 +1688,10 @@ update b set eid=1
"SetValue": null
}
# type mismatch
update b set eid=1.2
"type mismatch: strconv.ParseUint: parsing "1.2": invalid syntax"
# pk changed as qualified column name
update b set a.eid=1
{
@ -1888,6 +2064,26 @@ set a=1
"SetValue": 1
}
# float
set a=1.2
{
"PlanId": "SET",
"Reason": "DEFAULT",
"TableName": "",
"DisplayQuery": "set a = ?",
"FieldQuery": null,
"FullQuery": "set a = 1.2",
"OuterQuery": null,
"Subquery": null,
"IndexUsed": "",
"ColumnNumbers": null,
"PKValues": null,
"SecondaryPKValues": null,
"SubqueryPKColumns": null,
"SetKey": "a",
"SetValue": 1.2
}
# string
set a='b'
{
@ -1927,3 +2123,111 @@ set a=1, b=2
"SetKey": "",
"SetValue": null
}
# create
create table a(a int, b varchar(8))
{
"PlanId":"DDL",
"Reason":"DEFAULT",
"TableName":"",
"DisplayQuery":"create table a",
"FieldQuery":null,
"FullQuery":null,
"OuterQuery":null,
"Subquery":null,
"IndexUsed":"",
"ColumnNumbers":null,
"PKValues":null,
"SecondaryPKValues":null,
"SubqueryPKColumns":null,
"SetKey":"",
"SetValue":null
}
# alter
alter table a add column(a int)
{
"PlanId":"DDL",
"Reason":"DEFAULT",
"TableName":"",
"DisplayQuery":"alter table a",
"FieldQuery":null,
"FullQuery":null,
"OuterQuery":null,
"Subquery":null,
"IndexUsed":"",
"ColumnNumbers":null,
"PKValues":null,
"SecondaryPKValues":null,
"SubqueryPKColumns":null,
"SetKey":"",
"SetValue":null
}
# alter rename
alter table a rename b
{
"PlanId":"DDL",
"Reason":"DEFAULT",
"TableName":"",
"DisplayQuery":"rename table a b",
"FieldQuery":null,
"FullQuery":null,
"OuterQuery":null,
"Subquery":null,
"IndexUsed":"",
"ColumnNumbers":null,
"PKValues":null,
"SecondaryPKValues":null,
"SubqueryPKColumns":null,
"SetKey":"",
"SetValue":null
}
# rename
rename table a to b
{
"PlanId":"DDL",
"Reason":"DEFAULT",
"TableName":"",
"DisplayQuery":"rename table a b",
"FieldQuery":null,
"FullQuery":null,
"OuterQuery":null,
"Subquery":null,
"IndexUsed":"",
"ColumnNumbers":null,
"PKValues":null,
"SecondaryPKValues":null,
"SubqueryPKColumns":null,
"SetKey":"",
"SetValue":null
}
# drop
drop table a
{
"PlanId":"DDL",
"Reason":"DEFAULT",
"TableName":"",
"DisplayQuery":"drop table a",
"FieldQuery":null,
"FullQuery":null,
"OuterQuery":null,
"Subquery":null,
"IndexUsed":"",
"ColumnNumbers":null,
"PKValues":null,
"SecondaryPKValues":null,
"SubqueryPKColumns":null,
"SetKey":"",
"SetValue":null
}
# table not found
select * from aaaa
"table aaaa not found in schema"
# syntax error
syntax error
"syntax error at position 7 near syntax"

Просмотреть файл

@ -0,0 +1,6 @@
select !8 from t#syntax error at position 9 near unexpected character '!'
select $ from t#syntax error at position 9 near unexpected character '$'
select : from t#syntax error at position 9 near :
select 078 from t#syntax error at position 11 near 078
select 'aa\#syntax error at position 12 near aa
select 'aa#syntax error at position 12 near aa

Просмотреть файл

@ -1,5 +1,12 @@
select 1 from t
select .1 from t
select 1.2e1 from t
select 1.2e+1 from t
select 1.2e-1 from t
select 08.3 from t
select -1 from t where b = -2
select 1 from t // aa#select 1 from t
select 1 from t -- aa#select 1 from t
select /* simplest */ 1 from t
select /* back-quote */ 1 from `t`#select /* back-quote */ 1 from t
select /* back-quote keyword */ 1 from `from`#select /* back-quote keyword */ 1 from `from`
@ -104,6 +111,7 @@ select /* multiple positional arguments */ ?, ? from t#select /* multiple positi
select /* null */ null from t
select /* octal */ 010 from t
select /* hex */ 0xf0 from t
select /* hex caps */ 0xF0 from t
select /* float */ 0.1 from t
select /* group by */ 1 from t group by a
select /* having */ 1 from t having a = b

Просмотреть файл

@ -0,0 +1,25 @@
# select
select * from a
{
"DisplayQuery": "select * from a",
"FullQuery": "select * from a"
}
# select for update
select * from a for update
"select with lock disallowed with streaming"
# union
select * from a union select * from b
{
"DisplayQuery": "select * from a union select * from b",
"FullQuery": "select * from a union select * from b"
}
# dml
update a set b = 1
"update not allowed for streaming"
# syntax error
syntax error
"syntax error at position 7 near syntax"

Просмотреть файл

@ -218,7 +218,7 @@ func BuildValue(goval interface{}) (v Value, err error) {
case Value:
v = bindVal
default:
return Value{}, fmt.Errorf("Unsupported bind variable type %T: %v", goval, goval)
return Value{}, fmt.Errorf("unsupported bind variable type %T: %v", goval, goval)
}
return v, nil
}

Просмотреть файл

@ -34,8 +34,5 @@ func extractDBName(node *Node) string {
if node.Type != '.' {
return ""
}
if node.At(0).Type != ID {
return ""
}
return string(node.At(0).Value)
}

Просмотреть файл

@ -264,7 +264,7 @@ func (node *Node) execAnalyzeSql(getTable TableGetter) (plan *ExecPlan) {
case CREATE, ALTER, DROP, RENAME:
return &ExecPlan{PlanId: PLAN_DDL}
}
panic(NewParserError("Invalid SQL"))
panic(NewParserError("invalid SQL"))
}
func (node *Node) execAnalyzeSelect(getTable TableGetter) (plan *ExecPlan) {
@ -542,7 +542,7 @@ func (node *Node) execAnalyzeSet() (plan *ExecPlan) {
func (node *ExecPlan) setTableInfo(tableName string, getTable TableGetter) *schema.Table {
tableInfo, ok := getTable(tableName)
if !ok {
panic(NewParserError("Table %s not found in schema", tableName))
panic(NewParserError("table %s not found in schema", tableName))
}
node.TableName = tableInfo.Name
return tableInfo
@ -582,7 +582,7 @@ func (node *Node) execAnalyzeSelectExpressions(table *schema.Table) (selects []i
} else if colIndex := table.FindColumn(name); colIndex != -1 {
selects = append(selects, colIndex)
} else {
panic(NewParserError("Column %s not found in table %s", name, table.Name))
panic(NewParserError("column %s not found in table %s", name, table.Name))
}
} else {
// Complex expression
@ -780,7 +780,7 @@ func getInsertPKValues(pkColumnNumbers []int, rowList *Node, tableInfo *schema.T
values := make([]interface{}, rowList.Len())
for j := 0; j < rowList.Len(); j++ {
if columnNumber >= rowList.At(j).At(0).Len() { // NODE_LIST->'('->NODE_LIST
panic(NewParserError("Column count doesn't match value count"))
panic(NewParserError("column count doesn't match value count"))
}
node := rowList.At(j).At(0).At(columnNumber) // NODE_LIST->'('->NODE_LIST->Value
value := node.execAnalyzeValue()
@ -988,23 +988,6 @@ func (node *Node) GenerateSelectLimitQuery() *ParsedQuery {
return buf.ParsedQuery()
}
func (node *Node) GenerateDefaultQuery(tableInfo *schema.Table) *ParsedQuery {
buf := NewTrackedBuffer(nil)
limit := node.At(SELECT_LIMIT_OFFSET)
if limit.Len() == 0 {
limit.PushLimit()
defer limit.Pop()
}
fmt.Fprintf(buf, "select ")
writeColumnList(buf, tableInfo.Columns)
buf.Fprintf(" from %v%v%v%v",
node.At(SELECT_FROM_OFFSET),
node.At(SELECT_WHERE_OFFSET),
node.At(SELECT_ORDER_OFFSET),
limit)
return buf.ParsedQuery()
}
func (node *Node) GenerateEqualOuterQuery(tableInfo *schema.Table) *ParsedQuery {
buf := NewTrackedBuffer(nil)
fmt.Fprintf(buf, "select ")
@ -1142,9 +1125,9 @@ func asInterface(node *Node) interface{} {
case NUMBER:
n, err := sqltypes.BuildNumeric(string(node.Value))
if err != nil {
panic(NewParserError("Type mismatch: %s", err))
panic(NewParserError("type mismatch: %s", err))
}
return n
}
panic(NewParserError("Unexpected node %v", node))
panic(NewParserError("unexpected node %v", node))
}

Просмотреть файл

@ -34,7 +34,7 @@ var (
var schem map[string]*schema.Table
func initTables() {
func init() {
schem = make(map[string]*schema.Table)
a := schema.NewTable("a")
@ -56,7 +56,7 @@ func initTables() {
b.AddColumn("id", "int", SQLZERO, "")
bcolumns := []string{"eid", "id"}
b.Indexes = append(a.Indexes, &schema.Index{Name: "PRIMARY", Columns: []string{"eid", "id"}, Cardinality: []uint64{1, 1}, DataColumns: bcolumns})
b.PKColumns = append(a.PKColumns, 0, 1)
b.PKColumns = append(b.PKColumns, 0, 1)
b.CacheType = schema.CACHE_NONE
schem["b"] = b
@ -96,7 +96,6 @@ func tableGetter(name string) (*schema.Table, bool) {
}
func TestExec(t *testing.T) {
initTables()
for tcase := range iterateJSONFile("exec_cases.txt") {
plan, err := ExecParse(tcase.input, tableGetter, true)
var out string
@ -116,6 +115,115 @@ func TestExec(t *testing.T) {
}
}
func TestStreamExec(t *testing.T) {
for tcase := range iterateJSONFile("stream_cases.txt") {
plan, err := StreamExecParse(tcase.input, true)
var out string
if err != nil {
out = err.Error()
} else {
bout, err := json.Marshal(plan)
if err != nil {
panic(fmt.Sprintf("Error marshalling %v: %v", plan, err))
}
out = string(bout)
}
if out != tcase.output {
t.Error(fmt.Sprintf("Line:%v\n%s\n%s", tcase.lineno, tcase.output, out))
}
//fmt.Printf("%s\n%s\n\n", tcase.input, out)
}
}
var actionToString = map[int]string{
CREATE: "CREATE",
ALTER: "ALTER",
DROP: "DROP",
RENAME: "RENAME",
0: "NONE",
}
func TestDDL(t *testing.T) {
for tcase := range iterateFiles("sqlparser_test/ddl_cases.txt") {
plan := DDLParse(tcase.input)
expected := make(map[string]interface{})
err := json.Unmarshal([]byte(tcase.output), &expected)
if err != nil {
panic(fmt.Sprintf("Error marshalling %v", plan))
}
matchString(t, tcase.lineno, expected["Action"], actionToString[plan.Action])
matchString(t, tcase.lineno, expected["TableName"], plan.TableName)
matchString(t, tcase.lineno, expected["NewName"], plan.NewName)
}
}
func matchString(t *testing.T, line int, expected interface{}, actual string) {
if expected != nil {
if expected.(string) != actual {
t.Error(fmt.Sprintf("Line %d: expected: %v, received %s", line, expected, actual))
}
}
}
func TestParse(t *testing.T) {
for tcase := range iterateFiles("sqlparser_test/*.sql") {
if tcase.output == "" {
tcase.output = tcase.input
}
tree, err := Parse(tcase.input)
var out string
if err != nil {
out = err.Error()
} else {
out = tree.String()
}
if out != tcase.output {
t.Error(fmt.Sprintf("File:%s Line:%v\n%s\n%s", tcase.file, tcase.lineno, tcase.output, out))
}
}
}
func TestRouting(t *testing.T) {
tabletkeys := []key.KeyspaceId{
"\x00\x00\x00\x00\x00\x00\x00\x02",
"\x00\x00\x00\x00\x00\x00\x00\x04",
"\x00\x00\x00\x00\x00\x00\x00\x06",
"a",
"b",
"d",
}
bindVariables := make(map[string]interface{})
bindVariables["id0"] = 0
bindVariables["id2"] = 2
bindVariables["id3"] = 3
bindVariables["id4"] = 4
bindVariables["id6"] = 6
bindVariables["id8"] = 8
bindVariables["ids"] = []interface{}{1, 4}
bindVariables["a"] = "a"
bindVariables["b"] = "b"
bindVariables["c"] = "c"
bindVariables["d"] = "d"
bindVariables["e"] = "e"
for tcase := range iterateFiles("sqlparser_test/routing_cases.txt") {
if tcase.output == "" {
tcase.output = tcase.input
}
out, err := GetShardList(tcase.input, bindVariables, tabletkeys)
if err != nil {
if err.Error() != tcase.output {
t.Error(fmt.Sprintf("Line:%v\n%s\n%s", tcase.lineno, tcase.input, err))
}
continue
}
sort.Ints(out)
outstr := fmt.Sprintf("%v", out)
if outstr != tcase.output {
t.Error(fmt.Sprintf("Line:%v\n%s\n%s", tcase.lineno, tcase.output, outstr))
}
}
}
func TestAnonymizer(t *testing.T) {
sql := "select 'abcd', 20, 30.0, eid from a where 1=eid and name='3'"
plan, err := ExecParse(sql, tableGetter, true)
@ -159,94 +267,6 @@ func TestAnonymizer(t *testing.T) {
}
}
var actionToString = map[int]string{
CREATE: "CREATE",
ALTER: "ALTER",
DROP: "DROP",
RENAME: "RENAME",
0: "NONE",
}
func TestDDL(t *testing.T) {
for tcase := range iterateFiles("sqlparser_test/ddl_cases.txt") {
plan := DDLParse(tcase.input)
expected := make(map[string]interface{})
err := json.Unmarshal([]byte(tcase.output), &expected)
if err != nil {
panic(fmt.Sprintf("Error marshalling %v", plan))
}
matchString(t, tcase.lineno, expected["Action"], actionToString[plan.Action])
matchString(t, tcase.lineno, expected["TableName"], plan.TableName)
matchString(t, tcase.lineno, expected["NewName"], plan.NewName)
}
}
func matchString(t *testing.T, line int, expected interface{}, actual string) {
if expected != nil {
if expected.(string) != actual {
t.Error(fmt.Sprintf("Line %d: expected: %v, received %s", line, expected, actual))
}
}
}
func TestParse(t *testing.T) {
for tcase := range iterateFiles("sqlparser_test/*.sql") {
if tcase.output == "" {
tcase.output = tcase.input
}
tree, err := Parse(tcase.input)
if err != nil {
t.Error(fmt.Sprintf("File:%s Line:%v\n%s\n%s", tcase.file, tcase.lineno, tcase.input, err))
} else {
out := tree.String()
if out != tcase.output {
t.Error(fmt.Sprintf("File:%s Line:%v\n%s\n%s", tcase.file, tcase.lineno, tcase.output, out))
}
}
}
}
func TestRouting(t *testing.T) {
tabletkeys := []key.KeyspaceId{
"\x00\x00\x00\x00\x00\x00\x00\x02",
"\x00\x00\x00\x00\x00\x00\x00\x04",
"\x00\x00\x00\x00\x00\x00\x00\x06",
"a",
"b",
"d",
}
bindVariables := make(map[string]interface{})
bindVariables["id0"] = 0
bindVariables["id2"] = 2
bindVariables["id3"] = 3
bindVariables["id4"] = 4
bindVariables["id6"] = 6
bindVariables["id8"] = 8
bindVariables["ids"] = []interface{}{1, 4}
bindVariables["a"] = "a"
bindVariables["b"] = "b"
bindVariables["c"] = "c"
bindVariables["d"] = "d"
bindVariables["e"] = "e"
for tcase := range iterateFiles("sqlparser_test/routing_cases.txt") {
if tcase.output == "" {
tcase.output = tcase.input
}
out, err := GetShardList(tcase.input, bindVariables, tabletkeys)
if err != nil {
if err.Error() != tcase.output {
t.Error(fmt.Sprintf("Line:%v\n%s\n%s", tcase.lineno, tcase.input, err))
}
continue
}
sort.Ints(out)
outstr := fmt.Sprintf("%v", out)
if outstr != tcase.output {
t.Error(fmt.Sprintf("Line:%v\n%s\n%s", tcase.lineno, tcase.output, outstr))
}
}
}
type testCase struct {
file string
lineno int

Просмотреть файл

@ -36,10 +36,10 @@ func (pq *ParsedQuery) GenerateQuery(bindVariables map[string]interface{}, listV
if varName[0] >= '0' && varName[0] <= '9' {
index, err := strconv.Atoi(varName)
if err != nil {
return nil, NewParserError("Unexpected: %v for %s", err, varName)
return nil, NewParserError("unexpected: %v for %s", err, varName)
}
if index >= len(listVariables) {
return nil, NewParserError("Index out of range: %d", index)
return nil, NewParserError("index out of range: %d", index)
}
supplied = listVariables[index]
} else if varName[0] == '*' {
@ -48,7 +48,7 @@ func (pq *ParsedQuery) GenerateQuery(bindVariables map[string]interface{}, listV
var ok bool
supplied, ok = bindVariables[varName]
if !ok {
return nil, NewParserError("Missing bind var %s", varName)
return nil, NewParserError("missing bind var %s", varName)
}
}
if err := EncodeValue(buf, supplied); err != nil {

Просмотреть файл

@ -0,0 +1,152 @@
// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sqlparser
import (
"testing"
"github.com/youtube/vitess/go/sqltypes"
)
func TestParsedQuery(t *testing.T) {
tcases := []struct {
desc string
query string
bindVars map[string]interface{}
listVars []sqltypes.Value
output string
}{
{
"no subs",
"select * from a where id = 2",
map[string]interface{}{
"id": 1,
},
nil,
"select * from a where id = 2",
}, {
"simple bindvar sub",
"select * from a where id1 = :id1 and id2 = :id2",
map[string]interface{}{
"id1": 1,
"id2": nil,
},
nil,
"select * from a where id1 = 1 and id2 = null",
}, {
"missing bind var",
"select * from a where id1 = :id1 and id2 = :id2",
map[string]interface{}{
"id1": 1,
},
nil,
"missing bind var id2",
}, {
"unencodable bind var",
"select * from a where id1 = :id",
map[string]interface{}{
"id": make([]int, 1),
},
nil,
"unsupported bind variable type []int: [0]",
}, {
"list var sub",
"select * from a where id = :0 and name = :1",
nil,
[]sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
},
"select * from a where id = 1 and name = 'aa'",
}, {
"list inside bind vars",
"select * from a where id in (:vals)",
map[string]interface{}{
"vals": []sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
},
},
nil,
"select * from a where id in (1, 'aa')",
}, {
"two lists inside bind vars",
"select * from a where id in (:vals)",
map[string]interface{}{
"vals": [][]sqltypes.Value{
[]sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
},
[]sqltypes.Value{
sqltypes.Value{},
sqltypes.MakeString([]byte("bb")),
},
},
},
nil,
"select * from a where id in ((1, 'aa'), (null, 'bb'))",
}, {
"illega list var name",
"select * from a where id = :0a",
nil,
[]sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
},
`unexpected: strconv.ParseInt: parsing "0a": invalid syntax for 0a`,
}, {
"out of range list var index",
"select * from a where id = :10",
nil,
[]sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
},
"index out of range: 10",
},
}
for _, tcase := range tcases {
tree, err := Parse(tcase.query)
if err != nil {
t.Errorf("parse failed for %s: %v", tcase.desc, err)
continue
}
buf := NewTrackedBuffer(nil)
buf.Fprintf("%v", tree)
pq := buf.ParsedQuery()
bytes, err := pq.GenerateQuery(tcase.bindVars, tcase.listVars)
var got string
if err != nil {
got = err.Error()
} else {
got = string(bytes)
}
if got != tcase.output {
t.Errorf("for test case: %s, got: '%s', want '%s'", tcase.desc, got, tcase.output)
}
}
}
func TestStarParam(t *testing.T) {
buf := NewTrackedBuffer(nil)
buf.Fprintf("select * from a where id in (%a)", "*")
pq := buf.ParsedQuery()
listvars := []sqltypes.Value{
sqltypes.MakeNumeric([]byte("1")),
sqltypes.MakeString([]byte("aa")),
}
bytes, err := pq.GenerateQuery(nil, listvars)
if err != nil {
t.Errorf("generate failed: %v", err)
return
}
got := string(bytes)
want := "select * from a where id in (1, 'aa')"
if got != want {
t.Errorf("got %s, want %s", got, want)
}
}

Просмотреть файл

@ -1,9 +1,9 @@
//line sql.y:33
//line sql.y:6
package sqlparser
import __yyfmt__ "fmt"
//line sql.y:33
//line sql.y:6
import "bytes"
func SetParseTree(yylex interface{}, root *Node) {
@ -65,7 +65,7 @@ const (
DELETE_LIMIT_OFFSET
)
//line sql.y:98
//line sql.y:71
type yySymType struct {
yys int
node *Node
@ -802,7 +802,7 @@ yydefault:
switch yynt {
case 1:
//line sql.y:153
//line sql.y:126
{
SetParseTree(yylex, yyS[yypt-0].node)
}
@ -825,7 +825,7 @@ yydefault:
case 10:
yyVAL.node = yyS[yypt-0].node
case 11:
//line sql.y:170
//line sql.y:143
{
yyVAL.node = yyS[yypt-11].node
yyVAL.node.Push(yyS[yypt-10].node) // 0: comment_opt
@ -840,12 +840,12 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node) // 9: lock_opt
}
case 12:
//line sql.y:184
//line sql.y:157
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 13:
//line sql.y:190
//line sql.y:163
{
yyVAL.node = yyS[yypt-6].node
yyVAL.node.Push(yyS[yypt-5].node) // 0: comment_opt
@ -855,7 +855,7 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node) // 4: on_dup_opt
}
case 14:
//line sql.y:201
//line sql.y:174
{
yyVAL.node = yyS[yypt-7].node
yyVAL.node.Push(yyS[yypt-6].node) // 0: comment_opt
@ -866,7 +866,7 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node) // 5: limit_opt
}
case 15:
//line sql.y:213
//line sql.y:186
{
yyVAL.node = yyS[yypt-6].node
yyVAL.node.Push(yyS[yypt-5].node) // 0: comment_opt
@ -876,93 +876,93 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node) // 4: limit_opt
}
case 16:
//line sql.y:224
//line sql.y:197
{
yyVAL.node = yyS[yypt-2].node
yyVAL.node.Push(yyS[yypt-1].node)
yyVAL.node.Push(yyS[yypt-0].node)
}
case 17:
//line sql.y:232
//line sql.y:205
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 18:
//line sql.y:236
//line sql.y:209
{
// Change this to an alter statement
yyVAL.node = NewSimpleParseNode(ALTER, "alter")
yyVAL.node.Push(yyS[yypt-1].node)
}
case 19:
//line sql.y:242
//line sql.y:215
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 20:
//line sql.y:248
//line sql.y:221
{
yyVAL.node.Push(yyS[yypt-2].node)
}
case 21:
//line sql.y:252
//line sql.y:225
{
// Change this to a rename statement
yyVAL.node = NewSimpleParseNode(RENAME, "rename")
yyVAL.node.PushTwo(yyS[yypt-3].node, yyS[yypt-0].node)
}
case 22:
//line sql.y:258
//line sql.y:231
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 23:
//line sql.y:264
//line sql.y:237
{
yyVAL.node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 24:
//line sql.y:270
//line sql.y:243
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 25:
//line sql.y:274
//line sql.y:247
{
// Change this to an alter statement
yyVAL.node = NewSimpleParseNode(ALTER, "alter")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 26:
//line sql.y:280
//line sql.y:253
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 27:
//line sql.y:285
//line sql.y:258
{
SetAllowComments(yylex, true)
}
case 28:
//line sql.y:289
//line sql.y:262
{
yyVAL.node = yyS[yypt-0].node
SetAllowComments(yylex, false)
}
case 29:
//line sql.y:295
//line sql.y:268
{
yyVAL.node = NewSimpleParseNode(COMMENT_LIST, "")
}
case 30:
//line sql.y:299
//line sql.y:272
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 31:
yyVAL.node = yyS[yypt-0].node
case 32:
//line sql.y:306
//line sql.y:279
{
yyVAL.node = NewSimpleParseNode(UNION_ALL, "union all")
}
@ -973,40 +973,40 @@ yydefault:
case 35:
yyVAL.node = yyS[yypt-0].node
case 36:
//line sql.y:314
//line sql.y:287
{
yyVAL.node = NewSimpleParseNode(NO_DISTINCT, "")
}
case 37:
//line sql.y:318
//line sql.y:291
{
yyVAL.node = NewSimpleParseNode(DISTINCT, "distinct")
}
case 38:
//line sql.y:324
//line sql.y:297
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 39:
//line sql.y:329
//line sql.y:302
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 40:
//line sql.y:335
//line sql.y:308
{
yyVAL.node = NewSimpleParseNode(SELECT_STAR, "*")
}
case 41:
yyVAL.node = yyS[yypt-0].node
case 42:
//line sql.y:340
//line sql.y:313
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 43:
//line sql.y:344
//line sql.y:317
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, NewSimpleParseNode(SELECT_STAR, "*"))
}
@ -1015,30 +1015,30 @@ yydefault:
case 45:
yyVAL.node = yyS[yypt-0].node
case 46:
//line sql.y:353
//line sql.y:326
{
yyVAL.node = NewSimpleParseNode(AS, "as")
}
case 47:
yyVAL.node = yyS[yypt-0].node
case 48:
//line sql.y:360
//line sql.y:333
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 49:
//line sql.y:365
//line sql.y:338
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 50:
//line sql.y:369
//line sql.y:342
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 51:
//line sql.y:375
//line sql.y:348
{
yyVAL.node = NewSimpleParseNode(TABLE_EXPR, "")
yyVAL.node.Push(yyS[yypt-1].node)
@ -1046,7 +1046,7 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node)
}
case 52:
//line sql.y:382
//line sql.y:355
{
yyVAL.node = NewSimpleParseNode(TABLE_EXPR, "")
yyVAL.node.Push(yyS[yypt-3].node)
@ -1054,12 +1054,12 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node)
}
case 53:
//line sql.y:389
//line sql.y:362
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 54:
//line sql.y:393
//line sql.y:366
{
yyVAL.node = yyS[yypt-3].node
yyVAL.node.Push(yyS[yypt-4].node)
@ -1071,133 +1071,133 @@ yydefault:
case 56:
yyVAL.node = yyS[yypt-0].node
case 57:
//line sql.y:404
//line sql.y:377
{
yyVAL.node = NewSimpleParseNode(LEFT, "left join")
}
case 58:
//line sql.y:408
//line sql.y:381
{
yyVAL.node = NewSimpleParseNode(LEFT, "left join")
}
case 59:
//line sql.y:412
//line sql.y:385
{
yyVAL.node = NewSimpleParseNode(RIGHT, "right join")
}
case 60:
//line sql.y:416
//line sql.y:389
{
yyVAL.node = NewSimpleParseNode(RIGHT, "right join")
}
case 61:
//line sql.y:420
//line sql.y:393
{
yyVAL.node = yyS[yypt-0].node
}
case 62:
//line sql.y:424
//line sql.y:397
{
yyVAL.node = NewSimpleParseNode(CROSS, "cross join")
}
case 63:
//line sql.y:428
//line sql.y:401
{
yyVAL.node = NewSimpleParseNode(NATURAL, "natural join")
}
case 64:
yyVAL.node = yyS[yypt-0].node
case 65:
//line sql.y:435
//line sql.y:408
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 66:
//line sql.y:439
//line sql.y:412
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 67:
yyVAL.node = yyS[yypt-0].node
case 68:
//line sql.y:446
//line sql.y:419
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 69:
//line sql.y:451
//line sql.y:424
{
yyVAL.node = NewSimpleParseNode(USE, "use")
}
case 70:
//line sql.y:455
//line sql.y:428
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 71:
//line sql.y:459
//line sql.y:432
{
yyVAL.node.Push(yyS[yypt-1].node)
}
case 72:
//line sql.y:464
//line sql.y:437
{
yyVAL.node = NewSimpleParseNode(WHERE, "where")
}
case 73:
//line sql.y:468
//line sql.y:441
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 74:
yyVAL.node = yyS[yypt-0].node
case 75:
//line sql.y:475
//line sql.y:448
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 76:
//line sql.y:479
//line sql.y:452
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 77:
//line sql.y:483
//line sql.y:456
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 78:
//line sql.y:487
//line sql.y:460
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 79:
//line sql.y:493
//line sql.y:466
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 80:
//line sql.y:497
//line sql.y:470
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 81:
//line sql.y:501
//line sql.y:474
{
yyVAL.node = NewSimpleParseNode(NOT_IN, "not in").PushTwo(yyS[yypt-3].node, yyS[yypt-0].node)
}
case 82:
//line sql.y:505
//line sql.y:478
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 83:
//line sql.y:509
//line sql.y:482
{
yyVAL.node = NewSimpleParseNode(NOT_LIKE, "not like").PushTwo(yyS[yypt-3].node, yyS[yypt-0].node)
}
case 84:
//line sql.y:513
//line sql.y:486
{
yyVAL.node = yyS[yypt-3].node
yyVAL.node.Push(yyS[yypt-4].node)
@ -1205,7 +1205,7 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node)
}
case 85:
//line sql.y:520
//line sql.y:493
{
yyVAL.node = NewSimpleParseNode(NOT_BETWEEN, "not between")
yyVAL.node.Push(yyS[yypt-5].node)
@ -1213,17 +1213,17 @@ yydefault:
yyVAL.node.Push(yyS[yypt-0].node)
}
case 86:
//line sql.y:527
//line sql.y:500
{
yyVAL.node = NewSimpleParseNode(IS_NULL, "is null").Push(yyS[yypt-2].node)
}
case 87:
//line sql.y:531
//line sql.y:504
{
yyVAL.node = NewSimpleParseNode(IS_NOT_NULL, "is not null").Push(yyS[yypt-3].node)
}
case 88:
//line sql.y:535
//line sql.y:508
{
yyVAL.node = yyS[yypt-3].node.Push(yyS[yypt-1].node)
}
@ -1242,41 +1242,41 @@ yydefault:
case 95:
yyVAL.node = yyS[yypt-0].node
case 96:
//line sql.y:550
//line sql.y:523
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 97:
yyVAL.node = yyS[yypt-0].node
case 98:
//line sql.y:557
//line sql.y:530
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 99:
//line sql.y:562
//line sql.y:535
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 100:
//line sql.y:568
//line sql.y:541
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 101:
//line sql.y:572
//line sql.y:545
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 102:
//line sql.y:578
//line sql.y:551
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 103:
//line sql.y:583
//line sql.y:556
{
yyVAL.node.Push(yyS[yypt-0].node)
}
@ -1285,12 +1285,12 @@ yydefault:
case 105:
yyVAL.node = yyS[yypt-0].node
case 106:
//line sql.y:591
//line sql.y:564
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-1].node)
}
case 107:
//line sql.y:595
//line sql.y:568
{
if yyS[yypt-1].node.Len() == 1 {
yyS[yypt-1].node = yyS[yypt-1].node.At(0)
@ -1303,47 +1303,47 @@ yydefault:
}
}
case 108:
//line sql.y:607
//line sql.y:580
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 109:
//line sql.y:611
//line sql.y:584
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 110:
//line sql.y:615
//line sql.y:588
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 111:
//line sql.y:619
//line sql.y:592
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 112:
//line sql.y:623
//line sql.y:596
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 113:
//line sql.y:627
//line sql.y:600
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 114:
//line sql.y:631
//line sql.y:604
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 115:
//line sql.y:635
//line sql.y:608
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 116:
//line sql.y:639
//line sql.y:612
{
if yyS[yypt-0].node.Type == NUMBER { // Simplify trivial unary expressions
switch yyS[yypt-1].node.Type {
@ -1360,26 +1360,26 @@ yydefault:
}
}
case 117:
//line sql.y:655
//line sql.y:628
{
yyS[yypt-2].node.Type = FUNCTION
yyVAL.node = yyS[yypt-2].node.Push(NewSimpleParseNode(NODE_LIST, "node_list"))
}
case 118:
//line sql.y:660
//line sql.y:633
{
yyS[yypt-3].node.Type = FUNCTION
yyVAL.node = yyS[yypt-3].node.Push(yyS[yypt-1].node)
}
case 119:
//line sql.y:665
//line sql.y:638
{
yyS[yypt-4].node.Type = FUNCTION
yyVAL.node = yyS[yypt-4].node.Push(yyS[yypt-2].node)
yyVAL.node = yyS[yypt-4].node.Push(yyS[yypt-1].node)
}
case 120:
//line sql.y:671
//line sql.y:644
{
yyS[yypt-3].node.Type = FUNCTION
yyVAL.node = yyS[yypt-3].node.Push(yyS[yypt-1].node)
@ -1391,53 +1391,53 @@ yydefault:
case 123:
yyVAL.node = yyS[yypt-0].node
case 124:
//line sql.y:683
//line sql.y:656
{
yyVAL.node = NewSimpleParseNode(UPLUS, "+")
}
case 125:
//line sql.y:687
//line sql.y:660
{
yyVAL.node = NewSimpleParseNode(UMINUS, "-")
}
case 126:
yyVAL.node = yyS[yypt-0].node
case 127:
//line sql.y:694
//line sql.y:667
{
yyVAL.node = NewSimpleParseNode(CASE_WHEN, "case")
yyVAL.node.Push(yyS[yypt-1].node)
}
case 128:
//line sql.y:699
//line sql.y:672
{
yyVAL.node.PushTwo(yyS[yypt-2].node, yyS[yypt-1].node)
}
case 129:
//line sql.y:705
//line sql.y:678
{
yyVAL.node = NewSimpleParseNode(WHEN_LIST, "when_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 130:
//line sql.y:710
//line sql.y:683
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 131:
//line sql.y:716
//line sql.y:689
{
yyVAL.node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 132:
//line sql.y:720
//line sql.y:693
{
yyVAL.node.Push(yyS[yypt-0].node)
}
case 133:
yyVAL.node = yyS[yypt-0].node
case 134:
//line sql.y:727
//line sql.y:700
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
@ -1450,53 +1450,53 @@ yydefault:
case 138:
yyVAL.node = yyS[yypt-0].node
case 139:
//line sql.y:738
//line sql.y:711
{
yyVAL.node = NewSimpleParseNode(GROUP, "group")
}
case 140:
//line sql.y:742
//line sql.y:715
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 141:
//line sql.y:747
//line sql.y:720
{
yyVAL.node = NewSimpleParseNode(HAVING, "having")
}
case 142:
//line sql.y:751
//line sql.y:724
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 143:
//line sql.y:756
//line sql.y:729
{
yyVAL.node = NewSimpleParseNode(ORDER, "order")
}
case 144:
//line sql.y:760
//line sql.y:733
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 145:
//line sql.y:766
//line sql.y:739
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 146:
//line sql.y:771
//line sql.y:744
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 147:
//line sql.y:777
//line sql.y:750
{
yyVAL.node = yyS[yypt-0].node.Push(yyS[yypt-1].node)
}
case 148:
//line sql.y:782
//line sql.y:755
{
yyVAL.node = NewSimpleParseNode(ASC, "asc")
}
@ -1505,32 +1505,32 @@ yydefault:
case 150:
yyVAL.node = yyS[yypt-0].node
case 151:
//line sql.y:789
//line sql.y:762
{
yyVAL.node = NewSimpleParseNode(LIMIT, "limit")
}
case 152:
//line sql.y:793
//line sql.y:766
{
yyVAL.node = yyS[yypt-1].node.Push(yyS[yypt-0].node)
}
case 153:
//line sql.y:797
//line sql.y:770
{
yyVAL.node = yyS[yypt-3].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 154:
//line sql.y:802
//line sql.y:775
{
yyVAL.node = NewSimpleParseNode(NO_LOCK, "")
}
case 155:
//line sql.y:806
//line sql.y:779
{
yyVAL.node = NewSimpleParseNode(FOR_UPDATE, " for update")
}
case 156:
//line sql.y:810
//line sql.y:783
{
if !bytes.Equal(yyS[yypt-1].node.Value, SHARE) {
yylex.Error("expecting share")
@ -1543,79 +1543,79 @@ yydefault:
yyVAL.node = NewSimpleParseNode(LOCK_IN_SHARE_MODE, " lock in share mode")
}
case 157:
//line sql.y:823
//line sql.y:796
{
yyVAL.node = NewSimpleParseNode(COLUMN_LIST, "")
}
case 158:
//line sql.y:827
//line sql.y:800
{
yyVAL.node = yyS[yypt-1].node
}
case 159:
//line sql.y:833
//line sql.y:806
{
yyVAL.node = NewSimpleParseNode(COLUMN_LIST, "")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 160:
//line sql.y:838
//line sql.y:811
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 161:
//line sql.y:844
//line sql.y:817
{
yyVAL.node = NewSimpleParseNode(INDEX_LIST, "")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 162:
//line sql.y:849
//line sql.y:822
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 163:
//line sql.y:854
//line sql.y:827
{
yyVAL.node = NewSimpleParseNode(DUPLICATE, "duplicate")
}
case 164:
//line sql.y:858
//line sql.y:831
{
yyVAL.node = yyS[yypt-3].node.Push(yyS[yypt-0].node)
}
case 165:
//line sql.y:864
//line sql.y:837
{
yyVAL.node = NewSimpleParseNode(NODE_LIST, "node_list")
yyVAL.node.Push(yyS[yypt-0].node)
}
case 166:
//line sql.y:869
//line sql.y:842
{
yyVAL.node = yyS[yypt-2].node.Push(yyS[yypt-0].node)
}
case 167:
//line sql.y:875
//line sql.y:848
{
yyVAL.node = yyS[yypt-1].node.PushTwo(yyS[yypt-2].node, yyS[yypt-0].node)
}
case 168:
//line sql.y:880
//line sql.y:853
{
yyVAL.node = nil
}
case 169:
yyVAL.node = yyS[yypt-0].node
case 170:
//line sql.y:884
//line sql.y:857
{
yyVAL.node = nil
}
case 171:
yyVAL.node = yyS[yypt-0].node
case 172:
//line sql.y:888
//line sql.y:861
{
yyVAL.node = nil
}
@ -1632,33 +1632,33 @@ yydefault:
case 178:
yyVAL.node = yyS[yypt-0].node
case 179:
//line sql.y:899
//line sql.y:872
{
yyVAL.node = nil
}
case 180:
yyVAL.node = yyS[yypt-0].node
case 181:
//line sql.y:903
//line sql.y:876
{
yyVAL.node = nil
}
case 182:
yyVAL.node = yyS[yypt-0].node
case 183:
//line sql.y:907
//line sql.y:880
{
yyVAL.node = nil
}
case 184:
yyVAL.node = yyS[yypt-0].node
case 185:
//line sql.y:912
//line sql.y:885
{
yyVAL.node.LowerCase()
}
case 186:
//line sql.y:917
//line sql.y:890
{
ForceEOF(yylex)
}

Просмотреть файл

@ -1,33 +1,6 @@
/*
Copyright 2012, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
%{
package sqlparser

Просмотреть файл

@ -208,7 +208,7 @@ func (tkn *Tokenizer) Scan() (parseNode *Node) {
tkn.Next()
return NewSimpleParseNode(NE, "!=")
} else {
return NewSimpleParseNode(LEX_ERROR, "Unexpected character '!'")
return NewSimpleParseNode(LEX_ERROR, "unexpected character '!'")
}
case '\'', '"':
return tkn.scanString(ch)
@ -217,7 +217,7 @@ func (tkn *Tokenizer) Scan() (parseNode *Node) {
tok.Type = ID
return tok
default:
return NewSimpleParseNode(LEX_ERROR, fmt.Sprintf("Unexpected character '%c'", ch))
return NewSimpleParseNode(LEX_ERROR, fmt.Sprintf("unexpected character '%c'", ch))
}
}
}
@ -264,6 +264,7 @@ func (tkn *Tokenizer) scanMantissa(base int, buffer *bytes.Buffer) {
func (tkn *Tokenizer) scanNumber(seenDecimalPoint bool) *Node {
buffer := bytes.NewBuffer(make([]byte, 0, 8))
if seenDecimalPoint {
buffer.WriteByte('.')
tkn.scanMantissa(10, buffer)
goto exponent
}
@ -380,7 +381,7 @@ func (tkn *Tokenizer) scanCommentType2() *Node {
func (tkn *Tokenizer) ConsumeNext(buffer *bytes.Buffer) {
// Never consume an EOF
if tkn.lastChar == EOFCHAR {
panic(NewParserError("Unexpected EOF"))
panic(NewParserError("unexpected EOF"))
}
buffer.WriteByte(byte(tkn.lastChar))
tkn.Next()

Просмотреть файл

@ -121,11 +121,11 @@ func validateValue(col *schema.TableColumn, value sqltypes.Value) {
switch col.Category {
case schema.CAT_NUMBER:
if !value.IsNumeric() {
panic(NewTabletError(FAIL, "Type mismatch, expecting numeric type for %v", value))
panic(NewTabletError(FAIL, "type mismatch, expecting numeric type for %v", value))
}
case schema.CAT_VARBINARY:
if !value.IsString() {
panic(NewTabletError(FAIL, "Type mismatch, expecting string type for %v", value))
panic(NewTabletError(FAIL, "type mismatch, expecting string type for %v", value))
}
}
}

Просмотреть файл

@ -32,7 +32,7 @@ class TestCache(framework.TestCase):
try:
self.env.execute("select bid, eid from vtocc_cached2 where eid = 1 and bid = 1")
except dbexceptions.DatabaseError as e:
self.assertContains(str(e), "error: Type")
self.assertContains(str(e), "error: type mismatch")
else:
self.fail("Did not receive exception")
@ -209,7 +209,7 @@ class TestCache(framework.TestCase):
try:
self.env.execute(query, bindvars)
except dbexceptions.DatabaseError as e:
self.assertContains(str(e), "error: Type mismatch")
self.assertContains(str(e), "error: type mismatch")
else:
self.fail("Did not receive exception")

Просмотреть файл

@ -457,7 +457,7 @@ class TestNocache(framework.TestCase):
self.assertTrue((tendTimesNs - tstartTimesNs) > 0)
def _verify_mismatch(self, query, bindvars=None):
self._verify_error(query, bindvars, "error: Type mismatch")
self._verify_error(query, bindvars, "error: type mismatch")
def _verify_error(self, query, bindvars, err):
self.env.conn.begin()