fix issue 205
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_printerfix@959 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
index c41d908..2dce5f6 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
@@ -48,22 +48,18 @@
* recursive way. It enables: 1. bag-based fields in a record, 2. bidirectional
* cast of a open field and a matched closed field, and 3. put in null fields
* when necessary.
- *
* Here is an example: A record { "hobby": {{"music", "coding"}}, "id": "001",
* "name": "Person Three"} which confirms to closed type ( id: string, name:
* string, hobby: {{string}}? ) can be cast to an open type (id: string ), or
* vice versa.
- *
* However, if the input record is a variable, then we don't know its exact
* field layout at compile time. For example, records conforming to the same
* type can have different field orderings and different open parts. That's why
* we need dynamic type casting.
- *
* Note that as we can see in the example, the ordering of fields of a record is
* not required. Since the open/closed part of a record has completely different
* underlying memory/storage layout, a cast-record function will change the
* layout as specified at runtime.
- *
* Implementation wise, this rule checks the target dataset type and the input
* record type, and if the types are different, then it plugs in an assign with
* a cast-record function, and projects away the original (uncast) field.
@@ -80,9 +76,7 @@
throws AlgebricksException {
/**
* pattern match: sink insert assign
- *
* resulting plan: sink-insert-project-assign
- *
*/
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
if (op1.getOperatorTag() != LogicalOperatorTag.SINK)
@@ -90,6 +84,9 @@
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.INSERT_DELETE)
return false;
+ InsertDeleteOperator insertDeleteOp = (InsertDeleteOperator) op2;
+ if (insertDeleteOp.getOperation() == InsertDeleteOperator.Kind.DELETE)
+ return false;
AbstractLogicalOperator op3 = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
if (op3.getOperatorTag() != LogicalOperatorTag.ASSIGN)
return false;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
index 9241217..3aae2dd 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
@@ -87,6 +87,9 @@
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.INSERT_DELETE)
return false;
+ InsertDeleteOperator insertDeleteOp = (InsertDeleteOperator) op2;
+ if (insertDeleteOp.getOperation() == InsertDeleteOperator.Kind.DELETE)
+ return false;
AbstractLogicalOperator assignOp = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
if (assignOp.getOperatorTag() != LogicalOperatorTag.ASSIGN)
return false;
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/query-issue205.aql b/asterix-app/src/test/resources/runtimets/queries/dml/query-issue205.aql
new file mode 100644
index 0000000..6ce9bf8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/query-issue205.aql
@@ -0,0 +1,26 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type EmployeeStat as open {
+ age: int32,
+ salary:int32
+}
+
+create type EmployeeType as closed {
+ id:string,
+ stat:EmployeeStat,
+ deptCode:int32
+}
+
+create dataset Employees(EmployeeType)
+ partitioned by key id;
+
+insert into dataset Employees({"id":"1234", "stat":{ "age":50, "salary":120000}, "deptCode":32 });
+insert into dataset Employees({"id":"5678", "stat":{ "age":40, "salary":100000}, "deptCode":16 });
+
+delete $l from dataset Employees where $l.id = "1234";
+
+write output to nc1:"rttest/dml_query-issue205.adm";
+for $l in dataset('Employees')
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/query-issue205.adm b/asterix-app/src/test/resources/runtimets/results/dml/query-issue205.adm
new file mode 100644
index 0000000..ea80112
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/dml/query-issue205.adm
@@ -0,0 +1 @@
+{ "id": "5678", "stat": { "age": 40, "salary": 100000 }, "deptCode": 16 }
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index f32f0b8..2e4f590 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -739,6 +739,11 @@
</test-group>
<test-group name="dml">
<test-case FilePath="dml">
+ <compilation-unit name="query-issue205">
+ <output-file compare="Text">query-issue205.adm</output-file>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="dml">
<compilation-unit name="delete-from-loaded-dataset-with-index">
<output-file compare="Text">delete-from-loaded-dataset-with-index.adm</output-file>
</compilation-unit>