On Wed, Jan 5, 2022 at 8:07 AM Peter Eisentraut <peter.eisentr...@enterprisedb.com> wrote: > > This patch set looks very interesting.
Thank you for the review! I'll work on your feedback but in the meantime here are replies to your questions: > I'm confused about how to query tables based on application time > periods. Online, I see examples using AS OF, but in the SQL standard > I only see this used for system time, which we are not doing here. Correct, the standard only gives it for system time. I think application time is intended to be more "in user space" so it's fine to use regular operators in your WHERE condition against the time columns, whereas system time is more of a managed thing---automatic, read-only, possibly stored in a separate table. Having a special syntax cue lets the RDBMS know it needs to involve the historical records. > validate_period(): Could use an explanatory comment. There are a > bunch of output arguments, and it's not clear what all of this is > supposed to do, and what "validating" is in this context. I'm not too happy with that function, but a previous reviewer asked me to factor out what was shared between the CREATE TABLE and ALTER TABLE cases. It does some sanity checks on the columns you've chosen, and along the way it collects info about those columns that we'll need later. But yeah all those out parameters are pretty ugly. I'll see if I can come up with a stronger abstraction for it, and at the very least I'll add some comments. > MergeAttributes(): I would perhaps initially just prohibit inheritance > situations that involve periods on either side. (It should work for > partitioning, IMO, but that should be easier to arrange.) Okay. I'm glad to hear you think partitioning won't be too hard. It is one of the last things, but to me it's a bit intimidating. > I didn't follow why indexes would have periods, for example, the new > period field in IndexStmt. Is that explained anywhere? When you create a primary key or a unique constraint (which are backed by a unique index), you can give a period name to make it a temporal constraint. We create the index first and then create the constraint as a side-effect of that (e.g. index_create calls index_constraint_create). The analysis phase generates an IndexStmt. So I think this was mostly a way to pass the period info down to the constraint. It probably doesn't actually need to be stored on pg_index though. Maybe it does for index_concurrently_create_copy. I'll add some comments, but if you think it's the wrong approach let me know. > While reading this patch I kept wondering whether it would be possible > to fold periods into pg_attribute, perhaps with negative attribute > numbers. Have you looked into something like that? No doubt it's > also complicated, but it might simplify some things, like the name > conflict checking. Hmm, I thought that sort of thing would be frowned upon. :-) But also it seems like periods really do have a bunch of details they need beyond what other attributes have (e.g. the two source attributes, the matching range type, the period type (application-vs-system), maybe some extra things for table inheritance. Also are you sure we aren't already using negative attnums somewhere already? I thought I saw something like that. > Of course, the main problem in this patch is that for most uses it > requires btree_gist. I think we should consider moving that into > core, or at least the support for types that are most relevant to this > functionality, specifically the date/time types. Aside from user > convenience, this would also allow writing more realistic test cases. I think this would be great too. How realistic do you think it is? I figured since exclusion constraints are also pretty useless without btree_gist, it wasn't asking too much to have people install the extension, but still it'd be better if it were all built in. > src/backend/access/brin/brin_minmax_multi.c > > These renaming changes seem unrelated (but still seem like a good > idea). Should they be progressed separately? I can pull this out into a separate patch. I needed to do it because when I added an `#include <rangetypes.h>` somewhere, these conflicted with the range_{de,}serialize functions declared there. > I don't understand why a temporal primary key is required for doing > UPDATE FOR PORTION OF. I don't see this in the standard. You're right, it's not in the standard. I'm doing that because creating the PK is when we add the triggers to implement UPDATE FOR PORTION OF. I thought it was acceptable since we also require a PK/unique constraint as the referent of a foreign key. But we could avoid it if I went back to the executor-based FOR PORTION OF implementation, since that doesn't depend on triggers. What do you think? Also: I noticed recently that you can't use FOR PORTION OF against an updatable view. I'm working on a new patch set to fix that. But the main reason is this PK check. So that's maybe another reason to go back to the executor implementation. > How to proceed. I suppose we could focus on committing 0001 and 0002 > first. That would be great! I don't think either is likely to conflict with future system-time work. > Is there anything else you think we can do as > preparatory work to make the main patches more manageable? I think it would be smart to have a rough plan for how this work will be compatible with system-time support. Corey & I have talked about that a lot, and In general they are orthogonal, but it would be nice to have details written down somewhere. Yours, Paul