Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,25 @@
#### Enso Standard Library

- [Multiline if_then_else][14522].
- [Using dual JVM mode for Standard.Microsoft][14476].
- [Using dual JVM mode for `Standard.Microsoft`][14476].
- [Standard.Test pending field is lazy][14536].
- [Using dual JVM mode for Standard.AWS][14568].
- [Using dual JVM mode for `Standard.AWS`][14568].
- [Running `Standard.Tableau` in dual JVM mode][14607].
- [Polishing Standard.Test API][14599].

[14522]: https://github.com/enso-org/enso/pull/14522
[14476]: https://github.com/enso-org/enso/pull/14476
[14536]: https://github.com/enso-org/enso/pull/14536
[14568]: https://github.com/enso-org/enso/pull/14568
[14607]: https://github.com/enso-org/enso/pull/14607
[14599]: https://github.com/enso-org/enso/pull/14599

#### Enso Language & Runtime

- [`Panic.rethrow` keeps original location][14480]
- [Use `State.get if_missing` to avoid too frequent `Panic.throw`][14490]
- [Lazily initialized local variables with Ref.memoize][14554].
- [Flush system caches via Runtime.gc][14557]
- [Lazily initialized local variables with `Ref.new lazy=True`][14554].
- [Flush system caches via `Runtime.gc`][14557]

[14480]: https://github.com/enso-org/enso/pull/14480
[14490]: https://github.com/enso-org/enso/pull/14490
Expand Down
3 changes: 0 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3828,9 +3828,6 @@ lazy val `engine-runner` = project
`database-polyglot-root`
.listFiles("*.jar")
.map(_.getAbsolutePath()) ++
`std-tableau-polyglot-root`
.listFiles("*.jar")
.map(_.getAbsolutePath()) ++
`std-duckdb-polyglot-root`
.listFiles("*.jar")
.map(_.getAbsolutePath())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
- new columns:(Standard.Base.Data.Vector.Vector Standard.Base.Any.Any) -> (Standard.Table.Table.Table|Standard.Base.Any.Any)
- to_delimited self delimiter:(Standard.Table.Delimited.Delimited_Format.Delimited_Format|Standard.Base.Data.Text.Text)= quote_style:Standard.Table.Delimited.Quote_Style.Quote_Style= headers:Standard.Table.Headers.Headers= value_formatter:(Standard.Table.Data_Formatter.Data_Formatter|Standard.Base.Nothing.Nothing)= line_endings:(Standard.Base.Data.Text.Line_Ending_Style.Line_Ending_Style|Standard.Base.System.File_Format.Infer)= -> Standard.Base.Data.Text.Text
- from_java_table java_table:Standard.Base.Any.Any -> Standard.Base.Any.Any
- to_java_table table:Standard.Table.In_Memory_Table.In_Memory_Table -> Standard.Base.Any.Any
- to_java_table table:Standard.Table.In_Memory_Table.In_Memory_Table table_class:Standard.Base.Any.Any= column_class:Standard.Base.Any.Any= -> Standard.Base.Any.Any
- Standard.Table.Table.Table.from that:Standard.Table.In_Memory_Table.In_Memory_Table -> Standard.Table.Table.Table
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ from_java_table java_table =
private: true
---
Helper method for internal use to make a Java Table from a Table.
to_java_table table:In_Memory_Table =
table.java_table
to_java_table table:In_Memory_Table table_class=Java_Table column_class=Java_Column =
table.java_table table_class column_class

## ---
private: true
Expand Down
44 changes: 42 additions & 2 deletions distribution/lib/Standard/Tableau/0.0.0-dev/src/Hyper_File.enso
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ import project.Hyper_Table.Hyper_Table
import project.Internal.Telemetry

polyglot java import org.enso.tableau.HyperFormat
polyglot java import java.io.File as Java_File
polyglot java import java.io.FileNotFoundException
polyglot java import java.io.IOException
polyglot java import java.io.UncheckedIOException
polyglot java import java.nio.file.AccessDeniedException
polyglot java import java.nio.file.DirectoryNotEmptyException
polyglot java import java.nio.file.FileAlreadyExistsException
polyglot java import java.nio.file.FileSystemException
polyglot java import java.nio.file.NoSuchFileException
polyglot java import java.nio.file.NotDirectoryException

## Represents a Tableau Hyper Extract file.
type Hyper_File
Expand Down Expand Up @@ -41,7 +51,7 @@ type Hyper_File
Returns the list of schemas for the connection within the current database
(or catalog).
schemas : Vector Text
schemas self = File_Error.handle_java_exceptions self.file <|
schemas self = handle_java_exceptions self.file <|
array = HyperFormat.readSchemas self.file.path
Vector.from_polyglot_array array

Expand Down Expand Up @@ -76,7 +86,7 @@ type Hyper_File
@schema (hyper -> make_schema_selector hyper True)
tables : Text -> Vector Hyper_Table
tables self schema:Text=self.schema = if schema == "" then self.tables self.schema else
File_Error.handle_java_exceptions self.file <|
handle_java_exceptions self.file <|
array = case schema of
"*" -> HyperFormat.listTablesAllSchemas self.file.path
_ -> HyperFormat.listTables self.file.path schema
Expand Down Expand Up @@ -134,3 +144,33 @@ Table_Viz_Data.from (that:Hyper_File) =
tables = that.tables.map t->t.table.to_text
if schemas.distinct.length <= 1 then (Table_Viz_Data.GenericGrid [Table_Viz_Header.Link "Table" "Table" "read {{@Table}}"] [tables]) else
(Table_Viz_Data.GenericGrid [Table_Viz_Header.Label "Schema", Table_Viz_Header.Link "Table" "Table" "read {{@Table}} {{@Schema}}"] [schemas, tables])

private wrap_io_exception (file : File | Nothing) io_exception =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

associated_file = case io_exception of
_ : FileSystemException ->
path_from_exception = io_exception.getFile
if path_from_exception.is_nothing then file else
File.new path_from_exception
_ -> file

## If the file is not known, all we can do is throw a generic IO error.
This will only usually matter on stream operations, where there is no relevant file -
and so the exceptions like `NoSuchFileException` should not occur in such context.
But instead of risking a Type_Error, we just throw the more generic IO_Error.
if associated_file.is_nothing then Error.throw (File_Error.IO_Error Nothing "An IO error has occurred: "+io_exception.to_text) else case io_exception of
_ : FileNotFoundException -> Error.throw (File_Error.Not_Found associated_file)
_ : NoSuchFileException -> Error.throw (File_Error.Not_Found associated_file)
_ : FileAlreadyExistsException -> Error.throw (File_Error.Already_Exists associated_file)
_ : AccessDeniedException -> File_Error.access_denied associated_file
_ : DirectoryNotEmptyException -> Error.throw (File_Error.Directory_Not_Empty associated_file)
_ : NotDirectoryException -> Error.throw (File_Error.Not_A_Directory associated_file)
_ -> Error.throw (File_Error.IO_Error associated_file "An IO error has occurred: "+io_exception.to_text)

private handle_java_exceptions (file : File | Nothing) ~action =
handle_io_exception caught_panic =
wrap_io_exception file caught_panic.payload
handle_unchecked_io_exception caught_panic =
wrap_io_exception file caught_panic.payload.getCause
Panic.catch IOException handler=handle_io_exception <|
Panic.catch UncheckedIOException handler=handle_unchecked_io_exception <|
action
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import project.Hyper_File.Hyper_File
polyglot java import java.sql.Types
polyglot java import org.enso.tableau.HyperFormat
polyglot java import org.enso.tableau.HyperTableColumn
polyglot java import org.enso.table.problems.ProblemAggregator

## An Enso representation of a Tableau Hyper Table.
type Hyper_Table
Expand Down Expand Up @@ -108,7 +109,7 @@ type Hyper_Table
@max_rows Rows_To_Read.default_widget
read : Rows_To_Read -> Table
read self (max_rows : Rows_To_Read = ..All_Rows) = File_Error.handle_java_exceptions self.file.file <| Hyper_Errors.handle_java_exceptions <|
Java_Problems.with_problem_aggregator Problem_Behavior.Report_Warning java_problem_aggregator->
Java_Problems.with_problem_aggregator problem_aggregator=ProblemAggregator Problem_Behavior.Report_Warning java_problem_aggregator->
row_count = if max_rows == Rows_To_Read.All_Rows then Nothing else max_rows.rows
java_columns = HyperFormat.readTable self.file.file.path self.schema self.table row_count java_problem_aggregator
enso_columns = java_columns.map Java_Exports.make_column_from_java_column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import project.Internal.Telemetry
from project.Hyper_Errors import Hyper_Unsupported_Type

polyglot java import org.enso.tableau.HyperFormat
polyglot java import org.enso.table.data.table.Column as Java_Column
polyglot java import org.enso.table.data.table.Table as Java_Table

## Read the file to a `Hyper_File` object.
type Tableau_Format
Expand Down Expand Up @@ -127,7 +129,8 @@ type Tableau_Format
Tableau_Format.Hyper_Table _ t -> t
_ -> "Extract"
warning_unmatched_columns = Hyper_Errors.handle_java_exceptions <|
HyperFormat.writeTable resolved_file resolved_schema resolved_table (to_java_table table:In_Memory_Table) (on_existing_file == Existing_File_Behavior.Append) (match_columns == Match_Columns.By_Name) (on_problems == Problem_Behavior.Report_Error)
java_table = to_java_table table:In_Memory_Table Java_Table Java_Column
HyperFormat.writeTable resolved_file resolved_schema resolved_table java_table (on_existing_file == Existing_File_Behavior.Append) (match_columns == Match_Columns.By_Name) (on_problems == Problem_Behavior.Report_Error)
problems = if warning_unmatched_columns.length > 0 then [Unmatched_Columns.Error warning_unmatched_columns.to_vector] else []
on_problems.attach_problems_before problems <|
File.new resolved_file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URI;
Expand Down Expand Up @@ -54,6 +55,7 @@
import org.enso.table.data.table.Table;
import org.enso.table.problems.ProblemAggregator;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -168,7 +170,7 @@ public URL getResource(String name) {
dotIdx == -1 ? name.substring(libIdx + 1) : name.substring(libIdx + 1, dotIdx);
// Windows libs don't have `lib` prefix.
var libName = osLibName.startsWith("lib") ? osLibName.substring(3) : osLibName;
var bindings = Context.getCurrent().getBindings("enso");
var bindings = getBindings();
var found = bindings.invokeMember("find_native_library", libName);
try {
if (found == null || found.asString() == null) {
Expand All @@ -195,7 +197,7 @@ public InputStream getResourceAsStream(String name) {
dotIdx == -1 ? name.substring(libIdx + 1) : name.substring(libIdx + 1, dotIdx);
// Windows libs don't have `lib` prefix.
var libName = osLibName.startsWith("lib") ? osLibName.substring(3) : osLibName;
var bindings = Context.getCurrent().getBindings("enso");
var bindings = getBindings();
var found = bindings.invokeMember("find_native_library", libName);
try {
if (found == null || found.asString() == null) {
Expand Down Expand Up @@ -399,8 +401,18 @@ private static TableDefinition createTable(
return tableDef;
}

@SuppressWarnings("unchecked")
private static <T> StorageType<T> toLocal(StorageType<T> type) {
if (Proxy.isProxyClass(type.getClass())) {
var local = StorageType.fromTypeCharAndSize(type.typeChar(), type.size());
return (StorageType<T>) local;
} else {
return type;
}
}

private static SqlType mapEnsoTypeToSqlType(StorageType<?> type) {
return switch (type) {
return switch (toLocal(type)) {
case TextType t -> SqlType.text();
case IntegerType t -> SqlType.bigInt();
case FloatType t -> SqlType.doublePrecision();
Expand Down Expand Up @@ -504,7 +516,39 @@ private static void addValueToInserter(Inserter inserter, ColumnStorage<?> stora
case LocalTime lt -> inserter.add(lt);
case ZonedDateTime zdt -> inserter.add(zdt);
case BigDecimal bd -> inserter.add(bd);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is different than the classical switch over StorageType. That one can be fixed by making the StorageType local. Is there any reason why this code has to be different and not follow the typical switch (storageType) pattern?

default -> throw new HyperUnsupportedTypeError(value.toString());
default -> {
var v = Value.asValue(value);
if (v.isDate() && v.isTime() && v.isTimeZone()) {
inserter.add(ZonedDateTime.of(v.asDate(), v.asTime(), v.asTimeZone()));
} else if (v.isDate()) {
inserter.add(v.asDate());
} else if (v.isTime()) {
inserter.add(v.asTime());
} else if (v.fitsInLong()) {
inserter.add(v.asLong());
} else if (v.fitsInDouble()) {
inserter.add(v.asDouble());
} else if (v.isBoolean()) {
inserter.add(v.asBoolean());
} else {
var type = value.getClass().getName();
if (v.getMetaObject() instanceof Value meta) {
type = meta.getMetaQualifiedName();
}
if ("java.math.BigDecimal".equals(type)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var unscaledValue = v.invokeMember("unscaledValue");
var scale = v.invokeMember("scale");
if (unscaledValue != null
&& unscaledValue.fitsInBigInteger()
&& scale != null
&& scale.fitsInInt()) {
inserter.add(new BigDecimal(unscaledValue.asBigInteger(), scale.asInt()));
return;
}
}
throw new HyperUnsupportedTypeError(value.toString() + " type: " + type);
}
}
}
}
}
Expand Down Expand Up @@ -588,4 +632,14 @@ private static void validateTypesMatch(ColumnStorage<?>[] storages, TableDefinit
}
}
}

private static Value getBindings() {
var ctx = Context.getCurrent();
var bindings = ctx.getPolyglotBindings().getMember("ensoBindings");
if (bindings != null) {
return bindings.execute("enso");
} else {
return ctx.getBindings("enso");
}
}
}
Loading
Loading