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
2 changes: 1 addition & 1 deletion docs/dev/ppl-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ If you are working on contributing a new PPL command, please read this guide and
- Add a test in `PPLQueryDataAnonymizerTest`

- [ ] **Cross-cluster Tests (optional, nice to have):**
- Add a test in `CrossClusterSearchIT`
- Add a test in `CrossClusterSearchIT`, or in `CalciteCrossClusterSearchIT` if the command requires Calcite.

- [ ] **User doc:**
- Add a xxx.md under `docs/user/ppl/cmd` and link the new doc to `docs/user/ppl/index.md`
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,74 @@ public void testCrossClusterRexWithOffsetField() throws IOException {
verifyDataRows(
result, rows("Duke Willmington", "u", "vowel=1-1"), rows("Bond", "o", "vowel=1-1"));
}

@Test
public void testCrossClusterAddTotals() throws IOException {
JSONObject result =
executeQuery(
String.format(
"search source=%s| sort 1 age | fields firstname, age | addtotals age",
TEST_INDEX_BANK_REMOTE));
verifyDataRows(result, rows("Nanette", 28, 28));
}

/** CrossClusterSearchIT Test for addcoltotals. */
@Test
public void testCrossClusterAddColTotals() throws IOException {
JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname ='Nanette'|fields"
+ " firstname,age,balance | addcoltotals age balance",
TEST_INDEX_BANK_REMOTE));
verifyDataRows(
result, rows("Hattie", 36, 5686), rows("Nanette", 28, 32838), rows(null, 64, 38524));
}

@Test
public void testCrossClusterTranspose() throws IOException {
JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname ='Nanette' or"
+ " firstname='Dale'|sort firstname desc |fields firstname,age,balance |"
+ " transpose 3 column_name='column_names'",
TEST_INDEX_BANK_REMOTE));

verifyDataRows(
result,
rows("firstname", "Nanette", "Hattie", "Dale"),
rows("balance", "32838", "5686", "4180"),
rows("age", "28", "36", "33"));
}

@Test
public void testCrossClusterAppend() throws IOException {
JSONObject result =
executeQuery(
String.format(
"search source=%s | stats count() as cnt by gender | append [ search source=%s |"
+ " stats count() as cnt ]",
TEST_INDEX_BANK_REMOTE, TEST_INDEX_BANK_REMOTE));
verifyDataRows(result, rows(3, "F"), rows(4, "M"), rows(7, null));
}

/** CrossClusterSearchIT Test for mvcombine. */
@Test
public void testCrossClusterMvcombine() throws IOException {

JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname='Nanette' "
+ "| fields firstname, age | mvcombine age",
TEST_INDEX_BANK_REMOTE));

verifyColumn(result, columnName("firstname"), columnName("age"));

verifyDataRows(
result,
rows("Hattie", new org.json.JSONArray().put(36)),
rows("Nanette", new org.json.JSONArray().put(28)));
}
Comment on lines +353 to +421
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add null/invalid/boundary coverage (or point to existing coverage) for these new Calcite cross-cluster tests.
These additions are happy-path only. Please add null/invalid/boundary cases for addtotals/addcoltotals/transpose/append/mvcombine and ensure multi-document coverage where the command is per-document, or link to existing tests that already cover these scenarios.

As per coding guidelines: “NULL input tests must be included for all new functions”, “Include boundary condition tests (min/max values, empty inputs) for all new functions”, “Include error condition tests (invalid inputs, exceptions) for all new functions”, and “Include multi-document tests for per-document operations”.

🤖 Prompt for AI Agents
In
`@integ-test/src/test/java/org/opensearch/sql/security/CalciteCrossClusterSearchIT.java`
around lines 353 - 421, Add null/invalid/boundary and multi-document coverage
for the new cross-cluster Calcite tests by extending the existing test methods
(or adding new tests) for testCrossClusterAddTotals,
testCrossClusterAddColTotals, testCrossClusterTranspose, testCrossClusterAppend,
and testCrossClusterMvcombine: include cases with null field values, empty
result sets, out-of-range/boundary numeric values, and malformed/invalid input
strings; verify results using the same helpers (verifyDataRows, verifyColumn,
rows, columnName) and add multi-document scenarios where the operator is
per-document (e.g., multiple docs with/without target field) and negative tests
asserting proper error messages or empty outputs for invalid inputs. Ensure each
new test asserts NULL handling, boundary numeric sums/concats, and at least one
multi-document aggregation scenario for each operator.

}
Original file line number Diff line number Diff line change
Expand Up @@ -246,78 +246,4 @@ public void testCrossClusterQueryStringWithoutFields() throws IOException {
TEST_INDEX_BANK_REMOTE));
verifyDataRows(result, rows("Hattie"));
}

@Test
public void testCrossClusterAddTotals() throws IOException {
// Test query_string without fields parameter on remote cluster
JSONObject result =
executeQuery(
String.format(
"search source=%s| sort 1 age | fields firstname, age | addtotals age",
TEST_INDEX_BANK_REMOTE));
verifyDataRows(result, rows("Nanette", 28, 28));
}

/** CrossClusterSearchIT Test for addcoltotals. */
@Test
public void testCrossClusterAddColTotals() throws IOException {
// Test query_string without fields parameter on remote cluster
JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname ='Nanette'|fields"
+ " firstname,age,balance | addcoltotals age balance",
TEST_INDEX_BANK_REMOTE));
verifyDataRows(
result, rows("Hattie", 36, 5686), rows("Nanette", 28, 32838), rows(null, 64, 38524));
}

@Test
public void testCrossClusterTranspose() throws IOException {
// Test query_string without fields parameter on remote cluster
JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname ='Nanette' or"
+ " firstname='Dale'|sort firstname desc |fields firstname,age,balance |"
+ " transpose 3 column_name='column_names'",
TEST_INDEX_BANK_REMOTE));

verifyDataRows(
result,
rows("firstname", "Nanette", "Hattie", "Dale"),
rows("balance", "32838", "5686", "4180"),
rows("age", "28", "36", "33"));
}

@Test
public void testCrossClusterAppend() throws IOException {
// TODO: We should enable calcite by default in CrossClusterSearchIT?
JSONObject result =
executeQuery(
String.format(
"search source=%s | stats count() as cnt by gender | append [ search source=%s |"
+ " stats count() as cnt ]",
TEST_INDEX_BANK_REMOTE, TEST_INDEX_BANK_REMOTE));
verifyDataRows(result, rows(3, "F"), rows(4, "M"), rows(7, null));
}

/** CrossClusterSearchIT Test for mvcombine. */
@Test
public void testCrossClusterMvcombine() throws IOException {

JSONObject result =
executeQuery(
String.format(
"search source=%s | where firstname='Hattie' or firstname='Nanette' "
+ "| fields firstname, age | mvcombine age",
TEST_INDEX_BANK_REMOTE));

verifyColumn(result, columnName("firstname"), columnName("age"));

verifyDataRows(
result,
rows("Hattie", new org.json.JSONArray().put(36)),
rows("Nanette", new org.json.JSONArray().put(28)));
}
}
Loading