This is an automated email from the ASF dual-hosted git repository.
htowaileb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git
The following commit(s) were added to refs/heads/master by this push:
new a81ffc8dda [ASTERIXDB-3294][EXT]: Fail if there are conflicting types
for computed fields
a81ffc8dda is described below
commit a81ffc8dda2bbe0f9eff856591178d14b1c7970b
Author: Hussain Towaileb <[email protected]>
AuthorDate: Wed Nov 1 08:43:16 2023 +0300
[ASTERIXDB-3294][EXT]: Fail if there are conflicting types for computed
fields
Change-Id: I936c7afbf7e95271ede2230c08c7841a27995a21
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17896
Reviewed-by: Hussain Towaileb <[email protected]>
Reviewed-by: Wail Alkowaileet <[email protected]>
Integration-Tests: Jenkins <[email protected]>
Tested-by: Jenkins <[email protected]>
---
.../test.000.ddl.sqlpp} | 12 ++---
.../test.001.ddl.sqlpp} | 2 +-
.../test.002.ddl.sqlpp} | 2 +-
.../test.999.ddl.sqlpp} | 11 +---
.../duplicate-field/test.005.ddl.sqlpp | 2 +-
.../parquet/duplicate-field/test.005.ddl.sqlpp | 2 +-
...stsuite_external_dataset_azure_blob_storage.xml | 22 +++++---
.../runtimets/testsuite_external_dataset_s3.xml | 30 +++++++----
.../asterix/common/exceptions/ErrorCode.java | 1 +
.../src/main/resources/asx_errormsg/en.properties | 3 +-
.../asterix/external/util/ExternalDataPrefix.java | 63 +++++++++++++++++++---
11 files changed, 103 insertions(+), 47 deletions(-)
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.000.ddl.sqlpp
similarity index 75%
copy from
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
copy to
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.000.ddl.sqlpp
index 1c6fa81d6c..0e265e3998 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.000.ddl.sqlpp
@@ -17,13 +17,9 @@
* under the License.
*/
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
USE test;
-CREATE EXTERNAL DATASET test1(test) USING %adapter% (
- %template%,
- ("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
- ("embed-filter-values" = "true"),
- ("format"="json")
-);
-
+CREATE TYPE test AS {
+};
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.001.ddl.sqlpp
similarity index 92%
copy from
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
copy to
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.001.ddl.sqlpp
index 1c6fa81d6c..14230dc661 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.001.ddl.sqlpp
@@ -22,7 +22,7 @@ USE test;
CREATE EXTERNAL DATASET test1(test) USING %adapter% (
%template%,
("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
+ ("definition"="{person.name.first:string}/{person.name:string}"),
("embed-filter-values" = "true"),
("format"="json")
);
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.002.ddl.sqlpp
similarity index 92%
copy from
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
copy to
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.002.ddl.sqlpp
index 1c6fa81d6c..18a03a1033 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.002.ddl.sqlpp
@@ -22,7 +22,7 @@ USE test;
CREATE EXTERNAL DATASET test1(test) USING %adapter% (
%template%,
("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
+ ("definition"="{person.name:string}/{person.name.first:string}"),
("embed-filter-values" = "true"),
("format"="json")
);
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.999.ddl.sqlpp
similarity index 74%
copy from
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
copy to
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.999.ddl.sqlpp
index 1c6fa81d6c..36b2bab543 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/conflicted-fields/test.999.ddl.sqlpp
@@ -17,13 +17,4 @@
* under the License.
*/
-USE test;
-
-CREATE EXTERNAL DATASET test1(test) USING %adapter% (
- %template%,
- ("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
- ("embed-filter-values" = "true"),
- ("format"="json")
-);
-
+DROP DATAVERSE test IF EXISTS;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
index 1c6fa81d6c..1316e3fd9c 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/duplicate-field/test.005.ddl.sqlpp
@@ -22,7 +22,7 @@ USE test;
CREATE EXTERNAL DATASET test1(test) USING %adapter% (
%template%,
("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
+ ("definition"="{a.b:int}/foo/{a.b:string}"),
("embed-filter-values" = "true"),
("format"="json")
);
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/parquet/duplicate-field/test.005.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/parquet/duplicate-field/test.005.ddl.sqlpp
index 0e1157f8c6..03b043a1a1 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/parquet/duplicate-field/test.005.ddl.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-dataset/common/dynamic-prefixes/parquet/duplicate-field/test.005.ddl.sqlpp
@@ -22,7 +22,7 @@ USE test;
CREATE EXTERNAL DATASET test1(test) USING %adapter% (
%template%,
("container"="dynamic-prefix-at-start-container"),
- ("definition"="{a.b:int}/foo/{a.b.c:int}/{a.b.c.d:int}-{a.b.c.d:int}/"),
+ ("definition"="{a.b:int}/foo/{a.b:string}"),
("embed-filter-values" = "true"),
("format"="parquet")
);
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_azure_blob_storage.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_azure_blob_storage.xml
index 7322b1ac8f..af0ae36829 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_azure_blob_storage.xml
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_azure_blob_storage.xml
@@ -284,13 +284,13 @@
<compilation-unit name="type-mismatch">
<placeholder name="adapter" value="AZUREBLOB" />
<output-dir compare="Text">type-mismatch</output-dir>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/accounting/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'accounting'. Reason:
'java.lang.NumberFormatException: For input string:
"accounting"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/engineering/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'engineering'. Reason:
'java.lang.NumberFormatException: For input string:
"engineering"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/hr/0.json'. Computed Field Name: 'name'. Computed
Field Type: 'bigint'. Computed Field Value: 'hr'. Reason:
'java.lang.NumberFormatException: For input string: "hr"'</expected-warn>
+ <expected-warn>In the file
'external-filter/department/accounting/0.json' the expected type for the 'name'
field is 'bigint' but the value 'accounting' was found instead.</expected-warn>
+ <expected-warn>In the file
'external-filter/department/engineering/0.json' the expected type for the
'name' field is 'bigint' but the value 'engineering' was found
instead.</expected-warn>
+ <expected-warn>In the file 'external-filter/department/hr/0.json' the
expected type for the 'name' field is 'bigint' but the value 'hr' was found
instead.</expected-warn>
<expected-warn>The provided external dataset configuration returned no
files from the external source</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/accounting/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'accounting'. Reason:
'java.lang.NumberFormatException: For input string:
"accounting"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/engineering/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'engineering'. Reason:
'java.lang.NumberFormatException: For input string:
"engineering"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/hr/0.json'. Computed Field Name: 'name'. Computed
Field Type: 'bigint'. Computed Field Value: 'hr'. Reason:
'java.lang.NumberFormatException: For input string: "hr"'</expected-warn>
+ <expected-warn>In the file
'external-filter/department/accounting/0.json' the expected type for the 'name'
field is 'bigint' but the value 'accounting' was found instead.</expected-warn>
+ <expected-warn>In the file
'external-filter/department/engineering/0.json' the expected type for the
'name' field is 'bigint' but the value 'engineering' was found
instead.</expected-warn>
+ <expected-warn>In the file 'external-filter/department/hr/0.json' the
expected type for the 'name' field is 'bigint' but the value 'hr' was found
instead.</expected-warn>
<expected-warn>The provided external dataset configuration returned no
files from the external source</expected-warn>
</compilation-unit>
</test-case>
@@ -356,7 +356,15 @@
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
- <expected-error>Duplicate field name 'a.b.c.d'</expected-error>
+ <expected-error>Duplicate field name 'a.b'</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="external-dataset/common/dynamic-prefixes">
+ <compilation-unit name="conflicted-fields">
+ <placeholder name="adapter" value="AZUREBLOB" />
+ <output-dir compare="Text">conflicted-fields</output-dir>
+ <expected-error>A computed field cannot have more than one type.
'person.name' is both 'string' and 'object'.</expected-error>
+ <expected-error>A computed field cannot have more than one type.
'person.name' is both 'string' and 'object'.</expected-error>
</compilation-unit>
</test-case>
<!-- Dynamic prefixes tests end -->
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
index 5b53b41430..bd9e6cacae 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_external_dataset_s3.xml
@@ -291,13 +291,13 @@
<compilation-unit name="type-mismatch">
<placeholder name="adapter" value="S3" />
<output-dir compare="Text">type-mismatch</output-dir>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/accounting/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'accounting'. Reason:
'java.lang.NumberFormatException: For input string:
"accounting"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/engineering/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'engineering'. Reason:
'java.lang.NumberFormatException: For input string:
"engineering"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/hr/0.json'. Computed Field Name: 'name'. Computed
Field Type: 'bigint'. Computed Field Value: 'hr'. Reason:
'java.lang.NumberFormatException: For input string: "hr"'</expected-warn>
+ <expected-warn>In the file
'external-filter/department/accounting/0.json' the expected type for the 'name'
field is 'bigint' but the value 'accounting' was found instead.</expected-warn>
+ <expected-warn>In the file
'external-filter/department/engineering/0.json' the expected type for the
'name' field is 'bigint' but the value 'engineering' was found
instead.</expected-warn>
+ <expected-warn>In the file 'external-filter/department/hr/0.json' the
expected type for the 'name' field is 'bigint' but the value 'hr' was found
instead.</expected-warn>
<expected-warn>The provided external dataset configuration returned no
files from the external source</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/accounting/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'accounting'. Reason:
'java.lang.NumberFormatException: For input string:
"accounting"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/engineering/0.json'. Computed Field Name: 'name'.
Computed Field Type: 'bigint'. Computed Field Value: 'engineering'. Reason:
'java.lang.NumberFormatException: For input string:
"engineering"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'external-filter/department/hr/0.json'. Computed Field Name: 'name'. Computed
Field Type: 'bigint'. Computed Field Value: 'hr'. Reason:
'java.lang.NumberFormatException: For input string: "hr"'</expected-warn>
+ <expected-warn>In the file
'external-filter/department/accounting/0.json' the expected type for the 'name'
field is 'bigint' but the value 'accounting' was found instead.</expected-warn>
+ <expected-warn>In the file
'external-filter/department/engineering/0.json' the expected type for the
'name' field is 'bigint' but the value 'engineering' was found
instead.</expected-warn>
+ <expected-warn>In the file 'external-filter/department/hr/0.json' the
expected type for the 'name' field is 'bigint' but the value 'hr' was found
instead.</expected-warn>
<expected-warn>The provided external dataset configuration returned no
files from the external source</expected-warn>
</compilation-unit>
</test-case>
@@ -383,7 +383,15 @@
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
- <expected-error>Duplicate field name 'a.b.c.d'</expected-error>
+ <expected-error>Duplicate field name 'a.b'</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="external-dataset/common/dynamic-prefixes">
+ <compilation-unit name="conflicted-fields">
+ <placeholder name="adapter" value="S3" />
+ <output-dir compare="Text">conflicted-fields</output-dir>
+ <expected-error>A computed field cannot have more than one type.
'person.name' is both 'string' and 'object'.</expected-error>
+ <expected-error>A computed field cannot have more than one type.
'person.name' is both 'string' and 'object'.</expected-error>
</compilation-unit>
</test-case>
<test-case FilePath="external-dataset/common/dynamic-prefixes/parquet">
@@ -396,9 +404,9 @@
<compilation-unit name="type-mismatch">
<placeholder name="adapter" value="S3" />
<output-dir compare="Text">type-mismatch</output-dir>
- <expected-warn>Failed to evaluate computed field. File:
'parquet-data/external-filter/department/accounting/0.parquet'. Computed Field
Name: 'name'. Computed Field Type: 'bigint'. Computed Field Value:
'accounting'. Reason: 'java.lang.NumberFormatException: For input string:
"accounting"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'parquet-data/external-filter/department/engineering/0.parquet'. Computed Field
Name: 'name'. Computed Field Type: 'bigint'. Computed Field Value:
'engineering'. Reason: 'java.lang.NumberFormatException: For input string:
"engineering"'</expected-warn>
- <expected-warn>Failed to evaluate computed field. File:
'parquet-data/external-filter/department/hr/0.parquet'. Computed Field Name:
'name'. Computed Field Type: 'bigint'. Computed Field Value: 'hr'. Reason:
'java.lang.NumberFormatException: For input string: "hr"'</expected-warn>
+ <expected-warn>In the file
'parquet-data/external-filter/department/accounting/0.parquet' the expected
type for the 'name' field is 'bigint' but the value 'accounting' was found
instead.</expected-warn>
+ <expected-warn>In the file
'parquet-data/external-filter/department/engineering/0.parquet' the expected
type for the 'name' field is 'bigint' but the value 'engineering' was found
instead.</expected-warn>
+ <expected-warn>In the file
'parquet-data/external-filter/department/hr/0.parquet' the expected type for
the 'name' field is 'bigint' but the value 'hr' was found
instead.</expected-warn>
<expected-warn>The provided external dataset configuration returned no
files from the external source</expected-warn>
</compilation-unit>
</test-case>
@@ -458,7 +466,7 @@
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
<expected-error>Duplicate field name 'year'</expected-error>
- <expected-error>Duplicate field name 'a.b.c.d'</expected-error>
+ <expected-error>Duplicate field name 'a.b'</expected-error>
</compilation-unit>
</test-case>
<test-case FilePath="external-dataset/common/dynamic-prefixes/csv">
diff --git
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 0c3d8cacf0..f780ee1d44 100644
---
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -288,6 +288,7 @@ public enum ErrorCode implements IError {
CANNOT_DROP_DATABASE_DEPENDENT_EXISTS(1187),
UNSUPPORTED_WRITING_ADAPTER(1188),
UNSUPPORTED_WRITING_FORMAT(1189),
+ COMPUTED_FIELD_CONFLICTING_TYPE(1190),
// Feed errors
DATAFLOW_ILLEGAL_STATE(3001),
diff --git
a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index 1d48e1e12d..0da70b26e7 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -283,13 +283,14 @@
1180 = Error reading iceberg data
1181 = Unsupported computed field type: '%1$s'
1182 = Failed to calculate computed fields: %1$s
-1183 = Failed to evaluate computed field. File: '%1$s'. Computed Field Name:
'%2$s'. Computed Field Type: '%3$s'. Computed Field Value: '%4$s'. Reason:
'%5$s'
+1183 = In the file '%1$s' the expected type for the '%2$s' field is '%3$s' but
the value '%4$s' was found instead.
1184 = Compilation error: %1$s: %2$s dataset is not supported on datasets with
meta records
1185 = Cannot find database with name %1$s
1186 = A database with this name %1$s already exists
1187 = Cannot drop database: %1$s %2$s being used by %3$s %4$s
1188 = Unsupported writing adapter '%1$s'. Supported adapters: %2$s
1189 = Unsupported writing format '%1$s'. Supported formats: %2$s
+1190 = A computed field cannot have more than one type. '%1$s' is both '%2$s'
and 'object'.
# Feed Errors
3001 = Illegal state.
diff --git
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataPrefix.java
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataPrefix.java
index 7eefc8ab2e..0ed0622052 100644
---
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataPrefix.java
+++
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataPrefix.java
@@ -57,6 +57,7 @@ public final class ExternalDataPrefix implements Serializable
{
private final List<String> segments;
private final List<String> computedFieldNames = new ArrayList<>();
+ private final Map<String, ATypeTag> computedFieldsParts = new HashMap<>();
private final List<IAType> computedFieldTypes = new ArrayList<>();
private final List<Integer> computedFieldSegmentIndexes = new
ArrayList<>();
private final List<ARecordType> paths = new ArrayList<>();
@@ -154,26 +155,24 @@ public final class ExternalDataPrefix implements
Serializable {
String namePart = splits[0].substring(1);
String typePart = splits[1].substring(0,
splits[1].length() - 1);
- // ensure no duplicate fields
- if (computedFieldNames.contains(namePart)) {
- throw new
CompilationException(ErrorCode.DUPLICATE_FIELD_NAME, namePart);
- }
-
// ensure supported type
IAType type = BuiltinTypeMap.getBuiltinType(typePart);
if (type == null) {
throw new
CompilationException(ErrorCode.UNSUPPORTED_COMPUTED_FIELD_TYPE, typePart);
}
-
type = getUpdatedType(type);
validateSupported(type.getTypeTag());
+ // ensure no issues with the incoming computed field
+ validateConflictingFields(namePart, type.getTypeTag());
+
computedFieldNames.add(namePart);
computedFieldTypes.add(type);
computedFieldSegmentIndexes.add(i);
updateIndexToComputedFieldMap(i, namePart, type);
List<String> nameParts = List.of(namePart.split("\\."));
+ addNameParts(nameParts, type.getTypeTag());
paths.add(ProjectionFiltrationTypeUtil.getPathRecordType(nameParts));
expression.append("(.+)");
@@ -188,6 +187,58 @@ public final class ExternalDataPrefix implements
Serializable {
}
}
+ /**
+ * Adds the computed field parts with their respective types.
+ * Given the following computed field: {person.name.first:string}, the
following is added to the map:
+ * person -> object
+ * person.name -> object
+ * person.name.first -> string
+ *
+ * @param nameParts name parts of the computed field
+ * @param type type of the computed field
+ * @throws CompilationException CompilationException
+ */
+ private void addNameParts(List<String> nameParts, ATypeTag type) throws
CompilationException {
+ String concat = "";
+ for (int i = 0; i < nameParts.size() - 1; i++) {
+ concat += nameParts.get(i);
+
+ ATypeTag existingType = computedFieldsParts.get(concat);
+ if (existingType != null && existingType != ATypeTag.OBJECT) {
+ throw new
CompilationException(ErrorCode.COMPUTED_FIELD_CONFLICTING_TYPE, concat,
existingType);
+ }
+ computedFieldsParts.putIfAbsent(concat, ATypeTag.OBJECT);
+ concat += ".";
+ }
+
+ concat += nameParts.get(nameParts.size() - 1);
+ computedFieldsParts.put(concat, type);
+ }
+
+ /**
+ * This will ensure that the incoming computed field is not conflicting
with an existing computed field. For example:
+ * existing computed field: {person.name:string}
+ * incoming computed field: {person.name.first:string}
+ * <p>
+ * This should fail as person.name.first is expecting person.name to be an
object, but it is a string
+ *
+ * @param name computed field name
+ * @param type computed field type
+ * @throws CompilationException CompilationException
+ */
+ private void validateConflictingFields(String name, ATypeTag type) throws
CompilationException {
+ ATypeTag existingType = computedFieldsParts.get(name);
+
+ // the provided computed field already exists, check if duplicate or
conflicting
+ if (existingType != null) {
+ if (existingType == ATypeTag.OBJECT) {
+ throw new
CompilationException(ErrorCode.COMPUTED_FIELD_CONFLICTING_TYPE, name, type);
+ } else {
+ throw new CompilationException(ErrorCode.DUPLICATE_FIELD_NAME,
name);
+ }
+ }
+ }
+
private void updateIndexToComputedFieldMap(int segmentIndex, String
computedFieldName, IAType computedFieldType) {
if (indexToComputedFieldsMap.containsKey(segmentIndex)) {
PrefixSegment prefixSegment =
indexToComputedFieldsMap.get(segmentIndex);