@@ -125,7 +125,9 @@ static void fileBeginForeignScan(ForeignScanState *node, int eflags);
125
125
static TupleTableSlot * fileIterateForeignScan (ForeignScanState * node );
126
126
static void fileReScanForeignScan (ForeignScanState * node );
127
127
static void fileEndForeignScan (ForeignScanState * node );
128
- static AcquireSampleRowsFunc fileAnalyzeForeignTable (Relation relation );
128
+ static bool fileAnalyzeForeignTable (Relation relation ,
129
+ AcquireSampleRowsFunc * func ,
130
+ BlockNumber * totalpages );
129
131
130
132
/*
131
133
* Helper functions
@@ -141,8 +143,7 @@ static void estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
141
143
Cost * startup_cost , Cost * total_cost );
142
144
static int file_acquire_sample_rows (Relation onerel , int elevel ,
143
145
HeapTuple * rows , int targrows ,
144
- double * totalrows , double * totaldeadrows ,
145
- BlockNumber * totalpages );
146
+ double * totalrows , double * totaldeadrows );
146
147
147
148
148
149
/*
@@ -656,10 +657,39 @@ fileEndForeignScan(ForeignScanState *node)
656
657
* fileAnalyzeForeignTable
657
658
* Test whether analyzing this foreign table is supported
658
659
*/
659
- static AcquireSampleRowsFunc
660
- fileAnalyzeForeignTable (Relation relation )
660
+ static bool
661
+ fileAnalyzeForeignTable (Relation relation ,
662
+ AcquireSampleRowsFunc * func ,
663
+ BlockNumber * totalpages )
661
664
{
662
- return file_acquire_sample_rows ;
665
+ char * filename ;
666
+ List * options ;
667
+ struct stat stat_buf ;
668
+
669
+ /* Fetch options of foreign table */
670
+ fileGetOptions (RelationGetRelid (relation ), & filename , & options );
671
+
672
+ /*
673
+ * Get size of the file. (XXX if we fail here, would it be better to
674
+ * just return false to skip analyzing the table?)
675
+ */
676
+ if (stat (filename , & stat_buf ) < 0 )
677
+ ereport (ERROR ,
678
+ (errcode_for_file_access (),
679
+ errmsg ("could not stat file \"%s\": %m" ,
680
+ filename )));
681
+
682
+ /*
683
+ * Convert size to pages. Must return at least 1 so that we can tell
684
+ * later on that pg_class.relpages is not default.
685
+ */
686
+ * totalpages = (stat_buf .st_size + (BLCKSZ - 1 )) / BLCKSZ ;
687
+ if (* totalpages < 1 )
688
+ * totalpages = 1 ;
689
+
690
+ * func = file_acquire_sample_rows ;
691
+
692
+ return true;
663
693
}
664
694
665
695
/*
@@ -780,8 +810,7 @@ estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
780
810
* which must have at least targrows entries.
781
811
* The actual number of rows selected is returned as the function result.
782
812
* We also count the total number of rows in the file and return it into
783
- * *totalrows, and return the file's physical size in *totalpages.
784
- * Note that *totaldeadrows is always set to 0.
813
+ * *totalrows. Note that *totaldeadrows is always set to 0.
785
814
*
786
815
* Note that the returned list of rows is not always in order by physical
787
816
* position in the file. Therefore, correlation estimates derived later
@@ -791,8 +820,7 @@ estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
791
820
static int
792
821
file_acquire_sample_rows (Relation onerel , int elevel ,
793
822
HeapTuple * rows , int targrows ,
794
- double * totalrows , double * totaldeadrows ,
795
- BlockNumber * totalpages )
823
+ double * totalrows , double * totaldeadrows )
796
824
{
797
825
int numrows = 0 ;
798
826
double rowstoskip = -1 ; /* -1 means not set yet */
@@ -802,7 +830,6 @@ file_acquire_sample_rows(Relation onerel, int elevel,
802
830
bool * nulls ;
803
831
bool found ;
804
832
char * filename ;
805
- struct stat stat_buf ;
806
833
List * options ;
807
834
CopyState cstate ;
808
835
ErrorContextCallback errcontext ;
@@ -819,22 +846,6 @@ file_acquire_sample_rows(Relation onerel, int elevel,
819
846
/* Fetch options of foreign table */
820
847
fileGetOptions (RelationGetRelid (onerel ), & filename , & options );
821
848
822
- /*
823
- * Get size of the file.
824
- */
825
- if (stat (filename , & stat_buf ) < 0 )
826
- ereport (ERROR ,
827
- (errcode_for_file_access (),
828
- errmsg ("could not stat file \"%s\": %m" ,
829
- filename )));
830
-
831
- /*
832
- * Convert size to pages for use in I/O cost estimate.
833
- */
834
- * totalpages = (stat_buf .st_size + (BLCKSZ - 1 )) / BLCKSZ ;
835
- if (* totalpages < 1 )
836
- * totalpages = 1 ;
837
-
838
849
/*
839
850
* Create CopyState from FDW options.
840
851
*/
@@ -931,10 +942,10 @@ file_acquire_sample_rows(Relation onerel, int elevel,
931
942
* Emit some interesting relation info
932
943
*/
933
944
ereport (elevel ,
934
- (errmsg ("\"%s\": scanned %u pages containing %.0f rows; "
945
+ (errmsg ("\"%s\": file contains %.0f rows; "
935
946
"%d rows in sample" ,
936
947
RelationGetRelationName (onerel ),
937
- * totalpages , * totalrows , numrows )));
948
+ * totalrows , numrows )));
938
949
939
950
return numrows ;
940
951
}
0 commit comments