Skip to content
6 changes: 5 additions & 1 deletion docs/user/ppl/cmd/head.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ head
:local:
:depth: 2

.. versionadded:: 1.0.0
.. versionchanged:: 3.3.0
Added support for the `limit=` argument name.

Description
============
Expand All @@ -16,9 +19,10 @@ Description

Syntax
============
head [<size>] [from <offset>]
head [limit=][<size>] [from <offset>]

* <size>: optional integer. number of results to return. **Default:** 10
* For readability or convenience, this can be prefixed by `limit=`.
* <offset>: integer after optional ``from``. number of results to skip. **Default:** 0

Example 1: Get first 10 results
Expand Down
6 changes: 5 additions & 1 deletion docs/user/ppl/cmd/top.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ top
:local:
:depth: 2

.. versionadded:: 1.0.0
.. versionchanged:: 3.3.0
Added support for the `limit=` argument name.

Description
============
Expand All @@ -18,9 +21,10 @@ Syntax
============
top [N] <field-list> [by-clause]

top [N] <field-list> [top-options] [by-clause] ``(available from 3.1.0+)``
top [limit=][N] <field-list> [top-options] [by-clause] ``(available from 3.1.0+)``

* N: number of results to return. **Default**: 10
* For readability or convenience, this can be prefixed by `limit=`.
* field-list: mandatory. comma-delimited list of field names.
* by-clause: optional. one or more fields to group the results by.
* top-options: optional. options for the top command. Supported syntax is [countfield=<string>] [showcount=<bool>].
Expand Down
7 changes: 4 additions & 3 deletions ppl/src/main/antlr/OpenSearchPPLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ evalCommand
;

headCommand
: HEAD (number = integerLiteral)? (FROM from = integerLiteral)?
: HEAD ((LIMIT EQUAL)? number = integerLiteral)? (FROM from = integerLiteral)?
;

binCommand
Expand Down Expand Up @@ -302,11 +302,11 @@ logSpanValue
;

topCommand
: TOP (number = integerLiteral)? (COUNTFIELD EQUAL countfield = stringLiteral)? (SHOWCOUNT EQUAL showcount = booleanLiteral)? fieldList (byClause)?
: TOP ((LIMIT EQUAL)? number = integerLiteral)? (COUNTFIELD EQUAL countfield = stringLiteral)? (SHOWCOUNT EQUAL showcount = booleanLiteral)? fieldList (byClause)?
;

rareCommand
: RARE (number = integerLiteral)? (COUNTFIELD EQUAL countfield = stringLiteral)? (SHOWCOUNT EQUAL showcount = booleanLiteral)? fieldList (byClause)?
: RARE ((LIMIT EQUAL)? number = integerLiteral)? (COUNTFIELD EQUAL countfield = stringLiteral)? (SHOWCOUNT EQUAL showcount = booleanLiteral)? fieldList (byClause)?
;

grokCommand
Expand Down Expand Up @@ -1422,6 +1422,7 @@ searchableKeyWord
| FREQUENCY_THRESHOLD_PERCENTAGE
| MAX_SAMPLE_COUNT
| BUFFER_LIMIT
| LIMIT
| WITH
| REGEX
| PUNCT
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.ppl;

import org.mockito.Mockito;
import org.opensearch.sql.ast.Node;
import org.opensearch.sql.common.setting.Settings;
import org.opensearch.sql.ppl.antlr.PPLSyntaxParser;
import org.opensearch.sql.ppl.parser.AstBuilder;

/** Base class for tests for the AST query planner. */
public class AstPlanningTestBase {
protected final Settings settings = Mockito.mock(Settings.class);
protected final PPLSyntaxParser parser = new PPLSyntaxParser();

protected Node plan(String query) {
AstBuilder astBuilder = new AstBuilder(query, settings);
return astBuilder.visit(parser.parse(query));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.opensearch.sql.ast.Node;
import org.opensearch.sql.ast.dsl.AstDSL;
import org.opensearch.sql.ast.expression.DataType;
Expand All @@ -76,19 +75,14 @@
import org.opensearch.sql.ast.tree.ML;
import org.opensearch.sql.ast.tree.RareTopN.CommandType;
import org.opensearch.sql.common.antlr.SyntaxCheckException;
import org.opensearch.sql.common.setting.Settings;
import org.opensearch.sql.common.setting.Settings.Key;
import org.opensearch.sql.ppl.antlr.PPLSyntaxParser;
import org.opensearch.sql.ppl.AstPlanningTestBase;
import org.opensearch.sql.utils.SystemIndexUtils;

public class AstBuilderTest {
public class AstBuilderTest extends AstPlanningTestBase {

@Rule public ExpectedException exceptionRule = ExpectedException.none();

private final Settings settings = Mockito.mock(Settings.class);

private final PPLSyntaxParser parser = new PPLSyntaxParser();

@Test
public void testDynamicSourceClauseThrowsUnsupportedException() {
String query = "source=[myindex, logs, fieldIndex=\"test\"]";
Expand Down Expand Up @@ -1080,11 +1074,6 @@ protected void assertEqual(String query, String expected) {
assertEqual(query, expectedPlan);
}

private Node plan(String query) {
AstBuilder astBuilder = new AstBuilder(query, settings);
return astBuilder.visit(parser.parse(query));
}

private String mappingTable(String indexName) {
return SystemIndexUtils.mappingTable(indexName, PPL_SPEC);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.ppl.parser;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.opensearch.sql.ppl.AstPlanningTestBase;

public class AstEquivalenceTest extends AstPlanningTestBase {
@Test
public void testSpathArgumentDeshuffle() {
assertEquals(plan("source = t | spath path=a input=a"), plan("source = t | spath input=a a"));
}

@Test
public void testHeadLimitEquivalent() {
assertEquals(plan("source = t | head limit=50"), plan("source = t | head 50"));
}

@Test
public void testTopLimitEquivalent() {
assertEquals(
plan("source = t | top limit=50 field_name"), plan("source = t | top 50 field_name"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.ppl.utils;
package org.opensearch.sql.ppl.rewrite;

import static org.junit.Assert.assertEquals;
import static org.opensearch.sql.ast.dsl.AstDSL.eval;
Expand All @@ -15,23 +15,11 @@
import static org.opensearch.sql.ast.dsl.AstDSL.stringLiteral;

import org.junit.Test;
import org.mockito.Mockito;
import org.opensearch.sql.ast.Node;
import org.opensearch.sql.ast.tree.Eval;
import org.opensearch.sql.ast.tree.SPath;
import org.opensearch.sql.common.setting.Settings;
import org.opensearch.sql.ppl.antlr.PPLSyntaxParser;
import org.opensearch.sql.ppl.parser.AstBuilder;

public class SPathRewriteTest {
private final Settings settings = Mockito.mock(Settings.class);
private final PPLSyntaxParser parser = new PPLSyntaxParser();

private Node plan(String query) {
AstBuilder astBuilder = new AstBuilder(query, settings);
return astBuilder.visit(parser.parse(query));
}
import org.opensearch.sql.ppl.AstPlanningTestBase;

public class SpathRewriteTest extends AstPlanningTestBase {
// Control test to make sure something fundamental hasn't changed about the json_extract parsing
@Test
public void testEvalControl() {
Expand Down Expand Up @@ -59,9 +47,4 @@ public void testSpathMissingInputArgumentHandling() {
public void testSpathMissingPathArgumentHandling() {
plan("source = t | spath input=a output=a");
}

@Test
public void testSpathArgumentDeshuffle() {
assertEquals(plan("source = t | spath path=a input=a"), plan("source = t | spath input=a a"));
}
}
Loading