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

sql: fix tuple type-checking #98152

Open
Tracked by #75101
mgartner opened this issue Mar 7, 2023 · 0 comments
Open
Tracked by #75101

sql: fix tuple type-checking #98152

mgartner opened this issue Mar 7, 2023 · 0 comments
Labels
C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. T-sql-queries SQL Queries Team

Comments

@mgartner
Copy link
Collaborator

mgartner commented Mar 7, 2023

Our type-checking logic for comparison of tuple-typed expressions assumes that the inputs expressions are tree.Tuple. This is deeply flawed because there are all sorts of other expressions that are not tree.Tuple but have the type of tuple. Our type-checking code should never be breaking apart expressions like tree.Tuple. It must operate on the types of sub-expressions, not the sub-expressions themselves.

A core hurdle to get over is our overload resolution, which currently operates on tree.Expr, rather then types.T to determine the correct overload for an operator and it's input. We should be following the logic described in detail here: https://www.postgresql.org/docs/current/typeconv-oper.html

  1. Select the operators to be considered from the pg_operator system catalog. If
    a non-schema-qualified operator name was used (the usual case), the operators
    considered are those with the matching name and argument count that are visible
    in the current search path (see Section 5.9.3). If a qualified operator name was
    given, only operators in the specified schema are considered.

    a. If the search path finds multiple operators with identical argument
    types, only the one appearing earliest in the path is considered. Operators
    with different argument types are considered on an equal footing regardless
    of search path position.

  2. Check for an operator accepting exactly the input argument types. If one
    exists (there can be only one exact match in the set of operators considered),
    use it. Lack of an exact match creates a security hazard when calling, via
    qualified name [9] (not typical), any operator found in a schema that permits
    untrusted users to create objects. In such situations, cast arguments to force
    an exact match.

    a. If one argument of a binary operator invocation is of the unknown type,
    then assume it is the same type as the other argument for this check.
    Invocations involving two unknown inputs, or a prefix operator with an
    unknown input, will never find a match at this step.

    b. If one argument of a binary operator invocation is of the unknown type
    and the other is of a domain type, next check to see if there is an operator
    accepting exactly the domain's base type on both sides; if so, use it.

  3. Look for the best match.

    a. Discard candidate operators for which the input types do not match and
    cannot be converted (using an implicit conversion) to match. unknown
    literals are assumed to be convertible to anything for this purpose. If only
    one candidate remains, use it; else continue to the next step.

    b. If any input argument is of a domain type, treat it as being of the
    domain's base type for all subsequent steps. This ensures that domains act
    like their base types for purposes of ambiguous-operator resolution.

    c. Run through all candidates and keep those with the most exact matches on
    input types. Keep all candidates if none have exact matches. If only one
    candidate remains, use it; else continue to the next step.

    d. Run through all candidates and keep those that accept preferred types (of
    the input data type's type category) at the most positions where type
    conversion will be required. Keep all candidates if none accept preferred
    types. If only one candidate remains, use it; else continue to the next
    step.

    e. If any input arguments are unknown, check the type categories accepted at
    those argument positions by the remaining candidates. At each position,
    select the string category if any candidate accepts that category. (This
    bias towards string is appropriate since an unknown-type literal looks like
    a string.) Otherwise, if all the remaining candidates accept the same type
    category, select that category; otherwise fail because the correct choice
    cannot be deduced without more clues. Now discard candidates that do not
    accept the selected type category. Furthermore, if any candidate accepts a
    preferred type in that category, discard candidates that accept
    non-preferred types for that argument. Keep all candidates if none survive
    these tests. If only one candidate remains, use it; else continue to the
    next step.

    f. If there are both unknown and known-type arguments, and all the
    known-type arguments have the same type, assume that the unknown arguments
    are also of that type, and check which candidates can accept that type at
    the unknown-argument positions. If exactly one candidate passes this test,
    use it. Otherwise, fail.

Jira issue: CRDB-25105

@mgartner mgartner added the C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. label Mar 7, 2023
@blathers-crl blathers-crl bot added the T-sql-queries SQL Queries Team label Mar 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. T-sql-queries SQL Queries Team
Projects
Status: Backlog
Development

No branches or pull requests

1 participant