163 lines
6.5 KiB
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); }
|
|
}
|
|
|
|
} |