history-early-demo/src/main/java/org/vizierdb/sql/MimirAdaptor.java

163 lines
6.5 KiB
Java

/*
* Licensed 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.vizierdb.sql;
import java.util.*;
import scala.Enumeration;
import org.vizierdb.database.*;
import org.vizierdb.database.script.*;
import org.vizierdb.database.script.op.*;
import mimir.algebra.Table;
import mimir.algebra.Project;
import mimir.algebra.ProjectArg;
import mimir.algebra.Select;
import mimir.algebra.Union;
/**
* A script in VizUAL is a sequence of operations. Each operation generates a
* new snapshot. Operations and generated snapshot identifiers are recorded as
* part of the script.
*
* @author Oliver Kennedy
*/
public class MimirAdaptor {
public static <A, B> scala.collection.immutable.Map<A, B> toScalaMap(Map<A, B> m) {
return scala.collection.JavaConverters.mapAsScalaMapConverter(m).asScala().toMap(
scala.Predef.<scala.Tuple2<A, B>>conforms()
);
}
public static scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> makeMimirSchema(Collection<String> cols)
{
return makeMimirSchema(cols, mimir.algebra.Type.withName("TString"));
}
public static scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> makeMimirSchema(Collection<String> cols, scala.Enumeration.Value t)
{
scala.collection.immutable.List<scala.Tuple2<String,scala.Enumeration.Value>> ret =
scala.collection.immutable.List$.MODULE$.empty();
for(String col : cols){
ret = new scala.collection.immutable.$colon$colon<scala.Tuple2<String,scala.Enumeration.Value>>(
new scala.Tuple2<String,scala.Enumeration.Value>(col, t), ret
);
}
return ret;
}
public static mimir.algebra.Operator compileToRA(VizUALScript script, Map<String, List<String>> schemas)
{
mimir.algebra.Operator raTree = null;
ColumnList cols = new ColumnList();
int colIdx = 0;
BitSet deleted = new BitSet();
for(int x = 0; x < script.size(); x++){
Operation step = script.getOperation(x);
// System.out.println("CONVERT: "+step);
if(step instanceof CellUpdate){
CellUpdate update = (CellUpdate)step;
String targetCol = cols.get(update.getColumnId()).getName();
raTree = mimir.algebra.OperatorUtils$.MODULE$.replaceColumn(
targetCol,
(mimir.algebra.Expression)(new mimir.algebra.Conditional(
new mimir.algebra.Comparison(
mimir.algebra.Cmp.withName("Eq"),
new mimir.algebra.Var("ROWID_MIMIR"),
new mimir.algebra.RowIdPrimitive(""+update.getRowId())
),
new mimir.algebra.StringPrimitive(update.getValue()),
new mimir.algebra.Var(targetCol)
)),
raTree
);
} else if(step instanceof ColumnDelete){
ColumnDelete delete = (ColumnDelete)step;
String targetCol = cols.get(delete.getColumnId()).getName();
// System.out.println("Deleting "+ targetCol);
raTree = mimir.algebra.OperatorUtils$.MODULE$.projectAwayColumn(targetCol, raTree);
deleted.set(delete.getColumnId());
} else if(step instanceof ColumnInsert){
ColumnInsert insert = (ColumnInsert)step;
raTree = mimir.algebra.OperatorUtils$.MODULE$.projectInColumn(insert.getName(), new mimir.algebra.NullPrimitive(), raTree);
cols.add(colIdx++, insert.getName());
} else if(step instanceof ColumnMove){
//ignore positions for now
} else if(step instanceof ColumnRename){
ColumnRename rename = (ColumnRename)step;
String targetCol = cols.get(rename.getColumnId()).getName();
raTree = mimir.algebra.OperatorUtils$.MODULE$.renameColumn(targetCol, rename.getName(), raTree);
cols.renameColumn(rename.getColumnId(), rename.getName());
} else if(step instanceof CSVFileLoad){
String relName = ((CSVFileLoad)step).getFileName().replaceFirst("\\..*$", "");
colIdx = 0;
cols = new ColumnList();
for(String col : schemas.get(relName)){
cols.add(colIdx++, col);
}
raTree = new mimir.algebra.Table(relName,
makeMimirSchema(schemas.get(relName)),
makeMimirSchema(Arrays.asList("ROWID_MIMIR"), mimir.algebra.Type.withName("TRowId"))
);
} else if(step instanceof RowDelete){
RowDelete delete = (RowDelete)step;
raTree = new mimir.algebra.Select(
(mimir.algebra.Expression)(new mimir.algebra.Comparison(
mimir.algebra.Cmp.withName("Neq"),
new mimir.algebra.Var("ROWID_MIMIR"),
new mimir.algebra.RowIdPrimitive(""+delete.getRowId())
)),
raTree
);
} else if(step instanceof RowInsert){
mimir.algebra.Operator dual = new mimir.algebra.Table("dual",
makeMimirSchema(schemas.get("dual")),
makeMimirSchema(Arrays.asList("ROWID_MIMIR"), mimir.algebra.Type.withName("TRowId"))
);
for(int i = 0; i < colIdx; i++){
if(!deleted.get(i)){
dual = mimir.algebra.OperatorUtils$.MODULE$.projectInColumn(cols.getColumn(i).getName(), new mimir.algebra.NullPrimitive(), dual);
}
}
dual = mimir.optimizer.InlineProjections$.MODULE$.optimize(dual);
raTree = new mimir.algebra.Union(dual, raTree);
} else if(step instanceof RowMove){
} else {
}
}
return mimir.algebra.OperatorUtils$.MODULE$.projectAwayColumn("ROWID_MIMIR", raTree);
}
public static String compileToSQL(mimir.algebra.Operator raTree, Map<String, List<String>> schemas)
{
Map<String,
scala.collection.immutable.List<
scala.Tuple2<String,scala.Enumeration.Value>>> scalaSchemas = new HashMap<>();
for(Map.Entry<String, List<String>> table : schemas.entrySet()){
scalaSchemas.put(table.getKey(), makeMimirSchema(table.getValue()));
}
mimir.Database db = new mimir.Database("Test DB",
new mimir.sql.NullBackend(toScalaMap(scalaSchemas)));
return db.convert(raTree).toString();
}
public static class UnsupportedFeature extends Exception {
public UnsupportedFeature(String msg) { super(msg); }
}
}