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

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

Open
uladkasach opened this issue Dec 14, 2021 · 1 comment

Comments

@uladkasach
Copy link
Member

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!

@uladkasach
Copy link
Member Author

🤔 - we can probably start with just treating everything as a union

e.g., still suffix each token so that we identify the type of every position of the token without explicitly considering whether its a Union or Intersection - and then when we go to output the types just treat everything as a union

this is not ideal as it removes some type saftey (i.e., if we did consider intersections, we would help notify users sooner that their query is not going to work)

but it is ideal in the sense that it is way faster to implement and way more convinient to use


lets start there - and we can create another ticket for intersections and explicit AND -vs- OR support when we need it / when the benefit is justified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant