22
22
import com .starrocks .catalog .PartitionKey ;
23
23
import com .starrocks .catalog .Table ;
24
24
import com .starrocks .catalog .Type ;
25
+ import com .starrocks .common .Config ;
25
26
import com .starrocks .common .profile .Timer ;
26
27
import com .starrocks .common .profile .Tracers ;
27
28
import com .starrocks .connector .ColumnTypeConverter ;
65
66
import org .apache .paimon .table .source .InnerTableScan ;
66
67
import org .apache .paimon .table .source .ReadBuilder ;
67
68
import org .apache .paimon .table .source .Split ;
68
- import org .apache .paimon .table .system .PartitionsTable ;
69
69
import org .apache .paimon .table .system .SchemasTable ;
70
70
import org .apache .paimon .table .system .SnapshotsTable ;
71
71
import org .apache .paimon .types .DataField ;
74
74
import org .apache .paimon .types .DateType ;
75
75
import org .apache .paimon .types .RowType ;
76
76
import org .apache .paimon .utils .DateTimeUtils ;
77
+ import org .apache .paimon .utils .PartitionPathUtils ;
77
78
78
79
import java .time .LocalDateTime ;
79
80
import java .time .ZoneId ;
80
81
import java .time .ZonedDateTime ;
81
82
import java .util .ArrayList ;
83
+ import java .util .Arrays ;
84
+ import java .util .HashMap ;
82
85
import java .util .List ;
83
86
import java .util .Map ;
84
87
import java .util .Optional ;
@@ -150,39 +153,21 @@ private void updatePartitionInfo(String databaseName, String tableName) {
150
153
partitionColumnTypes .add (dataTableRowType .getTypeAt (dataTableRowType .getFieldIndex (partitionColumnName )));
151
154
}
152
155
153
- Identifier partitionTableIdentifier = new Identifier (databaseName , String .format ("%s%s" , tableName , "$partitions" ));
154
- RecordReaderIterator <InternalRow > iterator = null ;
155
156
try {
156
- PartitionsTable table = (PartitionsTable ) paimonNativeCatalog .getTable (partitionTableIdentifier );
157
- RowType partitionTableRowType = table .rowType ();
158
- DataType lastUpdateTimeType = partitionTableRowType .getTypeAt (partitionTableRowType
159
- .getFieldIndex ("last_update_time" ));
160
- int [] projected = new int [] {0 , 1 , 2 , 3 , 4 };
161
- RecordReader <InternalRow > recordReader = table .newReadBuilder ().withProjection (projected )
162
- .newRead ().createReader (table .newScan ().plan ());
163
- iterator = new RecordReaderIterator <>(recordReader );
164
- while (iterator .hasNext ()) {
165
- InternalRow rowData = iterator .next ();
166
- String partitionStr = rowData .getString (0 ).toString ();
167
- org .apache .paimon .data .Timestamp lastUpdateTime = rowData .getTimestamp (4 ,
168
- DataTypeChecks .getPrecision (lastUpdateTimeType ));
169
- String [] partitionValues = partitionStr .replace ("[" , "" ).replace ("]" , "" )
170
- .split ("," );
171
- Partition partition =
172
- getPartition (rowData .getLong (1 ), rowData .getLong (2 ), rowData .getLong (3 ),
173
- partitionColumnNames , partitionColumnTypes , partitionValues , lastUpdateTime );
174
- this .partitionInfos .put (partition .getPartitionName (), partition );
157
+ List <org .apache .paimon .partition .Partition > partitions = paimonNativeCatalog .listPartitions (identifier );
158
+ for (org .apache .paimon .partition .Partition partition : partitions ) {
159
+ String partitionPath = PartitionPathUtils .generatePartitionPath (partition .spec (), dataTableRowType );
160
+ String [] partitionValues = Arrays .stream (partitionPath .split ("/" ))
161
+ .map (part -> part .split ("=" )[1 ])
162
+ .toArray (String []::new );
163
+ Partition srPartition = getPartition (partition .recordCount (),
164
+ partition .fileSizeInBytes (), partition .fileCount (),
165
+ partitionColumnNames , partitionColumnTypes , partitionValues ,
166
+ Timestamp .fromEpochMillis (partition .lastFileCreationTime ()));
167
+ this .partitionInfos .put (srPartition .getPartitionName (), srPartition );
175
168
}
176
- } catch (Exception e ) {
169
+ } catch (Catalog . TableNotExistException e ) {
177
170
LOG .error ("Failed to update partition info of paimon table {}.{}." , databaseName , tableName , e );
178
- } finally {
179
- if (iterator != null ) {
180
- try {
181
- iterator .close ();
182
- } catch (Exception e ) {
183
- LOG .error ("Failed to update partition info of paimon table {}.{}." , databaseName , tableName , e );
184
- }
185
- }
186
171
}
187
172
}
188
173
@@ -192,7 +177,7 @@ private Partition getPartition(Long recordCount,
192
177
List <String > partitionColumnNames ,
193
178
List <DataType > partitionColumnTypes ,
194
179
String [] partitionValues ,
195
- org . apache . paimon . data . Timestamp lastUpdateTime ) {
180
+ Timestamp lastUpdateTime ) {
196
181
if (partitionValues .length != partitionColumnNames .size ()) {
197
182
String errorMsg = String .format ("The length of partitionValues %s is not equal to " +
198
183
"the partitionColumnNames %s." , partitionValues .length , partitionColumnNames .size ());
@@ -214,10 +199,9 @@ private Partition getPartition(Long recordCount,
214
199
215
200
return new Partition (partitionName , convertToSystemDefaultTime (lastUpdateTime ),
216
201
recordCount , fileSizeInBytes , fileCount );
217
-
218
202
}
219
203
220
- private Long convertToSystemDefaultTime (org . apache . paimon . data . Timestamp lastUpdateTime ) {
204
+ private Long convertToSystemDefaultTime (Timestamp lastUpdateTime ) {
221
205
LocalDateTime localDateTime = lastUpdateTime .toLocalDateTime ();
222
206
ZoneId zoneId = ZoneId .systemDefault ();
223
207
ZonedDateTime zonedDateTime = localDateTime .atZone (zoneId );
@@ -533,15 +517,14 @@ public long getTableCreateTime(String dbName, String tblName) {
533
517
DataType updateTimeType = rowType .getTypeAt (rowType .getFieldIndex ("update_time" ));
534
518
int [] projected = new int [] {0 , 6 };
535
519
PredicateBuilder predicateBuilder = new PredicateBuilder (rowType );
536
- Predicate equal = predicateBuilder .equal (predicateBuilder .indexOf ("schema_id" ), 0 );
520
+ Predicate equal = predicateBuilder .equal (predicateBuilder .indexOf ("schema_id" ), 0L );
537
521
RecordReader <InternalRow > recordReader = table .newReadBuilder ().withProjection (projected )
538
522
.withFilter (equal ).newRead ().createReader (table .newScan ().plan ());
539
523
iterator = new RecordReaderIterator <>(recordReader );
540
524
while (iterator .hasNext ()) {
541
525
InternalRow rowData = iterator .next ();
542
526
Long schemaIdValue = rowData .getLong (0 );
543
- org .apache .paimon .data .Timestamp updateTime = rowData
544
- .getTimestamp (1 , DataTypeChecks .getPrecision (updateTimeType ));
527
+ Timestamp updateTime = rowData .getTimestamp (1 , DataTypeChecks .getPrecision (updateTimeType ));
545
528
if (schemaIdValue == 0 ) {
546
529
return updateTime .getMillisecond ();
547
530
}
@@ -577,8 +560,7 @@ public long getTableUpdateTime(String dbName, String tblName) {
577
560
iterator = new RecordReaderIterator <>(recordReader );
578
561
while (iterator .hasNext ()) {
579
562
InternalRow rowData = iterator .next ();
580
- org .apache .paimon .data .Timestamp commitTime = rowData
581
- .getTimestamp (0 , DataTypeChecks .getPrecision (commitTimeType ));
563
+ Timestamp commitTime = rowData .getTimestamp (0 , DataTypeChecks .getPrecision (commitTimeType ));
582
564
if (convertToSystemDefaultTime (commitTime ) > lastCommitTime ) {
583
565
lastCommitTime = convertToSystemDefaultTime (commitTime );
584
566
}
@@ -623,4 +605,50 @@ public List<PartitionInfo> getPartitions(Table table, List<String> partitionName
623
605
}
624
606
return result ;
625
607
}
608
+
609
+ @ Override
610
+ public void refreshTable (String srDbName , Table table , List <String > partitionNames , boolean onlyCachedPartitions ) {
611
+ String tableName = table .getCatalogTableName ();
612
+ Identifier identifier = new Identifier (srDbName , tableName );
613
+ paimonNativeCatalog .invalidateTable (identifier );
614
+ try {
615
+ ((PaimonTable ) table ).setPaimonNativeTable (paimonNativeCatalog .getTable (identifier ));
616
+ if (partitionNames != null && !partitionNames .isEmpty ()) {
617
+ // todo: paimon does not support to refresh an exact partition
618
+ this .refreshPartitionInfo (identifier );
619
+ } else {
620
+ this .refreshPartitionInfo (identifier );
621
+ }
622
+ // Preheat manifest files, disabled by default
623
+ if (Config .enable_paimon_refresh_manifest_files ) {
624
+ if (partitionNames == null || partitionNames .isEmpty ()) {
625
+ ((PaimonTable ) table ).getNativeTable ().newReadBuilder ().newScan ().plan ();
626
+ } else {
627
+ List <String > partitionColumnNames = table .getPartitionColumnNames ();
628
+ Map <String , String > partitionSpec = new HashMap <>();
629
+ for (String partitionName : partitionNames ) {
630
+ partitionSpec .put (String .join ("," , partitionColumnNames ), partitionName );
631
+ }
632
+ ((PaimonTable ) table ).getNativeTable ().newReadBuilder ()
633
+ .withPartitionFilter (partitionSpec ).newScan ().plan ();
634
+ }
635
+ }
636
+ tables .put (identifier , table );
637
+ } catch (Exception e ) {
638
+ LOG .error ("Failed to refresh table {}.{}.{}." , catalogName , srDbName , tableName , e );
639
+ }
640
+ }
641
+
642
+ private void refreshPartitionInfo (Identifier identifier ) {
643
+ if (paimonNativeCatalog instanceof CachingCatalog ) {
644
+ try {
645
+ paimonNativeCatalog .invalidateTable (identifier );
646
+ ((CachingCatalog ) paimonNativeCatalog ).refreshPartitions (identifier );
647
+ } catch (Catalog .TableNotExistException e ) {
648
+ throw new RuntimeException (e );
649
+ }
650
+ } else {
651
+ LOG .warn ("Current catalog {} does not support cache." , catalogName );
652
+ }
653
+ }
626
654
}
0 commit comments