Skip to content
Open
Show file tree
Hide file tree
Changes from all 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