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 ;
60
61
import org .apache .paimon .table .source .InnerTableScan ;
61
62
import org .apache .paimon .table .source .ReadBuilder ;
62
63
import org .apache .paimon .table .source .Split ;
63
- import org .apache .paimon .table .system .PartitionsTable ;
64
64
import org .apache .paimon .table .system .SchemasTable ;
65
65
import org .apache .paimon .table .system .SnapshotsTable ;
66
66
import org .apache .paimon .types .DataField ;
69
69
import org .apache .paimon .types .DateType ;
70
70
import org .apache .paimon .types .RowType ;
71
71
import org .apache .paimon .utils .DateTimeUtils ;
72
+ import org .apache .paimon .utils .PartitionPathUtils ;
72
73
73
74
import java .time .LocalDateTime ;
74
75
import java .time .ZoneId ;
75
76
import java .time .ZonedDateTime ;
76
77
import java .util .ArrayList ;
78
+ import java .util .Arrays ;
79
+ import java .util .HashMap ;
77
80
import java .util .List ;
78
81
import java .util .Map ;
79
82
import java .util .Optional ;
@@ -142,39 +145,21 @@ private void updatePartitionInfo(String databaseName, String tableName) {
142
145
partitionColumnTypes .add (dataTableRowType .getTypeAt (dataTableRowType .getFieldIndex (partitionColumnName )));
143
146
}
144
147
145
- Identifier partitionTableIdentifier = new Identifier (databaseName , String .format ("%s%s" , tableName , "$partitions" ));
146
- RecordReaderIterator <InternalRow > iterator = null ;
147
148
try {
148
- PartitionsTable table = (PartitionsTable ) paimonNativeCatalog .getTable (partitionTableIdentifier );
149
- RowType partitionTableRowType = table .rowType ();
150
- DataType lastUpdateTimeType = partitionTableRowType .getTypeAt (partitionTableRowType
151
- .getFieldIndex ("last_update_time" ));
152
- int [] projected = new int [] {0 , 1 , 2 , 3 , 4 };
153
- RecordReader <InternalRow > recordReader = table .newReadBuilder ().withProjection (projected )
154
- .newRead ().createReader (table .newScan ().plan ());
155
- iterator = new RecordReaderIterator <>(recordReader );
156
- while (iterator .hasNext ()) {
157
- InternalRow rowData = iterator .next ();
158
- String partitionStr = rowData .getString (0 ).toString ();
159
- org .apache .paimon .data .Timestamp lastUpdateTime = rowData .getTimestamp (4 ,
160
- DataTypeChecks .getPrecision (lastUpdateTimeType ));
161
- String [] partitionValues = partitionStr .replace ("[" , "" ).replace ("]" , "" )
162
- .split ("," );
163
- Partition partition =
164
- getPartition (rowData .getLong (1 ), rowData .getLong (2 ), rowData .getLong (3 ),
165
- partitionColumnNames , partitionColumnTypes , partitionValues , lastUpdateTime );
166
- this .partitionInfos .put (partition .getPartitionName (), partition );
149
+ List <org .apache .paimon .partition .Partition > partitions = paimonNativeCatalog .listPartitions (identifier );
150
+ for (org .apache .paimon .partition .Partition partition : partitions ) {
151
+ String partitionPath = PartitionPathUtils .generatePartitionPath (partition .spec (), dataTableRowType );
152
+ String [] partitionValues = Arrays .stream (partitionPath .split ("/" ))
153
+ .map (part -> part .split ("=" )[1 ])
154
+ .toArray (String []::new );
155
+ Partition srPartition = getPartition (partition .recordCount (),
156
+ partition .fileSizeInBytes (), partition .fileCount (),
157
+ partitionColumnNames , partitionColumnTypes , partitionValues ,
158
+ Timestamp .fromEpochMillis (partition .lastFileCreationTime ()));
159
+ this .partitionInfos .put (srPartition .getPartitionName (), srPartition );
167
160
}
168
- } catch (Exception e ) {
161
+ } catch (Catalog . TableNotExistException e ) {
169
162
LOG .error ("Failed to update partition info of paimon table {}.{}." , databaseName , tableName , e );
170
- } finally {
171
- if (iterator != null ) {
172
- try {
173
- iterator .close ();
174
- } catch (Exception e ) {
175
- LOG .error ("Failed to update partition info of paimon table {}.{}." , databaseName , tableName , e );
176
- }
177
- }
178
163
}
179
164
}
180
165
@@ -184,7 +169,7 @@ private Partition getPartition(Long recordCount,
184
169
List <String > partitionColumnNames ,
185
170
List <DataType > partitionColumnTypes ,
186
171
String [] partitionValues ,
187
- org . apache . paimon . data . Timestamp lastUpdateTime ) {
172
+ Timestamp lastUpdateTime ) {
188
173
if (partitionValues .length != partitionColumnNames .size ()) {
189
174
String errorMsg = String .format ("The length of partitionValues %s is not equal to " +
190
175
"the partitionColumnNames %s." , partitionValues .length , partitionColumnNames .size ());
@@ -206,10 +191,9 @@ private Partition getPartition(Long recordCount,
206
191
207
192
return new Partition (partitionName , convertToSystemDefaultTime (lastUpdateTime ),
208
193
recordCount , fileSizeInBytes , fileCount );
209
-
210
194
}
211
195
212
- private Long convertToSystemDefaultTime (org . apache . paimon . data . Timestamp lastUpdateTime ) {
196
+ private Long convertToSystemDefaultTime (Timestamp lastUpdateTime ) {
213
197
LocalDateTime localDateTime = lastUpdateTime .toLocalDateTime ();
214
198
ZoneId zoneId = ZoneId .systemDefault ();
215
199
ZonedDateTime zonedDateTime = localDateTime .atZone (zoneId );
@@ -521,15 +505,14 @@ public long getTableCreateTime(String dbName, String tblName) {
521
505
DataType updateTimeType = rowType .getTypeAt (rowType .getFieldIndex ("update_time" ));
522
506
int [] projected = new int [] {0 , 6 };
523
507
PredicateBuilder predicateBuilder = new PredicateBuilder (rowType );
524
- Predicate equal = predicateBuilder .equal (predicateBuilder .indexOf ("schema_id" ), 0 );
508
+ Predicate equal = predicateBuilder .equal (predicateBuilder .indexOf ("schema_id" ), 0L );
525
509
RecordReader <InternalRow > recordReader = table .newReadBuilder ().withProjection (projected )
526
510
.withFilter (equal ).newRead ().createReader (table .newScan ().plan ());
527
511
iterator = new RecordReaderIterator <>(recordReader );
528
512
while (iterator .hasNext ()) {
529
513
InternalRow rowData = iterator .next ();
530
514
Long schemaIdValue = rowData .getLong (0 );
531
- org .apache .paimon .data .Timestamp updateTime = rowData
532
- .getTimestamp (1 , DataTypeChecks .getPrecision (updateTimeType ));
515
+ Timestamp updateTime = rowData .getTimestamp (1 , DataTypeChecks .getPrecision (updateTimeType ));
533
516
if (schemaIdValue == 0 ) {
534
517
return updateTime .getMillisecond ();
535
518
}
@@ -565,8 +548,7 @@ public long getTableUpdateTime(String dbName, String tblName) {
565
548
iterator = new RecordReaderIterator <>(recordReader );
566
549
while (iterator .hasNext ()) {
567
550
InternalRow rowData = iterator .next ();
568
- org .apache .paimon .data .Timestamp commitTime = rowData
569
- .getTimestamp (0 , DataTypeChecks .getPrecision (commitTimeType ));
551
+ Timestamp commitTime = rowData .getTimestamp (0 , DataTypeChecks .getPrecision (commitTimeType ));
570
552
if (convertToSystemDefaultTime (commitTime ) > lastCommitTime ) {
571
553
lastCommitTime = convertToSystemDefaultTime (commitTime );
572
554
}
@@ -610,4 +592,50 @@ public List<PartitionInfo> getPartitions(Table table, List<String> partitionName
610
592
}
611
593
return result ;
612
594
}
595
+
596
+ @ Override
597
+ public void refreshTable (String srDbName , Table table , List <String > partitionNames , boolean onlyCachedPartitions ) {
598
+ String tableName = table .getName ();
599
+ Identifier identifier = new Identifier (srDbName , tableName );
600
+ paimonNativeCatalog .invalidateTable (identifier );
601
+ try {
602
+ ((PaimonTable ) table ).setPaimonNativeTable (paimonNativeCatalog .getTable (identifier ));
603
+ if (partitionNames != null && !partitionNames .isEmpty ()) {
604
+ // todo: paimon does not support to refresh an exact partition
605
+ this .refreshPartitionInfo (identifier );
606
+ } else {
607
+ this .refreshPartitionInfo (identifier );
608
+ }
609
+ // Preheat manifest files, disabled by default
610
+ if (Config .enable_paimon_refresh_manifest_files ) {
611
+ if (partitionNames == null || partitionNames .isEmpty ()) {
612
+ ((PaimonTable ) table ).getNativeTable ().newReadBuilder ().newScan ().plan ();
613
+ } else {
614
+ List <String > partitionColumnNames = table .getPartitionColumnNames ();
615
+ Map <String , String > partitionSpec = new HashMap <>();
616
+ for (String partitionName : partitionNames ) {
617
+ partitionSpec .put (String .join ("," , partitionColumnNames ), partitionName );
618
+ }
619
+ ((PaimonTable ) table ).getNativeTable ().newReadBuilder ()
620
+ .withPartitionFilter (partitionSpec ).newScan ().plan ();
621
+ }
622
+ }
623
+ tables .put (identifier , table );
624
+ } catch (Exception e ) {
625
+ LOG .error ("Failed to refresh table {}.{}.{}." , catalogName , srDbName , tableName , e );
626
+ }
627
+ }
628
+
629
+ private void refreshPartitionInfo (Identifier identifier ) {
630
+ if (paimonNativeCatalog instanceof CachingCatalog ) {
631
+ try {
632
+ paimonNativeCatalog .invalidateTable (identifier );
633
+ ((CachingCatalog ) paimonNativeCatalog ).refreshPartitions (identifier );
634
+ } catch (Catalog .TableNotExistException e ) {
635
+ throw new RuntimeException (e );
636
+ }
637
+ } else {
638
+ LOG .warn ("Current catalog {} does not support cache." , catalogName );
639
+ }
640
+ }
613
641
}
0 commit comments