-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updates plugins to use the Catalog and Bindings interfaces (#1502)
- Loading branch information
Showing
26 changed files
with
349 additions
and
1,208 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
partiql-cli/src/test/kotlin/org/partiql/plugins/local/LocalConnectorTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.partiql.plugins.local | ||
|
||
import org.junit.jupiter.api.Test | ||
|
||
class LocalConnectorTest { | ||
|
||
@Test | ||
fun sanity() { | ||
TODO("Not yet implemented") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 17 additions & 13 deletions
30
partiql-planner/src/main/kotlin/org/partiql/planner/catalog/Name.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,28 @@ | ||
package org.partiql.planner.catalog | ||
|
||
import java.util.Spliterator | ||
import java.util.function.Consumer | ||
|
||
/** | ||
* Thin wrapper over a list of strings. | ||
*/ | ||
public data class Name(public val steps: List<String>) : Iterable<String> { | ||
|
||
public companion object { | ||
public data class Name( | ||
private val namespace: Namespace, | ||
private val name: String, | ||
) { | ||
|
||
@JvmStatic | ||
public fun of(vararg steps: String): Name = Name(steps.toList()) | ||
} | ||
public fun getNamespace(): Namespace = namespace | ||
|
||
public operator fun get(index: Int): String = steps[index] | ||
public fun hasNamespace(): Boolean = !namespace.isEmpty() | ||
|
||
override fun forEach(action: Consumer<in String>?): Unit = steps.forEach(action) | ||
public fun getName(): String = name | ||
|
||
override fun iterator(): Iterator<String> = steps.iterator() | ||
public companion object { | ||
|
||
override fun spliterator(): Spliterator<String> = steps.spliterator() | ||
@JvmStatic | ||
public fun of(vararg names: String): Name { | ||
assert(names.size > 1) { "Cannot create an empty" } | ||
return Name( | ||
namespace = Namespace.of(*names.drop(1).toTypedArray()), | ||
name = names.last(), | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
plugins/partiql-local/src/main/kotlin/org/partiql/plugins/local/LocalBindings.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.partiql.plugins.local | ||
|
||
import org.partiql.eval.bindings.Binding | ||
import org.partiql.eval.bindings.Bindings | ||
|
||
internal object LocalBindings : Bindings { | ||
|
||
override fun getBindings(name: String): Bindings? = null | ||
|
||
override fun getBinding(name: String): Binding? = null | ||
} |
140 changes: 53 additions & 87 deletions
140
plugins/partiql-local/src/main/kotlin/org/partiql/plugins/local/LocalCatalog.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,109 +1,75 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at: | ||
* | ||
* http://aws.amazon.com/apache2.0/ | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific | ||
* language governing permissions and limitations under the License. | ||
*/ | ||
|
||
package org.partiql.plugins.local | ||
|
||
import com.amazon.ionelement.api.loadSingleElement | ||
import org.partiql.spi.BindingCase | ||
import org.partiql.spi.BindingName | ||
import org.partiql.spi.BindingPath | ||
import org.partiql.types.StaticType | ||
import java.io.File | ||
import org.partiql.planner.catalog.Catalog | ||
import org.partiql.planner.catalog.Name | ||
import org.partiql.planner.catalog.Namespace | ||
import org.partiql.planner.catalog.Routine | ||
import org.partiql.planner.catalog.Table | ||
import java.nio.file.Path | ||
|
||
private sealed class FsTree(val name: String) { | ||
|
||
// "Directory" node | ||
class D(name: String, val children: List<FsTree>) : FsTree(name) | ||
|
||
// Type node | ||
class T(name: String, val type: StaticType) : FsTree(name) | ||
} | ||
import kotlin.io.path.isDirectory | ||
import kotlin.io.path.notExists | ||
|
||
/** | ||
* Build a memoized catalog tree from local schema definitions. | ||
* Implementation of [Catalog] where dirs are namespaces and files are table metadata. | ||
*/ | ||
internal class LocalCatalog private constructor(private val root: FsTree.D) { | ||
internal class LocalCatalog( | ||
private val name: String, | ||
private val root: Path, | ||
) : Catalog { | ||
|
||
/** | ||
* Search the tree for the type. | ||
*/ | ||
public fun lookup(path: BindingPath): LocalObject? { | ||
val match = mutableListOf<String>() | ||
var curr: FsTree? = root | ||
for (step in path.steps) { | ||
if (curr == null) return null | ||
when (curr) { | ||
is FsTree.T -> break | ||
is FsTree.D -> { | ||
curr = curr.children.firstOrNull { step.matches(it.name) } | ||
if (curr != null) match.add(curr.name) | ||
} | ||
} | ||
} | ||
// All steps matched and we're at a leaf | ||
if (curr is FsTree.T) { | ||
return LocalObject(match, curr.type) | ||
} | ||
return null | ||
private companion object { | ||
private const val EXT = ".ion" | ||
} | ||
|
||
init { | ||
assert(root.isDirectory()) { "LocalNamespace must be a directory" } | ||
} | ||
|
||
/** | ||
* Provide a list of all objects in this catalog. | ||
*/ | ||
public fun listObjects(): List<BindingPath> = sequence { search(emptyList(), root) }.toList() | ||
override fun getName(): String { | ||
return name | ||
} | ||
|
||
private suspend fun SequenceScope<BindingPath>.search(acc: List<BindingName>, node: FsTree) = | ||
when (node) { | ||
is FsTree.D -> search(acc, node) | ||
is FsTree.T -> search(acc, node) | ||
override fun getTable(name: Name): Table? { | ||
val path = toPath(name.getNamespace()).resolve(name.getName() + EXT) | ||
if (path.notExists() || !path.isDirectory()) { | ||
return null | ||
} | ||
return LocalTable(name.getName(), path) | ||
} | ||
|
||
private suspend fun SequenceScope<BindingPath>.search(acc: List<BindingName>, node: FsTree.D) { | ||
val steps = acc + BindingName(node.name, BindingCase.INSENSITIVE) | ||
for (child in node.children) { | ||
search(steps, child) | ||
override fun listTables(namespace: Namespace): Collection<Name> { | ||
val path = toPath(namespace) | ||
if (path.notExists()) { | ||
// throw exception? | ||
return emptyList() | ||
} | ||
return super.listTables(namespace) | ||
} | ||
|
||
private suspend fun SequenceScope<BindingPath>.search(acc: List<BindingName>, node: FsTree.T) { | ||
val steps = acc + BindingName(node.name, BindingCase.INSENSITIVE) | ||
this.yield(BindingPath(steps)) | ||
override fun listNamespaces(namespace: Namespace): Collection<Namespace> { | ||
val path = toPath(namespace) | ||
if (path.notExists() || path.isDirectory()) { | ||
// throw exception? | ||
return emptyList() | ||
} | ||
// List all child directories | ||
return path.toFile() | ||
.listFiles()!! | ||
.filter { it.isDirectory } | ||
.map { toNamespace(it.toPath()) } | ||
} | ||
|
||
companion object { | ||
|
||
/** | ||
* Builds a FsTree from the given root. | ||
*/ | ||
public fun load(root: Path): LocalCatalog = LocalCatalog(root.toFile().tree() as FsTree.D) | ||
override fun getRoutines(name: Name): Collection<Routine> = emptyList() | ||
|
||
private fun File.tree(): FsTree = when (this.isDirectory) { | ||
true -> d() | ||
else -> t() | ||
} | ||
|
||
private fun File.d(): FsTree.D { | ||
val children = listFiles()!!.map { it.tree() } | ||
return FsTree.D(name, children) | ||
private fun toPath(namespace: Namespace): Path { | ||
var curr = root | ||
for (level in namespace) { | ||
curr = curr.resolve(level) | ||
} | ||
return curr | ||
} | ||
|
||
private fun File.t(): FsTree.T { | ||
val text = readText() | ||
val ion = loadSingleElement(text) | ||
val type = ion.toStaticType() | ||
return FsTree.T(nameWithoutExtension, type) | ||
} | ||
private fun toNamespace(path: Path): Namespace { | ||
return Namespace.of(path.relativize(root).map { it.toString() }) | ||
} | ||
} |
Oops, something went wrong.