This is an automated email from the ASF dual-hosted git repository. mblow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit b99ca94f7d62e51b0806e0615a2876a888ac0e1e Merge: 67fd1f3 e3e4220 Author: Michael Blow <[email protected]> AuthorDate: Fri Mar 5 08:55:24 2021 -0500 Merge branch 'gerrit/cheshire-cat' Change-Id: I6ffd99a066577e26494765f404f8694c3359d8b1 .../operators/physical/AssignBatchPOperator.java | 103 +++++ .../jobgen/QueryLogicalExpressionJobGen.java | 8 +- .../asterix/optimizer/base/RuleCollections.java | 6 +- .../ExtractBatchableExternalFunctionCallsRule.java | 220 +++++++++ .../rules/SetAsterixPhysicalOperatorsRule.java | 61 +++ .../apache/asterix/api/common/APIFramework.java | 4 +- .../asterix/app/translator/QueryTranslator.java | 8 +- .../asterix/test/metadata/MetadataManagerTest.java | 88 +++- .../metadata/MetadataManagerWindowsOsTest.java | 92 ++++ .../bad-ext-function-ddl-1.4.ddl.sqlpp} | 12 +- .../external-library/mysum/mysum.2.ddl.sqlpp | 2 +- .../bad-function-ddl-11.4.ddl.sqlpp} | 15 +- .../resources/runtimets/testsuite_it_sqlpp.xml | 3 +- .../test/resources/runtimets/testsuite_sqlpp.xml | 23 +- .../asterix/common/exceptions/ErrorCode.java | 26 +- .../common/metadata/DatasetFullyQualifiedName.java | 64 +++ .../common/storage/DatasetCopyIdentifier.java | 4 +- .../asterix/common/storage/ResourceReference.java | 61 ++- .../asterix/common/utils/StoragePathUtil.java | 18 +- .../src/main/resources/asx_errormsg/en.properties | 32 +- asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf | 2 +- .../src/main/markdown/builtins/14_window.md | 22 +- .../src/main/markdown/builtins/15_bitwise.md | 1 + .../src/main/markdown/builtins/9_aggregate_sql.md | 4 +- .../main/markdown/datamodel/datamodel_composite.md | 1 + .../datamodel/datamodel_primitive_common.md | 2 +- .../asterix-doc/src/main/markdown/sqlpp/1_intro.md | 3 +- .../asterix-doc/src/main/markdown/sqlpp/2_expr.md | 289 +++++------- .../asterix-doc/src/main/markdown/sqlpp/3_query.md | 515 +++++++++------------ .../src/main/markdown/sqlpp/3_query_title.md | 20 - .../src/main/markdown/sqlpp/4_windowfunctions.md | 136 ++---- .../src/main/markdown/sqlpp/7_ddl_dml.md | 386 +++++++-------- .../src/main/markdown/sqlpp/7_ddl_head.md | 12 +- .../main/markdown/sqlpp/appendix_2_parameters.md | 7 +- .../main/markdown/sqlpp/appendix_3_resolution.md | 10 +- .../main/markdown/sqlpp/appendix_4_manual_data.md | 1 + .../ExternalFunctionDescriptorProvider.java | 19 +- .../library/ExternalScalarFunctionDescriptor.java | 14 +- .../ExternalAssignBatchRuntimeFactory.java | 52 +++ .../apache/asterix/external/util/FeedUtils.java | 4 +- .../asterix-lang-sqlpp/src/main/javacc/SQLPP.jj | 16 +- .../apache/asterix/metadata/MetadataManager.java | 3 +- .../org/apache/asterix/metadata/MetadataNode.java | 283 +++++------ .../metadata/declared/MetadataProvider.java | 13 +- .../apache/asterix/metadata/entities/Dataset.java | 8 + .../functions/ExternalFunctionCompilerUtil.java | 20 + .../apache/asterix/metadata/utils/DatasetUtil.java | 2 +- .../asterix/metadata/utils/MetadataConstants.java | 9 +- .../asterix/metadata/utils/MetadataUtil.java | 6 + .../metadata/utils/SplitsAndConstraintsUtil.java | 9 +- .../apache/asterix/metadata/utils/TypeUtil.java | 2 +- .../om/functions/IExternalFunctionDescriptor.java} | 13 +- asterixdb/asterix-server/pom.xml | 4 +- .../appended-resources/supplemental-models.xml | 6 +- ....com_netty_netty_netty-4.1.59.Final_NOTICE.txt} | 16 +- .../core/algebra/base/PhysicalOperatorTag.java | 2 +- ...POperator.java => AbstractAssignPOperator.java} | 36 +- .../operators/physical/AssignPOperator.java | 84 +--- .../core/algebra/plan/PlanStabilityVerifier.java | 16 +- .../algebra/util/OperatorManipulationUtil.java | 16 +- .../rewriter/rules/ConsolidateAssignsRule.java | 9 + .../rules/SetAlgebricksPhysicalOperatorsRule.java | 2 +- hyracks-fullstack/hyracks/hyracks-api/pom.xml | 4 + .../apache/hyracks/api/util/ExceptionUtils.java | 25 + .../java/org/apache/hyracks/util/MXHelper.java | 3 +- hyracks-fullstack/pom.xml | 2 +- 66 files changed, 1736 insertions(+), 1223 deletions(-) diff --cc asterixdb/asterix-algebra/src/main/java/org/apache/asterix/jobgen/QueryLogicalExpressionJobGen.java index 8707be5,2a662d0..b1d0b47 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/jobgen/QueryLogicalExpressionJobGen.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/jobgen/QueryLogicalExpressionJobGen.java @@@ -138,17 -137,9 +137,14 @@@ public class QueryLogicalExpressionJobG IVariableTypeEnvironment env, IOperatorSchema[] inputSchemas, JobGenContext context) throws AlgebricksException { IScalarEvaluatorFactory[] args = codegenArguments(expr, env, inputSchemas, context); - IFunctionDescriptor fd = null; - IFunctionDescriptor fd = expr.getFunctionInfo() instanceof IExternalFunctionInfo - ? ExternalFunctionDescriptorProvider.resolveExternalFunction(expr, env, context) - : resolveFunction(expr, env, context); ++ IFunctionDescriptor fd; + if (expr.getFunctionInfo() instanceof IExternalFunctionInfo) { + // Expr is an external function - fd = ExternalFunctionDescriptorProvider - .getExternalFunctionDescriptor((IExternalFunctionInfo) expr.getFunctionInfo()); - CompilerProperties props = ((IApplicationContext) context.getAppContext()).getCompilerProperties(); - FunctionTypeInferers.SET_ARGUMENTS_TYPE.infer(expr, fd, env, props); ++ fd = ExternalFunctionDescriptorProvider.resolveExternalFunction(expr, env, context); + } else { + // Expr is an internal (built-in) function + fd = resolveFunction(expr, env, context); + } return fd.createEvaluatorFactory(args); } diff --cc asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 2b4b983,8963f49..e0471ff --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@@ -7808,416 -7803,6 +7808,416 @@@ </compilation-unit> </test-case> </test-group> + <test-group name="array-index"> + <test-group name="array-index/error-handling"> + <test-case FilePath="array-index/error-handling"> + <compilation-unit name="index-two-array-fields"> + <output-dir compare="Text">index-two-array-fields</output-dir> + <expected-error>ASX1079: Compilation error: Cannot create composite index with multiple array fields using different arrays</expected-error> + <expected-error>ASX1079: Compilation error: Cannot create composite index with multiple array fields using different arrays</expected-error> + <source-location>false</source-location> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/error-handling"> + <compilation-unit name="invalid-array-path"> + <output-dir compare="Text">invalid-array-path</output-dir> + <expected-error>ASX0037: Type mismatch: expected value of type array or multiset, but got the value of type CheckinType_checkin_time:</expected-error> + <expected-error>ASX0037: Type mismatch: expected value of type array or multiset, but got the value of type string</expected-error> + <source-location>false</source-location> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/error-handling"> + <compilation-unit name="index-on-closed-array"> + <output-dir compare="Text">index-on-closed-array</output-dir> + <expected-error>ASX1014: Field "date" is not found</expected-error> + <source-location>false</source-location> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/error-handling"> + <compilation-unit name="index-with-enforced-type"> + <output-dir compare="Text">index-with-enforced-type</output-dir> - <expected-error>ASX1140: Incompatible index type ARRAY</expected-error> ++ <expected-error>ASX1154: Incompatible index type ARRAY</expected-error> + <source-location>false</source-location> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/error-handling"> + <compilation-unit name="index-mixed-composite"> + <output-dir compare="Text">index-mixed-composite</output-dir> - <expected-error>ASX1140: Incompatible index type ARRAY</expected-error> ++ <expected-error>ASX1154: Incompatible index type ARRAY</expected-error> + <source-location>false</source-location> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/metadata"> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <!-- <test-case FilePath="array-index/metadata/closed">--> + <!-- <compilation-unit name="with-composite-sk">--> + <!-- <output-dir compare="Text">with-composite-sk</output-dir>--> + <!-- </compilation-unit>--> + <!-- </test-case>--> + <!-- <test-case FilePath="array-index/metadata/open">--> + <!-- <compilation-unit name="with-composite-sk">--> + <!-- <output-dir compare="Text">with-composite-sk</output-dir>--> + <!-- </compilation-unit>--> + <!-- </test-case>--> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="with-composite-array-different-indicators"> + <output-dir compare="Text">with-composite-array-different-indicators</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="with-composite-array-different-indicators"> + <output-dir compare="Text">with-composite-array-different-indicators</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/closed"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/metadata/open"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/bulk-loading/on-index-creation"> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/open"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/open"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/open"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/open"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="with-composite-pk"> + <output-dir compare="Text">with-composite-pk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="with-filter-fields"> + <output-dir compare="Text">with-filter-fields</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/on-index-creation/closed"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/bulk-loading/after-index-creation"> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="with-composite-pk"> + <output-dir compare="Text">with-composite-pk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="with-filter-fields"> + <output-dir compare="Text">with-filter-fields</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/bulk-loading/after-index-creation"> + <compilation-unit name="with-open-index"> + <output-dir compare="Text">with-open-index</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/insert-upsert-delete"> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="with-composite-sk"> + <output-dir compare="Text">with-composite-sk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="with-composite-sk"> + <output-dir compare="Text">with-composite-sk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="with-additional-atomic-index"> + <output-dir compare="Text">with-additional-atomic-index</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/open"> + <compilation-unit name="with-additional-atomic-index"> + <output-dir compare="Text">with-additional-atomic-index</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/insert-upsert-delete/closed"> + <compilation-unit name="with-filter-fields"> + <output-dir compare="Text">with-filter-fields</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/join-unnest-queries"> + <test-case FilePath="array-index/join-unnest-queries"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/join-unnest-queries"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/join-unnest-queries"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/join-unnest-queries"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/join-unnest-queries"> + <compilation-unit name="with-open-index"> + <output-dir compare="Text">with-open-index</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/select-unnest-queries"> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="with-3-level-record-path"> + <output-dir compare="Text">with-3-level-record-path</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="with-composite-sk"> + <output-dir compare="Text">with-composite-sk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/open"> + <compilation-unit name="with-composite-sk"> + <output-dir compare="Text">with-composite-sk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="with-composite-pk"> + <output-dir compare="Text">with-composite-pk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-unnest-queries/closed"> + <compilation-unit name="with-filter-fields"> + <output-dir compare="Text">with-filter-fields</output-dir> + </compilation-unit> + </test-case> + </test-group> + <test-group name="array-index/select-quantified-queries"> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="use-case-1"> + <output-dir compare="Text">use-case-1</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="use-case-2"> + <output-dir compare="Text">use-case-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="use-case-3"> + <output-dir compare="Text">use-case-3</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="use-case-4"> + <output-dir compare="Text">use-case-4</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="with-composite-pk"> + <output-dir compare="Text">with-composite-pk</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array-index/select-quantified-queries"> + <compilation-unit name="with-open-index"> + <output-dir compare="Text">with-open-index</output-dir> + </compilation-unit> + </test-case> + </test-group> + </test-group> <test-group name="nestrecords"> <test-case FilePath="nestrecords"> <compilation-unit name="nestrecord"> diff --cc asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index bcaf0ae,47a388d..0406132 --- 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 @@@ -219,12 -219,20 +219,26 @@@ public enum ErrorCode implements IErro INVALID_HINT(1132), ONLY_SINGLE_AUTHENTICATION_IS_ALLOWED(1133), NO_AUTH_METHOD_PROVIDED(1134), - FULL_TEXT_CONFIG_ALREADY_EXISTS(1135), - FULL_TEXT_FILTER_ALREADY_EXISTS(1136), - FULL_TEXT_CONFIG_NOT_FOUND(1137), - FULL_TEXT_FILTER_NOT_FOUND(1138), - FULL_TEXT_DEFAULT_CONFIG_CANNOT_BE_DELETED_OR_CREATED(1139), - COMPILATION_INCOMPATIBLE_INDEX_TYPE(1140), + NODE_EXISTS(1135), + NODEGROUP_EXISTS(1136), + COMPACTION_POLICY_EXISTS(1137), + EXTERNAL_FILE_EXISTS(1138), + FEED_EXISTS(1139), + FEED_POLICY_EXISTS(1140), + FEED_CONNECTION_EXISTS(1141), + LIBRARY_EXISTS(1142), + UNKNOWN_EXTERNAL_FILE(1143), + UNKNOWN_FEED(1144), + UNKNOWN_FEED_CONNECTION(1145), + UNKNOWN_FEED_POLICY(1146), + CANNOT_DROP_DATAVERSE_DEPENDENT_EXISTS(1147), + CANNOT_DROP_OBJECT_DEPENDENT_EXISTS(1148), ++ FULL_TEXT_CONFIG_ALREADY_EXISTS(1149), ++ FULL_TEXT_FILTER_ALREADY_EXISTS(1150), ++ FULL_TEXT_CONFIG_NOT_FOUND(1151), ++ FULL_TEXT_FILTER_NOT_FOUND(1152), ++ FULL_TEXT_DEFAULT_CONFIG_CANNOT_BE_DELETED_OR_CREATED(1153), ++ COMPILATION_INCOMPATIBLE_INDEX_TYPE(1154), // Feed errors DATAFLOW_ILLEGAL_STATE(3001), diff --cc asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties index f8f00db,50f6458..cc56ede --- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties +++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties @@@ -219,14 -219,22 +219,28 @@@ 1130 = Illegal use of RIGHT OUTER JOIN 1131 = A synonym with this name %1$s already exists 1132 = Invalid specification for hint %1$s. %2$s - 1133 = Full-text filter %1$s not found - 1134 = Default full-text config with a name of null cannot be deleted or created - 1135 = Full-text config %1$s already exists - 1136 = Full-text filter %1$s already exists - 1137 = Full-text config %1$s not found - 1138 = Only a single authentication method is allowed: connectionString, accountName & accountKey, or accountName & sharedAccessSignature - 1139 = No authentication parameters provided - 1140 = Incompatible index type %1$s + 1133 = Only a single authentication method is allowed: connectionString, accountName & accountKey, or accountName & sharedAccessSignature + 1134 = No authentication parameters provided + 1135 = A node with this name %1$s already exists + 1136 = A node group with this name %1$s already exists + 1137 = A compaction policy with this name %1$s already exists + 1138 = A external file with this number %1$s already exists in dataset %2$s + 1139 = A feed with this name %1$s already exists + 1140 = A feed policy with this name %1$s already exists + 1141 = A feed connection between feed %1$s and dataset %2$s already exists + 1142 = A library with this name %1$s already exists + 1143 = Cannot find external file with number %1$s in dataset %2$s + 1144 = Cannot find feed with name %1$s + 1145 = Cannot find feed connection between feed %1$s and dataset %2$s + 1146 = Cannot find feed policy with name %1$s + 1147 = Cannot drop dataverse: %1$s %2$s being used by %3$s %4$s + 1148 = Cannot drop %1$s %2$s being used by %3$s %4$s ++1149 = Full-text config %1$s already exists ++1150 = Full-text filter %1$s already exists ++1151 = Full-text config %1$s not found ++1152 = Full-text filter %1$s not found ++1153 = Default full-text config with a name of null cannot be deleted or created ++1154 = Incompatible index type %1$s # Feed Errors 3001 = Illegal state. diff --cc asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md index b591b3e,e064f06..b2b893b --- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md +++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md @@@ -312,32 -295,23 +295,29 @@@ the URL and path needed to locate the d #### <a id="Indices">Create Index</a> - --- - ### CreateIndex - **** + ##### CreateIndex +  - ### CreateSecondaryIndex - **** + ##### CreateSecondaryIndex +  - ### CreatePrimaryKeyIndex - **** + ##### CreatePrimaryKeyIndex +  - ### IndexedElement ++##### IndexedElement +**** + - ### ArrayIndexElement ++##### ArrayIndexElement +**** + - ### IndexField + ##### IndexField - +**** - ### NestedField - **** + ##### NestedField +  - ### IndexType - **** - - --- + ##### IndexType +  The `CREATE INDEX` statement creates a secondary index on one or more fields of a specified dataset. Supported index types include `BTREE` for totally ordered datatypes, `RTREE` for spatial data, @@@ -383,22 -355,15 +363,22 @@@ The following example creates a btree i a nested field residing within a object-valued user field in the `orders` dataset. This index can be useful for accelerating exact-match queries, range search queries, and joins involving the nested `orderUserName` field. -Such nested fields must be singular, i.e., one cannot index through (or on) an array-valued field. - #### Example + ##### Example CREATE INDEX oOrderUserNameIdx ON orders(order.orderUserName) TYPE BTREE; +The following example creates an array index called `oItemsPriceIdx` on the `price` field inside the `items` array of the `orders` dataset. +This index can be useful for accelerating membership queries, existential or universal quantification queries, or joins involving the `price` field inside this array. +(To enable array index query optimization, be sure to set the [`arrayindex` compiler option](manual.html#ArrayIndexFlag).) + +#### Example + + CREATE INDEX oItemsPriceIdx ON orders(UNNEST items SELECT price); + The following example creates an open rtree index called `oOrderLocIdx` on the order-location field of the `orders` dataset. This index can be useful for accelerating queries that use the [`spatial-intersect` function](builtins.html#spatial_intersect) in a predicate involving the sender-location field. - #### Example + ##### Example CREATE INDEX oOrderLocIDx ON orders(`order-location` : point?) TYPE RTREE ENFORCED; diff --cc asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java index 20c852a,a481f99..699ad74 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java @@@ -627,141 -622,6 +626,141 @@@ public abstract class MetadataManager i } @Override + public void addFullTextFilter(MetadataTransactionContext mdTxnCtx, FullTextFilterMetadataEntity filter) + throws AlgebricksException { + try { + metadataNode.addFullTextFilter(mdTxnCtx.getTxnId(), filter); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + mdTxnCtx.addFullTextFilter(filter); + } + + @Override + public void dropFullTextFilter(MetadataTransactionContext mdTxnCtx, DataverseName dataverseName, String filterName) + throws AlgebricksException { + try { + metadataNode.dropFullTextFilter(mdTxnCtx.getTxnId(), dataverseName, filterName); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + mdTxnCtx.dropFullTextFilter(dataverseName, filterName); + } + + @Override + public FullTextFilterMetadataEntity getFullTextFilter(MetadataTransactionContext ctx, DataverseName dataverseName, + String filterName) throws AlgebricksException { + // First look in the context to see if this transaction created the + // requested full-text filter itself (but the full-text filter is still uncommitted). + FullTextFilterMetadataEntity filter = ctx.getFullTextFilter(dataverseName, filterName); + if (filter != null) { + // Don't add this filter to the cache, since it is still + // uncommitted. + return filter; + } + + if (ctx.fullTextFilterIsDropped(dataverseName, filterName)) { + // Filter has been dropped by this transaction but could still be + // in the cache. + return null; + } + + if (ctx.getDataverse(dataverseName) != null) { + // This transaction has dropped and subsequently created the same + // dataverse. + return null; + } + + filter = cache.getFullTextFilter(dataverseName, filterName); + if (filter != null) { + // filter is already in the cache, don't add it again. + return filter; + } + + try { + filter = metadataNode.getFullTextFilter(ctx.getTxnId(), dataverseName, filterName); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + // We fetched the filter from the MetadataNode. Add it to the cache + // when this transaction commits. + if (filter != null) { + ctx.addFullTextFilter(filter); + } + return filter; + } + + @Override + public void addFullTextConfig(MetadataTransactionContext mdTxnCtx, + FullTextConfigMetadataEntity configMetadataEntity) throws AlgebricksException { + if (Strings.isNullOrEmpty(configMetadataEntity.getFullTextConfig().getName())) { - throw new AsterixException(ErrorCode.FULL_TEXT_CONFIG_ALREADY_EXISTS); ++ throw new MetadataException(ErrorCode.FULL_TEXT_CONFIG_ALREADY_EXISTS); + } + + try { + metadataNode.addFullTextConfig(mdTxnCtx.getTxnId(), configMetadataEntity); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + mdTxnCtx.addFullTextConfig(configMetadataEntity); + } + + @Override + public FullTextConfigMetadataEntity getFullTextConfig(MetadataTransactionContext ctx, DataverseName dataverseName, + String configName) throws AlgebricksException { + // First look in the context to see if this transaction created the + // requested full-text config itself (but the full-text config is still uncommitted). + FullTextConfigMetadataEntity configMetadataEntity = ctx.getFullTextConfig(dataverseName, configName); + if (configMetadataEntity != null) { + // Don't add this config to the cache, since it is still + // uncommitted. + return configMetadataEntity; + } + + if (ctx.fullTextConfigIsDropped(dataverseName, configName)) { + // config has been dropped by this transaction but could still be + // in the cache. + return null; + } + + if (ctx.getDataverse(dataverseName) != null) { + // This transaction has dropped and subsequently created the same + // dataverse. + return null; + } + + configMetadataEntity = cache.getFullTextConfig(dataverseName, configName); + if (configMetadataEntity != null) { + // config is already in the cache, don't add it again. + return configMetadataEntity; + } + + try { + configMetadataEntity = metadataNode.getFullTextConfig(ctx.getTxnId(), dataverseName, configName); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + + // We fetched the config from the MetadataNode. Add it to the cache + // when this transaction commits. + if (configMetadataEntity != null) { + ctx.addFullTextConfig(configMetadataEntity); + } + return configMetadataEntity; + } + + @Override + public void dropFullTextConfig(MetadataTransactionContext mdTxnCtx, DataverseName dataverseName, String configName) + throws AlgebricksException { + try { + metadataNode.dropFullTextConfig(mdTxnCtx.getTxnId(), dataverseName, configName); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + mdTxnCtx.dropFullTextConfig(dataverseName, configName); + } + + @Override public void addFeedPolicy(MetadataTransactionContext mdTxnCtx, FeedPolicyEntity feedPolicy) throws AlgebricksException { try { diff --cc asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java index 72b3e9a,088bbc6..37aae78 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java @@@ -33,7 -32,7 +34,8 @@@ import org.apache.asterix.common.api.IN import org.apache.asterix.common.config.DatasetConfig.DatasetType; import org.apache.asterix.common.config.DatasetConfig.IndexType; import org.apache.asterix.common.dataflow.LSMIndexUtil; + import org.apache.asterix.common.exceptions.AsterixException; +import org.apache.asterix.common.exceptions.MetadataException; import org.apache.asterix.common.functions.FunctionSignature; import org.apache.asterix.common.metadata.DataverseName; import org.apache.asterix.common.metadata.MetadataIndexImmutableProperties; @@@ -1332,25 -1133,10 +1352,26 @@@ public class MetadataNode implements IM for (Function function : functions) { for (Triple<DataverseName, String, String> datasetDependency : function.getDependencies().get(2)) { if (datasetDependency.first.equals(dataverseName) && datasetDependency.second.equals(dataTypeName)) { - throw new AlgebricksException( - "Cannot drop type " + TypeUtil.getFullyQualifiedDisplayName(dataverseName, dataTypeName) - + " is being used by function " + function.getSignature()); + throw new AsterixException( + org.apache.asterix.common.exceptions.ErrorCode.CANNOT_DROP_OBJECT_DEPENDENT_EXISTS, "type", + TypeUtil.getFullyQualifiedDisplayName(dataverseName, dataTypeName), "function", + function.getSignature()); + } + } + } + } + + private void confirmFullTextFilterCanBeDeleted(TxnId txnId, DataverseName dataverseName, String fullTextFilterName) + throws AlgebricksException { + List<FullTextConfigMetadataEntity> configMetadataEntities = getDataverseFullTextConfigs(txnId, dataverseName); + for (FullTextConfigMetadataEntity configMetadataEntity : configMetadataEntities) { + FullTextConfigDescriptor config = configMetadataEntity.getFullTextConfig(); + for (String filterName : config.getFilterNames()) { + if (filterName.equals(fullTextFilterName)) { + throw new AlgebricksException("Cannot drop full-text filter " + + TypeUtil.getFullyQualifiedDisplayName(dataverseName, fullTextFilterName) + + " being used by full-text config " + + TypeUtil.getFullyQualifiedDisplayName(dataverseName, config.getName())); } } }
