Skip to content

Commit 39f8360

Browse files
authored
Merge pull request #60 from dolthub/zachmu/exprs
Implemented support for various expressions needed by sqllogictest
2 parents 06567ef + 7b284d5 commit 39f8360

File tree

6 files changed

+176
-13
lines changed

6 files changed

+176
-13
lines changed

postgres/messages/row_description.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,10 @@ func VitessFieldToDataTypeObjectID(field *query.Field) (int32, error) {
174174
return 1114, nil
175175
case query.Type_DATE:
176176
return 1082, nil
177+
case query.Type_NULL_TYPE:
178+
return 25, nil // NULL is treated as TEXT on the wire
177179
default:
178-
return 0, fmt.Errorf("unsupported type returned from engine")
180+
return 0, fmt.Errorf("unsupported type returned from engine: %s", field.Type)
179181
}
180182
}
181183

@@ -210,8 +212,10 @@ func VitessFieldToDataTypeSize(field *query.Field) (int16, error) {
210212
return 8, nil
211213
case query.Type_DATE:
212214
return 4, nil
215+
case query.Type_NULL_TYPE:
216+
return -1, nil // NULL is treated as TEXT on the wire
213217
default:
214-
return 0, fmt.Errorf("unsupported type returned from engine")
218+
return 0, fmt.Errorf("unsupported type returned from engine: %s", field.Type)
215219
}
216220
}
217221

@@ -255,7 +259,9 @@ func VitessFieldToDataTypeModifier(field *query.Field) (int32, error) {
255259
return -1, nil
256260
case query.Type_DATE:
257261
return -1, nil
262+
case query.Type_NULL_TYPE:
263+
return -1, nil // NULL is treated as TEXT on the wire
258264
default:
259-
return 0, fmt.Errorf("unsupported type returned from engine")
265+
return 0, fmt.Errorf("unsupported type returned from engine: %s", field.Type)
260266
}
261267
}

server/ast/expr.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,15 @@ func nodeExpr(node tree.Expr) (vitess.Expr, error) {
210210
Type: convertType,
211211
}, nil
212212
case *tree.CoalesceExpr:
213-
return nil, fmt.Errorf("COALESCE is not yet supported")
213+
exprs, err := nodeExprsToSelectExprs(node.Exprs)
214+
if err != nil {
215+
return nil, err
216+
}
217+
218+
return &vitess.FuncExpr{
219+
Name: vitess.NewColIdent("COALESCE"),
220+
Exprs: exprs,
221+
}, nil
214222
case *tree.CollateExpr:
215223
return nil, fmt.Errorf("collations are not yet supported")
216224
case *tree.ColumnAccessExpr:
@@ -400,8 +408,20 @@ func nodeExpr(node tree.Expr) (vitess.Expr, error) {
400408
Expr: expr,
401409
}, nil
402410
case *tree.NullIfExpr:
403-
//TODO: probably should be the IF function: IF(Expr1 == Expr2, NULL, Expr1)
404-
return nil, fmt.Errorf("NULLIF is not yet supported")
411+
expr1, err := nodeExprToSelectExpr(node.Expr1)
412+
if err != nil {
413+
return nil, err
414+
}
415+
416+
expr2, err := nodeExprToSelectExpr(node.Expr2)
417+
if err != nil {
418+
return nil, err
419+
}
420+
421+
return &vitess.FuncExpr{
422+
Name: vitess.NewColIdent("NULLIF"),
423+
Exprs: vitess.SelectExprs{expr1, expr2},
424+
}, nil
405425
case tree.NullLiteral:
406426
return &vitess.NullVal{}, nil
407427
case *tree.NumVal:

server/ast/func_expr.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ func nodeFuncExpr(node *tree.FuncExpr) (*vitess.FuncExpr, error) {
5454
}
5555
var distinct bool
5656
switch node.Type {
57-
case 0:
57+
case 0, tree.AllFuncType:
5858
distinct = false
5959
case tree.DistinctFuncType:
6060
distinct = true
61-
case tree.AllFuncType:
62-
return nil, fmt.Errorf("function spec is not yet supported")
61+
default:
62+
return nil, fmt.Errorf("unknown function spec type %d", node.Type)
6363
}
6464
windowDef, err := nodeWindowDef(node.WindowDef)
6565
if err != nil {

server/ast/table_expr.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ func nodeTableExpr(node tree.TableExpr) (vitess.TableExpr, error) {
5151
for i := range treeCondition.Cols {
5252
condition.Using[i] = vitess.NewColIdent(string(treeCondition.Cols[i]))
5353
}
54+
case nil:
55+
// cross join (no join condition)
5456
default:
5557
return nil, fmt.Errorf("unknown JOIN condition: `%T`", treeCondition)
5658
}
@@ -70,10 +72,7 @@ func nodeTableExpr(node tree.TableExpr) (vitess.TableExpr, error) {
7072
} else {
7173
joinType = vitess.RightJoinStr
7274
}
73-
case tree.AstCross:
74-
// GMS doesn't have any support for CROSS joins, as MySQL doesn't actually implement them
75-
return nil, fmt.Errorf("CROSS joins are not yet supported")
76-
case tree.AstInner:
75+
case tree.AstCross, tree.AstInner:
7776
joinType = vitess.JoinStr
7877
case "":
7978
if condition.On == nil && len(condition.Using) == 0 {

testing/go/regression_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2023 Dolthub, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package _go
16+
17+
import (
18+
"testing"
19+
20+
"github.com/dolthub/go-mysql-server/sql"
21+
)
22+
23+
func TestRegressions(t *testing.T) {
24+
RunScripts(t, []ScriptTest{
25+
// {
26+
// Name: "nullif",
27+
// SetUpScript: []string{},
28+
// Assertions: []ScriptTestAssertion{
29+
// {
30+
// Query: "select nullif(1, 1);",
31+
// Expected: []sql.Row{{nil}},
32+
// },
33+
// {
34+
// Query: "select nullif('', null);",
35+
// Expected: []sql.Row{{""}},
36+
// },
37+
// {
38+
// Query: "select nullif(10, 'a');",
39+
// Expected: []sql.Row{{10}},
40+
// },
41+
// },
42+
// },
43+
// {
44+
// Name: "coalesce",
45+
// SetUpScript: []string{},
46+
// Assertions: []ScriptTestAssertion{
47+
// {
48+
// Query: "select coalesce(null + 5, 100);",
49+
// Expected: []sql.Row{{100.0}}, // TODO: this should be an integer
50+
// },
51+
// {
52+
// Query: "select coalesce(null, null, 'abc');",
53+
// Expected: []sql.Row{{"abc"}},
54+
// },
55+
// {
56+
// Query: "select coalesce(null, null);",
57+
// Expected: []sql.Row{{nil}},
58+
// },
59+
// },
60+
// },
61+
{
62+
Name: "case / when",
63+
SetUpScript: []string{},
64+
Assertions: []ScriptTestAssertion{
65+
{
66+
Query: "SELECT\n" +
67+
" CASE\n" +
68+
" WHEN 1 = 1 THEN 'One is equal to One'\n" +
69+
" ELSE 'One is not equal to One'\n" +
70+
" END AS result;",
71+
Expected: []sql.Row{{"One is equal to One"}},
72+
},
73+
{
74+
Query: "SELECT\n" +
75+
" CASE\n" +
76+
" WHEN NULL IS NULL THEN 'NULL is NULL'\n" +
77+
" ELSE 'NULL is not NULL'\n" +
78+
" END AS result;",
79+
Expected: []sql.Row{{"NULL is NULL"}},
80+
},
81+
},
82+
},
83+
{
84+
Name: "ALL / DISTINCT in functions",
85+
SetUpScript: []string{
86+
"create table t1 (pk int);",
87+
"insert into t1 values (1), (2), (3), (1);",
88+
},
89+
Assertions: []ScriptTestAssertion{
90+
{
91+
Query: "select all count(*) from t1;",
92+
Expected: []sql.Row{{4}},
93+
},
94+
{
95+
Query: "select all count(distinct pk) from t1;",
96+
Expected: []sql.Row{{3}},
97+
},
98+
{
99+
Query: "select all count(all pk) from t1;",
100+
Expected: []sql.Row{{4}},
101+
},
102+
},
103+
},
104+
{
105+
Name: "cross joins",
106+
SetUpScript: []string{
107+
"create table t1 (pk1 int);",
108+
"create table t2 (pk2 int);",
109+
"insert into t1 values (1), (2);",
110+
"insert into t2 values (3), (4);",
111+
},
112+
Assertions: []ScriptTestAssertion{
113+
{
114+
Query: "select * from t1 cross join t2 order by pk1, pk2;",
115+
Expected: []sql.Row{
116+
{1, 3},
117+
{1, 4},
118+
{2, 3},
119+
{2, 4},
120+
},
121+
},
122+
{
123+
Query: "select * from t1, t2 order by pk1, pk2;",
124+
Expected: []sql.Row{
125+
{1, 3},
126+
{1, 4},
127+
{2, 3},
128+
{2, 4},
129+
},
130+
},
131+
},
132+
},
133+
})
134+
}

testing/logictest/harness/doltgres_harness.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ func columns(rows *sql.Rows) (string, []interface{}, error) {
238238
colVal := sql.NullInt64{}
239239
columns = append(columns, &colVal)
240240
sb.WriteString("I")
241+
case "UNKNOWN": // used for NULL values
242+
colVal := sql.NullString{}
243+
columns = append(columns, &colVal)
244+
sb.WriteString("I") // is this right?
241245
default:
242246
return "", nil, fmt.Errorf("Unhandled type %s", columnType.DatabaseTypeName())
243247
}

0 commit comments

Comments
 (0)