Skip to content

Commit

Permalink
Fix parsing of TRIM specification keywords (BOTH, LEADING, and …
Browse files Browse the repository at this point in the history
…`TRAILING`) (#326)
  • Loading branch information
alancai98 committed Dec 8, 2020
1 parent a8f59bf commit a22e529
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ internal class TrimExprFunction(valueFactory: ExprValueFactory) : NullPropagatin
1 -> Triple(DEFAULT_SPECIFICATION, DEFAULT_TO_REMOVE, args[0].codePoints())
2 -> {

if(args[0].type != ExprValueType.STRING){
if(!args[0].type.isText){
errNoContext("with two arguments trim's first argument must be either the " +
"specification or a 'to remove' string",
internal = false)
Expand Down
3 changes: 2 additions & 1 deletion lang/src/org/partiql/lang/syntax/LexerConstants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,10 @@ internal val DATE_PART_KEYWORDS: Set<String> = DatePart.values()
"work",
"write",
"zone"
).union(TRIM_SPECIFICATION_KEYWORDS)
)
// Note: DATE_PART_KEYWORDs are not keywords in the traditional sense--they are only keywords within
// the context of the DATE_ADD, DATE_DIFF and EXTRACT functions, for which [SqlParser] has special support.
// Similarly, TRIM_SPECIFICATION_KEYWORDS are only keywords within the context of the TRIM function.

/** PartiQL additional keywords. */
@JvmField internal val SQLPP_KEYWORDS = setOf(
Expand Down
5 changes: 0 additions & 5 deletions lang/src/org/partiql/lang/syntax/SqlLexer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -515,11 +515,6 @@ class SqlLexer(private val ion: IonSystem) : Lexer {
tokenType = FOR
ion.newSymbol(lower)
}
lower in TRIM_SPECIFICATION_KEYWORDS -> {
// used to determine the type of trim
tokenType = TRIM_SPECIFICATION
ion.newString(lower)
}
lower in BOOLEAN_KEYWORDS -> {
// literal boolean
tokenType = LITERAL
Expand Down
8 changes: 5 additions & 3 deletions lang/src/org/partiql/lang/syntax/SqlParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1779,9 +1779,11 @@ class SqlParser(private val ion: IonSystem) : Parser {
return node.remaining
}

val hasSpecification = when(rem.head?.type) {
TRIM_SPECIFICATION -> {
rem = parseArgument()
val maybeTrimSpec = rem.head
val hasSpecification = when {
maybeTrimSpec?.type == IDENTIFIER && TRIM_SPECIFICATION_KEYWORDS.contains(maybeTrimSpec.text?.toLowerCase()) -> {
arguments.add(ParseNode(ATOM, maybeTrimSpec.copy(type = TRIM_SPECIFICATION), listOf(), rem.tail))
rem = rem.tail

true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,48 @@ class EvaluatingCompilerExceptionsTest : EvaluatorTestBase() {
"""SELECT ? FROM <<1>>""",
ErrorCode.EVALUATOR_UNBOUND_PARAMETER,
sourceLocationProperties(1, 8) + mapOf(Property.EXPECTED_PARAMETER_ORDINAL to 1, Property.BOUND_PARAMETER_COUNT to 0))

@Test
fun trimSpecKeywordBothNotUsedInTrim() =
checkInputThrowingEvaluationException(
"SELECT 1 FROM both",
ErrorCode.EVALUATOR_BINDING_DOES_NOT_EXIST,
mapOf(
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 15L,
Property.BINDING_NAME to "both")
)

@Test
fun trimSpecKeywordLeadingNotUsedInTrim() =
checkInputThrowingEvaluationException(
"SELECT 1 FROM leading",
ErrorCode.EVALUATOR_BINDING_DOES_NOT_EXIST,
mapOf(
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 15L,
Property.BINDING_NAME to "leading")
)

@Test
fun trimSpecKeywordTrailingNotUsedInTrim() =
checkInputThrowingEvaluationException(
"SELECT 1 FROM trailing",
ErrorCode.EVALUATOR_BINDING_DOES_NOT_EXIST,
mapOf(
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 15L,
Property.BINDING_NAME to "trailing")
)

@Test
fun trimSpecKeywordLeadingUsedAsSecondArgInTrim() =
checkInputThrowingEvaluationException(
"trim(both leading from 'foo')",
ErrorCode.EVALUATOR_BINDING_DOES_NOT_EXIST,
mapOf(
Property.LINE_NUMBER to 1L,
Property.COLUMN_NUMBER to 11L,
Property.BINDING_NAME to "leading")
)
}
6 changes: 3 additions & 3 deletions lang/test/org/partiql/lang/syntax/SqlParserTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,17 @@ class SqlParserTest : SqlParserTestBase() {
@Test
fun callTrimTwoArgumentsUsingBoth() = assertExpression(
"trim(both from 'test')",
"(call trim (lit \"both\") (lit \"test\"))")
"(call trim (lit both) (lit \"test\"))")

@Test
fun callTrimTwoArgumentsUsingLeading() = assertExpression(
"trim(leading from 'test')",
"(call trim (lit \"leading\") (lit \"test\"))")
"(call trim (lit leading) (lit \"test\"))")

@Test
fun callTrimTwoArgumentsUsingTrailing() = assertExpression(
"trim(trailing from 'test')",
"(call trim (lit \"trailing\") (lit \"test\"))")
"(call trim (lit trailing) (lit \"test\"))")

//****************************************
// Unary operators
Expand Down

0 comments on commit a22e529

Please sign in to comment.