diff --git a/README.md b/README.md index adea97d..4e401f3 100644 --- a/README.md +++ b/README.md @@ -712,6 +712,12 @@ more results? (y/n): n # Change Log +## [1.22](https://github.com/vincentrussell/sql-to-mongo-db-query-converter/tree/sql-to-mongo-db-query-converter-1.21) (2024-04-09) + +**Bugs:** + +- Custom functions weren't being parsed correctly + ## [1.21](https://github.com/vincentrussell/sql-to-mongo-db-query-converter/tree/sql-to-mongo-db-query-converter-1.21) (2022-03-21) diff --git a/src/main/java/com/github/vincentrussell/query/mongodb/sql/converter/processor/WhereClauseProcessor.java b/src/main/java/com/github/vincentrussell/query/mongodb/sql/converter/processor/WhereClauseProcessor.java index 0fc6817..34115fd 100644 --- a/src/main/java/com/github/vincentrussell/query/mongodb/sql/converter/processor/WhereClauseProcessor.java +++ b/src/main/java/com/github/vincentrussell/query/mongodb/sql/converter/processor/WhereClauseProcessor.java @@ -95,8 +95,9 @@ private void parseComparativeExpr(final Document query, final Expression leftExp Document doc = new Document(); Object leftParse = parseExpression(new Document(), leftExpression, rightExpression); Object rightParse = parseExpression(new Document(), rightExpression, leftExpression); - doc.put(operator, Arrays.asList(leftParse, (SqlUtils.isColumn(rightExpression) - && !rightExpression.toString().startsWith("$") ? "$" + rightParse : rightParse))); + doc.put(operator, Arrays.asList(leftParse, ((SqlUtils.isColumn(rightExpression) + && !rightExpression.toString().startsWith("$") + && !Document.class.isInstance(leftParse)) ? "$" + rightParse : rightParse))); if (requiresMultistepAggregation) { query.put("$expr", doc); } else { @@ -117,10 +118,11 @@ private void parseComparativeExpr(final Document query, final Expression leftExp } } else if (Function.class.isInstance(rightExpression)) { Document doc = new Document(); - Object leftParse = parseExpression(new Document(), rightExpression, leftExpression); - Object rightParse = parseExpression(new Document(), leftExpression, rightExpression); - doc.put(operator, Arrays.asList(leftParse, (SqlUtils.isColumn(leftExpression) - && !leftExpression.toString().startsWith("$") ? "$" + rightParse : rightParse))); + Object leftParse = parseExpression(new Document(), leftExpression, rightExpression); + Object rightParse = parseExpression(new Document(), rightExpression, leftExpression); + doc.put(operator, Arrays.asList(leftParse, ((SqlUtils.isColumn(leftExpression) + && !leftExpression.toString().startsWith("$") + && !Document.class.isInstance(rightParse)) ? "$" + rightParse : rightParse))); if (requiresMultistepAggregation) { query.put("$expr", doc); } else { diff --git a/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterJoinTest.java b/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterJoinTest.java index db4a1a8..7e5565e 100644 --- a/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterJoinTest.java +++ b/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterJoinTest.java @@ -895,81 +895,81 @@ public void writeJoinWithAllCount() throws ParseException, IOException { QueryConverter queryConverter = new QueryConverter.Builder().sqlString("select count(*) from Table1 as t join Table2 as e on e._id = OID(t.Table1.eventId) where 1 = 1 AND t.Table1.eventId='111111' AND e.Table2.tid='2222222'").build(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); queryConverter.write(byteArrayOutputStream); - assertEquals("db.Table1.aggregate([{\n" + - " \"$match\": {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " 1,\n" + - " 1\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"Table1.eventId\": \"111111\"\n" + - " }\n" + - " ]\n" + - " }\n" + - "},{\n" + - " \"$lookup\": {\n" + - " \"from\": \"Table2\",\n" + - " \"let\": {\n" + - " \"table1_eventid\": \"$Table1.eventId\"\n" + - " },\n" + - " \"pipeline\": [\n" + - " {\n" + - " \"$match\": {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " {\n" + - " \"$toObjectId\": \"$$table1_eventid\"\n" + - " },\n" + - " \"$_id\"\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " 1,\n" + - " 1\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"Table2.tid\": \"2222222\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"as\": \"e\"\n" + - " }\n" + - "},{\n" + - " \"$unwind\": {\n" + - " \"path\": \"$e\",\n" + - " \"preserveNullAndEmptyArrays\": false\n" + - " }\n" + - "},{\n" + - " \"$group\": {\n" + - " \"_id\": {},\n" + - " \"count\": {\n" + - " \"$sum\": 1\n" + - " }\n" + - " }\n" + - "},{\n" + - " \"$project\": {\n" + - " \"count\": 1,\n" + - " \"_id\": 0\n" + - " }\n" + - "}])",byteArrayOutputStream.toString("UTF-8")); + assertEquals("db.Table1.aggregate([{\n" + + " \"$match\": {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " 1,\n" + + " 1\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"Table1.eventId\": \"111111\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "},{\n" + + " \"$lookup\": {\n" + + " \"from\": \"Table2\",\n" + + " \"let\": {\n" + + " \"table1_eventid\": \"$Table1.eventId\"\n" + + " },\n" + + " \"pipeline\": [\n" + + " {\n" + + " \"$match\": {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " \"$_id\",\n" + + " {\n" + + " \"$toObjectId\": \"$$table1_eventid\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " 1,\n" + + " 1\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"Table2.tid\": \"2222222\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"as\": \"e\"\n" + + " }\n" + + "},{\n" + + " \"$unwind\": {\n" + + " \"path\": \"$e\",\n" + + " \"preserveNullAndEmptyArrays\": false\n" + + " }\n" + + "},{\n" + + " \"$group\": {\n" + + " \"_id\": {},\n" + + " \"count\": {\n" + + " \"$sum\": 1\n" + + " }\n" + + " }\n" + + "},{\n" + + " \"$project\": {\n" + + " \"count\": 1,\n" + + " \"_id\": 0\n" + + " }\n" + + "}])",byteArrayOutputStream.toString("UTF-8")); } @Test @@ -977,81 +977,81 @@ public void writeJoinWithAllCountNestedDif() throws ParseException, IOException QueryConverter queryConverter = new QueryConverter.Builder().sqlString("select count(*) from Table1 as t join Table2 as e on e._id = OID(t.root1.eventId) where 1 = 1 AND t.root1.eventId='111111' AND e.root2.tid='2222222'").build(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); queryConverter.write(byteArrayOutputStream); - assertEquals("db.Table1.aggregate([{\n" + - " \"$match\": {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " 1,\n" + - " 1\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"root1.eventId\": \"111111\"\n" + - " }\n" + - " ]\n" + - " }\n" + - "},{\n" + - " \"$lookup\": {\n" + - " \"from\": \"Table2\",\n" + - " \"let\": {\n" + - " \"root1_eventid\": \"$root1.eventId\"\n" + - " },\n" + - " \"pipeline\": [\n" + - " {\n" + - " \"$match\": {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " {\n" + - " \"$toObjectId\": \"$$root1_eventid\"\n" + - " },\n" + - " \"$_id\"\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"$and\": [\n" + - " {\n" + - " \"$expr\": {\n" + - " \"$eq\": [\n" + - " 1,\n" + - " 1\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"root2.tid\": \"2222222\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"as\": \"e\"\n" + - " }\n" + - "},{\n" + - " \"$unwind\": {\n" + - " \"path\": \"$e\",\n" + - " \"preserveNullAndEmptyArrays\": false\n" + - " }\n" + - "},{\n" + - " \"$group\": {\n" + - " \"_id\": {},\n" + - " \"count\": {\n" + - " \"$sum\": 1\n" + - " }\n" + - " }\n" + - "},{\n" + - " \"$project\": {\n" + - " \"count\": 1,\n" + - " \"_id\": 0\n" + - " }\n" + - "}])",byteArrayOutputStream.toString("UTF-8")); + assertEquals("db.Table1.aggregate([{\n" + + " \"$match\": {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " 1,\n" + + " 1\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"root1.eventId\": \"111111\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "},{\n" + + " \"$lookup\": {\n" + + " \"from\": \"Table2\",\n" + + " \"let\": {\n" + + " \"root1_eventid\": \"$root1.eventId\"\n" + + " },\n" + + " \"pipeline\": [\n" + + " {\n" + + " \"$match\": {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " \"$_id\",\n" + + " {\n" + + " \"$toObjectId\": \"$$root1_eventid\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"$and\": [\n" + + " {\n" + + " \"$expr\": {\n" + + " \"$eq\": [\n" + + " 1,\n" + + " 1\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"root2.tid\": \"2222222\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"as\": \"e\"\n" + + " }\n" + + "},{\n" + + " \"$unwind\": {\n" + + " \"path\": \"$e\",\n" + + " \"preserveNullAndEmptyArrays\": false\n" + + " }\n" + + "},{\n" + + " \"$group\": {\n" + + " \"_id\": {},\n" + + " \"count\": {\n" + + " \"$sum\": 1\n" + + " }\n" + + " }\n" + + "},{\n" + + " \"$project\": {\n" + + " \"count\": 1,\n" + + " \"_id\": 0\n" + + " }\n" + + "}])",byteArrayOutputStream.toString("UTF-8")); } diff --git a/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterTest.java b/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterTest.java index 14a5236..4bf9819 100644 --- a/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterTest.java +++ b/src/test/java/com/github/vincentrussell/query/mongodb/sql/converter/QueryConverterTest.java @@ -96,6 +96,27 @@ public void betweenWithDates() throws ParseException, java.text.ParseException { assertEquals(documentValuesArray("$and", document("date", document("$gte", toDate("yyyy-MM-dd", "2012-12-01"))), document("date", document("$lte", toDate("yyyy-MM-dd", "2012-12-02")))), mongoDBQueryHolder.getQuery()); } + + @Test + public void functionsStayOnSameSideOfOperandLeftSide() throws ParseException { + QueryConverter queryConverter = new QueryConverter.Builder().sqlString("select * from table where beginningOfMonth(-1) < eventTime").build(); + MongoDBQueryHolder mongoDBQueryHolder = queryConverter.getMongoQuery(); + assertEquals(document("$lt", objsToList(document("$beginningOfMonth", Long.parseLong("-1")), "eventTime")), mongoDBQueryHolder.getQuery()); + } + + @Test + public void functionsStayOnSameSideOfOperandRightSide() throws ParseException { + QueryConverter queryConverter = new QueryConverter.Builder().sqlString("select * from table where eventTime > beginningOfMonth(-1)").build(); + MongoDBQueryHolder mongoDBQueryHolder = queryConverter.getMongoQuery(); + assertEquals(document("$gt", objsToList("eventTime", document("$beginningOfMonth", Long.parseLong("-1")))), mongoDBQueryHolder.getQuery()); + } + + @Test + public void functionsOnBothSide() throws ParseException { + QueryConverter queryConverter = new QueryConverter.Builder().sqlString("select * from table where beginningOfMonth(-1) > beginningOfMonth(-1)").build(); + MongoDBQueryHolder mongoDBQueryHolder = queryConverter.getMongoQuery(); + assertEquals(document("$gt", objsToList(document("$beginningOfMonth", Long.parseLong("-1")), document("$beginningOfMonth", Long.parseLong("-1")))), mongoDBQueryHolder.getQuery()); + } @Test public void selectFieldSurroundedInQuotesInFunctions() throws ParseException {