Skip to content

Commit 3c4c4e1

Browse files
committed
opt: propagate HasUDF in cached shared logical properties
This commit fixes a minor bug where the `props.Shared.HasUDF` property was not correctly propagated from cached shared properties of an expression's children. As far as I can tell, this bug currently has no effect on any optimizer behavior. `HasUDF` is only used in determining if the insert fast path can be used and there are other, more strict restrictions for the insert fast path that preclude acceptance of any expression in which `HasUDF` may not be properly propagated (e.g., a Values expression without subqueries is required and the only way I can figure to include a UDF invocation in a relational expression that's a child of a Values clause is with a subquery). Release note: None
1 parent c3f3951 commit 3c4c4e1

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

pkg/sql/opt/memo/logical_props_builder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,9 @@ func BuildSharedProps(e opt.Expr, shared *props.Shared, evalCtx *eval.Context) {
17301730
if cached.HasCorrelatedSubquery {
17311731
shared.HasCorrelatedSubquery = true
17321732
}
1733+
if cached.HasUDF {
1734+
shared.HasUDF = true
1735+
}
17331736
} else {
17341737
BuildSharedProps(e.Child(i), shared, evalCtx)
17351738
}

pkg/sql/opt/memo/testdata/logprops/udf

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,68 @@ project
209209
│ └── projections
210210
│ └── const: 1 [as="?column?":5, type=int]
211211
└── const: 1 [type=int]
212+
213+
# The "udf" property should propagate to the top-most filter.
214+
build
215+
SELECT i FROM (VALUES (1), (2)) v(i) WHERE i = (SELECT a FROM ab WHERE b = fn_leakproof())
216+
----
217+
select
218+
├── columns: i:1(int!null)
219+
├── cardinality: [0 - 2]
220+
├── values
221+
│ ├── columns: column1:1(int!null)
222+
│ ├── cardinality: [2 - 2]
223+
│ ├── prune: (1)
224+
│ ├── tuple [type=tuple{int}]
225+
│ │ └── const: 1 [type=int]
226+
│ └── tuple [type=tuple{int}]
227+
│ └── const: 2 [type=int]
228+
└── filters
229+
└── eq [type=bool, outer=(1), subquery, udf, constraints=(/1: (/NULL - ])]
230+
├── variable: column1:1 [type=int]
231+
└── subquery [type=int]
232+
└── max1-row
233+
├── columns: a:2(int!null)
234+
├── error: "more than one row returned by a subquery used as an expression"
235+
├── cardinality: [0 - 1]
236+
├── key: ()
237+
├── fd: ()-->(2)
238+
└── project
239+
├── columns: a:2(int!null)
240+
├── key: (2)
241+
├── prune: (2)
242+
├── interesting orderings: (+2)
243+
└── select
244+
├── columns: a:2(int!null) b:3(int!null) crdb_internal_mvcc_timestamp:4(decimal) tableoid:5(oid)
245+
├── key: (2)
246+
├── fd: ()-->(3), (2)-->(4,5)
247+
├── prune: (2,4,5)
248+
├── interesting orderings: (+2 opt(3))
249+
├── scan ab
250+
│ ├── columns: a:2(int!null) b:3(int) crdb_internal_mvcc_timestamp:4(decimal) tableoid:5(oid)
251+
│ ├── key: (2)
252+
│ ├── fd: (2)-->(3-5)
253+
│ ├── prune: (2-5)
254+
│ └── interesting orderings: (+2)
255+
└── filters
256+
└── eq [type=bool, outer=(3), udf, constraints=(/3: (/NULL - ]), fd=()-->(3)]
257+
├── variable: b:3 [type=int]
258+
└── udf: fn_leakproof [type=int]
259+
└── body
260+
└── limit
261+
├── columns: "?column?":6(int!null)
262+
├── cardinality: [1 - 1]
263+
├── key: ()
264+
├── fd: ()-->(6)
265+
├── project
266+
│ ├── columns: "?column?":6(int!null)
267+
│ ├── cardinality: [1 - 1]
268+
│ ├── key: ()
269+
│ ├── fd: ()-->(6)
270+
│ ├── values
271+
│ │ ├── cardinality: [1 - 1]
272+
│ │ ├── key: ()
273+
│ │ └── tuple [type=tuple]
274+
│ └── projections
275+
│ └── const: 1 [as="?column?":6, type=int]
276+
└── const: 1 [type=int]

0 commit comments

Comments
 (0)