Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .changeset/large-buttons-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"graphile-build-pg": patch
"postgraphile": patch
---

Allow PostgreSQL enum table with no values... catch at GraphQL layer.
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ Original error: ${e.message}
(row) => row[pgAttribute.attname] != null,
);
if (data.length < 1) {
throw new Error(
console.warn(
`Enum table "${pgNamespace.nspname}"."${pgClass.relname}" contains no visible entries for enum constraint '${pgConstraint.conname}'. Check that the table contains at least one row and that the rows are not hidden by row-level security policies.`,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ grant select on enum_tables.simple_enum to postgraphile_test_authenticator;
grant select on enum_tables.abcd to postgraphile_test_authenticator;
grant select on enum_tables.abcd_view to postgraphile_test_authenticator;
grant select on enum_tables.lots_of_enums to postgraphile_test_authenticator;
grant select on enum_tables.empty_enum to postgraphile_test_authenticator;
grant execute on function enum_tables.empty_enum_query() to postgraphile_test_visitor;

grant usage on schema issue_2334 to postgraphile_test_visitor;
grant select, insert (id, col), update (col), delete on issue_2334.foo to postgraphile_test_visitor;
Expand Down
10 changes: 10 additions & 0 deletions postgraphile/postgraphile/__tests__/kitchen-sink-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,16 @@ comment on constraint enum_2 on enum_tables.lots_of_enums is E'@enum\n@enumName
comment on constraint enum_3 on enum_tables.lots_of_enums is E'@enum';
comment on constraint enum_4 on enum_tables.lots_of_enums is E'@enum';

create table enum_tables.empty_enum (
value text primary key,
description text
);
comment on table enum_tables.empty_enum is E'@enum';

create function enum_tables.empty_enum_query() returns enum_tables.empty_enum as $$
select null::text as value, null::text as description;
$$ language sql stable;

-- Enum table needs values added as part of the migration, not as part of the
-- data.
insert into enum_tables.simple_enum (value, description) values
Expand Down
18 changes: 18 additions & 0 deletions postgraphile/postgraphile/__tests__/schema/v4/cjk.1.export.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,24 @@ const resource_PgResource = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,12 @@ const registry = makeRegistry({
}],
extensions: {}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2773,6 +2773,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2773,6 +2773,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PgDeleteSingleStep, PgExecutor, PgSelectStep, TYPES, assertPgClassSingleStep, enumCodec, makeRegistry, pgDeleteSingle, pgInsertSingle, pgSelectFromRecord, pgUpdateSingle, recordCodec, sqlFromArgDigests, sqlValueWithCodec } from "@dataplan/pg";
import { PgDeleteSingleStep, PgExecutor, PgResource, PgSelectStep, TYPES, assertPgClassSingleStep, enumCodec, makeRegistry, pgDeleteSingle, pgInsertSingle, pgSelectFromRecord, pgUpdateSingle, recordCodec, sqlFromArgDigests, sqlValueWithCodec } from "@dataplan/pg";
import { ConnectionStep, EdgeStep, ObjectStep, __ValueStep, access, assertStep, bakedInput, bakedInputRuntime, connection, constant, context, createObjectAndApplyChildren, first, get as get2, inhibitOnNull, inspect, lambda, list, makeDecodeNodeId, makeGrafastSchema, markSyncAndSafe, object, operationPlan, specFromNodeId, trap } from "grafast";
import { GraphQLError, Kind } from "graphql";
import { sql } from "pg-sql2";
Expand Down Expand Up @@ -129,6 +129,34 @@ const abcdViewCodec = recordCodec({
},
executor: executor
});
const emptyEnumIdentifier = sql.identifier("enum_tables", "empty_enum");
const emptyEnumCodec = recordCodec({
name: "emptyEnum",
identifier: emptyEnumIdentifier,
attributes: {
__proto__: null,
value: {
codec: TYPES.text,
notNull: true
},
description: {
codec: TYPES.text
}
},
extensions: {
isTableLike: true,
pg: {
serviceName: "main",
schemaName: "enum_tables",
name: "empty_enum"
},
tags: {
__proto__: null,
enum: true
}
},
executor: executor
});
const simpleEnumIdentifier = sql.identifier("enum_tables", "simple_enum");
const simpleEnumCodec = recordCodec({
name: "simpleEnum",
Expand Down Expand Up @@ -496,6 +524,27 @@ const abcd_view_resourceOptionsConfig = {
isPrimary: true
}]
};
const empty_enum_resourceOptionsConfig = {
executor: executor,
name: "empty_enum",
identifier: "main.enum_tables.empty_enum",
from: emptyEnumIdentifier,
codec: emptyEnumCodec,
extensions: {
pg: {
serviceName: "main",
schemaName: "enum_tables",
name: "empty_enum"
},
tags: {
enum: true
}
},
uniques: [{
attributes: ["value"],
isPrimary: true
}]
};
const simple_enum_resourceOptionsConfig = {
executor: executor,
name: "simple_enum",
Expand All @@ -518,6 +567,7 @@ const simple_enum_resourceOptionsConfig = {
}]
};
const referencing_table_mutationFunctionIdentifer = sql.identifier("enum_tables", "referencing_table_mutation");
const empty_enum_queryFunctionIdentifer = sql.identifier("enum_tables", "empty_enum_query");
const letter_descriptionsUniques = [{
attributes: ["id"],
isPrimary: true
Expand Down Expand Up @@ -629,6 +679,7 @@ const registry = makeRegistry({
abcd: abcdCodec,
text: TYPES.text,
abcdView: abcdViewCodec,
emptyEnum: emptyEnumCodec,
simpleEnum: simpleEnumCodec,
int4: TYPES.int,
letterDescriptions: letterDescriptionsCodec,
Expand All @@ -642,6 +693,24 @@ const registry = makeRegistry({
lotsOfEnums: lotsOfEnumsCodec,
varchar: TYPES.varchar,
bpchar: TYPES.bpchar,
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
LotsOfEnumsEnum4Enum: enumCodec({
name: "LotsOfEnumsEnum4Enum",
identifier: TYPES.text.sqlType,
Expand Down Expand Up @@ -788,6 +857,7 @@ const registry = makeRegistry({
__proto__: null,
abcd: abcd_resourceOptionsConfig,
abcd_view: abcd_view_resourceOptionsConfig,
empty_enum: empty_enum_resourceOptionsConfig,
simple_enum: simple_enum_resourceOptionsConfig,
referencing_table_mutation: {
executor: executor,
Expand All @@ -812,6 +882,22 @@ const registry = makeRegistry({
isUnique: true,
isMutation: true
},
empty_enum_query: PgResource.functionResourceOptions(empty_enum_resourceOptionsConfig, {
name: "empty_enum_query",
identifier: "main.enum_tables.empty_enum_query()",
from(...args) {
return sql`${empty_enum_queryFunctionIdentifer}(${sqlFromArgDigests(args)})`;
},
parameters: [],
returnsSetof: false,
extensions: {
pg: {
serviceName: "main",
schemaName: "enum_tables",
name: "empty_enum_query"
}
}
}),
letter_descriptions: letter_descriptions_resourceOptionsConfig,
referencing_table: referencing_table_resourceOptionsConfig,
lots_of_enums: lots_of_enums_resourceOptionsConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,24 @@ const registry = makeRegistry({
}
}
}),
EmptyEnumEnum: enumCodec({
name: "EmptyEnumEnum",
identifier: TYPES.text.sqlType,
values: [],
extensions: {
isEnumTableEnum: true,
enumTableEnumDetails: {
serviceName: "main",
schemaName: "enum_tables",
tableName: "empty_enum",
constraintType: "p",
constraintName: "empty_enum_pkey"
},
tags: {
name: "EmptyEnum"
}
}
}),
EnumTheFirstEnum: enumCodec({
name: "EnumTheFirstEnum",
identifier: TYPES.text.sqlType,
Expand Down
Loading
Loading