Skip to content

Commit c51ea1d

Browse files
committed
CNDB-15280: Remove user data from Plan.toString
1 parent 13e25fe commit c51ea1d

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

src/java/org/apache/cassandra/index/sai/plan/Plan.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,37 @@ enum ControlFlow { Continue, Break }
288288
*/
289289
public final String toStringRecursive()
290290
{
291-
TreeFormatter<Plan> formatter = new TreeFormatter<>(Plan::toString, Plan::subplans);
291+
return toStringRecursive(true);
292+
}
293+
294+
/**
295+
* Formats the whole plan as a pretty tree
296+
*
297+
* @param redact whether to redact the queried column values.
298+
*/
299+
public final String toStringRecursive(boolean redact)
300+
{
301+
TreeFormatter<Plan> formatter = new TreeFormatter<>(plan -> plan.toString(redact), Plan::subplans);
292302
return formatter.format(this);
293303
}
294304

295305
/**
296306
* Returns the string representation of this node only
297307
*/
308+
@Override
298309
public final String toString()
299310
{
300-
String title = title();
311+
return toString(true);
312+
}
313+
314+
/**
315+
* Returns the string representation of this node only
316+
*
317+
* @param redact whether to redact the queried column values.
318+
*/
319+
public final String toString(boolean redact)
320+
{
321+
String title = title(redact);
301322
String description = description();
302323
return (title.isEmpty())
303324
? String.format("%s (%s)\n%s", getClass().getSimpleName(), cost(), description).stripTrailing()
@@ -309,7 +330,7 @@ public final String toString()
309330
* The information is included in the output of {@link #toString()} and {@link #toStringRecursive()}.
310331
* It is up to subclasses to implement it.
311332
*/
312-
protected String title()
333+
protected String title(boolean redact)
313334
{
314335
return "";
315336
}
@@ -345,7 +366,7 @@ protected String description()
345366
public final Plan optimize()
346367
{
347368
if (logger.isTraceEnabled())
348-
logger.trace("Optimizing plan:\n{}", this.toStringRecursive());
369+
logger.trace("Optimizing plan:\n{}", toStringRecursive());
349370

350371
Plan bestPlanSoFar = this;
351372
List<Leaf> leaves = nodesOfType(Leaf.class);
@@ -796,7 +817,7 @@ public IndexScan(Factory factory, int id, Expression predicate, long matchingKey
796817
}
797818

798819
@Override
799-
protected final String title()
820+
protected final String title(boolean redact)
800821
{
801822
return String.format("of %s (sel: %.9f, step: %.1f)",
802823
getIndexName(), selectivity(), access.meanDistance());
@@ -1689,9 +1710,9 @@ protected Filter withAccess(Access access)
16891710
}
16901711

16911712
@Override
1692-
protected String title()
1713+
protected String title(boolean redact)
16931714
{
1694-
return String.format("%s (sel: %.9f)", filter, selectivity() / source.get().selectivity());
1715+
return String.format("%s (sel: %.9f)", filter.toCQLString(redact), selectivity() / source.get().selectivity());
16951716
}
16961717
}
16971718

@@ -1757,7 +1778,7 @@ protected RowsIteration withAccess(Access access)
17571778
}
17581779

17591780
@Override
1760-
protected String title()
1781+
protected String title(boolean redact)
17611782
{
17621783
return "" + limit;
17631784
}

src/java/org/apache/cassandra/index/sai/plan/QueryController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ Plan buildPlan()
419419

420420
if (Tracing.isTracing())
421421
{
422-
Tracing.trace("Query execution plan:\n" + plan.toStringRecursive());
422+
Tracing.trace("Query execution plan:\n" + plan.toStringRecursive(false));
423423
List<Plan.IndexScan> origIndexScans = keysIterationPlan.nodesOfType(Plan.IndexScan.class);
424424
List<Plan.IndexScan> selectedIndexScans = plan.nodesOfType(Plan.IndexScan.class);
425425
Tracing.trace("Selecting {} {} of {} out of {} indexes",

test/unit/org/apache/cassandra/index/sai/plan/PlanTest.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ private static RowFilter.Expression filerPred(String column, Operator operation)
108108
{
109109
RowFilter.Expression pred = Mockito.mock(RowFilter.Expression.class);
110110
Mockito.when(pred.toCQLString(false)).thenReturn(column + ' ' + operation + " X");
111+
Mockito.when(pred.toCQLString(true)).thenReturn(column + ' ' + operation + " ?");
111112
Mockito.when(pred.operator()).thenReturn(operation);
112113
return pred;
113114
}
@@ -561,8 +562,6 @@ public void prettyPrint()
561562
Plan.RowsIteration filter = factory.recheckFilter(RowFilter.builder().add(pred1).add(pred2).add(pred4).build(), fetch);
562563
Plan.RowsIteration limit = factory.limit(filter, 3);
563564

564-
String prettyStr = limit.toStringRecursive();
565-
566565
assertEquals("Limit 3 (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
567566
" └─ Filter pred1 < X AND pred2 < X AND pred4 < X (sel: 1.000000000) (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
568567
" └─ Fetch (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
@@ -574,7 +573,22 @@ public void prettyPrint()
574573
" │ └─ NumericIndexScan of pred1_idx (sel: 0.500000000, step: 250.0) (keys: 2000.0, cost/key: 14.6, cost: 4500.0..33701.3)\n" +
575574
" │ predicate: RANGE(pred1)\n" +
576575
" └─ LiteralIndexScan of pred4_idx (sel: 0.001000000, step: 1.0) (keys: 1000.0, cost/key: 0.1, cost: 4500.0..4600.0)\n" +
577-
" predicate: RANGE(pred4)\n", prettyStr);
576+
" predicate: RANGE(pred4)\n",
577+
limit.toStringRecursive(false));
578+
579+
assertEquals("Limit 3 (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
580+
" └─ Filter pred1 < ? AND pred2 < ? AND pred4 < ? (sel: 1.000000000) (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
581+
" └─ Fetch (rows: 3.0, cost/row: 3895.8, cost: 44171.3..55858.7)\n" +
582+
" └─ KeysSort (keys: 3.0, cost/key: 3792.4, cost: 44171.3..55548.4)\n" +
583+
" └─ Union (keys: 1999.0, cost/key: 14.8, cost: 13500.0..43001.3)\n" +
584+
" ├─ Intersection (keys: 1000.0, cost/key: 29.4, cost: 9000.0..38401.3)\n" +
585+
" │ ├─ NumericIndexScan of pred2_idx (sel: 0.002000000, step: 1.0) (keys: 2000.0, cost/key: 0.1, cost: 4500.0..4700.0)\n" +
586+
" │ │ predicate: RANGE(pred2)\n" +
587+
" │ └─ NumericIndexScan of pred1_idx (sel: 0.500000000, step: 250.0) (keys: 2000.0, cost/key: 14.6, cost: 4500.0..33701.3)\n" +
588+
" │ predicate: RANGE(pred1)\n" +
589+
" └─ LiteralIndexScan of pred4_idx (sel: 0.001000000, step: 1.0) (keys: 1000.0, cost/key: 0.1, cost: 4500.0..4600.0)\n" +
590+
" predicate: RANGE(pred4)\n",
591+
limit.toStringRecursive(true));
578592
}
579593

580594
@Test
@@ -1035,7 +1049,6 @@ public void testLazyAccessPropagation()
10351049
Mockito.when(indexScan1.withAccess(Mockito.any())).thenReturn(indexScan1);
10361050
Mockito.when(indexScan1.estimateCost()).thenReturn(new Plan.KeysIterationCost(20,0.0, 0.5));
10371051
Mockito.when(indexScan1.estimateSelectivity()).thenReturn(0.001);
1038-
Mockito.when(indexScan1.title()).thenReturn("");
10391052

10401053
Plan.KeysIteration indexScan2 = factory.indexScan(saiPred2, (long) (0.01 * factory.tableMetrics.rows));
10411054
Plan.KeysIteration indexScan3 = factory.indexScan(saiPred3, (long) (0.5 * factory.tableMetrics.rows));

0 commit comments

Comments
 (0)