bhabegger commented on code in PR #3139:
URL: https://github.com/apache/jackrabbit-oak/pull/3139#discussion_r4193129388
##########
oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java:
##########
@@ -168,13 +169,194 @@ public void testCoalesce() throws ParseException {
.convert("//*[fn:coalesce(fn:coalesce(j:c/@a, b),
fn:coalesce(c, c:d)) = 'a']"));
}
+ @Test
+ public void testCoalesceWithStringLiteral() throws ParseException {
+ // a literal is a valid dynamic operand anywhere, not just for op()
+ Query q = p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a],
'default')='default'");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where coalesce([nt:base].[a], 'default') = 'default'",
q.toString());
+ q = p.parse("SELECT * FROM [nt:base] WHERE COALESCE('default',
[a])='default'");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where coalesce('default', [nt:base].[a]) = 'default'",
q.toString());
+ }
+
+ @Test
+ public void testTypedLiteral() throws ParseException {
+ // the function token is the same as the one FunctionIndexProcessor
creates
+ Query q = p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a],
'lon:0') > 1");
+ assertTrue(q.toString(),
q.toString().contains("coalesce([nt:base].[a], 'lon:0')"));
+ }
+
+ @Test(expected = ParseException.class)
+ public void testNumberLiteralNotSupported() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a], 0) > 1");
+ }
+
+ @Test(expected = ParseException.class)
+ public void testSignedNumberLiteralNotSupported() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a], +0) > 1");
+ }
+
+ @Test(expected = ParseException.class)
+ public void testInvalidTypedLiteral() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a], 'lon:abc') > 1");
+ }
+
+ @Test
+ public void testCoalesceWithEscapedQuoteLiteral() throws ParseException {
+ // a single quote within a literal is escaped as two single quotes;
+ // the resulting function-restriction token must round-trip with the
+ // same escaping FunctionIndexProcessor uses, since index-restriction
+ // matching relies on exact string equality between the two
+ Query query = p.parse("SELECT * FROM [nt:base] WHERE COALESCE([a],
'it''s a test')='x'");
+ assertTrue("expected the literal's escaping to be preserved, got: " +
query,
+ query.toString().contains("'it''s a test'"));
+ }
+
@Test
public void testFirst() throws ParseException {
p.parse("SELECT * FROM [nt:base] WHERE FIRST([d:t])='a'");
p.parse("SELECT * FROM [nt:base] WHERE FIRST([jcr:mixinTypes])='a'");
}
+ @Test
+ public void testIf() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE IF([cond], [a], [b])='x'");
+
+ p.parse("SELECT * FROM [nt:base] WHERE IF(EXISTS([alias]), PATH(),
null)='x'");
+
+ p.parse("SELECT * FROM [nt:base] WHERE IF([cond], IF([cond2], [a],
[b]), [c])='x'");
+
+ // XPath uses the "jcr:" prefix
+ p.parse(new XPathToSQL2Converter()
+ .convert("//*[jcr:if(@cond, @a, @b) = 'x']"));
+
+ p.parse(new XPathToSQL2Converter()
+ .convert("//*[jcr:if(jcr:exists(@alias), fn:path(), @b) =
'x']"));
+
+ // jcr:null() is the XPath spelling of the "null" literal
+ String sql2 = new XPathToSQL2Converter()
+ .convert("//*[jcr:if(jcr:exists(@alias), fn:path(),
jcr:null()) = 'x']");
+ assertTrue("expected a bare null literal, got: " + sql2,
+ sql2.contains("null)") && !sql2.contains("[null]"));
+ p.parse(sql2);
+ }
+
+ @Test(expected = ParseException.class)
+ public void ifFailsWithTwoParams() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE IF([cond], [a])='x'");
+ }
+
+ @Test
+ public void testExists() throws ParseException {
+ Query q = p.parse("SELECT * FROM [nt:base] WHERE
EXISTS([alias])=true");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where exists([nt:base].[alias]) = cast('true' as boolean)",
q.toString());
+
+ q = p.parse("SELECT * FROM [nt:base] WHERE
EXISTS(UPPER([alias]))=true");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where exists(upper([nt:base].[alias])) = cast('true' as
boolean)", q.toString());
+
+ // XPath uses the "jcr:" prefix
+ q = p.parse(new XPathToSQL2Converter()
+ .convert("//*[jcr:exists(@alias) = true()]"));
+ assertEquals("select [a].[jcr:path] as [jcr:path], [a].[jcr:score] as
[jcr:score], [a].[jcr:primaryType] as [a.jcr:primaryType] " +
+ "from [nt:base] as [a] " +
+ "where exists([a].[alias]) = cast('true' as boolean)",
q.toString());
+ }
+
+ @Test(expected = ParseException.class)
+ public void existsFailsWithNoParam() throws ParseException {
+ p.parse("SELECT * FROM [nt:base] WHERE EXISTS()=true");
+ }
+
+ @Test(expected = ParseException.class)
+ public void opFailsWhenDisabledByDefault() throws ParseException {
+ // the op(a, operator, b) function is disabled by default
+ p.parse("SELECT * FROM [nt:base] WHERE OP([a], '+', [b])=3");
+ }
+
+ @Test(expected = ParseException.class)
+ public void opXPathFailsWhenDisabledByDefault() throws ParseException {
+ // the XPath -> SQL-2 conversion itself always succeeds (it's purely
+ // syntactic); the toggle is enforced when the resulting SQL-2 is
parsed
+ p.parse(new XPathToSQL2Converter()
+ .convert("//*[jcr:op(@a, '+', @b) = 3]"));
+ }
+
+ @Test
+ public void testOpWhenEnabled() throws ParseException {
+ SQL2Parser opParser =
createTestSQL2Parser(createSettingsWithOpEnabled());
+
+ Query q = opParser.parse("SELECT * FROM [nt:base] WHERE OP([a], '+',
[b])=3");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where op([nt:base].[a], '+', [nt:base].[b]) = 3",
q.toString());
+ opParser.parse("SELECT * FROM [nt:base] WHERE OP([a], '=', [b])=true");
+ assertEquals("select [nt:base].[jcr:primaryType] as
[nt:base.jcr:primaryType] " +
+ "from [nt:base] as [nt:base] " +
+ "where op([nt:base].[a], '+', [nt:base].[b]) = 3",
q.toString());
Review Comment:
Here we are asserting on '+' and just rechecking the first query not the one
parsed just above.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]