Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
1 change: 0 additions & 1 deletion lib/verifiers/validate_check_constraints.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,3 @@ defmodule AshPostgres.Verifiers.ValidateCheckConstraints do
:ok
end
end

3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ defmodule AshPostgres.MixProject do
{:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
{:mix_audit, ">= 0.0.0", only: [:dev, :test], runtime: false},
{:dialyxir, ">= 0.0.0", only: [:dev, :test], runtime: false},
{:sobelow, ">= 0.0.0", only: [:dev, :test], runtime: false}
{:sobelow, ">= 0.0.0", only: [:dev, :test], runtime: false},
{:mix_test_interactive, "~> 5.0", only: [:dev, :test]}
]
end

Expand Down
13 changes: 8 additions & 5 deletions mix.lock

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions priv/resource_snapshots/test_repo/containers/20251118120836.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v7()\")",
"generated?": false,
"precision": null,
"primary_key?": true,
"references": null,
"scale": null,
"size": null,
"source": "id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "85454A705DFC565FD634E25E9CE8FB510367A800470B9B85E0FA65494AC296D8",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshPostgres.TestRepo",
"schema": null,
"table": "containers"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs.contributors>

SPDX-License-Identifier: MIT
122 changes: 122 additions & 0 deletions priv/resource_snapshots/test_repo/items/20251118120836.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"uuid_generate_v7()\")",
"generated?": false,
"precision": null,
"primary_key?": true,
"references": null,
"scale": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "active",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": false,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "items_container_id_fkey",
"on_delete": null,
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "containers"
},
"scale": null,
"size": null,
"source": "container_id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "key",
"type": "text"
},
{
"allow_nil?": true,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "inserted_at",
"type": "utc_datetime_usec"
},
{
"allow_nil?": true,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"precision": null,
"primary_key?": false,
"references": null,
"scale": null,
"size": null,
"source": "updated_at",
"type": "utc_datetime_usec"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "8BF7AAEFEDD546F7EF1E399B6267932F80A964026BD5299E54C56AC52346833C",
"identities": [],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.AshPostgres.TestRepo",
"schema": null,
"table": "items"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs.contributors>

SPDX-License-Identifier: MIT
57 changes: 57 additions & 0 deletions priv/test_repo/migrations/20251118120836_migrate_resources67.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule AshPostgres.TestRepo.Migrations.MigrateResources67 do
@moduledoc """
Updates resources based on their most recent snapshots.

This file was autogenerated with `mix ash_postgres.generate_migrations`
"""

use Ecto.Migration

def up do
alter table(:items) do
modify(:updated_at, :utc_datetime_usec, null: true)
modify(:inserted_at, :utc_datetime_usec, null: true)
add(:name, :text)
add(:active, :boolean, default: false)
add(:container_id, :uuid)
end

create table(:containers, primary_key: false) do
add(:id, :uuid, null: false, default: fragment("uuid_generate_v7()"), primary_key: true)
end

alter table(:items) do
modify(
:container_id,
references(:containers,
column: :id,
name: "items_container_id_fkey",
type: :uuid,
prefix: "public"
)
)
end
end

def down do
drop(constraint(:items, "items_container_id_fkey"))

alter table(:items) do
modify(:container_id, :uuid)
end

drop(table(:containers))

alter table(:items) do
remove(:container_id)
remove(:active)
remove(:name)
modify(:inserted_at, :utc_datetime_usec, null: false)
modify(:updated_at, :utc_datetime_usec, null: false)
end
end
end
65 changes: 65 additions & 0 deletions test/aggregate_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1919,4 +1919,69 @@ defmodule AshSql.AggregateTest do
|> Ash.read!()
end
end

describe "page with count and aggregates with relationship-based calculations" do
test "loads relationship-based calculations correctly when using page(count: true) with aggregates" do
# This test reproduces the bug from https://github.com/ash-project/ash_sql/issues/191
# When using page(count: true) with both an aggregate and a calculation that depends on
# a relationship, the calculation fails to load (remains #Ash.NotLoaded)

# Create test data
author =
Author
|> Ash.Changeset.for_create(:create, %{
first_name: "John",
last_name: "Doe"
})
|> Ash.create!()

post =
Post
|> Ash.Changeset.for_create(:create, %{
title: "Test Post"
})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()

Comment
|> Ash.Changeset.for_create(:create, %{title: "Test Comment"})
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|> Ash.create!()

# Test without page(count: true) - should work
result_without_page_count =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load([
# aggregate
:count_of_comments,
# calculation that depends on author relationship
:author_first_name_calc
])
|> Ash.read_one!()

assert result_without_page_count.count_of_comments == 1
assert result_without_page_count.author_first_name_calc == "John"

Logger.configure(level: :debug)
# Test with page(count: true) - this triggers the bug
%{results: [result_with_page_count | _]} =
Post
|> Ash.Query.filter(id == ^post.id)
|> Ash.Query.load([
# aggregate
:count_of_comments,
# calculation that depends on author relationship
:author_first_name_calc
])
|> Ash.Query.page(limit: 50, offset: 0, count: true)
|> Ash.read!()

# Both should be loaded correctly
assert result_with_page_count.count_of_comments == 1
# This assertion should fail if the bug is present
assert result_with_page_count.author_first_name_calc == "John",
"Calculation was not loaded when using page(count: true) with aggregates"
end
end
end
Loading
Loading