@@ -1457,6 +1457,179 @@ SET ROLE root
1457
1457
statement ok
1458
1458
DROP TABLE force_check CASCADE;
1459
1459
1460
+ # Test to make sure that the scan to enforce uniqueness is done without RLS policies.
1461
+ subtest uniq
1462
+
1463
+ statement ok
1464
+ CREATE TABLE uniq (rls_col TEXT, uniq_col INT8 UNIQUE);
1465
+
1466
+ statement ok
1467
+ CREATE USER uniq_user;
1468
+
1469
+ statement ok
1470
+ GRANT ALL ON uniq TO uniq_user;
1471
+
1472
+ statement ok
1473
+ ALTER TABLE uniq OWNER TO uniq_user;
1474
+
1475
+ statement ok
1476
+ SET ROLE uniq_user;
1477
+
1478
+ statement ok
1479
+ ALTER TABLE uniq NO FORCE ROW LEVEL SECURITY, ENABLE ROW LEVEL SECURITY;
1480
+
1481
+ statement ok
1482
+ CREATE POLICY access ON uniq USING (rls_col = 'cat');
1483
+
1484
+ statement ok
1485
+ INSERT INTO uniq VALUES ('cat', 1), ('cat', 2), ('dog', 3), ('cat', 4), ('hamster', 5);
1486
+
1487
+ statement ok
1488
+ ALTER TABLE uniq FORCE ROW LEVEL SECURITY;
1489
+
1490
+ statement error pq: duplicate key value violates unique constraint "uniq_uniq_col_key"\nDETAIL: Key \(uniq_col\)=\(3\) already exists.
1491
+ INSERT INTO uniq VALUES ('cat', 3);
1492
+
1493
+ statement ok
1494
+ INSERT INTO uniq VALUES ('cat', 6);
1495
+
1496
+ statement error pq: duplicate key value violates unique constraint "uniq_uniq_col_key"\nDETAIL: Key \(uniq_col\)=\(5\) already exists.
1497
+ UPDATE uniq SET uniq_col = 5 WHERE uniq_col = 1;
1498
+
1499
+ statement ok
1500
+ UPDATE uniq SET uniq_col = 7 WHERE uniq_col = 1;
1501
+
1502
+ # Ensure that any attempts to update an invisible row will be a no-op
1503
+ query TI
1504
+ UPDATE uniq SET uniq_col = 8 WHERE uniq_col = 5 RETURNING rls_col, uniq_col;
1505
+ ----
1506
+
1507
+ statement ok
1508
+ ALTER TABLE uniq NO FORCE ROW LEVEL SECURITY;
1509
+
1510
+ query TI
1511
+ select rls_col, uniq_col FROM uniq ORDER BY uniq_col;
1512
+ ----
1513
+ cat 2
1514
+ dog 3
1515
+ cat 4
1516
+ hamster 5
1517
+ cat 6
1518
+ cat 7
1519
+
1520
+ statement ok
1521
+ SET ROLE root;
1522
+
1523
+ statement ok
1524
+ DROP TABLE uniq;
1525
+
1526
+ statement ok
1527
+ DROP USER uniq_user;
1528
+
1529
+ # Test to make sure that the scan to enforce foreign keys is done without RLS policies.
1530
+ subtest fk
1531
+
1532
+ statement ok
1533
+ CREATE TABLE parent (key INT8 NOT NULL PRIMARY KEY);
1534
+
1535
+ statement ok
1536
+ CREATE TABLE child (
1537
+ rls_col TEXT,
1538
+ key INT8 NOT NULL,
1539
+ CONSTRAINT fk FOREIGN KEY (key) REFERENCES parent(key) ON DELETE CASCADE
1540
+ );
1541
+
1542
+ statement ok
1543
+ CREATE USER fk_user;
1544
+
1545
+ statement ok
1546
+ GRANT ALL ON parent TO fk_user;
1547
+
1548
+ statement ok
1549
+ GRANT ALL ON child TO fk_user;
1550
+
1551
+ statement ok
1552
+ ALTER TABLE parent OWNER TO fk_user;
1553
+
1554
+ statement ok
1555
+ ALTER TABLE child OWNER TO fk_user;
1556
+
1557
+ statement ok
1558
+ SET ROLE fk_user;
1559
+
1560
+ statement ok
1561
+ INSERT INTO parent SELECT * FROM generate_series(1,6);
1562
+
1563
+ statement ok
1564
+ INSERT INTO child VALUES ('bedroom', 1), ('office', 2)
1565
+
1566
+ # Set RLS at the parent and ensure FK still enforced.
1567
+ statement ok
1568
+ ALTER TABLE parent ENABLE ROW LEVEL SECURITY, FORCE ROW LEVEL SECURITY;
1569
+
1570
+ statement error pq: insert on table "child" violates foreign key constraint "fk"
1571
+ INSERT INTO child VALUES ('hall', 7);
1572
+
1573
+ statement ok
1574
+ INSERT INTO child VALUES ('hall', 3);
1575
+
1576
+ # mimic the FK lookup to show that the given RLS policies will hide the value
1577
+ query I
1578
+ SELECT 1 FROM parent WHERE key = 3;
1579
+ ----
1580
+
1581
+ query I
1582
+ SELECT key FROM child ORDER BY key;
1583
+ ----
1584
+ 1
1585
+ 2
1586
+ 3
1587
+
1588
+ # Set RLS at the child and ensure FK still enforced
1589
+ statement ok
1590
+ ALTER TABLE child ENABLE ROW LEVEL SECURITY, FORCE ROW LEVEL SECURITY;
1591
+
1592
+ statement ok
1593
+ CREATE POLICY ins1 ON child FOR INSERT WITH CHECK (rls_col = 'bedroom');
1594
+
1595
+ statement error pq: insert on table "child" violates foreign key constraint "fk"
1596
+ INSERT INTO child VALUES ('bedroom', 7);
1597
+
1598
+ statement error pq: new row violates row-level security policy for table "child"
1599
+ INSERT INTO child VALUES ('deck', 7);
1600
+
1601
+ statement ok
1602
+ INSERT INTO child VALUES ('bedroom', 4);
1603
+
1604
+ # Disable RLS at the parent so that we can do a delete and have it cascade down
1605
+ statement ok
1606
+ ALTER TABLE parent NO FORCE ROW LEVEL SECURITY;
1607
+
1608
+ statement ok
1609
+ DELETE FROM parent WHERE key = 1;
1610
+
1611
+ statement ok
1612
+ CREATE POLICY sel1 ON child FOR SELECT USING (true);
1613
+
1614
+ query I
1615
+ SELECT key FROM child ORDER BY key;
1616
+ ----
1617
+ 2
1618
+ 3
1619
+ 4
1620
+
1621
+ statement ok
1622
+ SET ROLE root
1623
+
1624
+ statement ok
1625
+ DROP TABLE child;
1626
+
1627
+ statement ok
1628
+ DROP TABLE parent;
1629
+
1630
+ statement ok
1631
+ DROP USER fk_user;
1632
+
1460
1633
subtest truncate
1461
1634
1462
1635
statement ok
0 commit comments