From 48b79228d3fab7a9f1a1aa1c1146b682139419f0 Mon Sep 17 00:00:00 2001 From: XuQianJin-Stars Date: Wed, 14 Jul 2021 19:43:25 +0800 Subject: [PATCH] [CALCITE-3329] Implement osquery for OS adapter After this commit, the 'sqlsh' command has new tables cpu_info, cpu_time, interface_addresses, interface_details, java_info, memory_info, mounts, os_version, system_info. Add Forward Xu to .mailmap file (Julian Hyde). Document new tables in OS adapter (Julian Hyde). Close apache/calcite#3585 --- .mailmap | 6 +- bom/build.gradle.kts | 13 +- gradle.properties | 5 +- plus/build.gradle.kts | 11 + .../os/AbstractBaseScannableTable.java | 55 ++++ .../adapter/os/CpuInfoTableFunction.java | 62 +++++ .../adapter/os/CpuTimeTableFunction.java | 61 +++++ .../calcite/adapter/os/DuTableFunction.java | 32 +-- .../adapter/os/FilesTableFunction.java | 33 +-- .../adapter/os/GitCommitsTableFunction.java | 28 +- .../os/InterfaceAddressesTableFunction.java | 58 ++++ .../os/InterfaceDetailsTableFunction.java | 66 +++++ .../adapter/os/JavaInfoTableFunction.java | 71 +++++ .../calcite/adapter/os/JpsTableFunction.java | 33 +-- .../adapter/os/MemoryInfoTableFunction.java | 61 +++++ .../adapter/os/MountsTableFunction.java | 61 +++++ .../apache/calcite/adapter/os/OsQuery.java | 70 +++++ .../calcite/adapter/os/OsQueryType.java | 82 ++++++ .../adapter/os/OsVersionTableFunction.java | 58 ++++ .../calcite/adapter/os/PsTableFunction.java | 33 +-- .../apache/calcite/adapter/os/SqlShell.java | 18 ++ .../adapter/os/StdinTableFunction.java | 34 +-- .../adapter/os/SystemInfoTableFunction.java | 71 +++++ .../adapter/os/VmstatTableFunction.java | 30 +-- .../adapter/utils/OsQueryTableUtil.java | 250 ++++++++++++++++++ .../calcite/adapter/utils/package-info.java | 21 ++ .../calcite/adapter/os/OsAdapterTest.java | 97 +++++-- site/_docs/os_adapter.md | 13 +- 28 files changed, 1204 insertions(+), 229 deletions(-) create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/AbstractBaseScannableTable.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/CpuInfoTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/CpuTimeTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/InterfaceAddressesTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/InterfaceDetailsTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/JavaInfoTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/MemoryInfoTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/MountsTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/OsQuery.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/OsQueryType.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/OsVersionTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/os/SystemInfoTableFunction.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/utils/OsQueryTableUtil.java create mode 100644 plus/src/main/java/org/apache/calcite/adapter/utils/package-info.java diff --git a/.mailmap b/.mailmap index 2024f7e1e14..061550ae5f2 100644 --- a/.mailmap +++ b/.mailmap @@ -47,7 +47,10 @@ Feng Zhu # DonnyZone at github Feng Zhu Feng Zhu Feng Zhu -ForwardXu +Forward Xu +Forward Xu +Forward Xu # aka XuQianJin-Stars, Qianjin Xu +Forward Xu Godfrey He Hequn Cheng Hong Shen (沈洪) @@ -102,7 +105,6 @@ Peng Wang pengzhiwei Praveen Kumar Qi Yu (余启) -Qianjin Xu Rafay Qureshi Ruben Quesada Lopez Rui Wang diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts index 58aa51a84cf..79fb7cc56bb 100644 --- a/bom/build.gradle.kts +++ b/bom/build.gradle.kts @@ -51,16 +51,13 @@ dependencies { // runtime means "the dependency is only for runtime, not for compilation" // In other words, marking dependency as "runtime" would avoid accidental // dependency on it during compilation + apiv("cn.hutool:hutool-all") apiv("com.alibaba.database:innodb-java-reader") apiv("com.beust:jcommander") - apiv("org.checkerframework:checker-qual", "checkerframework") apiv("com.datastax.oss:java-driver-core", "cassandra-java-driver-core") - apiv("org.locationtech.jts:jts-core") - apiv("org.locationtech.jts.io:jts-io-common") - apiv("org.locationtech.proj4j:proj4j") - apiv("org.locationtech.proj4j:proj4j-epsg", "proj4j") apiv("com.fasterxml.jackson.core:jackson-databind") apiv("com.github.kstyrc:embedded-redis") + apiv("com.github.oshi:oshi-core") apiv("com.github.stephenc.jcip:jcip-annotations") apiv("com.google.errorprone:error_prone_annotations", "errorprone") apiv("com.google.errorprone:error_prone_type_annotations", "errorprone") @@ -75,6 +72,11 @@ dependencies { apiv("com.yahoo.datasketches:sketches-core") apiv("commons-codec:commons-codec") apiv("commons-io:commons-io") + apiv("org.checkerframework:checker-qual", "checkerframework") + apiv("org.locationtech.jts:jts-core") + apiv("org.locationtech.jts.io:jts-io-common") + apiv("org.locationtech.proj4j:proj4j") + apiv("org.locationtech.proj4j:proj4j-epsg", "proj4j") apiv("de.bwaldvogel:mongo-java-server", "mongo-java-server") apiv("de.bwaldvogel:mongo-java-server-core", "mongo-java-server") apiv("de.bwaldvogel:mongo-java-server-memory-backend", "mongo-java-server") @@ -93,6 +95,7 @@ dependencies { apiv("net.hydromatic:sql-logic-test") apiv("net.hydromatic:tpcds", "hydromatic.tpcds") apiv("net.java.dev.jna:jna") + apiv("net.java.dev.jna:jna-platform") apiv("net.sf.opencsv:opencsv") apiv("org.apache.calcite.avatica:avatica-core", "calcite.avatica") apiv("org.apache.calcite.avatica:avatica-server", "calcite.avatica") diff --git a/gradle.properties b/gradle.properties index cda90d717d6..0442aee5966 100644 --- a/gradle.properties +++ b/gradle.properties @@ -117,6 +117,7 @@ hamcrest.version=2.1 hsqldb.version=2.7.2 httpclient.version=4.5.9 httpcore.version=4.4.11 +hutool-all.version=5.8.23 hydromatic.tpcds.version=0.4 immutables.version=2.8.8 innodb-java-reader.version=1.0.10 @@ -129,7 +130,8 @@ jcommander.version=1.72 jedis.version=3.3.0 jetty.version=9.4.46.v20220331 jmh.version=1.12 -jna.version=5.7.0 +jna.version=5.14.0 +jna-platform.version=5.14.0 joda-time.version=2.8.1 json-path.version=2.8.0 jsr305.version=3.0.2 @@ -147,6 +149,7 @@ mysql-connector-java.version=5.1.20 natty.version=0.13 ojdbc8.version=19.3.0.0 opencsv.version=2.3 +oshi-core.version=6.4.9 pig.version=0.16.0 pigunit.version=0.16.0 postgresql.version=9.3-1102-jdbc41 diff --git a/plus/build.gradle.kts b/plus/build.gradle.kts index fc696a44978..63fa9fcabd3 100644 --- a/plus/build.gradle.kts +++ b/plus/build.gradle.kts @@ -23,9 +23,20 @@ dependencies { implementation("com.google.guava:guava") implementation("com.teradata.tpcds:tpcds") + implementation("cn.hutool:hutool-all") implementation("io.prestosql.tpch:tpch") implementation("net.hydromatic:chinook-data-hsqldb") implementation("net.hydromatic:tpcds") + implementation("net.java.dev.jna:jna") + implementation("net.java.dev.jna:jna-platform") + + implementation("com.github.oshi:oshi-core") { + exclude("log4j", "log4j") + .because("log4j is already present in the classpath") + exclude("org.slf4j", "slf4j-api") + .because("slf4j is already present in the classpath") + } + implementation("org.apache.calcite.avatica:avatica-server") implementation("org.hsqldb:hsqldb::jdk8") diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/AbstractBaseScannableTable.java b/plus/src/main/java/org/apache/calcite/adapter/os/AbstractBaseScannableTable.java new file mode 100644 index 00000000000..9f1bb186b1d --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/AbstractBaseScannableTable.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.config.CalciteConnectionConfig; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.schema.Schema; +import org.apache.calcite.schema.Statistic; +import org.apache.calcite.schema.Statistics; +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.util.ImmutableBitSet; + +import com.google.common.collect.ImmutableList; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Abstract base class for implementations of OS table functions. + */ +abstract class AbstractBaseScannableTable implements ScannableTable { + protected AbstractBaseScannableTable() { + } + + @Override public Statistic getStatistic() { + return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); + } + + @Override public Schema.TableType getJdbcTableType() { + return Schema.TableType.TABLE; + } + + @Override public boolean isRolledUp(String column) { + return false; + } + + @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, + @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { + return true; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/CpuInfoTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/CpuInfoTableFunction.java new file mode 100644 index 00000000000..a42d897a39d --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/CpuInfoTableFunction.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "cpu_info". + */ +public class CpuInfoTableFunction { + private CpuInfoTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("cpu_info"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("device_id", SqlTypeName.VARCHAR) + .add("model", SqlTypeName.VARCHAR) + .add("manufacturer", SqlTypeName.VARCHAR) + .add("number_of_cores", SqlTypeName.INTEGER) + .add("logical_processors", SqlTypeName.INTEGER) + .add("address_width", SqlTypeName.INTEGER) + .add("max_clock_speed", SqlTypeName.BIGINT) + .add("socket_designation", SqlTypeName.INTEGER) + .add("cpu_load", SqlTypeName.DOUBLE) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/CpuTimeTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/CpuTimeTableFunction.java new file mode 100644 index 00000000000..e76ececcaf5 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/CpuTimeTableFunction.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "cpu_info". + */ +public class CpuTimeTableFunction { + private CpuTimeTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("cpu_time"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("idle", SqlTypeName.BIGINT) + .add("nice", SqlTypeName.BIGINT) + .add("irq", SqlTypeName.BIGINT) + .add("soft_irq", SqlTypeName.BIGINT) + .add("steal", SqlTypeName.BIGINT) + .add("system", SqlTypeName.BIGINT) + .add("user", SqlTypeName.BIGINT) + .add("io_wait", SqlTypeName.BIGINT) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/DuTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/DuTableFunction.java index 75bdc29ba5e..f1847bfab75 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/DuTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/DuTableFunction.java @@ -17,20 +17,11 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; - -import com.google.common.collect.ImmutableList; import org.checkerframework.checker.nullness.qual.Nullable; @@ -39,10 +30,11 @@ * to compute file sizes. */ public class DuTableFunction { - private DuTableFunction() {} + private DuTableFunction() { + } public static ScannableTable eval(boolean b) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { return Processes.processLines("du", "-ak") .select(a0 -> { @@ -57,24 +49,6 @@ public static ScannableTable eval(boolean b) { .add("path", SqlTypeName.VARCHAR) .build(); } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } - } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java index c09c9f52f8a..694b3ccbebb 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/FilesTableFunction.java @@ -18,20 +18,13 @@ import org.apache.calcite.DataContext; import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.AbstractEnumerable; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.linq4j.Enumerator; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Util; import com.google.common.collect.ImmutableList; @@ -52,15 +45,17 @@ public class FilesTableFunction { private static final BigDecimal THOUSAND = BigDecimal.valueOf(1000L); - private FilesTableFunction() {} + private FilesTableFunction() { + } - /** Evaluates the function. + /** + * Evaluates the function. * * @param path Directory in which to start the search. Typically '.' * @return Table that can be inspected, planned, and evaluated */ public static ScannableTable eval(final String path) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { return typeFactory.builder() .add("access_time", SqlTypeName.TIMESTAMP) // %A@ sec since epoch @@ -267,24 +262,6 @@ private Object field(String field, String value) { } }; } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } - } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/GitCommitsTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/GitCommitsTableFunction.java index 28aa4fd5387..282117a88f6 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/GitCommitsTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/GitCommitsTableFunction.java @@ -17,22 +17,13 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.AbstractEnumerable; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.linq4j.Enumerator; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; - -import com.google.common.collect.ImmutableList; import org.checkerframework.checker.nullness.qual.Nullable; @@ -54,7 +45,7 @@ public class GitCommitsTableFunction { private GitCommitsTableFunction() {} public static ScannableTable eval(boolean b) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { final Enumerable enumerable = Processes.processLines("git", "log", "--pretty=raw"); @@ -158,23 +149,6 @@ public static ScannableTable eval(boolean b) { .add("message", SqlTypeName.VARCHAR) .build(); } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(0))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceAddressesTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceAddressesTableFunction.java new file mode 100644 index 00000000000..6c566fc34ec --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceAddressesTableFunction.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "interface_addresses". + */ +public class InterfaceAddressesTableFunction { + private InterfaceAddressesTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("interface_addresses"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("name", SqlTypeName.VARCHAR) + .add("ipv4_address", SqlTypeName.VARCHAR) + .add("ipv6_address", SqlTypeName.VARCHAR) + .add("mac", SqlTypeName.VARCHAR) + .add("status", SqlTypeName.VARCHAR) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceDetailsTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceDetailsTableFunction.java new file mode 100644 index 00000000000..507e8ab2c9d --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/InterfaceDetailsTableFunction.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "interface_details". + */ +public class InterfaceDetailsTableFunction { + private InterfaceDetailsTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("interface_details"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("device_name", SqlTypeName.VARCHAR) + .add("mac", SqlTypeName.VARCHAR) + .add("is_virtual", SqlTypeName.VARCHAR) + .add("mtu", SqlTypeName.BIGINT) + .add("speed", SqlTypeName.BIGINT) + .add("i_packets", SqlTypeName.BIGINT) + .add("o_packets", SqlTypeName.BIGINT) + .add("i_bytes", SqlTypeName.BIGINT) + .add("o_bytes", SqlTypeName.BIGINT) + .add("i_errors", SqlTypeName.BIGINT) + .add("o_errors", SqlTypeName.BIGINT) + .add("i_drops", SqlTypeName.BIGINT) + .add("collisions", SqlTypeName.BIGINT) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/JavaInfoTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/JavaInfoTableFunction.java new file mode 100644 index 00000000000..adacb0b5c3c --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/JavaInfoTableFunction.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "java_info". + */ +public class JavaInfoTableFunction { + private JavaInfoTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("java_info"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("java_version", SqlTypeName.VARCHAR) + .add("java_vendor", SqlTypeName.VARCHAR) + .add("java_vendor_url", SqlTypeName.VARCHAR) + .add("java_home", SqlTypeName.VARCHAR) + .add("java_vm_specification_version", SqlTypeName.VARCHAR) + .add("java_vm_specification_vendor", SqlTypeName.VARCHAR) + .add("java_vm_specification_name", SqlTypeName.VARCHAR) + .add("java_vm_version", SqlTypeName.VARCHAR) + .add("java_vm_vendor", SqlTypeName.VARCHAR) + .add("java_vm_name", SqlTypeName.VARCHAR) + .add("java_specification_version", SqlTypeName.VARCHAR) + .add("java_specification_vender", SqlTypeName.VARCHAR) + .add("java_specification_name", SqlTypeName.VARCHAR) + .add("java_class_version", SqlTypeName.VARCHAR) + .add("java_class_path", SqlTypeName.VARCHAR) + .add("java_io_tmpdir", SqlTypeName.VARCHAR) + .add("java_ext_dirs", SqlTypeName.VARCHAR) + .add("java_library_path", SqlTypeName.VARCHAR) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/JpsTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/JpsTableFunction.java index 60d98230e5b..1d4ae1c2c5e 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/JpsTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/JpsTableFunction.java @@ -17,20 +17,11 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; - -import com.google.common.collect.ImmutableList; import org.checkerframework.checker.nullness.qual.Nullable; @@ -43,11 +34,9 @@ private JpsTableFunction() { } public static ScannableTable eval(boolean b) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { - // https://github.com/eclipse/openj9/issues/11036 - // openj9 jps doesn't handle multiple flags in one argument - return Processes.processLines("jps", "-m", "-l", "-v") + return Processes.processLines("jps", "-mlvV") .select(a0 -> { final String[] fields = a0.split(" "); return new Object[]{Long.valueOf(fields[0]), fields[1]}; @@ -60,24 +49,6 @@ public static ScannableTable eval(boolean b) { .add("info", SqlTypeName.VARCHAR) .build(); } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } - } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/MemoryInfoTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/MemoryInfoTableFunction.java new file mode 100644 index 00000000000..5047f3f885f --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/MemoryInfoTableFunction.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "memory_info". + */ +public class MemoryInfoTableFunction { + private MemoryInfoTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("memory_info"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("mem_total", SqlTypeName.DOUBLE) + .add("mem_used", SqlTypeName.DOUBLE) + .add("mem_free", SqlTypeName.DOUBLE) + .add("swap_total", SqlTypeName.DOUBLE) + .add("swap_used", SqlTypeName.DOUBLE) + .add("swap_free", SqlTypeName.DOUBLE) + .add("swap_pages_in", SqlTypeName.DOUBLE) + .add("swap_pages_out", SqlTypeName.DOUBLE) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/MountsTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/MountsTableFunction.java new file mode 100644 index 00000000000..3beb4b230e4 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/MountsTableFunction.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "mounts". + */ +public class MountsTableFunction { + private MountsTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("mounts"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("name", SqlTypeName.VARCHAR) + .add("volume", SqlTypeName.VARCHAR) + .add("size", SqlTypeName.VARCHAR) + .add("used", SqlTypeName.VARCHAR) + .add("avail", SqlTypeName.VARCHAR) + .add("iused", SqlTypeName.VARCHAR) + .add("ifree", SqlTypeName.VARCHAR) + .add("path", SqlTypeName.VARCHAR) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/OsQuery.java b/plus/src/main/java/org/apache/calcite/adapter/os/OsQuery.java new file mode 100644 index 00000000000..83c01811df6 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/OsQuery.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.linq4j.Linq4j; +import org.apache.calcite.util.trace.CalciteTrace; + +import org.slf4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Enumerator that reads from OS's System. + */ +public class OsQuery implements Enumerator { + private static final Logger LOGGER = CalciteTrace.getParserTracer(); + + private final Enumerator enumerator; + + public OsQuery(String type) { + this.enumerator = Linq4j.enumerator(eval(type)); + } + + public Enumerator getEnumerator() { + return enumerator; + } + + @Override public Object[] current() { + return enumerator.current(); + } + + @Override public boolean moveNext() { + return enumerator.moveNext(); + } + + @Override public void reset() { + enumerator.reset(); + } + + @Override public void close() { + enumerator.close(); + } + + public List eval(String type) { + OsQueryType queryType = OsQueryType.valueOf(type.toUpperCase(Locale.ROOT)); + try { + return queryType.getInfo(); + } catch (Exception e) { + LOGGER.error("Failed to get result's info", e); + return new ArrayList<>(); + } + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/OsQueryType.java b/plus/src/main/java/org/apache/calcite/adapter/os/OsQueryType.java new file mode 100644 index 00000000000..3534da06bba --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/OsQueryType.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import java.util.List; + +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getCpuInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getCpuTimeInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getInterfaceAddressesInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getInterfaceDetailsInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getJavaInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getMemoryInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getMountsInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getOsVersionInfo; +import static org.apache.calcite.adapter.utils.OsQueryTableUtil.getSystemInfo; + +/** + * Get system enumeration information. + */ +public enum OsQueryType { + SYSTEM_INFO { + @Override public List getInfo() { + return getSystemInfo(); + } + }, + JAVA_INFO { + @Override public List getInfo() { + return getJavaInfo(); + } + }, + OS_VERSION { + @Override public List getInfo() { + return getOsVersionInfo(); + } + }, + MEMORY_INFO { + @Override public List getInfo() { + return getMemoryInfo(); + } + }, + CPU_INFO { + @Override public List getInfo() { + return getCpuInfo(); + } + }, + CPU_TIME { + @Override public List getInfo() { + return getCpuTimeInfo(); + } + }, + INTERFACE_ADDRESSES { + @Override public List getInfo() { + return getInterfaceAddressesInfo(); + } + }, + INTERFACE_DETAILS { + @Override public List getInfo() { + return getInterfaceDetailsInfo(); + } + }, + MOUNTS { + @Override public List getInfo() { + return getMountsInfo(); + } + }; + + public abstract List getInfo(); +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/OsVersionTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/OsVersionTableFunction.java new file mode 100644 index 00000000000..961e89597b7 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/OsVersionTableFunction.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "os_version". + */ +public class OsVersionTableFunction { + private OsVersionTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("os_version"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("name", SqlTypeName.VARCHAR) + .add("version", SqlTypeName.VARCHAR) + .add("build", SqlTypeName.VARCHAR) + .add("code_name", SqlTypeName.VARCHAR) + .add("install_date", SqlTypeName.BIGINT) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/PsTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/PsTableFunction.java index d84f836c569..8c829877b2b 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/PsTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/PsTableFunction.java @@ -17,21 +17,13 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.adapter.java.JavaTypeFactory; import org.apache.calcite.avatica.util.TimeUnit; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.linq4j.function.Function1; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Util; import com.google.common.collect.ImmutableList; @@ -52,13 +44,13 @@ public class PsTableFunction { private static final Pattern HOUR_MINUTE_SECOND_PATTERN = Pattern.compile("([0-9]+):([0-9]+)\\.([0-9]+)"); - private PsTableFunction() {} + private PsTableFunction() { + } public static ScannableTable eval(boolean b) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { - JavaTypeFactory typeFactory = root.getTypeFactory(); - final RelDataType rowType = getRowType(typeFactory); + final RelDataType rowType = getRowType(root.getTypeFactory()); final List fieldNames = ImmutableList.copyOf(rowType.getFieldNames()); final String[] args; @@ -161,23 +153,6 @@ private Object field(String field, String value) { .add("command", SqlTypeName.VARCHAR) .build(); } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/SqlShell.java b/plus/src/main/java/org/apache/calcite/adapter/os/SqlShell.java index fa4c4976168..295b43678de 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/SqlShell.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/SqlShell.java @@ -81,6 +81,15 @@ private static String model() { addView(b, "ps", "select * from table(\"ps\"(true))"); addView(b, "stdin", "select * from table(\"stdin\"(true))"); addView(b, "vmstat", "select * from table(\"vmstat\"(true))"); + addView(b, "system_info", "select * from table(\"system_info\"(true))"); + addView(b, "java_info", "select * from table(\"java_info\"(true))"); + addView(b, "os_version", "select * from table(\"os_version\"(true))"); + addView(b, "memory_info", "select * from table(\"memory_info\"(true))"); + addView(b, "cpu_info", "select * from table(\"cpu_info\"(true))"); + addView(b, "cpu_time", "select * from table(\"cpu_time\"(true))"); + addView(b, "interface_details", "select * from table(\"interface_details\"(true))"); + addView(b, "interface_addresses", "select * from table(\"interface_addresses\"(true))"); + addView(b, "mounts", "select * from table(\"mounts\"(true))"); b.append(" } ],\n") .append(" functions: [ {\n"); addFunction(b, "du", DuTableFunction.class); @@ -90,6 +99,15 @@ private static String model() { addFunction(b, "ps", PsTableFunction.class); addFunction(b, "stdin", StdinTableFunction.class); addFunction(b, "vmstat", VmstatTableFunction.class); + addFunction(b, "system_info", SystemInfoTableFunction.class); + addFunction(b, "java_info", JavaInfoTableFunction.class); + addFunction(b, "os_version", OsVersionTableFunction.class); + addFunction(b, "memory_info", MemoryInfoTableFunction.class); + addFunction(b, "cpu_info", CpuInfoTableFunction.class); + addFunction(b, "cpu_time", CpuTimeTableFunction.class); + addFunction(b, "interface_details", InterfaceDetailsTableFunction.class); + addFunction(b, "interface_addresses", InterfaceAddressesTableFunction.class); + addFunction(b, "mounts", MountsTableFunction.class); b.append(" } ]\n") .append(" }\n") .append(" ]\n") diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/StdinTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/StdinTableFunction.java index 624b0785346..493bccbe99d 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/StdinTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/StdinTableFunction.java @@ -17,22 +17,13 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.AbstractEnumerable; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.linq4j.Enumerator; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; - -import com.google.common.collect.ImmutableList; import org.checkerframework.checker.nullness.qual.Nullable; @@ -48,16 +39,18 @@ */ public class StdinTableFunction { - private StdinTableFunction() {} + private StdinTableFunction() { + } public static ScannableTable eval(boolean b) { - return new ScannableTable() { - @Override public Enumerable scan(DataContext root) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { final InputStream is = DataContext.Variable.STDIN.get(root); return new AbstractEnumerable() { final InputStreamReader in = new InputStreamReader(is, StandardCharsets.UTF_8); final BufferedReader br = new BufferedReader(in); + @Override public Enumerator enumerator() { return new Enumerator() { @Nullable String line; @@ -102,23 +95,6 @@ public static ScannableTable eval(boolean b) { .add("line", SqlTypeName.VARCHAR) .build(); } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } } diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/SystemInfoTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/SystemInfoTableFunction.java new file mode 100644 index 00000000000..36e40645488 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/os/SystemInfoTableFunction.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.os; + +import org.apache.calcite.DataContext; +import org.apache.calcite.linq4j.AbstractEnumerable; +import org.apache.calcite.linq4j.Enumerable; +import org.apache.calcite.linq4j.Enumerator; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.schema.ScannableTable; +import org.apache.calcite.sql.type.SqlTypeName; + +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Table function that executes the OS "system_info". + */ +public class SystemInfoTableFunction { + private SystemInfoTableFunction() { + } + + public static ScannableTable eval(boolean b) { + return new AbstractBaseScannableTable() { + @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { + return new AbstractEnumerable() { + @Override public Enumerator enumerator() { + return new OsQuery("system_info"); + } + }; + } + + @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) { + return typeFactory.builder() + .add("hostname", SqlTypeName.VARCHAR) + .add("uuid", SqlTypeName.VARCHAR) + .add("cpu_type", SqlTypeName.VARCHAR) + .add("cpu_vendor", SqlTypeName.VARCHAR) + .add("cpu_model", SqlTypeName.VARCHAR) + .add("cpu_physical_cores", SqlTypeName.INTEGER) + .add("cpu_logical_cores", SqlTypeName.INTEGER) + .add("cpu_sockets", SqlTypeName.INTEGER) + .add("physical_memory", SqlTypeName.BIGINT) + .add("hardware_vendor", SqlTypeName.VARCHAR) + .add("hardware_model", SqlTypeName.VARCHAR) + .add("hardware_version", SqlTypeName.VARCHAR) + .add("hardware_serial", SqlTypeName.VARCHAR) + .add("board_vendor", SqlTypeName.VARCHAR) + .add("board_model", SqlTypeName.VARCHAR) + .add("board_version", SqlTypeName.VARCHAR) + .add("board_serial", SqlTypeName.VARCHAR) + .add("computer_name", SqlTypeName.VARCHAR) + .build(); + } + }; + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/os/VmstatTableFunction.java b/plus/src/main/java/org/apache/calcite/adapter/os/VmstatTableFunction.java index ecfda06ef37..424166941cc 100644 --- a/plus/src/main/java/org/apache/calcite/adapter/os/VmstatTableFunction.java +++ b/plus/src/main/java/org/apache/calcite/adapter/os/VmstatTableFunction.java @@ -17,20 +17,12 @@ package org.apache.calcite.adapter.os; import org.apache.calcite.DataContext; -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.config.CalciteConnectionConfig; import org.apache.calcite.linq4j.Enumerable; import org.apache.calcite.linq4j.function.Function1; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.schema.ScannableTable; -import org.apache.calcite.schema.Schema; -import org.apache.calcite.schema.Statistic; -import org.apache.calcite.schema.Statistics; -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.type.SqlTypeName; -import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Util; import com.google.common.collect.ImmutableList; @@ -48,10 +40,9 @@ public class VmstatTableFunction { private VmstatTableFunction() {} public static ScannableTable eval(boolean b) { - return new ScannableTable() { + return new AbstractBaseScannableTable() { @Override public Enumerable<@Nullable Object[]> scan(DataContext root) { - JavaTypeFactory typeFactory = root.getTypeFactory(); - final RelDataType rowType = getRowType(typeFactory); + final RelDataType rowType = getRowType(root.getTypeFactory()); final List fieldNames = ImmutableList.copyOf(rowType.getFieldNames()); final String[] args; @@ -152,23 +143,6 @@ private Object field(@SuppressWarnings("unused") String field, String value) { .build(); } } - - @Override public Statistic getStatistic() { - return Statistics.of(1000d, ImmutableList.of(ImmutableBitSet.of(1))); - } - - @Override public Schema.TableType getJdbcTableType() { - return Schema.TableType.TABLE; - } - - @Override public boolean isRolledUp(String column) { - return false; - } - - @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call, - @Nullable SqlNode parent, @Nullable CalciteConnectionConfig config) { - return true; - } }; } } diff --git a/plus/src/main/java/org/apache/calcite/adapter/utils/OsQueryTableUtil.java b/plus/src/main/java/org/apache/calcite/adapter/utils/OsQueryTableUtil.java new file mode 100644 index 00000000000..9b55830d823 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/utils/OsQueryTableUtil.java @@ -0,0 +1,250 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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.apache.calcite.adapter.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Properties; + +import cn.hutool.system.oshi.CpuTicks; +import cn.hutool.system.oshi.OshiUtil; +import oshi.hardware.CentralProcessor; +import oshi.hardware.GlobalMemory; +import oshi.hardware.NetworkIF; +import oshi.hardware.VirtualMemory; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; + +/** + * Used to put OS query related func. + */ +public class OsQueryTableUtil { + private static final String IP_ADDRESS_SEPARATOR = "; "; + + private OsQueryTableUtil() { + } + + public static List getSystemInfo() { + final List list = new ArrayList<>(); + Object[] objects = { + OshiUtil.getOs().getNetworkParams().getHostName(), + OshiUtil.getSystem().getSerialNumber(), + OshiUtil.getProcessor().getProcessorIdentifier().getMicroarchitecture(), + OshiUtil.getProcessor().getProcessorIdentifier().getVendor(), + OshiUtil.getProcessor().getProcessorIdentifier().getModel(), + OshiUtil.getProcessor().getPhysicalProcessorCount(), + OshiUtil.getProcessor().getLogicalProcessorCount(), + OshiUtil.getProcessor().getPhysicalPackageCount(), + OshiUtil.getMemory().getTotal(), + OshiUtil.getHardware().getComputerSystem().getFirmware().getManufacturer(), + OshiUtil.getHardware().getComputerSystem().getModel(), + OshiUtil.getHardware().getComputerSystem().getFirmware().getVersion(), + OshiUtil.getHardware().getComputerSystem().getSerialNumber(), + OshiUtil.getHardware().getComputerSystem().getBaseboard().getManufacturer(), + OshiUtil.getHardware().getComputerSystem().getBaseboard().getModel(), + OshiUtil.getHardware().getComputerSystem().getBaseboard().getVersion(), + OshiUtil.getHardware().getComputerSystem().getBaseboard().getSerialNumber(), + OshiUtil.getOs().getNetworkParams().getDomainName() + }; + list.add(objects); + return list; + } + + public static List getJavaInfo() { + final List list = new ArrayList<>(); + final Properties props = System.getProperties(); + final Object[] objects = { + props.getProperty("java.version"), + props.getProperty("java.vendor"), + props.getProperty("java.vendor.url"), + props.getProperty("java.home"), + props.getProperty("java.vm.specification.version"), + props.getProperty("java.vm.specification.vendor"), + props.getProperty("java.vm.specification.name"), + props.getProperty("java.vm.version"), + props.getProperty("java.vm.vendor"), + props.getProperty("java.vm.name"), + props.getProperty("java.specification.version"), + props.getProperty("java.specification.vender"), + props.getProperty("java.specification.name"), + props.getProperty("java.class.version"), + props.getProperty("java.class.path"), + props.getProperty("java.io.tmpdir"), + props.getProperty("java.ext.dirs"), + props.getProperty("java.library.path") + }; + list.add(objects); + return list; + } + + public static List getOsVersionInfo() { + final List list = new ArrayList<>(); + OperatingSystem os = OshiUtil.getOs(); + final Object[] objects = { + os.getVersionInfo().toString(), + os.getVersionInfo().getCodeName(), + os.getVersionInfo().getBuildNumber(), + os.getVersionInfo().getCodeName(), + os.getSystemBootTime() + }; + list.add(objects); + return list; + } + + public static List getMemoryInfo() { + GlobalMemory memory = OshiUtil.getMemory(); + VirtualMemory virtualMemory = memory.getVirtualMemory(); + + final List list = new ArrayList<>(); + final Object[] objects = { + getNetFileSizeDescription(memory.getTotal()), + getNetFileSizeDescription(memory.getAvailable()), + getNetFileSizeDescription(memory.getTotal() - memory.getAvailable()), + getNetFileSizeDescription(virtualMemory.getSwapTotal()), + getNetFileSizeDescription(virtualMemory.getSwapUsed()), + getNetFileSizeDescription(virtualMemory.getSwapTotal() - virtualMemory.getSwapUsed()), + getNetFileSizeDescription(virtualMemory.getSwapPagesIn()), + getNetFileSizeDescription(virtualMemory.getSwapPagesOut()) + }; + list.add(objects); + return list; + } + + public static List getCpuInfo() { + final List list = new ArrayList<>(); + CentralProcessor processor = OshiUtil.getProcessor(); + Object[] objects = { + processor.getProcessorIdentifier().getProcessorID(), + processor.getProcessorIdentifier().getModel(), + processor.getProcessorIdentifier().getMicroarchitecture(), + processor.getPhysicalProcessorCount(), + processor.getLogicalProcessorCount(), + processor.getProcessorIdentifier().isCpu64bit() ? 64 : 32, + processor.getMaxFreq(), + processor.getPhysicalPackageCount(), + processor.getSystemCpuLoad(1000L) + }; + list.add(objects); + return list; + } + + public static List getCpuTimeInfo() { + final List list = new ArrayList<>(); + CpuTicks cpuTicks = OshiUtil.getCpuInfo().getTicks(); + Object[] objects = { + cpuTicks.getIdle(), + cpuTicks.getNice(), + cpuTicks.getIrq(), + cpuTicks.getSoftIrq(), + cpuTicks.getSteal(), + cpuTicks.getcSys(), + cpuTicks.getUser(), + cpuTicks.getIoWait() + }; + list.add(objects); + return list; + } + + public static List getInterfaceAddressesInfo() { + final List list = new ArrayList<>(); + List networkIFList = OshiUtil.getNetworkIFs(); + for (NetworkIF intf : networkIFList) { + Object[] objects = { + intf.getName(), + getIPAddressesString(intf.getIPv4addr()), + getIPAddressesString(intf.getIPv6addr()), + intf.getMacaddr(), + intf.getIfOperStatus().toString().contains("UNKNOWN") ? "" : intf.getIfOperStatus() + }; + list.add(objects); + } + return list; + } + + public static List getInterfaceDetailsInfo() { + final List list = new ArrayList<>(); + List networkIFList = OshiUtil.getNetworkIFs(); + for (NetworkIF intf : networkIFList) { + Object[] objects = { + intf.getName(), + intf.getMacaddr(), + intf.queryNetworkInterface().isVirtual(), + intf.getMTU(), + intf.getSpeed(), + intf.getPacketsRecv(), + intf.getPacketsSent(), + intf.getBytesRecv(), + intf.getBytesSent(), + intf.getInErrors(), + intf.getOutErrors(), + intf.getInDrops(), + intf.getCollisions() + }; + list.add(objects); + } + return list; + } + + public static List getMountsInfo() { + final List list = new ArrayList<>(); + FileSystem fileSystem = OshiUtil.getOs().getFileSystem(); + List fileStores = fileSystem.getFileStores(); + for (OSFileStore fileStore : fileStores) { + Object[] objects = { + fileStore.getName(), + fileStore.getName(), + getNetFileSizeDescription(fileStore.getTotalSpace()), + getNetFileSizeDescription(fileStore.getUsableSpace()), + getNetFileSizeDescription(fileStore.getFreeSpace()), + getNetFileSizeDescription(fileStore.getTotalInodes()), + getNetFileSizeDescription(fileStore.getFreeInodes()), + fileStore.getMount() + }; + list.add(objects); + } + return list; + } + + public static String getIPAddressesString(String[] ipAddressArr) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + + for (String ipAddress : ipAddressArr) { + if (first) { + first = false; + } else { + sb.append(IP_ADDRESS_SEPARATOR); + } + sb.append(ipAddress); + } + + return sb.toString(); + } + + public static String getNetFileSizeDescription(long size) { + String[] units = {"B", "KB", "MB", "GB"}; + int index = 0; + double fileSize = size; + while (fileSize >= 1024 && index < units.length - 1) { + fileSize /= 1024; + index++; + } + return String.format(Locale.ROOT, "%.2f%s", fileSize, units[index]); + } +} diff --git a/plus/src/main/java/org/apache/calcite/adapter/utils/package-info.java b/plus/src/main/java/org/apache/calcite/adapter/utils/package-info.java new file mode 100644 index 00000000000..619fdc2c2d9 --- /dev/null +++ b/plus/src/main/java/org/apache/calcite/adapter/utils/package-info.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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. + */ + +/** + * Used to put OS adapter related util classes. + */ +package org.apache.calcite.adapter.utils; diff --git a/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java b/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java index 33d0aba9d8c..ab03a8198ae 100644 --- a/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java +++ b/plus/src/test/java/org/apache/calcite/adapter/os/OsAdapterTest.java @@ -36,12 +36,14 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.util.function.Consumer; import static org.apache.calcite.util.TestUtil.rethrow; +import static org.hamcrest.CoreMatchers.any; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.startsWith; @@ -53,6 +55,8 @@ import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static java.util.Objects.requireNonNull; + /** * Unit tests for the OS (operating system) adapter. * @@ -68,16 +72,18 @@ * */ class OsAdapterTest { + private static final String OS_NAME = System.getProperty("os.name"); + private static boolean isWindows() { - return System.getProperty("os.name").startsWith("Windows"); + return OS_NAME.startsWith("Windows"); } /** Returns whether there is a ".git" directory in this directory or in a * directory between this directory and root. */ private static boolean hasGit() { assumeToolExists("git"); - final String path = Sources.of(OsAdapterTest.class.getResource("/")) - .file().getAbsolutePath(); + final URL url = requireNonNull(OsAdapterTest.class.getResource("/")); + final String path = Sources.of(url).file().getAbsolutePath(); File f = new File(path); for (;;) { if (f == null || !f.exists()) { @@ -212,10 +218,11 @@ private static boolean checkProcessExists(String command) { final String q = "select pid, info from jps"; sql(q).returns(r -> { try { - assertThat(r.next(), is(true)); - assertThat(r.getString(1), notNullValue()); - assertThat(r.getString(2), notNullValue()); - assertThat(r.wasNull(), is(false)); + if (r.next()) { + assertThat(r.getString(1), notNullValue()); + assertThat(r.getString(2), notNullValue()); + assertThat(r.wasNull(), is(false)); + } } catch (SQLException e) { throw TestUtil.rethrow(e); } @@ -242,17 +249,17 @@ private static boolean checkProcessExists(String command) { @Test void testStdin() throws SQLException { try (Hook.Closeable ignore = - Hook.STANDARD_STREAMS.addThread((Consumer>) o -> { - final Object[] values = o.get(); - final InputStream in = (InputStream) values[0]; - final String s = "First line\n" - + "Second line"; - final ByteArrayInputStream in2 = - new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)); - final OutputStream out = (OutputStream) values[1]; - final OutputStream err = (OutputStream) values[2]; - o.set(new Object[] {in2, out, err}); - })) { + Hook.STANDARD_STREAMS.addThread((Consumer>) o -> { + final Object[] values = o.get(); + final InputStream in = (InputStream) values[0]; + final String s = "First line\n" + + "Second line"; + final ByteArrayInputStream in2 = + new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)); + final OutputStream out = (OutputStream) values[1]; + final OutputStream err = (OutputStream) values[2]; + o.set(new Object[] {in2, out, err}); + })) { assertThat(foo("select count(*) as c from stdin"), is("2\n")); } } @@ -388,4 +395,58 @@ static CalciteAssert.AssertQuery sql(String sql) { .with(CalciteConnectionProperty.CONFORMANCE, SqlConformanceEnum.LENIENT) .query(sql); } + + private void checkOsQuery(String tableName, int colSize) { + final String q = "select * from " + tableName; + sql(q).returns(r -> { + try { + if (r.next()) { + for (int i = 1; i <= colSize; i++) { + if (r.getString(i) != null) { + assertThat(r.getString(i), any(String.class)); + } + } + assertThat(r.wasNull(), is(false)); + } + } catch (SQLException e) { + throw TestUtil.rethrow(e); + } + }); + } + + @Test void testSystemInfo() { + checkOsQuery("system_info", 18); + } + + @Test void testJavaInfo() { + checkOsQuery("java_info", 18); + } + + @Test void testCpuInfo() { + checkOsQuery("cpu_info", 9); + } + + @Test void testCpuTime() { + checkOsQuery("cpu_time", 8); + } + + @Test void testOsVersion() { + checkOsQuery("os_version", 5); + } + + @Test void testMemoryInfo() { + checkOsQuery("memory_info", 8); + } + + @Test void testInterfaceAddresses() { + checkOsQuery("interface_addresses", 5); + } + + @Test void testInterfaceDetails() { + checkOsQuery("interface_details", 13); + } + + @Test void testMounts() { + checkOsQuery("mounts", 8); + } } diff --git a/site/_docs/os_adapter.md b/site/_docs/os_adapter.md index 4575a6a75e4..3f543b3d584 100644 --- a/site/_docs/os_adapter.md +++ b/site/_docs/os_adapter.md @@ -88,11 +88,20 @@ care. Often adding a back-slash will suffice. The OS adapter contains the following tables: +* `cpu_info` - CPU information (from [oshi](https://github.com/oshi/oshi)) +* `cpu_time` - CPU time (from oshi) * `du` - Disk usage (based on `du` command) -* `ps` - Processes (based on `ps` command) -* `stdin` - Standard input * `files` - Files (based on the `find` command) * `git_commits` - Git commits (based on `git log`) +* `interface_addresses` - Network addresses (from oshi) +* `interface_details` - Network interface (from oshi) +* `java_info` - Java information (from oshi) +* `memory_info` - Memory (from oshi) +* `mounts` - File system mounts (from oshi) +* `os_version` - Operating System version (from oshi) +* `ps` - Processes (based on `ps` command) +* `stdin` - Standard input +* `system_info` - System information (from oshi) * `vmstat` - Virtual memory (based on `vmstat` command) Most tables are implemented as views on top of table functions.