From b5525e08c38d86cf7d939aa3615eefe1f468e37a Mon Sep 17 00:00:00 2001 From: Sam Sovereign <5209310+ldaIas@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:12:10 -0600 Subject: [PATCH 1/3] add collate parsing and tests for order by --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 + .../statement/select/OrderByCollateTest.java | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 35238b44e..970bb4fca 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -5152,9 +5152,11 @@ OrderByElement OrderByElement(): { OrderByElement orderByElement = new OrderByElement(); Expression columnReference = null; + Token collateToken = null; } { columnReference = Expression() + [ LOOKAHEAD() (collateToken= | collateToken=) { columnReference = new CollateExpression(columnReference, collateToken.image); } ] [ LOOKAHEAD(2) ( | ( { orderByElement.setAsc(false); } )) { orderByElement.setAscDescPresent(true); } ] [ LOOKAHEAD(2) [ LOOKAHEAD(2) ( diff --git a/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java b/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java new file mode 100644 index 000000000..cfab40e25 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java @@ -0,0 +1,56 @@ +package net.sf.jsqlparser.statement.select; + +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.expression.CollateExpression; +import org.junit.jupiter.api.Test; + +public class OrderByCollateTest { + + @Test + public void testOrderByWithCollate() throws JSQLParserException { + String sql = "SELECT * FROM a ORDER BY CAST(a.xyz AS TEXT) COLLATE \"und-x-icu\" ASC NULLS FIRST"; + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testOrderByWithCollateSimple() throws JSQLParserException { + String sql = "SELECT * FROM a ORDER BY col COLLATE \"C\" ASC"; + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testOrderByWithCollateMultiple() throws JSQLParserException { + String sql = "SELECT * FROM a ORDER BY col1 COLLATE \"C\" ASC, col2 COLLATE \"POSIX\" DESC"; + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testOrderByWithCollateAndNulls() throws JSQLParserException { + String sql = "SELECT * FROM a ORDER BY col COLLATE \"C\" DESC NULLS LAST"; + assertSqlCanBeParsedAndDeparsed(sql); + } + + @Test + public void testOrderByCollateStructure() throws JSQLParserException { + String sql = "SELECT * FROM a ORDER BY col COLLATE \"C\" ASC"; + Select select = (Select) CCJSqlParserUtil.parse(sql); + PlainSelect plainSelect = (PlainSelect) select; + + assertNotNull(plainSelect.getOrderByElements()); + assertEquals(1, plainSelect.getOrderByElements().size()); + + OrderByElement orderByElement = plainSelect.getOrderByElements().get(0); + assertNotNull(orderByElement.getExpression()); + + // The expression should be a CollateExpression + if (orderByElement.getExpression() instanceof CollateExpression) { + CollateExpression collateExpr = (CollateExpression) orderByElement.getExpression(); + assertEquals("\"C\"", collateExpr.getCollate()); + } + } +} \ No newline at end of file From 574518747e6941eb908de3a5a997b13506d604a3 Mon Sep 17 00:00:00 2001 From: Sam Sovereign <5209310+ldaIas@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:25:10 -0600 Subject: [PATCH 2/3] rm unnecessary test --- .../statement/select/OrderByCollateTest.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java b/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java index cfab40e25..6615ce5cc 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/OrderByCollateTest.java @@ -1,12 +1,8 @@ package net.sf.jsqlparser.statement.select; import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import net.sf.jsqlparser.JSQLParserException; -import net.sf.jsqlparser.parser.CCJSqlParserUtil; -import net.sf.jsqlparser.expression.CollateExpression; import org.junit.jupiter.api.Test; public class OrderByCollateTest { @@ -34,23 +30,4 @@ public void testOrderByWithCollateAndNulls() throws JSQLParserException { String sql = "SELECT * FROM a ORDER BY col COLLATE \"C\" DESC NULLS LAST"; assertSqlCanBeParsedAndDeparsed(sql); } - - @Test - public void testOrderByCollateStructure() throws JSQLParserException { - String sql = "SELECT * FROM a ORDER BY col COLLATE \"C\" ASC"; - Select select = (Select) CCJSqlParserUtil.parse(sql); - PlainSelect plainSelect = (PlainSelect) select; - - assertNotNull(plainSelect.getOrderByElements()); - assertEquals(1, plainSelect.getOrderByElements().size()); - - OrderByElement orderByElement = plainSelect.getOrderByElements().get(0); - assertNotNull(orderByElement.getExpression()); - - // The expression should be a CollateExpression - if (orderByElement.getExpression() instanceof CollateExpression) { - CollateExpression collateExpr = (CollateExpression) orderByElement.getExpression(); - assertEquals("\"C\"", collateExpr.getCollate()); - } - } } \ No newline at end of file From a3df3772a8d5a274ea203e67d58518504e918f15 Mon Sep 17 00:00:00 2001 From: Sam Sovereign <5209310+ldaIas@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:56:46 -0600 Subject: [PATCH 3/3] add quoted identifier for "und-x-icu" --- src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 970bb4fca..211187492 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -6453,7 +6453,7 @@ Expression PrimaryExpression() #PrimaryExpression: ) [ - LOOKAHEAD(2) token= { retval = new CollateExpression(retval, token.image); } + LOOKAHEAD(2) (token= | token= | token=) { retval = new CollateExpression(retval, token.image); } ] [