Query Information
PPL Command/Query:
source=test-rename-bug
| rename timestamp_field as @timestamp
| where TIMESTAMPDIFF(MINUTE, @timestamp, NOW()) <= 60
| timechart span=1minute COUNT()
Expected Result:
Query executes successfully, filtering documents where the renamed @timestamp field is within the last 60 minutes, then aggregating by 1-minute intervals.
Actual Result:
{
"error": {
"reason": "Error occurred in OpenSearch engine: all shards failed",
"details": "QueryShardException[failed to create query: Failed to compile inline script [...] using lang [opensearch_compounded_script]]; nested: GeneralScriptException[...]; nested: NullPointerException",
"type": "SearchPhaseExecutionException"
},
"status": 400
}
Reproduction Steps
Execute the following curl commands to reproduce:
# 1. Create test index
curl -X PUT "http://localhost:9200/test-rename-bug" -H 'Content-Type: application/json' -d '{
"mappings": {
"properties": {
"timestamp_field": {"type": "date_nanos"},
"value": {"type": "integer"}
}
}
}'
# 2. Insert test data
curl -X POST "http://localhost:9200/test-rename-bug/_doc" -H 'Content-Type: application/json' -d '{
"timestamp_field": "2025-10-24T23:45:00.000Z",
"value": 100
}'
# 3. Refresh index
curl -X POST "http://localhost:9200/test-rename-bug/_refresh"
# 4. Run failing query
curl -X POST "http://localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' -d '{
"query": "source=test-rename-bug | rename timestamp_field as @timestamp | where TIMESTAMPDIFF(MINUTE, @timestamp, NOW()) <= 60 | timechart span=1minute COUNT()"
}'
Result: NullPointerException error
Bug Description
Issue Summary:
When a field is renamed using the rename command and then used in a where clause with a function (like TIMESTAMPDIFF), the query fails with a NullPointerException during Calcite script compilation. This occurs because the script engine receives the renamed field name but only has access to the original field name mappings.
Impact:
This bug prevents users from using renamed fields in WHERE clauses with functions when Calcite pushdown is enabled. It's particularly problematic for observability use cases where users need to rename timestamp fields to @timestamp for compatibility with timechart (see related issue #4576).
Comparison:
❌ Failing (rename before where):
source=test-rename-bug
| rename timestamp_field as @timestamp
| where TIMESTAMPDIFF(MINUTE, @timestamp, NOW()) <= 60
| timechart span=1minute COUNT()
Result: NullPointerException
✅ Working (where before rename):
source=test-rename-bug
| where TIMESTAMPDIFF(MINUTE, timestamp_field, NOW()) <= 60
| rename timestamp_field as @timestamp
| timechart span=1minute COUNT()
Result: Returns correct data
Environment Information
OpenSearch Version: 3.4.0-SNAPSHOT (reproduced on latest main branch)
Additional Details:
- Requires
plugins.calcite.enabled=true (default in 3.x)
- Only affects queries where renamed fields are used in WHERE clauses with functions
- Does not affect simple comparisons without functions
Root Cause Analysis
Tentative Root Cause:
The bug occurs in two locations:
List<String> schema = this.getRowType().getFieldNames();
Map<String, ExprType> fieldTypes =
this.osIndex.getAllFieldTypes().entrySet().stream()
.filter(entry -> schema.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
After a rename operation:
schema contains renamed field names (e.g., @timestamp)
osIndex.getAllFieldTypes() contains original field names (e.g., timestamp_field)
- The filter fails to match, so
fieldTypes doesn't include the renamed field mapping
String fieldName = rowType.getFieldList().get(index).getName();
ExprType exprType = fieldTypes.get(fieldName);
During script execution:
fieldName gets the renamed field name from rowType (e.g., @timestamp)
fieldTypes.get(fieldName) returns null because fieldTypes only has original names
- Causes
NullPointerException when trying to use the null exprType
Workaround
Place the where clause before the rename command:
curl -X POST "http://localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' -d '{
"query": "source=test-rename-bug | where TIMESTAMPDIFF(MINUTE, timestamp_field, NOW()) <= 60 | rename timestamp_field as @timestamp | timechart span=1minute COUNT()"
}'
Related Issues
Query Information
PPL Command/Query:
Expected Result:
Query executes successfully, filtering documents where the renamed
@timestampfield is within the last 60 minutes, then aggregating by 1-minute intervals.Actual Result:
{ "error": { "reason": "Error occurred in OpenSearch engine: all shards failed", "details": "QueryShardException[failed to create query: Failed to compile inline script [...] using lang [opensearch_compounded_script]]; nested: GeneralScriptException[...]; nested: NullPointerException", "type": "SearchPhaseExecutionException" }, "status": 400 }Reproduction Steps
Execute the following curl commands to reproduce:
Result: NullPointerException error
Bug Description
Issue Summary:
When a field is renamed using the
renamecommand and then used in awhereclause with a function (likeTIMESTAMPDIFF), the query fails with aNullPointerExceptionduring Calcite script compilation. This occurs because the script engine receives the renamed field name but only has access to the original field name mappings.Impact:
This bug prevents users from using renamed fields in WHERE clauses with functions when Calcite pushdown is enabled. It's particularly problematic for observability use cases where users need to rename timestamp fields to
@timestampfor compatibility withtimechart(see related issue #4576).Comparison:
❌ Failing (rename before where):
Result: NullPointerException
✅ Working (where before rename):
Result: Returns correct data
Environment Information
OpenSearch Version: 3.4.0-SNAPSHOT (reproduced on latest main branch)
Additional Details:
plugins.calcite.enabled=true(default in 3.x)Root Cause Analysis
Tentative Root Cause:
The bug occurs in two locations:
1. Filter Pushdown (
CalciteLogicalIndexScan.java:125-128):After a
renameoperation:schemacontains renamed field names (e.g.,@timestamp)osIndex.getAllFieldTypes()contains original field names (e.g.,timestamp_field)fieldTypesdoesn't include the renamed field mapping2. Script Execution (
CalciteScriptEngine.java:186-187):During script execution:
fieldNamegets the renamed field name from rowType (e.g.,@timestamp)fieldTypes.get(fieldName)returnsnullbecause fieldTypes only has original namesNullPointerExceptionwhen trying to use the nullexprTypeWorkaround
Place the
whereclause before therenamecommand:Related Issues
renamecommand breaksdedupoperation - returns null values #4563 -renamebreaksdedupoperation (same root cause, different pushdown operation)timechartcustom timestamp field (mentions workaround)