cockroachdb / cockroachdb/cockroach

sql: support overlay() on BIT/VARBIT strings

Open
#171,573 0 comments 0 reactions 0 assignees View on GitHub
A-sql-builtins A-sql-pgcompat C-enhancement O-agent O-pg-regress T-sql-foundations
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Is your feature request related to a problem? Please describe.**

CockroachDB does not support the `overlay()` function on `BIT`/`VARBIT` values.
PostgreSQL allows `overlay()` over bit strings (substituting a substring of bits
starting at a given position), but CockroachDB rejects it:

```
SELECT overlay(B'0101011100' placing '001' from 2 for 3);
ERROR: unknown signature: overlay(varbit, string, int, int)
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

SELECT overlay(B'0101011100' placing '101' from 6);
ERROR: unknown signature: overlay(varbit, string, int)
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
```

CockroachDB already implements `overlay()` for string types, so this is a
missing set of overloads for the bit-string types rather than a new function:
- [pkg/sql/sem/builtins/builtins.go#L1537](https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/sem/builtins/builtins.go#L1537)

This was discovered via the `pg_regress` roachtest (the `bit` test).

**Describe the solution you'd like**

Add `overlay()` overloads for bit strings, matching PostgreSQL semantics:

```
overlay(bits bit placing newsubstring bit from int) → bit
overlay(bits bit placing newsubstring bit from int for int) → bit
```

PostgreSQL behavior for the cases above (for reference):

| Query | PostgreSQL result |
|-------|-------------------|
| `overlay(B'0101011100' placing '001' from 2 for 3)` | `0001011100` |
| `overlay(B'0101011100' placing '101' from 6)` | `0101010100` |
| `overlay(B'0101011100' placing '001' from 11)` | `0101011100001` |
| `overlay(B'0101011100' placing '001' from 20)` | `0101011100001` |

Note the `placing` argument is itself a bit string in PostgreSQL; the literal
`'001'` is coerced to `bit`/`varbit` (which is why the current CockroachDB error
reports a `string` second argument — the bit-string overload simply doesn't
exist for the typing rules to resolve to).

**Describe alternatives you've considered**

- Requiring users to cast to/from string and use the string `overlay()`:
rejected as a poor compatibility story and a behavior mismatch (bit-string
positions/lengths are in bits, not characters).

**Additional context**

Surfaced while refreshing the `pg_regress` golden files. The divergence is
recorded in the `bit` regression diff:
- [pkg/cmd/roachtest/testdata/pg_regress/bit.diffs](https://github.com/cockroachdb/cockroach/blob/master/pkg/cmd/roachtest/testdata/pg_regress/bit.diffs)

Epic: none

Jira issue: CRDB-64696

Epic CRDB-60814

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.