Skip to content
Snippets Groups Projects
Commit d6d41824 authored by Julien Lopez's avatar Julien Lopez
Browse files

Add proper handling of Truffle nodes.

parent 998cad9b
No related branches found
No related tags found
No related merge requests found
package qir.ast;
import java.util.function.Function;
import com.oracle.truffle.api.source.SourceSection;
import qir.util.IQIRVisitor;
......@@ -11,11 +13,13 @@ import qir.util.IQIRVisitor;
public final class QIRTruffleNode extends QIRNode {
private final String name;
private final String code;
private final Function<QIRTruffleNode, String> translation;
public QIRTruffleNode(final SourceSection source, final String name, final String code) {
public QIRTruffleNode(final SourceSection source, final String name, final String code, final Function<QIRTruffleNode, String> translation) {
super(source);
this.name = name;
this.code = code;
this.translation = translation;
}
public final String getName() {
......@@ -26,6 +30,10 @@ public final class QIRTruffleNode extends QIRNode {
return code;
}
public final Function<QIRTruffleNode, String> getTranslation() {
return translation;
}
@Override
public final <T> T accept(final IQIRVisitor<T> visitor) {
return visitor.visit(this);
......
......@@ -66,10 +66,9 @@ public final class OracleDriver extends SQLDriver {
// extract function name and number of arguments
final String functionHeader = function.split("\\)")[0].trim();
if (!functionHeader.startsWith("function")) {
throw new RuntimeException("SL function has to start with the keyword 'function'");
throw new RuntimeException("Not an SL function");
}
final String reducedFuncHeader = functionHeader.substring("function".length()).trim();
final String[] nameArguments = reducedFuncHeader.split("\\(");
final String[] nameArguments = functionHeader.substring("function".length()).trim().split("\\(");
final String name = nameArguments[0];
// check if name is upper case
if (!name.toUpperCase().equals(name)) {
......@@ -81,32 +80,28 @@ public final class OracleDriver extends SQLDriver {
String oraArguments = "(";
char oraArgName = 'a';
for (int i = 0; i < arguments.length; i++) {
oraArguments += oraArgName + " NUMBER";
oraArgName++;
oraArguments += oraArgName++ + " NUMBER";
if (i + 1 != arguments.length) {
oraArguments += ", ";
}
}
oraArguments += ") RETURN NUMBER";
final String addOrUpdate = update ? "update" : "add";
final String query = "begin sys." + addOrUpdate + "_UDF_Function ('scott', '" + name + "', ' " + oraArguments + " ', '" + function + "', 'SLSQL'); end;";
try (Statement stmt = conn.createStatement()) {
final String query = "begin sys." + (update ? "update" : "add") + "_UDF_Function ('scott', '" + name + "', ' " + oraArguments + " ', '" + function + "', 'SLSQL'); end;";
try (final Statement stmt = conn.createStatement()) {
stmt.executeUpdate(query);
}
}
private void executeUpdate(String query) throws SQLException {
try (Statement stmt = conn.createStatement()) {
private final void executeUpdate(final String query) throws SQLException {
try (final Statement stmt = conn.createStatement()) {
stmt.executeUpdate(query);
}
}
private boolean functionExists(String name) throws SQLException {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from all_objects " + "where object_type = 'FUNCTION' " + "and object_name = '" + name + "' ");
// check if the function was found
return rs.next();
private final boolean functionExists(final String name) throws SQLException {
try (final Statement stmt = conn.createStatement()) {
return stmt.executeQuery("select * from all_objects where object_type = 'FUNCTION' and object_name = '" + name + "' ").next();
}
}
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ public final class PostgreSQLDriver extends SQLDriver {
public final QIRList run(final QIRNode root) throws QIRException {
final QIRSQLVisitor visitor = new QIRSQLVisitor();
String query = root.accept(visitor);
// TODO: Fix this.
query = query.startsWith("from ") ? "select * " + query : query;
try {
return executeQuery(query);
......
package qir.driver;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import qir.ast.*;
import qir.ast.data.*;
......@@ -14,7 +15,7 @@ import qir.util.*;
/**
* Translation from QIR to SQL.
*/
public class QIRSQLVisitor implements IQIRVisitor<String> {
public final class QIRSQLVisitor implements IQIRVisitor<String> {
/**
* The functions to send to the database before the query can be executed.
*/
......@@ -72,7 +73,13 @@ public class QIRSQLVisitor implements IQIRVisitor<String> {
@Override
public final String visit(final QIRApply qirApply) {
return qirApply.getLeft().accept(this) + "(" + qirApply.getRight().accept(this) + ")";
final QIRNode left = qirApply.getLeft();
final String fun = left.accept(this);
final String args = qirApply.getRight().accept(this);
if (left instanceof QIRTruffleNode)
return "truffle.executeapply(" + fun + ", " + args + ")";
return fun + "(" + args + ")";
}
@Override
......@@ -223,8 +230,6 @@ public class QIRSQLVisitor implements IQIRVisitor<String> {
@Override
public final String visit(final QIRTruffleNode qirTruffleNode) {
final String funName = qirTruffleNode.getName();
prolog.put(funName, qirTruffleNode.getCode());
return funName;
return "truffle.executetruffle('" + qirTruffleNode.getTranslation().apply(qirTruffleNode) + "')";
}
}
\ No newline at end of file
......@@ -64,6 +64,21 @@ public abstract class SQLDriver extends DBDriver {
// TODO: Handle overflow
data = new QIRNumber(SourceSection.createUnavailable("QIRNode", "QIRNumber"), rs.getLong(i));
break;
case Types.OTHER:
String v = rs.getObject(i).toString();
v = v.substring(1, v.length() - 1);
try {
Long l = Long.parseLong(v);
data = new QIRNumber(SourceSection.createUnavailable("QIRNode", "QIRNumber"), l);
} catch (NumberFormatException e) {
if (v.equals("true"))
data = new QIRBoolean(SourceSection.createUnavailable("QIRNode", "QIRNumber"), true);
else if (v.equals("false"))
data = new QIRBoolean(SourceSection.createUnavailable("QIRNode", "QIRNumber"), false);
else
data = new QIRBoolean(SourceSection.createUnavailable("QIRNode", "QIRNumber"), false);
}
break;
default:
data = new QIRString(SourceSection.createUnavailable("QIRNode", "QIRString"), rs.getString(i));
break;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment