diff --git a/prql-java/DEVELOPMENT.md b/prql-java/DEVELOPMENT.md
index a8dc766aa1eb..5d2933a86a32 100644
--- a/prql-java/DEVELOPMENT.md
+++ b/prql-java/DEVELOPMENT.md
@@ -8,8 +8,8 @@ We implement Rust bindings to Java with
[JNI](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/).
First, define a native method --
-`public static native String toSql(String query)` for PrqlCompiler, `toJson` is
-same.
+`public static native String toSql(String query, String target, boolean format, boolean signature)`
+for PrqlCompiler, `toJson` is same.
And then implement it in Rust with this
[crate](https://docs.rs/jni/latest/jni/).
diff --git a/prql-java/java/pom.xml b/prql-java/java/pom.xml
index 84d8bddd2339..d7276e6edff1 100644
--- a/prql-java/java/pom.xml
+++ b/prql-java/java/pom.xml
@@ -6,7 +6,7 @@
org.prqllang
prql-java
- 0.2.1
+ 0.5.2
${project.groupId}:${project.artifactId}
prql-compiler api for java
diff --git a/prql-java/java/src/main/java/org/prql/prql4j/PrqlCompiler.java b/prql-java/java/src/main/java/org/prql/prql4j/PrqlCompiler.java
index 49f47d19728d..bf0efbf46f23 100644
--- a/prql-java/java/src/main/java/org/prql/prql4j/PrqlCompiler.java
+++ b/prql-java/java/src/main/java/org/prql/prql4j/PrqlCompiler.java
@@ -3,8 +3,19 @@
import java.io.IOException;
public class PrqlCompiler {
- public static native String toSql(String query);
- public static native String toJson(String query);
+
+ /**
+ * compile PRQL to SQL
+ * @param query PRQL query
+ * @param target target dialect, such as sql.mysql etc. Please refer PRQL Target and Version
+ * @param format format SQL or not
+ * @param signature comment signature or not
+ * @return SQL
+ * @throws Exception PRQL compile exception
+ */
+ public static native String toSql(String query, String target, boolean format, boolean signature) throws Exception;
+ public static native String toJson(String query) throws Exception;
+ public static native String format(String query) throws Exception;
static {
try {
diff --git a/prql-java/java/src/test/java/org/prql/prql4j/PrqlCompilerTest.java b/prql-java/java/src/test/java/org/prql/prql4j/PrqlCompilerTest.java
index 4ca948b87959..5a8627d62c57 100644
--- a/prql-java/java/src/test/java/org/prql/prql4j/PrqlCompilerTest.java
+++ b/prql-java/java/src/test/java/org/prql/prql4j/PrqlCompilerTest.java
@@ -4,8 +4,8 @@
public class PrqlCompilerTest {
@Test
- public void compile() {
- String found = PrqlCompiler.toSql("from table");
+ public void compile() throws Exception {
+ String found = PrqlCompiler.toSql("from table", "sql.mysql", true, true);
// remove signature
found = found.substring(0, found.indexOf("\n\n--"));
@@ -16,4 +16,9 @@ public void compile() {
" table";
assert expected.equalsIgnoreCase(found);
}
+
+ @Test(expected = Exception.class)
+ public void compileWithError() throws Exception {
+ PrqlCompiler.toSql("from table | filter id >> 1", "sql.mysql", true, true);
+ }
}
diff --git a/prql-java/src/lib.rs b/prql-java/src/lib.rs
index 6c59dfa9fb24..93e7052dc160 100644
--- a/prql-java/src/lib.rs
+++ b/prql-java/src/lib.rs
@@ -1,7 +1,8 @@
use jni::objects::{JClass, JString};
-use jni::sys::jstring;
+use jni::sys::{jboolean, jstring};
use jni::JNIEnv;
-use prql_compiler::{json, prql_to_pl, Options};
+use prql_compiler::{json, pl_to_prql, prql_to_pl, ErrorMessages, Options, Target};
+use std::str::FromStr;
#[no_mangle]
#[allow(non_snake_case)]
@@ -9,16 +10,41 @@ pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_toSql(
env: JNIEnv,
_class: JClass,
query: JString,
+ target: JString,
+ format: jboolean,
+ signature: jboolean,
) -> jstring {
let prql_query: String = env
.get_string(query)
.expect("Couldn't get java string!")
.into();
- let rs_sql_str: String = prql_compiler::compile(&prql_query, &Options::default())
- .expect("Couldn't compile query to prql!");
- env.new_string(rs_sql_str)
- .expect("Couldn't create java string!")
- .into_raw()
+ let target_str: String = env
+ .get_string(target)
+ .expect("Couldn't get java string")
+ .into();
+ let prql_dialect: Target = Target::from_str(&target_str).unwrap_or(Target::Sql(None));
+ let opt = Options {
+ format: format != 0,
+ target: prql_dialect,
+ signature_comment: signature != 0,
+ };
+ let result = prql_compiler::compile(&prql_query, &opt);
+ java_string_with_exception(result, &env)
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_format(
+ env: JNIEnv,
+ _class: JClass,
+ query: JString,
+) -> jstring {
+ let prql_query: String = env
+ .get_string(query)
+ .expect("Couldn't get java string!")
+ .into();
+ let result = prql_to_pl(&prql_query).and_then(pl_to_prql);
+ java_string_with_exception(result, &env)
}
#[no_mangle]
@@ -32,9 +58,20 @@ pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_toJson(
.get_string(query)
.expect("Couldn't get java string!")
.into();
- let rs_json_str: String = { prql_to_pl(&prql_query).and_then(json::from_pl) }
- .expect("Couldn't get json from prql query!");
- env.new_string(rs_json_str)
- .expect("Couldn't create java string!")
- .into_raw()
+ let result = prql_to_pl(&prql_query).and_then(json::from_pl);
+ java_string_with_exception(result, &env)
+}
+
+fn java_string_with_exception(result: Result, env: &JNIEnv) -> jstring {
+ if let Ok(text) = result {
+ env.new_string(text)
+ .expect("Couldn't create java string!")
+ .into_raw()
+ } else {
+ let exception = env.find_class("java/lang/Exception").unwrap();
+ if let Err(e) = env.throw_new(exception, result.err().unwrap().to_string()) {
+ println!("Error throwing exception: {:?}", e);
+ }
+ std::ptr::null_mut() as jstring
+ }
}