Skip to content

Commit 3d98cc2

Browse files
Merge 1280052 into fa0a7c0
2 parents fa0a7c0 + 1280052 commit 3d98cc2

File tree

4 files changed

+1021
-151
lines changed

4 files changed

+1021
-151
lines changed

packages/firestore/src/lite-api/query.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,20 +1076,14 @@ function conflictingOps(op: Operator): Operator[] {
10761076
case Operator.NOT_EQUAL:
10771077
return [Operator.NOT_EQUAL, Operator.NOT_IN];
10781078
case Operator.ARRAY_CONTAINS:
1079-
return [
1080-
Operator.ARRAY_CONTAINS,
1081-
Operator.ARRAY_CONTAINS_ANY,
1082-
Operator.NOT_IN
1083-
];
1084-
case Operator.IN:
1085-
return [Operator.ARRAY_CONTAINS_ANY, Operator.IN, Operator.NOT_IN];
10861079
case Operator.ARRAY_CONTAINS_ANY:
10871080
return [
10881081
Operator.ARRAY_CONTAINS,
10891082
Operator.ARRAY_CONTAINS_ANY,
1090-
Operator.IN,
10911083
Operator.NOT_IN
10921084
];
1085+
case Operator.IN:
1086+
return [Operator.NOT_IN];
10931087
case Operator.NOT_IN:
10941088
return [
10951089
Operator.ARRAY_CONTAINS,
@@ -1218,6 +1212,7 @@ export function validateQueryFilterConstraint(
12181212
) {
12191213
throw new FirestoreError(
12201214
Code.INVALID_ARGUMENT,
1215+
12211216
`Function ${functionName}() requires AppliableConstraints created with a call to 'where(...)', 'or(...)', or 'and(...)'.`
12221217
);
12231218
}

packages/firestore/test/integration/api/query.test.ts

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,246 @@ apiDescribe('Queries', (persistence: boolean) => {
15741574
);
15751575
});
15761576
});
1577+
1578+
// TODO(orquery): Enable this test when prod supports OR queries.
1579+
// eslint-disable-next-line no-restricted-properties
1580+
it('supports multiple in ops', () => {
1581+
const testDocs = {
1582+
doc1: { a: 1, b: 0 },
1583+
doc2: { b: 1 },
1584+
doc3: { a: 3, b: 2 },
1585+
doc4: { a: 1, b: 3 },
1586+
doc5: { a: 1 },
1587+
doc6: { a: 2 }
1588+
};
1589+
1590+
return withTestCollection(persistence, testDocs, async coll => {
1591+
// Two IN operations on different fields with disjunction.
1592+
await checkOnlineAndOfflineResultsMatch(
1593+
query(
1594+
coll,
1595+
or(where('a', 'in', [2, 3]), where('b', 'in', [0, 2])),
1596+
orderBy('a')
1597+
),
1598+
'doc1',
1599+
'doc6',
1600+
'doc3'
1601+
);
1602+
1603+
// Two IN operations on different fields with conjunction.
1604+
await checkOnlineAndOfflineResultsMatch(
1605+
query(
1606+
coll,
1607+
and(where('a', 'in', [2, 3]), where('b', 'in', [0, 2])),
1608+
orderBy('a')
1609+
),
1610+
'doc3'
1611+
);
1612+
1613+
// Two IN operations on the same field.
1614+
// a IN [1,2,3] && a IN [0,1,4] should result in "a==1".
1615+
await checkOnlineAndOfflineResultsMatch(
1616+
query(
1617+
coll,
1618+
and(where('a', 'in', [1, 2, 3]), where('a', 'in', [0, 1, 4]))
1619+
),
1620+
'doc1',
1621+
'doc4',
1622+
'doc5'
1623+
);
1624+
1625+
// a IN [2,3] && a IN [0,1,4] is never true and so the result should be an
1626+
// empty set.
1627+
await checkOnlineAndOfflineResultsMatch(
1628+
query(coll, and(where('a', 'in', [2, 3]), where('a', 'in', [0, 1, 4])))
1629+
);
1630+
1631+
// a IN [0,3] || a IN [0,2] should union them (similar to: a IN [0,2,3]).
1632+
await checkOnlineAndOfflineResultsMatch(
1633+
query(coll, or(where('a', 'in', [0, 3]), where('a', 'in', [0, 2]))),
1634+
'doc3',
1635+
'doc6'
1636+
);
1637+
1638+
// Nested composite filter on the same field.
1639+
await checkOnlineAndOfflineResultsMatch(
1640+
query(
1641+
coll,
1642+
and(
1643+
where('a', 'in', [1, 3]),
1644+
or(
1645+
where('a', 'in', [0, 2]),
1646+
and(where('b', '>=', 1), where('a', 'in', [1, 3]))
1647+
)
1648+
)
1649+
),
1650+
'doc3',
1651+
'doc4'
1652+
);
1653+
1654+
// Nested composite filter on the different fields.
1655+
await checkOnlineAndOfflineResultsMatch(
1656+
query(
1657+
coll,
1658+
and(
1659+
where('b', 'in', [0, 3]),
1660+
or(
1661+
where('b', 'in', [1]),
1662+
and(where('b', 'in', [2, 3]), where('a', 'in', [1, 3]))
1663+
)
1664+
)
1665+
),
1666+
'doc4'
1667+
);
1668+
});
1669+
});
1670+
1671+
// TODO(orquery): Enable this test when prod supports OR queries.
1672+
// eslint-disable-next-line no-restricted-properties
1673+
it.skip('supports using in with array contains any', () => {
1674+
const testDocs = {
1675+
doc1: { a: 1, b: [0] },
1676+
doc2: { b: [1] },
1677+
doc3: { a: 3, b: [2, 7], c: 10 },
1678+
doc4: { a: 1, b: [3, 7] },
1679+
doc5: { a: 1 },
1680+
doc6: { a: 2, c: 20 }
1681+
};
1682+
1683+
return withTestCollection(persistence, testDocs, async coll => {
1684+
await checkOnlineAndOfflineResultsMatch(
1685+
query(
1686+
coll,
1687+
or(where('a', 'in', [2, 3]), where('b', 'array-contains-any', [0, 7]))
1688+
),
1689+
'doc1',
1690+
'doc3',
1691+
'doc4',
1692+
'doc6'
1693+
);
1694+
1695+
await checkOnlineAndOfflineResultsMatch(
1696+
query(
1697+
coll,
1698+
and(
1699+
where('a', 'in', [2, 3]),
1700+
where('b', 'array-contains-any', [0, 7])
1701+
)
1702+
),
1703+
'doc3'
1704+
);
1705+
1706+
await checkOnlineAndOfflineResultsMatch(
1707+
query(
1708+
coll,
1709+
or(
1710+
and(where('a', 'in', [2, 3]), where('c', '==', 10)),
1711+
where('b', 'array-contains-any', [0, 7])
1712+
)
1713+
),
1714+
'doc1',
1715+
'doc3',
1716+
'doc4'
1717+
);
1718+
1719+
await checkOnlineAndOfflineResultsMatch(
1720+
query(
1721+
coll,
1722+
and(
1723+
where('a', 'in', [2, 3]),
1724+
or(where('b', 'array-contains-any', [0, 7]), where('c', '==', 20))
1725+
)
1726+
),
1727+
'doc3',
1728+
'doc6'
1729+
);
1730+
});
1731+
});
1732+
1733+
// TODO(orquery): Enable this test when prod supports OR queries.
1734+
// eslint-disable-next-line no-restricted-properties
1735+
it.skip('supports using in with array contains', () => {
1736+
const testDocs = {
1737+
doc1: { a: 1, b: [0] },
1738+
doc2: { b: [1] },
1739+
doc3: { a: 3, b: [2, 7] },
1740+
doc4: { a: 1, b: [3, 7] },
1741+
doc5: { a: 1 },
1742+
doc6: { a: 2 }
1743+
};
1744+
1745+
return withTestCollection(persistence, testDocs, async coll => {
1746+
await checkOnlineAndOfflineResultsMatch(
1747+
query(
1748+
coll,
1749+
or(where('a', 'in', [2, 3]), where('b', 'array-contains', 3))
1750+
),
1751+
'doc3',
1752+
'doc4',
1753+
'doc6'
1754+
);
1755+
1756+
await checkOnlineAndOfflineResultsMatch(
1757+
query(
1758+
coll,
1759+
and(where('a', 'in', [2, 3]), where('b', 'array-contains', 7))
1760+
),
1761+
'doc3'
1762+
);
1763+
1764+
await checkOnlineAndOfflineResultsMatch(
1765+
query(
1766+
coll,
1767+
or(
1768+
where('a', 'in', [2, 3]),
1769+
and(where('b', 'array-contains', 3), where('a', '==', 1))
1770+
)
1771+
),
1772+
'doc3',
1773+
'doc4',
1774+
'doc6'
1775+
);
1776+
1777+
await checkOnlineAndOfflineResultsMatch(
1778+
query(
1779+
coll,
1780+
and(
1781+
where('a', 'in', [2, 3]),
1782+
or(where('b', 'array-contains', 7), where('a', '==', 1))
1783+
)
1784+
),
1785+
'doc3'
1786+
);
1787+
});
1788+
});
1789+
1790+
// TODO(orquery): Enable this test when prod supports OR queries.
1791+
// eslint-disable-next-line no-restricted-properties
1792+
it.skip('supports order by equality', () => {
1793+
const testDocs = {
1794+
doc1: {a: 1, b: [0]},
1795+
doc2: {b: [1]},
1796+
doc3: {a: 3, b: [2, 7], c: 10},
1797+
doc4: {a: 1, b: [3, 7]},
1798+
doc5: {a: 1},
1799+
doc6: {a: 2, c: 20}
1800+
};
1801+
1802+
return withTestCollection(persistence, testDocs, async coll => {
1803+
await checkOnlineAndOfflineResultsMatch(
1804+
query(coll, where('a', '==', 1), orderBy('a')),
1805+
'doc1',
1806+
'doc4',
1807+
'doc5'
1808+
);
1809+
1810+
await checkOnlineAndOfflineResultsMatch(
1811+
query(coll, where('a', 'in', [2, 3]), orderBy('a')),
1812+
'doc6',
1813+
'doc3'
1814+
);
1815+
});
1816+
});
15771817
});
15781818

15791819
// Reproduces https://github.com/firebase/firebase-js-sdk/issues/5873
@@ -1612,6 +1852,7 @@ apiDescribe('Queries', (persistence: boolean) => {
16121852
expect(snapshot2.metadata.fromCache).to.be.true;
16131853
expect(toDataArray(snapshot2)).to.deep.equal([]);
16141854
});
1855+
>>>>>>> master
16151856
});
16161857
});
16171858
});

0 commit comments

Comments
 (0)