You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							133 lines
						
					
					
						
							4.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							133 lines
						
					
					
						
							4.8 KiB
						
					
					
				
								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")
							 | 
						|
									})
							 | 
						|
								}
							 |