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

Add partitioned tables support #2197

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

magnetised
Copy link
Contributor

@magnetised magnetised commented Dec 19, 2024

Allows for subscribing to partitions of a partitioned table (which you could already do) but also subscribing to the root, partitioned, table and receiving all updates across all partitions.

Fixes #2118

Major changes:

  • Add support for partitioned table types in the various inspector queries
  • Include partition hierarchy information in relation information from pg and in inspector relation info
  • Force reload of table information when receiving a new relation that is a partition
  • Add partition information to Filter so that it can correctly pass on a change on a partition table to a shape on the partition root.
  • For a shape subscribed to the partition root, changes coming in on partitions will be re-written so that their relation matches the partition root. The change keys are not being re-written - I don't think this is an issue as the keys are guaranteed to be unique and that's enough.
  • Relation messages notifying of a new partition table are forwarded onto root-partition consumers so the shape can be updated with knowledge of the new partition (this does not cause the shape to be deleted)
  • I've added a full-stack test to verify this stuff so that we're not making assumptions about pg's handling of partitions

Minor:

  • support querying the inspector based on the {schema, name} relation tuple, as well as the table name string because I needed to be able to look up table info based
  • Filter instances now have an inspector instance so they can do table info lookups to get partition information
  • The filter functions used by the dispatcher now return {filter, shape_ids} so that the filter's state can be updated
  • I've tweaked StubInspector so we can return richer info from the load_relation call
  • Added missing serialisation of a shape's replica setting

@magnetised magnetised force-pushed the 2118-support-shapes-on-partitioned-tables branch from 5e6a8f1 to 8aafed5 Compare December 19, 2024 18:17
Copy link

netlify bot commented Dec 20, 2024

Deploy Preview for electric-next ready!

Name Link
🔨 Latest commit c59bdc2
🔍 Latest deploy log https://app.netlify.com/sites/electric-next/deploys/678634215b54b70008f94254
😎 Deploy Preview https://deploy-preview-2197--electric-next.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@magnetised magnetised force-pushed the 2118-support-shapes-on-partitioned-tables branch from 65582f7 to b9e1bd0 Compare January 13, 2025 10:39
@magnetised
Copy link
Contributor Author

magnetised commented Jan 13, 2025

Think i have a more up-to-date version of this on my laptop which I seem to have forgotten to push or have over-written with my old work-machine version. @robacourt please hold off review until I can recover the situation

@magnetised magnetised force-pushed the 2118-support-shapes-on-partitioned-tables branch from b9e1bd0 to b517c38 Compare January 13, 2025 11:09
@magnetised
Copy link
Contributor Author

@robacourt situation recovered. review away. great start to the year!

@balegas
Copy link
Contributor

balegas commented Jan 13, 2025

Nice work! We should document the two possible ways to subscribe to partitioned tables.

@magnetised
Copy link
Contributor Author

Nice work! We should document the two possible ways to subscribe to partitioned tables.

@balegas I've added basic docs highlighting the behaviour of shapes on partitioned tables - pls review

Copy link
Contributor

@robacourt robacourt left a comment

Choose a reason for hiding this comment

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

Nice work! I've left a few comments.

I've also been thinking there might be an alternative implementation, whereby the replication steam is processed (by a PartitionTransformer for want of a better name) before it gets to the filter, and if it sees a change for a partition it inserts a change into the stream for the logical table. That way, all the partition logic can go in the PartitionTransformer. Shape, Filter, Consumer etc. would remain unchanged. Sure it will create some changes that might not be used, but that seems a good tradeoff for the simplicity. Is there a reason why this is not possible? Or undesirable?

{:ok, relation_info()} | {:error, String.t()}

@callback load_column_info(relation(), opts :: term()) ::
{:ok, [column_info()]} | :table_not_found

# @callback introspect_relation()
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing this should be removed?

Suggested change
# @callback introspect_relation()

assert_affected(filter, insert, MapSet.new(["s1", "s2"]))
end

@tag :wip
Copy link
Contributor

Choose a reason for hiding this comment

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

Presumably this can be removed?

Suggested change
@tag :wip

Comment on lines +183 to +185
{:error, _} ->
# just ignore errors here, they're unlikely anyway
:ok
Copy link
Contributor

Choose a reason for hiding this comment

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

Surely the ShapeLogCollector should crash if there's an error? An error could be something as simple as loss of network connectivity to the database, which if we just swallow the error we won't clean the relation leading to stale cache and an inconsistent state, or have I missed something?

Comment on lines +179 to +181
{:ok, _} ->
# probably a malformed value from a test inspector
:ok
Copy link
Contributor

Choose a reason for hiding this comment

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

When would this happen?

@@ -56,6 +56,36 @@ This is the root table of the shape. All shapes must specify a table and it must

The value can be just a tablename like `projects`, or can be a qualified tablename prefixed by the database schema using a `.` delimiter, such as `foo.projects`. If you don't provide a schema prefix, then the table is assumed to be in the `public.` schema.

#### Partitioned Tables
Copy link
Contributor

Choose a reason for hiding this comment

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

👌

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.

Support shapes on partitioned tables
3 participants