cockroachdb / cockroachdb/cockroach
sql: inlining of UDFs only works for IMMUTABLE or STABLE functions
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Describe the problem**
UDFs can only be inlined if the function is declared to be IMMUTABLE or STABLE. This is true even if there is only a single statement in the UDF and it is only called from a single place in a query. This seems too restrictive, since I imagine that many people will write UDFs that omit the IMMUTABLE or STABLE designation. Note that Postgres seems to inline functions if they have a single statement that can be constant-folded, regardless of the volatility.
**To Reproduce**
On `cockroach demo` on master or v23.1 alpha, run:
```
CREATE TABLE tab (x int, y int);
INSERT INTO tab VALUES (1, 1), (2, 2);
CREATE FUNCTION foo() RETURNS bool AS $$
SELECT (x + y) = 2 FROM tab WHERE x = 1;
$$ LANGUAGE SQL;
```
This function does not get inlined even if it's only called in a single place. For example:
```
EXPLAIN (VERBOSE) SELECT foo();
```
Returns:
```
demo@127.0.0.1:26257/demoapp/movr> EXPLAIN (VERBOSE) SELECT foo();
info
---------------------------
distribution: local
vectorized: true
• values
columns: (foo)
size: 1 column, 1 row
row 0, expr 0: foo()
(7 rows)
```
This one doesn't either:
```
CREATE FUNCTION foo2() RETURNS bool AS $$
SELECT true;
$$ LANGUAGE SQL;
EXPLAIN (VERBOSE) SELECT foo2();
```
It does get inlined if I specify that the function is IMMUTABLE or STABLE, though:
```
CREATE FUNCTION foo3() RETURNS bool AS $$
SELECT true;
$$ LANGUAGE SQL STABLE;
EXPLAIN (VERBOSE) SELECT foo3();
```
Produces:
```
info
-----------------------------------
distribution: local
vectorized: true
• root
│ columns: (foo3)
│
├── • values
│ columns: (foo3)
│ size: 1 column, 1 row
│ row 0, expr 0: @S1
│
└── • subquery
│ id: @S1
│ original sql:
│ exec mode: one row
│
└── • values
columns: (bool)
size: 1 column, 1 row
row 0, expr 0: true
(20 rows)
```
**Expected behavior**
I could be wrong, but it seems like we are being too conservative with inlining. It seems like we should be able to inline in all the cases above.
Jira issue: CRDB-26883
Contributor guide
Research direction
Start by reproducing the SQL UDF examples with `cockroach demo`, then compare the `EXPLAIN (VERBOSE)` output for functions with and without IMMUTABLE or STABLE. Trace the SQL UDF inlining behavior and verify that eligible single-statement functions are inlined without an explicit volatility designation, while preserving correct semantics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100