Skip to content

Commit cd06b0f

Browse files
authored
Merge pull request #152893 from mw5h/backportrelease-24.1-152399
release-24.1: lookup join: add a cast when mapping references in computed columns
2 parents d1856a6 + 3f20b33 commit cd06b0f

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

pkg/sql/logictest/testdata/logic_test/lookup_join

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,10 @@ SELECT col1_6 FROM table_1_124732 INNER HASH JOIN table_3_124732 ON col3_0 = col
16011601
----
16021602
-
16031603

1604-
statement error pgcode XXUUU pq: could not produce a query plan conforming to the LOOKUP JOIN hint
1604+
query T
16051605
SELECT col1_6 FROM table_1_124732 INNER LOOKUP JOIN table_3_124732 ON col3_0 = col1_6;
1606+
----
1607+
-
16061608

16071609
# Regression test for incorrectly remapping columns in a composite-sensitive
16081610
# expression to produce a lookup join (#124732).

pkg/sql/opt/lookupjoin/constraint_builder.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,17 +260,6 @@ func (b *ConstraintBuilder) Build(
260260
keyCols = nil
261261
}
262262

263-
// rightEqIdenticalTypeCols is the set of columns in rightEq that have
264-
// identical types to the corresponding columns in leftEq. This is used to
265-
// determine if a computed column can be synthesized for a column in the
266-
// index in order to allow a lookup join.
267-
var rightEqIdenticalTypeCols opt.ColSet
268-
for i := range rightEq {
269-
if b.md.ColumnMeta(rightEq[i]).Type.Identical(b.md.ColumnMeta(leftEq[i]).Type) {
270-
rightEqIdenticalTypeCols.Add(rightEq[i])
271-
}
272-
}
273-
274263
// All the lookup conditions must apply to the prefix of the index and so
275264
// the projected columns created must be created in order.
276265
for j := 0; j < numIndexKeyCols; j++ {
@@ -294,7 +283,7 @@ func (b *ConstraintBuilder) Build(
294283
//
295284
// NOTE: we must only consider equivalent columns with identical types,
296285
// since column remapping is otherwise not valid.
297-
if expr, ok := b.findComputedColJoinEquality(b.table, idxCol, rightEqIdenticalTypeCols); ok {
286+
if expr, ok := b.findComputedColJoinEquality(b.table, idxCol, rightEq.ToSet()); ok {
298287
colMeta := b.md.ColumnMeta(idxCol)
299288
compEqCol := b.md.AddColumn(fmt.Sprintf("%s_eq", colMeta.Alias), colMeta.Type)
300289

@@ -307,7 +296,22 @@ func (b *ConstraintBuilder) Build(
307296

308297
// Project the computed column expression, mapping all columns
309298
// in rightEq to corresponding columns in leftEq.
310-
projection := b.f.ConstructProjectionsItem(b.f.RemapCols(expr, b.eqColMap), compEqCol)
299+
var replace norm.ReplaceFunc
300+
replace = func(e opt.Expr) opt.Expr {
301+
if v, ok := e.(*memo.VariableExpr); ok {
302+
if col, ok := b.eqColMap.Get(int(v.Col)); ok {
303+
// If the column is a computed column, we need to
304+
// cast it to the type of the original column so that
305+
// functions which are type sensitive still return the
306+
// expected results.
307+
return b.f.ConstructCast(b.f.ConstructVariable(opt.ColumnID(col)), b.md.ColumnMeta(v.Col).Type)
308+
} else {
309+
return e
310+
}
311+
}
312+
return b.f.Replace(e, replace)
313+
}
314+
projection := b.f.ConstructProjectionsItem(b.f.Replace(expr, replace).(opt.ScalarExpr), compEqCol)
311315
inputProjections = append(inputProjections, projection)
312316
addEqualityColumns(compEqCol, idxCol)
313317
derivedEquivCols.Add(compEqCol)

pkg/sql/opt/lookupjoin/testdata/computed

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,11 @@ lookup expression:
126126
lookup-constraints left=(a regclass, b int) right=(x oid, v string not null as (x::string) stored) index=(v, x)
127127
x = a
128128
----
129-
lookup join not possible
129+
key cols:
130+
v = v_eq
131+
x = a
132+
input projections:
133+
v_eq = a::OID::STRING [type=STRING]
130134

131135
# Computed columns cannot be remapped if the expression is composite-sensitive.
132136
lookup-constraints left=(a decimal, b int) right=(x decimal, v int not null as (x::int) stored) index=(v, x)

0 commit comments

Comments
 (0)