generated from amazon-archives/__template_Custom
-
Notifications
You must be signed in to change notification settings - Fork 181
[Feature] fieldformat command implementation #5080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
asifabashar
wants to merge
36
commits into
opensearch-project:main
Choose a base branch
from
asifabashar:feature-fieldformat
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
d02ff60
fielfformat changes
asifabashar 3c62d86
added field format with concatenation of string , added more examples
asifabashar 553ffa7
added field format with concatenation of string , added more examples
asifabashar 36085f5
ci failure fix test
asifabashar c08beda
ci failure fix test
asifabashar faaf0f9
ci failure fix test
asifabashar b6e8965
ci failure fix test
asifabashar 330cfc0
added missing test files
asifabashar d853f36
added missing test files
asifabashar c74151d
doc fix
asifabashar 6c93ebe
doc fix
asifabashar 239df5a
doc fix
asifabashar be0d82b
added test
asifabashar 090bea7
[Feature] implement transpose command as in the roadmap #4786 (#5011)
asifabashar fcd0f87
added test
asifabashar 1ff53f6
[Feature] implement transpose command as in the roadmap #4786 (#5011)
asifabashar 4fc4113
fielfformat changes
asifabashar 43ec5c9
added field format with concatenation of string , added more examples
asifabashar 90c88fc
added test
asifabashar 8725e4d
[Feature] implement transpose command as in the roadmap #4786 (#5011)
asifabashar 3e3908f
added test
asifabashar 99673af
merge from main
asifabashar 8ead775
merge conflict issues
asifabashar 538efac
merge conflict issues
asifabashar 8ec8887
doc fix
asifabashar c57b38f
test fix
asifabashar 2f6cd1a
test fix
asifabashar 7b05103
coderabbit recommendations
asifabashar ffd33bd
resolve conflicts
asifabashar 494df1d
resolve conflicts
asifabashar 7543224
resolve conflicts
asifabashar 1a5d916
resolve conflicts
asifabashar 54b3a06
resolve conflicts
asifabashar f5703a4
removed ambigous sentence
asifabashar 72bef4b
added missing test files
asifabashar b9b2908
spotlessApply
asifabashar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
|
|
||
| # fieldformat | ||
|
|
||
| The `fieldformat` command sets the value to a field with the specified expression and appends the field with evaluated result to the search results. The command is an alias of eval command. | ||
| Additionally, it also provides string concatenation dot operator followed by and/or follows a string that will be concatenated to the expression. | ||
|
|
||
|
|
||
| ## Syntax | ||
|
|
||
| The `fieldformat` command has the following syntax: | ||
|
|
||
| ```syntax | ||
| fieldformat <field>=[(prefix).]<expression>[.(suffix)] ["," <field>=[(prefix).]<expression>[.(suffix)] ]... | ||
|
|
||
asifabashar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| ## Parameters | ||
|
|
||
| The `fieldformat` command supports the following parameters. | ||
|
|
||
| | Parameter| Required/Optional | Description | | ||
| |----------------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| | ||
| | `<field>` | Required | The name of the field to create or update. If the field does not exist, a new field is added. If it already exists, its value is overwritten. | | ||
| | `<expression>` | Required | The expression to evaluate. The expression can have a prefix and/or suffix string part that will be concatenated to the expression. | | ||
| | `prefix` | Optional | A string before the expression followed by dot operator which will be concatenated as prefix to the evaluated expression value. | | ||
| | `suffix` | Optional | A string that follows the expression and dot operator which will be concatenated as suffix to the evaluated expression value. | | ||
|
|
||
|
|
||
| ## Example 1: Create a new field | ||
|
|
||
| The following query creates a new `doubleAge` field for each document: | ||
|
|
||
| ```ppl | ||
| source=accounts | ||
| | fieldformat doubleAge = age * 2 | ||
| | fields age, doubleAge | ||
| ``` | ||
|
|
||
| The query returns the following results: | ||
|
|
||
| ```text | ||
| fetched rows / total rows = 4/4 | ||
| +-----+-----------+ | ||
| | age | doubleAge | | ||
| |-----+-----------| | ||
| | 32 | 64 | | ||
| | 36 | 72 | | ||
| | 28 | 56 | | ||
| | 33 | 66 | | ||
| +-----+-----------+ | ||
| ``` | ||
|
|
||
|
|
||
| ## Example 2: Override an existing field | ||
|
|
||
| The following query overrides the `age` field by adding `1` to its value: | ||
|
|
||
| ```ppl | ||
| source=accounts | ||
| | fieldformat age = age + 1 | ||
| | fields age | ||
| ``` | ||
|
|
||
| The query returns the following results: | ||
|
|
||
| ```text | ||
| fetched rows / total rows = 4/4 | ||
| +-----+ | ||
| | age | | ||
| |-----| | ||
| | 33 | | ||
| | 37 | | ||
| | 29 | | ||
| | 34 | | ||
| +-----+ | ||
| ``` | ||
|
|
||
|
|
||
|
|
||
|
|
||
| ## Example 3: String concatenation with prefix | ||
|
|
||
| The following query uses the `.` (dot) operator for string concatenation. You can concatenate string literals and field values as follows: | ||
|
|
||
| ```ppl | ||
| source=accounts | ||
| | fieldformat greeting = 'Hello '.tostring( firstname) | ||
| | fields firstname, greeting | ||
| ``` | ||
|
|
||
| The query returns the following results: | ||
|
|
||
| ```text | ||
| fetched rows / total rows = 4/4 | ||
| +-----------+---------------+ | ||
| | firstname | greeting | | ||
| |-----------+---------------| | ||
| | Amber | Hello Amber | | ||
| | Hattie | Hello Hattie | | ||
| | Nanette | Hello Nanette | | ||
| | Dale | Hello Dale | | ||
| +-----------+---------------+ | ||
| ``` | ||
|
|
||
|
|
||
| ## Example 4: String concatenation with dot operator, prefix and suffix | ||
|
|
||
| The following query performs prefix and suffix string concatenation operations using dot operator: | ||
|
|
||
| ```ppl | ||
| source=accounts | fieldformat age_info = 'Age: '.CAST(age AS STRING).' years.' | fields firstname, age, age_info | ||
| ``` | ||
|
|
||
| The query returns the following results: | ||
|
|
||
| ```text | ||
| fetched rows / total rows = 4/4 | ||
| +-----------+-----+----------------+ | ||
| | firstname | age | age_info | | ||
| |-----------+-----+----------------| | ||
| | Amber | 32 | Age: 32 years. | | ||
| | Hattie | 36 | Age: 36 years. | | ||
| | Nanette | 28 | Age: 28 years. | | ||
| | Dale | 33 | Age: 33 years. | | ||
| +-----------+-----+----------------+ | ||
| ``` | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteFieldFormatCommandIT.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| /* | ||
| * Copyright OpenSearch Contributors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package org.opensearch.sql.calcite.remote; | ||
|
|
||
| import static org.opensearch.sql.util.MatcherUtils.*; | ||
|
|
||
| import java.io.IOException; | ||
| import org.apache.commons.text.StringEscapeUtils; | ||
| import org.json.JSONObject; | ||
| import org.junit.jupiter.api.Test; | ||
asifabashar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| import org.opensearch.client.Request; | ||
| import org.opensearch.sql.ppl.PPLIntegTestCase; | ||
|
|
||
| public class CalciteFieldFormatCommandIT extends PPLIntegTestCase { | ||
|
|
||
| @Override | ||
| public void init() throws Exception { | ||
| super.init(); | ||
| enableCalcite(); | ||
|
|
||
| loadIndex(Index.BANK); | ||
|
|
||
| // Create test data for string concatenation | ||
| Request request1 = new Request("PUT", "/test_eval/_doc/1?refresh=true"); | ||
| request1.setJsonEntity("{\"name\": \"Alice\", \"age\": 25, \"title\": \"Engineer\"}"); | ||
| client().performRequest(request1); | ||
|
|
||
| Request request2 = new Request("PUT", "/test_eval/_doc/2?refresh=true"); | ||
| request2.setJsonEntity("{\"name\": \"Bob\", \"age\": 30, \"title\": \"Manager\"}"); | ||
| client().performRequest(request2); | ||
|
|
||
| Request request3 = new Request("PUT", "/test_eval/_doc/3?refresh=true"); | ||
| request3.setJsonEntity("{\"name\": \"Charlie\", \"age\": null, \"title\": \"Analyst\"}"); | ||
| client().performRequest(request3); | ||
| } | ||
|
|
||
| @Test | ||
| public void testFieldFormatStringConcatenation() throws IOException { | ||
| JSONObject result = | ||
| executeQuery( | ||
| StringEscapeUtils.escapeJson( | ||
| "source=test_eval | fieldformat greeting = 'Hello ' + name")); | ||
| verifySchema( | ||
| result, | ||
| schema("name", "string"), | ||
| schema("title", "string"), | ||
| schema("age", "bigint"), | ||
| schema("greeting", "string")); | ||
| verifyDataRows( | ||
| result, | ||
| rows("Alice", "Engineer", 25, "Hello Alice"), | ||
| rows("Bob", "Manager", 30, "Hello Bob"), | ||
| rows("Charlie", "Analyst", null, "Hello Charlie")); | ||
| } | ||
|
|
||
| @Test | ||
| public void testFieldFormatStringConcatenationWithNullFieldToString() throws IOException { | ||
| JSONObject result = | ||
| executeQuery( | ||
| StringEscapeUtils.escapeJson( | ||
| "source=test_eval | fieldformat age_desc = \"Age: \".tostring(age,\"commas\") |" | ||
| + " fields name, age, age_desc")); | ||
| verifySchema( | ||
| result, schema("name", "string"), schema("age", "bigint"), schema("age_desc", "string")); | ||
| verifyDataRows( | ||
| result, | ||
| rows("Alice", 25, "Age: 25"), | ||
| rows("Bob", 30, "Age: 30"), | ||
| rows("Charlie", null, null)); | ||
asifabashar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @Test | ||
| public void testFieldFormatStringConcatenationWithNullField() throws IOException { | ||
| JSONObject result = | ||
| executeQuery( | ||
| StringEscapeUtils.escapeJson( | ||
| "source=test_eval | fieldformat age_desc = \"Age: \".CAST(age AS STRING) | fields" | ||
| + " name, age, age_desc")); | ||
| verifySchema( | ||
| result, schema("name", "string"), schema("age", "bigint"), schema("age_desc", "string")); | ||
| verifyDataRows( | ||
| result, | ||
| rows("Alice", 25, "Age: 25"), | ||
| rows("Bob", 30, "Age: 30"), | ||
| rows("Charlie", null, null)); | ||
| } | ||
|
|
||
| @Test | ||
| public void testFieldFormatStringConcatWithSuffix() throws IOException { | ||
| JSONObject result = | ||
| executeQuery( | ||
| StringEscapeUtils.escapeJson( | ||
| "source=test_eval | fieldformat age_desc = CAST(age AS STRING).\" years\" | fields" | ||
| + " name, age, age_desc")); | ||
| verifySchema( | ||
| result, schema("name", "string"), schema("age", "bigint"), schema("age_desc", "string")); | ||
| verifyDataRows( | ||
| result, | ||
| rows("Alice", 25, "25 years"), | ||
| rows("Bob", 30, "30 years"), | ||
| rows("Charlie", null, null)); | ||
| } | ||
|
|
||
| @Test | ||
| public void testFieldFormatStringConcatWithPrefixSuffix() throws IOException { | ||
| JSONObject result = | ||
| executeQuery( | ||
| StringEscapeUtils.escapeJson( | ||
| "source=test_eval | fieldformat age_desc = \"Age: \".CAST(age AS STRING).\" years\"" | ||
| + " | fields name, age, age_desc")); | ||
| verifySchema( | ||
| result, schema("name", "string"), schema("age", "bigint"), schema("age_desc", "string")); | ||
| verifyDataRows( | ||
| result, | ||
| rows("Alice", 25, "Age: 25 years"), | ||
| rows("Bob", 30, "Age: 30 years"), | ||
| rows("Charlie", null, null)); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.