Enum Order By values are `{ alias: null, specs: [] }`
<!-- Before opening an issue: if you use `npm` try running `yarn` instead; if
      you run `yarn`, please try running `npx yarn-deduplicate && yarn`. -->

### Summary

With this query:
```gql
query {
  allSiteConfigs (orderBy: NATURAL) {
    nodes {
      siteId
      public
    }
  }
}
```

Seeing this error:
```json
{
  "errors": [
    {
      "message": "Variable \"$_v0_orderBy\" got invalid value { alias: null, specs: [] } at \"_v0_orderBy[0]\"; Enum \"SiteConfigsOrderBy\" cannot represent non-string value: { alias: null, specs: [] }.",
      "path": [
        "allSiteConfigs"
      ]
    }
  ],
  "data": {
    "allSiteConfigs": null
  }
}
```

Also occurs with no orderBy at all, making the auto-generated postgraphile schema unusable unfortunately. The Postgres 15.4 RDS table I'm using has a very simple schema, it has `site_id: UUID` and `public: JSONB` as its two columns.

### Steps to reproduce

```ts
async function createPostGraphileSchemaFromPool(pgPool: Pool): Promise<GraphQLSchema> {
  return createPostGraphileSchema(pgPool, "public", {
    dynamicJson: false,
    setofFunctionsContainNulls: false,
  });
}
```

### Expected results


{
  node {
     public: "{ /* example JSON /* }"
     siteId: " /* example UUID /* "
  }
}

### Actual results

```json
{
  "errors": [
    {
      "message": "Variable \"$_v0_orderBy\" got invalid value { alias: null, specs: [] } at \"_v0_orderBy[0]\"; Enum \"SiteConfigsOrderBy\" cannot represent non-string value: { alias: null, specs: [] }.",
      "path": [
        "allSiteConfigs"
      ]
    }
  ],
  "data": {
    "allSiteConfigs": null
  }
}
```

### Additional context

<!-- Please provide additional context such as environment versions (including
      operating system, Node, PostgreSQL, Redis, etc. as relevant), software
      versions (from `yarn.lock`) or similar, plugins in use, database schema
      if relevant, bundler (if any). -->

Node dependencies:
```json
"apollo-link-http": "^1.5.17",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-graphql": "^0.12.0",
"graphile-utils": "^4.13.0",
"graphql": "15",
"graphql-tools": "4",
"graphql-type-json": "^0.3.2",
"pg": "^8.11.3",
"postgraphile": "^4.13.0"
```

Here is the generated postgraphile schema:
```sh
"""The root query type which gives access points into the data universe."""
type Query implements Node {
  """
  Exposes the root query type nested one level down. This is helpful for Relay 1
  which can only query top level fields if they are in a particular form.
  """
  query: Query!

  """
  The root query type must be a `Node` to work well with Relay 1 mutations. This just resolves to `query`.
  """
  nodeId: ID!

  """Fetches an object given its globally unique `ID`."""
  node(
    """The globally unique `ID`."""
    nodeId: ID!
  ): Node

  """Reads and enables pagination through a set of `SiteConfig`."""
  allSiteConfigs(
    """Only read the first `n` values of the set."""
    first: Int

    """Only read the last `n` values of the set."""
    last: Int

    """
    Skip the first `n` values from our `after` cursor, an alternative to cursor
    based pagination. May not be used with `last`.
    """
    offset: Int

    """Read all values in the set before (above) this cursor."""
    before: Cursor

    """Read all values in the set after (below) this cursor."""
    after: Cursor

    """The method to use when ordering `SiteConfig`."""
    orderBy: [SiteConfigsOrderBy!] = [NATURAL]

    """
    A condition to be used in determining which values should be returned by the collection.
    """
    condition: SiteConfigCondition
  ): SiteConfigsConnection

  """Reads and enables pagination through a set of `TestDatum`."""
  allTestData(
    """Only read the first `n` values of the set."""
    first: Int

    """Only read the last `n` values of the set."""
    last: Int

    """
    Skip the first `n` values from our `after` cursor, an alternative to cursor
    based pagination. May not be used with `last`.
    """
    offset: Int

    """Read all values in the set before (above) this cursor."""
    before: Cursor

    """Read all values in the set after (below) this cursor."""
    after: Cursor

    """The method to use when ordering `TestDatum`."""
    orderBy: [TestDataOrderBy!] = [PRIMARY_KEY_ASC]

    """
    A condition to be used in determining which values should be returned by the collection.
    """
    condition: TestDatumCondition
  ): TestDataConnection
  testDatumById(id: Int!): TestDatum

  """Reads a single `TestDatum` using its globally unique `ID`."""
  testDatum(
    """The globally unique `ID` to be used in selecting a single `TestDatum`."""
    nodeId: ID!
  ): TestDatum
}

"""An object with a globally unique `ID`."""
interface Node {
  """
  A globally unique identifier. Can be used in various places throughout the system to identify this single value.
  """
  nodeId: ID!
}

"""A connection to a list of `SiteConfig` values."""
type SiteConfigsConnection {
  """A list of `SiteConfig` objects."""
  nodes: [SiteConfig!]!

  """
  A list of edges which contains the `SiteConfig` and cursor to aid in pagination.
  """
  edges: [SiteConfigsEdge!]!

  """Information to aid in pagination."""
  pageInfo: PageInfo!

  """The count of *all* `SiteConfig` you could get from the connection."""
  totalCount: Int!
}

""" @orderByDesc _"""
type SiteConfig {
  siteId: UUID!
  public: JSON!
}

"""
A universally unique identifier as defined by [RFC 4122](https://tools.ietf.org/html/rfc4122).
"""
scalar UUID

"""
A JavaScript object encoded in the JSON format as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON

"""A `SiteConfig` edge in the connection."""
type SiteConfigsEdge {
  """A cursor for use in pagination."""
  cursor: Cursor

  """The `SiteConfig` at the end of the edge."""
  node: SiteConfig!
}

"""A location in a connection that can be used for resuming pagination."""
scalar Cursor

"""Information about pagination in a connection."""
type PageInfo {
  """When paginating forwards, are there more items?"""
  hasNextPage: Boolean!

  """When paginating backwards, are there more items?"""
  hasPreviousPage: Boolean!

  """When paginating backwards, the cursor to continue."""
  startCursor: Cursor

  """When paginating forwards, the cursor to continue."""
  endCursor: Cursor
}

"""Methods to use when ordering `SiteConfig`."""
enum SiteConfigsOrderBy {
  NATURAL
  SITE_ID_ASC
  SITE_ID_DESC
  PUBLIC_ASC
  PUBLIC_DESC
}

"""
A condition to be used against `SiteConfig` object types. All fields are tested
for equality and combined with a logical ‘and.’
"""
input SiteConfigCondition {
  """Checks for equality with the object’s `siteId` field."""
  siteId: UUID

  """Checks for equality with the object’s `public` field."""
  public: JSON
}

"""A connection to a list of `TestDatum` values."""
type TestDataConnection {
  """A list of `TestDatum` objects."""
  nodes: [TestDatum!]!

  """
  A list of edges which contains the `TestDatum` and cursor to aid in pagination.
  """
  edges: [TestDataEdge!]!

  """Information to aid in pagination."""
  pageInfo: PageInfo!

  """The count of *all* `TestDatum` you could get from the connection."""
  totalCount: Int!
}

type TestDatum implements Node {
  """
  A globally unique identifier. Can be used in various places throughout the system to identify this single value.
  """
  nodeId: ID!
  id: Int!
  name: String!
  value: Int!
  createdAt: Datetime
}

"""
A point in time as described by the [ISO
8601](https://en.wikipedia.org/wiki/ISO_8601) standard. May or may not include a timezone.
"""
scalar Datetime

"""A `TestDatum` edge in the connection."""
type TestDataEdge {
  """A cursor for use in pagination."""
  cursor: Cursor

  """The `TestDatum` at the end of the edge."""
  node: TestDatum!
}

"""Methods to use when ordering `TestDatum`."""
enum TestDataOrderBy {
  NATURAL
  ID_ASC
  ID_DESC
  NAME_ASC
  NAME_DESC
  VALUE_ASC
  VALUE_DESC
  CREATED_AT_ASC
  CREATED_AT_DESC
  PRIMARY_KEY_ASC
  PRIMARY_KEY_DESC
}

"""
A condition to be used against `TestDatum` object types. All fields are tested
for equality and combined with a logical ‘and.’
"""
input TestDatumCondition {
  """Checks for equality with the object’s `id` field."""
  id: Int

  """Checks for equality with the object’s `name` field."""
  name: String

  """Checks for equality with the object’s `value` field."""
  value: Int

  """Checks for equality with the object’s `createdAt` field."""
  createdAt: Datetime
}

"""
The root mutation type which contains root level fields which mutate data.
"""
type Mutation {
  """Creates a single `SiteConfig`."""
  createSiteConfig(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: CreateSiteConfigInput!
  ): CreateSiteConfigPayload

  """Creates a single `TestDatum`."""
  createTestDatum(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: CreateTestDatumInput!
  ): CreateTestDatumPayload

  """Updates a single `TestDatum` using its globally unique id and a patch."""
  updateTestDatum(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: UpdateTestDatumInput!
  ): UpdateTestDatumPayload

  """Updates a single `TestDatum` using a unique key and a patch."""
  updateTestDatumById(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: UpdateTestDatumByIdInput!
  ): UpdateTestDatumPayload

  """Deletes a single `TestDatum` using its globally unique id."""
  deleteTestDatum(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: DeleteTestDatumInput!
  ): DeleteTestDatumPayload

  """Deletes a single `TestDatum` using a unique key."""
  deleteTestDatumById(
    """
    The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    """
    input: DeleteTestDatumByIdInput!
  ): DeleteTestDatumPayload
}

"""The output of our create `SiteConfig` mutation."""
type CreateSiteConfigPayload {
  """
  The exact same `clientMutationId` that was provided in the mutation input,
  unchanged and unused. May be used by a client to track mutations.
  """
  clientMutationId: String

  """The `SiteConfig` that was created by this mutation."""
  siteConfig: SiteConfig

  """
  Our root query field type. Allows us to run any query from our mutation payload.
  """
  query: Query

  """An edge for our `SiteConfig`. May be used by Relay 1."""
  siteConfigEdge(
    """The method to use when ordering `SiteConfig`."""
    orderBy: [SiteConfigsOrderBy!] = [NATURAL]
  ): SiteConfigsEdge
}

"""All input for the create `SiteConfig` mutation."""
input CreateSiteConfigInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String

  """The `SiteConfig` to be created by this mutation."""
  siteConfig: SiteConfigInput!
}

"""An input for mutations affecting `SiteConfig`"""
input SiteConfigInput {
  siteId: UUID!
  public: JSON!
}

"""The output of our create `TestDatum` mutation."""
type CreateTestDatumPayload {
  """
  The exact same `clientMutationId` that was provided in the mutation input,
  unchanged and unused. May be used by a client to track mutations.
  """
  clientMutationId: String

  """The `TestDatum` that was created by this mutation."""
  testDatum: TestDatum

  """
  Our root query field type. Allows us to run any query from our mutation payload.
  """
  query: Query

  """An edge for our `TestDatum`. May be used by Relay 1."""
  testDatumEdge(
    """The method to use when ordering `TestDatum`."""
    orderBy: [TestDataOrderBy!] = [PRIMARY_KEY_ASC]
  ): TestDataEdge
}

"""All input for the create `TestDatum` mutation."""
input CreateTestDatumInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String

  """The `TestDatum` to be created by this mutation."""
  testDatum: TestDatumInput!
}

"""An input for mutations affecting `TestDatum`"""
input TestDatumInput {
  id: Int
  name: String!
  value: Int!
  createdAt: Datetime
}

"""The output of our update `TestDatum` mutation."""
type UpdateTestDatumPayload {
  """
  The exact same `clientMutationId` that was provided in the mutation input,
  unchanged and unused. May be used by a client to track mutations.
  """
  clientMutationId: String

  """The `TestDatum` that was updated by this mutation."""
  testDatum: TestDatum

  """
  Our root query field type. Allows us to run any query from our mutation payload.
  """
  query: Query

  """An edge for our `TestDatum`. May be used by Relay 1."""
  testDatumEdge(
    """The method to use when ordering `TestDatum`."""
    orderBy: [TestDataOrderBy!] = [PRIMARY_KEY_ASC]
  ): TestDataEdge
}

"""All input for the `updateTestDatum` mutation."""
input UpdateTestDatumInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String

  """
  The globally unique `ID` which will identify a single `TestDatum` to be updated.
  """
  nodeId: ID!

  """
  An object where the defined keys will be set on the `TestDatum` being updated.
  """
  testDatumPatch: TestDatumPatch!
}

"""
Represents an update to a `TestDatum`. Fields that are set will be updated.
"""
input TestDatumPatch {
  id: Int
  name: String
  value: Int
  createdAt: Datetime
}

"""All input for the `updateTestDatumById` mutation."""
input UpdateTestDatumByIdInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String

  """
  An object where the defined keys will be set on the `TestDatum` being updated.
  """
  testDatumPatch: TestDatumPatch!
  id: Int!
}

"""The output of our delete `TestDatum` mutation."""
type DeleteTestDatumPayload {
  """
  The exact same `clientMutationId` that was provided in the mutation input,
  unchanged and unused. May be used by a client to track mutations.
  """
  clientMutationId: String

  """The `TestDatum` that was deleted by this mutation."""
  testDatum: TestDatum
  deletedTestDatumId: ID

  """
  Our root query field type. Allows us to run any query from our mutation payload.
  """
  query: Query

  """An edge for our `TestDatum`. May be used by Relay 1."""
  testDatumEdge(
    """The method to use when ordering `TestDatum`."""
    orderBy: [TestDataOrderBy!] = [PRIMARY_KEY_ASC]
  ): TestDataEdge
}

"""All input for the `deleteTestDatum` mutation."""
input DeleteTestDatumInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String

  """
  The globally unique `ID` which will identify a single `TestDatum` to be deleted.
  """
  nodeId: ID!
}

"""All input for the `deleteTestDatumById` mutation."""
input DeleteTestDatumByIdInput {
  """
  An arbitrary string value with no semantic meaning. Will be included in the
  payload verbatim. May be used to track mutations by the client.
  """
  clientMutationId: String
  id: Int!
}
```
### Possible Solution

Possibly related:
* https://github.com/graphile/crystal/issues/1215

