Skip to content

Commit

Permalink
Merge branch 'master' into update/auth-2.20.15
Browse files Browse the repository at this point in the history
  • Loading branch information
xerial authored Mar 25, 2023
2 parents a6d918c + 2ac7f2d commit 841350a
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 35 deletions.
14 changes: 14 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pull_request_rules:
- name: Automatic merge Scala Steward PRs
conditions:
- author=xerial-bot
- check-success~=.*
- or:
- title~=^Update airframe-
- title~=^Update sbt-airframe
- title~=^Update airspec
- label=sbt-plugin-update
- label=test-library-update
actions:
merge:
method: squash
Original file line number Diff line number Diff line change
Expand Up @@ -442,13 +442,13 @@ object TypeResolver extends LogSupport {
): List[Expression] = {
val resolvedAttributes = inputAttributes.map(resolveAttribute)

def lookup(name: String): List[Expression] = {
def lookup(name: String, context: AnalyzerContext): List[Expression] = {
val resolvedExprs = List.newBuilder[Expression]
ColumnPath.fromQName(context.database, name) match {
ColumnPath.fromQName(name) match {
case Some(columnPath) =>
resolvedAttributes.foreach {
case a: Attribute =>
resolvedExprs ++= a.matched(columnPath)
resolvedExprs ++= a.matched(columnPath, context)
case _ =>
}
case None =>
Expand All @@ -458,9 +458,9 @@ object TypeResolver extends LogSupport {

val results = expr match {
case i: Identifier =>
lookup(i.value).map(toResolvedAttribute(i.value, _))
lookup(i.value, context).map(toResolvedAttribute(i.value, _))
case u @ UnresolvedAttribute(qualifier, name, _) =>
lookup(u.fullName).map(toResolvedAttribute(name, _).withQualifier(qualifier))
lookup(u.fullName, context).map(toResolvedAttribute(name, _).withQualifier(qualifier))
case a @ AllColumns(qualifier, None, _) =>
// Resolve the inputs of AllColumn as ResolvedAttribute
// so as not to pull up too much details
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package wvlet.airframe.sql.model

import wvlet.airframe.sql.analyzer.AnalyzerContext
import wvlet.airframe.sql.catalog.DataType
import wvlet.airframe.sql.catalog.DataType._
import wvlet.airframe.sql.model.Expression.{AllColumns, MultiSourceColumn}
Expand Down Expand Up @@ -232,10 +233,10 @@ trait BinaryExpression extends Expression {
case class ColumnPath(database: Option[String], table: Option[String], columnName: String)

object ColumnPath {
def fromQName(contextDatabase: String, fullName: String): Option[ColumnPath] = {
def fromQName(fullName: String): Option[ColumnPath] = {
// TODO Should we handle quotation in the name or just reject such strings?
fullName.split("\\.").toList match {
case List(db, t, c) if db == contextDatabase =>
case List(db, t, c) =>
Some(ColumnPath(Some(db), Some(t), c))
case List(t, c) =>
Some(ColumnPath(None, Some(t), c))
Expand Down Expand Up @@ -338,33 +339,52 @@ trait Attribute extends LeafExpression with LogSupport {
* If a given column name matches with this Attribute, return this. If there are multiple candidate attributes (e.g.,
* via Join, Union), return MultiSourceAttribute.
*/
def matched(columnPath: ColumnPath): Option[Attribute] = {
def findMatched(columnName: String): Seq[Attribute] = {
this match {
case a: AllColumns =>
a.inputColumns.filter(_.name == columnName)
case a: Attribute if a.name == columnName =>
Seq(a)
case _ =>
Seq.empty
def matched(columnPath: ColumnPath, context: AnalyzerContext): Option[Attribute] = {
def findMatched(tableName: Option[String], columnName: String): Seq[Attribute] = {
tableName match {
case Some(tableName) =>
this match {
case r: ResolvedAttribute if r.sourceColumn.exists(_.table.name == tableName) =>
findMatched(None, columnName)
case _ =>
Nil
}
case None =>
this match {
case a: AllColumns =>
a.inputColumns.filter(_.name == columnName)
case a: Attribute if a.name == columnName =>
Seq(a)
case _ =>
Seq.empty
}
}
}

val result: Seq[Attribute] = columnPath.table match {
val result: Seq[Attribute] = columnPath match {
// TODO handle (catalog).(database).(table) names in the qualifier
case Some(tableName) =>
if (qualifier.exists(_ == tableName)) {
findMatched(columnPath.columnName).map(_.withQualifier(qualifier))
case ColumnPath(Some(databaseName), Some(tableName), columnName) =>
if (databaseName == context.database) {
if (qualifier.exists(_ == tableName)) {
findMatched(None, columnName).map(_.withQualifier(qualifier))
} else {
findMatched(Some(tableName), columnName)
}
} else {
this match {
case r: ResolvedAttribute if r.sourceColumn.nonEmpty && r.sourceColumn.get.table.name == tableName =>
findMatched(columnPath.columnName)
case _ =>
Nil
case r: ResolvedAttribute if r.sourceColumn.exists(_.table.database.contains(databaseName)) =>
findMatched(Some(tableName), columnName)
case _ => Nil
}
}
case None =>
findMatched(columnPath.columnName)
case ColumnPath(None, Some(tableName), columnName) =>
if (qualifier.exists(_ == tableName)) {
findMatched(None, columnName).map(_.withQualifier(qualifier))
} else {
findMatched(Some(tableName), columnName)
}
case ColumnPath(_, _, columnName) =>
findMatched(None, columnName)
}

if (result.size > 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ class TypeResolverTest extends AirSpec with ResolverTestHelper {
.addColumn(c2)
)

private val d1 = TableColumn("id", DataType.LongType, properties = Map("tag" -> Seq("personal_identifier")))
private val d2 = TableColumn("name", DataType.StringType, properties = Map("tag" -> Seq("private")))

private val tableD = Catalog.newTable(
"shared",
"D",
Catalog.newSchema
.addColumn(d1)
.addColumn(d2)
)

override protected def demoCatalog: Catalog = {
val catalog = new InMemoryCatalog(
"global",
Expand All @@ -68,6 +79,8 @@ class TypeResolverTest extends AirSpec with ResolverTestHelper {
catalog.createTable(tableA, CreateMode.CREATE_IF_NOT_EXISTS)
catalog.createTable(tableB, CreateMode.CREATE_IF_NOT_EXISTS)
catalog.createTable(tableC, CreateMode.CREATE_IF_NOT_EXISTS)
catalog.createDatabase(Catalog.Database("shared"), CreateMode.CREATE_IF_NOT_EXISTS)
catalog.createTable(tableD, CreateMode.CREATE_IF_NOT_EXISTS)
catalog
}

Expand Down Expand Up @@ -1029,4 +1042,18 @@ class TypeResolverTest extends AirSpec with ResolverTestHelper {
}
}

test("Resolve column name fully qualified with non-default database name in join condition") {
analyze(
"""select default.A.name from default.A
|inner join shared.D on A.id = shared.D.id""".stripMargin
)
val e = intercept[SQLError] {
analyze(
"""select default.A.name from default.A
|inner join shared.D on A.id = shared.A.id""".stripMargin
)
}
e.message.contains("join key column: id is not found") shouldBe true
}

}
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ val targetScalaVersions = SCALA_3 :: uptoScala2
// Add this for using snapshot versions
// ThisBuild / resolvers += Resolver.sonatypeRepo("snapshots")

val AIRSPEC_VERSION = "22.12.5"
val AIRSPEC_VERSION = "23.3.4"
val SCALACHECK_VERSION = "1.17.0"
val MSGPACK_VERSION = "0.9.3"
val SCALA_PARSER_COMBINATOR_VERSION = "2.2.0"
val SQLITE_JDBC_VERSION = "3.41.0.1"
val SQLITE_JDBC_VERSION = "3.41.2.1"
val SLF4J_VERSION = "2.0.7"
val JS_JAVA_LOGGING_VERSION = "1.0.0"
val JS_JAVA_TIME_VERSION = "1.0.0"
Expand Down Expand Up @@ -867,9 +867,9 @@ lazy val parquet =
description := "Parquet columnar format reader/writer support",
libraryDependencies ++= Seq(
"org.apache.parquet" % "parquet-hadoop" % PARQUET_VERSION,
"org.apache.hadoop" % "hadoop-client" % "3.3.4" % Provided,
"org.apache.hadoop" % "hadoop-client" % "3.3.5" % Provided,
// For S3 support
"org.apache.hadoop" % "hadoop-aws" % "3.3.4" % Provided,
"org.apache.hadoop" % "hadoop-aws" % "3.3.5" % Provided,
"software.amazon.awssdk" % "auth" % "2.20.15" % Provided,
// For Apple Silicon (M1)
"org.xerial.snappy" % "snappy-java" % "1.1.9.1",
Expand Down
4 changes: 4 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ title: Release Notes

Airframe uses YY.MM.patch versioning scheme, so the version numbers match with the release year and month.

## 23.3.4

[Release notes](https://github.com/wvlet/airframe/releases/tag/v23.3.4)

## 23.3.3

[Release notes](https://github.com/wvlet/airframe/releases/tag/v23.3.3)
Expand Down
2 changes: 1 addition & 1 deletion examples/rpc-examples/hello-rpc/build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
val AIRFRAME_VERSION = "23.3.2"
val AIRFRAME_VERSION = "23.3.4"
ThisBuild / scalaVersion := "2.13.10"

// RPC API definition. This project should contain only RPC interfaces
Expand Down
2 changes: 1 addition & 1 deletion examples/rpc-examples/hello-rpc/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % "always"

addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.17")
addSbtPlugin("org.wvlet.airframe" % "sbt-airframe" % "23.3.2")
addSbtPlugin("org.wvlet.airframe" % "sbt-airframe" % "23.3.4")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
2 changes: 1 addition & 1 deletion examples/rpc-examples/rpc-scalajs/build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Global / onChangedBuildSource := ReloadOnSourceChanges

val AIRFRAME_VERSION = "23.3.2"
val AIRFRAME_VERSION = "23.3.4"
ThisBuild / scalaVersion := "2.13.10"

lazy val rpcExample =
Expand Down
2 changes: 1 addition & 1 deletion examples/rpc-examples/rpc-scalajs/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % "always"

addSbtPlugin("org.wvlet.airframe" % "sbt-airframe" % "23.3.2")
addSbtPlugin("org.wvlet.airframe" % "sbt-airframe" % "23.3.4")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.9.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
2 changes: 1 addition & 1 deletion examples/rx-demo/gallery/build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Global / onChangedBuildSource := ReloadOnSourceChanges

val AIRFRAME_VERSION = "23.3.2"
val AIRFRAME_VERSION = "23.3.4"
ThisBuild / scalaVersion := "2.13.10"

lazy val gallery =
Expand Down

0 comments on commit 841350a

Please sign in to comment.