Thread: Range type bounds

Range type bounds

From
Adrian Klaver
Date:
I am trying out the range types:

http://www.postgresql.org/docs/9.3/interactive/rangetypes.html

and got confused by the documentation wording for specifying no lower or
upper bound:

"The lower-bound may be either a string that is valid input for the
subtype, or empty to indicate no lower bound. Likewise, upper-bound may
be either a string that is valid input for the subtype, or empty to
indicate no upper bound."

What I saw was this:

aklaver@test=> select daterange('2014-11-01'::date,) ;
ERROR:  syntax error at or near ")"
LINE 1: select daterange('2014-11-01'::date,) ;

aklaver@test=> select '[2014-11-01,)'::daterange;
    daterange
---------------
  [2014-11-01,)
(1 row)

aklaver@test=> select daterange('2014-11-01'::date, Null) ;
    daterange
---------------
  [2014-11-01,)
(1 row)

which when I got further into the docs was shown in this example:

8.17.6. Constructing Ranges

-- Using NULL for either bound causes the range to be unbounded on that
side.
SELECT numrange(NULL, 2.2);


I will leave it to philosophers to decide whether NULL is empty, but it
seems the documentation could be more explicit on what constitutes empty
in the text versus constructor method of creating a range.

Thanks,
--
Adrian Klaver
adrian.klaver@aklaver.com


Re: Range type bounds

From
David G Johnston
Date:
Adrian Klaver-4 wrote
> I will leave it to philosophers to decide whether NULL is empty, but it
> seems the documentation could be more explicit on what constitutes empty
> in the text versus constructor method of creating a range.

Would it be sufficient to simply add another paragraph:

"The lower-bound may be either a string that is valid input for the subtype,
or NULL to indicate no lower bound. Likewise, upper-bound may be either a
string that is valid input for the subtype, or NULL to indicate no upper
bound."

?

@ 8.17.6. Constructing Ranges

I'm not particularly enamored with the title since "Range Input" is a means
of "Constructing [a] Range"...incorporating the word function into that
would seem warranted.

How about: 8.17.6 Functional Range Construction ?

For 8.17.5 The concept of "Input/Output" implies that we are dealing with
string-like literals and while not something an absolute beginner might pick
up on is likely sufficient and thus omitting the word "Literal" is OK by me.

All that said it is taken for granted that you cannot have an empty function
argument so ('val',) is invalid on its face.  The question becomes whether
you should use ('val','') or ('val',NULL).  The only place that is answered
is a single example.  It should be in the body of the text too.

David J.



--
View this message in context: http://postgresql.nabble.com/Range-type-bounds-tp5828396p5828402.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.


Re: Range type bounds

From
Adrian Klaver
Date:
On 11/26/2014 11:07 AM, David G Johnston wrote:
> Adrian Klaver-4 wrote
>> I will leave it to philosophers to decide whether NULL is empty, but it
>> seems the documentation could be more explicit on what constitutes empty
>> in the text versus constructor method of creating a range.
>
> Would it be sufficient to simply add another paragraph:
>
> "The lower-bound may be either a string that is valid input for the subtype,
> or NULL to indicate no lower bound. Likewise, upper-bound may be either a
> string that is valid input for the subtype, or NULL to indicate no upper
> bound."

Except that does not work in the text mode:( :

test=> select '[2014-11-01, NULL)'::daterange;
ERROR:  invalid input syntax for type date: " NULL"
LINE 1: select '[2014-11-01, NULL)'::daterange;


test=> select '[2014-11-01, "NULL")'::daterange;
ERROR:  invalid input syntax for type date: " NULL"
LINE 1: select '[2014-11-01, "NULL")'::daterange;

While testing the above I also got this:

test=> select '[2014-11-01, )'::daterange;
ERROR:  invalid input syntax for type date: " "
LINE 1: select '[2014-11-01, )'::daterange;

while:

test=> select '[2014-11-01,)'::daterange;
    daterange
---------------
  [2014-11-01,)
(1 row)

worked. Seems there is a specific meaning to empty.


>
> ?
>
> @ 8.17.6. Constructing Ranges
>
> I'm not particularly enamored with the title since "Range Input" is a means
> of "Constructing [a] Range"...incorporating the word function into that
> would seem warranted.
>
> How about: 8.17.6 Functional Range Construction ?
>
> For 8.17.5 The concept of "Input/Output" implies that we are dealing with
> string-like literals and while not something an absolute beginner might pick
> up on is likely sufficient and thus omitting the word "Literal" is OK by me.

I guess what is confusing to me is the transition between the text mode
and the constructor mode is not clear. In particular the page starts
with examples using the constructor mode but then goes to explanations
that actually apply to the text mode before getting back to explaining
the constructor mode. I eventually figured it out. I just thought it
might make it easier for others to make the distinction clearer.

>
> All that said it is taken for granted that you cannot have an empty function
> argument so ('val',) is invalid on its face.  The question becomes whether
> you should use ('val','') or ('val',NULL).  The only place that is answered
> is a single example.  It should be in the body of the text too.

Well I spend my time in Python for the most part so:

def test_fnc(a, b=None):
     print a, b

In [12]: test_fnc('a',)
a None

I will have to plead ignorance on C.

>
> David J.
>
>
>
> --
> View this message in context: http://postgresql.nabble.com/Range-type-bounds-tp5828396p5828402.html
> Sent from the PostgreSQL - general mailing list archive at Nabble.com.
>
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: Range type bounds

From
David Johnston
Date:

I guess what is confusing to me is the transition between the text mode and the constructor mode is not clear. In particular the page starts with examples using the constructor mode but then goes to explanations that actually apply to the text mode before getting back to explaining the constructor mode. 

They are contained in separate subsections of the documentation...the syntax described in each section only applies to that section.  The concept of empty doesn't apply to constructor functions at all.  

The part that is problematic is the overloaded use of empty to mean a range without bounds (a value) and a means to specify an infinite bound (an input).  Using "omitted" for the input case would probably add clarity.

I eventually figured it out. I just thought it might make it easier for others to make the distinction clearer.

Suggestions welcomed



All that said it is taken for granted that you cannot have an empty function
argument so ('val',) is invalid on its face.  The question becomes whether
you should use ('val','') or ('val',NULL).  The only place that is answered
is a single example.  It should be in the body of the text too.

Well I spend my time in Python for the most part so:

def test_fnc(a, b=None):
    print a, b

In [12]: test_fnc('a',)
a None

I will have to plead ignorance on C.

It gets to be very verbose if we try to anticipate cross-language differences and preemptively explain them away...

David J.

 

Re: Range type bounds

From
Adrian Klaver
Date:
On 11/26/2014 12:34 PM, David Johnston wrote:
>
>     I guess what is confusing to me is the transition between the text
>     mode and the constructor mode is not clear. In particular the page
>     starts with examples using the constructor mode but then goes to
>     explanations that actually apply to the text mode before getting
>     back to explaining the constructor mode.
>
>
> They are contained in separate subsections of the documentation...the
> syntax described in each section only applies to that section.  The
> concept of empty doesn't apply to constructor functions at all.

You get that from this?:

"

8.17.2. Examples

CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES
     (1108, '[2010-01-01 14:30, 2010-01-01 15:30)');

-- Containment
SELECT int4range(10, 20) @> 3;

-- Overlaps
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);

-- Extract the upper bound
SELECT upper(int8range(15, 25));

-- Compute the intersection
SELECT int4range(10, 20) * int4range(15, 25);

-- Is the range empty?
SELECT isempty(numrange(1, 5));

See Table 9-44 and Table 9-45 for complete lists of operators and
functions on range types.

8.17.3. Inclusive and Exclusive Bounds

Every non-empty range has two bounds, the lower bound and the upper
bound. All points between these values are included in the range. An
inclusive bound means that the boundary point itself is included in the
range as well, while an exclusive bound means that the boundary point is
not included in the range.

In the text form of a range, an inclusive lower bound is represented by
"[" while an exclusive lower bound is represented by "(". Likewise, an
inclusive upper bound is represented by "]", while an exclusive upper
bound is represented by ")". (See Section 8.17.5 for more details.)

The functions lower_inc and upper_inc test the inclusivity of the lower
and upper bounds of a range value, respectively.

8.17.4. Infinite (Unbounded) Ranges

The lower bound of a range can be omitted, meaning that all points less
than the upper bound are included in the range. Likewise, if the upper
bound of the range is omitted, then all points greater than the lower
bound are included in the range. If both lower and upper bounds are
omitted, all values of the element type are considered to be in the range.

This is equivalent to considering that the lower bound is "minus
infinity", or the upper bound is "plus infinity", respectively. But note
that these infinite values are never values of the range's element type,
and can never be part of the range. (So there is no such thing as an
inclusive infinite bound — if you try to write one, it will
automatically be converted to an exclusive bound.)

"
>
> The part that is problematic is the overloaded use of empty to mean a
> range without bounds (a value) and a means to specify an infinite bound
> (an input).  Using "omitted" for the input case would probably add clarity.
>
>     I eventually figured it out. I just thought it might make it easier
>     for others to make the distinction clearer.
>
>
> Suggestions welcomed

Understood. Will see what I can come up with.

>
>
>
>         All that said it is taken for granted that you cannot have an
>         empty function
>         argument so ('val',) is invalid on its face.  The question
>         becomes whether
>         you should use ('val','') or ('val',NULL).  The only place that
>         is answered
>         is a single example.  It should be in the body of the text too.
>
>
>     Well I spend my time in Python for the most part so:
>
>     def test_fnc(a, b=None):
>          print a, b
>
>     In [12]: test_fnc('a',)
>     a None
>
>     I will have to plead ignorance on C.
>
>
> It gets to be very verbose if we try to anticipate cross-language
> differences and preemptively explain them away...

Agreed. My example was as a counterpoint to your statement:

"All that said it is taken for granted that you cannot have an empty
function argument so ('val',) is invalid on its face."

It is not invalid on its face, just for this use case. I am not saying
explain all the exceptions, just the rule. In other words for the
purpose of this function at least two arguments must be provided. I
realize it does get covered in 8.17.6., but that is after the section I
quoted at the top which would seem to imply different. Have spent too
much time on this already, time to actually implement the suggestions:)

>
> David J.
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: Range type bounds

From
David Johnston
Date:
On Wednesday, November 26, 2014, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 11/26/2014 12:34 PM, David Johnston wrote:

    I guess what is confusing to me is the transition between the text
    mode and the constructor mode is not clear. In particular the page
    starts with examples using the constructor mode but then goes to
    explanations that actually apply to the text mode before getting
    back to explaining the constructor mode.


They are contained in separate subsections of the documentation...the
syntax described in each section only applies to that section.  The
concept of empty doesn't apply to constructor functions at all.

You get that from this?:

"

8.17.2. Examples


Examples do not constitute syntax specifications so while this useful for understanding it is not enough to generalize from.


Every non-empty range has two bounds, the lower bound and the upper bound. All points between these values are included in the range. An inclusive bound means that the boundary point itself is included in the range as well, while an exclusive bound means that the boundary point is not included in the range.

Use of empty as a value.
 

The lower bound of a range can be omitted, 

Omit is the best concept - implemented by a lack of value in a literal or a null in a function call.

It gets to be very verbose if we try to anticipate cross-language
differences and preemptively explain them away...

Agreed. My example was as a counterpoint to your statement:

"All that said it is taken for granted that you cannot have an empty function argument so ('val',) is invalid on its face."

It is not invalid on its face, just for this use case. 

Less a use case than a language/system.  I do not recall any case where you can call a function defined in PostgreSQL and leave an argument position defined but empty.  You can skip providing the given position and use defaults but dangling commas are not allowed.  That is taken for granted by the people writing documentation.
 
I am not saying explain all the exceptions, just the rule. In other words for the purpose of this function at least two arguments must be provided. I realize it does get covered in 8.17.6., but that is after the section I quoted at the top which would seem to imply different. Have spent too much time on this already, time to actually implement the suggestions:)


Yes, examples before definition is not all the common in the docs... 

David J.