Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ public void simpleGroupByOrdinal() {
String expected =
executeQuery(
StringUtils.format(
"SELECT lastname FROM %s AS b GROUP BY lastname LIMIT 3",
"SELECT lastname FROM %s AS b GROUP BY lastname ORDER BY lastname LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
String actual =
executeQuery(
StringUtils.format(
"SELECT lastname FROM %s AS b GROUP BY 1 LIMIT 3",
"SELECT lastname FROM %s AS b GROUP BY 1 ORDER BY 1 LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
assertThat(actual, equalTo(expected));
Expand All @@ -43,13 +43,14 @@ public void multipleGroupByOrdinal() {
executeQuery(
StringUtils.format(
"SELECT lastname, firstname, age FROM %s AS b GROUP BY firstname, age, lastname"
+ " LIMIT 3",
+ " ORDER BY lastname, firstname, age LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
String actual =
executeQuery(
StringUtils.format(
"SELECT lastname, firstname, age FROM %s AS b GROUP BY 2, 3, 1 LIMIT 3",
"SELECT lastname, firstname, age FROM %s AS b GROUP BY 2, 3, 1"
+ " ORDER BY 1, 2, 3 LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
assertThat(actual, equalTo(expected));
Expand All @@ -60,13 +61,13 @@ public void selectFieldiWithBacticksGroupByOrdinal() {
String expected =
executeQuery(
StringUtils.format(
"SELECT `lastname` FROM %s AS b GROUP BY `lastname` LIMIT 3",
"SELECT `lastname` FROM %s AS b GROUP BY `lastname` ORDER BY `lastname` LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
String actual =
executeQuery(
StringUtils.format(
"SELECT `lastname` FROM %s AS b GROUP BY 1 LIMIT 3",
"SELECT `lastname` FROM %s AS b GROUP BY 1 ORDER BY 1 LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
assertThat(actual, equalTo(expected));
Expand All @@ -78,13 +79,14 @@ public void selectFieldiWithBacticksAndTableAliasGroupByOrdinal() {
executeQuery(
StringUtils.format(
"SELECT `b`.`lastname`, `age`, firstname FROM %s AS b GROUP BY `age`,"
+ " `b`.`lastname` , firstname LIMIT 10",
+ " `b`.`lastname` , firstname ORDER BY `b`.`lastname`, `age` LIMIT 10",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
String actual =
executeQuery(
StringUtils.format(
"SELECT `b`.`lastname`, `age`, firstname FROM %s AS b GROUP BY 2, 1, 3 LIMIT 10",
"SELECT `b`.`lastname`, `age`, firstname FROM %s AS b GROUP BY 2, 1, 3 ORDER BY 1,"
+ " 2 LIMIT 10",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
assertThat(actual, equalTo(expected));
Expand Down Expand Up @@ -166,14 +168,14 @@ public void selectFieldiWithBacticksAndTableAliasOrderByOrdinalAndNull() {
executeQuery(
StringUtils.format(
"SELECT `b`.`lastname`, age FROM %s AS b ORDER BY `b`.`lastname` IS NOT NULL DESC,"
+ " age is NULL LIMIT 3",
+ " age is NULL, `b`.`lastname` LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
String actual =
executeQuery(
StringUtils.format(
"SELECT `b`.`lastname`, age FROM %s AS b ORDER BY 1 IS NOT NULL DESC, 2 IS NULL"
+ " LIMIT 3",
"SELECT `b`.`lastname`, age FROM %s AS b ORDER BY 1 IS NOT NULL DESC, 2 IS NULL,"
+ " 1 LIMIT 3",
TestsConstants.TEST_INDEX_ACCOUNT),
"jdbc");
assertThat(actual, equalTo(expected));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ protected void init() throws Exception {
loadIndex(Index.ACCOUNT);
loadIndex(Index.PHRASE);
loadIndex(Index.GAME_OF_THRONES);
loadIndex(Index.NESTED);
// Skip on the analytics-engine route, where the parquet store rejects nested_objects'
// multi-value array in the scalar-mapped myNum field at bulk load.
if (!TestUtils.AnalyticsIndexConfig.isEnabled()) {
loadIndex(Index.NESTED);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ public void testLengthWithTextFieldReturnsInt() {
public void testLengthWithGroupByExpr() {
JSONObject response =
executeJdbcRequest(
"SELECT Length(firstname) FROM "
"SELECT LENGTH(firstname) FROM "
+ TestsConstants.TEST_INDEX_ACCOUNT
+ " GROUP BY LENGTH(firstname) LIMIT 5");

verifySchema(response, schema("Length(firstname)", null, "integer"));
verifySchema(response, schema("LENGTH(firstname)", null, "integer"));
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,8 @@ public void init() throws Exception {
public void ifnullShouldPassJDBC() throws IOException {
JSONObject response =
executeJdbcRequest(
"SELECT IFNULL(lastname, 'unknown') AS name FROM "
+ TEST_INDEX_ACCOUNT
+ " GROUP BY name");
assertEquals("IFNULL(lastname, 'unknown')", response.query("/schema/0/name"));
assertEquals("name", response.query("/schema/0/alias"));
assertEquals("keyword", response.query("/schema/0/type"));
"SELECT IFNULL(lastname, 'unknown') FROM " + TEST_INDEX_ACCOUNT + " GROUP BY 1");
verifySchema(response, schema("IFNULL(lastname, 'unknown')", null, "keyword"));
}

@Test
Expand Down Expand Up @@ -109,9 +105,7 @@ public void ifnullWithMissingInputTest() {
public void nullifShouldPassJDBC() throws IOException {
JSONObject response =
executeJdbcRequest("SELECT NULLIF(lastname, 'unknown') AS name FROM " + TEST_INDEX_ACCOUNT);
assertEquals("NULLIF(lastname, 'unknown')", response.query("/schema/0/name"));
assertEquals("name", response.query("/schema/0/alias"));
assertEquals("keyword", response.query("/schema/0/type"));
verifySchema(response, schema("NULLIF(lastname, 'unknown')", "name", "keyword"));
}

@Test
Expand Down Expand Up @@ -152,9 +146,7 @@ public void nullifWithNullInputTest() {
public void isnullShouldPassJDBC() throws IOException {
JSONObject response =
executeJdbcRequest("SELECT ISNULL(lastname) AS name FROM " + TEST_INDEX_ACCOUNT);
assertEquals("ISNULL(lastname)", response.query("/schema/0/name"));
assertEquals("name", response.query("/schema/0/alias"));
assertEquals("boolean", response.query("/schema/0/type"));
verifySchema(response, schema("ISNULL(lastname)", "name", "boolean"));
}

@Ignore(
Expand Down Expand Up @@ -208,9 +200,7 @@ public void isnullWithMathExpr() throws IOException {
public void ifShouldPassJDBC() throws IOException {
JSONObject response =
executeJdbcRequest("SELECT IF(2 > 0, 'hello', 'world') AS name FROM " + TEST_INDEX_ACCOUNT);
assertEquals("IF(2 > 0, 'hello', 'world')", response.query("/schema/0/name"));
assertEquals("name", response.query("/schema/0/alias"));
assertEquals("keyword", response.query("/schema/0/type"));
verifySchema(response, schema("IF(2 > 0, 'hello', 'world')", "name", "keyword"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
Expand All @@ -39,6 +40,7 @@
import org.json.JSONObject;
import org.opensearch.search.SearchHit;
import org.opensearch.search.SearchHits;
import org.opensearch.sql.legacy.TestUtils;
import org.opensearch.sql.utils.YamlFormatter;

public class MatcherUtils {
Expand Down Expand Up @@ -275,6 +277,9 @@ public static TypeSafeMatcher<JSONObject> schema(String expectedName, String exp
public static TypeSafeMatcher<JSONObject> schema(
String expectedName, String expectedAlias, String expectedType) {
return new TypeSafeMatcher<JSONObject>() {
private static final Set<String> NUMERIC_TYPES = Set.of("integer", "long", "float", "double");
private static final Set<String> STRING_TYPES = Set.of("keyword", "text", "string");

@Override
public void describeTo(Description description) {
description.appendText(
Expand All @@ -287,10 +292,32 @@ protected boolean matchesSafely(JSONObject jsonObject) {
String actualName = (String) jsonObject.query("/name");
String actualAlias = (String) jsonObject.query("/alias");
String actualType = (String) jsonObject.query("/type");

if (TestUtils.AnalyticsIndexConfig.isEnabled()) {
// The analytics-engine route promotes the alias to the name (SQL-standard) and unifies
// keyword/text/string and the numeric types, so relax name and type matching for it only.
boolean nameMatches =
expectedName.equals(actualName)
|| (!Strings.isNullOrEmpty(expectedAlias) && expectedAlias.equals(actualName));
boolean typeMatches =
expectedType.equals(actualType) || isCompatibleType(expectedType, actualType);
return nameMatches && typeMatches;
}

return expectedName.equals(actualName)
&& (Strings.isNullOrEmpty(expectedAlias) || expectedAlias.equals(actualAlias))
&& expectedType.equals(actualType);
}

private boolean isCompatibleType(String expected, String actual) {
if (expected == null || actual == null) {
return false;
}
String e = expected.toLowerCase();
String a = actual.toLowerCase();
return (NUMERIC_TYPES.contains(e) && NUMERIC_TYPES.contains(a))
|| (STRING_TYPES.contains(e) && STRING_TYPES.contains(a));
}
};
}

Expand Down
14 changes: 7 additions & 7 deletions integ-test/src/test/resources/game_of_thrones_complex.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{"index":{"_id":"1"}}
{"name":{"firstname":"Daenerys","lastname":"Targaryen","ofHerName":1},"nickname":"Daenerys \"Stormborn\"","house":"Targaryen","gender":"F","parents":{"father":"Aerys" , "mother":"Rhaella"},"titles":["motherOfDragons","queenOfTheAndals","breakerOfChains","Khaleesi"]}
{"name": {"firstname": "Daenerys", "lastname": "Targaryen", "ofHerName": 1}, "nickname": "Daenerys \"Stormborn\"", "house": "Targaryen", "gender": "F", "parents": {"father": "Aerys", "mother": "Rhaella"}}
{"index":{"_id":"2"}}
{"name":{"firstname":"Eddard","lastname":"Stark","ofHisName":1},"house":"Stark", "parents":{"father":"Rickard" , "mother":"Lyarra"} ,"gender":"M","titles":["lordOfWinterfell","wardenOfTheNorth","handOfTheKing"]}
{"name": {"firstname": "Eddard", "lastname": "Stark", "ofHisName": 1}, "house": "Stark", "parents": {"father": "Rickard", "mother": "Lyarra"}, "gender": "M"}
{"index":{"_id":"3"}}
{"name":{"firstname":"Brandon","lastname":"Stark","ofHisName":4},"house":"Stark","parents":{"father":"Eddard","mother":"Catelyn"},"gender":"M","titles":["princeOfWinterfell"],"@wolf":"Summer"}
{"name": {"firstname": "Brandon", "lastname": "Stark", "ofHisName": 4}, "house": "Stark", "parents": {"father": "Eddard", "mother": "Catelyn"}, "gender": "M", "@wolf": "Summer"}
{"index":{"_id":"4"}}
{"name":{"firstname":"Jaime","lastname":"Lannister","ofHisName":1},"gender":"M","house":"Lannister","parents":{"father":"Tywin","mother":"Joanna"},"titles":["kingSlayer","lordCommanderOfTheKingsguard","Ser"]}
{"name": {"firstname": "Jaime", "lastname": "Lannister", "ofHisName": 1}, "gender": "M", "house": "Lannister", "parents": {"father": "Tywin", "mother": "Joanna"}}
{"index":{"_id":"5"}}
{"words":"fireAndBlood","hname":"Targaryen","sigil":"Dragon","seat":"Dragonstone"}
{"words": "fireAndBlood", "hname": "Targaryen", "sigil": "Dragon", "seat": "Dragonstone"}
{"index":{"_id":"6"}}
{"words":"winterIsComing" , "hname":"Stark","sigil":"direwolf","seat":"Winterfell"}
{"words": "winterIsComing", "hname": "Stark", "sigil": "direwolf", "seat": "Winterfell"}
{"index":{"_id":"7"}}
{"words":"hearMeRoar" , "hname":"Lannister","sigil":"lion","seat":"CasterlyRock"}
{"words": "hearMeRoar", "hname": "Lannister", "sigil": "lion", "seat": "CasterlyRock"}
Loading