aboutsummaryrefslogtreecommitdiff
path: root/weed/query/engine/execution_plan_fast_path_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/query/engine/execution_plan_fast_path_test.go')
-rw-r--r--weed/query/engine/execution_plan_fast_path_test.go133
1 files changed, 133 insertions, 0 deletions
diff --git a/weed/query/engine/execution_plan_fast_path_test.go b/weed/query/engine/execution_plan_fast_path_test.go
new file mode 100644
index 000000000..c0f08fa21
--- /dev/null
+++ b/weed/query/engine/execution_plan_fast_path_test.go
@@ -0,0 +1,133 @@
+package engine
+
+import (
+ "testing"
+
+ "github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestExecutionPlanFastPathDisplay tests that the execution plan correctly shows
+// "Parquet Statistics (fast path)" when fast path is used, not "Parquet Files (full scan)"
+func TestExecutionPlanFastPathDisplay(t *testing.T) {
+ engine := NewMockSQLEngine()
+
+ // Create realistic data sources for fast path scenario
+ dataSources := &TopicDataSources{
+ ParquetFiles: map[string][]*ParquetFileStats{
+ "/topics/test/topic/partition-1": {
+ {
+ RowCount: 500,
+ ColumnStats: map[string]*ParquetColumnStats{
+ "id": {
+ ColumnName: "id",
+ MinValue: &schema_pb.Value{Kind: &schema_pb.Value_Int64Value{Int64Value: 1}},
+ MaxValue: &schema_pb.Value{Kind: &schema_pb.Value_Int64Value{Int64Value: 500}},
+ NullCount: 0,
+ RowCount: 500,
+ },
+ },
+ },
+ },
+ },
+ ParquetRowCount: 500,
+ LiveLogRowCount: 0, // Pure parquet scenario - ideal for fast path
+ PartitionsCount: 1,
+ }
+
+ t.Run("Fast path execution plan shows correct data sources", func(t *testing.T) {
+ optimizer := NewFastPathOptimizer(engine.SQLEngine)
+
+ aggregations := []AggregationSpec{
+ {Function: FuncCOUNT, Column: "*", Alias: "COUNT(*)"},
+ }
+
+ // Test the strategy determination
+ strategy := optimizer.DetermineStrategy(aggregations)
+ assert.True(t, strategy.CanUseFastPath, "Strategy should allow fast path for COUNT(*)")
+ assert.Equal(t, "all_aggregations_supported", strategy.Reason)
+
+ // Test data source list building
+ builder := &ExecutionPlanBuilder{}
+ dataSources := &TopicDataSources{
+ ParquetFiles: map[string][]*ParquetFileStats{
+ "/topics/test/topic/partition-1": {
+ {RowCount: 500},
+ },
+ },
+ ParquetRowCount: 500,
+ LiveLogRowCount: 0,
+ PartitionsCount: 1,
+ }
+
+ dataSourcesList := builder.buildDataSourcesList(strategy, dataSources)
+
+ // When fast path is used, should show "parquet_stats" not "parquet_files"
+ assert.Contains(t, dataSourcesList, "parquet_stats",
+ "Data sources should contain 'parquet_stats' when fast path is used")
+ assert.NotContains(t, dataSourcesList, "parquet_files",
+ "Data sources should NOT contain 'parquet_files' when fast path is used")
+
+ // Test that the formatting works correctly
+ formattedSource := engine.SQLEngine.formatDataSource("parquet_stats")
+ assert.Equal(t, "Parquet Statistics (fast path)", formattedSource,
+ "parquet_stats should format to 'Parquet Statistics (fast path)'")
+
+ formattedFullScan := engine.SQLEngine.formatDataSource("parquet_files")
+ assert.Equal(t, "Parquet Files (full scan)", formattedFullScan,
+ "parquet_files should format to 'Parquet Files (full scan)'")
+ })
+
+ t.Run("Slow path execution plan shows full scan data sources", func(t *testing.T) {
+ builder := &ExecutionPlanBuilder{}
+
+ // Create strategy that cannot use fast path
+ strategy := AggregationStrategy{
+ CanUseFastPath: false,
+ Reason: "unsupported_aggregation_functions",
+ }
+
+ dataSourcesList := builder.buildDataSourcesList(strategy, dataSources)
+
+ // When slow path is used, should show "parquet_files" and "live_logs"
+ assert.Contains(t, dataSourcesList, "parquet_files",
+ "Slow path should contain 'parquet_files'")
+ assert.Contains(t, dataSourcesList, "live_logs",
+ "Slow path should contain 'live_logs'")
+ assert.NotContains(t, dataSourcesList, "parquet_stats",
+ "Slow path should NOT contain 'parquet_stats'")
+ })
+
+ t.Run("Data source formatting works correctly", func(t *testing.T) {
+ // Test just the data source formatting which is the key fix
+
+ // Test parquet_stats formatting (fast path)
+ fastPathFormatted := engine.SQLEngine.formatDataSource("parquet_stats")
+ assert.Equal(t, "Parquet Statistics (fast path)", fastPathFormatted,
+ "parquet_stats should format to show fast path usage")
+
+ // Test parquet_files formatting (slow path)
+ slowPathFormatted := engine.SQLEngine.formatDataSource("parquet_files")
+ assert.Equal(t, "Parquet Files (full scan)", slowPathFormatted,
+ "parquet_files should format to show full scan")
+
+ // Test that data sources list is built correctly for fast path
+ builder := &ExecutionPlanBuilder{}
+ fastStrategy := AggregationStrategy{CanUseFastPath: true}
+
+ fastSources := builder.buildDataSourcesList(fastStrategy, dataSources)
+ assert.Contains(t, fastSources, "parquet_stats",
+ "Fast path should include parquet_stats")
+ assert.NotContains(t, fastSources, "parquet_files",
+ "Fast path should NOT include parquet_files")
+
+ // Test that data sources list is built correctly for slow path
+ slowStrategy := AggregationStrategy{CanUseFastPath: false}
+
+ slowSources := builder.buildDataSourcesList(slowStrategy, dataSources)
+ assert.Contains(t, slowSources, "parquet_files",
+ "Slow path should include parquet_files")
+ assert.NotContains(t, slowSources, "parquet_stats",
+ "Slow path should NOT include parquet_stats")
+ })
+}