test recursive nested record-within-list
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@334 eaa15691-b419-025a-1212-ee371bd00084
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 afb01ef..b79be86 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
@@ -110,7 +110,8 @@
ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expr;
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
return false;
- rewriteRecordFuncExpr(funcExpr, requiredRecordType, inputRecordType);
+ IVariableTypeEnvironment assignEnv = oldAssignOperator.computeOutputTypeEnvironment(context);
+ rewriteFuncExpr(funcExpr, requiredRecordType, inputRecordType, assignEnv);
}
context.computeAndSetTypeEnvironmentForOperator(originalAssign);
}
@@ -123,27 +124,28 @@
return true;
}
+ private void rewriteFuncExpr(ScalarFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
+ IVariableTypeEnvironment env) throws AlgebricksException {
+ if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+ rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ }
+ if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+ rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ } else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
+ rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
+ }
+ }
+
private void rewriteRecordFuncExpr(ScalarFunctionCallExpression funcExpr, ARecordType requiredRecordType,
- ARecordType inputRecordType) {
+ ARecordType inputRecordType, IVariableTypeEnvironment env) throws AlgebricksException {
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
return;
TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
- staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType);
- }
-
- private void rewriteFuncExpr(ScalarFunctionCallExpression funcExpr, IAType reqType, IAType inputType) {
- if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
- rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType);
- }
- if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
- rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType);
- } else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
- rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType);
- }
+ staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
}
private void rewriteListFuncExpr(ScalarFunctionCallExpression funcExpr, AbstractCollectionType requiredListType,
- AbstractCollectionType inputListType) {
+ AbstractCollectionType inputListType, IVariableTypeEnvironment env) throws AlgebricksException {
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
return;
@@ -158,12 +160,19 @@
ILogicalExpression arg = args.get(j).getValue();
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) arg;
- rewriteFuncExpr(argFunc, itemType, inputItemType);
+ IAType currentItemType = (IAType) env.getType(argFunc);
+ if (inputItemType == null || inputItemType == BuiltinType.ANY) {
+ currentItemType = (IAType) env.getType(argFunc);
+ rewriteFuncExpr(argFunc, itemType, currentItemType, env);
+ } else {
+ rewriteFuncExpr(argFunc, itemType, inputItemType, env);
+ }
}
}
}
- private void staticRecordTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType) {
+ private void staticRecordTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType,
+ IVariableTypeEnvironment env) throws AlgebricksException {
IAType[] reqFieldTypes = reqType.getFieldTypes();
String[] reqFieldNames = reqType.getFieldNames();
IAType[] inputFieldTypes = inputType.getFieldTypes();
@@ -186,6 +195,9 @@
String fieldName = inputFieldNames[i];
IAType fieldType = inputFieldTypes[i];
+ if (2 * i + 1 > func.getArguments().size())
+ break;
+
ILogicalExpression arg = func.getArguments().get(2 * i + 1).getValue();
matched = false;
for (int j = 0; j < reqFieldNames.length; j++) {
@@ -199,7 +211,7 @@
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
- rewriteFuncExpr(scalarFunc, reqFieldType, fieldType);
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
}
break;
}
@@ -218,7 +230,7 @@
// rewrite record expr
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
- rewriteFuncExpr(scalarFunc, reqFieldType, fieldType);
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
}
break;
}
@@ -227,7 +239,7 @@
// match the record field: need cast
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
- rewriteFuncExpr(scalarFunc, reqFieldType, fieldType);
+ rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
@@ -319,9 +331,9 @@
if (inputFieldTypes[i].getTypeTag() == ATypeTag.UNORDEREDLIST) {
reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
}
- if (TypeComputerUtilities.getRequiredType((AbstractFunctionCallExpression)argExpr) == null) {
+ if (TypeComputerUtilities.getRequiredType((AbstractFunctionCallExpression) argExpr) == null) {
ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) argExpr;
- rewriteFuncExpr(argFunc, reqFieldType, inputFieldTypes[i]);
+ rewriteFuncExpr(argFunc, reqFieldType, inputFieldTypes[i], env);
}
}
arguments.add(fExprRef);
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
index 5b92f28..6c8264f 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
@@ -13,11 +13,16 @@
street: string,
city: string
}
+create type Dept as open{
+ name: string,
+ id: int32
+}
create type testtype as closed {
name: string,
id: string,
- address: AddressType?
+ address: AddressType?,
+ department: {{Dept}}?
}
create type testtype2 as open {
@@ -30,7 +35,7 @@
create dataset testds2(testtype2) partitioned by key id;
insert into dataset testds (
-{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697} }
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299, "review":5}, {"name":"EE", "id":399} }} }
);
insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
index 493b2cc..2070e20 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
@@ -14,6 +14,11 @@
city: string
}
+create type Dept as closed{
+ name: string,
+ id: int32
+}
+
create type testtype as open {
name: string,
id: string
@@ -22,7 +27,8 @@
create type testtype2 as closed {
name: string,
id: string,
- address: AddressType?
+ address: AddressType?,
+ department: {{Dept}}?
}
create dataset testds(testtype) partitioned by key id;
@@ -30,7 +36,7 @@
create dataset testds2(testtype2) partitioned by key id;
insert into dataset testds (
-{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697} }
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299}, {"name":"EE", "id":399} }} }
);
insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
index 8088fff..60a389c 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
@@ -1,4 +1,4 @@
-{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 } }
-{ "name": "Person Two", "id": "002", "address": null }
-{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" } }
-{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } } }
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299, "review": 5 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
index 8088fff..c67c3cb 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
@@ -1,4 +1,4 @@
-{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 } }
-{ "name": "Person Two", "id": "002", "address": null }
-{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" } }
-{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } } }
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }