Replies: 2 comments
-
Appendix I — Type Coercion TableNOTE: This is incomplete. ⬤ — Implicit CAST / Coercion Cast Table
|
Beta Was this translation helpful? Give feedback.
0 replies
-
Accredit to @RCHowell, originally from partiql/partiql-docs#48 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
PartiQL Functions
This document gives answer to following questions informed by PartiQL Kotlin's implementation of a resolved query plan.
Questions
Proposals
Q1. What is a function; what is an operator?
A function is defined by its name and a set of operators. Operators are defined by input types and an output type.
For example, we way define a function called "foo" which has the given operators:
(T1, T1) -> T1
(T2, T2) -> T2
That is, the function "foo" has an operator defined for input types (T1, T1) with output type T1, as well as an
operator with input types (T2, T2) with output type T2.
Given a function name and list of arguments, the PartiQL compiler must resolve the appropriate operator.
Q2. How do we define functions and operators?
Functions are defined by its operators. We use the SQL
CREATE FUNCTION
syntax to defined operators introduced in SQL-99 4.8. The basic syntax is as follows:This is a sketch of the syntax and not a full EBNF. Here are some examples:
For a complete list of the SQL-99 builtins, see section 20.70 Definition of SQL built-in functions.
Q3. What is SPECIFIC?
The "SPECIFIC" is a unique identifier for this operator. For now, I am thinking of this as the operator name. I have
generated specific names for the PartiQL builtins with some string mangling. The rule is to combine the function name,
input types, and output type joining with double underscore. The input types are joined with a single underscore.
For example,
NOTE:
foo(x,y) -> z
mangled toFOO\__X_Y__Z
.Q4. What are type coercions?
Type coercions are the implicit casting behavior defined by SQL. The planner is responsible for leverage coercions to
resolve functions and inserting an explicit cast operator where the coercion was matched.
For example, here are two operators for the function
LTE
Given the function name "LTE" and arguments of types
(INT8, INT16)
the planner would match to the second operator withan explicit cast. The result would be:
LTE(CAST(LHS AS INT16), RHS)
Q5. What is the operator precedence?
Operators of a function are ordered by the following rules
For now, the following type ordering is used:
For example, these operators (shown simply as a list of parameter types) are are sorted
This is implemented in the PartiQL Kotlin header.
Q6. How are functions resolved?
Functions are resolved quite simply,
We return the first match. See the Kotlin implementation for more details.
Note that if a parameter type is ANY, it will match every argument. We don't actually want this behavior; see Q8 for a brief proposal on handling this.
Q7. How are NULL and MISSING handled in functions?
Function evaluation is determined by the method specification, see 21.24 Method Specifications Base Table. The important specification here is the property
IS_NULL_CALL
.If a function is a null-call, it is evaluated as follows:
If a function is NOT a null-call, it is evaluated as follows:
SQL functions are called on NULL input by default.
Q8. How are ANY parameters matched?
In PartiQL, we wish to resolve operators when the types of arguments may not be known. For example, consider the given environment (defined as a binding tuple
< ... >
) and query.How do we resolve the appropriate
+
operator when the type oft.b
is unknown? PartiQL defines additional operators which takeANY
type parameters. So we would resolve to this operator:This is fine, but we don't want to always match on
ANY
. Consider this,Now we know that
t.b
isstring
, so we shouldn't match thePLUS
operator because we know thatPLUS
operates on numeric types. Consider these three possibilities.(ANY,ANY) -- match
(INT,ANY) -- match
(INT,STRING) -- ERR!
Let's consider modeling the allowable types of the parameters as constraints on the operator definition.
This is a bit verbose, but if we break it down what we are saying is that the type of
ARG_0
,ARG_1
, and theRETURNS
types are one of the types in the respective lists. We may be able to alias common lists of types such as NUMERIC in this case.The function resolver would use these constraints to resolve (or fail to resolve) with given arguments. To be continued ...
Beta Was this translation helpful? Give feedback.
All reactions