From b9ea7414fc24f6137c4388e859a2839959d0c35a Mon Sep 17 00:00:00 2001 From: vcarey Date: Sun, 12 Jul 2026 17:43:00 -0400 Subject: [PATCH] Fix top-level warmup parameter matching --- service/reader/service.go | 30 +++++++++++++++++++++++++- service/reader/service_warmup_test.go | 31 +++++++++++++++++++++------ 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/service/reader/service.go b/service/reader/service.go index 85c02a18..526f81e7 100644 --- a/service/reader/service.go +++ b/service/reader/service.go @@ -651,13 +651,41 @@ func warmupIndexParameter(aView *view.View) *state.Parameter { if candidate == nil { continue } - if strings.EqualFold(strings.TrimSpace(candidate.Name), parameterName) { + if matchesWarmupParameter(candidate, parameterName) { return candidate } } return nil } +func matchesWarmupParameter(candidate *state.Parameter, configured string) bool { + if candidate == nil { + return false + } + configured = strings.TrimSpace(configured) + if configured == "" { + return false + } + if strings.EqualFold(strings.TrimSpace(candidate.Name), configured) { + return true + } + if candidate.In != nil && strings.EqualFold(strings.TrimSpace(candidate.In.Name), configured) { + return true + } + + fieldName := warmupIndexFieldName(configured) + if fieldName == "" { + return false + } + if strings.EqualFold(strings.TrimSpace(candidate.Name), fieldName) { + return true + } + if strings.EqualFold(strings.TrimSpace(candidate.Name), fieldName+"s") { + return true + } + return false +} + func (s *Service) BuildCriteria(ctx context.Context, value interface{}, options *codec.CriteriaBuilderOptions) (*codec.Criteria, error) { baseView := view.Context(ctx) aSchema := state.NewSchema(reflect.TypeOf(value)) diff --git a/service/reader/service_warmup_test.go b/service/reader/service_warmup_test.go index 1b5ffb1b..53ca54d0 100644 --- a/service/reader/service_warmup_test.go +++ b/service/reader/service_warmup_test.go @@ -159,28 +159,45 @@ func TestWarmupIndexParameterUsesExplicitParameter(t *testing.T) { require.Equal(t, "OrderId", parameter.Name) } -func TestWarmupIndexParameterDoesNotInferCamelCase(t *testing.T) { +func TestWarmupIndexParameterMatchesCanonicalQueryLocation(t *testing.T) { aView := &view.View{ Cache: &view.Cache{ - Warmup: &view.Warmup{IndexColumn: "order_id"}, + Warmup: &view.Warmup{IndexColumn: "ad_order_id", IndexParameter: "order_id"}, }, Template: view.NewTemplate("", - view.WithTemplateParameters(state.NewParameter("OrderId", state.NewQueryLocation("order_id"))), + view.WithTemplateParameters(state.NewParameter("OrderIds", state.NewQueryLocation("order_id"))), ), } parameter := warmupIndexParameter(aView) - require.Nil(t, parameter) + require.NotNil(t, parameter) + require.Equal(t, "OrderIds", parameter.Name) } -func TestWarmupIndexParameterDoesNotFallbackToMatchingColumnName(t *testing.T) { +func TestWarmupIndexParameterMatchesFieldAliasPlural(t *testing.T) { aView := &view.View{ Cache: &view.Cache{ - Warmup: &view.Warmup{IndexColumn: "order_id"}, + Warmup: &view.Warmup{IndexColumn: "ad_order_id", IndexParameter: "order_id"}, + }, + Template: view.NewTemplate("", + view.WithTemplateParameters(state.NewParameter("OrderIds", nil)), + ), + } + + parameter := warmupIndexParameter(aView) + + require.NotNil(t, parameter) + require.Equal(t, "OrderIds", parameter.Name) +} + +func TestWarmupIndexParameterDoesNotMatchUnrelatedParameter(t *testing.T) { + aView := &view.View{ + Cache: &view.Cache{ + Warmup: &view.Warmup{IndexColumn: "ad_order_id", IndexParameter: "order_id"}, }, Template: view.NewTemplate("", - view.WithTemplateParameters(state.NewParameter("order_id", state.NewQueryLocation("order_id"))), + view.WithTemplateParameters(state.NewParameter("CampaignIds", state.NewQueryLocation("campaign_id"))), ), }