Skip to content

Commit 5011fbf

Browse files
committed
feat(firestore): add support for remaining string expressions
Adds support for string expressions `ltrim`, `rtrim`, `stringRepeat` `stringReplaceOne` `stringReplaceAll`, `stringIndexOf`. Ported from: googleapis/java-firestore#2326
1 parent 8bbbb18 commit 5011fbf

4 files changed

Lines changed: 902 additions & 13 deletions

File tree

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/PipelineTest.java

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,203 @@ public void testTrimWithCharacters() {
14781478
"The Hitchhiker's Guide to the Galaxy"));
14791479
}
14801480

1481+
@Test
1482+
public void testLTrim() {
1483+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1484+
1485+
Task<Pipeline.Snapshot> execute =
1486+
firestore
1487+
.pipeline()
1488+
.collection(randomCol)
1489+
.limit(1)
1490+
.replaceWith(
1491+
map(
1492+
ImmutableMap.of(
1493+
"strWhitespace", " trimMe ", "strChars", "xxxtrimMe", "chars", "x")))
1494+
.select(
1495+
Expression.ltrim(constant(" trimMe ")).alias("staticLtrimExpr"),
1496+
Expression.ltrim("strWhitespace").alias("staticLtrimStr"),
1497+
field("strWhitespace").ltrim().alias("instLtrim"),
1498+
Expression.ltrimValue(constant("xxxtrimMe"), "x").alias("staticLtrimValueExprPrim"),
1499+
Expression.ltrimValue(constant("xxxtrimMe"), constant("x"))
1500+
.alias("staticLtrimValueExprExpr"),
1501+
Expression.ltrimValue("strChars", "x").alias("staticLtrimValueStrPrim"),
1502+
Expression.ltrimValue("strChars", field("chars")).alias("staticLtrimValueStrExpr"),
1503+
field("strChars").ltrimValue("x").alias("instLtrimValuePrim"),
1504+
field("strChars").ltrimValue(field("chars")).alias("instLtrimValueExpr"))
1505+
.execute();
1506+
1507+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1508+
assertThat(result.get("staticLtrimExpr")).isEqualTo("trimMe ");
1509+
assertThat(result.get("staticLtrimStr")).isEqualTo("trimMe ");
1510+
assertThat(result.get("instLtrim")).isEqualTo("trimMe ");
1511+
1512+
assertThat(result.get("staticLtrimValueExprPrim")).isEqualTo("trimMe");
1513+
assertThat(result.get("staticLtrimValueExprExpr")).isEqualTo("trimMe");
1514+
assertThat(result.get("staticLtrimValueStrPrim")).isEqualTo("trimMe");
1515+
assertThat(result.get("staticLtrimValueStrExpr")).isEqualTo("trimMe");
1516+
assertThat(result.get("instLtrimValuePrim")).isEqualTo("trimMe");
1517+
assertThat(result.get("instLtrimValueExpr")).isEqualTo("trimMe");
1518+
}
1519+
1520+
@Test
1521+
public void testRTrim() {
1522+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1523+
1524+
Task<Pipeline.Snapshot> execute =
1525+
firestore
1526+
.pipeline()
1527+
.collection(randomCol)
1528+
.limit(1)
1529+
.replaceWith(
1530+
map(
1531+
ImmutableMap.of(
1532+
"strWhitespace", " trimMe ", "strChars", "trimMexxx", "chars", "x")))
1533+
.select(
1534+
Expression.rtrim(constant(" trimMe ")).alias("staticRtrimExpr"),
1535+
Expression.rtrim("strWhitespace").alias("staticRtrimStr"),
1536+
field("strWhitespace").rtrim().alias("instRtrim"),
1537+
Expression.rtrimValue(constant("trimMexxx"), "x").alias("staticRtrimValueExprPrim"),
1538+
Expression.rtrimValue(constant("trimMexxx"), constant("x"))
1539+
.alias("staticRtrimValueExprExpr"),
1540+
Expression.rtrimValue("strChars", "x").alias("staticRtrimValueStrPrim"),
1541+
Expression.rtrimValue("strChars", field("chars")).alias("staticRtrimValueStrExpr"),
1542+
field("strChars").rtrimValue("x").alias("instRtrimValuePrim"),
1543+
field("strChars").rtrimValue(field("chars")).alias("instRtrimValueExpr"))
1544+
.execute();
1545+
1546+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1547+
assertThat(result.get("staticRtrimExpr")).isEqualTo(" trimMe");
1548+
assertThat(result.get("staticRtrimStr")).isEqualTo(" trimMe");
1549+
assertThat(result.get("instRtrim")).isEqualTo(" trimMe");
1550+
1551+
assertThat(result.get("staticRtrimValueExprPrim")).isEqualTo("trimMe");
1552+
assertThat(result.get("staticRtrimValueExprExpr")).isEqualTo("trimMe");
1553+
assertThat(result.get("staticRtrimValueStrPrim")).isEqualTo("trimMe");
1554+
assertThat(result.get("staticRtrimValueStrExpr")).isEqualTo("trimMe");
1555+
assertThat(result.get("instRtrimValuePrim")).isEqualTo("trimMe");
1556+
assertThat(result.get("instRtrimValueExpr")).isEqualTo("trimMe");
1557+
}
1558+
1559+
@Test
1560+
public void testStringRepeat() {
1561+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1562+
1563+
Task<Pipeline.Snapshot> execute =
1564+
firestore
1565+
.pipeline()
1566+
.collection(randomCol)
1567+
.limit(1)
1568+
.replaceWith(map(ImmutableMap.of("str", "ha", "count", 3)))
1569+
.select(
1570+
Expression.stringRepeat(constant("ha"), 3).alias("staticExprPrim"),
1571+
Expression.stringRepeat(constant("ha"), constant(3)).alias("staticExprExpr"),
1572+
Expression.stringRepeat("str", 3).alias("staticStrPrim"),
1573+
Expression.stringRepeat("str", field("count")).alias("staticStrExpr"),
1574+
field("str").stringRepeat(3).alias("instPrim"),
1575+
field("str").stringRepeat(field("count")).alias("instExpr"))
1576+
.execute();
1577+
1578+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1579+
assertThat(result.get("staticExprPrim")).isEqualTo("hahaha");
1580+
assertThat(result.get("staticExprExpr")).isEqualTo("hahaha");
1581+
assertThat(result.get("staticStrPrim")).isEqualTo("hahaha");
1582+
assertThat(result.get("staticStrExpr")).isEqualTo("hahaha");
1583+
assertThat(result.get("instPrim")).isEqualTo("hahaha");
1584+
assertThat(result.get("instExpr")).isEqualTo("hahaha");
1585+
}
1586+
1587+
@Test
1588+
public void testStringReplaceAll() {
1589+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1590+
1591+
Task<Pipeline.Snapshot> execute =
1592+
firestore
1593+
.pipeline()
1594+
.collection(randomCol)
1595+
.limit(1)
1596+
.replaceWith(map(ImmutableMap.of("str", "hello world", "old", "o", "new", "a")))
1597+
.select(
1598+
Expression.stringReplaceAll(constant("hello world"), "o", "a")
1599+
.alias("staticExprPrim"),
1600+
Expression.stringReplaceAll(constant("hello world"), constant("o"), constant("a"))
1601+
.alias("staticExprExpr"),
1602+
Expression.stringReplaceAll("str", "o", "a").alias("staticStrPrim"),
1603+
Expression.stringReplaceAll("str", field("old"), field("new"))
1604+
.alias("staticStrExpr"),
1605+
field("str").stringReplaceAll("o", "a").alias("instPrim"),
1606+
field("str").stringReplaceAll(field("old"), field("new")).alias("instExpr"))
1607+
.execute();
1608+
1609+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1610+
assertThat(result.get("staticExprPrim")).isEqualTo("hella warld");
1611+
assertThat(result.get("staticExprExpr")).isEqualTo("hella warld");
1612+
assertThat(result.get("staticStrPrim")).isEqualTo("hella warld");
1613+
assertThat(result.get("staticStrExpr")).isEqualTo("hella warld");
1614+
assertThat(result.get("instPrim")).isEqualTo("hella warld");
1615+
assertThat(result.get("instExpr")).isEqualTo("hella warld");
1616+
}
1617+
1618+
@Test
1619+
public void testStringReplaceOne() {
1620+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1621+
1622+
Task<Pipeline.Snapshot> execute =
1623+
firestore
1624+
.pipeline()
1625+
.collection(randomCol)
1626+
.limit(1)
1627+
.replaceWith(map(ImmutableMap.of("str", "hello world", "old", "o", "new", "a")))
1628+
.select(
1629+
Expression.stringReplaceOne(constant("hello world"), "o", "a")
1630+
.alias("staticExprPrim"),
1631+
Expression.stringReplaceOne(constant("hello world"), constant("o"), constant("a"))
1632+
.alias("staticExprExpr"),
1633+
Expression.stringReplaceOne("str", "o", "a").alias("staticStrPrim"),
1634+
Expression.stringReplaceOne("str", field("old"), field("new"))
1635+
.alias("staticStrExpr"),
1636+
field("str").stringReplaceOne("o", "a").alias("instPrim"),
1637+
field("str").stringReplaceOne(field("old"), field("new")).alias("instExpr"))
1638+
.execute();
1639+
1640+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1641+
assertThat(result.get("staticExprPrim")).isEqualTo("hella world");
1642+
assertThat(result.get("staticExprExpr")).isEqualTo("hella world");
1643+
assertThat(result.get("staticStrPrim")).isEqualTo("hella world");
1644+
assertThat(result.get("staticStrExpr")).isEqualTo("hella world");
1645+
assertThat(result.get("instPrim")).isEqualTo("hella world");
1646+
assertThat(result.get("instExpr")).isEqualTo("hella world");
1647+
}
1648+
1649+
@Test
1650+
public void testStringIndexOf() {
1651+
assumeFalse("Not implemented.", isRunningAgainstEmulator());
1652+
1653+
Task<Pipeline.Snapshot> execute =
1654+
firestore
1655+
.pipeline()
1656+
.collection(randomCol)
1657+
.limit(1)
1658+
.replaceWith(map(ImmutableMap.of("str", "hello world", "sub", "world")))
1659+
.select(
1660+
Expression.stringIndexOf(constant("hello world"), "world").alias("staticExprPrim"),
1661+
Expression.stringIndexOf(constant("hello world"), constant("world"))
1662+
.alias("staticExprExpr"),
1663+
Expression.stringIndexOf("str", "world").alias("staticStrPrim"),
1664+
Expression.stringIndexOf("str", field("sub")).alias("staticStrExpr"),
1665+
field("str").stringIndexOf("world").alias("instPrim"),
1666+
field("str").stringIndexOf(field("sub")).alias("instExpr"))
1667+
.execute();
1668+
1669+
Map<String, Object> result = waitFor(execute).getResults().get(0).getData();
1670+
assertThat(result.get("staticExprPrim")).isEqualTo(6L);
1671+
assertThat(result.get("staticExprExpr")).isEqualTo(6L);
1672+
assertThat(result.get("staticStrPrim")).isEqualTo(6L);
1673+
assertThat(result.get("staticStrExpr")).isEqualTo(6L);
1674+
assertThat(result.get("instPrim")).isEqualTo(6L);
1675+
assertThat(result.get("instExpr")).isEqualTo(6L);
1676+
}
1677+
14811678
@Test
14821679
public void testLike() {
14831680
assumeFalse("Regexes are not supported against the emulator.", isRunningAgainstEmulator());

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/FunctionRegistry.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ internal object FunctionRegistry {
4545
"is_not_nan" to evaluateIsNotNaN,
4646
"is_null" to evaluateIsNull,
4747
"is_not_null" to evaluateIsNotNull,
48-
"replace_first" to evaluateReplaceFirst,
49-
"replace_all" to evaluateReplaceAll,
5048
"char_length" to evaluateCharLength,
5149
"byte_length" to evaluateByteLength,
5250
"like" to evaluateLike,
@@ -116,9 +114,14 @@ internal object FunctionRegistry {
116114
"cosine_distance" to notImplemented,
117115
"dot_product" to notImplemented,
118116
"timestamp_trunc" to notImplemented,
119-
"split" to evaluateSplit,
117+
"substring" to notImplemented,
118+
"string_repeat" to notImplemented,
119+
"string_replace_all" to notImplemented,
120+
"string_replace_one" to notImplemented,
121+
"string_index_of" to notImplemented,
122+
"ltrim" to notImplemented,
123+
"rtrim" to notImplemented,
124+
"split" to notImplemented,
120125
"substring" to evaluateSubstring,
121-
"ltrim" to evaluateLTrim,
122-
"rtrim" to evaluateRTrim
123126
)
124127
}

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/evaluation/Strings.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,6 @@ internal val evaluateTrim = unaryFunction { value: Value ->
269269
}
270270
}
271271

272-
internal val evaluateLTrim = notImplemented // TODO: Does not exist in expressions.kt yet.
273-
274-
internal val evaluateRTrim = notImplemented // TODO: Does not exist in expressions.kt yet.
275-
276-
internal val evaluateReplaceAll = notImplemented // TODO: Does not exist in backend yet.
277-
278-
internal val evaluateReplaceFirst = notImplemented // TODO: Does not exist in backend yet.
279-
280272
internal val evaluateRegexContains =
281273
binaryFunctionConstructorType(
282274
ValueTypeCase.STRING_VALUE,

0 commit comments

Comments
 (0)