@@ -282,32 +282,6 @@ export enum Status {
282282 *
283283 * Defines a single partition column. Multiple partition fields can be combined
284284 * in an IcebergPartitionSpec to create multi-level partitioning.
285- *
286- * @example
287- * // Partition by day from a timestamp field
288- * const table = new Table(stack, 'MyTable', {
289- * tableName: 'my_table',
290- * namespace: myNamespace,
291- * openTableFormat: OpenTableFormat.ICEBERG,
292- * icebergMetadata: {
293- * icebergSchema: {
294- * schemaFieldList: [
295- * { id: 1, name: 'event_id', type: 'string' },
296- * { id: 2, name: 'event_time', type: 'timestamp' },
297- * { id: 3, name: 'category', type: 'string' },
298- * ],
299- * },
300- * icebergPartitionSpec: {
301- * fields: [
302- * {
303- * sourceId: 2, // References event_time field (id: 2)
304- * transform: 'day', // Partition by day
305- * name: 'event_day', // Name for partition column
306- * },
307- * ],
308- * },
309- * },
310- * });
311285 */
312286export interface IcebergPartitionField {
313287 /**
@@ -338,40 +312,6 @@ export interface IcebergPartitionField {
338312 *
339313 * Contains the complete partitioning configuration for a table, including all partition fields.
340314 * Use this to define multi-level partitioning (e.g., partition by date, then by region).
341- *
342- * @example
343- * // Partition by date and category
344- * const table = new Table(stack, 'MyTable', {
345- * tableName: 'my_table',
346- * namespace: myNamespace,
347- * openTableFormat: OpenTableFormat.ICEBERG,
348- * icebergMetadata: {
349- * icebergSchema: {
350- * schemaFieldList: [
351- * { id: 1, name: 'date', type: 'date' },
352- * { id: 2, name: 'user_id', type: 'string' },
353- * { id: 3, name: 'category', type: 'string' },
354- * ],
355- * },
356- * icebergPartitionSpec: {
357- * specId: 0,
358- * fields: [
359- * {
360- * sourceId: 1, // References date field
361- * transform: 'day',
362- * name: 'date_partition',
363- * fieldId: 1000,
364- * },
365- * {
366- * sourceId: 3, // References category field
367- * transform: 'identity',
368- * name: 'category_partition',
369- * fieldId: 1001,
370- * },
371- * ],
372- * },
373- * },
374- * });
375315 */
376316export interface IcebergPartitionSpec {
377317 /**
@@ -414,40 +354,6 @@ export interface IcebergSortField {
414354
415355/**
416356 * Sort order specification for Iceberg table.
417- *
418- * @example
419- * // Sort by timestamp descending, then by user_id ascending
420- * const table = new Table(stack, 'MyTable', {
421- * tableName: 'my_table',
422- * namespace: myNamespace,
423- * openTableFormat: OpenTableFormat.ICEBERG,
424- * icebergMetadata: {
425- * icebergSchema: {
426- * schemaFieldList: [
427- * { id: 1, name: 'event_id', type: 'string' },
428- * { id: 2, name: 'timestamp', type: 'timestamp' },
429- * { id: 3, name: 'user_id', type: 'string' },
430- * ],
431- * },
432- * icebergSortOrder: {
433- * orderId: 1,
434- * fields: [
435- * {
436- * sourceId: 2, // timestamp field
437- * transform: 'identity',
438- * direction: 'desc',
439- * nullOrder: 'nulls-last',
440- * },
441- * {
442- * sourceId: 3, // user_id field
443- * transform: 'identity',
444- * direction: 'asc',
445- * nullOrder: 'nulls-first',
446- * },
447- * ],
448- * },
449- * },
450- * });
451357 */
452358export interface IcebergSortOrder {
453359 /**
@@ -463,6 +369,21 @@ export interface IcebergSortOrder {
463369 readonly fields : IcebergSortField [ ] ;
464370}
465371
372+ /**
373+ * A single table property key-value pair for Iceberg table configuration.
374+ */
375+ export interface TablePropertyEntry {
376+ /**
377+ * The property key.
378+ */
379+ readonly key : string ;
380+
381+ /**
382+ * The property value.
383+ */
384+ readonly value : string ;
385+ }
386+
466387/**
467388 * Contains details about the metadata for an Iceberg table.
468389 * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3tables-table-icebergmetadata.html
@@ -491,10 +412,11 @@ export interface IcebergMetadataProperty {
491412
492413 /**
493414 * Custom properties for the Iceberg table.
415+ * Each entry represents a key-value pair for Iceberg table configuration.
494416 *
495417 * @default - No custom properties
496418 */
497- readonly tableProperties ?: { [ key : string ] : string } ;
419+ readonly tableProperties ?: TablePropertyEntry [ ] ;
498420}
499421
500422/**
@@ -726,11 +648,66 @@ export class Table extends TableBase {
726648 tableBucketArn : props . namespace . tableBucket . tableBucketArn ,
727649 namespace : props . namespace . namespaceName ,
728650 compaction : props . compaction ,
729- icebergMetadata : props . icebergMetadata ,
651+ icebergMetadata : props . icebergMetadata ? {
652+ icebergSchema : {
653+ schemaFieldList : props . icebergMetadata . icebergSchema . schemaFieldList ,
654+ } ,
655+ } : undefined ,
730656 snapshotManagement : props . snapshotManagement ,
731657 withoutMetadata : props . withoutMetadata ? 'Yes' : undefined ,
732658 } ) ;
733659
660+ // Use addPropertyOverride for properties not yet in L1 types
661+ // Override schema to include Id field
662+ if ( props . icebergMetadata ?. icebergSchema . schemaFieldList . some ( f => f . id !== undefined ) ) {
663+ this . _resource . addPropertyOverride (
664+ 'IcebergMetadata.IcebergSchema.SchemaFieldList' ,
665+ props . icebergMetadata . icebergSchema . schemaFieldList . map ( f => ( {
666+ Id : f . id ,
667+ Name : f . name ,
668+ Type : f . type ,
669+ Required : f . required ,
670+ } ) ) ,
671+ ) ;
672+ }
673+ if ( props . icebergMetadata ?. icebergPartitionSpec ) {
674+ this . _resource . addPropertyOverride (
675+ 'IcebergMetadata.IcebergPartitionSpec' ,
676+ {
677+ SpecId : props . icebergMetadata . icebergPartitionSpec . specId ,
678+ Fields : props . icebergMetadata . icebergPartitionSpec . fields . map ( f => ( {
679+ SourceId : f . sourceId ,
680+ Transform : f . transform ,
681+ Name : f . name ,
682+ FieldId : f . fieldId ,
683+ } ) ) ,
684+ } ,
685+ ) ;
686+ }
687+ if ( props . icebergMetadata ?. icebergSortOrder ) {
688+ this . _resource . addPropertyOverride (
689+ 'IcebergMetadata.IcebergSortOrder' ,
690+ {
691+ OrderId : props . icebergMetadata . icebergSortOrder . orderId ,
692+ Fields : props . icebergMetadata . icebergSortOrder . fields . map ( f => ( {
693+ SourceId : f . sourceId ,
694+ Transform : f . transform ,
695+ Direction : f . direction ,
696+ NullOrder : f . nullOrder ,
697+ } ) ) ,
698+ } ,
699+ ) ;
700+ }
701+ if ( props . icebergMetadata ?. tableProperties ) {
702+ this . _resource . addPropertyOverride (
703+ 'IcebergMetadata.TableProperties' ,
704+ props . icebergMetadata . tableProperties . reduce (
705+ ( acc , entry ) => ( { ...acc , [ entry . key ] : entry . value } ) ,
706+ { } as { [ key : string ] : string } ,
707+ ) ,
708+ ) ;
709+ }
710+
734711 this . namespace = props . namespace ;
735712 this . tableName = props . tableName ;
736713 this . tableArn = this . _resource . attrTableArn ;
0 commit comments