Skip to content

Commit 7fe57b5

Browse files
authored
Merge pull request #1321 from partiql/simplify_is
2 parents c73efbf + caca049 commit 7fe57b5

File tree

3 files changed

+137
-49
lines changed

3 files changed

+137
-49
lines changed

partiql-planner/src/main/kotlin/org/partiql/planner/internal/PartiQLHeader.kt

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -403,68 +403,61 @@ internal object PartiQLHeader : Header() {
403403
// To model type assertion, generating a list of assertion function based on the type,
404404
// and the parameter will be the value entered.
405405
// i.e., 1 is INT2 => is_int16(1)
406-
private fun isType(): List<FunctionSignature.Scalar> = types.all.filterNot { it == NULL || it == MISSING }.flatMap { element ->
407-
types.all.filterNot { it == MISSING || it == ANY }.map { operand ->
406+
private fun isType(): List<FunctionSignature.Scalar> =
407+
types.all.filterNot { it == NULL || it == MISSING }.map { element ->
408408
FunctionSignature.Scalar(
409409
name = "is_${element.name.lowercase()}",
410410
returns = BOOL,
411411
parameters = listOf(
412-
FunctionParameter("value", operand)
412+
FunctionParameter("value", ANY)
413413
),
414-
isNullCall = false, // TODO: Should this be true?
415-
isNullable = false
414+
isNullable = false,
415+
isNullCall = false,
416416
)
417417
}
418-
}
419418

420419
// In type assertion, it is possible for types to have args
421420
// i.e., 'a' is CHAR(2)
422421
// we put type parameter before value.
423-
private fun isTypeSingleArg(): List<FunctionSignature.Scalar> = listOf(CHAR, STRING).flatMap { element ->
424-
types.all.filterNot { it == MISSING }.map { operand ->
425-
FunctionSignature.Scalar(
426-
name = "is_${element.name.lowercase()}",
427-
returns = BOOL,
428-
parameters = listOf(
429-
FunctionParameter("type_parameter_1", INT32),
430-
FunctionParameter("value", operand)
431-
),
432-
isNullable = false, // TODO: Should this be true?
433-
isNullCall = false
434-
)
435-
}
422+
private fun isTypeSingleArg(): List<FunctionSignature.Scalar> = listOf(CHAR, STRING).map { element ->
423+
FunctionSignature.Scalar(
424+
name = "is_${element.name.lowercase()}",
425+
returns = BOOL,
426+
parameters = listOf(
427+
FunctionParameter("type_parameter_1", INT32),
428+
FunctionParameter("value", ANY)
429+
),
430+
isNullable = false,
431+
isNullCall = false
432+
)
436433
}
437434

438-
private fun isTypeDoubleArgsInt(): List<FunctionSignature.Scalar> = listOf(DECIMAL).flatMap { element ->
439-
types.all.filterNot { it == MISSING }.map { operand ->
440-
FunctionSignature.Scalar(
441-
name = "is_${element.name.lowercase()}",
442-
returns = BOOL,
443-
parameters = listOf(
444-
FunctionParameter("type_parameter_1", INT32),
445-
FunctionParameter("type_parameter_2", INT32),
446-
FunctionParameter("value", operand)
447-
),
448-
isNullable = false,
449-
isNullCall = false
450-
)
451-
}
435+
private fun isTypeDoubleArgsInt(): List<FunctionSignature.Scalar> = listOf(DECIMAL).map { element ->
436+
FunctionSignature.Scalar(
437+
name = "is_${element.name.lowercase()}",
438+
returns = BOOL,
439+
parameters = listOf(
440+
FunctionParameter("type_parameter_1", INT32),
441+
FunctionParameter("type_parameter_2", INT32),
442+
FunctionParameter("value", ANY)
443+
),
444+
isNullable = false,
445+
isNullCall = false
446+
)
452447
}
453448

454-
private fun isTypeTime(): List<FunctionSignature.Scalar> = listOf(TIME, TIMESTAMP).flatMap { element ->
455-
types.all.filterNot { it == MISSING }.map { operand ->
456-
FunctionSignature.Scalar(
457-
name = "is_${element.name.lowercase()}",
458-
returns = BOOL,
459-
parameters = listOf(
460-
FunctionParameter("type_parameter_1", BOOL),
461-
FunctionParameter("type_parameter_2", INT32),
462-
FunctionParameter("value", operand) // TODO: Decide if we need to further segment this
463-
),
464-
isNullCall = false,
465-
isNullable = false
466-
)
467-
}
449+
private fun isTypeTime(): List<FunctionSignature.Scalar> = listOf(TIME, TIMESTAMP).map { element ->
450+
FunctionSignature.Scalar(
451+
name = "is_${element.name.lowercase()}",
452+
returns = BOOL,
453+
parameters = listOf(
454+
FunctionParameter("type_parameter_1", BOOL),
455+
FunctionParameter("type_parameter_2", INT32),
456+
FunctionParameter("value", ANY) // TODO: Decide if we need to further segment this
457+
),
458+
isNullable = false,
459+
isNullCall = false
460+
)
468461
}
469462

470463
// SUBSTRING (expression, start[, length]?)

partiql-planner/src/test/kotlin/org/partiql/planner/internal/typer/PlanTyperTestsPorted.kt

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,66 @@ class PlanTyperTestsPorted {
388388
),
389389
)
390390

391+
@JvmStatic
392+
fun isTypeCases() = listOf(
393+
SuccessTestCase(
394+
name = "IS BOOL",
395+
key = key("is-type-00"),
396+
catalog = "pql",
397+
catalogPath = listOf("main"),
398+
expected = StaticType.BOOL
399+
),
400+
SuccessTestCase(
401+
name = "IS INT",
402+
key = key("is-type-01"),
403+
catalog = "pql",
404+
catalogPath = listOf("main"),
405+
expected = StaticType.BOOL
406+
),
407+
SuccessTestCase(
408+
name = "IS STRING",
409+
key = key("is-type-02"),
410+
catalog = "pql",
411+
catalogPath = listOf("main"),
412+
expected = StaticType.BOOL
413+
),
414+
SuccessTestCase(
415+
name = "IS NULL",
416+
key = key("is-type-03"),
417+
catalog = "pql",
418+
expected = StaticType.BOOL,
419+
),
420+
SuccessTestCase(
421+
name = "MISSING IS NULL",
422+
key = key("is-type-04"),
423+
catalog = "pql",
424+
expected = StaticType.BOOL,
425+
),
426+
SuccessTestCase(
427+
name = "NULL IS NULL",
428+
key = key("is-type-05"),
429+
catalog = "pql",
430+
expected = StaticType.BOOL,
431+
),
432+
SuccessTestCase(
433+
name = "MISSING IS MISSING",
434+
key = key("is-type-06"),
435+
catalog = "pql",
436+
expected = StaticType.BOOL,
437+
),
438+
SuccessTestCase(
439+
name = "NULL IS MISSING",
440+
key = key("is-type-07"),
441+
catalog = "pql",
442+
expected = StaticType.BOOL,
443+
),
444+
ErrorTestCase(
445+
name = "ERROR always MISSING",
446+
key = key("is-type-08"),
447+
catalog = "pql",
448+
),
449+
)
450+
391451
@JvmStatic
392452
fun sessionVariables() = listOf(
393453
SuccessTestCase(
@@ -536,7 +596,10 @@ class PlanTyperTestsPorted {
536596
problemHandler = assertProblemExists {
537597
Problem(
538598
UNKNOWN_PROBLEM_LOCATION,
539-
PlanningProblemDetails.UnknownFunction("bitwise_and", listOf(StaticType.INT4, StaticType.STRING))
599+
PlanningProblemDetails.UnknownFunction(
600+
"bitwise_and",
601+
listOf(StaticType.INT4, StaticType.STRING)
602+
)
540603
)
541604
}
542605
),
@@ -2972,6 +3035,11 @@ class PlanTyperTestsPorted {
29723035
@Execution(ExecutionMode.CONCURRENT)
29733036
fun testPivot(tc: TestCase) = runTest(tc)
29743037

3038+
@ParameterizedTest
3039+
@MethodSource("isTypeCases")
3040+
@Execution(ExecutionMode.CONCURRENT)
3041+
fun testIsType(tc: TestCase) = runTest(tc)
3042+
29753043
// --------- Finish Parameterized Tests ------
29763044

29773045
//
@@ -2980,7 +3048,7 @@ class PlanTyperTestsPorted {
29803048
private fun infer(
29813049
query: String,
29823050
session: PartiQLPlanner.Session,
2983-
problemCollector: ProblemCollector
3051+
problemCollector: ProblemCollector,
29843052
): PartiQLPlan {
29853053
val ast = parser.parse(query).root
29863054
return planner.plan(ast, session, problemCollector).plan
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--#[is-type-00]
2+
false IS BOOL;
3+
4+
--#[is-type-01]
5+
item.i_class_id IS INT;
6+
7+
--#[is-type-02]
8+
item.i_brand IS STRING;
9+
10+
--#[is-type-03]
11+
1 IS NULL;
12+
13+
--#[is-type-04]
14+
MISSING IS NULL;
15+
16+
--#[is-type-05]
17+
NULL IS NULL;
18+
19+
--#[is-type-06]
20+
MISSING IS MISSING;
21+
22+
--#[is-type-07]
23+
NULL IS MISSING;
24+
25+
--#[is-type-08]
26+
-- ERROR! always MISSING
27+
MISSING IS BOOL;

0 commit comments

Comments
 (0)