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

type regconfig can not be handled by the types module Postgrex.DefaultTypes #502

Closed
asakura opened this issue Mar 21, 2020 · 5 comments
Closed

Comments

@asakura
Copy link

asakura commented Mar 21, 2020

PostgreSQL 12.2
Postgrex 0.15.3

Can not use text search configurations passed via raw query parameters:

iex(9)> Ecto.Adapters.SQL.query(Repo, "select $1::text::regconfig", ["english"])
[debug] QUERY ERROR db=0.0ms queue=0.3ms idle=9742.4ms
select $1::text::regconfig ["english"]
[error] Postgrex.Protocol (#PID<0.464.0>) disconnected: ** (Postgrex.QueryError) type `regconfig` can not be handled by the types module Postgrex.DefaultTypes
{:error,
 %Postgrex.QueryError{
   message: "type `regconfig` can not be handled by the types module Postgrex.DefaultTypes"
 }}

Same query works from psql:

# select 'english'::text::regconfig;
 regconfig 
-----------
 english
(1 row)
@josevalim
Copy link
Member

Correct. Postgrex doesn’t support all possible PG types, especially because they can be provided by extensions. In this case, you have to create your own Modules to handle this. See Postgrex docs. Odds are that someone has already done it, so please search existing packages. :)

github-actions bot pushed a commit to kphrx/pleroma that referenced this issue Aug 28, 2021
The original approach to search in GIN indexes is to use
`to_tsvector(text)` in the WHERE clause of the query. According to
postgres docs [pdoc], this method does not make use of the index,
while `to_tsvector(config, text)` does. This commit changed the
query to use the two-argument `to_tsvector()`.

[pdoc]: https://www.postgresql.org/docs/12/textsearch-tables.html

To obtain the search config in use, we make a query to the db first.
The `::regconfig::oid` hack is needed because Postgrex does not support
regconfig type directly [postgrexbug]. I use the conversion from and to
`oid` instead of `text` because I tested in the actual DB and querying
using the conversion via `text` is slow just as the one-argument
`to_tsvector()` variant.

[postgrexbug]: elixir-ecto/postgrex#502

BUG: https://git.pleroma.social/pleroma/pleroma/-/issues/2758
github-actions bot pushed a commit to kphrx/pleroma that referenced this issue Aug 29, 2021
The original approach to search in GIN indexes is to use
`to_tsvector(text)` in the WHERE clause of the query. According to
postgres docs [pdoc], this method does not make use of the index,
while `to_tsvector(config, text)` does. This commit changed the
query to use the two-argument `to_tsvector()`.

[pdoc]: https://www.postgresql.org/docs/12/textsearch-tables.html

To obtain the search config in use, we make a query to the db first.
The `::regconfig::oid` hack is needed because Postgrex does not support
regconfig type directly [postgrexbug]. I use the conversion from and to
`oid` instead of `text` because I tested in the actual DB and querying
using the conversion via `text` is slow just as the one-argument
`to_tsvector()` variant.

[postgrexbug]: elixir-ecto/postgrex#502

Backport of: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3519

Closes: https://git.pleroma.social/pleroma/pleroma/-/issues/2758
@kiddoshainingu
Copy link

I'm curious to know if anybody has written an extension for regconfig ever since ?

@PJUllrich
Copy link

Just an FYI for the future: In certain cases, you can use a trick to make Postgrex work with regconfig. For example, the following query won't work:

def search_comment_content(language, search_term) do
  query = from(c in Comment, where: fragment("content @@ plainto_tsquery(?, ?)", ^language, ^search_term)
  Repo.all(query)
end

Postgrex doesn't know how to translate the language from a binary into regconfig and you will receive the following error:

[error] Postgrex.Protocol (#PID<0.424.0>) disconnected: ** (Postgrex.QueryError) type `regconfig` can not be handled by the types module Postgrex.DefaultTypes

So, the trick is to type cast your language first into text and then into regconfig in your fragment, like this (note the ?::text::regconfig):

def search_comment_content(language, search_term) do
  query = from(c in Comment, where: fragment("content @@ plainto_tsquery(?::text::regconfig, ?)", ^language, ^search_term)
  Repo.all(query)
end

This way, Postgrex will transmit the language as text and Postgres handles the translation into regconfig. This query now works without using an external extension (which does not exist, yet, it appears).

@greg-rychlewski
Copy link
Member

greg-rychlewski commented Oct 24, 2022

For some context, ^ works because the result is a boolean. But if the result is a type that is unknown to Postgrex the error happens:

select $1::text::regconfig --> errors because postgrex gets regconfig type back from the db

select plainto_tsquery($1::text::regconfig, 'hi') --> errors because postgrex gets tsquery type back from the db

@greg-rychlewski
Copy link
Member

greg-rychlewski commented Dec 18, 2022

For posterity:

I've created a small library that can enable text encoding for any data type in Postgrex: https://github.com/greg-rychlewski/postgrex_text_ext.

This works well with OID types like regconfig where most of the time you want to use the string name instead of the integer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants