Skip to content

Commit

Permalink
Hide unlogged/temporary tables (#2157)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie authored Aug 16, 2024
2 parents abbae04 + a98eafe commit dc64350
Show file tree
Hide file tree
Showing 24 changed files with 1,194 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .changeset/poor-bears-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"graphile-build-pg": patch
"postgraphile": patch
"@dataplan/pg": patch
---

🚨 PostGraphile now ignores unlogged database tables by default.
5 changes: 0 additions & 5 deletions grafast/dataplan-pg/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,6 @@ declare global {
*/
interface PgCodecExtensions {
oid?: string;
pg?: {
serviceName: string;
schemaName: string;
name: string;
};
listItemNonNull?: boolean;
isEnumTableEnum?: boolean;
}
Expand Down
20 changes: 20 additions & 0 deletions graphile-build/graphile-build-pg/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,21 @@ declare global {
*/
namespace DataplanPg {
interface PgResourceExtensions {
description?: string;
tags: Partial<GraphileBuild.PgResourceTags>;
singleOutputParameterName?: string;
/** For v4 compatibility, what's the name of the actual table. */
pg?: {
serviceName: string;
schemaName: string;
name: string;
/**
* - p = permanent table/sequence
* - u = unlogged table/sequence
* - t = temporary table/sequence
*/
// eslint-disable-next-line @typescript-eslint/ban-types
persistence?: "p" | "u" | "t" | (string & {}) | null;
};
}

Expand All @@ -137,6 +145,18 @@ declare global {
/** If false but the codec has attributes then it's probably a composite type */
isTableLike?: boolean;
tags: Partial<GraphileBuild.PgCodecTags>;
pg?: {
serviceName: string;
schemaName: string;
name: string;
/**
* - p = permanent table/sequence
* - u = unlogged table/sequence
* - t = temporary table/sequence
*/
// eslint-disable-next-line @typescript-eslint/ban-types
persistence?: "p" | "u" | "t" | (string & {}) | null;
};
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ export const PgCodecsPlugin: GraphileConfig.Plugin = {
serviceName,
schemaName: pgClass.getNamespace()!.nspname,
name: pgClass.relname,
...(pgClass.relpersistence !== "p"
? {
persistence: pgClass.relpersistence,
}
: null),
},
tags,
};
Expand Down
47 changes: 37 additions & 10 deletions graphile-build/graphile-build-pg/src/plugins/PgTablesPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
PgCodec,
PgCodecAttribute,
PgResource,
PgResourceExtensions,
PgResourceOptions,
PgResourceUnique,
} from "@dataplan/pg";
Expand Down Expand Up @@ -459,12 +460,17 @@ export const PgTablesPlugin: GraphileConfig.Plugin = {
const isVirtual = !["r", "v", "m", "f", "p"].includes(
pgClass.relkind,
);
const extensions = {
const extensions: PgResourceExtensions = {
description,
pg: {
serviceName,
schemaName: pgClass.getNamespace()!.nspname,
name: pgClass.relname,
...(pgClass.relpersistence !== "p"
? {
persistence: pgClass.relpersistence,
}
: null),
},
tags: {
...tags,
Expand Down Expand Up @@ -568,23 +574,44 @@ export const PgTablesPlugin: GraphileConfig.Plugin = {
provides: ["default"],
before: ["inferred", "override"],
callback(behavior, codec) {
return [
"resource:select",
"table",
...(!codec.isAnonymous
? ["resource:insert", "resource:update", "resource:delete"]
: []),
behavior,
];
if (codec.attributes) {
const isUnloggedOrTemp =
codec.extensions?.pg?.persistence === "u" ||
codec.extensions?.pg?.persistence === "t";
return [
"resource:select",
"table",
...(!codec.isAnonymous
? ["resource:insert", "resource:update", "resource:delete"]
: []),
behavior,
...(isUnloggedOrTemp
? [
"-resource:select -resource:insert -resource:update -resource:delete",
]
: []),
];
} else {
return [behavior];
}
},
},
pgResource: {
provides: ["default"],
before: ["inferred", "override"],
callback(behavior, resource) {
const isFunction = !!resource.parameters;
const isUnloggedOrTemp =
resource.extensions?.pg?.persistence === "u" ||
resource.extensions?.pg?.persistence === "t";
return [
...(!resource.parameters ? ["resource:select"] : []),
...(!isFunction && !isUnloggedOrTemp ? ["resource:select"] : []),
behavior,
...(isUnloggedOrTemp
? [
"-resource:select -resource:insert -resource:update -resource:delete",
]
: []),
];
},
},
Expand Down
5 changes: 5 additions & 0 deletions postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ create table c.person (
created_at timestamp default current_timestamp
);

create unlogged table c.unlogged (
id serial primary key,
nonsense text
);

do $_$
begin
if current_setting('server_version_num')::int >= 90500 then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,43 @@ const spec_personSecret = {
executor: executor
};
const personSecretCodec = recordCodec(spec_personSecret);
const unloggedIdentifier = sql.identifier("c", "unlogged");
const unloggedCodec = recordCodec({
name: "unlogged",
identifier: unloggedIdentifier,
attributes: Object.assign(Object.create(null), {
id: {
description: undefined,
codec: TYPES.int,
notNull: true,
hasDefault: true,
extensions: {
tags: {}
}
},
nonsense: {
description: undefined,
codec: TYPES.text,
notNull: false,
hasDefault: false,
extensions: {
tags: {}
}
}
}),
description: undefined,
extensions: {
isTableLike: true,
pg: {
serviceName: "main",
schemaName: "c",
name: "unlogged",
persistence: "u"
},
tags: Object.create(null)
},
executor: executor
});
const viewTableIdentifier = sql.identifier("a", "view_table");
const spec_viewTable = {
name: "viewTable",
Expand Down Expand Up @@ -3562,6 +3599,7 @@ const registry = makeRegistry({
uniqueForeignKey: uniqueForeignKeyCodec,
myTable: myTableCodec,
personSecret: personSecretCodec,
unlogged: unloggedCodec,
viewTable: viewTableCodec,
compoundKey: compoundKeyCodec,
bool: TYPES.boolean,
Expand Down Expand Up @@ -5898,6 +5936,33 @@ const registry = makeRegistry({
}
},
person_secret: registryConfig_pgResources_person_secret_person_secret,
unlogged: {
executor: executor,
name: "unlogged",
identifier: "main.c.unlogged",
from: unloggedIdentifier,
codec: unloggedCodec,
uniques: [{
isPrimary: true,
attributes: ["id"],
description: undefined,
extensions: {
tags: Object.create(null)
}
}],
isVirtual: false,
description: undefined,
extensions: {
description: undefined,
pg: {
serviceName: "main",
schemaName: "c",
name: "unlogged",
persistence: "u"
},
tags: {}
}
},
view_table: {
executor: executor,
name: "view_table",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,43 @@ const spec_personSecret = {
executor: executor
};
const personSecretCodec = recordCodec(spec_personSecret);
const unloggedIdentifier = sql.identifier("c", "unlogged");
const unloggedCodec = recordCodec({
name: "unlogged",
identifier: unloggedIdentifier,
attributes: Object.assign(Object.create(null), {
id: {
description: undefined,
codec: TYPES.int,
notNull: true,
hasDefault: true,
extensions: {
tags: {}
}
},
nonsense: {
description: undefined,
codec: TYPES.text,
notNull: false,
hasDefault: false,
extensions: {
tags: {}
}
}
}),
description: undefined,
extensions: {
isTableLike: true,
pg: {
serviceName: "main",
schemaName: "c",
name: "unlogged",
persistence: "u"
},
tags: Object.create(null)
},
executor: executor
});
const viewTableIdentifier = sql.identifier("a", "view_table");
const spec_viewTable = {
name: "viewTable",
Expand Down Expand Up @@ -3562,6 +3599,7 @@ const registry = makeRegistry({
uniqueForeignKey: uniqueForeignKeyCodec,
myTable: myTableCodec,
personSecret: personSecretCodec,
unlogged: unloggedCodec,
viewTable: viewTableCodec,
compoundKey: compoundKeyCodec,
bool: TYPES.boolean,
Expand Down Expand Up @@ -5898,6 +5936,33 @@ const registry = makeRegistry({
}
},
person_secret: registryConfig_pgResources_person_secret_person_secret,
unlogged: {
executor: executor,
name: "unlogged",
identifier: "main.c.unlogged",
from: unloggedIdentifier,
codec: unloggedCodec,
uniques: [{
isPrimary: true,
attributes: ["id"],
description: undefined,
extensions: {
tags: Object.create(null)
}
}],
isVirtual: false,
description: undefined,
extensions: {
description: undefined,
pg: {
serviceName: "main",
schemaName: "c",
name: "unlogged",
persistence: "u"
},
tags: {}
}
},
view_table: {
executor: executor,
name: "view_table",
Expand Down
Loading

0 comments on commit dc64350

Please sign in to comment.