Skip to content

Commit

Permalink
Configure default timezone (#449)
Browse files Browse the repository at this point in the history
  • Loading branch information
lziq authored Sep 29, 2021
1 parent 5b3769f commit 28701e2
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 48 deletions.
5 changes: 2 additions & 3 deletions lang/src/org/partiql/lang/eval/EvaluatingCompiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import org.partiql.lang.eval.time.Time
import org.partiql.lang.eval.visitors.PartiqlAstSanityValidator
import org.partiql.lang.syntax.SqlParser
import org.partiql.lang.util.*
import org.partiql.lang.util.DEFAULT_TIMEZONE_OFFSET
import java.math.*
import java.util.*
import kotlin.collections.*
Expand Down Expand Up @@ -811,7 +810,7 @@ internal class EvaluatingCompiler(
val locationMeta = metas.sourceLocationMeta
thunkFactory.thunkEnv(metas) { env ->
val valueToCast = expThunk(env)
valueToCast.cast(dataType, valueFactory, locationMeta)
valueToCast.cast(dataType, valueFactory, locationMeta, env.session)
}
}
}
Expand Down Expand Up @@ -2010,7 +2009,7 @@ internal class EvaluatingCompiler(
second,
nano,
precision,
if (with_time_zone && tz_minutes == null) DEFAULT_TIMEZONE_OFFSET.totalMinutes else tz_minutes
if (with_time_zone && tz_minutes == null) it.session.defaultTimezoneOffset.totalMinutes else tz_minutes
)
)
}
Expand Down
14 changes: 12 additions & 2 deletions lang/src/org/partiql/lang/eval/EvaluationSession.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.partiql.lang.eval

import com.amazon.ion.*
import java.time.ZoneOffset

/**
* Evaluation Session. Holds user defined constants used during evaluation. Each value has a default value that can
Expand All @@ -23,10 +24,12 @@ import com.amazon.ion.*
* @property globals The global bindings. Defaults to [Bindings.empty]
* @property parameters List of parameters to be substituted for positional placeholders
* @property now Timestamp to consider as the current time, used by functions like `utcnow()` and `now()`. Defaults to [Timestamp.nowZ]
* @property defaultTimezoneOffset Default timezone offset to be used when TIME WITH TIME ZONE does not explicitily specify the time zone. Defaults to [ZoneOffset.UTC]
*/
class EvaluationSession private constructor(val globals: Bindings<ExprValue>,
val parameters: List<ExprValue>,
val now: Timestamp) {
val now: Timestamp,
val defaultTimezoneOffset: ZoneOffset) {
companion object {
/**
* Java style builder to construct a new [EvaluationSession]. Uses the default value for any non specified field
Expand Down Expand Up @@ -68,8 +71,15 @@ class EvaluationSession private constructor(val globals: Bindings<ExprValue>,
return this
}

private var defaultTimezoneOffset: ZoneOffset = ZoneOffset.UTC
fun defaultTimezoneOffset(value: ZoneOffset): Builder {
defaultTimezoneOffset = value
return this
}

fun build(): EvaluationSession = EvaluationSession(now = now ?: Timestamp.nowZ(),
parameters = parameters,
globals = globals)
globals = globals,
defaultTimezoneOffset = defaultTimezoneOffset)
}
}
8 changes: 5 additions & 3 deletions lang/src/org/partiql/lang/eval/ExprValueExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,13 @@ private val genericTimeRegex = Regex("\\d\\d:\\d\\d:\\d\\d(\\.\\d*)?([+|-]\\d\\d
*
* @param ion The ion system to synthesize values with.
* @param targetDataType The target type to cast this value to.
* @param session The EvaluationSession which provides necessary information for evaluation.
*/
fun ExprValue.cast(
targetDataType: DataType,
valueFactory: ExprValueFactory,
locationMeta: SourceLocationMeta?
locationMeta: SourceLocationMeta?,
session: EvaluationSession
): ExprValue {

val targetSqlDataType = targetDataType.sqlDataType
Expand Down Expand Up @@ -362,7 +364,7 @@ fun ExprValue.cast(
type == TIME -> {
val time = timeValue()
val timeZoneOffset = when (targetSqlDataType) {
SqlDataType.TIME_WITH_TIME_ZONE -> time.zoneOffset?: DEFAULT_TIMEZONE_OFFSET
SqlDataType.TIME_WITH_TIME_ZONE -> time.zoneOffset?: session.defaultTimezoneOffset
else -> null
}
return valueFactory.newTime(
Expand Down Expand Up @@ -405,7 +407,7 @@ fun ExprValue.cast(

// Note that the [genericTimeRegex] has a group to extract the zone offset.
val zoneOffsetString = matcher.group(2)
val zoneOffset = zoneOffsetString?.let { ZoneOffset.of(it) } ?: DEFAULT_TIMEZONE_OFFSET
val zoneOffset = zoneOffsetString?.let { ZoneOffset.of(it) } ?: session.defaultTimezoneOffset

return valueFactory.newTime(
Time.of(
Expand Down
8 changes: 0 additions & 8 deletions lang/src/org/partiql/lang/eval/time/TimeExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ internal val genericTimeRegex = Regex("\\d\\d:\\d\\d:\\d\\d(\\.\\d*)?([+|-]\\d\\
*/
internal val DATE_PATTERN_REGEX = Regex("\\d\\d\\d\\d-\\d\\d-\\d\\d")

/**
* If the default timezone offset is not provided with [CompileOptions], it defaults to [ZoneOffset.UTC].
* (The option to specify default timezone offset will be available once [#410](https://github.com/partiql/partiql-lang-kotlin/issues/410) is resolved)
*
* If timezone offset is not specified explicitly (when using `TIME WITH TIME ZONE`), the default time zone offset is used.
*/
internal val DEFAULT_TIMEZONE_OFFSET = ZoneOffset.UTC

/**
* Returns the string representation of the [ZoneOffset] in HH:mm format.
*/
Expand Down
Loading

0 comments on commit 28701e2

Please sign in to comment.