cockroachdb / cockroachdb/cockroach
`INTERSECT` semantics violated: different outputs with different query plans
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Describe the problem**
`intersect` produced incorrect result.
**To Reproduce**
```sql
--- for better reproduce
SET CLUSTER SETTING sql.query_cache.enabled = false;
--- init database
CREATE TABLE t5 (
a2 INT2 NULL,
a4 INT8 NULL,
INDEX i4 (a4 ASC, a2 ASC)
) WITH (sql_stats_automatic_collection_enabled = false);
insert into t5 values (32, null), (-129, -129);
--- error sql
select
a2::int8 as c1,
a2::int8 as c3
from t5
where (a2 is not null)
intersect (
select distinct
a2::int8 as c1,
a4 as c3
from t5
where (a2 is not null)
)
order by c1
;
```
**Wrong result**:
```
c1 | c3
----+----
(0 rows)
```
plan:
```
• intersect all
│ columns: (c1, c3)
│ ordering: +c1
│ estimated row count: 990 (missing stats)
│
├── • project
│ │ columns: (c1, c1)
│ │ ordering: +c1
│ │
│ └── • sort
│ │ columns: (c1)
│ │ estimated row count: 990 (missing stats)
│ │ order: +c1
│ │
│ └── • render
│ │ columns: (c1)
│ │ render c1: a2::INT8
│ │
│ └── • filter
│ │ columns: (a2)
│ │ estimated row count: 990 (missing stats)
│ │ filter: a2 IS NOT NULL
│ │
│ └── • scan
│ columns: (a2)
│ estimated row count: 1,000 (missing stats)
│ table: t5@t5_pkey
│ spans: FULL SCAN
│
└── • distinct
│ columns: (c1, a4)
│ ordering: +a4
│ estimated row count: 990 (missing stats)
│ distinct on: c1, a4
│ order key: a4
│
└── • render
│ columns: (c1, a4)
│ ordering: +a4
│ render c1: a2::INT8
│ render a4: a4
│
└── • filter
│ columns: (a2, a4)
│ ordering: +a4
│ estimated row count: 990 (missing stats)
│ filter: a2 IS NOT NULL
│
└── • scan
columns: (a2, a4)
ordering: +a4
estimated row count: 1,000 (missing stats)
table: t5@i4
spans: FULL SCAN
```
**correct result:**
if we inject a dummy statistics to alter plan:
```sql
ALTER TABLE t5 INJECT STATISTICS '[
{
"avg_size": 0,
"columns": [
"a2"
],
"created_at": "2025-04-22 10:08:51.758985",
"distinct_count": 0,
"histo_col_type": "",
"null_count": 0,
"row_count": 0
}
]';
```
we can get correct result:
```
c1 | c3
------+------
-129 | -129
(1 row)
```
plan:
```
• sort
│ columns: (c1, c3)
│ estimated row count: 0
│ order: +c1
│
└── • intersect all
│ columns: (c1, c1)
│ estimated row count: 0
│
├── • project
│ │ columns: (c1, c1)
│ │
│ └── • render
│ │ columns: (c1)
│ │ render c1: a2::INT8
│ │
│ └── • filter
│ │ columns: (a2)
│ │ estimated row count: 1
│ │ filter: a2 IS NOT NULL
│ │
│ └── • scan
│ columns: (a2)
│ estimated row count: 1 (100% of the table; stats collected 21 hours ago)
│ table: t5@t5_pkey
│ spans: FULL SCAN
│
└── • distinct
│ columns: (c1, a4)
│ estimated row count: 0
│ distinct on: c1, a4
│
└── • render
│ columns: (c1, a4)
│ render c1: a2::INT8
│ render a4: a4
│
└── • filter
│ columns: (a2, a4)
│ estimated row count: 1
│ filter: a2 IS NOT NULL
│
└── • scan
columns: (a2, a4)
estimated row count: 1 (100% of the table; stats collected 21 hours ago)
table: t5@t5_pkey
spans: FULL SCAN
```
**Environment:**
- CockroachDB version: 23.2.23
- Server OS: `Linux a002 6.5.0-18-generic #18~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 11:40:03 UTC 2 x86_64 x86_64 x86_64 GNU/Linux`
- Client app: psql
docker compose file:
```
x-service-defaults: &service_defaults
image: ${CR_IMAGE:?please provide the image name}
services:
crdb1:
<<: *service_defaults
command: "start --advertise-addr=crdb1:26357 --locality=region=r1,zone=r1a --http-addr=crdb1:8080 --listen-addr=crdb1:26357 --sql-addr=crdb1:26257 --insecure --join=crdb1:26357,crdb2:26357,crdb3:26357,crdb4:26357,crdb5:26357"
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.11
crdb2:
<<: *service_defaults
command: "start --advertise-addr=crdb2:26357 --locality=region=r2,zone=r2a --http-addr=crdb2:8080 --listen-addr=crdb2:26357 --sql-addr=crdb2:26257 --insecure --join=crdb1:26357,crdb2:26357,crdb3:26357,crdb4:26357,crdb5:26357"
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.12
crdb3:
<<: *service_defaults
command: "start --advertise-addr=crdb3:26357 --locality=region=r3,zone=r3a --http-addr=crdb3:8080 --listen-addr=crdb3:26357 --sql-addr=crdb3:26257 --insecure --join=crdb1:26357,crdb2:26357,crdb3:26357,crdb4:26357,crdb5:26357"
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.13
crdb4:
<<: *service_defaults
command: "start --advertise-addr=crdb4:26357 --locality=region=r4,zone=r4a --http-addr=crdb4:8080 --listen-addr=crdb4:26357 --sql-addr=crdb4:26257 --insecure --join=crdb1:26357,crdb2:26357,crdb3:26357,crdb4:26357,crdb5:26357"
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.14
crdb5:
<<: *service_defaults
command: "start --advertise-addr=crdb5:26357 --locality=region=r5,zone=r5a --http-addr=crdb5:8080 --listen-addr=crdb5:26357 --sql-addr=crdb5:26257 --insecure --join=crdb1:26357,crdb2:26357,crdb3:26357,crdb4:26357,crdb5:26357"
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.15
crdb_single:
<<: *service_defaults
command: start-single-node --insecure
volumes:
- "/cockroach/cockroach-data"
networks:
crnet:
ipv4_address: ${CR_SUBNET}.21
networks:
crnet:
driver: bridge
ipam:
config:
- subnet: ${CR_SUBNET:?please provide subnet range like `10.0.5`}.0/24
gateway: ${CR_SUBNET}.254
```
#### about us
We are the BASS team from the School of Cyber Science and Technology at Beihang University. Our main focus is on system software security, operating systems, and program analysis research, as well as the development of automated program testing frameworks for detecting software defects. Using our self-developed database vulnerability testing tool, we have identified the above-mentioned possible vulnerabilities that may lead to database logic error.
Jira issue: CRDB-49613
Contributor guide
Assessment
This issue has not been assessed yet.