Subject: cap-10 section 6.1.1 CAL-QUERY Value Type

From: Dan Winship <[email-masked]>
Date: 02 Apr 2003 17:31:29 -0500

> 1.  For the purpose of a query, all components should be handled as
>     tables, and the properties of those components, should be handled
>     as columns.

lose the comma after "components"

> 2.  All VAGENDAs and CS's look like tables for the purpose of a
>     QUERY.  And all of their properties look like columns in those
>     tables.

This is redundant with 1 since VAGENDAs are components, and you can't
search the CS itself other than by searching the VCALSTORE, which is a
component. (OTOH, if you keep this section, s/VAGENDAs/"VAGENDA"
components/)

> 3.  You CAN NOT do any cross component-type joins.  And that means
>     you can ONLY have one component, OR one "VAGENDA" component OR
>     one "VCALSTORE" component in the "FROM" clause.

Likewise, "OR one "VAGENDA" component OR one "VCALSTORE" component"
seems redundant.

> 6.  The '.' is used to separate the table name (component) and column
>     name (property or component) when selecting a property that is
>     contained inside of a component that is targeted in the TARGET
>     property.

s/when selecting a property/when selecting a property or component/
s/in the TARGET property/by the "WHERE" clause or the "TARGET" property/
(I think?)

7 has a gratuitous ":" at the end. Oh, or is that introducing the
example? The examples in this section in general need to be reformatted
clearly and consistently. There needs to be indenting and/or "C:"/"S:"
prefixing, or something. Also, consistency as to whether the description
or the "code" comes first. (eg, the "code" of the first example is
back-to-back with the "code" of the second example, making it not
totally obvious that they're two separate examples).

> If provided as "component-name.*", then only the properties and any
> contained components will be returned:

would make more sense as "If the FOO is provided as "component-name.*"
..." where "FOO" is whatever the name is for that part of the SQL
statement.

>     (d) SELECT * FROM VEVENT

AFAICT, nothing specifies whether the "SELECT * FROM" form returns the
surrounding BEGIN/END or not.

>     (g) SELECT DTSTART,UID FROM VEVENT WHERE
>         VTODO.SUMMERY = "Fix typo in CAP"
...
>     (g) Is NOT valid because it mixes VEVENT
>         and VTODO properties in the same VQUERY.

If that's a rule, it should be explicitly stated, not just noted as part
of an example. Also, should either fix the typo or note that (g) is
additionally invalid because it's ungrammatical.

>   cap-val    = cap-cols / param
>                / ( cap-val "," cap-val )

That's not very clean ABNF. Do we have an ABNF guru?

>   cap-cols   = cap-col / ( cap-cols "," cap-col)
>                / "*"

This allows "*" to appear multiple times, or with other columns. (Dunno
if that's a bug.)

>   cap-col    = comp-name
>                / comp-name "." cap-prop

About half of the examples (including one of the ones directly above the
cap-col definition) don't parse correctly unless you add

                 / cap-prop

to the definition of cap-col. I don't know if adding that allows
anything else that shouldn't be allowed though.

>   cap-prop   = ; A property that may be in the 'cap-comp' named
>                ; in the "SELECT" clause.

presumably s/cap-comp/comp-name/, but it's still not quite right since
that would allow:

        SELECT VALARM FROM VEVENT
        WHERE PARAM(VEVENT.TRIGGER,RELATED) = 'END'

> 6.1.1.1 [NOT] CAL-OWNERS()

There is no way in the CAL-QUERY grammar for a "NOT" to appear before
"CAL-OWNERS()". The upn-filter-specific bits should probably not be in
this section.

> This function returns the list of "OWNER" properties for the named
> calendar when used in the "SELECT" clause.

There is no way in the CAL-QUERY grammar for CAL-OWNERS() to appear in
the SELECT clause.

> If called as 'CAL-OWNERS(cal-address)', then it is the equivalent to
> the comma separated list of owners for the named calendar id.  If
> 'cal-address' is a CS, it returns the "CALMASTER" property.

Need to take non-local calids into account:

        If called as 'CAL-OWNERS(cal-address)' where 'cal-address' is
        the CalID of a calendar on the CS, then it is equivalent to the
        comma-separated list of owners for that calendar. If
        'cal-address' refers to the CS itself, it returns the
        "CALMASTER" property. If 'cal-address' points to another CS, the
        results are undefined.

> If used in the in the "WHERE" clause it then returns true if the
> currently authenticated UPN is an owner of the currently selected
> object matched in the provided "TARGET" property.

Remove "then" (or s/it then/then it/). Should specify that only the
non-cal-address form is allowed.

> 6.1.1.3 PARAM()

> When used in a "SELECT" clause, it returns the entire property and
> all of that properties parameters (the result is not limited to the

s/properties/property's/. Also not clear what "the entire property" is
referring to. Should probably be something like

        When used in a "SELECT" clause, it returns the entire value of
        each property that contains the named parameter.

> When used in the "WHERE" clause, a match is true when the parameter
> value is "IN" or "LIKE" compare clause according to the supplied
> WHERE values.

That doesn't cover non-IN/LIKE cases. (eg, "PARAM(ATTENDEE,PARTSTAT) !=
'ACCEPTED'"). I think you can just say

        When used in the "WHERE" clause, it returns only the value of
        the named parameter.

and readers can mentally combine that with the LIKE/IN discussion later.

> If multiple named properties contain the named
> parameter, then each parameter value is compared to the condition and
> if any match, then the results would be true for that condition the
> same as if only one had existed.

It would be a lot easier to just make PARAM take a cap-prop instead of a
cap-col. (At least in the WHERE case.)

There should be examples using PARAM.

The rest of 6.1.1. seems to be in "whatever order we thought of problems
in" order, and I propose reordering the sections like so: (the numbers
are their current numbers, the order is the proposed new order)

> 6.1.1.11 [NOT] LIKE
> 6.1.1.12 Empty vs. NULL
> 6.1.1.13 [NOT] IN
> 6.1.1.8 Use of single quote
> 6.1.1.9 Comparing DATE and DATE-TIME values
> 6.1.1.10 DTEND and DURATION
> 6.1.1.14 DATE-TIME and TIME values in a WHEN clause
> 6.1.1.6 Ordering of Results
> 6.1.1.7 Date sorting order

ie, finish off the input syntax bits first, then the semantic bits, then
the output bits.

> 6.1.1.11 [NOT] LIKE
>
> The pattern matching characters are the '%' that matches zero or more
> characters, and '_' that matches exactly one character (where
> character does not always mean octet).

s/the '%' that/'%', which/
s/'_' that/'_', which/

> To match a '%' or '_' in the data and not have it interpreted as a
> wildcard character, they MUST BE backslash escaped.  That is to
> search for a '%' or '_' in the string:

        To match a '%', '_', or '\' in the data, you must backslash
        escape it in the search string.

> Strings compared using the "LIKE" clause MUST BE performed using case
> in-sensitive comparisons when the locale allows.

s/case in-sensitive/case-insensitive/

> Some property values (such as the 'recur' value type), contain commas
> ...
> using the IN element.

This was copied from the "[NOT] IN" section, but doesn't say the right
thing here. Based on the examples in 6.1.1.13, it should say:

        When using a "LIKE" clause with a multi-valued property or
        parameter, it matches if ANY of the values matches the pattern.
        See the examples in Section 6.1.1.13.

Neither the examples nor the text answer the question of whether
"parameter LIKE '%,%'" matches "property;parameter=1,2:x". (Hopefully
the answer is "no".)

> 6.1.1.12 Empty vs. NULL

I'd rename this to "IS [NOT] NULL" for consistency with the preceding
and following sections

> 6.1.1.13 [NOT] IN
>
> This is similar to the "LIKE" clause, except it does value matching
> and not string comparison matches.

It's not really all that much like the LIKE clause...

> c       property:parameter=1,2:x           One parameter, two values.
> d       property:parameter="1,2",3:y       One parameter, one value.
> e       property:parameter=",":z           One parameter, one value.

should be ; between the property and parameter?

> 6.1.1.8 Use of single quote

Maybe rename to "Literals"?

The text of this section is highly redundant with the comments in the
query abnf and the "LIKE" section (which it anachronistically refers to
as "Note 7").

> 6.1.1.9 Comparing DATE and DATE-TIME values
>
> When comparing "DATE-TIME" values to "DATE" values and when comparing
> "DATE" values to "DATE-TIME" values, the result will be true if the
> "DATE" value is on the same day as the "DATE-TIME" value.  And they
> are compared in UTC no matter what time zone the data may actual have
> been stored in.

Presumably this means "when comparing FOR EQUALITY". But what about
greater than/less than? Also, it seems that the time zone of the DATE
value is irrelevant, right?

        When comparing a "DATE" value to a "DATE-TIME" value, the
        "DATE-TIME" value is first converted to UTC, and then its date
        portion is compared to the "DATE". The time zone of the "DATE'
        value is irrelevant. For example:
        
           VALUE-1             VALUE-2            Compare Results
        
           20020304            20020304T123456    VALUE-1 == VALUE-2
           (in UTC-3)          (in UTC-3)
        
           20020304            20020304T003456    VALUE-1 > VALUE-2
           (in UTC)            (in UTC-4)
        
           20020304T003456Z    20020205T003456    VALUE-1 > VALUE-2
           (in UTC-0)          (in UTC-7)

I don't really understand why the last one is there since it doesn't
involve DATE values, and the timezones don't affect the answer either...

> When the "DATE" value or "DATE-TIME" value is not associated with a
> time zone, then the CS will compare the value assuming that the no
> time zone values are in the calendars default time zone.

        If the "DATE-TIME" value is not associated with a time zone,
        then the CS will use the calendar's default time zone.

> When comparing "DATE" values and "DATE-TIME" values with the "LIKE"
> clause

Yow!

OK, yes, it's neat that you can say "date LIKE '200201%'" instead of
"date > '20020101' and date < '20020201'", but you can't actually use it
to fill in your calendar view, since the comparison is done in UTC, so
you'll be off by a few hours on the edges. So what is the point? Why
would any CUA ever want to use anything like any of the given examples?

Are there any current or future CUA authors who have any concrete plans
for using this functionality? Looking through the archives, I see people
requesting the ability to use LIKE with text fields, but not dates. Does
this really serve any purpose besides making CS authors tear their hair
out?

> 6.1.1.10 DTEND and DURATION

Based on the thread I started about this, I suggest removing the 3rd and
4th paragraphs and changing the examples to:

        Given a meeting room reserved with a component that contains:
        
        DTSTART:20020127T000000Z
        DTEND:20020127T010000Z
        
        A query containing either of the following two "WHERE" clauses
        would match:
        
        WHERE VEVENT.DTSTART = '20020127T000000Z'
        AND VEVENT.DTEND = '20020127T010000Z'
        
        WHERE VEVENT.DTSTART = '20020127T000000Z'
        AND VEVENT.DURATION = 'P1H'

> 6.1.1.6 Ordering of Results

> Date and date time values will be sorted by their equivalent value in
> UTC.  No matter what the returned time zone in the result set
> returns.  This is so that if multiple components are returned each in
> a unique time zone, the results will be sorted in UTC.  This does not
> mean the values MUST BE converted to UTC in the data returned to the
> CUA.  It means the CS must do the sort in UTC.

How about:

        Date and date-time values will be sorted as though they were all
        first converted to UTC, regardless of what time zone or zones
        the results are actually returned in.

> All other values are sorted according to the locale sorting order as
> specified in the command.  Or the calendar locale if known, or the CS
> locale if the calendar does not have any locale set.  And the locale
> to use for the sort is determined in that order.

        All other values are sorted according to the locale sorting
        order. If the calendar has a locale defined, that overrides the
        default locale of the CS, and if the command has a locale
        explicitly specified, that overrides the default locale of the
        calendar.

> 6.1.1.7 Date sorting order

This should really be merged together with the other Date-sorting
commentary in 6.1.1.6

> If the selected component(s) do not contain a "DTSTART" property or a
> "RECURRENCE-ID" property, then the order is unspecified.

Since it's possible to have a mix or components with and without the
properties, it might be better to say:

        The order in which component(s) that do not contain a "DTSTART"
        property or a "RECURRENCE-ID" property are returned is not
        specified.