Skip to content

Commit c7a2825

Browse files
author
Olena Rostotskyy
committed
fix: address PR review - use addPropertyOverride for new L1 properties, use TablePropertyEntry, simplify integ test, fix lint
1 parent acc5879 commit c7a2825

File tree

9 files changed

+164
-169
lines changed

9 files changed

+164
-169
lines changed

packages/@aws-cdk/aws-s3tables-alpha/lib/table.ts

Lines changed: 73 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
312286
export 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
*/
376316
export 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
*/
452358
export 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;

packages/@aws-cdk/aws-s3tables-alpha/test/integration/integ.table-with-partition-sort.js.snapshot/TablePartitionSortIntegTestDefaultTestDeployAssertC1659EB1.assets.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-s3tables-alpha/test/integration/integ.table-with-partition-sort.js.snapshot/TablePartitionSortIntegTestDefaultTestDeployAssertC1659EB1.template.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-s3tables-alpha/test/integration/integ.table-with-partition-sort.js.snapshot/TableWithPartitionSortStack.assets.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)