Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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: 1 addition & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ spark_locals_without_parens = [
error_fields: 1,
exclusion_constraint_names: 1,
foreign_key_names: 1,
identity_column_defaults: 1,
identity_index_names: 1,
identity_wheres_to_sql: 1,
ignore?: 1,
Expand Down
7 changes: 7 additions & 0 deletions lib/data_layer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,13 @@ defmodule AshPostgres.DataLayer do
doc: """
Options passed to ecto's table/2 in the create migration. See the [Ecto.Migration.table/2](https://hexdocs.pm/ecto_sql/Ecto.Migration.html#table/2) documentation for more information.
"""
],
identity_column_defaults: [
type: {:list, :atom},
default: [],
doc: """
A list of attribute names that should use `GENERATED BY DEFAULT AS IDENTITY` instead of `SERIAL`/`BIGSERIAL` in migrations. Use for `integer_primary_key` and other generated integer columns. Opt-in until the next major release.
"""
]
]
}
Expand Down
5 changes: 5 additions & 0 deletions lib/data_layer/info.ex
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,9 @@ defmodule AshPostgres.DataLayer.Info do
def create_table_options(resource) do
Extension.get_opt(resource, [:postgres], :create_table_options, nil)
end

@doc "Attributes that should use IDENTITY instead of SERIAL/BIGSERIAL in migrations"
def identity_column_defaults(resource) do
Extension.get_opt(resource, [:postgres], :identity_column_defaults, [])
end
end
10 changes: 10 additions & 0 deletions lib/migration_generator/migration_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3759,6 +3759,16 @@ defmodule AshPostgres.MigrationGenerator do
type
end

identity_column_defaults = AshPostgres.DataLayer.Info.identity_column_defaults(resource)
source = attribute.source || attribute.name

type =
if source in identity_column_defaults and attribute.generated? and type in [:bigint, :integer] do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sorry one more thing 😢. Now that we are just setting the column type to :identity, there is no real reason we need a new DSL option here. You should just be able to do migration_types: [id: :identity] and then you're good to go. No need for identity_column_defaults 😄

Also, be sure to run mix spark.cheat_sheets, mix format etc. locally.

:identity
else
type
end

{type, size, precision, scale} =
migration_type_to_type(type)

Expand Down
30 changes: 21 additions & 9 deletions lib/migration_generator/operation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,11 @@ defmodule AshPostgres.MigrationGenerator.Operation do
:bigint
end

def reference_type(%{type: :integer, default: "nil", generated?: true}, _) do
":bigserial"
end
def reference_type(%{type: :identity}, _), do: ":identity"

def reference_type(%{type: type}, _) do
type
end
def reference_type(%{type: :integer, default: "nil", generated?: true}, _), do: ":bigserial"

def reference_type(%{type: type}, _), do: type

def with_match(reference, source_attribute \\ nil)

Expand Down Expand Up @@ -489,6 +487,16 @@ defmodule AshPostgres.MigrationGenerator.Operation do
|> join()
end

def up(%{attribute: %{type: :identity} = attribute}) do
[
"add #{inspect(attribute.source)}",
":identity",
maybe_add_null(attribute.allow_nil?),
maybe_add_primary_key(attribute.primary_key?)
]
|> join()
end

def up(%{attribute: %{type: :bigint, default: "nil", generated?: true} = attribute}) do
[
"add #{inspect(attribute.source)}",
Expand Down Expand Up @@ -659,10 +667,14 @@ defmodule AshPostgres.MigrationGenerator.Operation do
Map.get(old_attribute, :references) != Map.get(attribute, :references) do
reference(multitenancy, attribute, schema)
else
if attribute.type == :bigint and attribute.default == "nil" and attribute.generated? do
":bigserial"
if attribute.type == :identity do
":identity"
else
inspect(attribute.type)
if attribute.type == :bigint and attribute.default == "nil" and attribute.generated? do
":bigserial"
else
inspect(attribute.type)
end
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/resource_generator/spec.ex
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do

defp type("bigint"), do: {:ok, :integer}
defp type("bigserial"), do: {:ok, :integer}
defp type("identity"), do: {:ok, :identity}
defp type("boolean"), do: {:ok, :boolean}
defp type("bytea"), do: {:ok, :binary}
defp type("varchar"), do: {:ok, :string}
Expand Down
Loading
Loading