perf(lastleg): reduce inventory turnover query aggregation work

This commit is contained in:
2026-10-14 03:36:54 +08:00
parent 16d0b9c80f
commit 765b6e6208
3 changed files with 353 additions and 37 deletions
@@ -35,7 +35,12 @@ class InventoryTurnoverContextTest {
assertEquals(END.minusDays(29),first.analyticsContext().rangeStartDate());
assertEquals(END.plusDays(1),first.analyticsContext().rangeEndDateExclusive());
assertEquals(first,at(NOW.plusSeconds(60)).resolve(request(first.snapshotContext())).response());
verify(mapper,times(2)).samples("demo","W",IH,utc(NOW),END.minusDays(29),END.plusDays(1));
var page2=new InventoryTurnoverRequest("demo","W",END,30,"SKU",null,null,"ALL",null,null,"PHYSICAL_DESC",2,20,false,first.snapshotContext());
var second=at(NOW.plusSeconds(90)).resolve(page2);
assertEquals(first,second.response());
assertEquals(InventoryTurnoverSql.input(request(first.snapshotContext()),contexts.resolve(request(first.snapshotContext()))).days(),
InventoryTurnoverSql.input(page2,second).days());
verify(mapper,times(4)).samples("demo","W",IH,utc(NOW),END.minusDays(29),END.plusDays(1));
// A subsequently published sample cannot appear in the old asOf query. If reconstruction
// ever differs, reject the context instead of mixing old charts and new rows.
when(mapper.samples(eq("demo"),eq("W"),eq(IH),any(),any(),any())).thenReturn(List.of());
@@ -103,6 +103,16 @@ class InventoryTurnoverSqlTest {
assertNull(absent.get("w30_outbound"));assertNull(absent.get("w30_observed"));
decimal("0",query("overview",input(q,30,0,true)).get(0).get("no_outbound_count"));
}
@Test void warehouseChartUsesSalesUnitsAndCoverageIndependentlyOfStockProfiles() throws Exception {
seed("A","SKU",30);
execute("UPDATE ll_selfop_sku_profile SET quantity_unit='UNKNOWN'");
execute("UPDATE ll_selfop_inventory_snapshot SET physical_quantity=NULL");
var p=input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),30,0,false);
var row=query("chartWindows",p).get(0);decimal("300",row.get("w30_outbound"));
execute("UPDATE ll_selfop_sku_daily_sales SET quantity_unit='UNKNOWN' WHERE business_date=DATE '"+END+"'");
row=query("chartWindows",p).get(0);assertNull(row.get("w30_outbound"));
decimal("290",row.get("w30_observed"));decimal("29",row.get("w30_complete"));decimal("6",row.get("w7_complete"));
}
@Test void fullScopeFilterPrecedesPaginationAndKeepsSoldOutHistoricalCandidates() throws Exception {
seed("A","LOW",30);seed("A","HIGH",30);seed("B","SOLD",30);
execute("UPDATE ll_selfop_inventory_snapshot SET available_quantity=3000,physical_quantity=3000 WHERE sku_code='HIGH' AND snapshot_run_id=22 AND product_quality=0");
@@ -137,6 +147,231 @@ class InventoryTurnoverSqlTest {
assertEquals(2,report.stream().filter(r->"OWNER".equals(r.get("section"))).count());
assertEquals(1,report.stream().filter(r->"OVERVIEW".equals(r.get("section"))).count());
}
@Test void frozenSamplesExcludeUnselectedVersionsWithoutDroppingMissingDays() throws Exception {
seed("A","SKU",30);
profile(999,"A","UNSELECTED");stock(999,"A","UNSELECTED",0,999,999);
var q=request("SKU","ALL","PHYSICAL_DESC",null,null,1,20);
var rows=reportRows(input(q,30,2,true));
assertEquals(1,rows.size());decimal("2",rows.get(0).get("sample_count"));
assertNull(rows.get(0).get("turnover"));
assertEquals(28,rows.get(0).get("missing_dates").toString().split(",").length);
rows=reportRows(input(q,30,0,true));
assertEquals(1,rows.size());decimal("0",rows.get(0).get("sample_count"));
assertEquals(30,rows.get(0).get("missing_dates").toString().split(",").length);
decimal("300",rows.get(0).get("w30_outbound"));
}
@Test void repeatedSampleRunAndHighestDateBitKeepAllThreeWindowsExact() throws Exception {
seed("A","SKU",30);
for(boolean onlyLast:List.of(true,false)) for(int n:List.of(7,15,30)) for(String group:List.of("SKU","OWNER")) {
var dates=new ArrayList<InventoryTurnoverSql.Day>();var missing=new ArrayList<String>();
for(int i=0;i<30;i++) {
var date=END.minusDays(29-i);boolean present=onlyLast?i==29:i!=29;
// Reusing a version on multiple frozen dates must retain each date.
dates.add(new InventoryTurnoverSql.Day(date,date.atStartOfDay().minusHours(8),1,present?100L:null));
if(i>=30-n&&!present)missing.add(date.toString());
}
var q=new InventoryTurnoverRequest("demo","W",END,n,group,null,null,"ALL",null,null,null,1,20,true,null);
var p=new InventoryTurnoverSql.Input(q,11,22,true,true,List.copyOf(dates));
var row=query("page",p).get(0);
decimal(onlyLast?"536870912":"536870911",row.get("sample_mask"));
decimal(String.valueOf(onlyLast?1:n-1),row.get("sample_count"));
assertEquals(String.join(",",missing),row.get("missing_dates"));
assertNull(row.get("average_physical"));assertNull(row.get("turnover"));
assertEquals(row.get("missing_dates"),reportRows(p).get(0).get("missing_dates"));
}
}
@Test void sparseSamplesKeepExactDateComplementAndFullOwnerDenominator() throws Exception {
seed("A","ONE",30);seed("A","TWO",30);
// Both edge bits and a middle bit, with different missing members per day.
execute("DELETE FROM ll_selfop_inventory_snapshot WHERE warehouse_code='W' AND ((sku_code='ONE' AND snapshot_run_id IN (100,114)) OR (sku_code='TWO' AND snapshot_run_id=129))");
for(int n:List.of(7,15,30)) {
var q=new InventoryTurnoverRequest("demo","W",END,n,"OWNER",null,null,"ALL",null,null,null,1,20,true,null);
var p=input(q,30,30,true);
var row=reportRows(p).get(0);
var expected=new ArrayList<LocalDate>();
for(int index:List.of(0,14,29)) if(index>=30-n) expected.add(END.minusDays(29-index));
decimal(String.valueOf(n-expected.size()),row.get("sample_count"));
assertEquals(String.join(",",expected.stream().map(LocalDate::toString).toList()),row.get("missing_dates"));
assertNull(row.get("average_physical"));assertNull(row.get("turnover"));
assertEquals(row.get("missing_dates"),query("page",p).get(0).get("missing_dates"));
}
var pageTwo=new InventoryTurnoverRequest("demo","W",END,30,"SKU",null,null,"ALL",null,null,null,2,1,false,null);
var second=reportRows(input(pageTwo,30,30,true)).get(0);
assertEquals("TWO",second.get("sku_code"));decimal("29",second.get("sample_count"));assertEquals(END.toString(),second.get("missing_dates"));
// A stock/profile-only candidate without samples invalidates all owner days.
profile(22,"A","NO-SAMPLES");stock(22,"A","NO-SAMPLES",0,0,0);
var owner=reportRows(input(request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true)).get(0);
decimal("0",owner.get("sample_count"));assertEquals(30,owner.get("missing_dates").toString().split(",").length);
}
@Test void reportBindsExactLargeSampleVersionsAndKeepsWindowDenominators() throws Exception {
seed("A","SKU",30);
long first=9_007_199_254_740_993L;
for(int i=0;i<30;i++) {
execute("UPDATE ll_selfop_sku_profile SET profile_run_id="+(first+i)+" WHERE profile_run_id="+(100+i));
execute("UPDATE ll_selfop_inventory_snapshot SET snapshot_run_id="+(first+i)+",physical_quantity=CASE WHEN product_quality=0 THEN "+((i+1)*10)+" ELSE 0 END WHERE snapshot_run_id="+(100+i));
}
List<InventoryTurnoverSql.Day> days=new ArrayList<>();
for(int i=0;i<30;i++){var date=END.minusDays(29-i);days.add(new InventoryTurnoverSql.Day(date,date.atStartOfDay().minusHours(8),1,first+i));}
for(int n:List.of(7,15,30)) {
var q=new InventoryTurnoverRequest("demo","W",END,n,"SKU",null,null,"ALL",null,null,null,1,20,true,null);
var p=new InventoryTurnoverSql.Input(q,11,22,true,true,List.copyOf(days));
var row=reportRows(p).get(0);
decimal(String.valueOf(n),row.get("sample_count"));
decimal(n==7?"270":n==15?"230":"155",row.get("average_physical"));
decimal("70",row.get("w7_outbound"));decimal("150",row.get("w15_outbound"));decimal("300",row.get("w30_outbound"));
assertNotNull(row.get("turnover"));
}
var missing=days.get(14);days.set(14,new InventoryTurnoverSql.Day(missing.date(),missing.startUtc(),1,null));
var row=reportRows(new InventoryTurnoverSql.Input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),11,22,true,true,List.copyOf(days))).get(0);
decimal("29",row.get("sample_count"));assertNull(row.get("turnover"));
assertEquals(missing.date().toString(),row.get("missing_dates"));
}
@Test void reportPaginationKeepsTotalAndCanOmitOverview() throws Exception {
seed("A","SKU",30);seed("B","SKU",30);
var first=reportRows(input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,1),30,30,true));
var secondQuery=new InventoryTurnoverRequest("demo","W",END,30,"SKU",null,null,"ALL",null,null,"PHYSICAL_DESC",2,1,false,"frozen");
var second=query("report",input(secondQuery,30,30,true));
var row=second.stream().filter(r->"ROW".equals(r.get("section"))).findFirst().orElseThrow();
assertNotEquals(first.get(0).get("customer_code"),payload(row).path("customer_code").asText());
assertEquals(2,second.size());
var beyond=new InventoryTurnoverRequest("demo","W",END,30,"SKU",null,null,"ALL",null,null,"PHYSICAL_DESC",3,1,false,"frozen");
var report=query("report",input(beyond,30,30,true));assertEquals(1,report.size());
assertEquals("TOTAL",report.get(0).get("section"));assertEquals(2,payload(report.get(0)).path("total").asInt());
}
@Test void projectedFormalWindowsKeepPartialObservationsAndUnknownDistinctFromZero() throws Exception {
seed("A","SKU",30);
for(String group:List.of("SKU","OWNER")) {
var p=input(request(group,"ALL","PHYSICAL_DESC",null,null,1,20),0,30,true);
var row=reportRows(p).get(0);
assertNull(row.get("w30_outbound"));decimal("300",row.get("w30_observed"));decimal("30",row.get("w30_partial"));
}
execute("DELETE FROM ll_selfop_sku_daily_sales WHERE warehouse_code='W'");
for(String group:List.of("SKU","OWNER")) {
var p=input(request(group,"ALL","PHYSICAL_DESC",null,null,1,20),0,30,true);
var unknown=reportRows(p).get(0);assertNull(unknown.get("w30_outbound"));assertNull(unknown.get("w30_observed"));
var partialDays=p.days().stream().map(d->new InventoryTurnoverSql.Day(d.date(),d.startUtc(),2,d.sampleRun())).toList();
var partial=reportRows(new InventoryTurnoverSql.Input(p.query(),11,22,true,true,partialDays)).get(0);
assertNull(partial.get("w30_outbound"));decimal("0",partial.get("w30_observed"));decimal("30",partial.get("w30_partial"));
var complete=reportRows(input(p.query(),30,30,true)).get(0);
decimal("0",complete.get("w30_outbound"));decimal("30",complete.get("w30_complete"));
}
}
@Test void zeroEvidenceUsesExactBeijingMidnightIncludingMilliseconds() throws Exception {
seed("A","SKU",0);execute("DELETE FROM ll_selfop_sku_daily_sales WHERE warehouse_code='W'");
for(int n:List.of(7,15,30)) for(int millis:List.of(-1,0,1)) {
LocalDate start=END.minusDays(n-1);var utc=start.atStartOfDay().minusHours(8).plusNanos(millis*1_000_000L);
execute("UPDATE ll_selfop_sku_profile SET earliest_evidence_at_utc=TIMESTAMP '"+utc.toString().replace('T',' ')+"'");
var p=input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),30,0,true);
var row=reportRows(p).get(0);decimal(String.valueOf(n-(millis>0?1:0)),row.get("w"+n+"_complete"));
if(millis>0)assertNull(row.get("w"+n+"_outbound"));else decimal("0",row.get("w"+n+"_outbound"));
execute("INSERT INTO ll_selfop_sku_daily_sales VALUES(11,'demo','W','A','SKU',DATE '"+start+"',0,'PCS')");
row=reportRows(p).get(0);decimal(String.valueOf(n),row.get("w"+n+"_complete"));decimal("0",row.get("w"+n+"_outbound"));
execute("DELETE FROM ll_selfop_sku_daily_sales WHERE warehouse_code='W'");
}
}
@Test void sparseCorrectionRevokesInvalidActualZeroAndHandlesEvidenceAfterLastBoundary() throws Exception {
seed("A","SKU",0);execute("DELETE FROM ll_selfop_sku_daily_sales WHERE warehouse_code='W'");
var p=input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),1,0,true);
var afterLast=END.atStartOfDay().minusHours(8).plusNanos(1_000_000);
execute("UPDATE ll_selfop_sku_profile SET earliest_evidence_at_utc=TIMESTAMP '"+afterLast.toString().replace('T',' ')+"'");
var row=reportRows(p).get(0);decimal("0",row.get("w7_complete"));assertNull(row.get("w7_observed"));decimal("0",row.get("w7_partial"));
execute("INSERT INTO ll_selfop_sku_daily_sales VALUES(11,'demo','W','A','SKU',DATE '"+END+"',1.234567,'PCS')");
row=reportRows(p).get(0);decimal("1",row.get("w7_complete"));decimal("1.234567",row.get("w7_observed"));
execute("UPDATE ll_selfop_sku_profile SET earliest_evidence_at_utc=TIMESTAMP '2026-01-01 00:00:00'");
execute("UPDATE ll_selfop_sku_daily_sales SET quantity_unit='UNKNOWN' WHERE warehouse_code='W'");
row=reportRows(p).get(0);decimal("0",row.get("w7_complete"));assertNull(row.get("w7_observed"));decimal("0",row.get("w7_partial"));
}
@Test void presentInvalidSamplesNeverQualifyAndOwnerZeroNeedsEverySku() throws Exception {
seed("A","ONE",30);seed("A","TWO",30);
String key=" WHERE snapshot_run_id=100 AND sku_code='TWO' AND product_quality=0";
for(String mutation:List.of("physical_quantity=NULL","physical_quantity=-1","product_quality=9","quality_status='UNKNOWN',quality_reason='UNCONFIRMED'","profile")) {
if("profile".equals(mutation))execute("UPDATE ll_selfop_sku_profile SET quantity_unit='UNKNOWN' WHERE profile_run_id=100 AND sku_code='TWO'");
else execute("UPDATE ll_selfop_inventory_snapshot SET "+mutation+key);
var owner=reportRows(input(request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true)).get(0);
decimal("29",owner.get("sample_count"));assertNull(owner.get("turnover"));assertEquals(END.minusDays(29).toString(),owner.get("missing_dates"));
execute("DELETE FROM ll_selfop_inventory_snapshot WHERE snapshot_run_id=100 AND sku_code='TWO'");stock(100,"A","TWO",0,450,450);stock(100,"A","TWO",1,50,0);
execute("UPDATE ll_selfop_sku_profile SET quantity_unit='PCS' WHERE profile_run_id=100 AND sku_code='TWO'");
}
execute("UPDATE ll_selfop_inventory_snapshot SET physical_quantity=0 WHERE snapshot_run_id>=100");
var owner=reportRows(input(request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true)).get(0);
decimal("30",owner.get("sample_count"));decimal("0",owner.get("average_physical"));assertNull(owner.get("turnover"));
}
@Test void ownerInvalidActualAndAbsentMemberKeepCoveredZeroDifferentFromUnknown() throws Exception {
seed("A","ONE",0);seed("A","TWO",0);execute("DELETE FROM ll_selfop_sku_daily_sales WHERE warehouse_code='W'");
execute("INSERT INTO ll_selfop_sku_daily_sales VALUES(11,'demo','W','A','ONE',DATE '"+END+"',10,'UNKNOWN')");
var q=request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20);
var row=reportRows(input(q,30,0,true)).get(0);decimal("6",row.get("w7_complete"));decimal("0",row.get("w7_observed"));decimal("1",row.get("w7_partial"));
row=reportRows(input(q,0,0,true)).get(0);assertNull(row.get("w7_observed"));decimal("0",row.get("w7_partial"));
execute("INSERT INTO ll_selfop_sku_daily_sales VALUES(11,'demo','W','A','TWO',DATE '"+END+"',10,'UNKNOWN')");
row=reportRows(input(q,1,0,true)).get(0);assertNull(row.get("w7_observed"));decimal("0",row.get("w7_complete"));decimal("0",row.get("w7_partial"));
}
@Test void decimalWindowsRemainExactBeyondJavascriptIntegerRangeWithoutDuplicatingCandidates() throws Exception {
for(String sku:List.of("ONE","TWO","THREE","FOUR"))seed("A",sku,30);
String amount="99999999999999.123456";var quantity=new BigDecimal(amount);
execute("UPDATE ll_selfop_sku_daily_sales SET outbound_quantity="+amount+" WHERE warehouse_code='W'");
execute("UPDATE ll_selfop_inventory_snapshot SET physical_quantity=CASE WHEN product_quality=0 THEN "+amount+" ELSE 0 END");
var report=query("report",input(request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true));
var row=payload(report.stream().filter(r->"ROW".equals(r.get("section"))).findFirst().orElseThrow());
decimal(quantity.multiply(BigDecimal.valueOf(120)).toPlainString(),row.path("w30_outbound").decimalValue());
decimal(quantity.multiply(BigDecimal.valueOf(4)).toPlainString(),row.path("average_physical").decimalValue());
decimal("30",row.path("turnover").decimalValue());assertEquals(30,row.path("sample_count").asInt());
var skuReport=query("report",input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true));
assertEquals(4,skuReport.stream().filter(r->"ROW".equals(r.get("section"))).count());
for(var raw:skuReport)if("ROW".equals(raw.get("section")))decimal(quantity.multiply(BigDecimal.valueOf(30)).toPlainString(),payload(raw).path("w30_outbound").decimalValue());
}
@Test void threeSourceCandidateUnionKeepsFullOwnerDenominator() throws Exception {
profile(100,"A","HISTORY");profile(11,"A","HISTORY");profile(22,"A","HISTORY");
stock(22,"A","STOCK",0,0,0);
execute("INSERT INTO ll_selfop_sku_daily_sales VALUES(11,'demo','W','A','SALES',DATE '"+END+"',1.123456,'PCS')");
var skuRows=reportRows(input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true));
assertEquals(Set.of("HISTORY","STOCK","SALES"),new HashSet<>(skuRows.stream().map(r->r.get("sku_code")).toList()));
assertEquals(3,skuRows.size());
var report=query("report",input(request("OWNER","ALL","PHYSICAL_DESC",null,null,1,20),30,30,true));
var row=payload(report.stream().filter(r->"ROW".equals(r.get("section"))).findFirst().orElseThrow());
decimal("1.123456",row.path("w30_outbound").decimalValue());
assertEquals(0,row.path("sample_count").asInt());assertTrue(row.path("average_physical").isNull());
assertEquals(30,row.path("missing_dates").asText().split(",").length);
}
@Test void ownerStockChartSurvivesMissingWindowsAndEmptySkuFilter() throws Exception {
seed("A","SKU",0);seed("B","SKU",0);seed("C","SOLD",0);
execute("UPDATE ll_selfop_inventory_snapshot SET physical_quantity=NULL,quality_status='UNKNOWN',quality_reason='FIELD_MISSING' WHERE customer_code='B' AND snapshot_run_id=22");
execute("UPDATE ll_selfop_inventory_snapshot SET physical_quantity=0,available_quantity=0 WHERE customer_code='C' AND snapshot_run_id=22");
var baseline=query("report",input(request("SKU","ALL","PHYSICAL_DESC",null,null,1,20),7,0,true));
var baselineSummary=payload(baseline.stream().filter(r->"OVERVIEW".equals(r.get("section"))).findFirst().orElseThrow());
for(String group:List.of("SKU","OWNER")) {
var full=input(request(group,"ALL","PHYSICAL_DESC",null,null,1,20),7,0,true);
var standalone=query("page",full);var reportRows=reportRows(full);
assertEquals(standalone.size(),reportRows.size());
for(int i=0;i<standalone.size();i++) for(var field:reportRows.get(i).entrySet()) {
Object expected=standalone.get(i).get(field.getKey()),actual=field.getValue();
if(expected instanceof Number)decimal(expected.toString(),actual);
else if(expected instanceof java.sql.Date)assertEquals(expected.toString(),actual);
else assertEquals(expected,actual,field.getKey());
}
var q=request(group,"ALL","PHYSICAL_DESC","SKU".equals(group)?"not-present":null,null,1,20);
var report=query("report",input(q,7,0,true));
var chart=report.stream().filter(r->"OWNER".equals(r.get("section"))).toList();
assertEquals(2,chart.size());
var known=payload(chart.get(0));assertEquals("A",known.path("customer_code").asText());decimal("610",known.path("physical").decimalValue());
var unknown=report.stream().filter(r->"OWNER_META".equals(r.get("section"))).findFirst().orElseThrow();
assertEquals(1,payload(unknown).path("unknown_count").asInt());
var summary=report.stream().filter(r->"OVERVIEW".equals(r.get("section"))).findFirst().orElseThrow();
assertEquals(3,payload(summary).path("sku_count").asInt());assertEquals(baselineSummary,payload(summary));
var total=report.stream().filter(r->"TOTAL".equals(r.get("section"))).findFirst().orElseThrow();
assertEquals("SKU".equals(group)?0:3,payload(total).path("total").asInt());
assertEquals("SKU".equals(group)?0:3,report.stream().filter(r->"ROW".equals(r.get("section"))).count());
}
}
private static com.fasterxml.jackson.databind.JsonNode payload(Map<String,Object> row) throws Exception {
var json=new com.fasterxml.jackson.databind.ObjectMapper().enable(com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);Object raw=row.get("payload");
return raw instanceof byte[] bytes?json.readTree(bytes):json.readTree(raw.toString());
}
private List<Map<String,Object>> reportRows(InventoryTurnoverSql.Input p) throws Exception {
var result=new ArrayList<Map<String,Object>>();var json=new com.fasterxml.jackson.databind.ObjectMapper();
for(var row:query("report",p)) if("ROW".equals(row.get("section")))
result.add(json.convertValue(payload(row),new com.fasterxml.jackson.core.type.TypeReference<Map<String,Object>>(){}));
return result;
}
private void seed(String owner,String sku,int samples) throws Exception {
profile(11,owner,sku);profile(22,owner,sku);stock(22,owner,sku,0,600,600);stock(22,owner,sku,1,10,0);
for(int i=0;i<30;i++) {
@@ -159,6 +394,10 @@ class InventoryTurnoverSqlTest {
Object value=meta.getValue(parameter.getProperty());String literal=value==null?"NULL":value instanceof Boolean b?b?"1":"0":value instanceof Number?value.toString():"'"+value.toString().replace("'","''")+"'";
sql=sql.replaceFirst("\\?",java.util.regex.Matcher.quoteReplacement(literal));
}
// MySQL SIGNED is a signed 64-bit integer; H2's alias is only 32-bit.
sql=sql.replace(" AS SIGNED)"," AS BIGINT)");
// MySQL's unbounded CHAR cast preserves the date; H2 defaults to CHAR(1).
sql=sql.replace("CAST(business_date AS CHAR)","CAST(business_date AS VARCHAR(10))");
// H2 inlines repeatedly referenced CTEs exponentially. Materialize each unchanged
// production relation in this local fixture; MySQL execution plans remain unverified.
List<String> relations=new ArrayList<>();int cursor=5;