[SPARK-35736][SQL] Parse any day-time interval types in SQL
### What changes were proposed in this pull request? This PR adda a feature which allow the parser parse any day-time interval types in SQL. ### Why are the changes needed? To comply with ANSI standard, we additionally need to support the following types. * INTERVAL DAY * INTERVAL DAY TO HOUR * INTERVAL DAY TO MINUTE * INTERVAL HOUR * INTERVAL HOUR TO MINUTE * INTERVAL HOUR TO SECOND * INTERVAL MINUTE * INTERVAL MINUTE TO SECOND * INTERVAL SECOND ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? New tests. Closes #32893 from sarutak/parse-any-day-time. Authored-by: Kousuke Saruta <sarutak@oss.nttdata.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
This commit is contained in:
parent
69aa7ad11f
commit
7978fdc97b
|
@ -300,6 +300,7 @@ Below is a list of all the keywords in Spark SQL.
|
|||
|GROUP|reserved|non-reserved|reserved|
|
||||
|GROUPING|non-reserved|non-reserved|reserved|
|
||||
|HAVING|reserved|non-reserved|reserved|
|
||||
|HOUR|non-reserved|non-reserved|non-reserved|
|
||||
|IF|non-reserved|non-reserved|not a keyword|
|
||||
|IGNORE|non-reserved|non-reserved|non-reserved|
|
||||
|IMPORT|non-reserved|non-reserved|non-reserved|
|
||||
|
@ -336,6 +337,7 @@ Below is a list of all the keywords in Spark SQL.
|
|||
|MAP|non-reserved|non-reserved|non-reserved|
|
||||
|MATCHED|non-reserved|non-reserved|non-reserved|
|
||||
|MERGE|non-reserved|non-reserved|non-reserved|
|
||||
|MINUTE|non-reserved|non-reserved|non-reserved|
|
||||
|MINUS|non-reserved|strict-non-reserved|non-reserved|
|
||||
|MONTH|non-reserved|non-reserved|non-reserved|
|
||||
|MSCK|non-reserved|non-reserved|non-reserved|
|
||||
|
|
|
@ -905,7 +905,8 @@ dataType
|
|||
| complex=MAP '<' dataType ',' dataType '>' #complexDataType
|
||||
| complex=STRUCT ('<' complexColTypeList? '>' | NEQ) #complexDataType
|
||||
| INTERVAL YEAR TO MONTH #yearMonthIntervalDataType
|
||||
| INTERVAL DAY TO SECOND #dayTimeIntervalDataType
|
||||
| INTERVAL from=(DAY | HOUR | MINUTE | SECOND)
|
||||
(TO to=(HOUR | MINUTE | SECOND))? #dayTimeIntervalDataType
|
||||
| identifier ('(' INTEGER_VALUE (',' INTEGER_VALUE)* ')')? #primitiveDataType
|
||||
;
|
||||
|
||||
|
@ -1110,6 +1111,7 @@ ansiNonReserved
|
|||
| FUNCTIONS
|
||||
| GLOBAL
|
||||
| GROUPING
|
||||
| HOUR
|
||||
| IF
|
||||
| IGNORE
|
||||
| IMPORT
|
||||
|
@ -1137,6 +1139,7 @@ ansiNonReserved
|
|||
| MAP
|
||||
| MATCHED
|
||||
| MERGE
|
||||
| MINUTE
|
||||
| MONTH
|
||||
| MSCK
|
||||
| NAMESPACE
|
||||
|
@ -1358,6 +1361,7 @@ nonReserved
|
|||
| GROUP
|
||||
| GROUPING
|
||||
| HAVING
|
||||
| HOUR
|
||||
| IF
|
||||
| IGNORE
|
||||
| IMPORT
|
||||
|
@ -1389,6 +1393,7 @@ nonReserved
|
|||
| MAP
|
||||
| MATCHED
|
||||
| MERGE
|
||||
| MINUTE
|
||||
| MONTH
|
||||
| MSCK
|
||||
| NAMESPACE
|
||||
|
@ -1612,6 +1617,7 @@ GRANT: 'GRANT';
|
|||
GROUP: 'GROUP';
|
||||
GROUPING: 'GROUPING';
|
||||
HAVING: 'HAVING';
|
||||
HOUR: 'HOUR';
|
||||
IF: 'IF';
|
||||
IGNORE: 'IGNORE';
|
||||
IMPORT: 'IMPORT';
|
||||
|
@ -1648,6 +1654,7 @@ MACRO: 'MACRO';
|
|||
MAP: 'MAP';
|
||||
MATCHED: 'MATCHED';
|
||||
MERGE: 'MERGE';
|
||||
MINUTE: 'MINUTE';
|
||||
MONTH: 'MONTH';
|
||||
MSCK: 'MSCK';
|
||||
NAMESPACE: 'NAMESPACE';
|
||||
|
|
|
@ -2514,8 +2514,15 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with SQLConfHelper with Logg
|
|||
}
|
||||
|
||||
override def visitDayTimeIntervalDataType(ctx: DayTimeIntervalDataTypeContext): DataType = {
|
||||
// TODO(SPARK-35736): Parse any day-time interval types in SQL
|
||||
DayTimeIntervalType()
|
||||
val strToFieldIndex =
|
||||
DayTimeIntervalType.dayTimeFields.map(i => DayTimeIntervalType.fieldToString(i) -> i).toMap
|
||||
val start = strToFieldIndex(ctx.from.getText.toLowerCase(Locale.ROOT))
|
||||
val end = if (ctx.to != null ) {
|
||||
strToFieldIndex(ctx.to.getText.toLowerCase(Locale.ROOT))
|
||||
} else {
|
||||
start
|
||||
}
|
||||
DayTimeIntervalType(start, end)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -257,7 +257,7 @@ class DataTypeSuite extends SparkFunSuite {
|
|||
checkDataTypeFromDDL(VarcharType(11))
|
||||
|
||||
checkDataTypeFromDDL(YearMonthIntervalType)
|
||||
checkDataTypeFromDDL(DayTimeIntervalType())
|
||||
dayTimeIntervalTypes.foreach(checkDataTypeFromDDL)
|
||||
|
||||
val metadata = new MetadataBuilder()
|
||||
.putString("name", "age")
|
||||
|
|
Loading…
Reference in a new issue