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

Automatic step coercion #1971

Open
benjie opened this issue Feb 21, 2024 · 0 comments
Open

Automatic step coercion #1971

benjie opened this issue Feb 21, 2024 · 0 comments

Comments

@benjie
Copy link
Member

benjie commented Feb 21, 2024

Feature description

When a step is used for a type which doesn't support that step class, the type could offer a function to attempt to coerce the step to a compatible type.

Motivating example

https://discord.com/channels/489127045289476126/498852330754801666/1209806376595882014

Discord user @box received Query planning error: $record.record is not a function because they attempted to use the result of object({sessionToken: withPgClientTransaction(...)).get('sessionToken') for a built in type SessionToken which expects to represent a Postgres type, and thus should use the PgSelectSingleStep or PgClassExpressionStep step classes.

However, we should be able to take an arbirary object and assume it's the right type, and convert it to a PgSelectSingleStep by piping it through json_populate_record or similar. For example:

function pgSelectSingleFromObject(resource: PgResource, $obj: ExecutableStep): PgSelectSingle {
  const $records = pgSelect({
    identifiers: [],
    resource,
    from: (r) =>
      sql`json_populate_record(null::${resource.codec.sqlType}, ${r.placeholder})`,
    args: [{ step: $obj, pgCodec: TYPES.json }],
  });
  return $records.single();
}

// ...

const sessionTokenCodec = build.input.pgRegistry.pgCodecs.session_token;
const resource = build.pgTableResource(sessionTokenCodec, false);

SessionTokenType.extensions.grafast.coerceStep = ($step) => {
  if ($step instanceof PgSelectSingleStep || $step instanceof PgClassExpressionStep) {
    // No co-ercion needed; we already support these types
    return $step;
  } else {
    // Attempt to convert
    return pgSelectSingleFromObject(resource, $step);
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant