Skip to content

Commit a996d24

Browse files
committed
Address review: rename the partial-result setting and fold the fallback into pushDownAggregate
The setting is user-facing behavior, not a Calcite internal, so move it from plugins.calcite.* to plugins.query.partial_result.on_mapping_conflict.enabled and drop the CALCITE_ prefix from the key. Fold tryPartialResultAggregate into pushDownAggregate so the planner rule keeps a single entry point. The fallback is now private and gated by an allowPartialFallback flag, so re-entering on the narrowed scan attempts it at most once. Signed-off-by: Kai Huang <ahkcs@amazon.com>
1 parent 51220fe commit a996d24

5 files changed

Lines changed: 29 additions & 25 deletions

File tree

common/src/main/java/org/opensearch/sql/common/setting/Settings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ public enum Key {
4444
CALCITE_PUSHDOWN_ROWCOUNT_ESTIMATION_FACTOR(
4545
"plugins.calcite.pushdown.rowcount.estimation.factor"),
4646
CALCITE_SUPPORT_ALL_JOIN_TYPES("plugins.calcite.all_join_types.allowed"),
47-
CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT(
48-
"plugins.calcite.partial_result.on_mapping_conflict.enabled"),
4947

5048
/** Query Settings. */
5149
FIELD_TYPE_TOLERANCE("plugins.query.field_type_tolerance"),
50+
PARTIAL_RESULT_ON_MAPPING_CONFLICT(
51+
"plugins.query.partial_result.on_mapping_conflict.enabled"),
5252

5353
/** Common Settings for SQL and PPL. */
5454
QUERY_MEMORY_LIMIT("plugins.query.memory_limit"),

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePartialResultOnMappingConflictIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* another collapses to text-without-keyword across the wildcard pattern, which defeats aggregation
3131
* pushdown and forces a per-shard document scan that opens a Point-In-Time context on every shard.
3232
*
33-
* <p>When {@code plugins.calcite.partial_result.on_mapping_conflict.enabled} is on, the aggregation
33+
* <p>When {@code plugins.query.partial_result.on_mapping_conflict.enabled} is on, the aggregation
3434
* is instead pushed down over just the aggregatable (keyword) index subset — no PIT — and the
3535
* response carries a {@code PARTIAL_RESULT} warning naming the excluded index.
3636
*/
@@ -304,7 +304,7 @@ private void setPartialResult(boolean enabled) throws IOException {
304304
updateClusterSettings(
305305
new ClusterSetting(
306306
"persistent",
307-
Settings.Key.CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT.getKeyValue(),
307+
Settings.Key.PARTIAL_RESULT_ON_MAPPING_CONFLICT.getKeyValue(),
308308
Boolean.toString(enabled)));
309309
}
310310

opensearch/src/main/java/org/opensearch/sql/opensearch/planner/rules/AggregateIndexScanRule.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ protected void apply(
9898
@Nullable LogicalProject project,
9999
CalciteLogicalIndexScan scan) {
100100
AbstractRelNode newRelNode = scan.pushDownAggregate(aggregate, project);
101-
if (newRelNode == null) {
102-
// Normal pushdown failed (e.g. a text/keyword mapping conflict across a wildcard pattern that
103-
// would otherwise fall back to a per-shard scan and exhaust PIT contexts). If partial results
104-
// are enabled, push the aggregation over the aggregatable index subset instead and warn.
105-
newRelNode = scan.tryPartialResultAggregate(aggregate, project);
106-
}
107101
if (newRelNode != null) {
108102
call.transformTo(newRelNode);
109103
PlanUtils.tryPruneRelNodes(call);

opensearch/src/main/java/org/opensearch/sql/opensearch/setting/OpenSearchSettings.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ public class OpenSearchSettings extends Settings {
187187
Setting.Property.NodeScope,
188188
Setting.Property.Dynamic);
189189

190-
public static final Setting<?> CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING =
190+
public static final Setting<?> PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING =
191191
Setting.boolSetting(
192-
Key.CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT.getKeyValue(),
192+
Key.PARTIAL_RESULT_ON_MAPPING_CONFLICT.getKeyValue(),
193193
false,
194194
Setting.Property.NodeScope,
195195
Setting.Property.Dynamic);
@@ -493,9 +493,9 @@ public OpenSearchSettings(ClusterSettings clusterSettings) {
493493
register(
494494
settingBuilder,
495495
clusterSettings,
496-
Key.CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT,
497-
CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING,
498-
new Updater(Key.CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT));
496+
Key.PARTIAL_RESULT_ON_MAPPING_CONFLICT,
497+
PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING,
498+
new Updater(Key.PARTIAL_RESULT_ON_MAPPING_CONFLICT));
499499
register(
500500
settingBuilder,
501501
clusterSettings,
@@ -700,7 +700,7 @@ public static List<Setting<?>> pluginSettings() {
700700
.add(CALCITE_PUSHDOWN_ENABLED_SETTING)
701701
.add(CALCITE_PUSHDOWN_ROWCOUNT_ESTIMATION_FACTOR_SETTING)
702702
.add(CALCITE_SUPPORT_ALL_JOIN_TYPES_SETTING)
703-
.add(CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING)
703+
.add(PARTIAL_RESULT_ON_MAPPING_CONFLICT_SETTING)
704704
.add(DEFAULT_PATTERN_METHOD_SETTING)
705705
.add(DEFAULT_PATTERN_MODE_SETTING)
706706
.add(DEFAULT_PATTERN_MAX_SAMPLE_COUNT_SETTING)

opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteLogicalIndexScan.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ public CalciteLogicalIndexScan pushDownRareTop(Project project, RareTopDigest di
375375
}
376376

377377
public AbstractRelNode pushDownAggregate(Aggregate aggregate, @Nullable Project project) {
378+
return pushDownAggregate(aggregate, project, true);
379+
}
380+
381+
/**
382+
* @param allowPartialFallback whether a failure may fall back to the partial-result path. False
383+
* when re-entering from that path, so the fallback is attempted at most once.
384+
*/
385+
private AbstractRelNode pushDownAggregate(
386+
Aggregate aggregate, @Nullable Project project, boolean allowPartialFallback) {
378387
try {
379388
CalciteLogicalIndexScan newScan =
380389
new CalciteLogicalIndexScan(
@@ -400,7 +409,7 @@ public AbstractRelNode pushDownAggregate(Aggregate aggregate, @Nullable Project
400409
if (LOG.isDebugEnabled()) {
401410
LOG.debug("Cannot pushdown the aggregate due to bucket contains array (nested) type");
402411
}
403-
return null;
412+
return allowPartialFallback ? tryPartialResultAggregate(aggregate, project) : null;
404413
}
405414
int queryBucketSize = osIndex.getQueryBucketSize();
406415
boolean bucketNullable = !PPLHintUtils.ignoreNullBucket(aggregate);
@@ -431,7 +440,7 @@ public AbstractRelNode pushDownAggregate(Aggregate aggregate, @Nullable Project
431440
LOG.debug("Cannot pushdown the aggregate {}", aggregate, e);
432441
}
433442
}
434-
return null;
443+
return allowPartialFallback ? tryPartialResultAggregate(aggregate, project) : null;
435444
}
436445

437446
/**
@@ -447,9 +456,10 @@ public AbstractRelNode pushDownAggregate(Aggregate aggregate, @Nullable Project
447456
* warning ({@link QueryContext#isWarningsSupported}). The partitioning decision lives in {@link
448457
* PartialResultAggregatePushdown}; this method owns the plan-time wiring (settings gate, mapping
449458
* lookup, narrowed-scan construction, warning emission). Returns {@code null} — leaving the
450-
* caller to fall back — whenever partial mode does not apply.
459+
* aggregate un-pushed, as before — whenever partial mode does not apply.
451460
*/
452-
public AbstractRelNode tryPartialResultAggregate(Aggregate aggregate, @Nullable Project project) {
461+
private AbstractRelNode tryPartialResultAggregate(
462+
Aggregate aggregate, @Nullable Project project) {
453463
if (!isPartialResultEnabled()) {
454464
return null;
455465
}
@@ -484,9 +494,11 @@ public AbstractRelNode tryPartialResultAggregate(Aggregate aggregate, @Nullable
484494
narrowedIndex,
485495
getRowType(),
486496
pushDownContext.cloneWithOsIndex(narrowedIndex));
487-
AbstractRelNode pushed = narrowedScan.pushDownAggregate(aggregate, project);
497+
// allowPartialFallback = false: the subset is already narrowed, so a second attempt would be
498+
// redundant. Keeps the fallback strictly one-shot.
499+
AbstractRelNode pushed = narrowedScan.pushDownAggregate(aggregate, project, false);
488500
if (pushed == null) {
489-
return null; // narrowed subset still can't push down -> fall back
501+
return null; // narrowed subset still can't push down -> leave un-pushed
490502
}
491503

492504
CalcitePlanContext.addWarning(plan.warning());
@@ -510,9 +522,7 @@ private boolean isPartialResultEnabled() {
510522
return override;
511523
}
512524
return (Boolean)
513-
osIndex
514-
.getSettings()
515-
.getSettingValue(Settings.Key.CALCITE_PARTIAL_RESULT_ON_MAPPING_CONFLICT);
525+
osIndex.getSettings().getSettingValue(Settings.Key.PARTIAL_RESULT_ON_MAPPING_CONFLICT);
516526
}
517527

518528
public AbstractRelNode pushDownLimit(LogicalSort sort, Integer limit, Integer offset) {

0 commit comments

Comments
 (0)