This is an automated email from the ASF dual-hosted git repository.

andygrove pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-java.git


The following commit(s) were added to refs/heads/main by this push:
     new 3698b9a  feat: configure SessionContext and RuntimeEnv via builder 
(#28)
3698b9a is described below

commit 3698b9a1af9a741c5935a32de6aaa8e4a2947b69
Author: Andy Grove <[email protected]>
AuthorDate: Wed May 13 10:44:15 2026 -0600

    feat: configure SessionContext and RuntimeEnv via builder (#28)
---
 native/Cargo.lock                                  | 100 +++++++++++++++++
 native/Cargo.toml                                  |   4 +
 native/build.rs                                    |  24 ++++
 native/src/lib.rs                                  |  50 ++++++++-
 native/src/proto.rs                                |  40 ++++---
 pom.xml                                            |   9 ++
 proto/session_options.proto                        |  39 +++++++
 .../java/org/apache/datafusion/SessionContext.java |  14 +++
 .../apache/datafusion/SessionContextBuilder.java   | 124 +++++++++++++++++++++
 .../datafusion/SessionContextBuilderTest.java      | 116 +++++++++++++++++++
 10 files changed, 502 insertions(+), 18 deletions(-)

diff --git a/native/Cargo.lock b/native/Cargo.lock
index 004fa98..495cc60 100644
--- a/native/Cargo.lock
+++ b/native/Cargo.lock
@@ -1143,6 +1143,8 @@ dependencies = [
  "datafusion-proto",
  "jni",
  "prost",
+ "prost-build",
+ "protoc-bin-vendored",
  "tokio",
 ]
 
@@ -2084,6 +2086,12 @@ dependencies = [
  "simd-adler32",
 ]
 
+[[package]]
+name = "multimap"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
+
 [[package]]
 name = "num-bigint"
 version = "0.4.6"
@@ -2332,6 +2340,25 @@ dependencies = [
  "prost-derive",
 ]
 
+[[package]]
+name = "prost-build"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
+dependencies = [
+ "heck",
+ "itertools",
+ "log",
+ "multimap",
+ "petgraph",
+ "prettyplease",
+ "prost",
+ "prost-types",
+ "regex",
+ "syn",
+ "tempfile",
+]
+
 [[package]]
 name = "prost-derive"
 version = "0.14.3"
@@ -2345,6 +2372,79 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "prost-types"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
+dependencies = [
+ "prost",
+]
+
+[[package]]
+name = "protoc-bin-vendored"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa"
+dependencies = [
+ "protoc-bin-vendored-linux-aarch_64",
+ "protoc-bin-vendored-linux-ppcle_64",
+ "protoc-bin-vendored-linux-s390_64",
+ "protoc-bin-vendored-linux-x86_32",
+ "protoc-bin-vendored-linux-x86_64",
+ "protoc-bin-vendored-macos-aarch_64",
+ "protoc-bin-vendored-macos-x86_64",
+ "protoc-bin-vendored-win32",
+]
+
+[[package]]
+name = "protoc-bin-vendored-linux-aarch_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c"
+
+[[package]]
+name = "protoc-bin-vendored-linux-ppcle_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c"
+
+[[package]]
+name = "protoc-bin-vendored-linux-s390_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0"
+
+[[package]]
+name = "protoc-bin-vendored-linux-x86_32"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5"
+
+[[package]]
+name = "protoc-bin-vendored-linux-x86_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78"
+
+[[package]]
+name = "protoc-bin-vendored-macos-aarch_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092"
+
+[[package]]
+name = "protoc-bin-vendored-macos-x86_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756"
+
+[[package]]
+name = "protoc-bin-vendored-win32"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3"
+
 [[package]]
 name = "psm"
 version = "0.1.31"
diff --git a/native/Cargo.toml b/native/Cargo.toml
index f2a6818..01dd002 100644
--- a/native/Cargo.toml
+++ b/native/Cargo.toml
@@ -31,3 +31,7 @@ datafusion-proto = "53.1.0"
 jni = "0.21"
 prost = "0.14"
 tokio = { version = "1", features = ["rt-multi-thread"] }
+
+[build-dependencies]
+prost-build = "0.14"
+protoc-bin-vendored = "3"
diff --git a/native/build.rs b/native/build.rs
new file mode 100644
index 0000000..495e147
--- /dev/null
+++ b/native/build.rs
@@ -0,0 +1,24 @@
+// 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.
+
+fn main() {
+    println!("cargo:rerun-if-changed=../proto/session_options.proto");
+    let protoc = protoc_bin_vendored::protoc_bin_path().expect("vendored 
protoc not available");
+    std::env::set_var("PROTOC", protoc);
+    prost_build::compile_protos(&["../proto/session_options.proto"], 
&["../proto"])
+        .expect("failed to compile session_options.proto");
+}
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 4ea1a61..677aaf9 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -19,6 +19,11 @@ mod csv;
 mod errors;
 mod proto;
 
+pub(crate) mod session_options {
+    include!(concat!(env!("OUT_DIR"), "/datafusion_java.rs"));
+}
+
+use std::path::PathBuf;
 use std::sync::{Arc, OnceLock};
 
 use datafusion::arrow::datatypes::{Schema, SchemaRef};
@@ -29,13 +34,16 @@ use datafusion::config::TableParquetOptions;
 use datafusion::dataframe::DataFrame;
 use datafusion::dataframe::DataFrameWriteOptions;
 use datafusion::error::DataFusionError;
-use datafusion::prelude::{ParquetReadOptions, SessionContext};
+use datafusion::execution::runtime_env::RuntimeEnvBuilder;
+use datafusion::prelude::{ParquetReadOptions, SessionConfig, SessionContext};
 use jni::objects::{JByteArray, JClass, JObjectArray, JString};
 use jni::sys::{jboolean, jint, jlong};
 use jni::JNIEnv;
+use prost::Message;
 use tokio::runtime::Runtime;
 
 use crate::errors::{try_unwrap_or_throw, JniResult};
+use crate::session_options::SessionOptions;
 
 pub(crate) fn runtime() -> &'static Runtime {
     static RT: OnceLock<Runtime> = OnceLock::new();
@@ -53,6 +61,46 @@ pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_createSessionCo
     })
 }
 
+#[no_mangle]
+pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_createSessionContextWithOptions<
+    'local,
+>(
+    mut env: JNIEnv<'local>,
+    _class: JClass<'local>,
+    options_bytes: JByteArray<'local>,
+) -> jlong {
+    try_unwrap_or_throw(&mut env, 0, |env| -> JniResult<jlong> {
+        let bytes: Vec<u8> = env.convert_byte_array(&options_bytes)?;
+        let opts = SessionOptions::decode(bytes.as_slice())?;
+
+        let mut config = SessionConfig::new();
+        if let Some(v) = opts.batch_size {
+            config = config.with_batch_size(v as usize);
+        }
+        if let Some(v) = opts.target_partitions {
+            config = config.with_target_partitions(v as usize);
+        }
+        if let Some(v) = opts.collect_statistics {
+            config = config.with_collect_statistics(v);
+        }
+        if let Some(v) = opts.information_schema {
+            config = config.with_information_schema(v);
+        }
+
+        let mut runtime = RuntimeEnvBuilder::new();
+        if let Some(mem) = opts.memory_limit {
+            runtime = runtime.with_memory_limit(mem.max_memory_bytes as usize, 
mem.memory_fraction);
+        }
+        if let Some(dir) = opts.temp_directory {
+            runtime = runtime.with_temp_file_path(PathBuf::from(dir));
+        }
+
+        let runtime_env = runtime.build()?;
+        let ctx = SessionContext::new_with_config_rt(config, 
Arc::new(runtime_env));
+        Ok(Box::into_raw(Box::new(ctx)) as jlong)
+    })
+}
+
 #[no_mangle]
 pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_createDataFrame<'local>(
     mut env: JNIEnv<'local>,
diff --git a/native/src/proto.rs b/native/src/proto.rs
index 429a91e..d90ed2c 100644
--- a/native/src/proto.rs
+++ b/native/src/proto.rs
@@ -32,7 +32,9 @@ use crate::errors::{try_unwrap_or_throw, JniResult};
 use crate::runtime;
 
 #[no_mangle]
-pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_createDataFrameFromProto<'local>(
+pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_createDataFrameFromProto<
+    'local,
+>(
     mut env: JNIEnv<'local>,
     _class: JClass<'local>,
     handle: jlong,
@@ -60,22 +62,26 @@ pub extern "system" fn 
Java_org_apache_datafusion_SessionContext_tableSchemaIpc<
     handle: jlong,
     name: JString<'local>,
 ) -> jbyteArray {
-    try_unwrap_or_throw(&mut env, std::ptr::null_mut(), |env| -> 
JniResult<jbyteArray> {
-        if handle == 0 {
-            return Err("SessionContext handle is null".into());
-        }
-        let ctx = unsafe { &*(handle as *const SessionContext) };
-        let name: String = env.get_string(&name)?.into();
+    try_unwrap_or_throw(
+        &mut env,
+        std::ptr::null_mut(),
+        |env| -> JniResult<jbyteArray> {
+            if handle == 0 {
+                return Err("SessionContext handle is null".into());
+            }
+            let ctx = unsafe { &*(handle as *const SessionContext) };
+            let name: String = env.get_string(&name)?.into();
 
-        let df = runtime().block_on(ctx.table(name.as_str()))?;
-        let schema: SchemaRef = Arc::new(df.schema().as_arrow().clone());
+            let df = runtime().block_on(ctx.table(name.as_str()))?;
+            let schema: SchemaRef = Arc::new(df.schema().as_arrow().clone());
 
-        let mut buf: Vec<u8> = Vec::new();
-        {
-            let mut writer = StreamWriter::try_new(&mut buf, schema.as_ref())?;
-            writer.finish()?;
-        }
-        let arr = env.byte_array_from_slice(&buf)?;
-        Ok(arr.into_raw())
-    })
+            let mut buf: Vec<u8> = Vec::new();
+            {
+                let mut writer = StreamWriter::try_new(&mut buf, 
schema.as_ref())?;
+                writer.finish()?;
+            }
+            let arr = env.byte_array_from_slice(&buf)?;
+            Ok(arr.into_raw())
+        },
+    )
 }
diff --git a/pom.xml b/pom.xml
index 9039d8b..47d5b4e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -192,8 +192,17 @@ under the License.
                 </configuration>
                 <executions>
                     <execution>
+                        <id>compile-upstream</id>
                         <goals><goal>compile</goal></goals>
                     </execution>
+                    <execution>
+                        <id>compile-local</id>
+                        <goals><goal>compile</goal></goals>
+                        <configuration>
+                            
<protoSourceRoot>${project.basedir}/proto</protoSourceRoot>
+                            <clearOutputDirectory>false</clearOutputDirectory>
+                        </configuration>
+                    </execution>
                 </executions>
             </plugin>
         </plugins>
diff --git a/proto/session_options.proto b/proto/session_options.proto
new file mode 100644
index 0000000..96342a6
--- /dev/null
+++ b/proto/session_options.proto
@@ -0,0 +1,39 @@
+// 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.
+
+syntax = "proto3";
+
+package datafusion_java;
+
+option java_package = "org.apache.datafusion.protobuf";
+option java_multiple_files = true;
+
+// Options used to construct a SessionContext. All fields are optional —
+// unset fields leave DataFusion's default behavior in place.
+message SessionOptions {
+  optional uint64 batch_size = 1;
+  optional uint64 target_partitions = 2;
+  optional bool collect_statistics = 3;
+  optional bool information_schema = 4;
+  optional MemoryLimit memory_limit = 5;
+  optional string temp_directory = 6;
+}
+
+message MemoryLimit {
+  uint64 max_memory_bytes = 1;
+  double memory_fraction = 2;
+}
diff --git a/src/main/java/org/apache/datafusion/SessionContext.java 
b/src/main/java/org/apache/datafusion/SessionContext.java
index 1aec343..a496883 100644
--- a/src/main/java/org/apache/datafusion/SessionContext.java
+++ b/src/main/java/org/apache/datafusion/SessionContext.java
@@ -54,6 +54,18 @@ public final class SessionContext implements AutoCloseable {
     }
   }
 
+  SessionContext(byte[] optionsBytes) {
+    this.nativeHandle = createSessionContextWithOptions(optionsBytes);
+    if (this.nativeHandle == 0) {
+      throw new RuntimeException("Failed to create native SessionContext");
+    }
+  }
+
+  /** Start configuring a {@link SessionContext}. */
+  public static SessionContextBuilder builder() {
+    return new SessionContextBuilder();
+  }
+
   /**
    * Parse and plan {@code query}, returning a lazy {@link DataFrame}. The 
query is not executed
    * until {@link DataFrame#collect} is called.
@@ -251,6 +263,8 @@ public final class SessionContext implements AutoCloseable {
 
   private static native long createSessionContext();
 
+  private static native long createSessionContextWithOptions(byte[] 
optionsBytes);
+
   private static native long createDataFrame(long handle, String sql);
 
   private static native long createDataFrameFromProto(long handle, byte[] 
planBytes);
diff --git a/src/main/java/org/apache/datafusion/SessionContextBuilder.java 
b/src/main/java/org/apache/datafusion/SessionContextBuilder.java
new file mode 100644
index 0000000..bb0cac9
--- /dev/null
+++ b/src/main/java/org/apache/datafusion/SessionContextBuilder.java
@@ -0,0 +1,124 @@
+/*
+ * 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.datafusion;
+
+import org.apache.datafusion.protobuf.MemoryLimit;
+import org.apache.datafusion.protobuf.SessionOptions;
+
+/**
+ * Builder for a configured {@link SessionContext}. Each setter is optional; 
unset fields leave the
+ * DataFusion default in place.
+ */
+public final class SessionContextBuilder {
+  private Integer batchSize;
+  private Integer targetPartitions;
+  private Boolean collectStatistics;
+  private Boolean informationSchema;
+  private Long memoryLimitBytes;
+  private Double memoryLimitFraction;
+  private String tempDirectory;
+
+  SessionContextBuilder() {}
+
+  public SessionContextBuilder batchSize(int batchSize) {
+    if (batchSize <= 0) {
+      throw new IllegalArgumentException("batchSize must be positive, got " + 
batchSize);
+    }
+    this.batchSize = batchSize;
+    return this;
+  }
+
+  public SessionContextBuilder targetPartitions(int targetPartitions) {
+    if (targetPartitions <= 0) {
+      throw new IllegalArgumentException(
+          "targetPartitions must be positive, got " + targetPartitions);
+    }
+    this.targetPartitions = targetPartitions;
+    return this;
+  }
+
+  public SessionContextBuilder collectStatistics(boolean collectStatistics) {
+    this.collectStatistics = collectStatistics;
+    return this;
+  }
+
+  public SessionContextBuilder informationSchema(boolean informationSchema) {
+    this.informationSchema = informationSchema;
+    return this;
+  }
+
+  /**
+   * Cap the memory pool at {@code maxMemoryBytes}, reserving {@code fraction} 
of it for queries.
+   */
+  public SessionContextBuilder memoryLimit(long maxMemoryBytes, double 
fraction) {
+    if (maxMemoryBytes <= 0) {
+      throw new IllegalArgumentException(
+          "maxMemoryBytes must be positive, got " + maxMemoryBytes);
+    }
+    if (fraction <= 0.0 || fraction > 1.0) {
+      throw new IllegalArgumentException("fraction must be in (0, 1], got " + 
fraction);
+    }
+    this.memoryLimitBytes = maxMemoryBytes;
+    this.memoryLimitFraction = fraction;
+    return this;
+  }
+
+  /** Directory the DiskManager uses for spill files. */
+  public SessionContextBuilder tempDirectory(String path) {
+    this.tempDirectory = path;
+    return this;
+  }
+
+  /**
+   * Construct a {@link SessionContext} with the configured options.
+   *
+   * @throws RuntimeException if the native side fails to construct the 
context.
+   */
+  public SessionContext build() {
+    return new SessionContext(toBytes());
+  }
+
+  byte[] toBytes() {
+    SessionOptions.Builder b = SessionOptions.newBuilder();
+    if (batchSize != null) {
+      b.setBatchSize(batchSize);
+    }
+    if (targetPartitions != null) {
+      b.setTargetPartitions(targetPartitions);
+    }
+    if (collectStatistics != null) {
+      b.setCollectStatistics(collectStatistics);
+    }
+    if (informationSchema != null) {
+      b.setInformationSchema(informationSchema);
+    }
+    if (memoryLimitBytes != null && memoryLimitFraction != null) {
+      b.setMemoryLimit(
+          MemoryLimit.newBuilder()
+              .setMaxMemoryBytes(memoryLimitBytes)
+              .setMemoryFraction(memoryLimitFraction)
+              .build());
+    }
+    if (tempDirectory != null) {
+      b.setTempDirectory(tempDirectory);
+    }
+    return b.build().toByteArray();
+  }
+}
diff --git a/src/test/java/org/apache/datafusion/SessionContextBuilderTest.java 
b/src/test/java/org/apache/datafusion/SessionContextBuilderTest.java
new file mode 100644
index 0000000..ed6cff2
--- /dev/null
+++ b/src/test/java/org/apache/datafusion/SessionContextBuilderTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.datafusion;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.nio.file.Path;
+
+import org.apache.arrow.memory.BufferAllocator;
+import org.apache.arrow.memory.RootAllocator;
+import org.apache.arrow.vector.ipc.ArrowReader;
+import org.apache.datafusion.protobuf.SessionOptions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+class SessionContextBuilderTest {
+
+  @Test
+  void protoRoundTripPreservesAllFields() throws Exception {
+    byte[] bytes =
+        SessionContext.builder()
+            .batchSize(8192)
+            .targetPartitions(4)
+            .collectStatistics(true)
+            .informationSchema(true)
+            .memoryLimit(1L << 30, 0.8)
+            .tempDirectory("/tmp/df")
+            .toBytes();
+
+    SessionOptions parsed = SessionOptions.parseFrom(bytes);
+    assertTrue(parsed.hasBatchSize());
+    assertEquals(8192L, parsed.getBatchSize());
+    assertTrue(parsed.hasTargetPartitions());
+    assertEquals(4L, parsed.getTargetPartitions());
+    assertTrue(parsed.hasCollectStatistics());
+    assertTrue(parsed.getCollectStatistics());
+    assertTrue(parsed.hasInformationSchema());
+    assertTrue(parsed.getInformationSchema());
+    assertTrue(parsed.hasMemoryLimit());
+    assertEquals(1L << 30, parsed.getMemoryLimit().getMaxMemoryBytes());
+    assertEquals(0.8, parsed.getMemoryLimit().getMemoryFraction(), 1e-9);
+    assertTrue(parsed.hasTempDirectory());
+    assertEquals("/tmp/df", parsed.getTempDirectory());
+  }
+
+  @Test
+  void unsetFieldsAreAbsentInProto() throws Exception {
+    byte[] bytes = SessionContext.builder().batchSize(8192).toBytes();
+    SessionOptions parsed = SessionOptions.parseFrom(bytes);
+    assertTrue(parsed.hasBatchSize());
+    assertFalse(parsed.hasTargetPartitions());
+    assertFalse(parsed.hasCollectStatistics());
+    assertFalse(parsed.hasInformationSchema());
+    assertFalse(parsed.hasMemoryLimit());
+    assertFalse(parsed.hasTempDirectory());
+  }
+
+  @Test
+  void informationSchemaEnabledMakesMetaQueryRun() throws Exception {
+    try (BufferAllocator allocator = new RootAllocator();
+        SessionContext ctx = 
SessionContext.builder().informationSchema(true).build();
+        DataFrame df = ctx.sql("SELECT table_name FROM 
information_schema.tables");
+        ArrowReader reader = df.collect(allocator)) {
+      // information_schema.tables always has at least one row.
+      assertTrue(reader.loadNextBatch());
+    }
+  }
+
+  @Test
+  void informationSchemaDisabledByDefaultThrows() {
+    try (SessionContext ctx = SessionContext.builder().build()) {
+      assertThrows(
+          RuntimeException.class,
+          () -> ctx.sql("SELECT table_name FROM information_schema.tables"));
+    }
+  }
+
+  @Test
+  void buildWithEveryKnobSetCanExecuteSelectOne(@TempDir Path tempDir) throws 
Exception {
+    try (BufferAllocator allocator = new RootAllocator();
+        SessionContext ctx =
+            SessionContext.builder()
+                .batchSize(8192)
+                .targetPartitions(4)
+                .collectStatistics(true)
+                .informationSchema(true)
+                .memoryLimit(1L << 30, 0.8)
+                .tempDirectory(tempDir.toAbsolutePath().toString())
+                .build();
+        DataFrame df = ctx.sql("SELECT 1");
+        ArrowReader reader = df.collect(allocator)) {
+      assertTrue(reader.loadNextBatch());
+      assertEquals(1, reader.getVectorSchemaRoot().getRowCount());
+    }
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to