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

[AWS] fix: raw sql query not being mapped properly on RDS (#578) #1071

Merged
merged 9 commits into from
Sep 5, 2023
18 changes: 17 additions & 1 deletion drizzle-orm/src/aws-data-api/pg/session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ExecuteStatementCommandOutput, Field, RDSDataClient } from '@aws-sdk/client-rds-data';
import type { ColumnMetadata, ExecuteStatementCommandOutput, Field, RDSDataClient } from '@aws-sdk/client-rds-data';
import {
BeginTransactionCommand,
CommitTransactionCommand,
Expand Down Expand Up @@ -48,6 +48,7 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep
resourceArn: options.resourceArn,
database: options.database,
transactionId,
includeResultMetadata: !fields && !customResultMapper,
});
}

Expand Down Expand Up @@ -80,6 +81,9 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep
const { fields, rawQuery, client, customResultMapper } = this;
if (!fields && !customResultMapper) {
const result = await client.send(rawQuery);
if (result.columnMetadata && result.columnMetadata.length > 0) {
return this.mapResultRows(result.records ?? [], result.columnMetadata);
}
return result.records ?? [];
}

Expand All @@ -89,6 +93,18 @@ export class AwsDataApiPreparedQuery<T extends PreparedQueryConfig> extends Prep
return row.map((field: Field) => getValueFromDataApi(field));
});
}

/** @internal */
mapResultRows(records: Field[][], columnMetadata: ColumnMetadata[]) {
return records.map((record) => {
const row: Record<string, unknown> = {};
for (const [index, field] of record.entries()) {
const { name } = columnMetadata[index]!;
row[name || index] = getValueFromDataApi(field); // not what to default if name is undefined
}
return row;
});
}
}

export interface AwsDataApiSessionOptions {
Expand Down
25 changes: 24 additions & 1 deletion integration-tests/tests/awsdatapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ test.serial('full join with alias', async (t) => {
test.serial('select from alias', async (t) => {
const { db } = t.context;

const pgTable = pgTableCreator((name) => `prefixed_${name}`);
const pgTable = pgTableCreator((name: string) => `prefixed_${name}`);

const users = pgTable('users', {
id: serial('id').primaryKey(),
Expand Down Expand Up @@ -835,6 +835,29 @@ test.serial('nested transaction rollback', async (t) => {
await db.execute(sql`drop table ${users}`);
});

test.serial('select from raw sql', async (t) => {
const { db } = t.context;

const result = await db.execute(sql`select 1 as id, 'John' as name`);

t.deepEqual(result, [
{ id: 1, name: 'John' },
]);
});

test.serial('select from raw sql with mapped values', async (t) => {
const { db } = t.context;

const result = await db.select({
id: sql<number>`id`,
name: sql<string>`name`,
}).from(sql`(select 1 as id, 'John' as name) as users`);

t.deepEqual(result, [
{ id: 1, name: 'John' },
]);
});

test.after.always(async (t) => {
const ctx = t.context;
await ctx.db.execute(sql`drop table "users"`);
Expand Down