be more strict about identifier printing
When stringifying a query, we would print the identifier bare most of the time. This caused issues when stringifying an identifier that contained elements of syntax. For example, querying for the value "in-bytes" would fail because the mapper would serialize it to in-bytes and would parse it as an expression. Same problem occured when using keywords as identifier names, such as select or in. Fixes #3547pull/3560/head
parent
affd0b1ca2
commit
fc4246d7f5
|
@ -1992,26 +1992,6 @@ func (f *Field) Name() string {
|
|||
func (f *Field) String() string {
|
||||
str := f.Expr.String()
|
||||
|
||||
switch f.Expr.(type) {
|
||||
case *VarRef:
|
||||
quoted := false
|
||||
// Escape any double-quotes in the field
|
||||
if strings.Contains(str, `"`) {
|
||||
str = strings.Replace(str, `"`, `\"`, -1)
|
||||
quoted = true
|
||||
}
|
||||
|
||||
// Escape any single-quotes in the field
|
||||
if strings.Contains(str, `'`) {
|
||||
quoted = true
|
||||
}
|
||||
|
||||
// Double-quote field names with spaces or that were previously escaped
|
||||
if strings.Contains(str, " ") || quoted {
|
||||
str = fmt.Sprintf("\"%s\"", str)
|
||||
}
|
||||
}
|
||||
|
||||
if f.Alias == "" {
|
||||
return str
|
||||
}
|
||||
|
@ -2132,7 +2112,9 @@ type VarRef struct {
|
|||
}
|
||||
|
||||
// String returns a string representation of the variable reference.
|
||||
func (r *VarRef) String() string { return r.Val }
|
||||
func (r *VarRef) String() string {
|
||||
return QuoteIdent(r.Val)
|
||||
}
|
||||
|
||||
// Call represents a function call.
|
||||
type Call struct {
|
||||
|
|
|
@ -44,35 +44,35 @@ func TestSelectStatement_Substatement(t *testing.T) {
|
|||
{
|
||||
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb`,
|
||||
expr: &influxql.VarRef{Val: "aa.value"},
|
||||
sub: `SELECT aa.value FROM aa`,
|
||||
sub: `SELECT "aa.value" FROM aa`,
|
||||
},
|
||||
|
||||
// 2. Simple merge
|
||||
{
|
||||
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb`,
|
||||
expr: &influxql.VarRef{Val: "bb.value"},
|
||||
sub: `SELECT bb.value FROM bb`,
|
||||
sub: `SELECT "bb.value" FROM bb`,
|
||||
},
|
||||
|
||||
// 3. Join with condition
|
||||
{
|
||||
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE aa.host = 'servera' AND bb.host = 'serverb'`,
|
||||
expr: &influxql.VarRef{Val: "bb.value"},
|
||||
sub: `SELECT bb.value FROM bb WHERE bb.host = 'serverb'`,
|
||||
sub: `SELECT "bb.value" FROM bb WHERE "bb.host" = 'serverb'`,
|
||||
},
|
||||
|
||||
// 4. Join with complex condition
|
||||
{
|
||||
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE aa.host = 'servera' AND (bb.host = 'serverb' OR bb.host = 'serverc') AND 1 = 2`,
|
||||
expr: &influxql.VarRef{Val: "bb.value"},
|
||||
sub: `SELECT bb.value FROM bb WHERE (bb.host = 'serverb' OR bb.host = 'serverc') AND 1.000 = 2.000`,
|
||||
sub: `SELECT "bb.value" FROM bb WHERE ("bb.host" = 'serverb' OR "bb.host" = 'serverc') AND 1.000 = 2.000`,
|
||||
},
|
||||
|
||||
// 5. 4 with different condition order
|
||||
{
|
||||
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE ((bb.host = 'serverb' OR bb.host = 'serverc') AND aa.host = 'servera') AND 1 = 2`,
|
||||
expr: &influxql.VarRef{Val: "bb.value"},
|
||||
sub: `SELECT bb.value FROM bb WHERE ((bb.host = 'serverb' OR bb.host = 'serverc')) AND 1.000 = 2.000`,
|
||||
sub: `SELECT "bb.value" FROM bb WHERE (("bb.host" = 'serverb' OR "bb.host" = 'serverc')) AND 1.000 = 2.000`,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -2217,6 +2217,11 @@ func QuoteIdent(segments ...string) string {
|
|||
|
||||
// IdentNeedsQuotes returns true if the ident string given would require quotes.
|
||||
func IdentNeedsQuotes(ident string) bool {
|
||||
// check if this identifier is a keyword
|
||||
tok := Lookup(ident)
|
||||
if tok != IDENT {
|
||||
return true
|
||||
}
|
||||
for i, r := range ident {
|
||||
if i == 0 && !isIdentFirstChar(r) {
|
||||
return true
|
||||
|
|
|
@ -1664,6 +1664,8 @@ func TestQuoteIdent(t *testing.T) {
|
|||
s string
|
||||
}{
|
||||
{[]string{``}, ``},
|
||||
{[]string{`select`}, `"select"`},
|
||||
{[]string{`in-bytes`}, `"in-bytes"`},
|
||||
{[]string{`foo`, `bar`}, `"foo".bar`},
|
||||
{[]string{`foo`, ``, `bar`}, `"foo"..bar`},
|
||||
{[]string{`foo bar`, `baz`}, `"foo bar".baz`},
|
||||
|
|
Loading…
Reference in New Issue