Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
yliuuuu committed Feb 26, 2024
1 parent 014a450 commit 30fe790
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ internal object RelConverter {
override fun visitFromJoin(node: From.Join, nil: Rel): Rel {
val lhs = visitFrom(node.lhs, nil)
val rhs = visitFrom(node.rhs, nil)
val schema = lhs.type.schema + rhs.type.schema
val props = emptySet<Rel.Prop>()
val condition = node.condition?.let { RexConverter.apply(it, env) } ?: rex(StaticType.BOOL, rexOpLit(boolValue(true)))

val joinType = when (node.type) {
From.Join.Type.LEFT_OUTER, From.Join.Type.LEFT -> Rel.Op.Join.Type.LEFT
Expand All @@ -254,17 +257,6 @@ internal object RelConverter {
From.Join.Type.CROSS -> Rel.Op.Join.Type.INNER // Cross Joins are just INNER JOIN ON TRUE
null -> Rel.Op.Join.Type.INNER // a JOIN b ON a.id = b.id <--> a INNER JOIN b ON a.id = b.id
}
val l = lhs.type.schema
val r = rhs.type.schema

val schema = when (joinType) {
Rel.Op.Join.Type.INNER -> l + r
Rel.Op.Join.Type.LEFT -> l + r.pad()
Rel.Op.Join.Type.RIGHT -> l.pad() + r
Rel.Op.Join.Type.FULL -> l.pad() + r.pad()
}
val props = emptySet<Rel.Prop>()
val condition = node.condition?.let { RexConverter.apply(it, env) } ?: rex(StaticType.BOOL, rexOpLit(boolValue(true)))

val type = relType(schema, props)
val op = relOpJoin(lhs, rhs, condition, joinType)
Expand All @@ -277,14 +269,6 @@ internal object RelConverter {
return copy(fields.map { it.copy(value = it.value.asNullable()) })
}

private fun List<Rel.Binding>.pad() = map {
val type = when (val t = it.type) {
is StructType -> t.withNullableFields()
else -> t.asNullable()
}
relBinding(it.name, type)
}

private fun convertScan(rex: Rex, binding: Rel.Binding): Rel {
val schema = listOf(binding)
val props = emptySet<Rel.Prop>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,34 +263,6 @@ internal object RexConverter {
return newRoot
}

val relFromDefault: (Rex, Int) -> Rel = { path, index ->
val schema = listOf(
relBinding(
name = "_v$index", // fresh variable
type = path.type
)
)
val props = emptySet<Rel.Prop>()
val relType = relType(schema, props)
rel(relType, relOpScan(path))
}

val relFromUnpivot: (Rex, Int) -> Rel = { path, index ->
val schema = listOf(
relBinding(
name = "_k$index", // fresh variable
type = StaticType.STRING
),
relBinding(
name = "_v$index", // fresh variable
type = path.type
)
)
val props = emptySet<Rel.Prop>()
val relType = relType(schema, props)
rel(relType, relOpUnpivot(path))
}

val fromList = mutableListOf<Rel>()

val pathNavi = newSteps.fold(newRoot) { current, step ->
Expand Down Expand Up @@ -327,13 +299,16 @@ internal object RexConverter {
}

is Expr.Path.Step.Unpivot -> {
val op = rexOpVarLocal(1, -1)
// Unpivot produces two binding, in this context we want the value,
// which always going to be the second binding
val op = rexOpVarLocal(1, 1)
val index = fromList.size
fromList.add(relFromUnpivot(current, index))
op
}
is Expr.Path.Step.Wildcard -> {
val op = rexOpVarLocal(1, -1)
// Scan produce only one binding
val op = rexOpVarLocal(1, 0)
val index = fromList.size
fromList.add(relFromDefault(current, index))
op
Expand All @@ -350,17 +325,59 @@ internal object RexConverter {
rel(type, relOpJoin(acc, scan, rex(StaticType.BOOL, rexOpLit(boolValue(true))), Rel.Op.Join.Type.INNER))
}

// compute the ref used by select construct
// always going to be the last binding
val selectRef = fromNode.type.schema.size - 1

val constructor = when (val op = pathNavi.op) {
is Rex.Op.Path.Index -> rex(pathNavi.type, rexOpPathIndex(rex(op.root.type, rexOpVarLocal(0, -1)), op.key))
is Rex.Op.Path.Key -> rex(pathNavi.type, rexOpPathKey(rex(op.root.type, rexOpVarLocal(0, -1)), op.key))
is Rex.Op.Path.Symbol -> rex(pathNavi.type, rexOpPathSymbol(rex(op.root.type, rexOpVarLocal(0, -1)), op.key))
is Rex.Op.Var.Local -> rex(pathNavi.type, rexOpVarLocal(0, -1))
is Rex.Op.Path.Index -> rex(pathNavi.type, rexOpPathIndex(rex(op.root.type, rexOpVarLocal(0, selectRef)), op.key))
is Rex.Op.Path.Key -> rex(pathNavi.type, rexOpPathKey(rex(op.root.type, rexOpVarLocal(0, selectRef)), op.key))
is Rex.Op.Path.Symbol -> rex(pathNavi.type, rexOpPathSymbol(rex(op.root.type, rexOpVarLocal(0, selectRef)), op.key))
is Rex.Op.Var.Local -> rex(pathNavi.type, rexOpVarLocal(0, selectRef))
else -> throw IllegalStateException()
}
val op = rexOpSelect(constructor, fromNode)
return rex(StaticType.ANY, op)
}

/**
* Construct Rel(Scan([path])).
*
* The constructed rel would produce one binding: _v$[index]
*/
private fun relFromDefault(path: Rex, index: Int): Rel {
val schema = listOf(
relBinding(
name = "_v$index", // fresh variable
type = path.type
)
)
val props = emptySet<Rel.Prop>()
val relType = relType(schema, props)
return rel(relType, relOpScan(path))
}

/**
* Construct Rel(Unpivot([path])).
*
* The constructed rel would produce two bindings: _k$[index] and _v$[index]
*/
private fun relFromUnpivot(path: Rex, index: Int): Rel {
val schema = listOf(
relBinding(
name = "_k$index", // fresh variable
type = StaticType.STRING
),
relBinding(
name = "_v$index", // fresh variable
type = path.type
)
)
val props = emptySet<Rel.Prop>()
val relType = relType(schema, props)
return rel(relType, relOpUnpivot(path))
}

private fun rexString(str: String) = rex(StaticType.STRING, rexOpLit(stringValue(str)))

override fun visitExprCall(node: Expr.Call, context: Env): Rex {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ import org.partiql.planner.internal.ir.rexOpStruct
import org.partiql.planner.internal.ir.rexOpStructField
import org.partiql.planner.internal.ir.rexOpSubquery
import org.partiql.planner.internal.ir.rexOpTupleUnion
import org.partiql.planner.internal.ir.rexOpVarLocal
import org.partiql.planner.internal.ir.statementQuery
import org.partiql.planner.internal.ir.util.PlanRewriter
import org.partiql.spi.BindingCase
Expand Down Expand Up @@ -94,7 +93,6 @@ import org.partiql.value.TextValue
import org.partiql.value.boolValue
import org.partiql.value.missingValue
import org.partiql.value.stringValue
import kotlin.math.absoluteValue

/**
* Rewrites an untyped algebraic translation of the query to be both typed and have resolved variables.
Expand Down Expand Up @@ -438,9 +436,8 @@ internal class PlanTyper(
assert(node.ref < scope.schema.size) {
"Invalid resolved variable (var ${node.ref}, stack frame ${node.depth}) in env: $locals"
}
val nodeRef = if (node.ref < 0) scope.schema.size - node.ref.absoluteValue else node.ref
val type = scope.schema.getOrNull(nodeRef)?.type ?: error("Can't find locals value.")
return rex(type, rexOpVarLocal(node.depth, nodeRef))
val type = scope.schema.getOrNull(node.ref)?.type ?: error("Can't find locals value.")
return rex(type, node)
}

override fun visitRexOpVarUnresolved(node: Rex.Op.Var.Unresolved, ctx: StaticType?): Rex {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ internal data class TypeEnv(
internal fun getScope(depth: Int): TypeEnv {
return when (depth) {
0 -> this
// TODO: Consider resolve the variable to the correct index
else -> outer.reversed()[depth - 1]
else -> outer[outer.size - depth]
}
}

Expand Down

0 comments on commit 30fe790

Please sign in to comment.