Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit 3fd2047

Browse files
authored
Fix validation rule to detect tuples in projections or groupbys (#672)
Fix validation rule to detect tuples in projections or groupbys
2 parents 634630f + b9b4912 commit 3fd2047

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ We support and actively test against certain third-party clients to ensure compa
7676
|`DAYOFWEEK(date)`|Returns the day of the week of the given date.|
7777
|`DAYOFYEAR(date)`|Returns the day of the year of the given date.|
7878
|`FLOOR(number)`|Return the largest integer value that is less than or equal to `number`.|
79+
|`FROM_BASE64(str)`|Decodes the base64-encoded string str.|
7980
|`HOUR(date)`|Returns the hours of the given date.|
8081
|`IFNULL(expr1, expr2)`|If expr1 is not NULL, IFNULL() returns expr1; otherwise it returns expr2.|
8182
|`IS_BINARY(blob)`|Returns whether a BLOB is a binary file or not.|
@@ -110,7 +111,6 @@ We support and actively test against certain third-party clients to ensure compa
110111
|`SUBSTRING(str, pos, [len])`|Return a substring from the provided string starting at `pos` with a length of `len` characters. If no `len` is provided, all characters from `pos` until the end will be taken.|
111112
|`SUM(expr)`|Returns the sum of expr in all rows.|
112113
|`TO_BASE64(str)`|Encodes the string str in base64 format.|
113-
|`FROM_BASE64(str)`|Decodes the base64-encoded string str.|
114114
|`TRIM(str)`|Returns the string str with all spaces removed.|
115115
|`UPPER(str)`|Returns the string str with all characters in upper case.|
116116
|`WEEKDAY(date)`|Returns the weekday of the given date.|

sql/analyzer/optimization_rules.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package analyzer
22

33
import (
4-
errors "gopkg.in/src-d/go-errors.v1"
4+
"gopkg.in/src-d/go-errors.v1"
55
"gopkg.in/src-d/go-mysql-server.v0/sql"
66
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
77
"gopkg.in/src-d/go-mysql-server.v0/sql/plan"

sql/analyzer/validation_rules.go

+19-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package analyzer
33
import (
44
"strings"
55

6-
errors "gopkg.in/src-d/go-errors.v1"
6+
"gopkg.in/src-d/go-errors.v1"
77
"gopkg.in/src-d/go-mysql-server.v0/sql"
88
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
99
"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function"
@@ -195,27 +195,36 @@ func validateSchema(t *plan.ResolvedTable) error {
195195
return nil
196196
}
197197

198-
func validateProjectTuples(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
199-
span, _ := ctx.Span("validate_project_tuples")
200-
defer span.Finish()
198+
func findProjectTuples(n sql.Node) (sql.Node, error) {
199+
if n == nil {
200+
return n, nil
201+
}
201202

202203
switch n := n.(type) {
203-
case *plan.Project:
204-
for i, e := range n.Projections {
204+
case *plan.Project, *plan.GroupBy:
205+
for i, e := range n.(sql.Expressioner).Expressions() {
205206
if sql.IsTuple(e.Type()) {
206207
return nil, ErrProjectTuple.New(i+1, sql.NumColumns(e.Type()))
207208
}
208209
}
209-
case *plan.GroupBy:
210-
for i, e := range n.Aggregate {
211-
if sql.IsTuple(e.Type()) {
212-
return nil, ErrProjectTuple.New(i+1, sql.NumColumns(e.Type()))
210+
default:
211+
for _, ch := range n.Children() {
212+
_, err := findProjectTuples(ch)
213+
if err != nil {
214+
return nil, err
213215
}
214216
}
215217
}
218+
216219
return n, nil
217220
}
218221

222+
func validateProjectTuples(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
223+
span, _ := ctx.Span("validate_project_tuples")
224+
defer span.Finish()
225+
return findProjectTuples(n)
226+
}
227+
219228
func validateCaseResultTypes(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
220229
span, ctx := ctx.Span("validate_case_result_types")
221230
defer span.Finish()

sql/analyzer/validation_rules_test.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,38 @@ func TestValidateProjectTuples(t *testing.T) {
235235
plan.NewProject([]sql.Expression{
236236
expression.NewTuple(
237237
expression.NewLiteral(1, sql.Int64),
238-
expression.NewLiteral(1, sql.Int64),
238+
expression.NewLiteral(2, sql.Int64),
239239
),
240240
}, nil),
241241
false,
242242
},
243+
{
244+
"distinct with a 2 elem tuple inside the project",
245+
plan.NewDistinct(
246+
plan.NewProject([]sql.Expression{
247+
expression.NewTuple(
248+
expression.NewLiteral(1, sql.Int64),
249+
expression.NewLiteral(2, sql.Int64),
250+
),
251+
}, nil)),
252+
false,
253+
},
254+
{
255+
"alias with a tuple",
256+
plan.NewProject(
257+
[]sql.Expression{
258+
expression.NewAlias(
259+
expression.NewTuple(
260+
expression.NewLiteral(1, sql.Int64),
261+
expression.NewLiteral(2, sql.Int64),
262+
),
263+
"foo",
264+
),
265+
},
266+
plan.NewUnresolvedTable("dual", ""),
267+
),
268+
false,
269+
},
243270
{
244271
"groupby with no tuple",
245272
plan.NewGroupBy([]sql.Expression{

0 commit comments

Comments
 (0)