Re: SQL:2011 application time

Поиск
Список
Период
Сортировка
От Paul Jungwirth
Тема Re: SQL:2011 application time
Дата
Msg-id af62a16b-9f88-4746-8e87-fdf0c242b266@illuminatedcomputing.com
обсуждение исходный текст
Ответ на Re: SQL:2011 application time  (Peter Eisentraut <peter@eisentraut.org>)
Ответы Re: SQL:2011 application time  (Peter Eisentraut <peter@eisentraut.org>)
Список pgsql-hackers
On 11/9/23 05:47, Peter Eisentraut wrote:
> I went over the patch v17-0001-Add-temporal-PRIMARY-KEY-and-UNIQUE-constraints.patch in more 
> detail.  Attached is a fixup patch that addresses a variety of cosmetic issues.

Thanks for the review! This all looks great to me, and it's applied in the attached patch (with one 
typo correction in a C comment). The patch addresses some of jian he's feedback too but I'll reply 
to those emails separately.

> Two areas that could be improved:
> 
> 1) In src/backend/commands/indexcmds.c, get_index_attr_temporal_operator() has this comment:
> 
> +    * This seems like a hack
> +    * but I can't find any existing lookup function
> +    * that knows about pseudotypes.
> 
> This doesn't see very confident. ;-)  I don't quite understand this.  Is this a gap in the currently 
> available APIs, do we need to improve something here, or does this need more research?

I've improved this a bit but I'm still concerned about part of it.

First the improved part: I realized I should be calling get_opclass_opfamily_and_input_type first 
and passing the opcintype to get_opfamily_member, which solves the problem of having a concrete 
rangetype but needing an operator that targets anyrange. We do the same thing with partition keys.

But I feel the overall approach is wrong: originally I used hardcoded "=" and "&&" operators, and 
you asked me to look them up by strategy number instead. But that leads to trouble with core gist 
types vs btree_gist types. The core gist opclasses use RT*StrategyNumbers, but btree_gist creates 
opclasses with BT*StrategyNumbers. I don't see any way to ask ahead of time which class of strategy 
numbers are used by a given opclass. So I have code like this:

     *strat = RTEqualStrategyNumber;
     opname = "equality";
     *opid = get_opfamily_member(opfamily, opcintype, opcintype, *strat);

     /*
      * For the non-overlaps key elements,
      * try both RTEqualStrategyNumber and BTEqualStrategyNumber.
      * If you're using btree_gist then you'll need the latter.
      */
     if (!OidIsValid(*opid))
     {
         *strat = BTEqualStrategyNumber;
         *opid = get_opfamily_member(opfamily, opcintype, opcintype, *strat);
     }

I do a similar thing for foreign keys.

But that can't be right. I added a scary comment there in this patch, but I'll explain here too:

It's only by luck that RTEqualStrategyNumber (18) is bigger than any BT*StrategyNumber. If I checked 
in the reverse order, I would always find an operator---it would just sometimes be the wrong one! 
And what if someone has defined a new type+opclass with totally different strategy numbers? As far 
as I can tell, the gist AM doesn't require an opclass have any particular operators, only support 
functions, so the strategy numbers are "private" and can vary between opclasses.

What we want is a way to ask which operators mean equality & overlaps for a given opclass. But the 
strategy numbers aren't meaningful terms to ask the question.

So I think asking for "=" and "&&" is actually better here. Those will be correct for both core & 
btree_gist, and they should also match user expectations for custom types. They are what you'd use 
in a roll-your-own temporal constraint via EXCLUDE. We can also document that we implement WITHOUT 
OVERLAPS with those operator names, so people can get the right behavior from custom types.

(This also maybe lets us implement WITHOUT OVERLAPS for more than rangetypes, as you suggested. See 
below for more about that.)

It's taken me a while to grok the am/opclass/opfamily/amop interaction, and maybe I'm still missing 
something here. Let me know if that's the case!

> 2) In src/backend/parser/parse_utilcmd.c, transformIndexConstraint(), there is too much duplication 
> between the normal and the if (constraint->without_overlaps) case, like the whole not-null 
> constraints stuff at the end.  This should be one code block with a few conditionals inside.  Also, 
> the normal case deals with things like table inheritance, which the added parts do not.  Is this all 
> complete?

Cleaned things up here. I agree it's much better now.

And you're right, now you should be able to use an inherited column in a temporal PK/UQ constraint. 
I think I need a lot more test coverage for how this feature combines with inherited tables, so I'll 
work on that.

> I'm not sure the validateWithoutOverlaps() function is needed at this point in the code.

Agreed, I removed it and moved the is-it-a-rangetype check into the caller.

> We don't even need to 
> restrict this to range types.  Consider for example, it's possible that a type does not have a btree 
> equality operator.  We don't check that here either, but let the index code later check it.

That is very interesting. Perhaps we allow anything with equals and overlaps then?

Note that we need more for FOR PORTION OF, foreign keys, and foreign keys with CASCADE/SET. So it 
might be confusing if a type works with temporal PKs but not those other things. But if we 
documented what operators you need for each feature then you could implement as much as you liked.

I like this direction a lot. It matches what I suggested in the conversation about multiple WITHOUT 
OVERLAPS/PERIOD columns: rather than having foreign keys and FOR PORTION OF know how to find 
n-dimensional "leftovers" we could leave it up the type, and just call a documented operator. (We 
would need to add that operator for rangetypes btw, one that calls range_leftover_internal. It 
should return an array (not a multirange!) of the untouched parts of the record.) This makes it easy 
to support bi/tri/n-temporal, spatial, multiranges, etc.

(For spatial you probably want PostGIS instead, and I'm wary of over-abstracting here, but I like 
how this "leaves the door open" for PostGIS to eventually support spatial PKs/FKs.)

Please let me know what you think!

Yours,

-- 
Paul              ~{:-)
pj@illuminatedcomputing.com
Вложения

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: mxid_age() and age(xid) appear undocumented
Следующее
От: Jeff Davis
Дата:
Сообщение: simplehash: preserve consistency in case of OOM