blob: 9e2150c29f21e048167def4bcb10dad2dffac530 [file] [log] [blame]
package edu.uci.ics.asterix.translator;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import edu.uci.ics.asterix.aql.base.Clause;
import edu.uci.ics.asterix.aql.base.Expression;
import edu.uci.ics.asterix.aql.base.Statement;
import edu.uci.ics.asterix.aql.base.Statement.Kind;
import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
import edu.uci.ics.asterix.aql.expression.CallExpr;
import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
import edu.uci.ics.asterix.aql.expression.DeleteStatement;
import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
import edu.uci.ics.asterix.aql.expression.FieldAccessor;
import edu.uci.ics.asterix.aql.expression.FieldBinding;
import edu.uci.ics.asterix.aql.expression.ForClause;
import edu.uci.ics.asterix.aql.expression.Identifier;
import edu.uci.ics.asterix.aql.expression.InsertStatement;
import edu.uci.ics.asterix.aql.expression.LiteralExpr;
import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
import edu.uci.ics.asterix.aql.expression.Query;
import edu.uci.ics.asterix.aql.expression.RecordConstructor;
import edu.uci.ics.asterix.aql.expression.VariableExpr;
import edu.uci.ics.asterix.aql.expression.WhereClause;
import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
import edu.uci.ics.asterix.aql.expression.ControlFeedStatement.OperationType;
import edu.uci.ics.asterix.aql.literal.StringLiteral;
import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
import edu.uci.ics.asterix.metadata.IDatasetDetails;
import edu.uci.ics.asterix.metadata.MetadataException;
import edu.uci.ics.asterix.metadata.MetadataManager;
import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
import edu.uci.ics.asterix.metadata.entities.Dataset;
import edu.uci.ics.asterix.metadata.entities.FeedDatasetDetails;
import edu.uci.ics.asterix.om.functions.AsterixFunction;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
public class DmlTranslator extends AbstractAqlTranslator {
private final MetadataTransactionContext mdTxnCtx;
private final List<Statement> aqlStatements;
private AqlCompiledMetadataDeclarations compiledDeclarations;
private List<ICompiledDmlStatement> compiledDmlStatements;
public DmlTranslator(MetadataTransactionContext mdTxnCtx, List<Statement> aqlStatements) {
this.mdTxnCtx = mdTxnCtx;
this.aqlStatements = aqlStatements;
}
public void translate() throws AlgebricksException, RemoteException, ACIDException, MetadataException {
compiledDeclarations = compileMetadata(mdTxnCtx, aqlStatements, true);
compiledDmlStatements = compileDmlStatements();
}
public AqlCompiledMetadataDeclarations getCompiledDeclarations() {
return compiledDeclarations;
}
public List<ICompiledDmlStatement> getCompiledDmlStatements() {
return compiledDmlStatements;
}
private List<ICompiledDmlStatement> compileDmlStatements() throws AlgebricksException {
List<ICompiledDmlStatement> dmlStatements = new ArrayList<ICompiledDmlStatement>();
for (Statement stmt : aqlStatements) {
validateOperation(compiledDeclarations, stmt);
switch (stmt.getKind()) {
case LOAD_FROM_FILE: {
LoadFromFileStatement st1 = (LoadFromFileStatement) stmt;
CompiledLoadFromFileStatement cls = new CompiledLoadFromFileStatement(st1.getDatasetName()
.getValue(), st1.getAdapter(), st1.getProperties(), st1.dataIsAlreadySorted());
dmlStatements.add(cls);
break;
}
case WRITE_FROM_QUERY_RESULT: {
WriteFromQueryResultStatement st1 = (WriteFromQueryResultStatement) stmt;
CompiledWriteFromQueryResultStatement clfrqs = new CompiledWriteFromQueryResultStatement(st1
.getDatasetName().getValue(), st1.getQuery(), st1.getVarCounter());
dmlStatements.add(clfrqs);
break;
}
case CREATE_INDEX: {
CreateIndexStatement cis = (CreateIndexStatement) stmt;
if (cis.getNeedToCreate()) {
CompiledCreateIndexStatement ccis = new CompiledCreateIndexStatement(cis.getIndexName()
.getValue(), cis.getDatasetName().getValue(), cis.getFieldExprs(), cis.getIndexType());
dmlStatements.add(ccis);
}
break;
}
case INSERT: {
InsertStatement is = (InsertStatement) stmt;
CompiledInsertStatement clfrqs = new CompiledInsertStatement(is.getDatasetName().getValue(), is
.getQuery(), is.getVarCounter());
dmlStatements.add(clfrqs);
break;
}
case DELETE: {
DeleteStatement ds = (DeleteStatement) stmt;
CompiledDeleteStatement clfrqs = new CompiledDeleteStatement(ds.getVariableExpr(), ds
.getDatasetName(), ds.getCondition(), ds.getDieClause(), ds.getVarCounter(),
compiledDeclarations);
dmlStatements.add(clfrqs);
break;
}
case BEGIN_FEED: {
BeginFeedStatement bfs = (BeginFeedStatement) stmt;
CompiledBeginFeedStatement cbfs = new CompiledBeginFeedStatement(bfs.getDatasetName(), bfs
.getQuery(), bfs.getVarCounter());
dmlStatements.add(cbfs);
Dataset dataset;
try {
dataset = MetadataManager.INSTANCE.getDataset(mdTxnCtx,
compiledDeclarations.getDataverseName(), bfs.getDatasetName().getValue());
} catch (MetadataException me) {
throw new AlgebricksException(me);
}
IDatasetDetails datasetDetails = dataset.getDatasetDetails();
if (datasetDetails.getDatasetType() != DatasetType.FEED) {
throw new IllegalArgumentException("Dataset " + bfs.getDatasetName().getValue()
+ " is not a feed dataset");
}
bfs.initialize((FeedDatasetDetails) datasetDetails);
cbfs.setQuery(bfs.getQuery());
break;
}
case CONTROL_FEED: {
ControlFeedStatement cfs = (ControlFeedStatement) stmt;
CompiledControlFeedStatement clcfs = new CompiledControlFeedStatement(cfs.getOperationType(), cfs
.getDatasetName(), cfs.getAlterAdapterConfParams());
dmlStatements.add(clcfs);
break;
}
}
}
return dmlStatements;
}
public static interface ICompiledDmlStatement {
public abstract Kind getKind();
}
public static class CompiledCreateIndexStatement implements ICompiledDmlStatement {
private String indexName;
private String datasetName;
private List<String> keyFields;
private IndexType indexType;
public CompiledCreateIndexStatement(String indexName, String datasetName, List<String> keyFields,
IndexType indexType) {
this.indexName = indexName;
this.datasetName = datasetName;
this.keyFields = keyFields;
this.indexType = indexType;
}
public String getDatasetName() {
return datasetName;
}
public String getIndexName() {
return indexName;
}
public List<String> getKeyFields() {
return keyFields;
}
public IndexType getIndexType() {
return indexType;
}
@Override
public Kind getKind() {
return Kind.CREATE_INDEX;
}
}
public static class CompiledLoadFromFileStatement implements ICompiledDmlStatement {
private String datasetName;
private boolean alreadySorted;
private String adapter;
private Map<String, String> properties;
public CompiledLoadFromFileStatement(String datasetName, String adapter, Map<String, String> properties,
boolean alreadySorted) {
this.datasetName = datasetName;
this.alreadySorted = alreadySorted;
this.adapter = adapter;
this.properties = properties;
}
public String getDatasetName() {
return datasetName;
}
public boolean alreadySorted() {
return alreadySorted;
}
public String getAdapter() {
return adapter;
}
public Map<String, String> getProperties() {
return properties;
}
@Override
public Kind getKind() {
return Kind.LOAD_FROM_FILE;
}
}
public static class CompiledWriteFromQueryResultStatement implements ICompiledDmlStatement {
private String datasetName;
private Query query;
private int varCounter;
public CompiledWriteFromQueryResultStatement(String datasetName, Query query, int varCounter) {
this.datasetName = datasetName;
this.query = query;
this.varCounter = varCounter;
}
public String getDatasetName() {
return datasetName;
}
public int getVarCounter() {
return varCounter;
}
public Query getQuery() {
return query;
}
@Override
public Kind getKind() {
return Kind.WRITE_FROM_QUERY_RESULT;
}
}
public static class CompiledInsertStatement implements ICompiledDmlStatement {
private String datasetName;
private Query query;
private int varCounter;
public CompiledInsertStatement(String datasetName, Query query, int varCounter) {
this.datasetName = datasetName;
this.query = query;
this.varCounter = varCounter;
}
public String getDatasetName() {
return datasetName;
}
public int getVarCounter() {
return varCounter;
}
public Query getQuery() {
return query;
}
@Override
public Kind getKind() {
return Kind.INSERT;
}
}
public static class CompiledBeginFeedStatement implements ICompiledDmlStatement {
private Identifier datasetName;
private Query query;
private int varCounter;
public CompiledBeginFeedStatement(Identifier datasetName, Query query, int varCounter) {
this.datasetName = datasetName;
this.query = query;
this.varCounter = varCounter;
}
public Identifier getDatasetName() {
return datasetName;
}
public int getVarCounter() {
return varCounter;
}
public Query getQuery() {
return query;
}
public void setQuery(Query query) {
this.query = query;
}
@Override
public Kind getKind() {
return Kind.BEGIN_FEED;
}
}
public static class CompiledControlFeedStatement implements ICompiledDmlStatement {
private Identifier datasetName;
private OperationType operationType;
private Query query;
private int varCounter;
private Map<String, String> alteredParams;
public CompiledControlFeedStatement(OperationType operationType, Identifier datasetName,
Map<String, String> alteredParams) {
this.datasetName = datasetName;
this.operationType = operationType;
this.alteredParams = alteredParams;
}
public Identifier getDatasetName() {
return datasetName;
}
public OperationType getOperationType() {
return operationType;
}
public int getVarCounter() {
return varCounter;
}
public Query getQuery() {
return query;
}
@Override
public Kind getKind() {
return Kind.CONTROL_FEED;
}
public Map<String, String> getProperties() {
return alteredParams;
}
public void setProperties(Map<String, String> properties) {
this.alteredParams = properties;
}
}
public static class CompiledDeleteStatement implements ICompiledDmlStatement {
private VariableExpr var;
private Identifier dataset;
private Expression condition;
private Clause dieClause;
private int varCounter;
private AqlCompiledMetadataDeclarations compiledDeclarations;
public CompiledDeleteStatement(VariableExpr var, Identifier dataset, Expression condition, Clause dieClause,
int varCounter, AqlCompiledMetadataDeclarations compiledDeclarations) {
this.var = var;
this.dataset = dataset;
this.condition = condition;
this.dieClause = dieClause;
this.varCounter = varCounter;
this.compiledDeclarations = compiledDeclarations;
}
public Identifier getDataset() {
return dataset;
}
public String getDatasetName() {
return dataset.getValue();
}
public int getVarCounter() {
return varCounter;
}
public Expression getCondition() {
return condition;
}
public Clause getDieClause() {
return dieClause;
}
public Query getQuery() throws AlgebricksException {
String datasetName = dataset.getValue();
List<Expression> arguments = new ArrayList<Expression>();
LiteralExpr argumentLiteral = new LiteralExpr(new StringLiteral(datasetName));
arguments.add(argumentLiteral);
CallExpr callExpression = new CallExpr(new AsterixFunction("dataset", 1), arguments);
List<Clause> clauseList = new ArrayList<Clause>();
Clause forClause = new ForClause(var, callExpression);
clauseList.add(forClause);
Clause whereClause = null;
if (condition != null) {
whereClause = new WhereClause(condition);
clauseList.add(whereClause);
}
if (dieClause != null) {
clauseList.add(dieClause);
}
AqlCompiledDatasetDecl aqlDataset = compiledDeclarations.findDataset(datasetName);
if (aqlDataset == null) {
throw new AlgebricksException("Unknown dataset " + datasetName);
}
String itemTypeName = aqlDataset.getItemTypeName();
IAType itemType = compiledDeclarations.findType(itemTypeName);
ARecordType recType = (ARecordType) itemType;
String[] fieldNames = recType.getFieldNames();
List<FieldBinding> fieldBindings = new ArrayList<FieldBinding>();
for (int i = 0; i < fieldNames.length; i++) {
FieldAccessor fa = new FieldAccessor(var, new Identifier(fieldNames[i]));
FieldBinding fb = new FieldBinding(new LiteralExpr(new StringLiteral(fieldNames[i])), fa);
fieldBindings.add(fb);
}
RecordConstructor rc = new RecordConstructor(fieldBindings);
FLWOGRExpression flowgr = new FLWOGRExpression(clauseList, rc);
Query query = new Query();
query.setBody(flowgr);
return query;
}
@Override
public Kind getKind() {
return Kind.DELETE;
}
}
}