Skip to content

formal support for OR statements on query input variable type definitions #49

@uladkasach

Description

@uladkasach

OR statements are important - but not trivial to support.

the reason they're not trivial is because they open the topic that one query may attempt to use the same token in different ways:

consider the following cases

  1. optional filter
WHERE (:until IS null OR chat_message.created_at <= :until)
  1. broader search
WHERE (
  user.first_name = :name
  OR
  user.last_name = :name
)
  1. impossible criteria
WHERE (
  user.id = :name -- => type = number
  AND
  user.first_name = :name -- => type = string
)

case 1 and 2 are no problem to support, just union the types

case 3 is a problem to support, because we have to intersect the types

how do we distinguish between intersection cases and union cases?:

  • by default its an intersection
  • its a union if there is an OR statement

how do we merge intersections?:

  • we can do so intelligently (i.e., check that the intersections make sense, if intersecting a union, check that all of the intersection makes sense?)
  • we can do so naively (i.e., just output the type definitions in full and let typescript tell the user that their query is unsatisfiable)
    • e.g., type name = string & number => can never satisfy

ok... how do we identify unions though?

  • OR is the keyword
  • we could require () wrapping around one or more ORs in order for us to allow it
  • its only a union if its all inside of the same OR
  • we can support nested ORs by unioning type & type[]

ok cool

and how do we distinguish in the data model unions vs intersections?

  • unions = all types are on one type definition
    • update the TypeDefInputVariable.type = array of datatype/references
  • intersections = multiple type definitions

ok so that means, when we're outputting the types

  • merge all of the TypeDefInputVariables w/ intersection operator &
  • merge all of the TypeDefInputVariable.types w/ union operator |

how do we handle identifying these cases then, functionally?

  • we can assign each token a unique id/suffix tokens with when we've seen them
    • that solves intersection, easy
    • e.g., until#1, until#2
  • we can identify OR statements as a special case when trying to get type definition?
    • i.e.,
      • first identify the type of each of those tokens, unique by position
      • next identify that the two tokens are unioned together, since we saw them inside of an OR clause together
      • e.g., find out whether this token was in a union at all, then find out whether another token of the same name was in the same union

this seems pretty tractable!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions