Skip to content

Commit ffdc4a9

Browse files
authored
Merge pull request #3060 from dolthub/angela/union
Merge scopeColumn types in SetOp scope
2 parents 4f63775 + 936afd9 commit ffdc4a9

File tree

5 files changed

+65
-24
lines changed

5 files changed

+65
-24
lines changed

enginetest/queries/integration_plans.go

Lines changed: 16 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/queries/script_queries.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8728,6 +8728,27 @@ where
87288728
},
87298729
},
87308730
},
8731+
{
8732+
// https://github.com/dolthub/dolt/issues/9024
8733+
Name: "subqueries should coerce union types",
8734+
Dialect: "mysql",
8735+
SetUpScript: []string{
8736+
"create table enum_table (i int primary key, e enum('a','b') not null)",
8737+
"insert into enum_table values (1,'a'),(2,'b')",
8738+
"create table uv (u int primary key, v varchar(10))",
8739+
"insert into uv values (0, 'bug'),(1,'ant'),(3, null)",
8740+
},
8741+
Assertions: []ScriptTestAssertion{
8742+
{
8743+
Query: "select * from (select e from enum_table union select v from uv) sq",
8744+
Expected: []sql.Row{{"a"}, {"b"}, {"bug"}, {"ant"}, {nil}},
8745+
},
8746+
{
8747+
Query: "with a as (select e from enum_table union select v from uv) select * from a",
8748+
Expected: []sql.Row{{"a"}, {"b"}, {"bug"}, {"ant"}, {nil}},
8749+
},
8750+
},
8751+
},
87318752

87328753
// Enum tests
87338754
{

sql/planbuilder/set_op.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/dolthub/go-mysql-server/sql/expression"
2525
"github.com/dolthub/go-mysql-server/sql/plan"
2626
"github.com/dolthub/go-mysql-server/sql/transform"
27+
"github.com/dolthub/go-mysql-server/sql/types"
2728
)
2829

2930
func hasRecursiveCte(node sql.Node) bool {
@@ -144,10 +145,28 @@ func (b *Builder) buildSetOp(inScope *scope, u *ast.SetOp) (outScope *scope) {
144145
tabId := b.tabId
145146
ret := plan.NewSetOp(setOpType, leftScope.node, rightScope.node, distinct, limit, offset, sortFields).WithId(tabId).WithColumns(cols)
146147
outScope = leftScope
148+
outScope.cols = b.mergeSetOpScopeColumns(leftScope.cols, rightScope.cols, tabId)
147149
outScope.node = b.mergeSetOpSchemas(ret.(*plan.SetOp))
148150
return
149151
}
150152

153+
func (b *Builder) mergeSetOpScopeColumns(left, right []scopeColumn, tabId sql.TableId) []scopeColumn {
154+
merged := make([]scopeColumn, len(left))
155+
for i := range left {
156+
merged[i] = scopeColumn{
157+
tableId: tabId,
158+
db: left[i].db,
159+
table: left[i].table,
160+
col: left[i].col,
161+
originalCol: left[i].originalCol,
162+
id: left[i].id,
163+
typ: types.GeneralizeTypes(left[i].typ, right[i].typ),
164+
nullable: left[i].nullable || right[i].nullable,
165+
}
166+
}
167+
return merged
168+
}
169+
151170
func (b *Builder) mergeSetOpSchemas(u *plan.SetOp) sql.Node {
152171
ls, rs := u.Left().Schema(), u.Right().Schema()
153172
if len(ls) != len(rs) {

sql/types/conversion.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package types
1616

1717
import (
1818
"fmt"
19+
"reflect"
1920
"strconv"
2021
"strings"
2122
"time"
@@ -635,7 +636,12 @@ func generalizeNumberTypes(a, b sql.Type) sql.Type {
635636
// GeneralizeTypes returns the more "general" of two types as defined by
636637
// https://dev.mysql.com/doc/refman/8.4/en/flow-control-functions.html
637638
// TODO: Create and handle "Illegal mix of collations" error
639+
// TODO: Handle extended types, like DoltgresType
638640
func GeneralizeTypes(a, b sql.Type) sql.Type {
641+
if reflect.DeepEqual(a, b) {
642+
return a
643+
}
644+
639645
if a == Null {
640646
return b
641647
}

sql/types/conversion_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,16 @@ func TestGeneralizeTypes(t *testing.T) {
198198
{Int8, Int8, Int8},
199199
{Boolean, Int64, Int64},
200200
{Boolean, Boolean, Boolean},
201-
{Text, Text, LongText},
201+
{Text, Text, Text},
202+
{Text, LongText, LongText},
202203
{Text, Float64, LongText},
203204
{Int64, Text, LongText},
204205
{Int8, Null, Int8},
205206
{Time, Time, Time},
206207
{Time, Date, DatetimeMaxPrecision},
207208
{Date, Date, Date},
208209
{Date, Timestamp, DatetimeMaxPrecision},
209-
{Timestamp, Timestamp, TimestampMaxPrecision},
210+
{Timestamp, Timestamp, Timestamp},
210211
{Timestamp, Datetime, DatetimeMaxPrecision},
211212
{Null, Int64, Int64},
212213
{Null, Null, Null},

0 commit comments

Comments
 (0)