Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(redshift): tables were dropped on table name change #24308

Merged
merged 56 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6b3a91c
buildup
Rizxcviii Feb 21, 2023
61c09aa
initial commit: test, initial work
Rizxcviii Feb 21, 2023
11c42ec
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Feb 22, 2023
6899734
reverting, updating resource id
Rizxcviii Feb 22, 2023
125d1f5
updating test
Rizxcviii Feb 22, 2023
5448bf9
more explicit with test
Rizxcviii Feb 22, 2023
96a5e8d
catching error when table name is changed
Rizxcviii Feb 23, 2023
93d7459
test to delete table name
Rizxcviii Feb 24, 2023
464847c
modification: new physicalResourceId creates new resource
Rizxcviii Feb 27, 2023
0c9d55d
modification: storing Data key in return object, to keep track of pre…
Rizxcviii Feb 28, 2023
adb99cc
modification
Rizxcviii Feb 28, 2023
43ad1cb
modification: update to delete scenario
Rizxcviii Mar 1, 2023
cf36699
modification: new resources are not created on table name change
Rizxcviii Mar 1, 2023
c444707
addition: test case for Data not existing
Rizxcviii Mar 1, 2023
da2f78f
modification: bugfix for failing test
Rizxcviii Mar 1, 2023
ac30602
integ test
Rizxcviii Mar 1, 2023
940942a
deleting table in integ test
Rizxcviii Mar 2, 2023
1724d38
creating new tables from stack id
Rizxcviii Mar 2, 2023
c8a3165
reverting replace
Rizxcviii Mar 2, 2023
6143c67
reverting file
Rizxcviii Mar 2, 2023
77b9ec1
reworking priviliges for this PR
Rizxcviii Mar 2, 2023
0f332df
modification: using stack id rather than request id, is the same as m…
Rizxcviii Mar 2, 2023
baacd96
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Mar 3, 2023
f5301d3
modification: deletion for both legacy and current tables
Rizxcviii Mar 6, 2023
312fc64
modification: this should not be called
Rizxcviii Mar 7, 2023
8b31212
addition: default actions
Rizxcviii Mar 7, 2023
021bd6d
addition: test for table id appended
Rizxcviii Mar 8, 2023
c61a7a3
integ test for change to table
Rizxcviii Mar 8, 2023
d06549e
modification: updating integ to remove table name change
Rizxcviii Mar 8, 2023
cf044b6
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Mar 9, 2023
e646409
integ test
Rizxcviii Mar 17, 2023
e9beee4
modification: test update for new cdk tests
Rizxcviii Mar 20, 2023
adfd101
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Oct 6, 2023
942e503
removing old files
Rizxcviii Oct 6, 2023
dbca263
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Oct 6, 2023
0dbd0d0
removing table id, not needed
Rizxcviii Oct 6, 2023
6ecf510
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Oct 28, 2023
842bfe2
removing tableid
Rizxcviii Nov 1, 2023
d2917e0
fixing test
Rizxcviii Nov 1, 2023
a879bc7
removing try, catch. Breaking change instead
Rizxcviii Nov 1, 2023
e2b6814
test
Rizxcviii Nov 1, 2023
61d608c
deleting only table name, not resource id
Rizxcviii Nov 1, 2023
11fe979
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Nov 1, 2023
0099b2e
removing diffAssets, was causing failure
Rizxcviii Nov 1, 2023
c539e47
moving tablename to top of handler
Rizxcviii Nov 9, 2023
3d9714b
using `newTableName`
Rizxcviii Nov 9, 2023
71a49f6
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Nov 9, 2023
1ee3968
Merge branch 'main' into feature/persist-table-name-change
scanlonp Nov 14, 2023
47443ee
disabling functionality for older tables
Rizxcviii Nov 20, 2023
ef50f34
revert
Rizxcviii Nov 20, 2023
4f4d609
Merge branch 'main' into feature/persist-table-name-change
Rizxcviii Nov 20, 2023
c571c8c
using old table name if needed
Rizxcviii Nov 20, 2023
1a3f408
linting
Rizxcviii Nov 20, 2023
f0f1ec8
changing table name README
Rizxcviii Dec 7, 2023
5019bb8
Merge branch 'main' into feature/persist-table-name-change
scanlonp Dec 7, 2023
eaa7285
Merge branch 'main' into feature/persist-table-name-change
mergify[bot] Dec 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ async function updatePrivileges(
if (oldTablePrivileges !== tablePrivileges) {
await revokePrivileges(username, oldTablePrivileges, clusterProps);
await grantPrivileges(username, tablePrivileges, clusterProps);
return { replace: false };
}

return { replace: false };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,26 @@ export async function handler(props: TableAndClusterProps, event: AWSLambda.Clou

if (event.RequestType === 'Create') {
const tableName = await createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
return { PhysicalResourceId: tableName };
return {
PhysicalResourceId: tableName,
Data: { TableName: tableName },
};
} else if (event.RequestType === 'Delete') {
await dropTable(event.PhysicalResourceId, tableAndClusterProps);
await dropTable(event.ResourceProperties.Data.TableName, tableAndClusterProps);
return;
} else if (event.RequestType === 'Update') {
const tableName = await updateTable(
event.PhysicalResourceId,
event.OldResourceProperties.Data.TableName ?? event.PhysicalResourceId,
tableNamePrefix,
tableNameSuffix,
tableColumns,
tableAndClusterProps,
event.OldResourceProperties as TableAndClusterProps,
);
return { PhysicalResourceId: tableName };
return {
PhysicalResourceId: event.PhysicalResourceId,
Data: { TableName: tableName },
};
} else {
/* eslint-disable-next-line dot-notation */
throw new Error(`Unrecognized event type: ${event['RequestType']}`);
Expand Down Expand Up @@ -87,11 +93,6 @@ async function updateTable(
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
}

const oldTableNamePrefix = oldResourceProperties.tableName.prefix;
if (tableNamePrefix !== oldTableNamePrefix) {
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, tableAndClusterProps);
}

const oldTableColumns = oldResourceProperties.tableColumns;
const columnDeletions = oldTableColumns.filter(oldColumn => (
tableColumns.every(column => oldColumn.name !== column.name)
Expand Down Expand Up @@ -156,6 +157,12 @@ async function updateTable(

await Promise.all(alterationStatements.map(statement => executeStatement(statement, tableAndClusterProps)));

const oldTableNamePrefix = oldResourceProperties.tableName.prefix;
if (tableNamePrefix !== oldTableNamePrefix) {
await executeStatement(`ALTER TABLE ${tableName} RENAME TO ${tableNamePrefix + tableNameSuffix}`, tableAndClusterProps);
return tableNamePrefix + tableNameSuffix;
}

return tableName;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-redshift/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
"@aws-cdk/integ-tests": "0.0.0",
"@types/jest": "^27.5.2",
"aws-sdk": "^2.1317.0",
"jest": "^27.5.1"
"jest": "^27.5.1",
"jsii": "v4.9-next"
},
"dependencies": {
"@aws-cdk/aws-ec2": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import { Column, TableDistStyle, TableSortStyle } from '../../lib';
import { handler as manageTable } from '../../lib/private/database-query-provider/table';
import { TableAndClusterProps } from '../../lib/private/database-query-provider/types';

type ResourcePropertiesType = TableAndClusterProps & { ServiceToken: string };
type ResourcePropertiesType = TableAndClusterProps & { ServiceToken: string, Data: { TableName: string } };

const tableNamePrefix = 'tableNamePrefix';
const tableColumns = [{ name: 'col1', dataType: 'varchar(1)' }];
const clusterName = 'clusterName';
const adminUserArn = 'adminUserArn';
const databaseName = 'databaseName';
const physicalResourceId = 'PhysicalResourceId';
const requestId = 'requestId';
const requestIdTruncated = 'requestI';
const resourceProperties: ResourcePropertiesType = {
tableName: {
prefix: tableNamePrefix,
Expand All @@ -28,10 +30,11 @@ const resourceProperties: ResourcePropertiesType = {
clusterName,
adminUserArn,
databaseName,
Data: {
TableName: `${tableNamePrefix}${requestIdTruncated}`,
},
ServiceToken: '',
};
const requestId = 'requestId';
const requestIdTruncated = 'requestI';
const genericEvent: AWSLambda.CloudFormationCustomResourceEventCommon = {
ResourceProperties: resourceProperties,
ServiceToken: '',
Expand All @@ -56,6 +59,9 @@ describe('create', () => {
const event = baseEvent;

await expect(manageTable(resourceProperties, event)).resolves.toEqual({
Data: {
TableName: `${tableNamePrefix}${requestIdTruncated}`,
},
PhysicalResourceId: `${tableNamePrefix}${requestIdTruncated}`,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Expand All @@ -74,6 +80,9 @@ describe('create', () => {
};

await expect(manageTable(newResourceProperties, event)).resolves.toEqual({
Data: {
TableName: tableNamePrefix,
},
PhysicalResourceId: tableNamePrefix,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Expand Down Expand Up @@ -163,7 +172,7 @@ describe('delete', () => {
await manageTable(resourceProperties, event);

expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `DROP TABLE ${physicalResourceId}`,
Sql: `DROP TABLE ${event.ResourceProperties.Data.TableName}`,
}));
});
});
Expand Down Expand Up @@ -200,6 +209,9 @@ describe('update', () => {
};

await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({
Data: {
TableName: `${tableNamePrefix}${requestIdTruncated}`,
},
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).not.toHaveBeenCalled();
Expand All @@ -221,22 +233,58 @@ describe('update', () => {
}));
});

test('replaces if table name changes', async () => {
const newTableNamePrefix = 'newTableNamePrefix';
const newResourceProperties = {
...resourceProperties,
tableName: {
...resourceProperties.tableName,
prefix: newTableNamePrefix,
},
};
describe('table name', () => {
test('does not replace if table name changes', async () => {
const newResourceProperties = {
...resourceProperties,
tableName: {
...resourceProperties.tableName,
prefix: 'newTableName',
generateSuffix: 'false',
},
};

await expect(manageTable(newResourceProperties, event)).resolves.not.toMatchObject({
PhysicalResourceId: physicalResourceId,
await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${event.OldResourceProperties.Data.TableName} RENAME TO newTableName`,
}));
});

test('does not replace if table name added', async () => {
const newResourceProperties = {
...resourceProperties,
tableName: {
prefix: 'newTable',
generateSuffix: 'false',
},
};

await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${event.OldResourceProperties.Data.TableName} RENAME TO newTable`,
}));
});

test('does not replace if table name removed', async () => {
const newResourceProperties = {
...resourceProperties,
tableName: {
prefix: 'Table',
generateSuffix: 'true',
},
};

await expect(manageTable(newResourceProperties, event)).resolves.toMatchObject({
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${event.OldResourceProperties.Data.TableName} RENAME TO Table${requestIdTruncated}`,
}));
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: expect.stringMatching(new RegExp(`CREATE TABLE ${newTableNamePrefix}${requestIdTruncated}`)),
}));
});

test('does not replace if table columns removed', async () => {
Expand All @@ -249,7 +297,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} DROP COLUMN col1`,
Sql: expect.stringMatching(new RegExp(`ALTER TABLE ${newResourceProperties.tableName.prefix}.+ DROP COLUMN col1`)),
}));
});

Expand All @@ -266,7 +314,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ADD ${newTableColumnName} ${newTableColumnDataType}`,
Sql: `ALTER TABLE ${event.OldResourceProperties.Data.TableName} ADD ${newTableColumnName} ${newTableColumnDataType}`,
}));
});

Expand Down Expand Up @@ -323,7 +371,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ALTER DISTSTYLE ${newDistStyle}`,
Sql: `ALTER TABLE ${newEvent.OldResourceProperties.Data.TableName} ALTER DISTSTYLE ${newDistStyle}`,
}));
});

Expand Down Expand Up @@ -385,7 +433,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ALTER DISTKEY ${newDistKey}`,
Sql: `ALTER TABLE ${newEvent.OldResourceProperties.Data.TableName} ALTER DISTKEY ${newDistKey}`,
}));
});
});
Expand Down Expand Up @@ -465,7 +513,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ALTER COMPOUND SORTKEY(col2)`,
Sql: `ALTER TABLE ${newEvent.OldResourceProperties.Data.TableName} ALTER COMPOUND SORTKEY(col2)`,
}));
});

Expand All @@ -488,7 +536,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ALTER COMPOUND SORTKEY(col1)`,
Sql: `ALTER TABLE ${newEvent.OldResourceProperties.Data.TableName} ALTER COMPOUND SORTKEY(col1)`,
}));
});

Expand All @@ -511,7 +559,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `ALTER TABLE ${physicalResourceId} ALTER SORTKEY AUTO`,
Sql: `ALTER TABLE ${newEvent.OldResourceProperties.Data.TableName} ALTER SORTKEY AUTO`,
}));
});
});
Expand All @@ -528,7 +576,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `COMMENT ON TABLE ${physicalResourceId} IS '${newComment}'`,
Sql: `COMMENT ON TABLE ${event.OldResourceProperties.Data.TableName} IS '${newComment}'`,
}));
});

Expand All @@ -548,7 +596,7 @@ describe('update', () => {
PhysicalResourceId: physicalResourceId,
});
expect(mockExecuteStatement).toHaveBeenCalledWith(expect.objectContaining({
Sql: `COMMENT ON TABLE ${physicalResourceId} IS NULL`,
Sql: `COMMENT ON TABLE ${event.OldResourceProperties.Data.TableName} IS NULL`,
}));
});
});
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-redshift/test/integ.database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const databaseOptions = {
const user = new redshift.User(stack, 'User', databaseOptions);
const table = new redshift.Table(stack, 'Table', {
...databaseOptions,
tableName: 'IntegTable',
tableColumns: [
{ name: 'col1', dataType: 'varchar(4)', distKey: true },
{ name: 'col2', dataType: 'float', sortKey: true },
Expand Down