55 "github.com/efritz/gostgres/internal/execution/expressions"
66 "github.com/efritz/gostgres/internal/execution/queries/nodes"
77 "github.com/efritz/gostgres/internal/execution/queries/nodes/access"
8+ "github.com/efritz/gostgres/internal/execution/queries/plan/cost"
89 "github.com/efritz/gostgres/internal/shared/fields"
910 "github.com/efritz/gostgres/internal/shared/impls"
1011)
@@ -59,8 +60,8 @@ func (n *logicalAccessNode) Optimize(ctx impls.OptimizationContext) {
5960 n .order = nil
6061}
6162
62- func (n * logicalAccessNode ) EstimateCost () Cost {
63- return Cost {} // TODO
63+ func (n * logicalAccessNode ) EstimateCost () impls. NodeCost {
64+ return cost . ApplyFilterToCost ( n . strategy . EstimateCost (), cost . EstimateFilterSelectivity ( n . filter ))
6465}
6566
6667func (n * logicalAccessNode ) Filter () impls.Expression {
@@ -162,6 +163,17 @@ func (s *logicalTableAccessStrategy) Ordering() impls.OrderExpression {
162163 return nil
163164}
164165
166+ var tableAccessCostPerRow = impls.ResourceCost {CPU : 0.01 , IO : 0.1 }
167+
168+ func (s * logicalTableAccessStrategy ) EstimateCost () impls.NodeCost {
169+ stats , _ := s .table .Statistics ()
170+
171+ return impls.NodeCost {
172+ EstimatedRows : stats .RowCount ,
173+ VariableCost : tableAccessCostPerRow .ScaleUniform (float64 (stats .RowCount )),
174+ }
175+ }
176+
165177func (s * logicalTableAccessStrategy ) Build () nodes.AccessStrategy {
166178 return access .NewTableAccessStrategy (s .table )
167179}
@@ -186,6 +198,20 @@ func (s *logicalIndexAccessStrategy[O]) Filter() impls.Expression {
186198 return expressions .UnionFilters (append (expressions .Conjunctions (filterExpression ), expressions .Conjunctions (condition )... )... )
187199}
188200
201+ var indexAccessCostPerRow = impls.ResourceCost {CPU : 0.01 , IO : 0.1 }
202+
203+ func (s * logicalIndexAccessStrategy [O ]) EstimateCost () impls.NodeCost {
204+ stats , _ := s .table .Statistics ()
205+
206+ // TODO - support parital indexes
207+ // TODO - determine selectivity based on index cond
208+
209+ return impls.NodeCost {
210+ EstimatedRows : stats .RowCount ,
211+ VariableCost : indexAccessCostPerRow .ScaleUniform (float64 (stats .RowCount )),
212+ }
213+ }
214+
189215func (s * logicalIndexAccessStrategy [O ]) Build () nodes.AccessStrategy {
190216 return access .NewIndexAccessStrategy (s .table , s .index , s .opts , s .Filter ())
191217}
0 commit comments