Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

quartz55
Copy link
Contributor

Custom types aren't being correctly casted in joins. The added test is failing with these two errors.

Should be casted as float tuple (float[]):

** (Ash.Error.Unknown)
Bread Crumbs:
  > Error returned from: AshPostgres.Test.DbPoint.read
  > Error returned from: AshPostgres.Test.Post.read

Unknown Error

* ** (Postgrex.Error) ERROR 42883 (undefined_function) operator does not exist: double precision[] = double precision

    query: SELECT p0."id" FROM "points" AS p0 WHERE (p0."id"::float[]::float[] = ANY($1::float[][]::float[][]))

Should be casted to string by calling StringPoint.dump_to_native/2:

** (Ash.Error.Unknown)
Bread Crumbs:
  > Error returned from: AshPostgres.Test.DbStringPoint.read
  > Error returned from: AshPostgres.Test.Post.read

Unknown Error

* ** (DBConnection.EncodeError) Postgrex expected a binary, got %AshPostgres.Test.StringPoint{x: 2.0, y: 3.0, z: 4.0}. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.

@quartz55 quartz55 force-pushed the fix/cast-custom-types-in-joins branch from f097ae2 to 8953387 Compare March 14, 2025 12:00
@zachdaniel zachdaniel merged commit c9c955c into ash-project:main Mar 14, 2025
45 of 51 checks passed
@zachdaniel
Copy link
Contributor

I'm pretty sure these types are just not compatible? One is stored as a string and the other is stored as an array, so you can't compare them in postgres. I don't think there is anything we can do to fix it. storage_type on StringPoint is :string.

@zachdaniel
Copy link
Contributor

I've removed the commits from the main branch but there is a branch with your failing tests in point-test. I don't think that its possible to compare these disparate types at the data layer.

@quartz55
Copy link
Contributor Author

I'm not sure I understand. I'm not trying to compare between attributes of different types but of the same type (Point with Point and StringPoint with StringPoint). Maybe I should separate into 2 tests?

From my understanding the error is happening when joining across tables and the join key coming from elixir side is not being properly casted/encoded in the query. For example, StringPoint is represented as a struct on elixir side and should be saved/encoded as a string in postgres. In this case, it should be encoded (dump_native) before being used in the join condition, but it is not hence the error:

* ** (DBConnection.EncodeError) Postgrex expected a binary, got %AshPostgres.Test.StringPoint{x: 2.0, y: 3.0, z: 4.0}. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.

@zachdaniel
Copy link
Contributor

Ah, okay, apologies for the confusion :)

Can you open an issue and reference this PR? I will re-add the tests and investigate 🙇

@zachdaniel
Copy link
Contributor

I've found the issue, will work on a fix 😄

@zachdaniel
Copy link
Contributor

@quartz55 might be worth confirming actually: in your real issue, is the value that you are using a tuple? i.e {1, 2, 3}? Or is it some other value? Because this issue is actually in our filter parsing in Ash core and only arises when you use tuples for relationship keys or primary keys.

@zachdaniel
Copy link
Contributor

Looks like there is another issue, which is that (from what I can tell) ANY only supports scalar values.

@zachdaniel
Copy link
Contributor

Okay, there were three separate bugs related to tuple values and multidimensional array values here. They are fixed now in ash_sql and ash main, and will be released next week.

zachdaniel pushed a commit that referenced this pull request Mar 16, 2025
@quartz55
Copy link
Contributor Author

@quartz55 might be worth confirming actually: in your real issue, is the value that you are using a tuple? i.e {1, 2, 3}? Or is it some other value? Because this issue is actually in our filter parsing in Ash core and only arises when you use tuples for relationship keys or primary keys.

My real issue is more or less replicated by the StringPoint type not the tuple one. Specifically I'm using country codes in the database as natural keys string type (e.g. PT or US) but in Elixir land they are decoded as a struct (defstruct [:code, :name, flag: nil]). I seem to have issues when this type is used as a join/relationship key because they are not encoded back to a string in SQL queries (it fails here in the test).

@zachdaniel
Copy link
Contributor

Does it still fail after the recent fixes?

@quartz55
Copy link
Contributor Author

Pointing both to main (ash and ash_sql) seems to have fixed it indeed! 🙌

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

Successfully merging this pull request may close these issues.

2 participants