Merged hyracks_dev_next -r 1287 into trunk

git-svn-id: https://hyracks.googlecode.com/svn/trunk@1288 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/pom.xml b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/pom.xml
new file mode 100644
index 0000000..92c4f5f
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/pom.xml
@@ -0,0 +1,65 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>piglet-example</artifactId>
+
+	<parent>
+		<groupId>edu.uci.ics.hyracks</groupId>
+		<artifactId>hyracks-algebricks-examples</artifactId>
+		<version>0.2.0-SNAPSHOT</version>
+	</parent>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.0.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>javacc-maven-plugin</artifactId>
+				<version>2.6</version>
+				<executions>
+					<execution>
+						<id>javacc</id>
+						<goals>
+							<goal>javacc</goal>
+						</goals>
+						<configuration>
+							<isStatic>false</isStatic>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.7.2</version>
+				<configuration>
+					<includes>
+						<include>**/*TestSuite.java</include>
+						<include>**/*Test.java</include>
+					</includes>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>edu.uci.ics.hyracks</groupId>
+			<artifactId>hyracks-algebricks-compiler</artifactId>
+			<version>0.2.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.2</version>
+			<type>jar</type>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ASTNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ASTNode.java
new file mode 100644
index 0000000..d94fb9e
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ASTNode.java
@@ -0,0 +1,16 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public abstract class ASTNode {
+    public enum Tag {
+        ASSIGNMENT,
+        DUMP,
+        LOAD,
+        FILTER,
+
+        SCALAR_FUNCTION,
+        LITERAL,
+        FIELD_ACCESS,
+    }
+
+    public abstract Tag getTag();
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/AssignmentNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/AssignmentNode.java
new file mode 100644
index 0000000..7fa8c6c
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/AssignmentNode.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public class AssignmentNode extends ASTNode {
+    private String alias;
+
+    private RelationNode relation;
+
+    public AssignmentNode(String alias, RelationNode relation) {
+        this.alias = alias;
+        this.relation = relation;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.ASSIGNMENT;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public RelationNode getRelation() {
+        return relation;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/DumpNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/DumpNode.java
new file mode 100644
index 0000000..5e8bc76
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/DumpNode.java
@@ -0,0 +1,24 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public class DumpNode extends RelationNode {
+    private final String file;
+    private final String alias;
+
+    public DumpNode(String file, String alias) {
+        this.file = file;
+        this.alias = alias;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.DUMP;
+    }
+
+    public String getFile() {
+        return file;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ExpressionNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ExpressionNode.java
new file mode 100644
index 0000000..3f68ae6
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ExpressionNode.java
@@ -0,0 +1,4 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public abstract class ExpressionNode extends ASTNode {
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FieldAccessExpressionNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FieldAccessExpressionNode.java
new file mode 100644
index 0000000..69c9262
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FieldAccessExpressionNode.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public class FieldAccessExpressionNode extends ExpressionNode {
+    private String relationName;
+
+    private String fieldName;
+
+    public FieldAccessExpressionNode(String relationName, String fieldName) {
+        this.relationName = relationName;
+        this.fieldName = fieldName;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.FIELD_ACCESS;
+    }
+
+    public String getRelationName() {
+        return relationName;
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FilterNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FilterNode.java
new file mode 100644
index 0000000..bc90043
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FilterNode.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public class FilterNode extends RelationNode {
+    private String alias;
+
+    private ExpressionNode expression;
+
+    public FilterNode(String alias, ExpressionNode expression) {
+        this.alias = alias;
+        this.expression = expression;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.FILTER;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public ExpressionNode getExpression() {
+        return expression;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FunctionTag.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FunctionTag.java
new file mode 100644
index 0000000..2ab397a
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/FunctionTag.java
@@ -0,0 +1,20 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public enum FunctionTag {
+    BOOLEAN_AND,
+    BOOLEAN_OR,
+    BOOLEAN_NOT,
+
+    EQ,
+    NEQ,
+    LT,
+    LTE,
+    GT,
+    GTE,
+
+    ADD,
+    SUBTRACT,
+    MULTIPLY,
+    DIVIDE,
+    MOD,
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LiteralExpressionNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LiteralExpressionNode.java
new file mode 100644
index 0000000..547d487
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LiteralExpressionNode.java
@@ -0,0 +1,27 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+
+public class LiteralExpressionNode extends ExpressionNode {
+    private String image;
+
+    private Type type;
+
+    public LiteralExpressionNode(String image, Type type) {
+        this.image = image;
+        this.type = type;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.LITERAL;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public Type getType() {
+        return type;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LoadNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LoadNode.java
new file mode 100644
index 0000000..e5da760
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/LoadNode.java
@@ -0,0 +1,27 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Schema;
+
+public class LoadNode extends RelationNode {
+    private String dataFile;
+
+    private Schema schema;
+
+    public LoadNode(String dataFile, Schema schema) {
+        this.dataFile = dataFile;
+        this.schema = schema;
+    }
+    
+    @Override
+    public Tag getTag() {
+        return Tag.LOAD;
+    }
+
+    public String getDataFile() {
+        return dataFile;
+    }
+
+    public Schema getSchema() {
+        return schema;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/RelationNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/RelationNode.java
new file mode 100644
index 0000000..51e275f
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/RelationNode.java
@@ -0,0 +1,4 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+public abstract class RelationNode extends ASTNode {
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ScalarFunctionExpressionNode.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ScalarFunctionExpressionNode.java
new file mode 100644
index 0000000..9b55ae9
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/ast/ScalarFunctionExpressionNode.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.ast;
+
+import java.util.List;
+
+public class ScalarFunctionExpressionNode extends ExpressionNode {
+    private FunctionTag fTag;
+
+    private String fName;
+
+    private List<ASTNode> arguments;
+
+    public ScalarFunctionExpressionNode(FunctionTag fTag, String fName, List<ASTNode> arguments) {
+        this.fTag = fTag;
+        this.fName = fName;
+        this.arguments = arguments;
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.SCALAR_FUNCTION;
+    }
+
+    public FunctionTag getFunctionTag() {
+        return fTag;
+    }
+
+    public String getFunctionName() {
+        return fName;
+    }
+
+    public List<ASTNode> getArguments() {
+        return arguments;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/ConstantValue.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/ConstantValue.java
new file mode 100644
index 0000000..e6226f4
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/ConstantValue.java
@@ -0,0 +1,38 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.compiler;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+
+public final class ConstantValue implements IAlgebricksConstantValue {
+    private final Type type;
+
+    private final String image;
+
+    public ConstantValue(Type type, String image) {
+        this.type = type;
+        this.image = image;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    @Override
+    public boolean isFalse() {
+        return false;
+    }
+
+    @Override
+    public boolean isNull() {
+        return false;
+    }
+
+    @Override
+    public boolean isTrue() {
+        return false;
+    }
+}
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java
new file mode 100644
index 0000000..07f6f5d
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java
@@ -0,0 +1,353 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.compiler;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.compiler.api.HeuristicCompilerFactoryBuilder;
+import edu.uci.ics.hyracks.algebricks.compiler.api.ICompiler;
+import edu.uci.ics.hyracks.algebricks.compiler.api.ICompilerFactory;
+import edu.uci.ics.hyracks.algebricks.compiler.rewriter.rulecontrollers.SequentialFixpointRuleController;
+import edu.uci.ics.hyracks.algebricks.compiler.rewriter.rulecontrollers.SequentialOnceRuleController;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.ISerializerDeserializerProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionTypeComputer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
+import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPrettyPrintVisitor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.AbstractRuleController;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.ASTNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.AssignmentNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.DumpNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.ExpressionNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.FieldAccessExpressionNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.FilterNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.FunctionTag;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.LiteralExpressionNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.LoadNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.RelationNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.ScalarFunctionExpressionNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.exceptions.PigletException;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.metadata.PigletFileDataSink;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.metadata.PigletFileDataSource;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.metadata.PigletMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.parser.ParseException;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.parser.PigletParser;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.rewriter.PigletRewriteRuleset;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.runtime.PigletExpressionJobGen;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Schema;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+
+public class PigletCompiler {
+    private static final Logger LOGGER = Logger.getLogger(PigletCompiler.class.getName());
+
+    private static List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> buildDefaultLogicalRewrites() {
+        List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> defaultLogicalRewrites = new ArrayList<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>>();
+        SequentialFixpointRuleController seqCtrlNoDfs = new SequentialFixpointRuleController(false);
+        SequentialFixpointRuleController seqCtrlFullDfs = new SequentialFixpointRuleController(true);
+        SequentialOnceRuleController seqOnceCtrl = new SequentialOnceRuleController(true);
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqOnceCtrl,
+                PigletRewriteRuleset.buildTypeInferenceRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqCtrlFullDfs,
+                PigletRewriteRuleset.buildNormalizationRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqCtrlNoDfs,
+                PigletRewriteRuleset.buildCondPushDownRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqCtrlNoDfs,
+                PigletRewriteRuleset.buildJoinInferenceRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqCtrlNoDfs,
+                PigletRewriteRuleset.buildOpPushDownRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqOnceCtrl,
+                PigletRewriteRuleset.buildDataExchangeRuleCollection()));
+        defaultLogicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqCtrlNoDfs,
+                PigletRewriteRuleset.buildConsolidationRuleCollection()));
+        return defaultLogicalRewrites;
+    }
+
+    private static List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> buildDefaultPhysicalRewrites() {
+        List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> defaultPhysicalRewrites = new ArrayList<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>>();
+        SequentialOnceRuleController seqOnceCtrlAllLevels = new SequentialOnceRuleController(true);
+        SequentialOnceRuleController seqOnceCtrlTopLevel = new SequentialOnceRuleController(false);
+        defaultPhysicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqOnceCtrlAllLevels,
+                PigletRewriteRuleset.buildPhysicalRewritesAllLevelsRuleCollection()));
+        defaultPhysicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqOnceCtrlTopLevel,
+                PigletRewriteRuleset.buildPhysicalRewritesTopLevelRuleCollection()));
+        defaultPhysicalRewrites.add(new Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>(seqOnceCtrlAllLevels,
+                PigletRewriteRuleset.prepareForJobGenRuleCollection()));
+        return defaultPhysicalRewrites;
+    }
+
+    private final ICompilerFactory cFactory;
+
+    private final PigletMetadataProvider metadataProvider;
+
+    private int varCounter;
+
+    private ILogicalOperator previousOp;
+
+    public PigletCompiler() {
+        HeuristicCompilerFactoryBuilder builder = new HeuristicCompilerFactoryBuilder();
+        builder.setLogicalRewrites(buildDefaultLogicalRewrites());
+        builder.setPhysicalRewrites(buildDefaultPhysicalRewrites());
+        builder.setSerializerDeserializerProvider(new ISerializerDeserializerProvider() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public ISerializerDeserializer getSerializerDeserializer(Object type) throws AlgebricksException {
+                return null;
+            }
+        });
+        builder.setPrinterProvider(PigletPrinterFactoryProvider.INSTANCE);
+        builder.setExprJobGen(new PigletExpressionJobGen());
+        builder.setExpressionTypeComputer(new IExpressionTypeComputer() {
+            @Override
+            public Object getType(ILogicalExpression expr, IMetadataProvider<?, ?> metadataProvider,
+                    IVariableTypeEnvironment env) throws AlgebricksException {
+                return null;
+            }
+        });
+        cFactory = builder.create();
+        metadataProvider = new PigletMetadataProvider();
+    }
+
+    public List<ASTNode> parse(Reader in) throws ParseException {
+        PigletParser parser = new PigletParser(in);
+        List<ASTNode> statements = parser.Statements();
+        return statements;
+    }
+
+    public JobSpecification compile(List<ASTNode> ast) throws AlgebricksException, PigletException {
+        ILogicalPlan plan = translate(ast);
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Translated Plan:");
+            LOGGER.info(getPrettyPrintedPlan(plan));
+        }
+        ICompiler compiler = cFactory.createCompiler(plan, metadataProvider, varCounter);
+        compiler.optimize();
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Optimized Plan:");
+            LOGGER.info(getPrettyPrintedPlan(plan));
+        }
+        return compiler.createJob(null);
+    }
+
+    private ILogicalPlan translate(List<ASTNode> ast) throws PigletException {
+        Map<String, Relation> symMap = new HashMap<String, Relation>();
+        List<Mutable<ILogicalOperator>> roots = new ArrayList<Mutable<ILogicalOperator>>();
+        previousOp = null;
+        for (ASTNode an : ast) {
+            switch (an.getTag()) {
+                case DUMP: {
+                    DumpNode dn = (DumpNode) an;
+                    Relation input = symMap.get(dn.getAlias());
+                    List<Mutable<ILogicalExpression>> expressions = new ArrayList<Mutable<ILogicalExpression>>();
+                    for (LogicalVariable v : input.schema.values()) {
+                        expressions.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(v)));
+                    }
+                    PigletFileDataSink dataSink = new PigletFileDataSink(dn.getFile());
+                    ILogicalOperator op = new WriteOperator(expressions, dataSink);
+                    op.getInputs().add(new MutableObject<ILogicalOperator>(input.op));
+                    roots.add(new MutableObject<ILogicalOperator>(op));
+                }
+                    break;
+
+                case ASSIGNMENT: {
+                    AssignmentNode asn = (AssignmentNode) an;
+                    String alias = asn.getAlias();
+                    RelationNode rn = asn.getRelation();
+                    Relation rel = translate(rn, symMap);
+                    previousOp = rel.op;
+                    rel.alias = alias;
+                    symMap.put(alias, rel);
+                }
+                    break;
+            }
+        }
+        return new ALogicalPlanImpl(roots);
+    }
+
+    private Relation translate(RelationNode rn, Map<String, Relation> symMap) throws PigletException {
+        switch (rn.getTag()) {
+            case LOAD: {
+                LoadNode ln = (LoadNode) rn;
+                String file = ln.getDataFile();
+                Schema schema = ln.getSchema();
+                List<Pair<String, Type>> fieldsSchema = schema.getSchema();
+                List<LogicalVariable> variables = new ArrayList<LogicalVariable>();
+                List<Object> types = new ArrayList<Object>();
+                Relation rel = new Relation();
+                for (Pair<String, Type> p : fieldsSchema) {
+                    LogicalVariable v = newVariable();
+                    rel.schema.put(p.first, v);
+                    variables.add(v);
+                    types.add(p.second);
+                }
+                PigletFileDataSource ds = new PigletFileDataSource(file, types.toArray());
+                rel.op = new DataSourceScanOperator(variables, ds);
+                rel.op.getInputs().add(
+                        new MutableObject<ILogicalOperator>(previousOp == null ? new EmptyTupleSourceOperator()
+                                : previousOp));
+                return rel;
+            }
+
+            case FILTER: {
+                FilterNode fn = (FilterNode) rn;
+                String alias = fn.getAlias();
+                ExpressionNode conditionNode = fn.getExpression();
+                Relation inputRel = findInputRelation(alias, symMap);
+                Pair<Relation, LogicalVariable> tempInput = translateScalarExpression(inputRel, conditionNode);
+                Relation rel = new Relation();
+                rel.op = new SelectOperator(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(
+                        tempInput.second)));
+                rel.op.getInputs().add(new MutableObject<ILogicalOperator>(tempInput.first.op));
+                rel.schema.putAll(tempInput.first.schema);
+                return rel;
+            }
+        }
+        throw new IllegalArgumentException("Unknown node: " + rn.getTag() + " encountered");
+    }
+
+    private Pair<Relation, LogicalVariable> translateScalarExpression(Relation inputRel, ExpressionNode expressionNode)
+            throws PigletException {
+        switch (expressionNode.getTag()) {
+            case FIELD_ACCESS: {
+                FieldAccessExpressionNode faen = (FieldAccessExpressionNode) expressionNode;
+                String fieldName = faen.getFieldName();
+                LogicalVariable lVar = findField(fieldName, inputRel.schema);
+                return new Pair<Relation, LogicalVariable>(inputRel, lVar);
+            }
+
+            case LITERAL: {
+                LiteralExpressionNode len = (LiteralExpressionNode) expressionNode;
+                String image = len.getImage();
+                Type type = len.getType();
+                ConstantExpression ce = new ConstantExpression(new ConstantValue(type, image));
+                Relation rel = new Relation();
+                LogicalVariable var = newVariable();
+                List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
+                vars.add(var);
+
+                List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
+                exprs.add(new MutableObject<ILogicalExpression>(ce));
+
+                rel.op = new AssignOperator(vars, exprs);
+                rel.op.getInputs().add(new MutableObject<ILogicalOperator>(inputRel.op));
+                rel.schema.putAll(inputRel.schema);
+
+                return new Pair<Relation, LogicalVariable>(rel, var);
+            }
+
+            case SCALAR_FUNCTION: {
+                ScalarFunctionExpressionNode sfen = (ScalarFunctionExpressionNode) expressionNode;
+                List<Mutable<ILogicalExpression>> argExprs = new ArrayList<Mutable<ILogicalExpression>>();
+                List<ASTNode> arguments = sfen.getArguments();
+                Relation rel = inputRel;
+                for (ASTNode a : arguments) {
+                    Pair<Relation, LogicalVariable> argPair = translateScalarExpression(rel, (ExpressionNode) a);
+                    rel = argPair.first;
+                    argExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(argPair.second)));
+                }
+                Relation outRel = new Relation();
+                outRel.schema.putAll(rel.schema);
+                LogicalVariable var = newVariable();
+                List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
+                vars.add(var);
+
+                IFunctionInfo fInfo = lookupFunction(sfen.getFunctionTag(), sfen.getFunctionName());
+
+                List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
+                exprs.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(fInfo, argExprs)));
+                outRel.op = new AssignOperator(vars, exprs);
+                outRel.op.getInputs().add(new MutableObject<ILogicalOperator>(rel.op));
+                return new Pair<Relation, LogicalVariable>(outRel, var);
+            }
+        }
+        return null;
+    }
+
+    private IFunctionInfo lookupFunction(FunctionTag functionTag, String functionName) throws PigletException {
+        switch (functionTag) {
+            case EQ:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.EQ);
+
+            case NEQ:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.NEQ);
+
+            case LT:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.LT);
+
+            case LTE:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.LE);
+
+            case GT:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.GT);
+
+            case GTE:
+                return AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.GE);
+        }
+        throw new PigletException("Unsupported function: " + functionTag);
+    }
+
+    private LogicalVariable newVariable() {
+        return new LogicalVariable(varCounter++);
+    }
+
+    private LogicalVariable findField(String fieldName, Map<String, LogicalVariable> schema) throws PigletException {
+        LogicalVariable var = schema.get(fieldName);
+        if (var == null) {
+            throw new PigletException("Unable to find field named: " + fieldName);
+        }
+        return var;
+    }
+
+    private Relation findInputRelation(String alias, Map<String, Relation> symMap) throws PigletException {
+        Relation rel = symMap.get(alias);
+        if (rel == null) {
+            throw new PigletException("Unknown alias " + alias + "referenced");
+        }
+        return rel;
+    }
+
+    private static class Relation {
+        String alias;
+        ILogicalOperator op;
+        final Map<String, LogicalVariable> schema;
+
+        public Relation() {
+            schema = new LinkedHashMap<String, LogicalVariable>();
+        }
+    }
+
+    private String getPrettyPrintedPlan(ILogicalPlan plan) throws AlgebricksException {
+        LogicalOperatorPrettyPrintVisitor v = new LogicalOperatorPrettyPrintVisitor();
+        StringBuilder buffer = new StringBuilder();
+        PlanPrettyPrinter.printPlan(plan, buffer, v, 0);
+        return buffer.toString();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletPrinterFactoryProvider.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletPrinterFactoryProvider.java
new file mode 100644
index 0000000..cb12b7d
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletPrinterFactoryProvider.java
@@ -0,0 +1,90 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.compiler;
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IPrinterFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IPrinterFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.data.IntegerPrinterFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.utils.WriteValueTools;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+
+public class PigletPrinterFactoryProvider implements IPrinterFactoryProvider {
+
+    public static final PigletPrinterFactoryProvider INSTANCE = new PigletPrinterFactoryProvider();
+
+    private PigletPrinterFactoryProvider() {
+    }
+
+    @Override
+    public IPrinterFactory getPrinterFactory(Object type) throws AlgebricksException {
+        Type t = (Type) type;
+        switch (t.getTag()) {
+            case INTEGER:
+                return IntegerPrinterFactory.INSTANCE;
+            case CHAR_ARRAY:
+                return CharArrayPrinterFactory.INSTANCE;
+            case FLOAT:
+                return FloatPrinterFactory.INSTANCE;
+            default:
+                throw new UnsupportedOperationException();
+
+        }
+    }
+
+    public static class CharArrayPrinterFactory implements IPrinterFactory {
+
+        private static final long serialVersionUID = 1L;
+
+        public static final CharArrayPrinterFactory INSTANCE = new CharArrayPrinterFactory();
+
+        private CharArrayPrinterFactory() {
+        }
+
+        @Override
+        public IPrinter createPrinter() {
+            return new IPrinter() {
+                @Override
+                public void init() throws AlgebricksException {
+                }
+
+                @Override
+                public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+                    try {
+                        WriteValueTools.writeUTF8String(b, s, l, ps);
+                    } catch (IOException e) {
+                        throw new AlgebricksException(e);
+                    }
+                }
+            };
+        }
+    }
+
+    public static class FloatPrinterFactory implements IPrinterFactory {
+
+        private static final long serialVersionUID = 1L;
+
+        public static final FloatPrinterFactory INSTANCE = new FloatPrinterFactory();
+
+        private FloatPrinterFactory() {
+        }
+
+        @Override
+        public IPrinter createPrinter() {
+            return new IPrinter() {
+                @Override
+                public void init() throws AlgebricksException {
+                }
+
+                @Override
+                public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+                    ps.print(FloatSerializerDeserializer.getFloat(b, s));
+                }
+            };
+        }
+    }
+
+}
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/exceptions/PigletException.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/exceptions/PigletException.java
new file mode 100644
index 0000000..d196b70
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/exceptions/PigletException.java
@@ -0,0 +1,9 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.exceptions;
+
+public class PigletException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    public PigletException(String message) {
+        super(message);
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/FileSplitUtils.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/FileSplitUtils.java
new file mode 100644
index 0000000..d0f9b44
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/FileSplitUtils.java
@@ -0,0 +1,22 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.metadata;
+
+import java.io.File;
+
+import edu.uci.ics.hyracks.api.io.FileReference;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+
+public class FileSplitUtils {
+    public static FileSplit[] parseFileSplits(String fileSplits) {
+        String[] splits = fileSplits.split(",");
+        FileSplit[] fSplits = new FileSplit[splits.length];
+        for (int i = 0; i < splits.length; ++i) {
+            String s = splits[i].trim();
+            int idx = s.indexOf(':');
+            if (idx < 0) {
+                throw new IllegalArgumentException("File split " + s + " not well formed");
+            }
+            fSplits[i] = new FileSplit(s.substring(0, idx), new FileReference(new File(s.substring(idx + 1))));
+        }
+        return fSplits;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSink.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSink.java
new file mode 100644
index 0000000..93f9cae
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSink.java
@@ -0,0 +1,40 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.metadata;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSink;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FileSplitDomain;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.RandomPartitioningProperty;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+
+public class PigletFileDataSink implements IDataSink {
+    private String file;
+
+    private FileSplit[] fileSplits;
+
+    private IPartitioningProperty partProp;
+
+    public PigletFileDataSink(String file) {
+        this.file = file;
+        fileSplits = FileSplitUtils.parseFileSplits(file);
+        partProp = new RandomPartitioningProperty(new FileSplitDomain(fileSplits));
+    }
+
+    @Override
+    public Object getId() {
+        return file;
+    }
+
+    public FileSplit[] getFileSplits() {
+        return fileSplits;
+    }
+
+    @Override
+    public Object[] getSchemaTypes() {
+        return null;
+    }
+
+    @Override
+    public IPartitioningProperty getPartitioningProperty() {
+        return partProp;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
new file mode 100644
index 0000000..6763d45
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletFileDataSource.java
@@ -0,0 +1,62 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSource;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSourcePropertiesProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FileSplitDomain;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.RandomPartitioningProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+
+public class PigletFileDataSource implements IDataSource<String> {
+    private final String file;
+
+    private final Object[] types;
+
+    private final FileSplit[] fileSplits;
+
+    private IDataSourcePropertiesProvider propProvider;
+
+    public PigletFileDataSource(String file, Object[] types) {
+        this.file = file;
+        this.types = types;
+        fileSplits = FileSplitUtils.parseFileSplits(file);
+        final IPhysicalPropertiesVector vec = new StructuralPropertiesVector(new RandomPartitioningProperty(
+                new FileSplitDomain(fileSplits)), new ArrayList<ILocalStructuralProperty>());
+        propProvider = new IDataSourcePropertiesProvider() {
+            @Override
+            public IPhysicalPropertiesVector computePropertiesVector(List<LogicalVariable> scanVariables) {
+                return vec;
+            }
+        };
+    }
+
+    @Override
+    public String getId() {
+        return file;
+    }
+
+    @Override
+    public Object[] getSchemaTypes() {
+        return types;
+    }
+
+    public FileSplit[] getFileSplits() {
+        return fileSplits;
+    }
+
+    @Override
+    public IDataSourcePropertiesProvider getPropertiesProvider() {
+        return propProvider;
+    }
+
+    @Override
+    public void computeFDs(List<LogicalVariable> scanVariables, List<FunctionalDependency> fdList) {
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletMetadataProvider.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletMetadataProvider.java
new file mode 100644
index 0000000..668d7a2
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/metadata/PigletMetadataProvider.java
@@ -0,0 +1,167 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.metadata;
+
+import java.util.List;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IPrinterFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSink;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSource;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSourceIndex;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IPushRuntimeFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.operators.std.SinkWriterRuntimeFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.writers.PrinterBasedWriterFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.constraints.AlgebricksAbsolutePartitionConstraint;
+import edu.uci.ics.hyracks.algebricks.core.api.constraints.AlgebricksPartitionConstraint;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+import edu.uci.ics.hyracks.api.dataflow.IOperatorDescriptor;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.FloatParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IntegerParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.ConstantFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.DelimitedDataTupleParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.FileScanOperatorDescriptor;
+import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
+import edu.uci.ics.hyracks.dataflow.std.file.IFileSplitProvider;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParserFactory;
+
+public class PigletMetadataProvider implements IMetadataProvider<String, String> {
+    @Override
+    public IDataSource<String> findDataSource(String id) throws AlgebricksException {
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getScannerRuntime(IDataSource<String> dataSource,
+            List<LogicalVariable> scanVariables, List<LogicalVariable> projectVariables, boolean projectPushed,
+            JobGenContext context, JobSpecification jobSpec) throws AlgebricksException {
+        PigletFileDataSource ds = (PigletFileDataSource) dataSource;
+
+        FileSplit[] fileSplits = ds.getFileSplits();
+        String[] locations = new String[fileSplits.length];
+        for (int i = 0; i < fileSplits.length; ++i) {
+            locations[i] = fileSplits[i].getNodeName();
+        }
+        IFileSplitProvider fsp = new ConstantFileSplitProvider(fileSplits);
+
+        Object[] colTypes = ds.getSchemaTypes();
+        IValueParserFactory[] vpfs = new IValueParserFactory[colTypes.length];
+        ISerializerDeserializer[] serDesers = new ISerializerDeserializer[colTypes.length];
+
+        for (int i = 0; i < colTypes.length; ++i) {
+            Type colType = (Type) colTypes[i];
+            IValueParserFactory vpf;
+            ISerializerDeserializer serDeser;
+            switch (colType.getTag()) {
+                case INTEGER:
+                    vpf = IntegerParserFactory.INSTANCE;
+                    serDeser = IntegerSerializerDeserializer.INSTANCE;
+                    break;
+
+                case CHAR_ARRAY:
+                    vpf = UTF8StringParserFactory.INSTANCE;
+                    serDeser = UTF8StringSerializerDeserializer.INSTANCE;
+                    break;
+
+                case FLOAT:
+                    vpf = FloatParserFactory.INSTANCE;
+                    serDeser = FloatSerializerDeserializer.INSTANCE;
+                    break;
+
+                default:
+                    throw new UnsupportedOperationException();
+            }
+            vpfs[i] = vpf;
+            serDesers[i] = serDeser;
+        }
+
+        ITupleParserFactory tpf = new DelimitedDataTupleParserFactory(vpfs, ',');
+        RecordDescriptor rDesc = new RecordDescriptor(serDesers);
+
+        IOperatorDescriptor scanner = new FileScanOperatorDescriptor(jobSpec, fsp, tpf, rDesc);
+        AlgebricksAbsolutePartitionConstraint constraint = new AlgebricksAbsolutePartitionConstraint(locations);
+        return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(scanner, constraint);
+    }
+
+    @Override
+    public boolean scannerOperatorIsLeaf(IDataSource<String> dataSource) {
+        return true;
+    }
+
+    @Override
+    public Pair<IPushRuntimeFactory, AlgebricksPartitionConstraint> getWriteFileRuntime(IDataSink sink,
+            int[] printColumns, IPrinterFactory[] printerFactories, RecordDescriptor inputDesc)
+            throws AlgebricksException {
+        PigletFileDataSink ds = (PigletFileDataSink) sink;
+        FileSplit[] fileSplits = ds.getFileSplits();
+        String[] locations = new String[fileSplits.length];
+        for (int i = 0; i < fileSplits.length; ++i) {
+            locations[i] = fileSplits[i].getNodeName();
+        }
+        IPushRuntimeFactory prf = new SinkWriterRuntimeFactory(printColumns, printerFactories, fileSplits[0]
+                .getLocalFile().getFile(), PrinterBasedWriterFactory.INSTANCE, inputDesc);
+        AlgebricksAbsolutePartitionConstraint constraint = new AlgebricksAbsolutePartitionConstraint(locations);
+        return new Pair<IPushRuntimeFactory, AlgebricksPartitionConstraint>(prf, constraint);
+    }
+
+    @Override
+    public IDataSourceIndex<String, String> findDataSourceIndex(String indexId, String dataSourceId)
+            throws AlgebricksException {
+        return null;
+    }
+
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getWriteResultRuntime(
+            IDataSource<String> dataSource, IOperatorSchema propagatedSchema, List<LogicalVariable> keys,
+            LogicalVariable payLoadVar, JobGenContext context, JobSpecification jobSpec) throws AlgebricksException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getInsertRuntime(IDataSource<String> dataSource,
+            IOperatorSchema propagatedSchema, List<LogicalVariable> keys, LogicalVariable payLoadVar,
+            RecordDescriptor recordDesc, JobGenContext context, JobSpecification jobSpec) throws AlgebricksException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getDeleteRuntime(IDataSource<String> dataSource,
+            IOperatorSchema propagatedSchema, List<LogicalVariable> keys, LogicalVariable payLoadVar,
+            RecordDescriptor recordDesc, JobGenContext context, JobSpecification jobSpec) throws AlgebricksException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getIndexInsertRuntime(
+            IDataSourceIndex<String, String> dataSource, IOperatorSchema propagatedSchema,
+            List<LogicalVariable> primaryKeys, List<LogicalVariable> secondaryKeys, RecordDescriptor recordDesc,
+            JobGenContext context, JobSpecification spec) throws AlgebricksException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> getIndexDeleteRuntime(
+            IDataSourceIndex<String, String> dataSource, IOperatorSchema propagatedSchema,
+            List<LogicalVariable> primaryKeys, List<LogicalVariable> secondaryKeys, RecordDescriptor recordDesc,
+            JobGenContext context, JobSpecification spec) throws AlgebricksException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/rewriter/PigletRewriteRuleset.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/rewriter/PigletRewriteRuleset.java
new file mode 100644
index 0000000..90ee5bb
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/rewriter/PigletRewriteRuleset.java
@@ -0,0 +1,116 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.rewriter;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.HeuristicOptimizer;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.BreakSelectIntoConjunctsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ComplexJoinInferenceRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateAssignsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateSelectsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateSubplanRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EnforceStructuralPropertiesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractCommonOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractGbyExpressionsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.FactorRedundantGroupAndDecorVarsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InferTypesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InlineVariablesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceGroupByForStandaloneAggregRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.IsolateHyracksOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PullSelectOutOfEqJoin;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushLimitDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectIntoDataSourceScanRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSelectDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSelectIntoJoinRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ReinferAllTypesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveUnusedAssignAndAggregateRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SetExecutionModeRule;
+
+public class PigletRewriteRuleset {
+
+    public final static List<IAlgebraicRewriteRule> buildTypeInferenceRuleCollection() {
+        List<IAlgebraicRewriteRule> typeInfer = new LinkedList<IAlgebraicRewriteRule>();
+        typeInfer.add(new InferTypesRule());
+        return typeInfer;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildNormalizationRuleCollection() {
+        List<IAlgebraicRewriteRule> normalization = new LinkedList<IAlgebraicRewriteRule>();
+        normalization.add(new EliminateSubplanRule());
+        normalization.add(new IntroduceGroupByForStandaloneAggregRule());
+        normalization.add(new BreakSelectIntoConjunctsRule());
+        normalization.add(new PushSelectIntoJoinRule());
+        normalization.add(new ExtractGbyExpressionsRule());
+        return normalization;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildCondPushDownRuleCollection() {
+        List<IAlgebraicRewriteRule> condPushDown = new LinkedList<IAlgebraicRewriteRule>();
+        condPushDown.add(new PushSelectDownRule());
+        condPushDown.add(new InlineVariablesRule());
+        condPushDown.add(new FactorRedundantGroupAndDecorVarsRule());
+        condPushDown.add(new EliminateSubplanRule());
+        return condPushDown;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildJoinInferenceRuleCollection() {
+        List<IAlgebraicRewriteRule> joinInference = new LinkedList<IAlgebraicRewriteRule>();
+        joinInference.add(new InlineVariablesRule());
+        joinInference.add(new ComplexJoinInferenceRule());
+        return joinInference;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildOpPushDownRuleCollection() {
+        List<IAlgebraicRewriteRule> opPushDown = new LinkedList<IAlgebraicRewriteRule>();
+        opPushDown.add(new PushProjectDownRule());
+        opPushDown.add(new PushSelectDownRule());
+        return opPushDown;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildDataExchangeRuleCollection() {
+        List<IAlgebraicRewriteRule> dataExchange = new LinkedList<IAlgebraicRewriteRule>();
+        dataExchange.add(new SetExecutionModeRule());
+        return dataExchange;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildConsolidationRuleCollection() {
+        List<IAlgebraicRewriteRule> consolidation = new LinkedList<IAlgebraicRewriteRule>();
+        consolidation.add(new ConsolidateSelectsRule());
+        consolidation.add(new ConsolidateAssignsRule());
+        consolidation.add(new RemoveUnusedAssignAndAggregateRule());
+        return consolidation;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildPhysicalRewritesAllLevelsRuleCollection() {
+        List<IAlgebraicRewriteRule> physicalPlanRewrites = new LinkedList<IAlgebraicRewriteRule>();
+        physicalPlanRewrites.add(new PullSelectOutOfEqJoin());
+        physicalPlanRewrites.add(new SetAlgebricksPhysicalOperatorsRule());
+        physicalPlanRewrites.add(new EnforceStructuralPropertiesRule());
+        physicalPlanRewrites.add(new PushProjectDownRule());
+        physicalPlanRewrites.add(new PushLimitDownRule());
+        return physicalPlanRewrites;
+    }
+
+    public final static List<IAlgebraicRewriteRule> buildPhysicalRewritesTopLevelRuleCollection() {
+        List<IAlgebraicRewriteRule> physicalPlanRewrites = new LinkedList<IAlgebraicRewriteRule>();
+        physicalPlanRewrites.add(new PushLimitDownRule());
+        return physicalPlanRewrites;
+    }
+
+    
+    public final static List<IAlgebraicRewriteRule> prepareForJobGenRuleCollection() {
+        List<IAlgebraicRewriteRule> prepareForJobGenRewrites = new LinkedList<IAlgebraicRewriteRule>();
+        prepareForJobGenRewrites.add(new IsolateHyracksOperatorsRule(
+                HeuristicOptimizer.hyraxOperatorsBelowWhichJobGenIsDisabled));
+        prepareForJobGenRewrites.add(new ExtractCommonOperatorsRule());
+        // Re-infer all types, so that, e.g., the effect of not-is-null is
+        // propagated.
+        prepareForJobGenRewrites.add(new PushProjectIntoDataSourceScanRule());
+        prepareForJobGenRewrites.add(new ReinferAllTypesRule());
+        return prepareForJobGenRewrites;
+    }
+
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java
new file mode 100644
index 0000000..63e6f53
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java
@@ -0,0 +1,126 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.runtime;
+
+import java.io.DataOutput;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ILogicalExpressionJobGen;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IRunningAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.evaluators.ColumnAccessEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.evaluators.ConstantEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.compiler.ConstantValue;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.exceptions.PigletException;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.runtime.functions.PigletFunctionRegistry;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.Type;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+
+public class PigletExpressionJobGen implements ILogicalExpressionJobGen {
+    @Override
+    public IEvaluatorFactory createEvaluatorFactory(ILogicalExpression expr, IVariableTypeEnvironment env,
+            IOperatorSchema[] inputSchemas, JobGenContext context) throws AlgebricksException {
+        switch (expr.getExpressionTag()) {
+            case CONSTANT: {
+                ConstantValue cv = (ConstantValue) ((ConstantExpression) expr).getValue();
+                Type type = cv.getType();
+                String image = cv.getImage();
+                ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
+                DataOutput dos = abvs.getDataOutput();
+                switch (type.getTag()) {
+                    case INTEGER:
+                        try {
+                            IntegerSerializerDeserializer.INSTANCE.serialize(Integer.valueOf(image), dos);
+                        } catch (Exception e) {
+                            throw new AlgebricksException(e);
+                        }
+                        break;
+
+                    case CHAR_ARRAY:
+                        try {
+                            UTF8StringSerializerDeserializer.INSTANCE.serialize(image, dos);
+                        } catch (Exception e) {
+                            throw new AlgebricksException(e);
+                        }
+                        break;
+
+                    default:
+                        throw new UnsupportedOperationException("Unsupported constant type: " + type.getTag());
+                }
+                return new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(), abvs.getLength()));
+            }
+
+            case FUNCTION_CALL: {
+                ScalarFunctionCallExpression sfce = (ScalarFunctionCallExpression) expr;
+
+                List<Mutable<ILogicalExpression>> argExprs = sfce.getArguments();
+                IEvaluatorFactory argEvalFactories[] = new IEvaluatorFactory[argExprs.size()];
+                for (int i = 0; i < argEvalFactories.length; ++i) {
+                    Mutable<ILogicalExpression> er = argExprs.get(i);
+                    argEvalFactories[i] = createEvaluatorFactory(er.getValue(), env, inputSchemas, context);
+                }
+                IEvaluatorFactory funcEvalFactory;
+                try {
+                    funcEvalFactory = PigletFunctionRegistry.createFunctionEvaluatorFactory(
+                            sfce.getFunctionIdentifier(), argEvalFactories);
+                } catch (PigletException e) {
+                    throw new AlgebricksException(e);
+                }
+                return funcEvalFactory;
+            }
+
+            case VARIABLE: {
+                LogicalVariable var = ((VariableReferenceExpression) expr).getVariableReference();
+                int index = inputSchemas[0].findVariable(var);
+                return new ColumnAccessEvalFactory(index);
+            }
+        }
+        throw new IllegalArgumentException("Unknown expression type: " + expr.getExpressionTag());
+    }
+
+    @Override
+    public IAggregateFunctionFactory createAggregateFunctionFactory(AggregateFunctionCallExpression expr,
+            IVariableTypeEnvironment env, IOperatorSchema[] inputSchemas, JobGenContext context)
+            throws AlgebricksException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ISerializableAggregateFunctionFactory createSerializableAggregateFunctionFactory(
+            AggregateFunctionCallExpression expr, IVariableTypeEnvironment env, IOperatorSchema[] inputSchemas,
+            JobGenContext context) throws AlgebricksException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public IRunningAggregateFunctionFactory createRunningAggregateFunctionFactory(StatefulFunctionCallExpression expr,
+            IVariableTypeEnvironment env, IOperatorSchema[] inputSchemas, JobGenContext context)
+            throws AlgebricksException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public IUnnestingFunctionFactory createUnnestingFunctionFactory(UnnestingFunctionCallExpression expr,
+            IVariableTypeEnvironment env, IOperatorSchema[] inputSchemas, JobGenContext context)
+            throws AlgebricksException {
+        throw new UnsupportedOperationException();
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IPigletFunctionEvaluatorFactoryBuilder.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IPigletFunctionEvaluatorFactoryBuilder.java
new file mode 100644
index 0000000..38e7615
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IPigletFunctionEvaluatorFactoryBuilder.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.runtime.functions;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+
+public interface IPigletFunctionEvaluatorFactoryBuilder {
+    public IEvaluatorFactory buildEvaluatorFactory(FunctionIdentifier fid, IEvaluatorFactory[] arguments);
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IntegerEqFunctionEvaluatorFactory.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IntegerEqFunctionEvaluatorFactory.java
new file mode 100644
index 0000000..d654d77
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/IntegerEqFunctionEvaluatorFactory.java
@@ -0,0 +1,52 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.runtime.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class IntegerEqFunctionEvaluatorFactory implements IEvaluatorFactory {
+    private static final long serialVersionUID = 1L;
+
+    private final IEvaluatorFactory arg1Factory;
+
+    private final IEvaluatorFactory arg2Factory;
+
+    public IntegerEqFunctionEvaluatorFactory(IEvaluatorFactory arg1Factory, IEvaluatorFactory arg2Factory) {
+        this.arg1Factory = arg1Factory;
+        this.arg2Factory = arg2Factory;
+    }
+
+    @Override
+    public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+        return new IEvaluator() {
+            private DataOutput dataout = output.getDataOutput();
+            private ArrayBackedValueStorage out1 = new ArrayBackedValueStorage();
+            private ArrayBackedValueStorage out2 = new ArrayBackedValueStorage();
+            private IEvaluator eval1 = arg1Factory.createEvaluator(out1);
+            private IEvaluator eval2 = arg2Factory.createEvaluator(out2);
+
+            @Override
+            public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                out1.reset();
+                eval1.evaluate(tuple);
+                out2.reset();
+                eval2.evaluate(tuple);
+                int v1 = IntegerSerializerDeserializer.getInt(out1.getBytes(), 0);
+                int v2 = IntegerSerializerDeserializer.getInt(out2.getBytes(), 0);
+                boolean r = v1 == v2;
+                try {
+                    dataout.writeBoolean(r);
+                } catch (IOException ioe) {
+                    throw new AlgebricksException(ioe);
+                }
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/PigletFunctionRegistry.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/PigletFunctionRegistry.java
new file mode 100644
index 0000000..5acded6
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/functions/PigletFunctionRegistry.java
@@ -0,0 +1,36 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.runtime.functions;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.exceptions.PigletException;
+
+public class PigletFunctionRegistry {
+    private static final Map<FunctionIdentifier, IPigletFunctionEvaluatorFactoryBuilder> builderMap;
+
+    static {
+        Map<FunctionIdentifier, IPigletFunctionEvaluatorFactoryBuilder> temp = new HashMap<FunctionIdentifier, IPigletFunctionEvaluatorFactoryBuilder>();
+
+        temp.put(AlgebricksBuiltinFunctions.EQ, new IPigletFunctionEvaluatorFactoryBuilder() {
+            @Override
+            public IEvaluatorFactory buildEvaluatorFactory(FunctionIdentifier fid, IEvaluatorFactory[] arguments) {
+                return new IntegerEqFunctionEvaluatorFactory(arguments[0], arguments[1]);
+            }
+        });
+
+        builderMap = Collections.unmodifiableMap(temp);
+    }
+
+    public static IEvaluatorFactory createFunctionEvaluatorFactory(FunctionIdentifier fid, IEvaluatorFactory[] args)
+            throws PigletException {
+        IPigletFunctionEvaluatorFactoryBuilder builder = builderMap.get(fid);
+        if (builder == null) {
+            throw new PigletException("Unknown function: " + fid);
+        }
+        return builder.buildEvaluatorFactory(fid, args);
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/BagType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/BagType.java
new file mode 100644
index 0000000..0d964b0
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/BagType.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class BagType extends Type {
+    @Override
+    public Tag getTag() {
+        return Tag.BAG;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/CharArrayType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/CharArrayType.java
new file mode 100644
index 0000000..ddb8e2b
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/CharArrayType.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class CharArrayType extends Type {
+    public static final Type INSTANCE = new CharArrayType();
+
+    private CharArrayType() {
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.CHAR_ARRAY;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/DoubleType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/DoubleType.java
new file mode 100644
index 0000000..f3a3a1b
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/DoubleType.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class DoubleType extends Type {
+    public static final Type INSTANCE = new DoubleType();
+
+    private DoubleType() {
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.DOUBLE;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/FloatType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/FloatType.java
new file mode 100644
index 0000000..4e6a9d9
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/FloatType.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class FloatType extends Type {
+    public static final Type INSTANCE = new FloatType();
+
+    private FloatType() {
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.FLOAT;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/IntegerType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/IntegerType.java
new file mode 100644
index 0000000..3e755c6
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/IntegerType.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class IntegerType extends Type {
+    public static final Type INSTANCE = new IntegerType();
+
+    private IntegerType() {
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.INTEGER;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/LongType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/LongType.java
new file mode 100644
index 0000000..e3af89a
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/LongType.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class LongType extends Type {
+    public static final Type INSTANCE = new LongType();
+
+    private LongType() {
+    }
+
+    @Override
+    public Tag getTag() {
+        return Tag.LONG;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/MapType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/MapType.java
new file mode 100644
index 0000000..74cf717
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/MapType.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class MapType extends Type {
+    @Override
+    public Tag getTag() {
+        return Tag.MAP;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Schema.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Schema.java
new file mode 100644
index 0000000..ba2401c
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Schema.java
@@ -0,0 +1,17 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+import java.util.List;
+
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+
+public class Schema {
+    private List<Pair<String, Type>> schema;
+
+    public Schema(List<Pair<String, Type>> schema) {
+        this.schema = schema;
+    }
+
+    public List<Pair<String, Type>> getSchema() {
+        return schema;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/TupleType.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/TupleType.java
new file mode 100644
index 0000000..4c68c2d
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/TupleType.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public class TupleType extends Type {
+    @Override
+    public Tag getTag() {
+        return Tag.TUPLE;
+    }
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Type.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Type.java
new file mode 100644
index 0000000..b8286e5
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/types/Type.java
@@ -0,0 +1,16 @@
+package edu.uci.ics.hyracks.algebricks.examples.piglet.types;
+
+public abstract class Type {
+    public enum Tag {
+        INTEGER,
+        LONG,
+        FLOAT,
+        DOUBLE,
+        CHAR_ARRAY,
+        TUPLE,
+        BAG,
+        MAP
+    }
+    
+    public abstract Tag getTag();
+}
\ No newline at end of file
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/javacc/PigletParser.jj b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/javacc/PigletParser.jj
new file mode 100644
index 0000000..9e339e4
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/javacc/PigletParser.jj
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ * 
+ *     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.
+ */
+options {
+    STATIC = false;
+    IGNORE_CASE = true;
+    LOOKAHEAD = 2;
+}
+
+PARSER_BEGIN(PigletParser)
+
+package edu.uci.ics.hyracks.algebricks.examples.piglet.parser;
+
+import java.util.*;
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.*;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.types.*;
+
+public class PigletParser {
+    private ExpressionNode createFunction(FunctionTag fTag, String fName, ExpressionNode... arguments) {
+        List<ASTNode> args = new ArrayList<ASTNode>();
+        for(ExpressionNode e : arguments) {
+            args.add(e);
+        }
+        return new ScalarFunctionExpressionNode(fTag, fName, args);
+    }
+    
+    private String stripQuotes(String s) {
+        s = s.substring(1);
+        s = s.substring(0, s.length() - 1);
+        return s;
+    }
+}
+
+PARSER_END(PigletParser)
+
+List<ASTNode> Statements(): {
+    List<ASTNode> statememts = new ArrayList<ASTNode>();
+    ASTNode s;
+} {
+    (
+        (
+            s = AssignmentStatement() {
+                statememts.add(s);
+            }
+            | s = DumpStatement() {
+                statememts.add(s);
+            }
+        ) ";"
+    )* <EOF> {
+        return statememts;
+    }
+}
+
+ASTNode AssignmentStatement(): {
+    String a;
+    RelationNode r;
+} {
+    a = Alias() "=" r = RelationalStatement() {
+        return new AssignmentNode(a, r);
+    }
+}
+
+String Alias(): {
+    Token t;
+} {
+    t = <IDENTIFIER> {
+        return t.image;
+    }
+}
+
+String ColumnName(): {
+    Token t;
+} {
+    t = <IDENTIFIER> {
+        return t.image;
+    }
+}
+
+Type TypeName(): {
+    Token t;
+} {
+    "int" {
+        return IntegerType.INSTANCE;
+    }
+    | "long" {
+        return LongType.INSTANCE;
+    }
+    | "float" {
+        return FloatType.INSTANCE;
+    }
+    | "double" {
+        return DoubleType.INSTANCE;
+    }
+    | "chararray" {
+        return CharArrayType.INSTANCE;
+    }
+    | "tuple" {
+        return new TupleType();
+    }
+    | "bag" {
+        return new BagType();
+    }
+    | "map" {
+        return new MapType();
+    }
+}
+
+Pair<String, Type> ColumnSchema(): {
+    String c;
+    Type t;
+} {
+    c = ColumnName() ":" t = TypeName() {
+        return new Pair<String, Type>(c, t);
+    }
+}
+
+Schema Schema(): {
+    List<Pair<String, Type>> schema = new ArrayList<Pair<String, Type>>();
+    Pair<String, Type> cSchema;
+} {
+    "(" (
+        cSchema = ColumnSchema() {
+            schema.add(cSchema);
+        } (
+            "," cSchema = ColumnSchema() {
+                schema.add(cSchema);
+            }
+        )*
+    )? ")" {
+        return new Schema(schema);
+    }
+}
+
+RelationNode RelationalStatement(): {
+    RelationNode r;
+} {
+    r = LoadStatement() {
+        return r;
+    }
+    | r = FilterStatement() {
+        return r;
+    }
+}
+
+RelationNode LoadStatement(): {
+    Token t;
+    Schema s;
+} {
+    "load" t = <STRING_LITERAL> "as" s = Schema() {
+        return new LoadNode(t.image, s);
+    }
+}
+
+RelationNode FilterStatement(): {
+    String a;
+    ExpressionNode e;
+} {
+    "filter" a = Alias() "by" e = Expression() {
+        return new FilterNode(a, e);
+    }
+}
+
+ASTNode DumpStatement(): {
+    String a;
+    Token t;
+} {
+    "dump" a = Alias() "into" t = <STRING_LITERAL> {
+        return new DumpNode(t.image, a);
+    }
+}
+
+ExpressionNode Expression(): {
+    ExpressionNode e;
+} {
+    e = OrExpression() {
+        return e;
+    }
+}
+
+ExpressionNode OrExpression(): {
+    ExpressionNode e1;
+    ExpressionNode e2;
+} {
+    e1 = AndExpression() (
+        "or" e2 = AndExpression() {
+            e1 = createFunction(FunctionTag.BOOLEAN_OR, null, e1, e2);
+        }
+    )* {
+        return e1;
+    }
+}
+
+ExpressionNode AndExpression(): {
+    ExpressionNode e1;
+    ExpressionNode e2;
+} {
+    e1 = ComparisonExpression() (
+        "and" e2 = ComparisonExpression() {
+            e1 = createFunction(FunctionTag.BOOLEAN_AND, null, e1, e2);
+        }
+    )* {
+        return e1;
+    }
+}
+
+ExpressionNode ComparisonExpression(): {
+    ExpressionNode e1;
+    ExpressionNode e2;
+    FunctionTag fTag;
+} {
+    e1 = AdditiveExpression() (
+        fTag = ComparisonOperator() e2 = AdditiveExpression() {
+            e1 = createFunction(fTag, null, e1, e2);
+        }
+    )? {
+        return e1;
+    }
+}
+
+FunctionTag ComparisonOperator(): {
+} {
+    "==" {
+        return FunctionTag.EQ;
+    }
+    | "!=" {
+        return FunctionTag.NEQ;
+    }
+    | "<" {
+        return FunctionTag.LT;
+    }
+    | "<=" {
+        return FunctionTag.LTE;
+    }
+    | ">" {
+        return FunctionTag.GT;
+    }
+    | ">=" {
+        return FunctionTag.GTE;
+    }
+}
+
+ExpressionNode AdditiveExpression(): {
+    ExpressionNode e1;
+    ExpressionNode e2;
+    FunctionTag fTag;
+} {
+    e1 = MultiplicativeExpression() (
+        fTag = AdditiveOperator() e2 = MultiplicativeExpression() {
+            e1 = createFunction(fTag, null, e1, e2);
+        }
+    )* {
+        return e1;
+    }
+}
+
+FunctionTag AdditiveOperator(): {
+} {
+    "+" {
+        return FunctionTag.ADD;
+    }
+    | "-" {
+        return FunctionTag.SUBTRACT;
+    }
+}
+
+ExpressionNode MultiplicativeExpression(): {
+    ExpressionNode e1;
+    ExpressionNode e2;
+    FunctionTag fTag;
+} {
+    e1 = PrimaryExpression() (
+        fTag = MultiplicativeOperator() e2 = PrimaryExpression() {
+            e1 = createFunction(fTag, null, e1, e2);
+        }
+    )* {
+        return e1;
+    }
+}
+
+FunctionTag MultiplicativeOperator(): {
+} {
+    "*" {
+        return FunctionTag.MULTIPLY;
+    }
+    | "/" {
+        return FunctionTag.DIVIDE;
+    }
+    | "%" {
+        return FunctionTag.MOD;
+    }
+}
+
+ExpressionNode PrimaryExpression(): {
+    ExpressionNode e;
+} {
+    e = Literal() {
+        return e;
+    }
+    | e = FieldAccess() {
+        return e;
+    }
+}
+
+ExpressionNode Literal(): {
+    Token t;
+} {
+    t = <STRING_LITERAL> {
+        return new LiteralExpressionNode(stripQuotes(t.image), CharArrayType.INSTANCE);
+    }
+    | t = <INTEGER_LITERAL> {
+        return new LiteralExpressionNode(t.image, IntegerType.INSTANCE);
+    }
+    | t = <DOUBLE_LITERAL> {
+        return new LiteralExpressionNode(t.image, DoubleType.INSTANCE);
+    }
+}
+
+ExpressionNode FieldAccess(): {
+    String relName = null;
+    Token fieldName;
+} {
+    (relName = Alias() ".")? fieldName = <IDENTIFIER> {
+        return new FieldAccessExpressionNode(relName, fieldName.image);
+    }
+}
+
+<DEFAULT>
+TOKEN : {
+    <STRING_LITERAL: (("\"" (~["\"", "\n"])* "\"") | ("'" (~["'", "\n"])* "'"))>
+    | <IDENTIFIER: <Letter> (<Letter> | <Digit> | <Extender>)*>
+    | <INTEGER_LITERAL: (<Digit>)+>
+    | <DOUBLE_LITERAL: (((<Digit>)* "." (<Digit>)+ (<Exponent>)?) | (<INTEGER_LITERAL> <Exponent>))>
+    | <INDEXED_FIELD: ("$" <INTEGER_LITERAL>)>
+}
+
+TOKEN :
+{
+ < #Exponent : ((["+", "-"])? ["E", "e"] <INTEGER_LITERAL>)>
+}
+
+SPECIAL_TOKEN :
+{
+ < WhitespaceChar : ["\t", "\r", "\n", " "] >
+}
+
+TOKEN :
+{
+ < #Letter : (<BaseChar> | <Ideographic>) >
+}
+
+TOKEN :
+{
+ < #BaseChar : ["\u0041" - "\u005a", "\u0061" - "\u007a", "\u00c0" - "\u00d6", "\u00d8" - "\u00f6", "\u00f8" - "\u00ff", "\u0100" - "\u0131", "\u0134" - "\u013e", "\u0141" - "\u0148", "\u014a" - "\u017e", "\u0180" - "\u01c3", "\u01cd" - "\u01f0", "\u01f4" - "\u01f5", "\u01fa" - "\u0217", "\u0250" - "\u02a8", "\u02bb" - "\u02c1", "\u0386", "\u0388" - "\u038a", "\u038c", "\u038e" - "\u03a1", "\u03a3" - "\u03ce", "\u03d0" - "\u03d6", "\u03da", "\u03dc", "\u03de", "\u03e0", "\u03e2" - "\u03f3", "\u0401" - "\u040c", "\u040e" - "\u044f", "\u0451" - "\u045c", "\u045e" - "\u0481", "\u0490" - "\u04c4", "\u04c7" - "\u04c8", "\u04cb" - "\u04cc", "\u04d0" - "\u04eb", "\u04ee" - "\u04f5", "\u04f8" - "\u04f9", "\u0531" - "\u0556", "\u0559", "\u0561" - "\u0586", "\u05d0" - "\u05ea", "\u05f0" - "\u05f2", "\u0621" - "\u063a", "\u0641" - "\u064a", "\u0671" - "\u06b7", "\u06ba" - "\u06be", "\u06c0" - "\u06ce", "\u06d0" - "\u06d3", "\u06d5", "\u06e5" - "\u06e6", "\u0905" - "\u0939", "\u093d", "\u0958" - "\u0961", "\u0985" - "\u098c", "\u098f" - "\u0990", "\u0993" - "\u09a8", "\u09aa" - "\u09b0", "\u09b2", "\u09b6" - "\u09b9", "\u09dc" - "\u09dd", "\u09df" - "\u09e1", "\u09f0" - "\u09f1", "\u0a05" - "\u0a0a", "\u0a0f" - "\u0a10", "\u0a13" - "\u0a28", "\u0a2a" - "\u0a30", "\u0a32" - "\u0a33", "\u0a35" - "\u0a36", "\u0a38" - "\u0a39", "\u0a59" - "\u0a5c", "\u0a5e", "\u0a72" - "\u0a74", "\u0a85" - "\u0a8b", "\u0a8d", "\u0a8f" - "\u0a91", "\u0a93" - "\u0aa8", "\u0aaa" - "\u0ab0", "\u0ab2" - "\u0ab3", "\u0ab5" - "\u0ab9", "\u0abd", "\u0ae0", "\u0b05" - "\u0b0c", "\u0b0f" - "\u0b10", "\u0b13" - "\u0b28", "\u0b2a" - "\u0b30", "\u0b32" - "\u0b33", "\u0b36" - "\u0b39", "\u0b3d", "\u0b5c" - "\u0b5d", "\u0b5f" - "\u0b61", "\u0b85" - "\u0b8a", "\u0b8e" - "\u0b90", "\u0b92" - "\u0b95", "\u0b99" - "\u0b9a", "\u0b9c", "\u0b9e" - "\u0b9f", "\u0ba3" - "\u0ba4", "\u0ba8" - "\u0baa", "\u0bae" - "\u0bb5", "\u0bb7" - "\u0bb9", "\u0c05" - "\u0c0c", "\u0c0e" - "\u0c10", "\u0c12" - "\u0c28", "\u0c2a" - "\u0c33", "\u0c35" - "\u0c39", "\u0c60" - "\u0c61", "\u0c85" - "\u0c8c", "\u0c8e" - "\u0c90", "\u0c92" - "\u0ca8", "\u0caa" - "\u0cb3", "\u0cb5" - "\u0cb9", "\u0cde", "\u0ce0" - "\u0ce1", "\u0d05" - "\u0d0c", "\u0d0e" - "\u0d10", "\u0d12" - "\u0d28", "\u0d2a" - "\u0d39", "\u0d60" - "\u0d61", "\u0e01" - "\u0e2e", "\u0e30", "\u0e32" - "\u0e33", "\u0e40" - "\u0e45", "\u0e81" - "\u0e82", "\u0e84", "\u0e87" - "\u0e88", "\u0e8a", "\u0e8d", "\u0e94" - "\u0e97", "\u0e99" - "\u0e9f", "\u0ea1" - "\u0ea3", "\u0ea5", "\u0ea7", "\u0eaa" - "\u0eab", "\u0ead" - "\u0eae", "\u0eb0", "\u0eb2" - "\u0eb3", "\u0ebd", "\u0ec0" - "\u0ec4", "\u0f40" - "\u0f47", "\u0f49" - "\u0f69", "\u10a0" - "\u10c5", "\u10d0" - "\u10f6", "\u1100", "\u1102" - "\u1103", "\u1105" - "\u1107", "\u1109", "\u110b" - "\u110c", "\u110e" - "\u1112", "\u113c", "\u113e", "\u1140", "\u114c", "\u114e", "\u1150", "\u1154" - "\u1155", "\u1159", "\u115f" - "\u1161", "\u1163", "\u1165", "\u1167", "\u1169", "\u116d" - "\u116e", "\u1172" - "\u1173", "\u1175", "\u119e", "\u11a8", "\u11ab", "\u11ae" - "\u11af", "\u11b7" - "\u11b8", "\u11ba", "\u11bc" - "\u11c2", "\u11eb", "\u11f0", "\u11f9", "\u1e00" - "\u1e9b", "\u1ea0" - "\u1ef9", "\u1f00" - "\u1f15", "\u1f18" - "\u1f1d", "\u1f20" - "\u1f45", "\u1f48" - "\u1f4d", "\u1f50" - "\u1f57", "\u1f59", "\u1f5b", "\u1f5d", "\u1f5f" - "\u1f7d", "\u1f80" - "\u1fb4", "\u1fb6" - "\u1fbc", "\u1fbe", "\u1fc2" - "\u1fc4", "\u1fc6" - "\u1fcc", "\u1fd0" - "\u1fd3", "\u1fd6" - "\u1fdb", "\u1fe0" - "\u1fec", "\u1ff2" - "\u1ff4", "\u1ff6" - "\u1ffc", "\u2126", "\u212a" - "\u212b", "\u212e", "\u2180" - "\u2182", "\u3041" - "\u3094", "\u30a1" - "\u30fa", "\u3105" - "\u312c", "\uac00" - "\ud7a3"] >
+}
+
+TOKEN :
+{
+ < #Ideographic : ["\u4e00" - "\u9fa5", "\u3007", "\u3021" - "\u3029"] >
+}
+
+TOKEN :
+{
+ < #CombiningChar : ["\u0300" - "\u0345", "\u0360" - "\u0361", "\u0483" - "\u0486", "\u0591" - "\u05a1", "\u05a3" - "\u05b9", "\u05bb" - "\u05bd", "\u05bf", "\u05c1" - "\u05c2", "\u05c4", "\u064b" - "\u0652", "\u0670", "\u06d6" - "\u06dc", "\u06dd" - "\u06df", "\u06e0" - "\u06e4", "\u06e7" - "\u06e8", "\u06ea" - "\u06ed", "\u0901" - "\u0903", "\u093c", "\u093e" - "\u094c", "\u094d", "\u0951" - "\u0954", "\u0962" - "\u0963", "\u0981" - "\u0983", "\u09bc", "\u09be", "\u09bf", "\u09c0" - "\u09c4", "\u09c7" - "\u09c8", "\u09cb" - "\u09cd", "\u09d7", "\u09e2" - "\u09e3", "\u0a02", "\u0a3c", "\u0a3e", "\u0a3f", "\u0a40" - "\u0a42", "\u0a47" - "\u0a48", "\u0a4b" - "\u0a4d", "\u0a70" - "\u0a71", "\u0a81" - "\u0a83", "\u0abc", "\u0abe" - "\u0ac5", "\u0ac7" - "\u0ac9", "\u0acb" - "\u0acd", "\u0b01" - "\u0b03", "\u0b3c", "\u0b3e" - "\u0b43", "\u0b47" - "\u0b48", "\u0b4b" - "\u0b4d", "\u0b56" - "\u0b57", "\u0b82" - "\u0b83", "\u0bbe" - "\u0bc2", "\u0bc6" - "\u0bc8", "\u0bca" - "\u0bcd", "\u0bd7", "\u0c01" - "\u0c03", "\u0c3e" - "\u0c44", "\u0c46" - "\u0c48", "\u0c4a" - "\u0c4d", "\u0c55" - "\u0c56", "\u0c82" - "\u0c83", "\u0cbe" - "\u0cc4", "\u0cc6" - "\u0cc8", "\u0cca" - "\u0ccd", "\u0cd5" - "\u0cd6", "\u0d02" - "\u0d03", "\u0d3e" - "\u0d43", "\u0d46" - "\u0d48", "\u0d4a" - "\u0d4d", "\u0d57", "\u0e31", "\u0e34" - "\u0e3a", "\u0e47" - "\u0e4e", "\u0eb1", "\u0eb4" - "\u0eb9", "\u0ebb" - "\u0ebc", "\u0ec8" - "\u0ecd", "\u0f18" - "\u0f19", "\u0f35", "\u0f37", "\u0f39", "\u0f3e", "\u0f3f", "\u0f71" - "\u0f84", "\u0f86" - "\u0f8b", "\u0f90" - "\u0f95", "\u0f97", "\u0f99" - "\u0fad", "\u0fb1" - "\u0fb7", "\u0fb9", "\u20d0" - "\u20dc", "\u20e1", "\u302a" - "\u302f", "\u3099", "\u309a"] >
+}
+
+TOKEN :
+{
+ < #Digit : ["\u0030" - "\u0039", "\u0660" - "\u0669", "\u06f0" - "\u06f9", "\u0966" - "\u096f", "\u09e6" - "\u09ef", "\u0a66" - "\u0a6f", "\u0ae6" - "\u0aef", "\u0b66" - "\u0b6f", "\u0be7" - "\u0bef", "\u0c66" - "\u0c6f", "\u0ce6" - "\u0cef", "\u0d66" - "\u0d6f", "\u0e50" - "\u0e59", "\u0ed0" - "\u0ed9", "\u0f20" - "\u0f29"] >
+}
+
+TOKEN :
+{
+ < #Extender : ["\u00b7", "\u02d0", "\u02d1", "\u0387", "\u0640", "\u0e46", "\u0ec6", "\u3005", "\u3031" - "\u3035", "\u309d" - "\u309e", "\u30fc" - "\u30fe"] >
+}
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTest.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTest.java
new file mode 100644
index 0000000..7e027fa
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTest.java
@@ -0,0 +1,29 @@
+package edu.uci.ics.algebricks.examples.piglet.test;
+
+import java.io.File;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class PigletTest {
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        File dir = new File("testcases");
+        findAndAddTests(suite, dir);
+
+        return suite;
+    }
+
+    private static void findAndAddTests(TestSuite suite, File dir) {
+        for (final File f : dir.listFiles()) {
+            if (f.getName().startsWith(".")) {
+                continue;
+            }
+            if (f.isDirectory()) {
+                findAndAddTests(suite, f);
+            } else if (f.getName().endsWith(".piglet")) {
+                suite.addTest(new PigletTestCase(f));
+            }
+        }
+    }
+}
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTestCase.java b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTestCase.java
new file mode 100644
index 0000000..1a329f6
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/test/java/edu/uci/ics/algebricks/examples/piglet/test/PigletTestCase.java
@@ -0,0 +1,42 @@
+package edu.uci.ics.algebricks.examples.piglet.test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import edu.uci.ics.hyracks.algebricks.examples.piglet.ast.ASTNode;
+import edu.uci.ics.hyracks.algebricks.examples.piglet.compiler.PigletCompiler;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+
+public class PigletTestCase extends TestCase {
+
+    private final File file;
+
+    PigletTestCase(File file) {
+        super("testPiglet");
+        this.file = file;
+    }
+
+    @Test
+    public void testPiglet() {
+        try {
+            FileReader in = new FileReader(file);
+            try {
+                PigletCompiler c = new PigletCompiler();
+
+                List<ASTNode> ast = c.parse(in);
+                JobSpecification jobSpec = c.compile(ast);
+
+                System.err.println(jobSpec.toJSON());
+            } finally {
+                in.close();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q1.piglet b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q1.piglet
new file mode 100644
index 0000000..88111ff
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q1.piglet
@@ -0,0 +1,2 @@
+R = load "nc1:data/file1.txt,nc2:data/file2.txt" as (id : int, name : chararray);
+dump R into "nc1:output";
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q2.piglet b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q2.piglet
new file mode 100644
index 0000000..5c45ac1
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/testcases/q2.piglet
@@ -0,0 +1,3 @@
+R = load "nc1:data/file1.txt,nc2:data/file2.txt" as (id : int, name : chararray);
+S = filter R by id == 5;
+dump S into "nc1:output";
diff --git a/hyracks/hyracks-algebricks/hyracks-algebricks-examples/pom.xml b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/pom.xml
new file mode 100644
index 0000000..05dd6df
--- /dev/null
+++ b/hyracks/hyracks-algebricks/hyracks-algebricks-examples/pom.xml
@@ -0,0 +1,15 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>hyracks-algebricks-examples</artifactId>
+  <packaging>pom</packaging>
+
+  <parent>
+    <groupId>edu.uci.ics.hyracks</groupId>
+    <artifactId>hyracks-algebricks</artifactId>
+    <version>0.2.0-SNAPSHOT</version>
+  </parent>
+
+  <modules>
+    <module>piglet-example</module>
+  </modules>
+</project>