You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by al...@apache.org on 2021/12/07 10:16:21 UTC
[ignite] branch sql-calcite updated (271390d -> 422e993)
This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a change to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git.
from 271390d IGNITE-12695 MERGE operator support - Fixes #9581.
add 2d67297 IGNITE-15732 Thin client: Fix transaction failure after timeout - Fixes #9504.
add 57315bf IGNITE-15831 Fix broken documentation link to the new-metrics-system (#9532)
add f0e3a64 IGNITE-15800 Fixed an issue that could lead to incorrect working of the IgniteLock after reconnecting the client node. Fixes #9513
add ef72651 IGNITE-15843 Do not print corrupted persistent data structure message for in-memory data region (#9538)
add a3ac617 IGNITE-15830 Fix performance suggestion when Ignite is run with a jdk other than 8x (#9533)
add d011f8e IGNITE-15854 Removes documentation notes about Ignite 2.10 and earlier support for spring-cache and spring-tx integrations. (#9546)
add bb33ebb IGNITE-15849 Remove idle verify and snapshot check ambiguity error output (#9543)
add 5c189a9 IGNITE-15848 Fixed consistency issue for persistence atomic cache. Fixes #9541
add 5fe73f0 IGNITE-15698 fix hang query when table is dropped concurrently (unhandled exception at the GridMapQueryExecutor#onQueryRequest) (#9506)
add 4a4195e IGNITE-15715 Missed values should be checked by Read Repair (#9505)
add 1be3b2e IGNITE-15637 CPP: Remove separate JNI module and move it to Core - Fixes #9521.
add 400827e IGNITE-15826: set storetype JKS for ducktests. (#9528)
add 4b1e8a9 IGNITE-15865: fixed persistence_upgrade_test.py (#9548)
add d9ced43 IGNITE-15862 Fix kubernetes ConfigMap docs on site (#9549)
add 1730bff IGNITE-15802 Remove duplicated code for affinity cache (#9519)
add 0f3102b IGNITE-15820 .NET: Fix thin client streamer not creating SQL table entries (#9531)
add 876a2ca IGNITE-15855 BinaryObjectBuilder builds invalid object in case the original object contains several collection or reference fields (#9547)
add c59ec1e IGNITE-15807 Java thin: follow user-defined endpoint order, try default port first (#9522)
add 19ac10d IGNITE-15530 IndexQuery uses MergeSort (#9540)
add 025cc9f IGNITE-15745 Add docs for IndexQuery (#9545)
add 0c5cb48 IGNITE-15702 Control.sh consistency check command should support status option (#9529)
add 7785089 IGNITE-15801 Annotation-based injection of ServiceContext. (#9542)
add 855fa17 IGNITE-15868 Unexpected command: PROBE when authorization is enabled (#9551)
add 1649eb2 IGNITE-15882 isInfoEnabled() check before logging on info level - Fixes #9555.
add ab68683 IGNITE-15895 ServiceContextResource javadoc fix. (#9560)
add dc25b35 IGNITE-15873 Fixed jetty-server configuration files. Fixes #9558
add 2e649da IGNITE-15134 Added documentation for SQL statistics functionality. Fixes #9556
add 60852ca IGNITE-15183 Thin client: Add requests thread pool monitoring - Fixes #9525.
add 2b0ee2d IGNITE-15911 Move sysprop for inline recommendation to IgniteSystemProperties (#9562)
add d110e5f IGNITE-15845 .NET: Fix TypeNameParser to ignore escaped characters in compiler-generated type names (#9564)
add 39d23aa IGNITE-15844 BusyExecutor allow task be executed after deactive/activate. (#9544)
add 95c8c6b IGNITE-15794 Implement request attributes support for java services - Fixes #9510.
add c4f8d04 IGNITE-15890: [ducktests] added ignite version 2.11.0 to Docker file and set it as LATEST (#9559)
add 5255324 IGNITE-15915 .NET: Allow null SslStreamFactory.CertificatePath (#9566)
add 4692f8d IGNITE-15917 Increase timeout for test. (#9563)
add e560cff IGNITE-14294 .NET: Fix ClientServerCompatibilityTest flakiness (#9567)
add 35a6e5b IGNITE-13558 Partitions restore process parallelization on node startup - Fixes #9327.
add 2831d65 IGNITE-15591 Update description of initiator-updated cache metrics (#9478)
add 5cebca6 IGNITE-15781 GridDhtPartitionMap#get use primitive int (#9518)
add 2e7235d IGNITE-15943 Fix comparison inlined fields with decimal search key (#9573)
add 69a68ea IGNITE-15954 .NET: Fix dynamic assemblies handling in TypeResolver (#9574)
add da2a4ec IGNITE-14744 Restore snapshot taken on different topologies (#9539)
add 9c04b2a IGNITE-15941 Fixed flaky test Flaky test FailureProcessorThreadDumpThrottlingTest.testThrottlingPerFailureType
add cca909c IGNITE-15795 .NET: Add ServiceCallContext (#9526)
add 620ee3f IGNITE-15924 Thin client cache for OptimizedMarshaller class names (#9576)
add 6c8e0bf IGNITE-15950 Added ability to hide sensitive argument for external tools. Fixes #9572
add 7eb396c IGNITE-15767 Fixed spontaneous SocketTimeoutException in server socket accept (JDK-8247750). (#9498)
add 83b517a IGNITE-15951 Fixes preconfigured service deployment authorization. (#9582)
add 625d110 IGNITE-14354 Disabled optimisation in case of constants in subquery. (#9585)
add 24da935 IGNITE-15973 Logging at WARN level changed to INFO when writing checkpoint pages - Fixes #9583.
add 4e1477f IGNITE-15986 .NET: Fix ClientConnectionTest.TestFailover flakiness (#9597)
add df36f11 IGNITE-15233 Move snapshot tests to dedicated suite with applying scale factor (#9584)
add 9021f78 IGNITE-15348 Checkstyle checks whitespace after cast token, connected issues are solved. - Fixes #9568.
add c726cf1 IGNITE-15968 Index de-fragmentation fails on DECIMAL and VARCHAR columns (#9580)
add 499e5ef IGNITE-15990 Fixed B+Tree corruption during concurrent replace and remove. (#9602)
add 0941c49 IGNITE-15968 Fix checkstyle (#9608)
add 6389f44 IGNITE-15985 Fix some test in Disk Page Compressions (#9605)
add 3993634 IGNITE-15758 Remove legacy service grid implementation (#9577)
add 57de2b5d IGNITE-16002 The remove cache method should update statistics if the method returns true (#9609)
add 7adda7a IGNITE-15537 Add new PersistenceBasicCompatibilityTest for 2.9, 2.10, 2.11 releases (#9420)
add 48ed770 IGNITE-16019 Fix check of SERVICE_DEPLOY permission (#9616)
add 85bb788 IGNITE-15921 Thin client: drop connection on invalid handshake without allocating buffer (#9610)
add 5526739 IGNITE-15887 Updated wording in Javadoc related to checkpoint frequency. Fixes #9557
add 29f9c54 IGNITE-15987 Generate create table sql key type by original column type. (#9600)
add 7cc4f10 IGNITE-15978 Support binary HANLDEs by BinaryObjectBuilder (#9590)
add e9a1b8c IGNITE-16036 testFunctionNpe no more failures on current H2, unignore it. - Fixes #9621.
add fd51111 IGNITE-16014 Add snapshot thread pool configuration (#9615)
add ec614d0 IGNITE-15515 Add exclusive find for BPlusTree (#9613)
add f8a42c0 IGNITE-16027 IGNITE_WAIT_FOR_BACKUPS_ON_SHUTDOWN system property is deprecated. Fixes #9617
add 7032df3 IGNITE-13804 Java thin: avoid buffer copy on send (#9622)
add 072b26f IGNITE-16045 Add documentation pages for the snapshot thread pool size property (#9624)
add 914c5dd IGNITE-14742 BinaryArray introduced (#9490)
new 422e993 Merge remote-tracking branch 'remotes/upstream/master' into sql-calcite
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
assembly/release-apache-ignite-base.xml | 6 -
checkstyle/checkstyle.xml | 2 +-
docs/_data/toc.yaml | 6 +-
docs/_docs/SQL/sql-statistics.adoc | 182 ++
docs/_docs/code-deployment/peer-class-loading.adoc | 4 +-
.../apache/ignite/snippets/UsingScanQueries.java | 75 +
.../k8s/stateful/node-configuration.xml | 4 +-
.../k8s/stateless/node-configuration.xml | 4 +-
docs/_docs/code-snippets/xml/jetty.xml | 2 +-
.../collocated-computations.adoc | 2 +-
docs/_docs/events/events.adoc | 6 +-
.../spring/spring-caching.adoc | 83 +-
.../spring/spring-tx.adoc | 89 +-
docs/_docs/images/svg/analyze_bnf1.svg | 188 ++
docs/_docs/images/svg/analyze_bnf2.svg | 168 ++
docs/_docs/images/svg/drop_bnf.svg | 188 ++
docs/_docs/images/svg/refresh_bnf.svg | 188 ++
...-scan-queries.adoc => using-cache-queries.adoc} | 60 +-
docs/_docs/monitoring-metrics/metrics.adoc | 2 +-
docs/_docs/monitoring-metrics/new-metrics.adoc | 24 +-
docs/_docs/monitoring-metrics/system-views.adoc | 74 +-
.../thread-pools-tuning.adoc | 8 +
docs/_docs/services/services.adoc | 6 +-
docs/_docs/snapshots/snapshots.adoc | 15 +-
docs/_docs/sql-reference/ddl.adoc | 83 +
docs/_docs/thin-clients/java-thin-client.adoc | 6 +-
docs/_docs/tools/control-script.adoc | 73 +-
.../examples/datagrid/CacheQueryExample.java | 50 +-
.../ANNClassificationExportImportExample.java | 4 +-
...domForestClassificationExportImportExample.java | 2 +-
...onTreeClassificationTrainerSQLTableExample.java | 2 +-
.../org/apache/ignite/examples/model/Person.java | 9 +-
.../examples/servicegrid/SimpleMapServiceImpl.java | 11 +-
.../gridify/aop/aspectj/GridifyAspectJAspect.java | 4 +-
.../aop/aspectj/GridifySetToSetAspectJAspect.java | 4 +-
.../aspectj/GridifySetToValueAspectJAspect.java | 4 +-
.../org/apache/ignite/gridify/AbstractAopTest.java | 22 +-
.../internal/benchmarks/jmh/algo/BenchmarkCRC.java | 2 +-
.../query/calcite/CalciteQueryProcessor.java | 4 +-
.../query/calcite/RemoteFragmentKey.java | 4 +-
.../query/calcite/exec/ExchangeServiceImpl.java | 8 +-
.../query/calcite/exec/ExecutionServiceImpl.java | 6 +-
.../processors/query/calcite/exec/IndexScan.java | 2 +-
.../query/calcite/exec/LogicalRelImplementor.java | 4 +-
.../query/calcite/exec/MailboxRegistryImpl.java | 4 +-
.../query/calcite/exec/exp/IgniteSqlFunctions.java | 2 +-
.../query/calcite/exec/exp/RexExecutorImpl.java | 2 +-
.../query/calcite/exec/exp/agg/GroupKey.java | 2 +-
.../processors/query/calcite/exec/rel/Inbox.java | 6 +-
.../query/calcite/message/MessageServiceImpl.java | 8 +-
.../query/calcite/message/MessageType.java | 2 +-
.../query/calcite/metadata/IgniteMdCollation.java | 4 +-
.../calcite/metadata/IgniteMdColumnOrigins.java | 4 +-
.../calcite/metadata/IgniteMdDistribution.java | 4 +-
.../processors/query/calcite/prepare/CacheKey.java | 2 +-
.../processors/query/calcite/prepare/Cloner.java | 50 +-
.../calcite/prepare/IgniteConvertletTable.java | 2 +-
.../query/calcite/prepare/IgnitePlanner.java | 2 +-
.../calcite/prepare/IgniteSqlToRelConvertor.java | 12 +-
.../query/calcite/prepare/IgniteSqlValidator.java | 8 +-
.../calcite/rule/LogicalScanConverterRule.java | 2 +-
.../query/calcite/schema/TableDescriptorImpl.java | 12 +-
.../calcite/sql/IgniteSqlIntervalTypeNameSpec.java | 2 +-
.../query/calcite/trait/CorrelationTrait.java | 2 +-
.../query/calcite/trait/DistributionFunction.java | 2 +-
.../query/calcite/trait/DistributionTrait.java | 8 +-
.../processors/query/calcite/trait/TraitUtils.java | 2 +-
.../processors/query/calcite/util/Commons.java | 8 +-
.../processors/query/calcite/util/RexUtils.java | 2 +-
.../calcite/exec/rel/ContinuousExecutionTest.java | 4 +-
.../ServerStatisticsIntegrationTest.java | 4 +-
.../planner/CorrelatedSubqueryPlannerTest.java | 2 +-
.../query/calcite/planner/PlannerTest.java | 6 +-
.../cache/store/cassandra/CassandraCacheStore.java | 2 +-
.../store/cassandra/common/CassandraHelper.java | 2 +-
.../persistence/PersistenceController.java | 2 +-
.../org/apache/ignite/tests/pojos/Product.java | 2 +-
.../apache/ignite/tests/pojos/ProductOrder.java | 2 +-
.../ignite/tests/utils/TestCacheSession.java | 2 +-
.../org/apache/ignite/tests/utils/TestsHelper.java | 2 +-
.../jdbc2/JdbcAbstractDmlStatementSelfTest.java | 2 +-
.../ignite/internal/jdbc2/JdbcSpringSelfTest.java | 2 +-
.../rest/ClientMemcachedProtocolSelfTest.java | 8 +-
.../rest/JettyRestProcessorAbstractSelfTest.java | 61 +-
.../processors/rest/TestMemcacheClient.java | 12 +-
.../rest/protocols/tcp/TcpRestParserSelfTest.java | 2 +-
.../thin/JdbcThinAbstractDmlStatementSelfTest.java | 2 +-
.../thin/JdbcThinAutoCloseServerCursorTest.java | 2 +-
.../JdbcThinCacheToJdbcDataTypesCoverageTest.java | 4 +-
.../resources/jetty/rest-jetty-ssl-client-auth.xml | 2 +-
.../src/test/resources/jetty/rest-jetty-ssl.xml | 2 +-
.../src/test/resources/jetty/router-jetty-ssl.xml | 2 +-
.../src/test/resources/jetty/router-jetty.xml | 2 +-
.../persistence/IndexTypesCompatibilityTest.java | 4 +-
.../InlineJavaObjectCompatibilityTest.java | 2 +-
.../MoveBinaryMetadataCompatibility.java | 2 +-
.../PersistenceBasicCompatibilityTest.java | 18 +
.../internal/commandline/CommandHandler.java | 10 +-
.../commandline/argument/parser/CLIArgument.java | 2 +-
.../consistency/ConsistencyCommand.java | 17 +-
.../consistency/ConsistencySubCommand.java | 6 +-
.../commandline/indexreader/IgniteIndexReader.java | 4 +-
.../IgniteIndexReaderFilePageStoreFactoryImpl.java | 2 +-
.../util/GridCommandHandlerAbstractTest.java | 4 +-
.../util/GridCommandHandlerIndexingTest.java | 2 +-
.../util/GridCommandHandlerPropertiesTest.java | 2 +-
.../apache/ignite/util/GridCommandHandlerTest.java | 12 +-
.../ignite/util/KillCommandsCommandShTest.java | 40 +-
.../java/org/apache/ignite/IgniteServices.java | 49 +
.../org/apache/ignite/IgniteSystemProperties.java | 41 +-
.../eviction/sorted/SortedEvictionPolicy.java | 2 +-
.../org/apache/ignite/cache/query/IndexQuery.java | 9 +-
.../store/jdbc/JdbcTypesDefaultTransformer.java | 2 +-
.../configuration/DataStorageConfiguration.java | 2 +-
.../ignite/configuration/IgniteConfiguration.java | 34 +-
.../apache/ignite/internal/GridKernalContext.java | 4 +-
.../ignite/internal/GridKernalContextImpl.java | 15 +-
.../ignite/internal/GridTaskSessionImpl.java | 2 +-
.../ignite/internal/IgniteDiagnosticMessage.java | 2 +-
.../org/apache/ignite/internal/IgniteKernal.java | 40 +-
.../ignite/internal/IgniteNodeAttributes.java | 4 -
.../apache/ignite/internal/IgniteServicesEx.java | 54 +
.../apache/ignite/internal/IgniteServicesImpl.java | 74 +-
.../org/apache/ignite/internal/IgnitionEx.java | 3 +
.../ignite/internal/MarshallerContextImpl.java | 2 +-
.../ignite/internal/ThreadPoolMXBeanAdapter.java | 2 +-
.../apache/ignite/internal/binary/BinaryArray.java | 282 +++
.../internal/binary/BinaryClassDescriptor.java | 10 +-
.../ignite/internal/binary/BinaryContext.java | 4 +-
.../ignite/internal/binary/BinaryEnumArray.java | 64 +
.../ignite/internal/binary/BinaryEnumCache.java | 2 +-
.../ignite/internal/binary/BinaryObjectImpl.java | 10 +-
.../internal/binary/BinaryObjectOffheapImpl.java | 4 +-
.../ignite/internal/binary/BinaryReaderExImpl.java | 18 +-
.../binary/BinarySerializedFieldComparator.java | 9 +-
.../apache/ignite/internal/binary/BinaryUtils.java | 101 +-
.../ignite/internal/binary/BinaryWriterExImpl.java | 38 +-
.../internal/binary/BinaryWriterSchemaHolder.java | 6 +-
.../internal/binary/GridBinaryMarshaller.java | 2 +-
.../binary/builder/BinaryBuilderReader.java | 12 +-
.../binary/builder/BinaryBuilderSerializer.java | 33 +
.../binary/builder/BinaryObjectBuilderImpl.java | 8 +
.../binary/streams/BinaryHeapOutputStream.java | 24 +
.../internal/cache/query/index/IndexProcessor.java | 2 +-
.../cache/query/index/IndexQueryProcessor.java | 255 ++-
.../DecimalIndexKey.java => IndexQueryResult.java} | 41 +-
.../cache/query/index/IndexQueryResultMeta.java | 90 +
.../DurableBackgroundCleanupIndexTreeTask.java | 1 +
.../query/index/sorted/IndexKeyDefinition.java | 35 +-
.../query/index/sorted/IndexKeyTypeSettings.java | 26 +-
.../query/index/sorted/IndexRowCompartorImpl.java | 8 -
.../query/index/sorted/SortedSegmentedIndex.java | 24 +-
.../sorted/defragmentation/DefragIndexFactory.java | 101 +-
.../defragmentation/IndexingDefragmentation.java | 25 +-
.../index/sorted/inline/InlineIndexFactory.java | 2 +-
.../query/index/sorted/inline/InlineIndexImpl.java | 9 +-
.../query/index/sorted/inline/InlineIndexTree.java | 6 +-
.../sorted/inline/InlineObjectBytesDetector.java | 2 +-
.../index/sorted/inline/InlineRecommender.java | 10 +-
.../sorted/inline/InlineTreeFilterClosure.java | 2 +-
.../sorted/inline/io/AbstractInlineInnerIO.java | 8 +-
.../sorted/inline/io/AbstractInlineLeafIO.java | 8 +-
.../index/sorted/inline/io/AbstractInnerIO.java | 6 +-
.../index/sorted/inline/io/AbstractLeafIO.java | 6 +-
.../query/index/sorted/inline/io/IORowHandler.java | 4 +-
.../inline/types/BooleanInlineIndexKeyType.java | 8 +-
.../inline/types/ByteInlineIndexKeyType.java | 8 +-
.../inline/types/BytesInlineIndexKeyType.java | 10 +-
.../inline/types/DateInlineIndexKeyType.java | 6 +-
.../inline/types/DoubleInlineIndexKeyType.java | 8 +-
.../inline/types/FloatInlineIndexKeyType.java | 8 +-
.../inline/types/IntegerInlineIndexKeyType.java | 8 +-
.../inline/types/LongInlineIndexKeyType.java | 8 +-
.../inline/types/NullableInlineIndexKeyType.java | 12 +-
.../types/ObjectByteArrayInlineIndexKeyType.java | 4 +-
.../inline/types/ObjectHashInlineIndexKeyType.java | 4 +-
.../inline/types/ShortInlineIndexKeyType.java | 6 +-
.../inline/types/StringInlineIndexKeyType.java | 28 +-
.../types/StringNoCompareInlineIndexKeyType.java | 2 +-
.../inline/types/TimeInlineIndexKeyType.java | 6 +-
.../inline/types/TimestampInlineIndexKeyType.java | 6 +-
.../inline/types/UuidInlineIndexKeyType.java | 8 +-
.../query/index/sorted/keys/BooleanIndexKey.java | 4 +-
.../query/index/sorted/keys/ByteIndexKey.java | 4 +-
.../query/index/sorted/keys/BytesIndexKey.java | 4 +-
.../query/index/sorted/keys/DecimalIndexKey.java | 2 +-
.../query/index/sorted/keys/DoubleIndexKey.java | 4 +-
.../query/index/sorted/keys/FloatIndexKey.java | 4 +-
.../query/index/sorted/keys/IndexKeyFactory.java | 24 +-
.../query/index/sorted/keys/IntegerIndexKey.java | 4 +-
.../index/sorted/keys/JavaObjectIndexKey.java | 4 +-
.../query/index/sorted/keys/LongIndexKey.java | 4 +-
.../query/index/sorted/keys/ShortIndexKey.java | 4 +-
.../index/sorted/keys/SignedBytesIndexKey.java | 4 +-
.../query/index/sorted/keys/StringIndexKey.java | 2 +-
.../query/index/sorted/keys/UuidIndexKey.java | 2 +-
.../internal/client/thin/ClientComputeImpl.java | 10 +-
.../internal/client/thin/PayloadOutputChannel.java | 15 +-
.../internal/client/thin/ReliableChannel.java | 52 +-
.../internal/client/thin/TcpClientChannel.java | 18 +-
.../internal/client/thin/TcpIgniteClient.java | 3 +
.../internal/client/thin/io/ClientConnection.java | 4 +-
.../io/gridnioserver/GridNioClientConnection.java | 8 +-
.../internal/events/DiscoveryCustomEvent.java | 4 +-
.../internal/jdbc/thin/JdbcThinResultSet.java | 26 +-
.../internal/jdbc/thin/JdbcThinStatement.java | 2 +-
.../ignite/internal/jdbc2/JdbcResultSet.java | 26 +-
.../internal/maintenance/MaintenanceFileStore.java | 2 +-
.../communication/AbstractTransmission.java | 4 +-
.../managers/communication/FileReceiver.java | 3 +-
.../managers/communication/GridIoManager.java | 30 +-
.../communication/GridIoMessageFactory.java | 4 +
.../communication/IgniteMessageFactoryImpl.java | 2 +-
.../communication/TransmissionHandler.java | 7 +-
.../deployment/GridDeploymentClassLoader.java | 2 +-
.../managers/discovery/GridDiscoveryManager.java | 28 +-
.../optimized/OptimizedClassDescriptor.java | 2 +-
.../ignite/internal/mem/file/MappedFile.java | 4 +-
.../apache/ignite/internal/pagemem/PageUtils.java | 2 +-
.../wal/record/PartitionClearingStartRecord.java | 98 +
.../internal/pagemem/wal/record/WALRecord.java | 5 +-
.../wal/record/delta/RotatedIdPartRecord.java | 2 +-
.../affinity/GridAffinityAssignmentCache.java | 22 +-
.../processors/affinity/GridAffinityUtils.java | 2 +-
.../cache/CacheAffinitySharedManager.java | 97 +-
.../processors/cache/CacheGroupContext.java | 25 +-
.../processors/cache/CacheGroupDescriptor.java | 2 +-
.../processors/cache/CacheInvokeResult.java | 2 +-
.../processors/cache/CacheMetricsImpl.java | 30 +-
.../processors/cache/CacheMetricsSnapshot.java | 8 +-
.../processors/cache/CacheObjectUtils.java | 6 +-
.../processors/cache/ClusterCachesInfo.java | 10 +-
.../internal/processors/cache/ExchangeActions.java | 4 +-
.../cache/GatewayProtectedCacheProxy.java | 16 +-
.../processors/cache/GridCacheAdapter.java | 68 +-
.../processors/cache/GridCacheContext.java | 2 +-
.../processors/cache/GridCacheContextInfo.java | 2 +-
.../processors/cache/GridCacheIoManager.java | 4 +-
.../processors/cache/GridCacheMvccManager.java | 2 +-
.../cache/GridCachePartitionExchangeManager.java | 6 +-
.../processors/cache/GridCacheProcessor.java | 176 +-
.../internal/processors/cache/GridCacheReturn.java | 4 +-
.../internal/processors/cache/GridCacheUtils.java | 16 +
.../cache/IgniteCacheOffheapManager.java | 23 +-
.../cache/IgniteCacheOffheapManagerImpl.java | 31 +-
.../processors/cache/IgniteCacheProxyImpl.java | 12 +-
.../internal/processors/cache/WalStateManager.java | 2 +-
.../binary/CacheObjectBinaryProcessorImpl.java | 43 +-
.../distributed/GridDistributedCacheAdapter.java | 6 +-
.../GridDistributedTxRemoteAdapter.java | 4 +-
.../dht/CacheDistributedGetFutureAdapter.java | 7 +
.../cache/distributed/dht/GridDhtLockFuture.java | 2 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 2 +-
.../distributed/dht/atomic/GridDhtAtomicCache.java | 2 +-
.../dht/preloader/GridDhtPartitionMap.java | 4 +-
.../preloader/GridDhtPartitionsExchangeFuture.java | 6 +-
.../dht/topology/GridDhtLocalPartition.java | 28 +-
.../dht/topology/GridDhtPartitionTopologyImpl.java | 2 +-
.../dht/topology/PartitionsEvictManager.java | 34 +-
.../cache/distributed/near/GridNearCacheEntry.java | 2 +-
...dNearOptimisticSerializableTxPrepareFuture.java | 2 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 6 +-
.../near/GridNearSingleGetResponse.java | 2 +-
.../near/GridNearTxQueryEnlistRequest.java | 13 +-
.../GridNearReadRepairCheckOnlyFuture.java | 55 +-
.../near/consistency/GridNearReadRepairFuture.java | 72 +-
.../cache/local/atomic/GridLocalAtomicCache.java | 4 +-
.../processors/cache/mvcc/MvccProcessorImpl.java | 6 +-
.../processors/cache/mvcc/MvccVersionImpl.java | 6 +-
.../processors/cache/mvcc/txlog/TxKey.java | 6 +-
.../processors/cache/mvcc/txlog/TxLogTree.java | 2 +-
.../AbstractCorruptedPersistenceException.java | 106 -
...n.java => CorruptedDataStructureException.java} | 46 +-
.../CorruptedPartitionMetaPageException.java | 31 +-
.../cache/persistence/DataRegionMetricsImpl.java | 2 +-
.../persistence/DataRegionMetricsMXBeanImpl.java | 4 +-
.../GridCacheDatabaseSharedManager.java | 84 +-
.../cache/persistence/GridCacheOffheapManager.java | 177 +-
.../checkpoint/CheckpointPagesWriter.java | 7 +-
.../defragmentation/IgniteDefragmentationImpl.java | 2 +-
.../cache/persistence/file/AbstractFileIO.java | 2 +-
.../cache/persistence/file/EncryptionUtil.java | 8 +-
.../cache/persistence/file/FilePageStore.java | 2 +-
.../persistence/file/FilePageStoreManager.java | 32 +-
.../freelist/CorruptedFreeListException.java | 38 +-
.../persistence/pagemem/PagesWriteThrottle.java | 2 +-
.../snapshot/AbstractSnapshotFutureTask.java | 136 ++
.../snapshot/AbstractSnapshotMessage.java | 108 +
.../snapshot/IgniteSnapshotManager.java | 899 ++++++++-
.../snapshot/IgniteSnapshotVerifyException.java | 3 +
.../snapshot/SnapshotFilesFailureMessage.java | 134 ++
.../snapshot/SnapshotFilesRequestMessage.java | 174 ++
.../snapshot/SnapshotFinishedFutureTask.java} | 34 +-
.../persistence/snapshot/SnapshotFutureTask.java | 117 +-
.../persistence/snapshot/SnapshotMetadata.java | 57 +-
.../snapshot/SnapshotPartitionsVerifyHandler.java | 9 +-
.../snapshot/SnapshotResponseRemoteFutureTask.java | 172 ++
.../snapshot/SnapshotRestoreProcess.java | 962 ++++++---
.../cache/persistence/tree/BPlusTree.java | 962 +++++----
.../persistence/tree/CorruptedTreeException.java | 98 +-
.../cache/persistence/tree/io/PageIO.java | 8 +-
.../cache/persistence/tree/io/TrackingPageIO.java | 2 +-
.../persistence/wal/FileWriteAheadLogManager.java | 8 +-
.../wal/reader/StandaloneGridKernalContext.java | 4 +-
.../wal/serializer/RecordDataV1Serializer.java | 34 +-
.../wal/serializer/RecordDataV2Serializer.java | 3 +
.../GridCacheDistributedFieldsQueryFuture.java | 4 +-
.../query/GridCacheDistributedQueryFuture.java | 33 +-
.../query/GridCacheDistributedQueryManager.java | 30 +-
.../query/GridCacheLocalFieldsQueryFuture.java | 4 +-
.../cache/query/GridCacheLocalQueryManager.java | 8 +-
.../cache/query/GridCacheQueryFutureAdapter.java | 36 +-
.../cache/query/GridCacheQueryManager.java | 73 +-
.../cache/query/GridCacheQueryResponse.java | 42 +-
.../query/jdbc/GridCacheQueryJdbcMetadataTask.java | 2 +-
.../cache/query/reducer/CacheQueryReducer.java | 9 +-
.../cache/query/reducer/IndexQueryReducer.java | 149 ++
.../query/reducer/MergeSortCacheQueryReducer.java | 20 +-
.../reducer/TextQueryReducer.java} | 39 +-
.../cache/transactions/IgniteTxManager.java | 2 +-
.../processors/cache/tree/AbstractDataLeafIO.java | 2 +-
.../cache/verify/IdleVerifyResultV2.java | 54 +-
.../cache/version/GridCacheVersionManager.java | 12 +-
.../processors/cluster/BaselineTopology.java | 2 +-
.../cluster/BaselineTopologyHistory.java | 2 +-
.../cluster/GridClusterStateProcessor.java | 11 +-
.../continuous/GridContinuousProcessor.java | 8 +-
.../datastructures/AtomicDataStructureProxy.java | 2 +-
.../datastructures/DataStructuresProcessor.java | 21 +-
.../DistributedCollectionMetadata.java | 4 +-
.../processors/datastructures/GridCacheLockEx.java | 7 +
.../datastructures/GridCacheLockImpl.java | 14 +-
.../processors/diagnostic/DiagnosticProcessor.java | 33 +-
.../processors/failure/FailureProcessor.java | 29 +-
.../marshaller/GridMarshallerMappingProcessor.java | 6 +-
.../marshaller/MarshallerMappingItem.java | 2 +-
.../processors/metric/GridMetricManager.java | 14 +-
.../odbc/ClientListenerNioMessageParser.java | 16 +-
.../processors/odbc/ClientListenerProcessor.java | 20 +-
.../internal/processors/odbc/ClientMessage.java | 72 +-
.../processors/odbc/jdbc/JdbcRequestHandler.java | 2 +-
.../processors/odbc/jdbc/JdbcResultWithIo.java | 2 +-
.../processors/odbc/odbc/OdbcColumnMeta.java | 2 +-
.../processors/odbc/odbc/OdbcMessageParser.java | 22 +-
.../processors/odbc/odbc/OdbcTableMeta.java | 2 +-
.../internal/processors/odbc/odbc/OdbcUtils.java | 2 +-
.../processors/platform/PlatformContextImpl.java | 2 +-
.../processors/platform/PlatformProcessorImpl.java | 2 +-
.../processors/platform/cache/PlatformCache.java | 6 +-
.../platform/client/ClientNotification.java | 2 +-
.../platform/client/ClientRequestHandler.java | 6 +-
.../platform/client/ClientResourceRegistry.java | 2 +-
.../client/binary/ClientBinaryTypePutRequest.java | 2 +-
.../cache/ClientCacheConfigurationSerializer.java | 2 +-
.../cache/ClientCacheEntryEventNotification.java | 8 +-
.../cache/ClientCacheGetConfigurationRequest.java | 2 +-
.../cache/ClientCacheQueryContinuousRequest.java | 4 +-
.../cache/ClientCacheSqlFieldsQueryRequest.java | 2 +-
.../client/cache/ClientCacheSqlQueryRequest.java | 2 +-
...lientClusterGroupGetNodesEndpointsResponse.java | 2 +-
.../client/compute/ClientExecuteTaskRequest.java | 2 +-
.../client/service/ClientServiceInvokeRequest.java | 14 +-
.../client/streamer/ClientDataStreamerReader.java | 5 +-
.../platform/client/tx/ClientTxContext.java | 18 +-
.../platform/cluster/PlatformClusterGroup.java | 4 +-
.../platform/compute/PlatformAbstractTask.java | 2 +-
.../platform/compute/PlatformCompute.java | 5 +-
.../datastreamer/PlatformDataStreamer.java | 6 +-
.../platform/dotnet/PlatformDotNetCacheStore.java | 8 +-
.../dotnet/PlatformDotNetConsoleStream.java | 2 +-
.../processors/platform/events/PlatformEvents.java | 2 +-
.../events/PlatformLocalEventListener.java | 2 +-
.../platform/memory/PlatformOutputStreamImpl.java | 4 +-
.../platform/services/PlatformAbstractService.java | 19 +-
.../platform/services/PlatformService.java | 25 +-
.../platform/services/PlatformServices.java | 27 +-
.../platform/utils/PlatformConfigurationUtils.java | 46 +-
.../platform/utils/PlatformFutureUtils.java | 14 +-
.../processors/platform/utils/PlatformUtils.java | 19 +-
.../processors/plugin/IgnitePluginProcessor.java | 4 +-
.../internal/processors/pool/PoolProcessor.java | 72 +
.../processors/query/GridQueryProcessor.java | 15 +-
.../processors/query/QueryTypeDescriptorImpl.java | 20 +-
.../internal/processors/query/QueryUtils.java | 2 +-
.../query/property/QueryBinaryProperty.java | 8 +-
.../processors/query/stat/StatisticsKey.java | 2 +-
.../processors/query/stat/StatisticsTarget.java | 2 +-
.../stat/config/StatisticsColumnOverrides.java | 2 +-
.../processors/resource/GridResourceIoc.java | 6 +-
.../processors/resource/GridResourceProcessor.java | 7 +-
.../resource/GridResourceServiceInjector.java | 55 +-
.../processors/rest/GridRestProcessor.java | 2 +
.../rest/client/message/GridClientCacheBean.java | 2 +-
.../rest/handlers/task/GridTaskCommandHandler.java | 2 +-
.../rest/protocols/tcp/GridMemcachedMessage.java | 2 +-
.../protocols/tcp/GridTcpMemcachedNioListener.java | 2 +-
.../processors/service/GridServiceProcessor.java | 2134 --------------------
.../processors/service/GridServiceProxy.java | 145 +-
.../processors/service/IgniteServiceProcessor.java | 279 ++-
.../ServiceCallContextHolder.java} | 43 +-
.../ServiceCallContextImpl.java} | 70 +-
.../processors/service/ServiceContextImpl.java | 6 +
.../service/ServiceProcessorAdapter.java | 162 --
.../ignite/internal/sql/SqlCommandProcessor.java | 10 +-
.../org/apache/ignite/internal/sql/SqlKeyword.java | 2 +-
.../suggestions/JvmConfigurationSuggestions.java | 4 +-
.../internal/util/GridBoundedLinkedHashSet.java | 2 +-
.../util/GridConcurrentPhantomHashSet.java | 2 +-
.../internal/util/GridConcurrentWeakHashSet.java | 2 +-
.../internal/util/GridPartitionStateMap.java | 2 +-
.../ignite/internal/util/GridStringBuilder.java | 2 +-
.../apache/ignite/internal/util/IgniteUtils.java | 24 +-
.../ignite/internal/util/StripedExecutor.java | 2 +-
.../util/distributed/DistributedProcess.java | 5 +
.../util/io/GridByteArrayOutputStream.java | 2 +-
.../util/io/GridReversedLinesFileReader.java | 2 +-
.../util/ipc/loopback/IpcServerTcpEndpoint.java | 3 +-
.../ipc/shmem/IpcSharedMemoryServerEndpoint.java | 3 +-
.../util/ipc/shmem/IpcSharedMemorySpace.java | 4 +-
.../apache/ignite/internal/util/lang/GridFunc.java | 6 +-
.../ignite/internal/util/nio/GridNioServer.java | 2 +-
.../util/tostring/GridToStringBuilder.java | 6 +-
.../visor/cache/VisorCacheConfiguration.java | 2 +-
.../internal/visor/cache/VisorCacheJdbcType.java | 2 +-
.../visor/consistency/AbstractConsistencyTask.java | 64 +
.../consistency/VisorConsistencyRepairTask.java | 48 +-
.../consistency/VisorConsistencyRepairTaskArg.java | 19 +
.../consistency/VisorConsistencyStatusTask.java | 95 +
...Result.java => VisorConsistencyTaskResult.java} | 2 +-
.../availability/VisorConnectivityTask.java | 2 +-
.../visor/node/VisorGridConfiguration.java | 2 +-
.../visor/persistence/PersistenceTask.java | 2 +-
.../visor/persistence/PersistenceTaskArg.java | 2 +-
.../ignite/internal/visor/util/VisorTaskUtils.java | 4 +-
.../dotnet/PlatformDotNetAffinityFunction.java | 2 +-
.../ignite/resources/ServiceContextResource.java | 65 +
.../apache/ignite/resources/ServiceResource.java | 7 +
.../java/org/apache/ignite/services/Service.java | 75 +-
.../apache/ignite/services/ServiceCallContext.java | 86 +
.../ignite/services/ServiceCallContextBuilder.java | 77 +
.../org/apache/ignite/services/ServiceContext.java | 16 +-
.../spi/ExponentialBackoffTimeoutStrategy.java | 2 +-
.../tcp/TcpCommunicationMetricsListener.java | 4 +-
.../communication/tcp/internal/ConnectionKey.java | 2 +-
.../TcpCommunicationConfigInitializer.java | 50 +-
.../ignite/spi/discovery/tcp/ClientImpl.java | 6 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 63 +-
.../ignite/spi/discovery/tcp/TcpDiscoveryImpl.java | 2 +-
.../discovery/tcp/internal/TcpDiscoveryNode.java | 2 +-
.../tcp/internal/TcpDiscoveryNodesRing.java | 2 +-
.../spi/indexing/IndexingQueryFilterImpl.java | 7 +
.../ignite/startup/cmdline/CommandLineStartup.java | 4 +-
.../org/apache/ignite/stream/StreamAdapter.java | 2 +-
.../java/org/jsr166/ConcurrentLinkedDeque8.java | 8 +-
.../java/org/jsr166/ConcurrentLinkedHashMap.java | 2 +-
.../main/resources/META-INF/classnames.properties | 5 +-
.../ignite/cache/RebalanceCancellationTest.java | 2 +-
.../ignite/cache/ResetLostPartitionTest.java | 4 +-
.../ignite/client/ClientConfigurationTest.java | 2 +-
.../org/apache/ignite/client/ConnectionTest.java | 49 +
.../org/apache/ignite/client/FunctionalTest.java | 58 +-
.../org/apache/ignite/client/IgniteBinaryTest.java | 2 +-
.../java/org/apache/ignite/client/LoadTest.java | 2 +-
.../apache/ignite/client/ReliabilityTestAsync.java | 2 +-
.../ignite/internal/ClusterGroupAbstractTest.java | 4 +-
.../internal/GridDiscoveryEventSelfTest.java | 10 +-
.../ignite/internal/GridDiscoverySelfTest.java | 2 +-
.../ignite/internal/GridKernalTestUtils.java | 2 +-
.../org/apache/ignite/internal/GridMBeansTest.java | 1 +
.../ignite/internal/GridSameVmStartupSelfTest.java | 4 +-
.../ignite/internal/GridTaskTimeoutSelfTest.java | 2 +-
...ientCheckClusterGroupLocalIdAfterReconnect.java | 4 +-
.../internal/IgniteClientReconnectLockTest.java | 178 ++
.../IgniteClientReconnectServicesTest.java | 54 -
.../IgniteSlowClientDetectionSelfTest.java | 2 +-
.../internal/TestRecordingCommunicationSpi.java | 6 +-
.../internal/TransactionsMXBeanImplTest.java | 4 +-
.../internal/binary/AbstractBinaryArraysTest.java | 56 +
.../apache/ignite/internal/binary/AffinityKey.java | 2 +-
.../internal/binary/BinaryArraySelfTest.java | 446 ++++
.../internal/binary/BinaryEnumsSelfTest.java | 38 +-
.../binary/BinaryFieldsAbstractSelfTest.java | 18 +-
.../internal/binary/BinaryMarshallerSelfTest.java | 216 +-
.../BinaryObjectBuilderAdditionalSelfTest.java | 296 ++-
.../BinaryObjectBuilderDefaultMappersSelfTest.java | 17 +-
.../internal/binary/BinaryObjectToStringTest.java | 12 +-
.../BinarySerialiedFieldComparatorSelfTest.java | 2 +-
.../binary/mutabletest/GridBinaryTestClasses.java | 44 +
.../thin/OptimizedMarshallerClassesCachedTest.java | 86 +
.../internal/client/thin/ReliableChannelTest.java | 38 +
.../client/thin/ServicesBinaryArraysTests.java} | 15 +-
.../ignite/internal/client/thin/ServicesTest.java | 17 +
.../ThinClientPartitionAwarenessDiscoveryTest.java | 2 +-
.../FullyConnectedComponentSearcherTest.java | 2 +-
...ectByteBufferStreamImplV2ByteOrderSelfTest.java | 2 +-
.../GridCheckpointManagerAbstractSelfTest.java | 4 +-
.../IgniteCommunicationBalanceTest.java | 6 +-
.../GridDifferentLocalDeploymentSelfTest.java | 6 +-
.../GridDiscoveryManagerAttributesSelfTest.java | 16 +-
.../optimized/OptimizedObjectStreamSelfTest.java | 2 +-
.../cache/AbstractDataTypesCoverageTest.java | 36 +-
.../AtomicCacheAffinityConfigurationTest.java | 2 +-
...acheConfigurationSerializationAbstractTest.java | 2 +-
...eConfigurationSerializationOnDiscoveryTest.java | 10 +-
...heConfigurationSerializationOnExchangeTest.java | 4 +-
.../CacheGroupLocalConfigurationSelfTest.java | 2 +-
...InterceptorPartitionCounterLocalSanityTest.java | 2 +-
...ceptorPartitionCounterRandomOperationsTest.java | 2 +-
.../processors/cache/CacheMetricsManageTest.java | 4 +-
.../cache/CacheNoAffinityExchangeTest.java | 2 +-
.../processors/cache/CacheRebalancingSelfTest.java | 2 +-
.../cache/CacheStoreTxPutAllMultiNodeTest.java | 2 +-
.../CacheStoreUsageMultinodeAbstractTest.java | 2 +-
.../cache/ClientSlowDiscoveryAbstractTest.java | 2 +-
.../ClientSlowDiscoveryTopologyChangeTest.java | 6 +-
.../ClientSlowDiscoveryTransactionRemapTest.java | 2 +-
.../processors/cache/ConcurrentCacheStartTest.java | 2 +-
.../GridAbstractCacheInterceptorRebalanceTest.java | 2 +-
.../cache/GridCacheAbstractMetricsSelfTest.java | 32 +-
.../cache/GridCacheAbstractRemoveFailureTest.java | 2 +-
.../GridCacheConcurrentTxMultiNodeLoadTest.java | 4 +-
.../cache/GridCacheEvictionEventAbstractTest.java | 4 +-
...CacheLongRunningTransactionDiagnosticsTest.java | 2 +-
.../cache/GridCacheOnCopyFlagAbstractSelfTest.java | 2 +-
.../cache/GridCacheQueryEmbeddedValue.java | 2 +-
.../GridCacheStoreManagerDeserializationTest.java | 2 +-
...idCacheTcpClientDiscoveryMultiThreadedTest.java | 4 +-
.../cache/GridLocalIgniteSerializationTest.java | 8 +-
.../GridTransactionsSystemUserTimeMetricsTest.java | 6 +-
.../cache/IgniteCacheAbstractStopBusySelfTest.java | 2 +-
.../IgniteCacheBinaryEntryProcessorSelfTest.java | 2 +-
.../IgniteCacheConfigVariationsFullApiTest.java | 2 +-
.../IgniteCacheEntryListenerAbstractTest.java | 2 +-
.../processors/cache/IgniteCacheGroupsTest.java | 4 +-
.../cache/IgniteCacheInvokeAbstractTest.java | 4 +-
.../cache/IgniteCachePeekModesAbstractTest.java | 14 +-
.../cache/IgniteClientCacheStartFailoverTest.java | 2 +-
...usterActivateDeactivateTestWithPersistence.java | 4 +-
...teDynamicCacheStartCoordinatorFailoverTest.java | 6 +-
.../cache/IgniteIncompleteCacheObjectSelfTest.java | 2 +-
...IgniteMarshallerCacheClassNameConflictTest.java | 2 +-
.../cache/IgniteMarshallerCacheFSRestoreTest.java | 4 +-
.../cache/IgniteTxConfigCacheSelfTest.java | 2 +-
.../cache/IgniteTxMultiNodeAbstractTest.java | 2 +-
.../PartitionsExchangeCoordinatorFailoverTest.java | 14 +-
.../cache/RestorePartitionStateTest.java | 8 +-
.../SetTxTimeoutOnPartitionMapExchangeTest.java | 2 +-
.../cache/TransactionValidationTest.java | 2 +-
.../cache/WalModeChangeAdvancedSelfTest.java | 2 +-
.../cache/WalModeChangeCommonAbstractSelfTest.java | 2 +-
.../binary/BinaryMetadataUpdatesFlowTest.java | 4 +-
...eBinaryObjectMetadataExchangeMultinodeTest.java | 8 +-
.../GridCacheBinaryObjectsAbstractSelfTest.java | 4 +-
...lientNodeBinaryObjectMetadataMultinodeTest.java | 2 +-
.../consistency/AbstractFullSetReadRepairTest.java | 22 +-
.../cache/consistency/AbstractReadRepairTest.java | 112 +-
.../cache/consistency/AtomicReadRepairTest.java | 20 +-
.../ExplicitTransactionalReadRepairTest.java | 20 +-
.../ImplicitTransactionalReadRepairTest.java | 20 +-
.../GridCacheSetAbstractSelfTest.java | 4 +-
.../datastructures/IgniteLockAbstractSelfTest.java | 2 +-
.../IgniteSemaphoreAbstractSelfTest.java | 8 +-
.../GridCachePartitionedNodeRestartTxSelfTest.java | 8 +-
.../distributed/CacheBaselineTopologyTest.java | 6 +-
.../cache/distributed/CacheExchangeMergeTest.java | 4 +-
.../CacheLateAffinityAssignmentTest.java | 2 +-
...CachePartitionLostAfterSupplierHasLeftTest.java | 2 +-
.../GridCachePartitionNotLoadedEventSelfTest.java | 2 +-
.../GridCachePreloadLifecycleAbstractTest.java | 2 +-
.../IgniteCacheClientNodeChangingTopologyTest.java | 2 +-
.../dht/GridCacheColocatedDebugTest.java | 4 +-
.../GridCachePartitionsStateValidationTest.java | 10 +-
...WaitForBackupsOnShutdownSystemPropertyTest.java | 92 +
.../dht/topology/BlockedEvictionsTest.java | 8 +-
...MovingPartitionIsEvictedDuringClearingTest.java | 2 +-
.../dht/topology/PartitionEvictionOrderTest.java | 2 +-
...reloadingRestartWhileClearingPartitionTest.java | 4 +-
.../near/GridCacheNearMetricsSelfTest.java | 12 +-
.../GridCacheNearOnlyMultiNodeFullApiSelfTest.java | 4 +-
.../GridCacheRebalancingOrderingTest.java | 12 +-
.../GridCacheRebalancingPartitionCountersTest.java | 2 +-
.../GridCacheRebalancingWithAsyncClearingTest.java | 4 +-
.../GridCacheReplicatedPreloadSelfTest.java | 4 +-
.../IgniteCacheExpireWhileRebalanceTest.java | 2 +-
.../IgniteCacheExpiryPolicyAbstractTest.java | 4 +-
.../IgniteCacheNoWriteThroughAbstractTest.java | 2 +-
.../cache/mvcc/CacheMvccAbstractFeatureTest.java | 2 +-
.../cache/mvcc/CacheMvccAbstractTest.java | 2 +-
.../cache/mvcc/CacheMvccClientTopologyTest.java | 2 +-
.../cache/mvcc/CacheMvccTxFailoverTest.java | 4 +-
...niteBaselineAffinityTopologyActivationTest.java | 24 +-
...gniteLostPartitionsOnLeaveBaselineSelfTest.java | 2 +-
...gnitePdsBinaryMetadataOnClusterRestartTest.java | 32 +-
.../IgnitePdsCacheAssignmentNodeRestartsTest.java | 10 +-
...CacheConfigurationFileConsistencyCheckTest.java | 8 +-
.../IgnitePdsCacheRebalancingAbstractTest.java | 4 +-
...itePdsCacheStartStopWithFreqCheckpointTest.java | 2 +-
...nitePdsConsistencyOnDelayedPartitionOwning.java | 6 +-
.../persistence/IgnitePdsCorruptedIndexTest.java | 8 +-
.../persistence/IgnitePdsDefragmentationTest.java | 2 +-
.../IgnitePdsRemoveDuringRebalancingTest.java | 1 -
...ocalWalModeChangeDuringRebalancingSelfTest.java | 10 +-
.../MemoryPolicyInitializationTest.java | 2 +-
.../PagesPossibleCorruptionDiagnosticTest.java | 9 +-
.../ClientAffinityAssignmentWithBaselineTest.java | 2 +-
.../persistence/db/IgniteLogicalRecoveryTest.java | 18 +-
...IgnitePdsCacheWalDisabledOnRebalancingTest.java | 20 +-
.../db/IgnitePdsTransactionsHangTest.java | 2 +-
.../db/file/IgnitePdsCheckpointSimpleTest.java | 1 -
.../db/file/IgnitePdsDiskErrorsRecoveringTest.java | 20 +-
.../persistence/db/wal/IgniteWalRebalanceTest.java | 22 +-
.../wal/IgniteWalRecoverySeveralRestartsTest.java | 7 +-
.../db/wal/WalArchiveSizeConfigurationTest.java | 2 +-
.../IgniteAbstractWalIteratorInvalidCrcTest.java | 2 +-
.../defragmentation/DefragmentationMXBeanTest.java | 2 +-
.../persistence/pagemem/FullPageIdTableTest.java | 2 +-
.../IgnitePageMemReplaceDelayedWriteUnitTest.java | 2 +-
.../pagemem/RobinHoodBackwardShiftHashMapTest.java | 2 +-
.../snapshot/AbstractSnapshotSelfTest.java | 98 +-
.../snapshot/IgniteClusterSnapshotCheckTest.java | 5 +-
.../IgniteClusterSnapshotRestoreBaseTest.java | 36 +
.../IgniteClusterSnapshotRestoreSelfTest.java | 77 +-
.../snapshot/IgniteClusterSnapshotSelfTest.java | 10 +-
.../snapshot/IgniteSnapshotManagerSelfTest.java | 33 +-
.../snapshot/IgniteSnapshotRemoteRequestTest.java | 336 +++
.../IgniteSnapshotRestoreFromRemoteTest.java | 374 ++++
.../IgniteSnapshotWithMetastorageTest.java | 3 +-
.../persistence/tree/io/TrackingPageIOTest.java | 4 +-
.../wal/WalEnableDisableWithNodeShutdownTest.java | 2 +-
.../wal/WalEnableDisableWithRestartsTest.java | 4 +-
.../IgniteCacheQueryCacheDestroySelfTest.java | 2 +-
.../CacheContinuousQueryLongP2PTest.java | 2 +-
...heContinuousQueryOperationFromCallbackTest.java | 2 +-
.../CacheContinuousQueryOrderingEventTest.java | 2 +-
.../CacheContinuousQueryRandomOperationsTest.java | 2 +-
.../GridCacheContinuousQueryAbstractSelfTest.java | 9 +-
.../GridCacheContinuousQueryConcurrentTest.java | 2 +-
...cheClientWriteBehindStoreNonCoalescingTest.java | 2 +-
.../AbstractTransactionIntergrityTest.java | 2 +-
.../TxPartitionCounterStateConsistencyTest.java | 97 +-
.../TxRecoveryWithConcurrentRollbackTest.java | 2 +-
.../transactions/TxWithKeyContentionSelfTest.java | 2 +-
.../cluster/ClusterReadOnlyModeSelfTest.java | 2 +-
.../continuous/GridEventConsumeSelfTest.java | 4 +-
.../database/BPlusTreeReplaceRemoveRaceTest.java | 424 ++++
.../processors/database/BPlusTreeSelfTest.java | 36 +-
.../processors/database/IgniteDbAbstractTest.java | 2 +-
.../database/IgniteDbSingleNodeTinyPutGetTest.java | 4 +-
.../database/SwapPathConstructionSelfTest.java | 2 +-
.../datastreamer/DataStreamerImplSelfTest.java | 8 +-
.../diagnostic/DiagnosticProcessorTest.java | 10 +-
.../cache/GridCacheCommandHandlerSelfTest.java | 4 +-
.../query/GridQueryCommandHandlerTest.java | 2 +-
.../security/client/CommonSecurityCheckTest.java | 4 +-
...butedClosureRemoteSecurityContextCheckTest.java | 4 +-
.../impl/TestAdditionalSecurityProcessor.java | 4 +-
.../security/impl/TestSecurityProcessor.java | 2 +-
.../security/service/ServiceAuthorizationTest.java | 430 ++++
.../security/service/ServiceStaticConfigTest.java | 99 +
...dServiceDeploymentExceptionPropagationTest.java | 8 -
.../GridServiceProcessorBatchDeploySelfTest.java | 4 -
.../service/GridServiceProcessorStopSelfTest.java | 7 +-
...GridServiceProxyTopologyInitializationTest.java | 12 +-
.../service/IgniteServiceCallContextTest.java | 238 +++
.../IgniteServiceDynamicCachesSelfTest.java | 21 +-
.../service/IgniteServiceReassignmentTest.java | 138 --
...mentDiscoveryListenerNotificationOrderTest.java | 8 -
...mentNonSerializableStaticConfigurationTest.java | 8 -
.../service/ServiceDeploymentOnActivationTest.java | 8 -
.../ServiceDeploymentOnClientDisconnectTest.java | 8 -
.../ServiceDeploymentProcessAbstractTest.java | 8 -
...ServiceHotRedeploymentViaDeploymentSpiTest.java | 8 -
.../ServiceReassignmentFunctionSelfTest.java | 2 +-
.../internal/sql/SqlParserCreateIndexSelfTest.java | 2 +-
.../JvmConfigurationSuggestionsTest.java | 86 +
.../internal/util/collection/BitSetIntSetTest.java | 6 +-
.../internal/util/collection/IntHashMapTest.java | 4 +-
.../IpcSharedMemoryCrashDetectionSelfTest.java | 2 +-
.../util/ipc/shmem/SharedMemoryTestClient.java | 2 +-
.../ignite/internal/util/nio/GridNioSelfTest.java | 6 +-
.../util/tostring/GridToStringBuilderSelfTest.java | 2 +-
.../direct/multisplit/GridLoadTestJob.java | 2 +-
.../ignite/loadtests/dsi/GridDsiPerfJob.java | 2 +-
.../ignite/loadtests/job/GridJobLoadTestJob.java | 2 +-
.../ignite/marshaller/GridMarshallerTestBean.java | 2 +-
.../marshaller/MarshallerContextSelfTest.java | 12 +-
...2PContinuousDeploymentClientDisconnectTest.java | 6 +-
.../p2p/GridP2PContinuousDeploymentSelfTest.java | 4 +-
.../p2p/GridP2PDoubleDeploymentSelfTest.java | 4 +-
.../ignite/p2p/GridP2PLocalDeploymentSelfTest.java | 2 +-
.../p2p/GridP2PRemoteClassLoadersSelfTest.java | 8 +-
.../apache/ignite/p2p/GridP2PTimeoutSelfTest.java | 4 +-
.../platform/AbstractPlatformServiceCallTask.java | 11 +-
.../ignite/platform/PlatformComputeEchoTask.java | 2 +-
.../ignite/platform/PlatformDeployServiceTask.java | 46 +-
.../platform/PlatformIsPartitionReservedTask.java | 2 +-
.../ignite/platform/PlatformProcessUtils.java | 13 +-
.../ignite/platform/PlatformServiceCallTask.java | 6 +
.../platform/PlatformServiceCallThinTask.java | 4 +
.../PlatformThinClientConnectionsTask.java | 2 +-
.../ignite/platform/javaobject/TestJavaObject.java | 12 +-
.../ignite/plugin/AbstractTestPluginProvider.java | 2 +-
...SharedFsCheckpointSpiMultiThreadedSelfTest.java | 4 +-
.../communication/GridCacheMessageSelfTest.java | 6 +-
...unicationInverseConnectionEstablishingTest.java | 6 +-
...pCommunicationSpiConcurrentConnectSelfTest.java | 2 +-
.../tcp/GridTcpCommunicationSpiLogTest.java | 2 +-
.../spi/discovery/ClusterRebalancedMetricTest.java | 6 +-
.../IgniteDiscoveryCacheReuseSelfTest.java | 4 +-
.../spi/discovery/tcp/IgniteClientConnectTest.java | 2 +-
...cpClientDiscoverySpiFailureTimeoutSelfTest.java | 4 +-
.../tcp/TcpClientDiscoverySpiSelfTest.java | 6 +-
.../tcp/TcpDiscoveryIpFinderFailureTest.java | 2 +-
.../tcp/TcpDiscoveryNodeConsistentIdSelfTest.java | 2 +-
.../spi/discovery/tcp/TcpDiscoverySelfTest.java | 10 +-
.../AbstractTestDependencyResolver.java | 2 +-
.../apache/ignite/testframework/GridTestNode.java | 2 +-
.../apache/ignite/testframework/GridTestUtils.java | 6 +-
.../testframework/config/GridTestProperties.java | 2 +-
.../testframework/junits/GridAbstractTest.java | 2 +-
.../junits/common/GridCommonAbstractTest.java | 12 +-
.../common/GridRollingRestartAbstractTest.java | 2 +-
.../testframework/wal/record/RecordUtils.java | 8 +
.../ignite/testsuites/IgniteBasicTestSuite.java | 6 +-
.../IgniteBasicWithPersistenceTestSuite.java | 17 -
.../testsuites/IgniteBinaryObjectsTestSuite.java | 2 +
.../ignite/testsuites/IgniteCacheTestSuite7.java | 2 +
.../testsuites/IgniteClientReconnectTestSuite.java | 2 +
.../testsuites/IgniteServiceGridTestSuite.java | 2 +
.../ignite/testsuites/IgniteSnapshotTestSuite.java | 48 +
.../ignite/testsuites/SecurityTestSuite.java | 6 +-
.../ignite/thread/ThreadPoolMetricsTest.java | 1 +
...ridCommandHandlerClusterByClassTest_help.output | 4 +
...andHandlerClusterByClassWithSSLTest_help.output | 4 +
.../development/utils/IgniteWalConverter.java | 2 +-
.../utils/IgniteWalConverterArgumentsTest.java | 16 +-
modules/ducktests/tests/certs/functions.sh | 10 +-
modules/ducktests/tests/docker/Dockerfile | 2 +-
.../tests/ignitetest/services/utils/ignite_spec.py | 2 +-
.../ducktests/tests/ignitetest/utils/version.py | 3 +-
.../plugin/PlatformTestPluginProvider.java | 2 +-
.../platform/plugin/PlatformTestPluginTarget.java | 4 +-
.../query/h2/opt/GeoSpatialIndexFactory.java | 2 +-
.../query/h2/opt/GeoSpatialIndexImpl.java | 6 +-
.../processors/query/h2/opt/GeoSpatialUtils.java | 2 +-
.../query/h2/opt/GridH2SpatialIndex.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 2 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 2 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/IgniteEntityDataAccess.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 18 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../hibernate/HibernateAccessStrategyFactory.java | 2 +-
.../managers/systemview/SystemViewLocal.java | 24 +-
.../processors/query/h2/CommandProcessor.java | 12 +-
.../processors/query/h2/ConnectionManager.java | 2 +-
.../query/h2/GridSubqueryJoinOptimizer.java | 10 +-
.../internal/processors/query/h2/H2Utils.java | 24 +-
.../internal/processors/query/h2/QueryParser.java | 2 +-
.../processors/query/h2/database/H2TreeIndex.java | 6 +-
.../processors/query/h2/dml/DmlAstUtils.java | 8 +-
.../internal/processors/query/h2/dml/DmlUtils.java | 10 +-
.../processors/query/h2/dml/UpdatePlan.java | 6 +-
.../processors/query/h2/dml/UpdatePlanBuilder.java | 12 +-
.../processors/query/h2/index/H2RowComparator.java | 15 +-
.../query/h2/index/QueryRowHandlerFactory.java | 2 +-
.../query/h2/index/client/ClientIndexFactory.java | 2 +-
.../query/h2/index/client/ClientInlineIndex.java | 17 +-
.../query/h2/index/keys/DateIndexKey.java | 2 +-
.../query/h2/index/keys/TimeIndexKey.java | 2 +-
.../query/h2/index/keys/TimestampIndexKey.java | 2 +-
.../processors/query/h2/opt/GridH2Table.java | 4 +-
.../query/h2/opt/GridLuceneInputStream.java | 2 +-
.../processors/query/h2/opt/H2IndexCostedBase.java | 6 +-
.../processors/query/h2/sql/GridSqlColumn.java | 2 +-
.../query/h2/sql/GridSqlQueryParser.java | 12 +-
.../processors/query/h2/sql/GridSqlTable.java | 9 +-
.../processors/query/h2/sql/SqlAstTraverser.java | 22 +-
.../query/h2/twostep/GridMapQueryExecutor.java | 85 +-
.../query/h2/twostep/msg/GridH2DmlRequest.java | 3 +-
.../query/h2/twostep/msg/GridH2DmlResponse.java | 3 +-
.../query/h2/twostep/msg/GridH2QueryRequest.java | 3 +-
.../processors/query/stat/BusyExecutor.java | 92 +-
.../processors/query/stat/CancellableTask.java} | 13 +-
.../processors/query/stat/ColumnStatistics.java | 2 +-
.../query/stat/ColumnStatisticsCollector.java | 2 +-
.../internal/processors/query/stat/Hasher.java | 28 +-
.../stat/IgniteStatisticsConfigurationManager.java | 9 +-
.../query/stat/IgniteStatisticsManagerImpl.java | 6 +-
.../stat/IgniteStatisticsPersistenceStoreImpl.java | 2 +-
.../query/stat/ObjectPartitionStatisticsImpl.java | 2 +-
.../query/stat/ObjectStatisticsImpl.java | 2 +-
.../processors/query/stat/StatisticsProcessor.java | 19 +-
.../processors/query/stat/StatisticsUtils.java | 2 +-
.../internal/processors/query/stat/hll/HLL.java | 2 +-
.../query/stat/messages/StatisticsKeyMessage.java | 2 +-
.../visor/verify/ValidateIndexesClosure.java | 10 +-
.../ignite/cache/query/IndexQueryAliasTest.java | 34 +-
.../ignite/cache/query/IndexQueryAllTypesTest.java | 29 +-
.../ignite/cache/query/IndexQueryFailoverTest.java | 8 +-
.../ignite/cache/query/IndexQueryFilterTest.java | 91 +-
.../cache/query/IndexQueryKeepBinaryTest.java | 56 +-
.../ignite/cache/query/IndexQueryLocalTest.java | 4 +-
.../cache/query/IndexQueryQueryEntityTest.java | 23 +-
.../ignite/cache/query/IndexQueryRangeTest.java | 248 +--
.../ignite/cache/query/IndexQuerySqlIndexTest.java | 41 +-
.../ignite/cache/query/MultiTableIndexQuery.java | 28 +-
.../cache/query/MultifieldIndexQueryTest.java | 333 ++-
.../cache/query/RepeatedFieldIndexQueryTest.java | 10 +-
.../org/apache/ignite/client/ClientTestSuite.java | 6 +-
.../apache/ignite/client/FunctionalQueryTest.java | 2 +-
.../ignite/client/IgniteBinaryQueryTest.java | 2 +-
.../org/apache/ignite/client/SecurityTest.java | 4 +-
.../metric/AbstractIndexPageMetricsTest.java | 2 +-
.../ignite/internal/metric/IndexPageCounter.java | 2 +-
.../IndexPagesMetricsPageDisplacementTest.java | 4 +-
.../processors/cache/BigEntryQueryTest.java | 2 +-
.../cache/GridCacheCrossCacheQuerySelfTest.java | 6 +-
.../cache/GridCacheFullTextQueryPagesTest.java | 13 +-
.../IgniteBinaryObjectQueryArgumentsTest.java | 4 +-
.../IgniteCacheAbstractInsertSqlQuerySelfTest.java | 6 +-
.../cache/IgniteCacheAbstractQuerySelfTest.java | 2 +-
.../IgniteCacheAbstractSqlDmlQuerySelfTest.java | 6 +-
.../cache/IgniteCacheUpdateSqlQuerySelfTest.java | 36 +-
.../cache/IgniteClientReconnectQueriesTest.java | 2 +-
.../encryption/EncryptedSqlTemplateTableTest.java | 2 +-
.../cache/index/AbstractIndexingCommonTest.java | 4 +-
.../cache/index/AbstractSchemaSelfTest.java | 4 +-
.../processors/cache/index/ArrayIndexTest.java | 67 +-
.../processors/cache/index/BasicIndexTest.java | 20 +-
.../index/ComplexPrimaryKeyUnwrapSelfTest.java | 43 +
...ransactionsCommandsWithMvccEnabledSelfTest.java | 2 +-
.../cache/index/SqlTransactionsSelfTest.java | 2 +-
.../index/StopNodeOnRebuildIndexFailureTest.java | 4 +-
.../cache/local/IgniteCacheLocalQuerySelfTest.java | 2 +-
.../mvcc/CacheMvccBasicContinuousQueryTest.java | 9 +-
.../mvcc/CacheMvccSqlQueriesAbstractTest.java | 2 +-
.../IgnitePdsIndexingDefragmentationTest.java | 96 +-
.../db/LongDestroyDurableBackgroundTaskTest.java | 2 +-
.../persistence/db/wal/IgniteWalRecoveryTest.java | 4 +-
...niteClusterSnapshotRestoreWithIndexingTest.java | 48 +-
.../query/ScanQueryConcurrentSqlUpdatesTest.java | 2 +-
...niteDbSingleNodeWithIndexingWalRestoreTest.java | 4 +-
.../IgnitePersistentStoreSchemaLoadTest.java | 2 +-
...actQueryTableLockAndConnectionPoolSelfTest.java | 97 +
.../query/IgniteSqlGroupConcatCollocatedTest.java | 2 +-
.../IgniteSqlGroupConcatNotCollocatedTest.java | 4 +-
.../query/IgniteSqlKeyValueFieldsTest.java | 4 +-
.../IgniteSqlQueryDecimalArgumentsWithTest.java | 125 ++
.../query/IgniteSqlSegmentedIndexSelfTest.java | 2 +-
...niteSqlSinglePartitionMultiParallelismTest.java | 6 +-
.../query/IgniteSqlSplitterSelfTest.java | 1 -
...SqlFieldTypeValidationOnKeyValueInsertTest.java | 2 +-
.../query/SqlFieldTypeValidationTypesTest.java | 4 +-
.../query/SqlNotNullKeyValueFieldTest.java | 4 +-
.../processors/query/SqlSchemaSelfTest.java | 2 +-
.../processors/query/SqlSystemViewsSelfTest.java | 2 +-
.../h2/GridSubqueryJoinOptimizerSelfTest.java | 100 +-
.../query/h2/IgniteSqlQueryMinMaxTest.java | 4 +-
.../inlinecolumn/InlineIndexColumnTest.java | 8 +-
.../query/h2/sql/GridQueryParsingTest.java | 8 +-
.../DisappearedCacheCauseRetryMessageSelfTest.java | 2 +-
...DisappearedCacheWasNotFoundMessageSelfTest.java | 2 +-
.../processors/query/stat/BusyExecutorTest.java | 160 +-
.../query/stat/ManagerStatisticsTypesTest.java | 6 +-
.../query/stat/SqlStatisticsCommandTests.java | 4 +-
.../query/stat/StatisticsAbstractTest.java | 2 +-
.../query/stat/StatisticsStorageTest.java | 8 +-
.../query/stat/StatisticsTypesAbstractTest.java | 2 +-
.../ignite/sqltests/SqlDataTypesCoverageTests.java | 7 +
.../IgniteBinaryCacheQueryTestSuite.java | 2 +
.../testsuites/IgnitePdsWithIndexingTestSuite.java | 4 -
.../IgniteSnapshotWithIndexingTestSuite.java} | 18 +-
.../ignite/cache/jta/jndi/CacheJndiTmFactory.java | 2 +-
.../ignite/cache/jta/jndi/CacheJndiTmLookup.java | 2 +-
.../cache/GridJtaLifecycleAwareSelfTest.java | 2 +-
.../TestKubernetesIpFinderDisconnection.java | 4 +-
.../ml/catboost/CatboostClassificationModel.java | 2 +-
.../ml/catboost/CatboostRegressionModel.java | 2 +-
.../org/apache/ignite/ml/h2o/H2OMojoModel.java | 10 +-
.../ignite/ml/composition/boosting/GDBModel.java | 2 +-
.../ignite/ml/dataset/feature/BucketMeta.java | 6 +-
.../impl/bootstrapping/BootstrappedVector.java | 2 +-
.../cache/util/DatasetAffinityFunctionWrapper.java | 2 +-
.../parallelism/DefaultParallelismStrategy.java | 2 +-
.../ignite/ml/inference/json/JacksonHelper.java | 2 +-
.../storage/model/DefaultModelStorage.java | 10 +-
.../ignite/ml/knn/ann/ANNClassificationModel.java | 2 +-
.../math/distances/WeightedMinkowskiDistance.java | 2 +-
.../storage/VectorizedViewMatrixStorage.java | 4 +-
.../discrete/DiscreteNaiveBayesTrainer.java | 2 +-
.../gaussian/GaussianNaiveBayesTrainer.java | 2 +-
.../onehotencoder/OneHotEncoderPreprocessor.java | 2 +-
.../normalization/NormalizationTrainer.java | 2 +-
.../logistic/LogisticRegressionSGDTrainer.java | 6 +-
.../ml/selection/cv/AbstractCrossValidation.java | 8 +-
.../org/apache/ignite/ml/structures/Dataset.java | 4 +-
.../partition/LabelPartitionDataBuilderOnHeap.java | 2 +-
.../apache/ignite/ml/util/genetic/Chromosome.java | 2 +-
.../apache/ignite/ml/common/LocalModelsTest.java | 2 +-
.../ignite/ml/knn/ANNClassificationTest.java | 8 +-
.../vector/storage/DenseVectorStorageTest.java | 2 +-
...onTreeClassificationTrainerIntegrationTest.java | 6 +-
...cisionTreeRegressionTrainerIntegrationTest.java | 6 +-
.../ml/tree/DecisionTreeRegressionTrainerTest.java | 6 +-
.../RandomForestClassifierTrainerTest.java | 4 +-
.../RandomForestRegressionTrainerTest.java | 4 +-
.../ignite/ml/util/genetic/PopulationTest.java | 4 +-
.../apache/ignite/osgi/IgniteOsgiServiceTest.java | 2 +-
modules/platforms/cpp/CMakeLists.txt | 1 -
modules/platforms/cpp/README.txt | 3 +-
modules/platforms/cpp/binary/CMakeLists.txt | 12 +-
modules/platforms/cpp/cmake/FindIgnite.cmake | 24 +-
modules/platforms/cpp/cmake/FindODBC.cmake | 14 +-
modules/platforms/cpp/common/CMakeLists.txt | 12 +-
.../platforms/cpp/core-test/src/affinity_test.cpp | 2 +-
modules/platforms/cpp/core/CMakeLists.txt | 27 +-
.../cpp/{jni => core}/include/ignite/jni/java.h | 2 +-
.../cpp/{jni => core}/include/ignite/jni/utils.h | 39 +-
modules/platforms/cpp/core/src/ignition.cpp | 2 -
.../cpp/core/src/impl/ignite_environment.cpp | 2 +-
.../cpp/{jni/src => core/src/jni}/java.cpp | 2 +-
.../linux/src => core/src/jni/os/linux}/utils.cpp | 4 +-
.../os/win/src => core/src/jni/os/win}/utils.cpp | 0
.../cpp/examples/compute-example/CMakeLists.txt | 3 +-
.../continuous-query-example/CMakeLists.txt | 3 +-
.../cpp/examples/odbc-example/CMakeLists.txt | 4 +-
.../cpp/examples/put-get-example/CMakeLists.txt | 3 +-
.../cpp/examples/query-example/CMakeLists.txt | 3 +-
.../thin-client-put-get-example/CMakeLists.txt | 3 +-
modules/platforms/cpp/jni/CMakeLists.txt | 56 -
.../platforms/cpp/jni/include/ignite/jni/exports.h | 59 -
modules/platforms/cpp/jni/src/exports.cpp | 116 --
modules/platforms/cpp/network/CMakeLists.txt | 12 +-
modules/platforms/cpp/odbc-test/README.TXT | 1 -
modules/platforms/cpp/odbc/CMakeLists.txt | 6 +-
modules/platforms/cpp/thin-client/CMakeLists.txt | 8 +-
.../Apache.Ignite.Core.Tests.DotNetCore.csproj | 3 +
.../Binary/TypeNameParserTest.cs | 22 +-
.../Binary/TypeResolverTest.cs | 24 +-
.../Cache/Platform/PlatformCacheTest.cs | 1 +
.../Client/ClientConnectionTest.cs | 103 +-
.../ClientProtocolCompatibilityTest.cs | 6 +-
.../Client/Datastream/DataStreamerClientTest.cs | 72 +
.../Client/RawSecureSocketTest.cs | 63 +-
.../Client/RawSocketTest.cs | 34 +-
...-ssl.xml => server-with-ssl-no-client-auth.xml} | 6 +-
.../Config/Client/server-with-ssl.xml | 2 +-
.../Dataload/DataStreamerTest.cs | 62 +
.../Examples/ExamplesTestBase.cs | 14 +-
.../dotnet/Apache.Ignite.Core.Tests/JavaServer.cs | 3 +
.../Services/CallPlatformServiceTest.cs | 14 +-
.../Services/IJavaService.cs | 3 +
.../Services/JavaServiceDynamicProxy.cs | 6 +
.../Services/PlatformTestService.cs | 10 +
.../Services/ServiceProxyTest.cs | 11 +-
.../Services/ServicesAsyncWrapper.cs | 14 +-
.../Services/ServicesTest.cs | 107 +-
.../Apache.Ignite.Core.Tests/TestUtilsJni.cs | 13 +-
.../Apache.Ignite.Core/Client/SslStreamFactory.cs | 9 +-
.../Common/IgniteExperimentalAttribute.cs | 4 +-
.../Impl/Binary/BinaryHashCodeUtils.cs | 5 +
.../Impl/Binary/TypeNameParser.cs | 20 +
.../Apache.Ignite.Core/Impl/Binary/TypeResolver.cs | 5 -
.../Impl/Services/ServiceCallContext.cs | 64 +
.../Impl/Services/ServiceContext.cs | 20 +-
.../Impl/Services/ServiceProxySerializer.cs | 12 +-
.../Apache.Ignite.Core/Impl/Services/Services.cs | 36 +-
.../Apache.Ignite.Core/Impl/Unmanaged/Jni/Jvm.cs | 4 +-
.../Impl/Unmanaged/UnmanagedCallbacks.cs | 22 +-
.../Services/IServiceCallContext.cs | 78 +
.../Apache.Ignite.Core/Services/IServiceContext.cs | 9 +
.../Apache.Ignite.Core/Services/IServices.cs | 31 +
.../Services/ServiceCallContextBuilder.cs | 81 +
.../http/jetty/GridJettyObjectMapper.java | 15 +
.../jdbc/CacheJdbcBlobStoreFactorySelfTest.java | 2 +-
.../GridServiceContextInjectionSelfTest.java | 246 +++
.../p2p/GridP2PUserVersionChangeSelfTest.java | 6 +-
...gniteSpringBeanSpringResourceInjectionTest.java | 2 +-
.../testsuites/IgniteResourceSelfTestSuite.java | 2 +
.../surefire/testsuites/IgniteTestsProvider.java | 2 +-
.../ignite/cache/websession/WebSessionFilter.java | 6 +-
.../internal/websession/WebSessionSelfTest.java | 10 +-
.../cache/IgniteBinaryIdentityBenchmark.java | 2 +-
.../cache/dml/IgniteSqlMergeQueryBenchmark.java | 4 +-
.../thin/cache/IgniteThinBenchmarkUtils.java | 4 +-
.../yarn/IgniteApplicationMasterSelfTest.java | 4 +-
.../zk/internal/ZookeeperClusterNode.java | 4 +-
.../tcp/ipfinder/zk/ZookeeperIpFinderTest.java | 2 +-
...ZookeeperDiscoveryCommunicationFailureTest.java | 2 +-
.../internal/ZookeeperDiscoverySpiSslTestBase.java | 2 +-
996 files changed, 16748 insertions(+), 7944 deletions(-)
create mode 100644 docs/_docs/SQL/sql-statistics.adoc
create mode 100644 docs/_docs/images/svg/analyze_bnf1.svg
create mode 100644 docs/_docs/images/svg/analyze_bnf2.svg
create mode 100644 docs/_docs/images/svg/drop_bnf.svg
create mode 100644 docs/_docs/images/svg/refresh_bnf.svg
rename docs/_docs/key-value-api/{using-scan-queries.adoc => using-cache-queries.adoc} (62%)
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/IgniteServicesEx.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumArray.java
copy modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/{sorted/keys/DecimalIndexKey.java => IndexQueryResult.java} (52%)
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/IndexQueryResultMeta.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/PartitionClearingStartRecord.java
delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/AbstractCorruptedPersistenceException.java
copy modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/{CorruptedPartitionMetaPageException.java => CorruptedDataStructureException.java} (52%)
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotFutureTask.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotMessage.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFilesFailureMessage.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotFilesRequestMessage.java
copy modules/core/src/main/java/org/apache/ignite/internal/{cache/query/index/sorted/keys/LongIndexKey.java => processors/cache/persistence/snapshot/SnapshotFinishedFutureTask.java} (60%)
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotResponseRemoteFutureTask.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/reducer/IndexQueryReducer.java
copy modules/core/src/main/java/org/apache/ignite/internal/processors/cache/{persistence/snapshot/IgniteSnapshotVerifyException.java => query/reducer/TextQueryReducer.java} (51%)
delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
copy modules/core/src/main/java/org/apache/ignite/internal/processors/{odbc/jdbc/JdbcResultWithIo.java => service/ServiceCallContextHolder.java} (52%)
copy modules/core/src/main/java/org/apache/ignite/internal/processors/{datastructures/DistributedCollectionMetadata.java => service/ServiceCallContextImpl.java} (51%)
delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceProcessorAdapter.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/AbstractConsistencyTask.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyStatusTask.java
rename modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/{VisorConsistencyRepairTaskResult.java => VisorConsistencyTaskResult.java} (96%)
create mode 100644 modules/core/src/main/java/org/apache/ignite/resources/ServiceContextResource.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/services/ServiceCallContext.java
create mode 100644 modules/core/src/main/java/org/apache/ignite/services/ServiceCallContextBuilder.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectLockTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/binary/AbstractBinaryArraysTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryArraySelfTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/client/thin/OptimizedMarshallerClassesCachedTest.java
copy modules/core/src/{main/java/org/apache/ignite/internal/cache/query/index/sorted/keys/SignedBytesIndexKey.java => test/java/org/apache/ignite/internal/client/thin/ServicesBinaryArraysTests.java} (68%)
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/WaitForBackupsOnShutdownSystemPropertyTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRemoteRequestTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRestoreFromRemoteTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeReplaceRemoveRaceTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/security/service/ServiceAuthorizationTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/security/service/ServiceStaticConfigTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/processors/service/IgniteServiceCallContextTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/suggestions/JvmConfigurationSuggestionsTest.java
create mode 100644 modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotTestSuite.java
rename modules/{core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CorruptedPersistenceException.java => indexing/src/main/java/org/apache/ignite/internal/processors/query/stat/CancellableTask.java} (68%)
create mode 100644 modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlQueryDecimalArgumentsWithTest.java
copy modules/{spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java => indexing/src/test/java/org/apache/ignite/testsuites/IgniteSnapshotWithIndexingTestSuite.java} (61%)
rename modules/platforms/cpp/{jni => core}/include/ignite/jni/java.h (99%)
rename modules/platforms/cpp/{jni => core}/include/ignite/jni/utils.h (85%)
rename modules/platforms/cpp/{jni/src => core/src/jni}/java.cpp (99%)
rename modules/platforms/cpp/{jni/os/linux/src => core/src/jni/os/linux}/utils.cpp (99%)
rename modules/platforms/cpp/{jni/os/win/src => core/src/jni/os/win}/utils.cpp (100%)
delete mode 100644 modules/platforms/cpp/jni/CMakeLists.txt
delete mode 100644 modules/platforms/cpp/jni/include/ignite/jni/exports.h
delete mode 100644 modules/platforms/cpp/jni/src/exports.cpp
delete mode 100644 modules/platforms/cpp/odbc-test/README.TXT
copy modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/{server-with-ssl.xml => server-with-ssl-no-client-auth.xml} (96%)
create mode 100644 modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceCallContext.cs
create mode 100644 modules/platforms/dotnet/Apache.Ignite.Core/Services/IServiceCallContext.cs
create mode 100644 modules/platforms/dotnet/Apache.Ignite.Core/Services/ServiceCallContextBuilder.cs
create mode 100644 modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridServiceContextInjectionSelfTest.java
[ignite] 01/01: Merge remote-tracking branch 'remotes/upstream/master' into sql-calcite
Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 422e993f1533ea0ad02168a34f87044fb4350e05
Merge: 271390d 914c5dd
Author: Aleksey Plekhanov <pl...@gmail.com>
AuthorDate: Tue Dec 7 13:12:47 2021 +0300
Merge remote-tracking branch 'remotes/upstream/master' into sql-calcite
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/query/stat/StatisticsKey.java
# modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/CommandProcessor.java
assembly/release-apache-ignite-base.xml | 6 -
checkstyle/checkstyle.xml | 2 +-
docs/_data/toc.yaml | 6 +-
docs/_docs/SQL/sql-statistics.adoc | 182 ++
docs/_docs/code-deployment/peer-class-loading.adoc | 4 +-
.../apache/ignite/snippets/UsingScanQueries.java | 75 +
.../k8s/stateful/node-configuration.xml | 4 +-
.../k8s/stateless/node-configuration.xml | 4 +-
docs/_docs/code-snippets/xml/jetty.xml | 2 +-
.../collocated-computations.adoc | 2 +-
docs/_docs/events/events.adoc | 6 +-
.../spring/spring-caching.adoc | 83 +-
.../spring/spring-tx.adoc | 89 +-
docs/_docs/images/svg/analyze_bnf1.svg | 188 ++
docs/_docs/images/svg/analyze_bnf2.svg | 168 ++
docs/_docs/images/svg/drop_bnf.svg | 188 ++
docs/_docs/images/svg/refresh_bnf.svg | 188 ++
...-scan-queries.adoc => using-cache-queries.adoc} | 60 +-
docs/_docs/monitoring-metrics/metrics.adoc | 2 +-
docs/_docs/monitoring-metrics/new-metrics.adoc | 24 +-
docs/_docs/monitoring-metrics/system-views.adoc | 74 +-
.../thread-pools-tuning.adoc | 8 +
docs/_docs/services/services.adoc | 6 +-
docs/_docs/snapshots/snapshots.adoc | 15 +-
docs/_docs/sql-reference/ddl.adoc | 83 +
docs/_docs/thin-clients/java-thin-client.adoc | 6 +-
docs/_docs/tools/control-script.adoc | 73 +-
.../examples/datagrid/CacheQueryExample.java | 50 +-
.../ANNClassificationExportImportExample.java | 4 +-
...domForestClassificationExportImportExample.java | 2 +-
...onTreeClassificationTrainerSQLTableExample.java | 2 +-
.../org/apache/ignite/examples/model/Person.java | 9 +-
.../examples/servicegrid/SimpleMapServiceImpl.java | 11 +-
.../gridify/aop/aspectj/GridifyAspectJAspect.java | 4 +-
.../aop/aspectj/GridifySetToSetAspectJAspect.java | 4 +-
.../aspectj/GridifySetToValueAspectJAspect.java | 4 +-
.../org/apache/ignite/gridify/AbstractAopTest.java | 22 +-
.../internal/benchmarks/jmh/algo/BenchmarkCRC.java | 2 +-
.../query/calcite/CalciteQueryProcessor.java | 4 +-
.../query/calcite/RemoteFragmentKey.java | 4 +-
.../query/calcite/exec/ExchangeServiceImpl.java | 8 +-
.../query/calcite/exec/ExecutionServiceImpl.java | 6 +-
.../processors/query/calcite/exec/IndexScan.java | 2 +-
.../query/calcite/exec/LogicalRelImplementor.java | 4 +-
.../query/calcite/exec/MailboxRegistryImpl.java | 4 +-
.../query/calcite/exec/exp/IgniteSqlFunctions.java | 2 +-
.../query/calcite/exec/exp/RexExecutorImpl.java | 2 +-
.../query/calcite/exec/exp/agg/GroupKey.java | 2 +-
.../processors/query/calcite/exec/rel/Inbox.java | 6 +-
.../query/calcite/message/MessageServiceImpl.java | 8 +-
.../query/calcite/message/MessageType.java | 2 +-
.../query/calcite/metadata/IgniteMdCollation.java | 4 +-
.../calcite/metadata/IgniteMdColumnOrigins.java | 4 +-
.../calcite/metadata/IgniteMdDistribution.java | 4 +-
.../processors/query/calcite/prepare/CacheKey.java | 2 +-
.../processors/query/calcite/prepare/Cloner.java | 50 +-
.../calcite/prepare/IgniteConvertletTable.java | 2 +-
.../query/calcite/prepare/IgnitePlanner.java | 2 +-
.../calcite/prepare/IgniteSqlToRelConvertor.java | 12 +-
.../query/calcite/prepare/IgniteSqlValidator.java | 8 +-
.../calcite/rule/LogicalScanConverterRule.java | 2 +-
.../query/calcite/schema/TableDescriptorImpl.java | 12 +-
.../calcite/sql/IgniteSqlIntervalTypeNameSpec.java | 2 +-
.../query/calcite/trait/CorrelationTrait.java | 2 +-
.../query/calcite/trait/DistributionFunction.java | 2 +-
.../query/calcite/trait/DistributionTrait.java | 8 +-
.../processors/query/calcite/trait/TraitUtils.java | 2 +-
.../processors/query/calcite/util/Commons.java | 8 +-
.../processors/query/calcite/util/RexUtils.java | 2 +-
.../calcite/exec/rel/ContinuousExecutionTest.java | 4 +-
.../ServerStatisticsIntegrationTest.java | 4 +-
.../planner/CorrelatedSubqueryPlannerTest.java | 2 +-
.../query/calcite/planner/PlannerTest.java | 6 +-
.../cache/store/cassandra/CassandraCacheStore.java | 2 +-
.../store/cassandra/common/CassandraHelper.java | 2 +-
.../persistence/PersistenceController.java | 2 +-
.../org/apache/ignite/tests/pojos/Product.java | 2 +-
.../apache/ignite/tests/pojos/ProductOrder.java | 2 +-
.../ignite/tests/utils/TestCacheSession.java | 2 +-
.../org/apache/ignite/tests/utils/TestsHelper.java | 2 +-
.../jdbc2/JdbcAbstractDmlStatementSelfTest.java | 2 +-
.../ignite/internal/jdbc2/JdbcSpringSelfTest.java | 2 +-
.../rest/ClientMemcachedProtocolSelfTest.java | 8 +-
.../rest/JettyRestProcessorAbstractSelfTest.java | 61 +-
.../processors/rest/TestMemcacheClient.java | 12 +-
.../rest/protocols/tcp/TcpRestParserSelfTest.java | 2 +-
.../thin/JdbcThinAbstractDmlStatementSelfTest.java | 2 +-
.../thin/JdbcThinAutoCloseServerCursorTest.java | 2 +-
.../JdbcThinCacheToJdbcDataTypesCoverageTest.java | 4 +-
.../resources/jetty/rest-jetty-ssl-client-auth.xml | 2 +-
.../src/test/resources/jetty/rest-jetty-ssl.xml | 2 +-
.../src/test/resources/jetty/router-jetty-ssl.xml | 2 +-
.../src/test/resources/jetty/router-jetty.xml | 2 +-
.../persistence/IndexTypesCompatibilityTest.java | 4 +-
.../InlineJavaObjectCompatibilityTest.java | 2 +-
.../MoveBinaryMetadataCompatibility.java | 2 +-
.../PersistenceBasicCompatibilityTest.java | 18 +
.../internal/commandline/CommandHandler.java | 10 +-
.../commandline/argument/parser/CLIArgument.java | 2 +-
.../consistency/ConsistencyCommand.java | 17 +-
.../consistency/ConsistencySubCommand.java | 6 +-
.../commandline/indexreader/IgniteIndexReader.java | 4 +-
.../IgniteIndexReaderFilePageStoreFactoryImpl.java | 2 +-
.../util/GridCommandHandlerAbstractTest.java | 4 +-
.../util/GridCommandHandlerIndexingTest.java | 2 +-
.../util/GridCommandHandlerPropertiesTest.java | 2 +-
.../apache/ignite/util/GridCommandHandlerTest.java | 12 +-
.../ignite/util/KillCommandsCommandShTest.java | 40 +-
.../java/org/apache/ignite/IgniteServices.java | 49 +
.../org/apache/ignite/IgniteSystemProperties.java | 41 +-
.../eviction/sorted/SortedEvictionPolicy.java | 2 +-
.../org/apache/ignite/cache/query/IndexQuery.java | 9 +-
.../store/jdbc/JdbcTypesDefaultTransformer.java | 2 +-
.../configuration/DataStorageConfiguration.java | 2 +-
.../ignite/configuration/IgniteConfiguration.java | 34 +-
.../apache/ignite/internal/GridKernalContext.java | 4 +-
.../ignite/internal/GridKernalContextImpl.java | 15 +-
.../ignite/internal/GridTaskSessionImpl.java | 2 +-
.../ignite/internal/IgniteDiagnosticMessage.java | 2 +-
.../org/apache/ignite/internal/IgniteKernal.java | 40 +-
.../ignite/internal/IgniteNodeAttributes.java | 4 -
.../apache/ignite/internal/IgniteServicesEx.java | 54 +
.../apache/ignite/internal/IgniteServicesImpl.java | 74 +-
.../org/apache/ignite/internal/IgnitionEx.java | 3 +
.../ignite/internal/MarshallerContextImpl.java | 2 +-
.../ignite/internal/ThreadPoolMXBeanAdapter.java | 2 +-
.../apache/ignite/internal/binary/BinaryArray.java | 282 +++
.../internal/binary/BinaryClassDescriptor.java | 10 +-
.../ignite/internal/binary/BinaryContext.java | 4 +-
.../ignite/internal/binary/BinaryEnumArray.java | 64 +
.../ignite/internal/binary/BinaryEnumCache.java | 2 +-
.../ignite/internal/binary/BinaryObjectImpl.java | 10 +-
.../internal/binary/BinaryObjectOffheapImpl.java | 4 +-
.../ignite/internal/binary/BinaryReaderExImpl.java | 18 +-
.../binary/BinarySerializedFieldComparator.java | 9 +-
.../apache/ignite/internal/binary/BinaryUtils.java | 101 +-
.../ignite/internal/binary/BinaryWriterExImpl.java | 38 +-
.../internal/binary/BinaryWriterSchemaHolder.java | 6 +-
.../internal/binary/GridBinaryMarshaller.java | 2 +-
.../binary/builder/BinaryBuilderReader.java | 12 +-
.../binary/builder/BinaryBuilderSerializer.java | 33 +
.../binary/builder/BinaryObjectBuilderImpl.java | 8 +
.../binary/streams/BinaryHeapOutputStream.java | 24 +
.../internal/cache/query/index/IndexProcessor.java | 2 +-
.../cache/query/index/IndexQueryProcessor.java | 255 ++-
.../DecimalIndexKey.java => IndexQueryResult.java} | 41 +-
.../cache/query/index/IndexQueryResultMeta.java | 90 +
.../DurableBackgroundCleanupIndexTreeTask.java | 1 +
.../query/index/sorted/IndexKeyDefinition.java | 35 +-
.../query/index/sorted/IndexKeyTypeSettings.java | 26 +-
.../query/index/sorted/IndexRowCompartorImpl.java | 8 -
.../query/index/sorted/SortedSegmentedIndex.java | 24 +-
.../sorted/defragmentation/DefragIndexFactory.java | 101 +-
.../defragmentation/IndexingDefragmentation.java | 25 +-
.../index/sorted/inline/InlineIndexFactory.java | 2 +-
.../query/index/sorted/inline/InlineIndexImpl.java | 9 +-
.../query/index/sorted/inline/InlineIndexTree.java | 6 +-
.../sorted/inline/InlineObjectBytesDetector.java | 2 +-
.../index/sorted/inline/InlineRecommender.java | 10 +-
.../sorted/inline/InlineTreeFilterClosure.java | 2 +-
.../sorted/inline/io/AbstractInlineInnerIO.java | 8 +-
.../sorted/inline/io/AbstractInlineLeafIO.java | 8 +-
.../index/sorted/inline/io/AbstractInnerIO.java | 6 +-
.../index/sorted/inline/io/AbstractLeafIO.java | 6 +-
.../query/index/sorted/inline/io/IORowHandler.java | 4 +-
.../inline/types/BooleanInlineIndexKeyType.java | 8 +-
.../inline/types/ByteInlineIndexKeyType.java | 8 +-
.../inline/types/BytesInlineIndexKeyType.java | 10 +-
.../inline/types/DateInlineIndexKeyType.java | 6 +-
.../inline/types/DoubleInlineIndexKeyType.java | 8 +-
.../inline/types/FloatInlineIndexKeyType.java | 8 +-
.../inline/types/IntegerInlineIndexKeyType.java | 8 +-
.../inline/types/LongInlineIndexKeyType.java | 8 +-
.../inline/types/NullableInlineIndexKeyType.java | 12 +-
.../types/ObjectByteArrayInlineIndexKeyType.java | 4 +-
.../inline/types/ObjectHashInlineIndexKeyType.java | 4 +-
.../inline/types/ShortInlineIndexKeyType.java | 6 +-
.../inline/types/StringInlineIndexKeyType.java | 28 +-
.../types/StringNoCompareInlineIndexKeyType.java | 2 +-
.../inline/types/TimeInlineIndexKeyType.java | 6 +-
.../inline/types/TimestampInlineIndexKeyType.java | 6 +-
.../inline/types/UuidInlineIndexKeyType.java | 8 +-
.../query/index/sorted/keys/BooleanIndexKey.java | 4 +-
.../query/index/sorted/keys/ByteIndexKey.java | 4 +-
.../query/index/sorted/keys/BytesIndexKey.java | 4 +-
.../query/index/sorted/keys/DecimalIndexKey.java | 2 +-
.../query/index/sorted/keys/DoubleIndexKey.java | 4 +-
.../query/index/sorted/keys/FloatIndexKey.java | 4 +-
.../query/index/sorted/keys/IndexKeyFactory.java | 24 +-
.../query/index/sorted/keys/IntegerIndexKey.java | 4 +-
.../index/sorted/keys/JavaObjectIndexKey.java | 4 +-
.../query/index/sorted/keys/LongIndexKey.java | 4 +-
.../query/index/sorted/keys/ShortIndexKey.java | 4 +-
.../index/sorted/keys/SignedBytesIndexKey.java | 4 +-
.../query/index/sorted/keys/StringIndexKey.java | 2 +-
.../query/index/sorted/keys/UuidIndexKey.java | 2 +-
.../internal/client/thin/ClientComputeImpl.java | 10 +-
.../internal/client/thin/PayloadOutputChannel.java | 15 +-
.../internal/client/thin/ReliableChannel.java | 52 +-
.../internal/client/thin/TcpClientChannel.java | 18 +-
.../internal/client/thin/TcpIgniteClient.java | 3 +
.../internal/client/thin/io/ClientConnection.java | 4 +-
.../io/gridnioserver/GridNioClientConnection.java | 8 +-
.../internal/events/DiscoveryCustomEvent.java | 4 +-
.../internal/jdbc/thin/JdbcThinResultSet.java | 26 +-
.../internal/jdbc/thin/JdbcThinStatement.java | 2 +-
.../ignite/internal/jdbc2/JdbcResultSet.java | 26 +-
.../internal/maintenance/MaintenanceFileStore.java | 2 +-
.../communication/AbstractTransmission.java | 4 +-
.../managers/communication/FileReceiver.java | 3 +-
.../managers/communication/GridIoManager.java | 30 +-
.../communication/GridIoMessageFactory.java | 4 +
.../communication/IgniteMessageFactoryImpl.java | 2 +-
.../communication/TransmissionHandler.java | 7 +-
.../deployment/GridDeploymentClassLoader.java | 2 +-
.../managers/discovery/GridDiscoveryManager.java | 28 +-
.../optimized/OptimizedClassDescriptor.java | 2 +-
.../ignite/internal/mem/file/MappedFile.java | 4 +-
.../apache/ignite/internal/pagemem/PageUtils.java | 2 +-
.../wal/record/PartitionClearingStartRecord.java | 98 +
.../internal/pagemem/wal/record/WALRecord.java | 5 +-
.../wal/record/delta/RotatedIdPartRecord.java | 2 +-
.../affinity/GridAffinityAssignmentCache.java | 22 +-
.../processors/affinity/GridAffinityUtils.java | 2 +-
.../cache/CacheAffinitySharedManager.java | 97 +-
.../processors/cache/CacheGroupContext.java | 25 +-
.../processors/cache/CacheGroupDescriptor.java | 2 +-
.../processors/cache/CacheInvokeResult.java | 2 +-
.../processors/cache/CacheMetricsImpl.java | 30 +-
.../processors/cache/CacheMetricsSnapshot.java | 8 +-
.../processors/cache/CacheObjectUtils.java | 6 +-
.../processors/cache/ClusterCachesInfo.java | 10 +-
.../internal/processors/cache/ExchangeActions.java | 4 +-
.../cache/GatewayProtectedCacheProxy.java | 16 +-
.../processors/cache/GridCacheAdapter.java | 68 +-
.../processors/cache/GridCacheContext.java | 2 +-
.../processors/cache/GridCacheContextInfo.java | 2 +-
.../processors/cache/GridCacheIoManager.java | 4 +-
.../processors/cache/GridCacheMvccManager.java | 2 +-
.../cache/GridCachePartitionExchangeManager.java | 6 +-
.../processors/cache/GridCacheProcessor.java | 176 +-
.../internal/processors/cache/GridCacheReturn.java | 4 +-
.../internal/processors/cache/GridCacheUtils.java | 16 +
.../cache/IgniteCacheOffheapManager.java | 23 +-
.../cache/IgniteCacheOffheapManagerImpl.java | 31 +-
.../processors/cache/IgniteCacheProxyImpl.java | 12 +-
.../internal/processors/cache/WalStateManager.java | 2 +-
.../binary/CacheObjectBinaryProcessorImpl.java | 43 +-
.../distributed/GridDistributedCacheAdapter.java | 6 +-
.../GridDistributedTxRemoteAdapter.java | 4 +-
.../dht/CacheDistributedGetFutureAdapter.java | 7 +
.../cache/distributed/dht/GridDhtLockFuture.java | 2 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 2 +-
.../distributed/dht/atomic/GridDhtAtomicCache.java | 2 +-
.../dht/preloader/GridDhtPartitionMap.java | 4 +-
.../preloader/GridDhtPartitionsExchangeFuture.java | 6 +-
.../dht/topology/GridDhtLocalPartition.java | 28 +-
.../dht/topology/GridDhtPartitionTopologyImpl.java | 2 +-
.../dht/topology/PartitionsEvictManager.java | 34 +-
.../cache/distributed/near/GridNearCacheEntry.java | 2 +-
...dNearOptimisticSerializableTxPrepareFuture.java | 2 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 6 +-
.../near/GridNearSingleGetResponse.java | 2 +-
.../near/GridNearTxQueryEnlistRequest.java | 13 +-
.../GridNearReadRepairCheckOnlyFuture.java | 55 +-
.../near/consistency/GridNearReadRepairFuture.java | 72 +-
.../cache/local/atomic/GridLocalAtomicCache.java | 4 +-
.../processors/cache/mvcc/MvccProcessorImpl.java | 6 +-
.../processors/cache/mvcc/MvccVersionImpl.java | 6 +-
.../processors/cache/mvcc/txlog/TxKey.java | 6 +-
.../processors/cache/mvcc/txlog/TxLogTree.java | 2 +-
.../AbstractCorruptedPersistenceException.java | 106 -
...n.java => CorruptedDataStructureException.java} | 46 +-
.../CorruptedPartitionMetaPageException.java | 31 +-
.../cache/persistence/DataRegionMetricsImpl.java | 2 +-
.../persistence/DataRegionMetricsMXBeanImpl.java | 4 +-
.../GridCacheDatabaseSharedManager.java | 84 +-
.../cache/persistence/GridCacheOffheapManager.java | 177 +-
.../checkpoint/CheckpointPagesWriter.java | 7 +-
.../defragmentation/IgniteDefragmentationImpl.java | 2 +-
.../cache/persistence/file/AbstractFileIO.java | 2 +-
.../cache/persistence/file/EncryptionUtil.java | 8 +-
.../cache/persistence/file/FilePageStore.java | 2 +-
.../persistence/file/FilePageStoreManager.java | 32 +-
.../freelist/CorruptedFreeListException.java | 38 +-
.../persistence/pagemem/PagesWriteThrottle.java | 2 +-
.../snapshot/AbstractSnapshotFutureTask.java | 136 ++
.../snapshot/AbstractSnapshotMessage.java | 108 +
.../snapshot/IgniteSnapshotManager.java | 899 ++++++++-
.../snapshot/IgniteSnapshotVerifyException.java | 3 +
.../snapshot/SnapshotFilesFailureMessage.java | 134 ++
.../snapshot/SnapshotFilesRequestMessage.java | 174 ++
.../snapshot/SnapshotFinishedFutureTask.java} | 34 +-
.../persistence/snapshot/SnapshotFutureTask.java | 117 +-
.../persistence/snapshot/SnapshotMetadata.java | 57 +-
.../snapshot/SnapshotPartitionsVerifyHandler.java | 9 +-
.../snapshot/SnapshotResponseRemoteFutureTask.java | 172 ++
.../snapshot/SnapshotRestoreProcess.java | 962 ++++++---
.../cache/persistence/tree/BPlusTree.java | 962 +++++----
.../persistence/tree/CorruptedTreeException.java | 98 +-
.../cache/persistence/tree/io/PageIO.java | 8 +-
.../cache/persistence/tree/io/TrackingPageIO.java | 2 +-
.../persistence/wal/FileWriteAheadLogManager.java | 8 +-
.../wal/reader/StandaloneGridKernalContext.java | 4 +-
.../wal/serializer/RecordDataV1Serializer.java | 34 +-
.../wal/serializer/RecordDataV2Serializer.java | 3 +
.../GridCacheDistributedFieldsQueryFuture.java | 4 +-
.../query/GridCacheDistributedQueryFuture.java | 33 +-
.../query/GridCacheDistributedQueryManager.java | 30 +-
.../query/GridCacheLocalFieldsQueryFuture.java | 4 +-
.../cache/query/GridCacheLocalQueryManager.java | 8 +-
.../cache/query/GridCacheQueryFutureAdapter.java | 36 +-
.../cache/query/GridCacheQueryManager.java | 73 +-
.../cache/query/GridCacheQueryResponse.java | 42 +-
.../query/jdbc/GridCacheQueryJdbcMetadataTask.java | 2 +-
.../cache/query/reducer/CacheQueryReducer.java | 9 +-
.../cache/query/reducer/IndexQueryReducer.java | 149 ++
.../query/reducer/MergeSortCacheQueryReducer.java | 20 +-
.../reducer/TextQueryReducer.java} | 39 +-
.../cache/transactions/IgniteTxManager.java | 2 +-
.../processors/cache/tree/AbstractDataLeafIO.java | 2 +-
.../cache/verify/IdleVerifyResultV2.java | 54 +-
.../cache/version/GridCacheVersionManager.java | 12 +-
.../processors/cluster/BaselineTopology.java | 2 +-
.../cluster/BaselineTopologyHistory.java | 2 +-
.../cluster/GridClusterStateProcessor.java | 11 +-
.../continuous/GridContinuousProcessor.java | 8 +-
.../datastructures/AtomicDataStructureProxy.java | 2 +-
.../datastructures/DataStructuresProcessor.java | 21 +-
.../DistributedCollectionMetadata.java | 4 +-
.../processors/datastructures/GridCacheLockEx.java | 7 +
.../datastructures/GridCacheLockImpl.java | 14 +-
.../processors/diagnostic/DiagnosticProcessor.java | 33 +-
.../processors/failure/FailureProcessor.java | 29 +-
.../marshaller/GridMarshallerMappingProcessor.java | 6 +-
.../marshaller/MarshallerMappingItem.java | 2 +-
.../processors/metric/GridMetricManager.java | 14 +-
.../odbc/ClientListenerNioMessageParser.java | 16 +-
.../processors/odbc/ClientListenerProcessor.java | 20 +-
.../internal/processors/odbc/ClientMessage.java | 72 +-
.../processors/odbc/jdbc/JdbcRequestHandler.java | 2 +-
.../processors/odbc/jdbc/JdbcResultWithIo.java | 2 +-
.../processors/odbc/odbc/OdbcColumnMeta.java | 2 +-
.../processors/odbc/odbc/OdbcMessageParser.java | 22 +-
.../processors/odbc/odbc/OdbcTableMeta.java | 2 +-
.../internal/processors/odbc/odbc/OdbcUtils.java | 2 +-
.../processors/platform/PlatformContextImpl.java | 2 +-
.../processors/platform/PlatformProcessorImpl.java | 2 +-
.../processors/platform/cache/PlatformCache.java | 6 +-
.../platform/client/ClientNotification.java | 2 +-
.../platform/client/ClientRequestHandler.java | 6 +-
.../platform/client/ClientResourceRegistry.java | 2 +-
.../client/binary/ClientBinaryTypePutRequest.java | 2 +-
.../cache/ClientCacheConfigurationSerializer.java | 2 +-
.../cache/ClientCacheEntryEventNotification.java | 8 +-
.../cache/ClientCacheGetConfigurationRequest.java | 2 +-
.../cache/ClientCacheQueryContinuousRequest.java | 4 +-
.../cache/ClientCacheSqlFieldsQueryRequest.java | 2 +-
.../client/cache/ClientCacheSqlQueryRequest.java | 2 +-
...lientClusterGroupGetNodesEndpointsResponse.java | 2 +-
.../client/compute/ClientExecuteTaskRequest.java | 2 +-
.../client/service/ClientServiceInvokeRequest.java | 14 +-
.../client/streamer/ClientDataStreamerReader.java | 5 +-
.../platform/client/tx/ClientTxContext.java | 18 +-
.../platform/cluster/PlatformClusterGroup.java | 4 +-
.../platform/compute/PlatformAbstractTask.java | 2 +-
.../platform/compute/PlatformCompute.java | 5 +-
.../datastreamer/PlatformDataStreamer.java | 6 +-
.../platform/dotnet/PlatformDotNetCacheStore.java | 8 +-
.../dotnet/PlatformDotNetConsoleStream.java | 2 +-
.../processors/platform/events/PlatformEvents.java | 2 +-
.../events/PlatformLocalEventListener.java | 2 +-
.../platform/memory/PlatformOutputStreamImpl.java | 4 +-
.../platform/services/PlatformAbstractService.java | 19 +-
.../platform/services/PlatformService.java | 25 +-
.../platform/services/PlatformServices.java | 27 +-
.../platform/utils/PlatformConfigurationUtils.java | 46 +-
.../platform/utils/PlatformFutureUtils.java | 14 +-
.../processors/platform/utils/PlatformUtils.java | 19 +-
.../processors/plugin/IgnitePluginProcessor.java | 4 +-
.../internal/processors/pool/PoolProcessor.java | 72 +
.../processors/query/GridQueryProcessor.java | 15 +-
.../processors/query/QueryTypeDescriptorImpl.java | 20 +-
.../internal/processors/query/QueryUtils.java | 2 +-
.../query/property/QueryBinaryProperty.java | 8 +-
.../processors/query/stat/StatisticsKey.java | 2 +-
.../processors/query/stat/StatisticsTarget.java | 2 +-
.../stat/config/StatisticsColumnOverrides.java | 2 +-
.../processors/resource/GridResourceIoc.java | 6 +-
.../processors/resource/GridResourceProcessor.java | 7 +-
.../resource/GridResourceServiceInjector.java | 55 +-
.../processors/rest/GridRestProcessor.java | 2 +
.../rest/client/message/GridClientCacheBean.java | 2 +-
.../rest/handlers/task/GridTaskCommandHandler.java | 2 +-
.../rest/protocols/tcp/GridMemcachedMessage.java | 2 +-
.../protocols/tcp/GridTcpMemcachedNioListener.java | 2 +-
.../processors/service/GridServiceProcessor.java | 2134 --------------------
.../processors/service/GridServiceProxy.java | 145 +-
.../processors/service/IgniteServiceProcessor.java | 279 ++-
.../ServiceCallContextHolder.java} | 43 +-
.../ServiceCallContextImpl.java} | 70 +-
.../processors/service/ServiceContextImpl.java | 6 +
.../service/ServiceProcessorAdapter.java | 162 --
.../ignite/internal/sql/SqlCommandProcessor.java | 10 +-
.../org/apache/ignite/internal/sql/SqlKeyword.java | 2 +-
.../suggestions/JvmConfigurationSuggestions.java | 4 +-
.../internal/util/GridBoundedLinkedHashSet.java | 2 +-
.../util/GridConcurrentPhantomHashSet.java | 2 +-
.../internal/util/GridConcurrentWeakHashSet.java | 2 +-
.../internal/util/GridPartitionStateMap.java | 2 +-
.../ignite/internal/util/GridStringBuilder.java | 2 +-
.../apache/ignite/internal/util/IgniteUtils.java | 24 +-
.../ignite/internal/util/StripedExecutor.java | 2 +-
.../util/distributed/DistributedProcess.java | 5 +
.../util/io/GridByteArrayOutputStream.java | 2 +-
.../util/io/GridReversedLinesFileReader.java | 2 +-
.../util/ipc/loopback/IpcServerTcpEndpoint.java | 3 +-
.../ipc/shmem/IpcSharedMemoryServerEndpoint.java | 3 +-
.../util/ipc/shmem/IpcSharedMemorySpace.java | 4 +-
.../apache/ignite/internal/util/lang/GridFunc.java | 6 +-
.../ignite/internal/util/nio/GridNioServer.java | 2 +-
.../util/tostring/GridToStringBuilder.java | 6 +-
.../visor/cache/VisorCacheConfiguration.java | 2 +-
.../internal/visor/cache/VisorCacheJdbcType.java | 2 +-
.../visor/consistency/AbstractConsistencyTask.java | 64 +
.../consistency/VisorConsistencyRepairTask.java | 48 +-
.../consistency/VisorConsistencyRepairTaskArg.java | 19 +
.../consistency/VisorConsistencyStatusTask.java | 95 +
...Result.java => VisorConsistencyTaskResult.java} | 2 +-
.../availability/VisorConnectivityTask.java | 2 +-
.../visor/node/VisorGridConfiguration.java | 2 +-
.../visor/persistence/PersistenceTask.java | 2 +-
.../visor/persistence/PersistenceTaskArg.java | 2 +-
.../ignite/internal/visor/util/VisorTaskUtils.java | 4 +-
.../dotnet/PlatformDotNetAffinityFunction.java | 2 +-
.../ignite/resources/ServiceContextResource.java | 65 +
.../apache/ignite/resources/ServiceResource.java | 7 +
.../java/org/apache/ignite/services/Service.java | 75 +-
.../apache/ignite/services/ServiceCallContext.java | 86 +
.../ignite/services/ServiceCallContextBuilder.java | 77 +
.../org/apache/ignite/services/ServiceContext.java | 16 +-
.../spi/ExponentialBackoffTimeoutStrategy.java | 2 +-
.../tcp/TcpCommunicationMetricsListener.java | 4 +-
.../communication/tcp/internal/ConnectionKey.java | 2 +-
.../TcpCommunicationConfigInitializer.java | 50 +-
.../ignite/spi/discovery/tcp/ClientImpl.java | 6 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 63 +-
.../ignite/spi/discovery/tcp/TcpDiscoveryImpl.java | 2 +-
.../discovery/tcp/internal/TcpDiscoveryNode.java | 2 +-
.../tcp/internal/TcpDiscoveryNodesRing.java | 2 +-
.../spi/indexing/IndexingQueryFilterImpl.java | 7 +
.../ignite/startup/cmdline/CommandLineStartup.java | 4 +-
.../org/apache/ignite/stream/StreamAdapter.java | 2 +-
.../java/org/jsr166/ConcurrentLinkedDeque8.java | 8 +-
.../java/org/jsr166/ConcurrentLinkedHashMap.java | 2 +-
.../main/resources/META-INF/classnames.properties | 5 +-
.../ignite/cache/RebalanceCancellationTest.java | 2 +-
.../ignite/cache/ResetLostPartitionTest.java | 4 +-
.../ignite/client/ClientConfigurationTest.java | 2 +-
.../org/apache/ignite/client/ConnectionTest.java | 49 +
.../org/apache/ignite/client/FunctionalTest.java | 58 +-
.../org/apache/ignite/client/IgniteBinaryTest.java | 2 +-
.../java/org/apache/ignite/client/LoadTest.java | 2 +-
.../apache/ignite/client/ReliabilityTestAsync.java | 2 +-
.../ignite/internal/ClusterGroupAbstractTest.java | 4 +-
.../internal/GridDiscoveryEventSelfTest.java | 10 +-
.../ignite/internal/GridDiscoverySelfTest.java | 2 +-
.../ignite/internal/GridKernalTestUtils.java | 2 +-
.../org/apache/ignite/internal/GridMBeansTest.java | 1 +
.../ignite/internal/GridSameVmStartupSelfTest.java | 4 +-
.../ignite/internal/GridTaskTimeoutSelfTest.java | 2 +-
...ientCheckClusterGroupLocalIdAfterReconnect.java | 4 +-
.../internal/IgniteClientReconnectLockTest.java | 178 ++
.../IgniteClientReconnectServicesTest.java | 54 -
.../IgniteSlowClientDetectionSelfTest.java | 2 +-
.../internal/TestRecordingCommunicationSpi.java | 6 +-
.../internal/TransactionsMXBeanImplTest.java | 4 +-
.../internal/binary/AbstractBinaryArraysTest.java | 56 +
.../apache/ignite/internal/binary/AffinityKey.java | 2 +-
.../internal/binary/BinaryArraySelfTest.java | 446 ++++
.../internal/binary/BinaryEnumsSelfTest.java | 38 +-
.../binary/BinaryFieldsAbstractSelfTest.java | 18 +-
.../internal/binary/BinaryMarshallerSelfTest.java | 216 +-
.../BinaryObjectBuilderAdditionalSelfTest.java | 296 ++-
.../BinaryObjectBuilderDefaultMappersSelfTest.java | 17 +-
.../internal/binary/BinaryObjectToStringTest.java | 12 +-
.../BinarySerialiedFieldComparatorSelfTest.java | 2 +-
.../binary/mutabletest/GridBinaryTestClasses.java | 44 +
.../thin/OptimizedMarshallerClassesCachedTest.java | 86 +
.../internal/client/thin/ReliableChannelTest.java | 38 +
.../client/thin/ServicesBinaryArraysTests.java} | 15 +-
.../ignite/internal/client/thin/ServicesTest.java | 17 +
.../ThinClientPartitionAwarenessDiscoveryTest.java | 2 +-
.../FullyConnectedComponentSearcherTest.java | 2 +-
...ectByteBufferStreamImplV2ByteOrderSelfTest.java | 2 +-
.../GridCheckpointManagerAbstractSelfTest.java | 4 +-
.../IgniteCommunicationBalanceTest.java | 6 +-
.../GridDifferentLocalDeploymentSelfTest.java | 6 +-
.../GridDiscoveryManagerAttributesSelfTest.java | 16 +-
.../optimized/OptimizedObjectStreamSelfTest.java | 2 +-
.../cache/AbstractDataTypesCoverageTest.java | 36 +-
.../AtomicCacheAffinityConfigurationTest.java | 2 +-
...acheConfigurationSerializationAbstractTest.java | 2 +-
...eConfigurationSerializationOnDiscoveryTest.java | 10 +-
...heConfigurationSerializationOnExchangeTest.java | 4 +-
.../CacheGroupLocalConfigurationSelfTest.java | 2 +-
...InterceptorPartitionCounterLocalSanityTest.java | 2 +-
...ceptorPartitionCounterRandomOperationsTest.java | 2 +-
.../processors/cache/CacheMetricsManageTest.java | 4 +-
.../cache/CacheNoAffinityExchangeTest.java | 2 +-
.../processors/cache/CacheRebalancingSelfTest.java | 2 +-
.../cache/CacheStoreTxPutAllMultiNodeTest.java | 2 +-
.../CacheStoreUsageMultinodeAbstractTest.java | 2 +-
.../cache/ClientSlowDiscoveryAbstractTest.java | 2 +-
.../ClientSlowDiscoveryTopologyChangeTest.java | 6 +-
.../ClientSlowDiscoveryTransactionRemapTest.java | 2 +-
.../processors/cache/ConcurrentCacheStartTest.java | 2 +-
.../GridAbstractCacheInterceptorRebalanceTest.java | 2 +-
.../cache/GridCacheAbstractMetricsSelfTest.java | 32 +-
.../cache/GridCacheAbstractRemoveFailureTest.java | 2 +-
.../GridCacheConcurrentTxMultiNodeLoadTest.java | 4 +-
.../cache/GridCacheEvictionEventAbstractTest.java | 4 +-
...CacheLongRunningTransactionDiagnosticsTest.java | 2 +-
.../cache/GridCacheOnCopyFlagAbstractSelfTest.java | 2 +-
.../cache/GridCacheQueryEmbeddedValue.java | 2 +-
.../GridCacheStoreManagerDeserializationTest.java | 2 +-
...idCacheTcpClientDiscoveryMultiThreadedTest.java | 4 +-
.../cache/GridLocalIgniteSerializationTest.java | 8 +-
.../GridTransactionsSystemUserTimeMetricsTest.java | 6 +-
.../cache/IgniteCacheAbstractStopBusySelfTest.java | 2 +-
.../IgniteCacheBinaryEntryProcessorSelfTest.java | 2 +-
.../IgniteCacheConfigVariationsFullApiTest.java | 2 +-
.../IgniteCacheEntryListenerAbstractTest.java | 2 +-
.../processors/cache/IgniteCacheGroupsTest.java | 4 +-
.../cache/IgniteCacheInvokeAbstractTest.java | 4 +-
.../cache/IgniteCachePeekModesAbstractTest.java | 14 +-
.../cache/IgniteClientCacheStartFailoverTest.java | 2 +-
...usterActivateDeactivateTestWithPersistence.java | 4 +-
...teDynamicCacheStartCoordinatorFailoverTest.java | 6 +-
.../cache/IgniteIncompleteCacheObjectSelfTest.java | 2 +-
...IgniteMarshallerCacheClassNameConflictTest.java | 2 +-
.../cache/IgniteMarshallerCacheFSRestoreTest.java | 4 +-
.../cache/IgniteTxConfigCacheSelfTest.java | 2 +-
.../cache/IgniteTxMultiNodeAbstractTest.java | 2 +-
.../PartitionsExchangeCoordinatorFailoverTest.java | 14 +-
.../cache/RestorePartitionStateTest.java | 8 +-
.../SetTxTimeoutOnPartitionMapExchangeTest.java | 2 +-
.../cache/TransactionValidationTest.java | 2 +-
.../cache/WalModeChangeAdvancedSelfTest.java | 2 +-
.../cache/WalModeChangeCommonAbstractSelfTest.java | 2 +-
.../binary/BinaryMetadataUpdatesFlowTest.java | 4 +-
...eBinaryObjectMetadataExchangeMultinodeTest.java | 8 +-
.../GridCacheBinaryObjectsAbstractSelfTest.java | 4 +-
...lientNodeBinaryObjectMetadataMultinodeTest.java | 2 +-
.../consistency/AbstractFullSetReadRepairTest.java | 22 +-
.../cache/consistency/AbstractReadRepairTest.java | 112 +-
.../cache/consistency/AtomicReadRepairTest.java | 20 +-
.../ExplicitTransactionalReadRepairTest.java | 20 +-
.../ImplicitTransactionalReadRepairTest.java | 20 +-
.../GridCacheSetAbstractSelfTest.java | 4 +-
.../datastructures/IgniteLockAbstractSelfTest.java | 2 +-
.../IgniteSemaphoreAbstractSelfTest.java | 8 +-
.../GridCachePartitionedNodeRestartTxSelfTest.java | 8 +-
.../distributed/CacheBaselineTopologyTest.java | 6 +-
.../cache/distributed/CacheExchangeMergeTest.java | 4 +-
.../CacheLateAffinityAssignmentTest.java | 2 +-
...CachePartitionLostAfterSupplierHasLeftTest.java | 2 +-
.../GridCachePartitionNotLoadedEventSelfTest.java | 2 +-
.../GridCachePreloadLifecycleAbstractTest.java | 2 +-
.../IgniteCacheClientNodeChangingTopologyTest.java | 2 +-
.../dht/GridCacheColocatedDebugTest.java | 4 +-
.../GridCachePartitionsStateValidationTest.java | 10 +-
...WaitForBackupsOnShutdownSystemPropertyTest.java | 92 +
.../dht/topology/BlockedEvictionsTest.java | 8 +-
...MovingPartitionIsEvictedDuringClearingTest.java | 2 +-
.../dht/topology/PartitionEvictionOrderTest.java | 2 +-
...reloadingRestartWhileClearingPartitionTest.java | 4 +-
.../near/GridCacheNearMetricsSelfTest.java | 12 +-
.../GridCacheNearOnlyMultiNodeFullApiSelfTest.java | 4 +-
.../GridCacheRebalancingOrderingTest.java | 12 +-
.../GridCacheRebalancingPartitionCountersTest.java | 2 +-
.../GridCacheRebalancingWithAsyncClearingTest.java | 4 +-
.../GridCacheReplicatedPreloadSelfTest.java | 4 +-
.../IgniteCacheExpireWhileRebalanceTest.java | 2 +-
.../IgniteCacheExpiryPolicyAbstractTest.java | 4 +-
.../IgniteCacheNoWriteThroughAbstractTest.java | 2 +-
.../cache/mvcc/CacheMvccAbstractFeatureTest.java | 2 +-
.../cache/mvcc/CacheMvccAbstractTest.java | 2 +-
.../cache/mvcc/CacheMvccClientTopologyTest.java | 2 +-
.../cache/mvcc/CacheMvccTxFailoverTest.java | 4 +-
...niteBaselineAffinityTopologyActivationTest.java | 24 +-
...gniteLostPartitionsOnLeaveBaselineSelfTest.java | 2 +-
...gnitePdsBinaryMetadataOnClusterRestartTest.java | 32 +-
.../IgnitePdsCacheAssignmentNodeRestartsTest.java | 10 +-
...CacheConfigurationFileConsistencyCheckTest.java | 8 +-
.../IgnitePdsCacheRebalancingAbstractTest.java | 4 +-
...itePdsCacheStartStopWithFreqCheckpointTest.java | 2 +-
...nitePdsConsistencyOnDelayedPartitionOwning.java | 6 +-
.../persistence/IgnitePdsCorruptedIndexTest.java | 8 +-
.../persistence/IgnitePdsDefragmentationTest.java | 2 +-
.../IgnitePdsRemoveDuringRebalancingTest.java | 1 -
...ocalWalModeChangeDuringRebalancingSelfTest.java | 10 +-
.../MemoryPolicyInitializationTest.java | 2 +-
.../PagesPossibleCorruptionDiagnosticTest.java | 9 +-
.../ClientAffinityAssignmentWithBaselineTest.java | 2 +-
.../persistence/db/IgniteLogicalRecoveryTest.java | 18 +-
...IgnitePdsCacheWalDisabledOnRebalancingTest.java | 20 +-
.../db/IgnitePdsTransactionsHangTest.java | 2 +-
.../db/file/IgnitePdsCheckpointSimpleTest.java | 1 -
.../db/file/IgnitePdsDiskErrorsRecoveringTest.java | 20 +-
.../persistence/db/wal/IgniteWalRebalanceTest.java | 22 +-
.../wal/IgniteWalRecoverySeveralRestartsTest.java | 7 +-
.../db/wal/WalArchiveSizeConfigurationTest.java | 2 +-
.../IgniteAbstractWalIteratorInvalidCrcTest.java | 2 +-
.../defragmentation/DefragmentationMXBeanTest.java | 2 +-
.../persistence/pagemem/FullPageIdTableTest.java | 2 +-
.../IgnitePageMemReplaceDelayedWriteUnitTest.java | 2 +-
.../pagemem/RobinHoodBackwardShiftHashMapTest.java | 2 +-
.../snapshot/AbstractSnapshotSelfTest.java | 98 +-
.../snapshot/IgniteClusterSnapshotCheckTest.java | 5 +-
.../IgniteClusterSnapshotRestoreBaseTest.java | 36 +
.../IgniteClusterSnapshotRestoreSelfTest.java | 77 +-
.../snapshot/IgniteClusterSnapshotSelfTest.java | 10 +-
.../snapshot/IgniteSnapshotManagerSelfTest.java | 33 +-
.../snapshot/IgniteSnapshotRemoteRequestTest.java | 336 +++
.../IgniteSnapshotRestoreFromRemoteTest.java | 374 ++++
.../IgniteSnapshotWithMetastorageTest.java | 3 +-
.../persistence/tree/io/TrackingPageIOTest.java | 4 +-
.../wal/WalEnableDisableWithNodeShutdownTest.java | 2 +-
.../wal/WalEnableDisableWithRestartsTest.java | 4 +-
.../IgniteCacheQueryCacheDestroySelfTest.java | 2 +-
.../CacheContinuousQueryLongP2PTest.java | 2 +-
...heContinuousQueryOperationFromCallbackTest.java | 2 +-
.../CacheContinuousQueryOrderingEventTest.java | 2 +-
.../CacheContinuousQueryRandomOperationsTest.java | 2 +-
.../GridCacheContinuousQueryAbstractSelfTest.java | 9 +-
.../GridCacheContinuousQueryConcurrentTest.java | 2 +-
...cheClientWriteBehindStoreNonCoalescingTest.java | 2 +-
.../AbstractTransactionIntergrityTest.java | 2 +-
.../TxPartitionCounterStateConsistencyTest.java | 97 +-
.../TxRecoveryWithConcurrentRollbackTest.java | 2 +-
.../transactions/TxWithKeyContentionSelfTest.java | 2 +-
.../cluster/ClusterReadOnlyModeSelfTest.java | 2 +-
.../continuous/GridEventConsumeSelfTest.java | 4 +-
.../database/BPlusTreeReplaceRemoveRaceTest.java | 424 ++++
.../processors/database/BPlusTreeSelfTest.java | 36 +-
.../processors/database/IgniteDbAbstractTest.java | 2 +-
.../database/IgniteDbSingleNodeTinyPutGetTest.java | 4 +-
.../database/SwapPathConstructionSelfTest.java | 2 +-
.../datastreamer/DataStreamerImplSelfTest.java | 8 +-
.../diagnostic/DiagnosticProcessorTest.java | 10 +-
.../cache/GridCacheCommandHandlerSelfTest.java | 4 +-
.../query/GridQueryCommandHandlerTest.java | 2 +-
.../security/client/CommonSecurityCheckTest.java | 4 +-
...butedClosureRemoteSecurityContextCheckTest.java | 4 +-
.../impl/TestAdditionalSecurityProcessor.java | 4 +-
.../security/impl/TestSecurityProcessor.java | 2 +-
.../security/service/ServiceAuthorizationTest.java | 430 ++++
.../security/service/ServiceStaticConfigTest.java | 99 +
...dServiceDeploymentExceptionPropagationTest.java | 8 -
.../GridServiceProcessorBatchDeploySelfTest.java | 4 -
.../service/GridServiceProcessorStopSelfTest.java | 7 +-
...GridServiceProxyTopologyInitializationTest.java | 12 +-
.../service/IgniteServiceCallContextTest.java | 238 +++
.../IgniteServiceDynamicCachesSelfTest.java | 21 +-
.../service/IgniteServiceReassignmentTest.java | 138 --
...mentDiscoveryListenerNotificationOrderTest.java | 8 -
...mentNonSerializableStaticConfigurationTest.java | 8 -
.../service/ServiceDeploymentOnActivationTest.java | 8 -
.../ServiceDeploymentOnClientDisconnectTest.java | 8 -
.../ServiceDeploymentProcessAbstractTest.java | 8 -
...ServiceHotRedeploymentViaDeploymentSpiTest.java | 8 -
.../ServiceReassignmentFunctionSelfTest.java | 2 +-
.../internal/sql/SqlParserCreateIndexSelfTest.java | 2 +-
.../JvmConfigurationSuggestionsTest.java | 86 +
.../internal/util/collection/BitSetIntSetTest.java | 6 +-
.../internal/util/collection/IntHashMapTest.java | 4 +-
.../IpcSharedMemoryCrashDetectionSelfTest.java | 2 +-
.../util/ipc/shmem/SharedMemoryTestClient.java | 2 +-
.../ignite/internal/util/nio/GridNioSelfTest.java | 6 +-
.../util/tostring/GridToStringBuilderSelfTest.java | 2 +-
.../direct/multisplit/GridLoadTestJob.java | 2 +-
.../ignite/loadtests/dsi/GridDsiPerfJob.java | 2 +-
.../ignite/loadtests/job/GridJobLoadTestJob.java | 2 +-
.../ignite/marshaller/GridMarshallerTestBean.java | 2 +-
.../marshaller/MarshallerContextSelfTest.java | 12 +-
...2PContinuousDeploymentClientDisconnectTest.java | 6 +-
.../p2p/GridP2PContinuousDeploymentSelfTest.java | 4 +-
.../p2p/GridP2PDoubleDeploymentSelfTest.java | 4 +-
.../ignite/p2p/GridP2PLocalDeploymentSelfTest.java | 2 +-
.../p2p/GridP2PRemoteClassLoadersSelfTest.java | 8 +-
.../apache/ignite/p2p/GridP2PTimeoutSelfTest.java | 4 +-
.../platform/AbstractPlatformServiceCallTask.java | 11 +-
.../ignite/platform/PlatformComputeEchoTask.java | 2 +-
.../ignite/platform/PlatformDeployServiceTask.java | 46 +-
.../platform/PlatformIsPartitionReservedTask.java | 2 +-
.../ignite/platform/PlatformProcessUtils.java | 13 +-
.../ignite/platform/PlatformServiceCallTask.java | 6 +
.../platform/PlatformServiceCallThinTask.java | 4 +
.../PlatformThinClientConnectionsTask.java | 2 +-
.../ignite/platform/javaobject/TestJavaObject.java | 12 +-
.../ignite/plugin/AbstractTestPluginProvider.java | 2 +-
...SharedFsCheckpointSpiMultiThreadedSelfTest.java | 4 +-
.../communication/GridCacheMessageSelfTest.java | 6 +-
...unicationInverseConnectionEstablishingTest.java | 6 +-
...pCommunicationSpiConcurrentConnectSelfTest.java | 2 +-
.../tcp/GridTcpCommunicationSpiLogTest.java | 2 +-
.../spi/discovery/ClusterRebalancedMetricTest.java | 6 +-
.../IgniteDiscoveryCacheReuseSelfTest.java | 4 +-
.../spi/discovery/tcp/IgniteClientConnectTest.java | 2 +-
...cpClientDiscoverySpiFailureTimeoutSelfTest.java | 4 +-
.../tcp/TcpClientDiscoverySpiSelfTest.java | 6 +-
.../tcp/TcpDiscoveryIpFinderFailureTest.java | 2 +-
.../tcp/TcpDiscoveryNodeConsistentIdSelfTest.java | 2 +-
.../spi/discovery/tcp/TcpDiscoverySelfTest.java | 10 +-
.../AbstractTestDependencyResolver.java | 2 +-
.../apache/ignite/testframework/GridTestNode.java | 2 +-
.../apache/ignite/testframework/GridTestUtils.java | 6 +-
.../testframework/config/GridTestProperties.java | 2 +-
.../testframework/junits/GridAbstractTest.java | 2 +-
.../junits/common/GridCommonAbstractTest.java | 12 +-
.../common/GridRollingRestartAbstractTest.java | 2 +-
.../testframework/wal/record/RecordUtils.java | 8 +
.../ignite/testsuites/IgniteBasicTestSuite.java | 6 +-
.../IgniteBasicWithPersistenceTestSuite.java | 17 -
.../testsuites/IgniteBinaryObjectsTestSuite.java | 2 +
.../ignite/testsuites/IgniteCacheTestSuite7.java | 2 +
.../testsuites/IgniteClientReconnectTestSuite.java | 2 +
.../testsuites/IgniteServiceGridTestSuite.java | 2 +
.../ignite/testsuites/IgniteSnapshotTestSuite.java | 48 +
.../ignite/testsuites/SecurityTestSuite.java | 6 +-
.../ignite/thread/ThreadPoolMetricsTest.java | 1 +
...ridCommandHandlerClusterByClassTest_help.output | 4 +
...andHandlerClusterByClassWithSSLTest_help.output | 4 +
.../development/utils/IgniteWalConverter.java | 2 +-
.../utils/IgniteWalConverterArgumentsTest.java | 16 +-
modules/ducktests/tests/certs/functions.sh | 10 +-
modules/ducktests/tests/docker/Dockerfile | 2 +-
.../tests/ignitetest/services/utils/ignite_spec.py | 2 +-
.../ducktests/tests/ignitetest/utils/version.py | 3 +-
.../plugin/PlatformTestPluginProvider.java | 2 +-
.../platform/plugin/PlatformTestPluginTarget.java | 4 +-
.../query/h2/opt/GeoSpatialIndexFactory.java | 2 +-
.../query/h2/opt/GeoSpatialIndexImpl.java | 6 +-
.../processors/query/h2/opt/GeoSpatialUtils.java | 2 +-
.../query/h2/opt/GridH2SpatialIndex.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 2 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 2 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../cache/hibernate/HibernateKeyWrapper.java | 2 +-
.../cache/hibernate/IgniteEntityDataAccess.java | 2 +-
.../cache/hibernate/HibernateL2CacheSelfTest.java | 18 +-
.../HibernateL2CacheStrategySelfTest.java | 2 +-
.../hibernate/HibernateAccessStrategyFactory.java | 2 +-
.../managers/systemview/SystemViewLocal.java | 24 +-
.../processors/query/h2/CommandProcessor.java | 12 +-
.../processors/query/h2/ConnectionManager.java | 2 +-
.../query/h2/GridSubqueryJoinOptimizer.java | 10 +-
.../internal/processors/query/h2/H2Utils.java | 24 +-
.../internal/processors/query/h2/QueryParser.java | 2 +-
.../processors/query/h2/database/H2TreeIndex.java | 6 +-
.../processors/query/h2/dml/DmlAstUtils.java | 8 +-
.../internal/processors/query/h2/dml/DmlUtils.java | 10 +-
.../processors/query/h2/dml/UpdatePlan.java | 6 +-
.../processors/query/h2/dml/UpdatePlanBuilder.java | 12 +-
.../processors/query/h2/index/H2RowComparator.java | 15 +-
.../query/h2/index/QueryRowHandlerFactory.java | 2 +-
.../query/h2/index/client/ClientIndexFactory.java | 2 +-
.../query/h2/index/client/ClientInlineIndex.java | 17 +-
.../query/h2/index/keys/DateIndexKey.java | 2 +-
.../query/h2/index/keys/TimeIndexKey.java | 2 +-
.../query/h2/index/keys/TimestampIndexKey.java | 2 +-
.../processors/query/h2/opt/GridH2Table.java | 4 +-
.../query/h2/opt/GridLuceneInputStream.java | 2 +-
.../processors/query/h2/opt/H2IndexCostedBase.java | 6 +-
.../processors/query/h2/sql/GridSqlColumn.java | 2 +-
.../query/h2/sql/GridSqlQueryParser.java | 12 +-
.../processors/query/h2/sql/GridSqlTable.java | 9 +-
.../processors/query/h2/sql/SqlAstTraverser.java | 22 +-
.../query/h2/twostep/GridMapQueryExecutor.java | 85 +-
.../query/h2/twostep/msg/GridH2DmlRequest.java | 3 +-
.../query/h2/twostep/msg/GridH2DmlResponse.java | 3 +-
.../query/h2/twostep/msg/GridH2QueryRequest.java | 3 +-
.../processors/query/stat/BusyExecutor.java | 92 +-
.../processors/query/stat/CancellableTask.java} | 13 +-
.../processors/query/stat/ColumnStatistics.java | 2 +-
.../query/stat/ColumnStatisticsCollector.java | 2 +-
.../internal/processors/query/stat/Hasher.java | 28 +-
.../stat/IgniteStatisticsConfigurationManager.java | 9 +-
.../query/stat/IgniteStatisticsManagerImpl.java | 6 +-
.../stat/IgniteStatisticsPersistenceStoreImpl.java | 2 +-
.../query/stat/ObjectPartitionStatisticsImpl.java | 2 +-
.../query/stat/ObjectStatisticsImpl.java | 2 +-
.../processors/query/stat/StatisticsProcessor.java | 19 +-
.../processors/query/stat/StatisticsUtils.java | 2 +-
.../internal/processors/query/stat/hll/HLL.java | 2 +-
.../query/stat/messages/StatisticsKeyMessage.java | 2 +-
.../visor/verify/ValidateIndexesClosure.java | 10 +-
.../ignite/cache/query/IndexQueryAliasTest.java | 34 +-
.../ignite/cache/query/IndexQueryAllTypesTest.java | 29 +-
.../ignite/cache/query/IndexQueryFailoverTest.java | 8 +-
.../ignite/cache/query/IndexQueryFilterTest.java | 91 +-
.../cache/query/IndexQueryKeepBinaryTest.java | 56 +-
.../ignite/cache/query/IndexQueryLocalTest.java | 4 +-
.../cache/query/IndexQueryQueryEntityTest.java | 23 +-
.../ignite/cache/query/IndexQueryRangeTest.java | 248 +--
.../ignite/cache/query/IndexQuerySqlIndexTest.java | 41 +-
.../ignite/cache/query/MultiTableIndexQuery.java | 28 +-
.../cache/query/MultifieldIndexQueryTest.java | 333 ++-
.../cache/query/RepeatedFieldIndexQueryTest.java | 10 +-
.../org/apache/ignite/client/ClientTestSuite.java | 6 +-
.../apache/ignite/client/FunctionalQueryTest.java | 2 +-
.../ignite/client/IgniteBinaryQueryTest.java | 2 +-
.../org/apache/ignite/client/SecurityTest.java | 4 +-
.../metric/AbstractIndexPageMetricsTest.java | 2 +-
.../ignite/internal/metric/IndexPageCounter.java | 2 +-
.../IndexPagesMetricsPageDisplacementTest.java | 4 +-
.../processors/cache/BigEntryQueryTest.java | 2 +-
.../cache/GridCacheCrossCacheQuerySelfTest.java | 6 +-
.../cache/GridCacheFullTextQueryPagesTest.java | 13 +-
.../IgniteBinaryObjectQueryArgumentsTest.java | 4 +-
.../IgniteCacheAbstractInsertSqlQuerySelfTest.java | 6 +-
.../cache/IgniteCacheAbstractQuerySelfTest.java | 2 +-
.../IgniteCacheAbstractSqlDmlQuerySelfTest.java | 6 +-
.../cache/IgniteCacheUpdateSqlQuerySelfTest.java | 36 +-
.../cache/IgniteClientReconnectQueriesTest.java | 2 +-
.../encryption/EncryptedSqlTemplateTableTest.java | 2 +-
.../cache/index/AbstractIndexingCommonTest.java | 4 +-
.../cache/index/AbstractSchemaSelfTest.java | 4 +-
.../processors/cache/index/ArrayIndexTest.java | 67 +-
.../processors/cache/index/BasicIndexTest.java | 20 +-
.../index/ComplexPrimaryKeyUnwrapSelfTest.java | 43 +
...ransactionsCommandsWithMvccEnabledSelfTest.java | 2 +-
.../cache/index/SqlTransactionsSelfTest.java | 2 +-
.../index/StopNodeOnRebuildIndexFailureTest.java | 4 +-
.../cache/local/IgniteCacheLocalQuerySelfTest.java | 2 +-
.../mvcc/CacheMvccBasicContinuousQueryTest.java | 9 +-
.../mvcc/CacheMvccSqlQueriesAbstractTest.java | 2 +-
.../IgnitePdsIndexingDefragmentationTest.java | 96 +-
.../db/LongDestroyDurableBackgroundTaskTest.java | 2 +-
.../persistence/db/wal/IgniteWalRecoveryTest.java | 4 +-
...niteClusterSnapshotRestoreWithIndexingTest.java | 48 +-
.../query/ScanQueryConcurrentSqlUpdatesTest.java | 2 +-
...niteDbSingleNodeWithIndexingWalRestoreTest.java | 4 +-
.../IgnitePersistentStoreSchemaLoadTest.java | 2 +-
...actQueryTableLockAndConnectionPoolSelfTest.java | 97 +
.../query/IgniteSqlGroupConcatCollocatedTest.java | 2 +-
.../IgniteSqlGroupConcatNotCollocatedTest.java | 4 +-
.../query/IgniteSqlKeyValueFieldsTest.java | 4 +-
.../IgniteSqlQueryDecimalArgumentsWithTest.java | 125 ++
.../query/IgniteSqlSegmentedIndexSelfTest.java | 2 +-
...niteSqlSinglePartitionMultiParallelismTest.java | 6 +-
.../query/IgniteSqlSplitterSelfTest.java | 1 -
...SqlFieldTypeValidationOnKeyValueInsertTest.java | 2 +-
.../query/SqlFieldTypeValidationTypesTest.java | 4 +-
.../query/SqlNotNullKeyValueFieldTest.java | 4 +-
.../processors/query/SqlSchemaSelfTest.java | 2 +-
.../processors/query/SqlSystemViewsSelfTest.java | 2 +-
.../h2/GridSubqueryJoinOptimizerSelfTest.java | 100 +-
.../query/h2/IgniteSqlQueryMinMaxTest.java | 4 +-
.../inlinecolumn/InlineIndexColumnTest.java | 8 +-
.../query/h2/sql/GridQueryParsingTest.java | 8 +-
.../DisappearedCacheCauseRetryMessageSelfTest.java | 2 +-
...DisappearedCacheWasNotFoundMessageSelfTest.java | 2 +-
.../processors/query/stat/BusyExecutorTest.java | 160 +-
.../query/stat/ManagerStatisticsTypesTest.java | 6 +-
.../query/stat/SqlStatisticsCommandTests.java | 4 +-
.../query/stat/StatisticsAbstractTest.java | 2 +-
.../query/stat/StatisticsStorageTest.java | 8 +-
.../query/stat/StatisticsTypesAbstractTest.java | 2 +-
.../ignite/sqltests/SqlDataTypesCoverageTests.java | 7 +
.../IgniteBinaryCacheQueryTestSuite.java | 2 +
.../testsuites/IgnitePdsWithIndexingTestSuite.java | 4 -
.../IgniteSnapshotWithIndexingTestSuite.java} | 18 +-
.../ignite/cache/jta/jndi/CacheJndiTmFactory.java | 2 +-
.../ignite/cache/jta/jndi/CacheJndiTmLookup.java | 2 +-
.../cache/GridJtaLifecycleAwareSelfTest.java | 2 +-
.../TestKubernetesIpFinderDisconnection.java | 4 +-
.../ml/catboost/CatboostClassificationModel.java | 2 +-
.../ml/catboost/CatboostRegressionModel.java | 2 +-
.../org/apache/ignite/ml/h2o/H2OMojoModel.java | 10 +-
.../ignite/ml/composition/boosting/GDBModel.java | 2 +-
.../ignite/ml/dataset/feature/BucketMeta.java | 6 +-
.../impl/bootstrapping/BootstrappedVector.java | 2 +-
.../cache/util/DatasetAffinityFunctionWrapper.java | 2 +-
.../parallelism/DefaultParallelismStrategy.java | 2 +-
.../ignite/ml/inference/json/JacksonHelper.java | 2 +-
.../storage/model/DefaultModelStorage.java | 10 +-
.../ignite/ml/knn/ann/ANNClassificationModel.java | 2 +-
.../math/distances/WeightedMinkowskiDistance.java | 2 +-
.../storage/VectorizedViewMatrixStorage.java | 4 +-
.../discrete/DiscreteNaiveBayesTrainer.java | 2 +-
.../gaussian/GaussianNaiveBayesTrainer.java | 2 +-
.../onehotencoder/OneHotEncoderPreprocessor.java | 2 +-
.../normalization/NormalizationTrainer.java | 2 +-
.../logistic/LogisticRegressionSGDTrainer.java | 6 +-
.../ml/selection/cv/AbstractCrossValidation.java | 8 +-
.../org/apache/ignite/ml/structures/Dataset.java | 4 +-
.../partition/LabelPartitionDataBuilderOnHeap.java | 2 +-
.../apache/ignite/ml/util/genetic/Chromosome.java | 2 +-
.../apache/ignite/ml/common/LocalModelsTest.java | 2 +-
.../ignite/ml/knn/ANNClassificationTest.java | 8 +-
.../vector/storage/DenseVectorStorageTest.java | 2 +-
...onTreeClassificationTrainerIntegrationTest.java | 6 +-
...cisionTreeRegressionTrainerIntegrationTest.java | 6 +-
.../ml/tree/DecisionTreeRegressionTrainerTest.java | 6 +-
.../RandomForestClassifierTrainerTest.java | 4 +-
.../RandomForestRegressionTrainerTest.java | 4 +-
.../ignite/ml/util/genetic/PopulationTest.java | 4 +-
.../apache/ignite/osgi/IgniteOsgiServiceTest.java | 2 +-
modules/platforms/cpp/CMakeLists.txt | 1 -
modules/platforms/cpp/README.txt | 3 +-
modules/platforms/cpp/binary/CMakeLists.txt | 12 +-
modules/platforms/cpp/cmake/FindIgnite.cmake | 24 +-
modules/platforms/cpp/cmake/FindODBC.cmake | 14 +-
modules/platforms/cpp/common/CMakeLists.txt | 12 +-
.../platforms/cpp/core-test/src/affinity_test.cpp | 2 +-
modules/platforms/cpp/core/CMakeLists.txt | 27 +-
.../cpp/{jni => core}/include/ignite/jni/java.h | 2 +-
.../cpp/{jni => core}/include/ignite/jni/utils.h | 39 +-
modules/platforms/cpp/core/src/ignition.cpp | 2 -
.../cpp/core/src/impl/ignite_environment.cpp | 2 +-
.../cpp/{jni/src => core/src/jni}/java.cpp | 2 +-
.../linux/src => core/src/jni/os/linux}/utils.cpp | 4 +-
.../os/win/src => core/src/jni/os/win}/utils.cpp | 0
.../cpp/examples/compute-example/CMakeLists.txt | 3 +-
.../continuous-query-example/CMakeLists.txt | 3 +-
.../cpp/examples/odbc-example/CMakeLists.txt | 4 +-
.../cpp/examples/put-get-example/CMakeLists.txt | 3 +-
.../cpp/examples/query-example/CMakeLists.txt | 3 +-
.../thin-client-put-get-example/CMakeLists.txt | 3 +-
modules/platforms/cpp/jni/CMakeLists.txt | 56 -
.../platforms/cpp/jni/include/ignite/jni/exports.h | 59 -
modules/platforms/cpp/jni/src/exports.cpp | 116 --
modules/platforms/cpp/network/CMakeLists.txt | 12 +-
modules/platforms/cpp/odbc-test/README.TXT | 1 -
modules/platforms/cpp/odbc/CMakeLists.txt | 6 +-
modules/platforms/cpp/thin-client/CMakeLists.txt | 8 +-
.../Apache.Ignite.Core.Tests.DotNetCore.csproj | 3 +
.../Binary/TypeNameParserTest.cs | 22 +-
.../Binary/TypeResolverTest.cs | 24 +-
.../Cache/Platform/PlatformCacheTest.cs | 1 +
.../Client/ClientConnectionTest.cs | 103 +-
.../ClientProtocolCompatibilityTest.cs | 6 +-
.../Client/Datastream/DataStreamerClientTest.cs | 72 +
.../Client/RawSecureSocketTest.cs | 63 +-
.../Client/RawSocketTest.cs | 34 +-
...-ssl.xml => server-with-ssl-no-client-auth.xml} | 6 +-
.../Config/Client/server-with-ssl.xml | 2 +-
.../Dataload/DataStreamerTest.cs | 62 +
.../Examples/ExamplesTestBase.cs | 14 +-
.../dotnet/Apache.Ignite.Core.Tests/JavaServer.cs | 3 +
.../Services/CallPlatformServiceTest.cs | 14 +-
.../Services/IJavaService.cs | 3 +
.../Services/JavaServiceDynamicProxy.cs | 6 +
.../Services/PlatformTestService.cs | 10 +
.../Services/ServiceProxyTest.cs | 11 +-
.../Services/ServicesAsyncWrapper.cs | 14 +-
.../Services/ServicesTest.cs | 107 +-
.../Apache.Ignite.Core.Tests/TestUtilsJni.cs | 13 +-
.../Apache.Ignite.Core/Client/SslStreamFactory.cs | 9 +-
.../Common/IgniteExperimentalAttribute.cs | 4 +-
.../Impl/Binary/BinaryHashCodeUtils.cs | 5 +
.../Impl/Binary/TypeNameParser.cs | 20 +
.../Apache.Ignite.Core/Impl/Binary/TypeResolver.cs | 5 -
.../Impl/Services/ServiceCallContext.cs | 64 +
.../Impl/Services/ServiceContext.cs | 20 +-
.../Impl/Services/ServiceProxySerializer.cs | 12 +-
.../Apache.Ignite.Core/Impl/Services/Services.cs | 36 +-
.../Apache.Ignite.Core/Impl/Unmanaged/Jni/Jvm.cs | 4 +-
.../Impl/Unmanaged/UnmanagedCallbacks.cs | 22 +-
.../Services/IServiceCallContext.cs | 78 +
.../Apache.Ignite.Core/Services/IServiceContext.cs | 9 +
.../Apache.Ignite.Core/Services/IServices.cs | 31 +
.../Services/ServiceCallContextBuilder.cs | 81 +
.../http/jetty/GridJettyObjectMapper.java | 15 +
.../jdbc/CacheJdbcBlobStoreFactorySelfTest.java | 2 +-
.../GridServiceContextInjectionSelfTest.java | 246 +++
.../p2p/GridP2PUserVersionChangeSelfTest.java | 6 +-
...gniteSpringBeanSpringResourceInjectionTest.java | 2 +-
.../testsuites/IgniteResourceSelfTestSuite.java | 2 +
.../surefire/testsuites/IgniteTestsProvider.java | 2 +-
.../ignite/cache/websession/WebSessionFilter.java | 6 +-
.../internal/websession/WebSessionSelfTest.java | 10 +-
.../cache/IgniteBinaryIdentityBenchmark.java | 2 +-
.../cache/dml/IgniteSqlMergeQueryBenchmark.java | 4 +-
.../thin/cache/IgniteThinBenchmarkUtils.java | 4 +-
.../yarn/IgniteApplicationMasterSelfTest.java | 4 +-
.../zk/internal/ZookeeperClusterNode.java | 4 +-
.../tcp/ipfinder/zk/ZookeeperIpFinderTest.java | 2 +-
...ZookeeperDiscoveryCommunicationFailureTest.java | 2 +-
.../internal/ZookeeperDiscoverySpiSslTestBase.java | 2 +-
996 files changed, 16748 insertions(+), 7944 deletions(-)
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
index 049aff6,0000000..77ef1bf
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java
@@@ -1,417 -1,0 +1,417 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import org.apache.calcite.DataContexts;
+import org.apache.calcite.config.Lex;
+import org.apache.calcite.config.NullCollation;
+import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.hint.HintStrategyTable;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.util.SqlOperatorTables;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.calcite.tools.FrameworkConfig;
+import org.apache.calcite.tools.Frameworks;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.GridProcessorAdapter;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.failure.FailureProcessor;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.QueryContext;
+import org.apache.ignite.internal.processors.query.QueryEngine;
+import org.apache.ignite.internal.processors.query.RunningQuery;
+import org.apache.ignite.internal.processors.query.calcite.exec.ArrayRowHandler;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExchangeService;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExchangeServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionService;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.exec.MailboxRegistry;
+import org.apache.ignite.internal.processors.query.calcite.exec.MailboxRegistryImpl;
+import org.apache.ignite.internal.processors.query.calcite.exec.QueryTaskExecutor;
+import org.apache.ignite.internal.processors.query.calcite.exec.QueryTaskExecutorImpl;
+import org.apache.ignite.internal.processors.query.calcite.exec.exp.RexExecutorImpl;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageService;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.metadata.MappingService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.MappingServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.metadata.cost.IgniteCostFactory;
+import org.apache.ignite.internal.processors.query.calcite.prepare.CacheKey;
+import org.apache.ignite.internal.processors.query.calcite.prepare.IgniteConvertletTable;
+import org.apache.ignite.internal.processors.query.calcite.prepare.IgniteTypeCoercion;
+import org.apache.ignite.internal.processors.query.calcite.prepare.PrepareServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCache;
+import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCacheImpl;
+import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolder;
+import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolderImpl;
+import org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlConformance;
+import org.apache.ignite.internal.processors.query.calcite.sql.IgniteSqlParserImpl;
+import org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteOwnSqlOperatorTable;
+import org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteStdSqlOperatorTable;
+import org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTraitDef;
+import org.apache.ignite.internal.processors.query.calcite.trait.DistributionTraitDef;
+import org.apache.ignite.internal.processors.query.calcite.trait.RewindabilityTraitDef;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.processors.query.calcite.util.LifecycleAware;
+import org.apache.ignite.internal.processors.query.calcite.util.Service;
+import org.jetbrains.annotations.Nullable;
+
+/** */
+public class CalciteQueryProcessor extends GridProcessorAdapter implements QueryEngine {
+ /** */
+ public static final FrameworkConfig FRAMEWORK_CONFIG = Frameworks.newConfigBuilder()
+ .executor(new RexExecutorImpl(DataContexts.EMPTY))
+ .sqlToRelConverterConfig(SqlToRelConverter.config()
+ .withTrimUnusedFields(true)
+ // currently SqlToRelConverter creates not optimal plan for both optimization and execution
+ // so it's better to disable such rewriting right now
+ // TODO: remove this after IGNITE-14277
+ .withInSubQueryThreshold(Integer.MAX_VALUE)
+ .withDecorrelationEnabled(true)
+ .withExpand(false)
+ .withHintStrategyTable(
+ HintStrategyTable.builder()
+ .hintStrategy("DISABLE_RULE", (hint, rel) -> true)
+ .hintStrategy("EXPAND_DISTINCT_AGG", (hint, rel) -> rel instanceof Aggregate)
+ .build()
+ )
+ )
+ .convertletTable(IgniteConvertletTable.INSTANCE)
+ .parserConfig(
+ SqlParser.config()
+ .withParserFactory(IgniteSqlParserImpl.FACTORY)
+ .withLex(Lex.ORACLE)
+ .withConformance(IgniteSqlConformance.INSTANCE))
+ .sqlValidatorConfig(SqlValidator.Config.DEFAULT
+ .withIdentifierExpansion(true)
+ .withDefaultNullCollation(NullCollation.LOW)
+ .withSqlConformance(IgniteSqlConformance.INSTANCE)
+ .withTypeCoercionFactory(IgniteTypeCoercion::new))
+ // Dialects support.
+ .operatorTable(SqlOperatorTables.chain(IgniteStdSqlOperatorTable.INSTANCE, IgniteOwnSqlOperatorTable.instance()))
+ // Context provides a way to store data within the planner session that can be accessed in planner rules.
+ .context(Contexts.empty())
+ // Custom cost factory to use during optimization
+ .costFactory(new IgniteCostFactory())
+ .typeSystem(IgniteTypeSystem.INSTANCE)
+ .traitDefs(new RelTraitDef<?>[] {
+ ConventionTraitDef.INSTANCE,
+ RelCollationTraitDef.INSTANCE,
+ DistributionTraitDef.INSTANCE,
+ RewindabilityTraitDef.INSTANCE,
+ CorrelationTraitDef.INSTANCE,
+ })
+ .build();
+
+ /** */
+ private final QueryPlanCache qryPlanCache;
+
+ /** */
+ private final QueryTaskExecutor taskExecutor;
+
+ /** */
+ private final FailureProcessor failureProcessor;
+
+ /** */
+ private final AffinityService partSvc;
+
+ /** */
+ private final SchemaHolder schemaHolder;
+
+ /** */
+ private final MessageService msgSvc;
+
+ /** */
+ private final ExchangeService exchangeSvc;
+
+ /** */
+ private final MappingService mappingSvc;
+
+ /** */
+ private final MailboxRegistry mailboxRegistry;
+
+ /** */
+ private final ExecutionService<Object[]> executionSvc;
+
+ /** */
+ private final PrepareServiceImpl prepareSvc;
+
+ /** */
+ private final QueryRegistry qryReg;
+
+ /**
+ * @param ctx Kernal context.
+ */
+ public CalciteQueryProcessor(GridKernalContext ctx) {
+ super(ctx);
+
+ failureProcessor = ctx.failure();
+ schemaHolder = new SchemaHolderImpl(ctx);
+ qryPlanCache = new QueryPlanCacheImpl(ctx);
+ mailboxRegistry = new MailboxRegistryImpl(ctx);
+ taskExecutor = new QueryTaskExecutorImpl(ctx);
+ executionSvc = new ExecutionServiceImpl<>(ctx, ArrayRowHandler.INSTANCE);
+ partSvc = new AffinityServiceImpl(ctx);
+ msgSvc = new MessageServiceImpl(ctx);
+ mappingSvc = new MappingServiceImpl(ctx);
+ exchangeSvc = new ExchangeServiceImpl(ctx);
+ prepareSvc = new PrepareServiceImpl(ctx);
+ qryReg = new QueryRegistryImpl(ctx.log(QueryRegistry.class));
+ }
+
+ /**
+ * @return Affinity service.
+ */
+ public AffinityService affinityService() {
+ return partSvc;
+ }
+
+ /**
+ * @return Query cache.
+ */
+ public QueryPlanCache queryPlanCache() {
+ return qryPlanCache;
+ }
+
+ /**
+ * @return Task executor.
+ */
+ public QueryTaskExecutor taskExecutor() {
+ return taskExecutor;
+ }
+
+ /**
+ * @return Schema holder.
+ */
+ public SchemaHolder schemaHolder() {
+ return schemaHolder;
+ }
+
+ /**
+ * @return Message service.
+ */
+ public MessageService messageService() {
+ return msgSvc;
+ }
+
+ /**
+ * @return Mapping service.
+ */
+ public MappingService mappingService() {
+ return mappingSvc;
+ }
+
+ /**
+ * @return Exchange service.
+ */
+ public ExchangeService exchangeService() {
+ return exchangeSvc;
+ }
+
+ /**
+ * @return Mailbox registry.
+ */
+ public MailboxRegistry mailboxRegistry() {
+ return mailboxRegistry;
+ }
+
+ /**
+ * @return Failure processor.
+ */
+ public FailureProcessor failureProcessor() {
+ return failureProcessor;
+ }
+
+ /** */
+ public PrepareServiceImpl prepareService() {
+ return prepareSvc;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void start() {
+ onStart(ctx,
+ executionSvc,
+ mailboxRegistry,
+ partSvc,
+ schemaHolder,
+ msgSvc,
+ taskExecutor,
+ mappingSvc,
+ qryPlanCache,
+ exchangeSvc,
+ qryReg
+ );
+ }
+
+ /** {@inheritDoc} */
+ @Override public void stop(boolean cancel) {
+ onStop(
+ qryReg,
+ executionSvc,
+ mailboxRegistry,
+ partSvc,
+ schemaHolder,
+ msgSvc,
+ taskExecutor,
+ mappingSvc,
+ qryPlanCache,
+ exchangeSvc
+ );
+ }
+
+ /** {@inheritDoc} */
+ @Override public List<FieldsQueryCursor<List<?>>> query(
+ @Nullable QueryContext qryCtx,
+ @Nullable String schemaName,
+ String sql,
+ Object... params
+ ) throws IgniteSQLException {
+ SchemaPlus schema = schemaHolder.schema(schemaName);
+
+ QueryPlan plan = queryPlanCache().queryPlan(new CacheKey(schema.getName(), sql));
+
+ if (plan != null) {
+ RootQuery<Object[]> qry = new RootQuery<>(
+ sql,
+ schema,
+ params,
+ qryCtx,
+ exchangeSvc,
+ (q) -> qryReg.unregister(q.id()),
+ log
+ );
+
+ qryReg.register(qry);
+
+ try {
+ return Collections.singletonList(executionSvc.executePlan(
+ qry,
+ plan
+ ));
+ }
+ catch (Exception e) {
+ boolean isCanceled = qry.isCancelled();
+
+ qry.cancel();
+
+ qryReg.unregister(qry.id());
+
+ if (isCanceled)
+ throw new IgniteSQLException("The query was cancelled while planning", IgniteQueryErrorCode.QUERY_CANCELED, e);
+ else
+ throw e;
+
+ }
+ }
+
+ SqlNodeList qryList = Commons.parse(sql, FRAMEWORK_CONFIG.getParserConfig());
+ List<FieldsQueryCursor<List<?>>> cursors = new ArrayList<>(qryList.size());
+
+ List<RootQuery<Object[]>> qrys = new ArrayList<>(qryList.size());
+
+ for (final SqlNode sqlNode: qryList) {
+ RootQuery<Object[]> qry = new RootQuery<>(
+ sqlNode.toString(),
+ schemaHolder.schema(schemaName), // Update schema for each query in multiple statements.
+ params,
+ qryCtx,
+ exchangeSvc,
+ (q) -> qryReg.unregister(q.id()),
+ log
+ );
+
+ qrys.add(qry);
+
+ qryReg.register(qry);
+
+ try {
+ if (qryList.size() == 1) {
+ plan = queryPlanCache().queryPlan(
+ new CacheKey(schemaName, qry.sql()),
+ () -> prepareSvc.prepareSingle(sqlNode, qry.planningContext()));
+ }
+ else
+ plan = prepareSvc.prepareSingle(sqlNode, qry.planningContext());
+
+ cursors.add(executionSvc.executePlan(qry, plan));
+ }
+ catch (Exception e) {
+ boolean isCanceled = qry.isCancelled();
+
+ qrys.forEach(RootQuery::cancel);
+
+ qryReg.unregister(qry.id());
+
+ if (isCanceled)
+ throw new IgniteSQLException("The query was cancelled while planning", IgniteQueryErrorCode.QUERY_CANCELED, e);
+ else
+ throw e;
+ }
+ }
+
+ return cursors;
+ }
+
+ /** */
+ private void onStart(GridKernalContext ctx, Service... services) {
+ for (Service service : services) {
+ if (service instanceof LifecycleAware)
- ((LifecycleAware) service).onStart(ctx);
++ ((LifecycleAware)service).onStart(ctx);
+ }
+ }
+
+ /** */
+ private void onStop(Service... services) {
+ for (Service service : services) {
+ if (service instanceof LifecycleAware)
- ((LifecycleAware) service).onStop();
++ ((LifecycleAware)service).onStop();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public RunningQuery runningQuery(UUID id) {
+ return qryReg.query(id);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<? extends RunningQuery> runningQueries() {
+ return qryReg.runningQueries();
+ }
+
+ /** */
+ public QueryRegistry queryRegistry() {
+ return qryReg;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/RemoteFragmentKey.java
index 9b1eac7,0000000..a2a0c64
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/RemoteFragmentKey.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/RemoteFragmentKey.java
@@@ -1,66 -1,0 +1,66 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite;
+
+import java.util.UUID;
+
+/** */
+final class RemoteFragmentKey {
+ /** */
+ private final UUID nodeId;
+
+ /** */
+ private final long fragmentId;
+
+ /** */
+ RemoteFragmentKey(UUID nodeId, long fragmentId) {
+ this.nodeId = nodeId;
+ this.fragmentId = fragmentId;
+ }
+
+ /** */
+ public UUID nodeId() {
+ return nodeId;
+ }
+
+ /** */
+ public long fragmentId() {
+ return fragmentId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
- RemoteFragmentKey that = (RemoteFragmentKey) o;
++ RemoteFragmentKey that = (RemoteFragmentKey)o;
+
+ if (fragmentId != that.fragmentId)
+ return false;
+ return nodeId.equals(that.nodeId);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = nodeId.hashCode();
- res = 31 * res + (int) (fragmentId ^ (fragmentId >>> 32));
++ res = 31 * res + (int)(fragmentId ^ (fragmentId >>> 32));
+ return res;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
index bd942552,0000000..abb45d2
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java
@@@ -1,283 -1,0 +1,283 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.query.RunningQuery;
+import org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
+import org.apache.ignite.internal.processors.query.calcite.QueryRegistry;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Inbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Outbox;
+import org.apache.ignite.internal.processors.query.calcite.message.ErrorMessage;
+import org.apache.ignite.internal.processors.query.calcite.message.InboxCloseMessage;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageService;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageType;
+import org.apache.ignite.internal.processors.query.calcite.message.QueryBatchAcknowledgeMessage;
+import org.apache.ignite.internal.processors.query.calcite.message.QueryBatchMessage;
+import org.apache.ignite.internal.processors.query.calcite.message.QueryCloseMessage;
+import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentDescription;
+import org.apache.ignite.internal.processors.query.calcite.prepare.BaseQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ *
+ */
+public class ExchangeServiceImpl extends AbstractService implements ExchangeService {
+ /** */
+ private final UUID locaNodeId;
+
+ /** */
+ private QueryTaskExecutor taskExecutor;
+
+ /** */
+ private MailboxRegistry mailboxRegistry;
+
+ /** */
+ private MessageService msgSvc;
+
+ /** */
+ private QueryRegistry qryRegistry;
+
+ /**
+ * @param ctx Kernal context.
+ */
+ public ExchangeServiceImpl(GridKernalContext ctx) {
+ super(ctx);
+
+ locaNodeId = ctx.localNodeId();
+ }
+
+ /**
+ * @param taskExecutor Task executor.
+ */
+ public void taskExecutor(QueryTaskExecutor taskExecutor) {
+ this.taskExecutor = taskExecutor;
+ }
+
+ /**
+ * @return Task executor.
+ */
+ public QueryTaskExecutor taskExecutor() {
+ return taskExecutor;
+ }
+
+ /**
+ * @param mailboxRegistry Mailbox registry.
+ */
+ public void mailboxRegistry(MailboxRegistry mailboxRegistry) {
+ this.mailboxRegistry = mailboxRegistry;
+ }
+
+ /**
+ * @return Mailbox registry.
+ */
+ public MailboxRegistry mailboxRegistry() {
+ return mailboxRegistry;
+ }
+
+ /**
+ * @param msgSvc Message service.
+ */
+ public void messageService(MessageService msgSvc) {
+ this.msgSvc = msgSvc;
+ }
+
+ /**
+ * @return Message service.
+ */
+ public MessageService messageService() {
+ return msgSvc;
+ }
+
+ /** */
+ public void queryRegistry(QueryRegistry qryRegistry) {
+ this.qryRegistry = qryRegistry;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> void sendBatch(UUID nodeId, UUID qryId, long fragmentId, long exchangeId, int batchId,
+ boolean last, List<Row> rows) throws IgniteCheckedException {
+ messageService().send(nodeId, new QueryBatchMessage(qryId, fragmentId, exchangeId, batchId, last, Commons.cast(rows)));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void acknowledge(UUID nodeId, UUID qryId, long fragmentId, long exchangeId, int batchId)
+ throws IgniteCheckedException {
+ messageService().send(nodeId, new QueryBatchAcknowledgeMessage(qryId, fragmentId, exchangeId, batchId));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void closeQuery(UUID nodeId, UUID qryId) throws IgniteCheckedException {
+ messageService().send(nodeId, new QueryCloseMessage(qryId));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void closeInbox(UUID nodeId, UUID qryId, long fragmentId, long exchangeId) throws IgniteCheckedException {
+ messageService().send(nodeId, new InboxCloseMessage(qryId, fragmentId, exchangeId));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void sendError(UUID nodeId, UUID qryId, long fragmentId, Throwable err) throws IgniteCheckedException {
+ messageService().send(nodeId, new ErrorMessage(qryId, fragmentId, err));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onStart(GridKernalContext ctx) {
+ CalciteQueryProcessor proc =
+ Objects.requireNonNull(Commons.lookupComponent(ctx, CalciteQueryProcessor.class));
+
+ taskExecutor(proc.taskExecutor());
+ mailboxRegistry(proc.mailboxRegistry());
+ messageService(proc.messageService());
+ queryRegistry(proc.queryRegistry());
+
+ init();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void init() {
- messageService().register((n, m) -> onMessage(n, (InboxCloseMessage) m), MessageType.QUERY_INBOX_CANCEL_MESSAGE);
- messageService().register((n, m) -> onMessage(n, (QueryBatchAcknowledgeMessage) m), MessageType.QUERY_ACKNOWLEDGE_MESSAGE);
- messageService().register((n, m) -> onMessage(n, (QueryBatchMessage) m), MessageType.QUERY_BATCH_MESSAGE);
- messageService().register((n, m) -> onMessage(n, (QueryCloseMessage) m), MessageType.QUERY_CLOSE_MESSAGE);
++ messageService().register((n, m) -> onMessage(n, (InboxCloseMessage)m), MessageType.QUERY_INBOX_CANCEL_MESSAGE);
++ messageService().register((n, m) -> onMessage(n, (QueryBatchAcknowledgeMessage)m), MessageType.QUERY_ACKNOWLEDGE_MESSAGE);
++ messageService().register((n, m) -> onMessage(n, (QueryBatchMessage)m), MessageType.QUERY_BATCH_MESSAGE);
++ messageService().register((n, m) -> onMessage(n, (QueryCloseMessage)m), MessageType.QUERY_CLOSE_MESSAGE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean alive(UUID nodeId) {
+ return messageService().alive(nodeId);
+ }
+
+ /** */
+ protected void onMessage(UUID nodeId, InboxCloseMessage msg) {
+ Collection<Inbox<?>> inboxes = mailboxRegistry().inboxes(msg.queryId(), msg.fragmentId(), msg.exchangeId());
+
+ if (!F.isEmpty(inboxes)) {
+ for (Inbox<?> inbox : inboxes)
+ inbox.context().execute(inbox::close, inbox::onError);
+ }
+ else if (log.isDebugEnabled()) {
+ log.debug("Stale inbox cancel message received: [" +
+ "nodeId=" + nodeId +
+ ", queryId=" + msg.queryId() +
+ ", fragmentId=" + msg.fragmentId() +
+ ", exchangeId=" + msg.exchangeId() + "]");
+ }
+ }
+
+ /** */
+ protected void onMessage(UUID nodeId, QueryCloseMessage msg) {
+ RunningQuery qry = qryRegistry.query(msg.queryId());
+
+ if (qry != null)
+ qry.cancel();
+ else {
+ log.warning("Stale query close message received: [" +
+ "nodeId=" + nodeId +
+ ", queryId=" + msg.queryId() + "]");
+ }
+ }
+
+ /** */
+ protected void onMessage(UUID nodeId, QueryBatchAcknowledgeMessage msg) {
+ Outbox<?> outbox = mailboxRegistry().outbox(msg.queryId(), msg.exchangeId());
+
+ if (outbox != null) {
+ try {
+ outbox.onAcknowledge(nodeId, msg.batchId());
+ }
+ catch (Throwable e) {
+ outbox.onError(e);
+
+ throw new IgniteException("Unexpected exception", e);
+ }
+ }
+ else if (log.isDebugEnabled()) {
+ log.debug("Stale acknowledge message received: [" +
+ "nodeId=" + nodeId + ", " +
+ "queryId=" + msg.queryId() + ", " +
+ "fragmentId=" + msg.fragmentId() + ", " +
+ "exchangeId=" + msg.exchangeId() + ", " +
+ "batchId=" + msg.batchId() + "]");
+ }
+ }
+
+ /** */
+ protected void onMessage(UUID nodeId, QueryBatchMessage msg) {
+ Inbox<?> inbox = mailboxRegistry().inbox(msg.queryId(), msg.exchangeId());
+
+ if (inbox == null && msg.batchId() == 0) {
+ // first message sent before a fragment is built
+ // note that an inbox source fragment id is also used as an exchange id
+ Inbox<?> newInbox = new Inbox<>(baseInboxContext(nodeId, msg.queryId(), msg.fragmentId()),
+ this, mailboxRegistry(), msg.exchangeId(), msg.exchangeId());
+
+ inbox = mailboxRegistry().register(newInbox);
+ }
+
+ if (inbox != null) {
+ try {
+ inbox.onBatchReceived(nodeId, msg.batchId(), msg.last(), Commons.cast(msg.rows()));
+ }
+ catch (Throwable e) {
+ inbox.onError(e);
+
+ throw new IgniteException("Unexpected exception", e);
+ }
+ }
+ else if (log.isDebugEnabled()) {
+ log.debug("Stale batch message received: [" +
+ "nodeId=" + nodeId + ", " +
+ "queryId=" + msg.queryId() + ", " +
+ "fragmentId=" + msg.fragmentId() + ", " +
+ "exchangeId=" + msg.exchangeId() + ", " +
+ "batchId=" + msg.batchId() + "]");
+ }
+ }
+
+ /**
+ * @return Minimal execution context to meet Inbox needs.
+ */
+ private ExecutionContext<?> baseInboxContext(UUID nodeId, UUID qryId, long fragmentId) {
+ return new ExecutionContext<>(
+ BaseQueryContext.builder()
+ .logger(log)
+ .build(),
+ taskExecutor(),
+ qryId,
+ locaNodeId,
+ nodeId,
+ null,
+ new FragmentDescription(
+ fragmentId,
+ null,
+ null,
+ null),
+ null,
+ ImmutableMap.of());
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
index 41ef0b1,0000000..2f429a5
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java
@@@ -1,724 -1,0 +1,724 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.tools.Frameworks;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.managers.eventstorage.DiscoveryEventListener;
+import org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager;
+import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.failure.FailureProcessor;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.QueryState;
+import org.apache.ignite.internal.processors.query.RunningQuery;
+import org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
+import org.apache.ignite.internal.processors.query.calcite.Query;
+import org.apache.ignite.internal.processors.query.calcite.QueryRegistry;
+import org.apache.ignite.internal.processors.query.calcite.RootQuery;
+import org.apache.ignite.internal.processors.query.calcite.RunningFragment;
+import org.apache.ignite.internal.processors.query.calcite.exec.ddl.DdlCommandHandler;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Inbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Node;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Outbox;
+import org.apache.ignite.internal.processors.query.calcite.message.ErrorMessage;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageService;
+import org.apache.ignite.internal.processors.query.calcite.message.MessageType;
+import org.apache.ignite.internal.processors.query.calcite.message.QueryStartRequest;
+import org.apache.ignite.internal.processors.query.calcite.message.QueryStartResponse;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentDescription;
+import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentMapping;
+import org.apache.ignite.internal.processors.query.calcite.metadata.MappingService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.RemoteException;
+import org.apache.ignite.internal.processors.query.calcite.prepare.BaseQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.prepare.CacheKey;
+import org.apache.ignite.internal.processors.query.calcite.prepare.DdlPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.ExplainPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.FieldsMetadata;
+import org.apache.ignite.internal.processors.query.calcite.prepare.FieldsMetadataImpl;
+import org.apache.ignite.internal.processors.query.calcite.prepare.Fragment;
+import org.apache.ignite.internal.processors.query.calcite.prepare.FragmentPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.prepare.MultiStepPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.PlanningContext;
+import org.apache.ignite.internal.processors.query.calcite.prepare.PrepareServiceImpl;
+import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlan;
+import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCache;
+import org.apache.ignite.internal.processors.query.calcite.prepare.ddl.CreateTableCommand;
+import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolder;
+import org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.processors.query.calcite.util.ListFieldsQueryCursor;
+import org.apache.ignite.internal.processors.query.calcite.util.TypeUtils;
+import org.apache.ignite.internal.processors.query.h2.H2Utils;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import static java.util.Collections.singletonList;
+import static org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor.FRAMEWORK_CONFIG;
+import static org.apache.ignite.internal.processors.query.calcite.externalize.RelJsonReader.fromJson;
+
+/**
+ *
+ */
+@SuppressWarnings("TypeMayBeWeakened")
+public class ExecutionServiceImpl<Row> extends AbstractService implements ExecutionService<Row> {
+ /** */
+ private final DiscoveryEventListener discoLsnr;
+
+ /** */
+ private UUID locNodeId;
+
+ /** */
+ private GridEventStorageManager evtMgr;
+
+ /** */
+ private GridCachePartitionExchangeManager<?, ?> exchangeMgr;
+
+ /** */
+ private QueryPlanCache qryPlanCache;
+
+ /** */
+ private SchemaHolder schemaHolder;
+
+ /** */
+ private QueryTaskExecutor taskExecutor;
+
+ /** */
+ private FailureProcessor failureProcessor;
+
+ /** */
+ private AffinityService partSvc;
+
+ /** */
+ private MailboxRegistry mailboxRegistry;
+
+ /** */
+ private MappingService mappingSvc;
+
+ /** */
+ private MessageService msgSvc;
+
+ /** */
+ private ExchangeService exchangeSvc;
+
+ /** */
+ private PrepareServiceImpl prepareSvc;
+
+ /** */
+ private ClosableIteratorsHolder iteratorsHolder;
+
+ /** */
+ private QueryRegistry qryReg;
+
+ /** */
+ private final RowHandler<Row> handler;
+
+ /** */
+ private final DdlCommandHandler ddlCmdHnd;
+
+ /**
+ * @param ctx Kernal.
+ */
+ public ExecutionServiceImpl(GridKernalContext ctx, RowHandler<Row> handler) {
+ super(ctx);
+ this.handler = handler;
+
+ discoLsnr = (e, c) -> onNodeLeft(e.eventNode().id());
+
+ ddlCmdHnd = new DdlCommandHandler(
+ ctx::query, ctx.cache(), ctx.security(), () -> schemaHolder().schema(null)
+ );
+ }
+
+ /**
+ * @param locNodeId Local node ID.
+ */
+ public void localNodeId(UUID locNodeId) {
+ this.locNodeId = locNodeId;
+ }
+
+ /**
+ * @return Local node ID.
+ */
+ public UUID localNodeId() {
+ return locNodeId;
+ }
+
+ /**
+ * @param qryPlanCache Query cache.
+ */
+ public void queryPlanCache(QueryPlanCache qryPlanCache) {
+ this.qryPlanCache = qryPlanCache;
+ }
+
+ /**
+ * @return Query cache.
+ */
+ public QueryPlanCache queryPlanCache() {
+ return qryPlanCache;
+ }
+
+ /**
+ * @param schemaHolder Schema holder.
+ */
+ public void schemaHolder(SchemaHolder schemaHolder) {
+ this.schemaHolder = schemaHolder;
+ }
+
+ /**
+ * @return Schema holder.
+ */
+ public SchemaHolder schemaHolder() {
+ return schemaHolder;
+ }
+
+ /**
+ * @param taskExecutor Task executor.
+ */
+ public void taskExecutor(QueryTaskExecutor taskExecutor) {
+ this.taskExecutor = taskExecutor;
+ }
+
+ /**
+ * @return Task executor.
+ */
+ public QueryTaskExecutor taskExecutor() {
+ return taskExecutor;
+ }
+
+ /**
+ * @param failureProcessor Failure processor.
+ */
+ public void failureProcessor(FailureProcessor failureProcessor) {
+ this.failureProcessor = failureProcessor;
+ }
+
+ /**
+ * @return Failure processor.
+ */
+ public FailureProcessor failureProcessor() {
+ return failureProcessor;
+ }
+
+ /**
+ * @param partSvc Partition service.
+ */
+ public void partitionService(AffinityService partSvc) {
+ this.partSvc = partSvc;
+ }
+
+ /**
+ * @return Partition service.
+ */
+ public AffinityService partitionService() {
+ return partSvc;
+ }
+
+ /**
+ * @param mailboxRegistry Mailbox registry.
+ */
+ public void mailboxRegistry(MailboxRegistry mailboxRegistry) {
+ this.mailboxRegistry = mailboxRegistry;
+ }
+
+ /**
+ * @return Mailbox registry.
+ */
+ public MailboxRegistry mailboxRegistry() {
+ return mailboxRegistry;
+ }
+
+ /**
+ * @param mappingSvc Mapping service.
+ */
+ public void mappingService(MappingService mappingSvc) {
+ this.mappingSvc = mappingSvc;
+ }
+
+ /**
+ * @return Mapping service.
+ */
+ public MappingService mappingService() {
+ return mappingSvc;
+ }
+
+ /**
+ * @param msgSvc Message service.
+ */
+ public void messageService(MessageService msgSvc) {
+ this.msgSvc = msgSvc;
+ }
+
+ /**
+ * @return Message service.
+ */
+ public MessageService messageService() {
+ return msgSvc;
+ }
+
+ /**
+ * @param exchangeSvc Exchange service.
+ */
+ public void exchangeService(ExchangeService exchangeSvc) {
+ this.exchangeSvc = exchangeSvc;
+ }
+
+ /**
+ * @param prepareSvc Prepare service.
+ */
+ public void prepareService(PrepareServiceImpl prepareSvc) {
+ this.prepareSvc = prepareSvc;
+ }
+
+ /**
+ * @return Exchange service.
+ */
+ public ExchangeService exchangeService() {
+ return exchangeSvc;
+ }
+
+ /**
+ * @param evtMgr Event manager.
+ */
+ public void eventManager(GridEventStorageManager evtMgr) {
+ this.evtMgr = evtMgr;
+ }
+
+ /**
+ * @return Event manager.
+ */
+ public GridEventStorageManager eventManager() {
+ return evtMgr;
+ }
+
+ /**
+ * @param exchangeMgr Exchange manager.
+ */
+ public void exchangeManager(GridCachePartitionExchangeManager<?, ?> exchangeMgr) {
+ this.exchangeMgr = exchangeMgr;
+ }
+
+ /**
+ * @return Exchange manager.
+ */
+ public GridCachePartitionExchangeManager<?, ?> exchangeManager() {
+ return exchangeMgr;
+ }
+
+ /**
+ * @param iteratorsHolder Iterators holder.
+ */
+ public void iteratorsHolder(ClosableIteratorsHolder iteratorsHolder) {
+ this.iteratorsHolder = iteratorsHolder;
+ }
+
+ /**
+ * @return Iterators holder.
+ */
+ public ClosableIteratorsHolder iteratorsHolder() {
+ return iteratorsHolder;
+ }
+
+ /** */
+ public void queryRegistry(QueryRegistry qryReg) {
+ this.qryReg = qryReg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onStart(GridKernalContext ctx) {
+ localNodeId(ctx.localNodeId());
+ exchangeManager(ctx.cache().context().exchange());
+ eventManager(ctx.event());
+ iteratorsHolder(new ClosableIteratorsHolder(log));
+
+ CalciteQueryProcessor proc = Objects.requireNonNull(
+ Commons.lookupComponent(ctx, CalciteQueryProcessor.class));
+
+ queryPlanCache(proc.queryPlanCache());
+ schemaHolder(proc.schemaHolder());
+ taskExecutor(proc.taskExecutor());
+ failureProcessor(proc.failureProcessor());
+ partitionService(proc.affinityService());
+ mailboxRegistry(proc.mailboxRegistry());
+ mappingService(proc.mappingService());
+ messageService(proc.messageService());
+ exchangeService(proc.exchangeService());
+ queryRegistry(proc.queryRegistry());
+ prepareService(proc.prepareService());
+
+ init();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void init() {
- messageService().register((n, m) -> onMessage(n, (QueryStartRequest) m), MessageType.QUERY_START_REQUEST);
- messageService().register((n, m) -> onMessage(n, (QueryStartResponse) m), MessageType.QUERY_START_RESPONSE);
- messageService().register((n, m) -> onMessage(n, (ErrorMessage) m), MessageType.QUERY_ERROR_MESSAGE);
++ messageService().register((n, m) -> onMessage(n, (QueryStartRequest)m), MessageType.QUERY_START_REQUEST);
++ messageService().register((n, m) -> onMessage(n, (QueryStartResponse)m), MessageType.QUERY_START_RESPONSE);
++ messageService().register((n, m) -> onMessage(n, (ErrorMessage)m), MessageType.QUERY_ERROR_MESSAGE);
+
+ eventManager().addDiscoveryEventListener(discoLsnr, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
+
+ iteratorsHolder().init();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void tearDown() {
+ eventManager().removeDiscoveryEventListener(discoLsnr, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
+
+ iteratorsHolder().tearDown();
+ }
+
+ /** */
+ protected AffinityTopologyVersion topologyVersion() {
+ return exchangeManager().readyAffinityVersion();
+ }
+
+ /** */
+ private BaseQueryContext createQueryContext(Context parent, @Nullable String schema) {
+ return BaseQueryContext.builder()
+ .parentContext(parent)
+ .frameworkConfig(
+ Frameworks.newConfigBuilder(FRAMEWORK_CONFIG)
+ .defaultSchema(schemaHolder().schema(schema))
+ .build()
+ )
+ .logger(log)
+ .build();
+ }
+
+ /** */
+ private QueryPlan prepareFragment(BaseQueryContext ctx, String jsonFragment) {
+ return new FragmentPlan(fromJson(ctx, jsonFragment));
+ }
+
+ /** {@inheritDoc} */
+ @Override public FieldsQueryCursor<List<?>> executePlan(
+ RootQuery<Row> qry,
+ QueryPlan plan
+ ) {
+ switch (plan.type()) {
+ case DML:
+ ListFieldsQueryCursor<?> cur = mapAndExecutePlan(
+ qry,
+ (MultiStepPlan)plan
+ );
+
+ cur.iterator().hasNext();
+
+ return cur;
+
+ case QUERY:
+ return mapAndExecutePlan(
+ qry,
+ (MultiStepPlan)plan
+ );
+
+ case EXPLAIN:
+ return executeExplain((ExplainPlan)plan);
+
+ case DDL:
+ return executeDdl(qry, (DdlPlan)plan);
+
+ default:
+ throw new AssertionError("Unexpected plan type: " + plan);
+ }
+ }
+
+ /** */
+ private FieldsQueryCursor<List<?>> executeDdl(RootQuery<Row> qry, DdlPlan plan) {
+ try {
+ ddlCmdHnd.handle(qry.id(), plan.command());
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + qry.sql() +
+ ", err=" + e.getMessage() + ']', e);
+ }
+ finally {
+ qryReg.unregister(qry.id());
+ }
+
+ if (plan.command() instanceof CreateTableCommand
+ && ((CreateTableCommand)plan.command()).insertStatement() != null) {
+ RootQuery<Row> insQry = qry.childQuery(schemaHolder.schema(qry.context().schemaName()));
+
+ qryReg.register(insQry);
+
+ SqlInsert insertStmt = ((CreateTableCommand)plan.command()).insertStatement();
+
+ QueryPlan dmlPlan = prepareSvc.prepareSingle(insertStmt, insQry.planningContext());
+
+ return executePlan(insQry, dmlPlan);
+ }
+ else
+ return H2Utils.zeroCursor();
+ }
+
+ /** */
+ private ListFieldsQueryCursor<?> mapAndExecutePlan(
+ RootQuery<Row> qry,
+ MultiStepPlan plan
+ ) {
+ qry.mapping();
+
+ MappingQueryContext mapCtx = Commons.mapContext(locNodeId, topologyVersion());
+ plan.init(mappingSvc, mapCtx);
+
+ List<Fragment> fragments = plan.fragments();
+
+ // Local execution
+ Fragment fragment = F.first(fragments);
+
+ if (U.assertionsEnabled()) {
+ assert fragment != null;
+
+ FragmentMapping mapping = plan.mapping(fragment);
+
+ assert mapping != null;
+
+ List<UUID> nodes = mapping.nodeIds();
+
+ assert nodes != null && nodes.size() == 1 && F.first(nodes).equals(localNodeId());
+ }
+
+ FragmentDescription fragmentDesc = new FragmentDescription(
+ fragment.fragmentId(),
+ plan.mapping(fragment),
+ plan.target(fragment),
+ plan.remotes(fragment));
+
+ ExecutionContext<Row> ectx = new ExecutionContext<>(
+ qry.context(),
+ taskExecutor(),
+ qry.id(),
+ locNodeId,
+ locNodeId,
+ mapCtx.topologyVersion(),
+ fragmentDesc,
+ handler,
+ Commons.parametersMap(qry.parameters()));
+
+ Node<Row> node = new LogicalRelImplementor<>(ectx, partitionService(), mailboxRegistry(),
+ exchangeService(), failureProcessor()).go(fragment.root());
+
+ qry.run(ectx, plan, node);
+
+ // start remote execution
+ for (int i = 1; i < fragments.size(); i++) {
+ fragment = fragments.get(i);
+ fragmentDesc = new FragmentDescription(
+ fragment.fragmentId(),
+ plan.mapping(fragment),
+ plan.target(fragment),
+ plan.remotes(fragment));
+
+ Throwable ex = null;
+ for (UUID nodeId : fragmentDesc.nodeIds()) {
+ if (ex != null)
+ qry.onResponse(nodeId, fragment.fragmentId(), ex);
+ else {
+ try {
+ QueryStartRequest req = new QueryStartRequest(
+ qry.id(),
+ qry.context().schemaName(),
+ fragment.serialized(),
+ ectx.topologyVersion(),
+ fragmentDesc,
+ qry.parameters());
+
+ messageService().send(nodeId, req);
+ }
+ catch (Throwable e) {
+ qry.onResponse(nodeId, fragment.fragmentId(), ex = e);
+ }
+ }
+ }
+ }
+
+ return new ListFieldsQueryCursor<>(plan, iteratorsHolder().iterator(qry.iterator()), ectx);
+ }
+
+ /** */
+ private FieldsQueryCursor<List<?>> executeExplain(ExplainPlan plan) {
+ QueryCursorImpl<List<?>> cur = new QueryCursorImpl<>(singletonList(singletonList(plan.plan())));
+ cur.fieldsMeta(plan.fieldsMeta().queryFieldsMetadata(Commons.typeFactory()));
+
+ return cur;
+ }
+
+ /** */
+ private void executeFragment(Query<Row> qry, FragmentPlan plan, ExecutionContext<Row> ectx) {
+ UUID origNodeId = ectx.originatingNodeId();
+
+ Outbox<Row> node = new LogicalRelImplementor<>(
+ ectx,
+ partitionService(),
+ mailboxRegistry(),
+ exchangeService(),
+ failureProcessor()
+ )
+ .go(plan.root());
+
+ qry.addFragment(new RunningFragment<>(plan.root(), node, ectx));
+
+ try {
+ messageService().send(origNodeId, new QueryStartResponse(qry.id(), ectx.fragmentId()));
+ }
+ catch (IgniteCheckedException e) {
+ IgniteException wrpEx = new IgniteException("Failed to send reply. [nodeId=" + origNodeId + ']', e);
+
+ throw wrpEx;
+ }
+
+ node.init();
+ }
+
+ /** */
+ private FieldsMetadata queryFieldsMetadata(PlanningContext ctx, RelDataType sqlType,
+ @Nullable List<List<String>> origins) {
+ RelDataType resultType = TypeUtils.getResultType(
+ ctx.typeFactory(), ctx.catalogReader(), sqlType, origins);
+ return new FieldsMetadataImpl(resultType, origins);
+ }
+
+ /** */
+ private void onMessage(UUID nodeId, final QueryStartRequest msg) {
+ assert nodeId != null && msg != null;
+
+ try {
+ Query<Row> qry = (Query<Row>)qryReg.register(
+ new Query<>(
+ msg.queryId(),
+ nodeId,
+ null,
+ exchangeSvc,
+ (q) -> qryReg.unregister(q.id()),
+ log
+ )
+ );
+
+ final BaseQueryContext qctx = createQueryContext(Contexts.empty(), msg.schema());
+
+ QueryPlan qryPlan = queryPlanCache().queryPlan(
+ new CacheKey(msg.schema(), msg.root()),
+ () -> prepareFragment(qctx, msg.root())
+ );
+
+ assert qryPlan.type() == QueryPlan.Type.FRAGMENT;
+
+ ExecutionContext<Row> ectx = new ExecutionContext<>(
+ qctx,
+ taskExecutor(),
+ msg.queryId(),
+ locNodeId,
+ nodeId,
+ msg.topologyVersion(),
+ msg.fragmentDescription(),
+ handler,
+ Commons.parametersMap(msg.parameters())
+ );
+
+ executeFragment(qry, (FragmentPlan)qryPlan, ectx);
+ }
+ catch (Throwable ex) {
+ U.error(log, "Failed to start query fragment ", ex);
+
+ mailboxRegistry.outboxes(msg.queryId(), msg.fragmentId(), -1)
+ .forEach(Outbox::close);
+ mailboxRegistry.inboxes(msg.queryId(), msg.fragmentId(), -1)
+ .forEach(Inbox::close);
+
+ try {
+ messageService().send(nodeId, new QueryStartResponse(msg.queryId(), msg.fragmentId(), ex));
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Error occurred during send error message: " + X.getFullStackTrace(e));
+
+ IgniteException wrpEx = new IgniteException("Error occurred during send error message", e);
+
+ e.addSuppressed(ex);
+
+ Query<Row> qry = (Query<Row>)qryReg.query(msg.queryId());
+
+ qry.cancel();
+
+ throw wrpEx;
+ }
+
+ throw ex;
+ }
+ }
+
+ /** */
+ private void onMessage(UUID nodeId, QueryStartResponse msg) {
+ assert nodeId != null && msg != null;
+
+ RunningQuery qry = qryReg.query(msg.queryId());
+
+ if (qry != null) {
+ assert qry instanceof RootQuery : "Unexpected query object: " + qry;
+
+ ((RootQuery<Row>)qry).onResponse(nodeId, msg.fragmentId(), msg.error());
+ }
+ }
+
+ /** */
+ private void onMessage(UUID nodeId, ErrorMessage msg) {
+ assert nodeId != null && msg != null;
+
+ RunningQuery qry = qryReg.query(msg.queryId());
+
+ if (qry != null && qry.state() != QueryState.CLOSED) {
+ assert qry instanceof RootQuery : "Unexpected query object: " + qry;
+
+ Exception e = new RemoteException(nodeId, msg.queryId(), msg.fragmentId(), msg.error());
+
+ if (X.hasCause(msg.error(), ExecutionCancelledException.class)) {
+ e = new IgniteSQLException(
+ "The query was cancelled while executing.",
+ IgniteQueryErrorCode.QUERY_CANCELED,
+ e
+ );
+ }
+
+ ((RootQuery<Row>)qry).onError(e);
+ }
+ }
+
+ /** */
+ private void onNodeLeft(UUID nodeId) {
+ qryReg.runningQueries()
+ .forEach((qry) -> ((Query<Row>)qry).onNodeLeft(nodeId));
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java
index 7ae84e7,0000000..bc866db
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java
@@@ -1,301 -1,0 +1,301 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+package org.apache.ignite.internal.processors.query.calcite.exec;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cluster.ClusterTopologyException;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.cache.query.index.sorted.IndexRow;
+import org.apache.ignite.internal.cache.query.index.sorted.IndexSearchRowImpl;
+import org.apache.ignite.internal.cache.query.index.sorted.InlineIndexRowHandler;
+import org.apache.ignite.internal.cache.query.index.sorted.inline.IndexQueryContext;
+import org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndex;
+import org.apache.ignite.internal.cache.query.index.sorted.keys.IndexKey;
+import org.apache.ignite.internal.cache.query.index.sorted.keys.IndexKeyFactory;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheObjectContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
+import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler.RowFactory;
+import org.apache.ignite.internal.processors.query.calcite.schema.TableDescriptor;
+import org.apache.ignite.internal.util.lang.GridCursor;
+import org.apache.ignite.spi.indexing.IndexingQueryFilter;
+import org.apache.ignite.spi.indexing.IndexingQueryFilterImpl;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Scan on index.
+ */
+public class IndexScan<Row> extends AbstractIndexScan<Row, IndexRow> {
+ /** */
+ private final GridKernalContext kctx;
+
+ /** */
+ private final GridCacheContext<?, ?> cctx;
+
+ /** */
+ private final CacheObjectContext coCtx;
+
+ /** */
+ private final TableDescriptor desc;
+
+ /** */
+ private final RowFactory<Row> factory;
+
+ /** */
+ private final AffinityTopologyVersion topVer;
+
+ /** */
+ private final int[] parts;
+
+ /** */
+ private final MvccSnapshot mvccSnapshot;
+
+ /** */
+ private volatile List<GridDhtLocalPartition> reserved;
+
+ /** */
+ private final ImmutableBitSet requiredColumns;
+
+ /** */
+ private final InlineIndex idx;
+
+ /** Mapping from index keys to row fields. */
+ private final ImmutableIntList idxFieldMapping;
+
+ /**
+ * @param ectx Execution context.
+ * @param desc Table descriptor.
+ * @param idxFieldMapping Mapping from index keys to row fields.
+ * @param idx Phisycal index.
+ * @param filters Additional filters.
+ * @param lowerBound Lower index scan bound.
+ * @param upperBound Upper index scan bound.
+ */
+ public IndexScan(
+ ExecutionContext<Row> ectx,
+ TableDescriptor desc,
+ InlineIndex idx,
+ ImmutableIntList idxFieldMapping,
+ int[] parts,
+ Predicate<Row> filters,
+ Supplier<Row> lowerBound,
+ Supplier<Row> upperBound,
+ Function<Row, Row> rowTransformer,
+ @Nullable ImmutableBitSet requiredColumns
+ ) {
+ super(
+ ectx,
+ desc.rowType(ectx.getTypeFactory(), requiredColumns),
+ new TreeIndexWrapper(idx),
+ filters,
+ lowerBound,
+ upperBound,
+ rowTransformer
+ );
+
+ this.desc = desc;
+ this.idx = idx;
+ cctx = desc.cacheContext();
+ kctx = cctx.kernalContext();
+ coCtx = cctx.cacheObjectContext();
+
+ factory = ectx.rowHandler().factory(ectx.getTypeFactory(), rowType);
+ topVer = ectx.topologyVersion();
+ this.parts = parts;
+ mvccSnapshot = ectx.mvccSnapshot();
+ this.requiredColumns = requiredColumns;
+ this.idxFieldMapping = idxFieldMapping;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized Iterator<Row> iterator() {
+ reserve();
+
+ try {
+ return super.iterator();
+ }
+ catch (Exception e) {
+ release();
+
+ throw e;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IndexRow row2indexRow(Row bound) {
+ if (bound == null)
+ return null;
+
+ InlineIndexRowHandler idxRowHnd = idx.segment(0).rowHandler();
+ RowHandler<Row> rowHnd = ectx.rowHandler();
+
+ IndexKey[] keys = new IndexKey[idxRowHnd.indexKeyDefinitions().size()];
+
+ assert keys.length >= idxFieldMapping.size() : "Unexpected index keys [keys.length=" + keys.length +
+ ", idxFieldMapping.size()=" + idxFieldMapping.size() + ']';
+
+ boolean nullSearchRow = true;
+
+ for (int i = 0; i < idxFieldMapping.size(); ++i) {
+ Object key = rowHnd.get(idxFieldMapping.getInt(i), bound);
+
+ if (key != null) {
+ keys[i] = IndexKeyFactory.wrap(key, idxRowHnd.indexKeyDefinitions().get(i).idxType(),
+ cctx.cacheObjectContext(), idxRowHnd.indexKeyTypeSettings());
+
+ nullSearchRow = false;
+ }
+ }
+
+ return nullSearchRow ? null : new IndexSearchRowImpl(keys, idxRowHnd);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Row indexRow2Row(IndexRow row) throws IgniteCheckedException {
+ return desc.toRow(ectx, row.cacheDataRow(), factory, requiredColumns);
+ }
+
+ /** */
+ @Override public void close() {
+ release();
+ }
+
+ /** */
+ private synchronized void reserve() {
+ if (reserved != null)
+ return;
+
+ GridDhtPartitionTopology top = cctx.topology();
+ top.readLock();
+
+ GridDhtTopologyFuture topFut = top.topologyVersionFuture();
+
+ boolean done = topFut.isDone();
+
+ if (!done || !(topFut.topologyVersion().compareTo(topVer) >= 0
+ && cctx.shared().exchange().lastAffinityChangedTopologyVersion(topFut.initialVersion()).compareTo(topVer) <= 0)) {
+ top.readUnlock();
+
+ throw new ClusterTopologyException("Topology was changed. Please retry on stable topology.");
+ }
+
+ List<GridDhtLocalPartition> toReserve;
+
+ if (cctx.isReplicated()) {
+ int partsCnt = cctx.affinity().partitions();
+ toReserve = new ArrayList<>(partsCnt);
+ for (int i = 0; i < partsCnt; i++)
+ toReserve.add(top.localPartition(i));
+ }
+ else if (cctx.isPartitioned()) {
+ assert parts != null;
+
+ toReserve = new ArrayList<>(parts.length);
+ for (int i = 0; i < parts.length; i++)
+ toReserve.add(top.localPartition(parts[i]));
+ }
+ else {
+ assert cctx.isLocal();
+
+ toReserve = Collections.emptyList();
+ }
+
+ reserved = new ArrayList<>(toReserve.size());
+
+ try {
+ for (GridDhtLocalPartition part : toReserve) {
+ if (part == null || !part.reserve()) {
+ throw new ClusterTopologyException(
+ "Failed to reserve partition for query execution. Retry on stable topology."
+ );
+ }
+ else if (part.state() != GridDhtPartitionState.OWNING) {
+ part.release();
+
+ throw new ClusterTopologyException(
+ "Failed to reserve partition for query execution. Retry on stable topology."
+ );
+ }
+
+ reserved.add(part);
+ }
+ }
+ catch (Exception e) {
+ release();
+
+ throw e;
+ }
+ finally {
+ top.readUnlock();
+ }
+ }
+
+ /** */
+ private synchronized void release() {
+ if (reserved == null)
+ return;
+
+ for (GridDhtLocalPartition part : reserved)
+ part.release();
+
+ reserved = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IndexQueryContext indexQueryContext() {
+ IndexingQueryFilter filter = new IndexingQueryFilterImpl(kctx, topVer, parts);
+ return new IndexQueryContext(filter, mvccSnapshot);
+ }
+
+ /** */
+ private static class TreeIndexWrapper implements TreeIndex<IndexRow> {
+ /** Underlying index. */
+ private final InlineIndex idx;
+
+ /** */
+ private TreeIndexWrapper(InlineIndex idx) {
+ this.idx = idx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridCursor<IndexRow> find(IndexRow lower, IndexRow upper, IndexQueryContext qctx) {
+ try {
+ int seg = 0; // TODO segments support
+
- return idx.find(lower, upper, seg, qctx);
++ return idx.find(lower, upper, true, true, seg, qctx);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException("Failed to find index rows", e);
+ }
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
index 6266c95,0000000..866ea80
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java
@@@ -1,675 -1,0 +1,675 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Intersect;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.Minus;
+import org.apache.calcite.rel.core.Spool;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.ignite.internal.processors.failure.FailureProcessor;
+import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler.RowFactory;
+import org.apache.ignite.internal.processors.query.calcite.exec.exp.ExpressionFactory;
+import org.apache.ignite.internal.processors.query.calcite.exec.exp.agg.AccumulatorWrapper;
+import org.apache.ignite.internal.processors.query.calcite.exec.exp.agg.AggregateType;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.AbstractSetOpNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.CorrelatedNestedLoopJoinNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.FilterNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.HashAggregateNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Inbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.IndexSpoolNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.IntersectNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.LimitNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.MergeJoinNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.MinusNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.ModifyNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.NestedLoopJoinNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Node;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Outbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.ProjectNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.ScanNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.SortAggregateNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.SortNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.TableSpoolNode;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.UnionAllNode;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteExchange;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteHashIndexSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteLimit;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteMergeJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteNestedLoopJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteProject;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteReceiver;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRelVisitor;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSender;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSort;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSortedIndexSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableFunctionScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableModify;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTrimExchange;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteUnionAll;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteMapHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteMapSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteReduceHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteReduceSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteSingleHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteSingleSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.set.IgniteSetOp;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteIndex;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable;
+import org.apache.ignite.internal.processors.query.calcite.schema.TableDescriptor;
+import org.apache.ignite.internal.processors.query.calcite.trait.Destination;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
+import org.apache.ignite.internal.processors.query.calcite.trait.TraitUtils;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.F;
+
+import static org.apache.calcite.rel.RelDistribution.Type.HASH_DISTRIBUTED;
+import static org.apache.ignite.internal.processors.query.calcite.util.TypeUtils.combinedRowType;
+
+/**
+ * Implements a query plan.
+ */
+@SuppressWarnings("TypeMayBeWeakened")
+public class LogicalRelImplementor<Row> implements IgniteRelVisitor<Node<Row>> {
+ /** */
+ public static final String CNLJ_NOT_SUPPORTED_JOIN_ASSERTION_MSG = "only INNER and LEFT join supported by IgniteCorrelatedNestedLoop";
+
+ /** */
+ private final ExecutionContext<Row> ctx;
+
+ /** */
+ private final AffinityService affSrvc;
+
+ /** */
+ private final ExchangeService exchangeSvc;
+
+ /** */
+ private final MailboxRegistry mailboxRegistry;
+
+ /** */
+ private final ExpressionFactory<Row> expressionFactory;
+
+ /**
+ * @param ctx Root context.
+ * @param affSrvc Affinity service.
+ * @param mailboxRegistry Mailbox registry.
+ * @param exchangeSvc Exchange service.
+ * @param failure Failure processor.
+ */
+ public LogicalRelImplementor(
+ ExecutionContext<Row> ctx,
+ AffinityService affSrvc,
+ MailboxRegistry mailboxRegistry,
+ ExchangeService exchangeSvc,
+ FailureProcessor failure
+ ) {
+ this.affSrvc = affSrvc;
+ this.mailboxRegistry = mailboxRegistry;
+ this.exchangeSvc = exchangeSvc;
+ this.ctx = ctx;
+
+ expressionFactory = ctx.expressionFactory();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSender rel) {
+ IgniteDistribution distribution = rel.distribution();
+
+ Destination<Row> dest = distribution.destination(ctx, affSrvc, ctx.target());
+
+ // Outbox fragment ID is used as exchange ID as well.
+ Outbox<Row> outbox =
+ new Outbox<>(ctx, rel.getRowType(), exchangeSvc, mailboxRegistry, rel.exchangeId(), rel.targetFragmentId(), dest);
+
+ Node<Row> input = visit(rel.getInput());
+
+ outbox.register(input);
+
+ mailboxRegistry.register(outbox);
+
+ return outbox;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteFilter rel) {
+ Predicate<Row> pred = expressionFactory.predicate(rel.getCondition(), rel.getRowType());
+
+ FilterNode<Row> node = new FilterNode<>(ctx, rel.getRowType(), pred);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteTrimExchange rel) {
+ assert TraitUtils.distribution(rel).getType() == HASH_DISTRIBUTED;
+
+ IgniteDistribution distr = rel.distribution();
+ Destination<Row> dest = distr.destination(ctx, affSrvc, ctx.group(rel.sourceId()));
+ UUID localNodeId = ctx.localNodeId();
+
+ FilterNode<Row> node = new FilterNode<>(ctx, rel.getRowType(), r -> Objects.equals(localNodeId, F.first(dest.targets(r))));
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteProject rel) {
+ Function<Row, Row> prj = expressionFactory.project(rel.getProjects(), rel.getInput().getRowType());
+
+ ProjectNode<Row> node = new ProjectNode<>(ctx, rel.getRowType(), prj);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteNestedLoopJoin rel) {
+ RelDataType outType = rel.getRowType();
+ RelDataType leftType = rel.getLeft().getRowType();
+ RelDataType rightType = rel.getRight().getRowType();
+ JoinRelType joinType = rel.getJoinType();
+
+ RelDataType rowType = combinedRowType(ctx.getTypeFactory(), leftType, rightType);
+
+ BiPredicate<Row, Row> cond = expressionFactory.biPredicate(rel.getCondition(), rowType);
+
+ Node<Row> node = NestedLoopJoinNode.create(ctx, outType, leftType, rightType, joinType, cond);
+
+ Node<Row> leftInput = visit(rel.getLeft());
+ Node<Row> rightInput = visit(rel.getRight());
+
+ node.register(F.asList(leftInput, rightInput));
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteCorrelatedNestedLoopJoin rel) {
+ RelDataType outType = rel.getRowType();
+ RelDataType leftType = rel.getLeft().getRowType();
+ RelDataType rightType = rel.getRight().getRowType();
+
+ RelDataType rowType = combinedRowType(ctx.getTypeFactory(), leftType, rightType);
+ BiPredicate<Row, Row> cond = expressionFactory.biPredicate(rel.getCondition(), rowType);
+
+ assert rel.getJoinType() == JoinRelType.INNER || rel.getJoinType() == JoinRelType.LEFT
+ : CNLJ_NOT_SUPPORTED_JOIN_ASSERTION_MSG;
+
+ Node<Row> node = new CorrelatedNestedLoopJoinNode<>(ctx, outType, cond, rel.getVariablesSet(),
+ rel.getJoinType());
+
+ Node<Row> leftInput = visit(rel.getLeft());
+ Node<Row> rightInput = visit(rel.getRight());
+
+ node.register(F.asList(leftInput, rightInput));
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteMergeJoin rel) {
+ RelDataType outType = rel.getRowType();
+ RelDataType leftType = rel.getLeft().getRowType();
+ RelDataType rightType = rel.getRight().getRowType();
+ JoinRelType joinType = rel.getJoinType();
+
+ int pairsCnt = rel.analyzeCondition().pairs().size();
+
+ Comparator<Row> comp = expressionFactory.comparator(
+ rel.leftCollation().getFieldCollations().subList(0, pairsCnt),
+ rel.rightCollation().getFieldCollations().subList(0, pairsCnt)
+ );
+
+ Node<Row> node = MergeJoinNode.create(ctx, outType, leftType, rightType, joinType, comp);
+
+ Node<Row> leftInput = visit(rel.getLeft());
+ Node<Row> rightInput = visit(rel.getRight());
+
+ node.register(F.asList(leftInput, rightInput));
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteIndexScan rel) {
+ RexNode condition = rel.condition();
+ List<RexNode> projects = rel.projects();
+
+ IgniteTable tbl = rel.getTable().unwrap(IgniteTable.class);
+ IgniteTypeFactory typeFactory = ctx.getTypeFactory();
+
+ ImmutableBitSet requiredColumns = rel.requiredColumns();
+ List<RexNode> lowerCond = rel.lowerBound();
+ List<RexNode> upperCond = rel.upperBound();
+
+ RelDataType rowType = tbl.getRowType(typeFactory, requiredColumns);
+
+ Predicate<Row> filters = condition == null ? null : expressionFactory.predicate(condition, rowType);
+ Supplier<Row> lower = lowerCond == null ? null : expressionFactory.rowSource(lowerCond);
+ Supplier<Row> upper = upperCond == null ? null : expressionFactory.rowSource(upperCond);
+ Function<Row, Row> prj = projects == null ? null : expressionFactory.project(projects, rowType);
+
+ IgniteIndex idx = tbl.getIndex(rel.indexName());
+
+ ColocationGroup group = ctx.group(rel.sourceId());
+
+ Iterable<Row> rowsIter = idx.scan(ctx, group, filters, lower, upper, prj, requiredColumns);
+
+ return new ScanNode<>(ctx, rowType, rowsIter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteTableScan rel) {
+ RexNode condition = rel.condition();
+ List<RexNode> projects = rel.projects();
+ ImmutableBitSet requiredColunms = rel.requiredColumns();
+
+ IgniteTable tbl = rel.getTable().unwrap(IgniteTable.class);
+ IgniteTypeFactory typeFactory = ctx.getTypeFactory();
+
+ RelDataType rowType = tbl.getRowType(typeFactory, requiredColunms);
+
+ Predicate<Row> filters = condition == null ? null : expressionFactory.predicate(condition, rowType);
+ Function<Row, Row> prj = projects == null ? null : expressionFactory.project(projects, rowType);
+
+ ColocationGroup group = ctx.group(rel.sourceId());
+
+ Iterable<Row> rowsIter = tbl.scan(ctx, group, filters, prj, requiredColunms);
+
+ return new ScanNode<>(ctx, rowType, rowsIter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteValues rel) {
+ List<RexLiteral> vals = Commons.flat(Commons.cast(rel.getTuples()));
+
+ RelDataType rowType = rel.getRowType();
+
+ return new ScanNode<>(ctx, rowType, expressionFactory.values(vals, rowType));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteUnionAll rel) {
+ UnionAllNode<Row> node = new UnionAllNode<>(ctx, rel.getRowType());
+
+ List<Node<Row>> inputs = Commons.transform(rel.getInputs(), this::visit);
+
+ node.register(inputs);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteLimit rel) {
+ Supplier<Integer> offset = (rel.offset() == null) ? null : expressionFactory.execute(rel.offset());
+ Supplier<Integer> fetch = (rel.fetch() == null) ? null : expressionFactory.execute(rel.fetch());
+
+ LimitNode<Row> node = new LimitNode<>(ctx, rel.getRowType(), offset, fetch);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSort rel) {
+ RelCollation collation = rel.getCollation();
+
+ SortNode<Row> node = new SortNode<>(ctx, rel.getRowType(), expressionFactory.comparator(collation));
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteTableSpool rel) {
+ TableSpoolNode<Row> node = new TableSpoolNode<>(ctx, rel.getRowType(), rel.readType == Spool.Type.LAZY);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSortedIndexSpool rel) {
+ RelCollation collation = rel.collation();
+
+ assert rel.indexCondition() != null : rel;
+
+ List<RexNode> lowerBound = rel.indexCondition().lowerBound();
+ List<RexNode> upperBound = rel.indexCondition().upperBound();
+
+ Predicate<Row> filter = expressionFactory.predicate(rel.condition(), rel.getRowType());
+ Supplier<Row> lower = lowerBound == null ? null : expressionFactory.rowSource(lowerBound);
+ Supplier<Row> upper = upperBound == null ? null : expressionFactory.rowSource(upperBound);
+
+ IndexSpoolNode<Row> node = IndexSpoolNode.createTreeSpool(
+ ctx,
+ rel.getRowType(),
+ collation,
+ expressionFactory.comparator(collation),
+ filter,
+ lower,
+ upper
+ );
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteHashIndexSpool rel) {
+ Supplier<Row> searchRow = expressionFactory.rowSource(rel.searchRow());
+
+ IndexSpoolNode<Row> node = IndexSpoolNode.createHashSpool(
+ ctx,
+ rel.getRowType(),
+ ImmutableBitSet.of(rel.keys()),
+ searchRow
+ );
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSetOp rel) {
+ RelDataType rowType = rel.getRowType();
+
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ List<Node<Row>> inputs = Commons.transform(rel.getInputs(), this::visit);
+
+ AbstractSetOpNode<Row> node;
+
+ if (rel instanceof Minus)
+ node = new MinusNode<>(ctx, rowType, rel.aggregateType(), rel.all(), rowFactory);
+ else if (rel instanceof Intersect)
+ node = new IntersectNode<>(ctx, rowType, rel.aggregateType(), rel.all(), rowFactory, rel.getInputs().size());
+ else
+ throw new AssertionError();
+
+ node.register(inputs);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteTableFunctionScan rel) {
+ Supplier<Iterable<Object[]>> dataSupplier = expressionFactory.execute(rel.getCall());
+
+ RelDataType rowType = rel.getRowType();
+
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ return new ScanNode<>(ctx, rowType, new TableFunctionScan<>(dataSupplier, rowFactory));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteTableModify rel) {
+ switch (rel.getOperation()) {
+ case INSERT:
+ case UPDATE:
+ case DELETE:
+ case MERGE:
+ ModifyNode<Row> node = new ModifyNode<>(ctx, rel.getRowType(), rel.getTable().unwrap(TableDescriptor.class),
+ rel.getOperation(), rel.getUpdateColumnList());
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteReceiver rel) {
- Inbox<Row> inbox = (Inbox<Row>) mailboxRegistry.register(
++ Inbox<Row> inbox = (Inbox<Row>)mailboxRegistry.register(
+ new Inbox<>(ctx, exchangeSvc, mailboxRegistry, rel.exchangeId(), rel.sourceFragmentId()));
+
+ // here may be an already created (to consume rows from remote nodes) inbox
+ // without proper context, we need to init it with a right one.
+ inbox.init(ctx, rel.getRowType(), ctx.remotes(rel.exchangeId()), expressionFactory.comparator(rel.collation()));
+
+ return inbox;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSingleHashAggregate rel) {
+ AggregateType type = AggregateType.SINGLE;
+
+ RelDataType rowType = rel.getRowType();
+ RelDataType inputType = rel.getInput().getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type, rel.getAggCallList(), inputType);
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ HashAggregateNode<Row> node = new HashAggregateNode<>(ctx, rowType, type, rel.getGroupSets(), accFactory, rowFactory);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteMapHashAggregate rel) {
+ AggregateType type = AggregateType.MAP;
+
+ RelDataType rowType = rel.getRowType();
+ RelDataType inputType = rel.getInput().getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type, rel.getAggCallList(), inputType);
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ HashAggregateNode<Row> node = new HashAggregateNode<>(ctx, rowType, type, rel.getGroupSets(), accFactory, rowFactory);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteReduceHashAggregate rel) {
+ AggregateType type = AggregateType.REDUCE;
+
+ RelDataType rowType = rel.getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type, rel.getAggregateCalls(), null);
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ HashAggregateNode<Row> node = new HashAggregateNode<>(ctx, rowType, type, rel.getGroupSets(), accFactory, rowFactory);
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteSingleSortAggregate rel) {
+ AggregateType type = AggregateType.SINGLE;
+
+ RelDataType rowType = rel.getRowType();
+ RelDataType inputType = rel.getInput().getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type,
+ rel.getAggCallList(),
+ inputType
+ );
+
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ SortAggregateNode<Row> node = new SortAggregateNode<>(
+ ctx,
+ rowType,
+ type,
+ rel.getGroupSet(),
+ accFactory,
+ rowFactory,
+ expressionFactory.comparator(rel.collation())
+ );
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteMapSortAggregate rel) {
+ AggregateType type = AggregateType.MAP;
+
+ RelDataType rowType = rel.getRowType();
+ RelDataType inputType = rel.getInput().getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type,
+ rel.getAggCallList(),
+ inputType
+ );
+
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ SortAggregateNode<Row> node = new SortAggregateNode<>(
+ ctx,
+ rowType,
+ type,
+ rel.getGroupSet(),
+ accFactory,
+ rowFactory,
+ expressionFactory.comparator(rel.collation())
+ );
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteReduceSortAggregate rel) {
+ AggregateType type = AggregateType.REDUCE;
+
+ RelDataType rowType = rel.getRowType();
+
+ Supplier<List<AccumulatorWrapper<Row>>> accFactory = expressionFactory.accumulatorsFactory(
+ type,
+ rel.getAggregateCalls(),
+ null
+ );
+
+ RowFactory<Row> rowFactory = ctx.rowHandler().factory(ctx.getTypeFactory(), rowType);
+
+ SortAggregateNode<Row> node = new SortAggregateNode<>(
+ ctx,
+ rowType,
+ type,
+ rel.getGroupSet(),
+ accFactory,
+ rowFactory,
+ expressionFactory.comparator(rel.collation())
+ );
+
+ Node<Row> input = visit(rel.getInput());
+
+ node.register(input);
+
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteRel rel) {
+ return rel.accept(this);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Node<Row> visit(IgniteExchange rel) {
+ throw new AssertionError();
+ }
+
+ /** */
+ private Node<Row> visit(RelNode rel) {
- return visit((IgniteRel) rel);
++ return visit((IgniteRel)rel);
+ }
+
+ /** */
+ public <T extends Node<Row>> T go(IgniteRel rel) {
+ return (T)visit(rel);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/MailboxRegistryImpl.java
index cbf7d95,0000000..538e7b0
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/MailboxRegistryImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/MailboxRegistryImpl.java
@@@ -1,216 -1,0 +1,216 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.managers.eventstorage.DiscoveryEventListener;
+import org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Inbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Mailbox;
+import org.apache.ignite.internal.processors.query.calcite.exec.rel.Outbox;
+import org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class MailboxRegistryImpl extends AbstractService implements MailboxRegistry {
+ /** */
+ private static final Predicate<Mailbox<?>> ALWAYS_TRUE = o -> true;
+
+ /** */
+ private final Map<MailboxKey, Outbox<?>> locals;
+
+ /** */
+ private final Map<MailboxKey, Inbox<?>> remotes;
+
+ /** */
+ @GridToStringExclude
+ private final DiscoveryEventListener discoLsnr;
+
+ /** */
+ @GridToStringExclude
+ private GridEventStorageManager evtMgr;
+
+ /**
+ * @param ctx Kernal.
+ */
+ public MailboxRegistryImpl(GridKernalContext ctx) {
+ super(ctx);
+
+ locals = new ConcurrentHashMap<>();
+ remotes = new ConcurrentHashMap<>();
+
+ discoLsnr = (e, c) -> onNodeLeft(e.eventNode().id());
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onStart(GridKernalContext ctx) {
+ eventManager(ctx.event());
+
+ init();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void init() {
+ eventManager().addDiscoveryEventListener(discoLsnr, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void tearDown() {
+ eventManager().removeDiscoveryEventListener(discoLsnr, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Inbox<?> register(Inbox<?> inbox) {
+ Inbox<?> old = remotes.putIfAbsent(new MailboxKey(inbox.queryId(), inbox.exchangeId()), inbox);
+
+ return old != null ? old : inbox;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void unregister(Inbox<?> inbox) {
+ remotes.remove(new MailboxKey(inbox.queryId(), inbox.exchangeId()), inbox);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void register(Outbox<?> outbox) {
+ Outbox<?> res = locals.put(new MailboxKey(outbox.queryId(), outbox.exchangeId()), outbox);
+
+ assert res == null : res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void unregister(Outbox<?> outbox) {
+ locals.remove(new MailboxKey(outbox.queryId(), outbox.exchangeId()), outbox);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Outbox<?> outbox(UUID qryId, long exchangeId) {
+ return locals.get(new MailboxKey(qryId, exchangeId));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Inbox<?> inbox(UUID qryId, long exchangeId) {
+ return remotes.get(new MailboxKey(qryId, exchangeId));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<Inbox<?>> inboxes(@Nullable UUID qryId, long fragmentId, long exchangeId) {
+ return remotes.values().stream()
+ .filter(makeFilter(qryId, fragmentId, exchangeId))
+ .collect(Collectors.toList());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<Outbox<?>> outboxes(@Nullable UUID qryId, long fragmentId, long exchangeId) {
+ return locals.values().stream()
+ .filter(makeFilter(qryId, fragmentId, exchangeId))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * @param evtMgr Event manager.
+ */
+ public void eventManager(GridEventStorageManager evtMgr) {
+ this.evtMgr = evtMgr;
+ }
+
+ /**
+ * @return Event manager.
+ */
+ public GridEventStorageManager eventManager() {
+ return evtMgr;
+ }
+
+ /** */
+ private void onNodeLeft(UUID nodeId) {
+ locals.values().forEach(n -> n.onNodeLeft(nodeId));
+ remotes.values().forEach(n -> n.onNodeLeft(nodeId));
+ }
+
+ /** */
+ private static Predicate<Mailbox<?>> makeFilter(@Nullable UUID qryId, long fragmentId, long exchangeId) {
+ Predicate<Mailbox<?>> filter = ALWAYS_TRUE;
+ if (qryId != null)
+ filter = filter.and(mailbox -> Objects.equals(mailbox.queryId(), qryId));
+ if (fragmentId != -1)
+ filter = filter.and(mailbox -> mailbox.fragmentId() == fragmentId);
+ if (exchangeId != -1)
+ filter = filter.and(mailbox -> mailbox.exchangeId() == exchangeId);
+
+ return filter;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(MailboxRegistryImpl.class, this);
+ }
+
+ /** */
+ private static class MailboxKey {
+ /** */
+ private final UUID qryId;
+
+ /** */
+ private final long exchangeId;
+
+ /** */
+ private MailboxKey(UUID qryId, long exchangeId) {
+ this.qryId = qryId;
+ this.exchangeId = exchangeId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
- MailboxKey that = (MailboxKey) o;
++ MailboxKey that = (MailboxKey)o;
+
+ if (exchangeId != that.exchangeId)
+ return false;
+ return qryId.equals(that.qryId);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = qryId.hashCode();
- res = 31 * res + (int) (exchangeId ^ (exchangeId >>> 32));
++ res = 31 * res + (int)(exchangeId ^ (exchangeId >>> 32));
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(MailboxKey.class, this);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
index 75243e8,0000000..f7c4b8b
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
@@@ -1,243 -1,0 +1,243 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 at
+ *
+ * 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.
+ */
+package org.apache.ignite.internal.processors.query.calcite.exec.exp;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import org.apache.calcite.DataContext;
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.linq4j.AbstractEnumerable;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.linq4j.Enumerator;
+import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.schema.ScannableTable;
+import org.apache.calcite.schema.Schema;
+import org.apache.calcite.schema.Statistic;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+/**
+ * Ignite SQL functions.
+ */
+public class IgniteSqlFunctions {
+ /**
+ * Default constructor.
+ */
+ private IgniteSqlFunctions() {
+ // No-op.
+ }
+
+ /** SQL SYSTEM_RANGE(start, end) table function. */
+ public static ScannableTable systemRange(Object rangeStart, Object rangeEnd) {
+ return new RangeTable(rangeStart, rangeEnd, 1L);
+ }
+
+ /** SQL SYSTEM_RANGE(start, end, increment) table function. */
+ public static ScannableTable systemRange(Object rangeStart, Object rangeEnd, Object increment) {
+ return new RangeTable(rangeStart, rangeEnd, increment);
+ }
+
+ /** CAST(DECIMAL AS VARCHAR). */
+ public static String toString(BigDecimal x) {
+ return x == null ? null : x.toPlainString();
+ }
+
+ /** */
+ private static BigDecimal setScale(int precision, int scale, BigDecimal decimal) {
+ return precision == IgniteTypeSystem.INSTANCE.getDefaultPrecision(SqlTypeName.DECIMAL)
+ ? decimal : decimal.setScale(scale, RoundingMode.HALF_UP);
+ }
+
+ /** CAST(DOUBLE AS DECIMAL). */
+ public static BigDecimal toBigDecimal(double val, int precision, int scale) {
+ BigDecimal decimal = BigDecimal.valueOf(val);
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(FLOAT AS DECIMAL). */
+ public static BigDecimal toBigDecimal(float val, int precision, int scale) {
+ BigDecimal decimal = new BigDecimal(String.valueOf(val));
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(java long AS DECIMAL). */
+ public static BigDecimal toBigDecimal(long val, int precision, int scale) {
+ BigDecimal decimal = BigDecimal.valueOf(val);
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(INT AS DECIMAL). */
+ public static BigDecimal toBigDecimal(int val, int precision, int scale) {
+ BigDecimal decimal = new BigDecimal(val);
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(java short AS DECIMAL). */
+ public static BigDecimal toBigDecimal(short val, int precision, int scale) {
+ BigDecimal decimal = new BigDecimal(String.valueOf(val));
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(java byte AS DECIMAL). */
+ public static BigDecimal toBigDecimal(byte val, int precision, int scale) {
+ BigDecimal decimal = new BigDecimal(String.valueOf(val));
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(BOOL AS DECIMAL). */
+ public static BigDecimal toBigDecimal(boolean val, int precision, int scale) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** CAST(VARCHAR AS DECIMAL). */
+ public static BigDecimal toBigDecimal(String s, int precision, int scale) {
+ if (s == null)
+ return null;
+ BigDecimal decimal = new BigDecimal(s.trim());
+ return setScale(precision, scale, decimal);
+ }
+
+ /** CAST(REAL AS DECIMAL). */
+ public static BigDecimal toBigDecimal(Number num, int precision, int scale) {
+ if (num == null)
+ return null;
+ // There are some values of "long" that cannot be represented as "double".
+ // Not so "int". If it isn't a long, go straight to double.
+ BigDecimal decimal = num instanceof BigDecimal ? ((BigDecimal)num)
+ : num instanceof BigInteger ? new BigDecimal((BigInteger)num)
+ : num instanceof Long ? new BigDecimal(num.longValue())
+ : BigDecimal.valueOf(num.doubleValue());
+ return setScale(precision, scale, decimal);
+ }
+
+ /** Cast object depending on type to DECIMAL. */
+ public static BigDecimal toBigDecimal(Object o, int precision, int scale) {
+ if (o == null)
+ return null;
+
+ if (o instanceof Boolean)
+ throw new UnsupportedOperationException();
+
- return o instanceof Number ? toBigDecimal((Number) o, precision, scale)
++ return o instanceof Number ? toBigDecimal((Number)o, precision, scale)
+ : toBigDecimal(o.toString(), precision, scale);
+ }
+
+ /** */
+ private static class RangeTable implements ScannableTable {
+ /** Start of the range. */
+ private final Object rangeStart;
+
+ /** End of the range. */
+ private final Object rangeEnd;
+
+ /** Increment. */
+ private final Object increment;
+
+ /**
+ * Note: {@code Object} arguments required here due to:
+ * 1. {@code NULL} arguments need to be supported, so we can't use {@code long} arguments type.
+ * 2. {@code Integer} and other numeric classes can be converted to {@code long} type by java, but can't be
+ * converted to {@code Long} type, so we can't use {@code Long} arguments type either.
+ * Instead, we accept {@code Object} arguments type and try to convert valid types to {@code long}.
+ */
+ RangeTable(Object rangeStart, Object rangeEnd, Object increment) {
+ this.rangeStart = rangeStart;
+ this.rangeEnd = rangeEnd;
+ this.increment = increment;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+ return typeFactory.builder().add("X", SqlTypeName.BIGINT).build();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Enumerable<@Nullable Object[]> scan(DataContext root) {
+ if (rangeStart == null || rangeEnd == null || increment == null)
+ return Linq4j.emptyEnumerable();
+
+ long rangeStart = convertToLongArg(this.rangeStart, "rangeStart");
+ long rangeEnd = convertToLongArg(this.rangeEnd, "rangeEnd");
+ long increment = convertToLongArg(this.increment, "increment");
+
+ if (increment == 0L)
+ throw new IllegalArgumentException("Increment can't be 0");
+
+ return new AbstractEnumerable<@Nullable Object[]>() {
+ @Override public Enumerator<@Nullable Object[]> enumerator() {
+ return new Enumerator<Object[]>() {
+ long cur = rangeStart - increment;
+
+ @Override public Object[] current() {
+ return new Object[] { cur };
+ }
+
+ @Override public boolean moveNext() {
+ cur += increment;
+
+ return increment > 0L ? cur <= rangeEnd : cur >= rangeEnd;
+ }
+
+ @Override public void reset() {
+ cur = rangeStart - increment;
+ }
+
+ @Override public void close() {
+ // No-op.
+ }
+ };
+ }
+ };
+ }
+
+ /** */
+ private long convertToLongArg(Object val, String name) {
+ if (val instanceof Byte || val instanceof Short || val instanceof Integer || val instanceof Long)
+ return ((Number)val).longValue();
+
+ throw new IllegalArgumentException("Unsupported argument type [arg=" + name +
+ ", type=" + val.getClass().getSimpleName() + ']');
+ }
+
+ /** {@inheritDoc} */
+ @Override public Statistic getStatistic() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Schema.TableType getJdbcTableType() {
+ return Schema.TableType.TABLE;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRolledUp(String column) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean rolledUpColumnValidInsideAgg(String column, SqlCall call,
+ SqlNode parent, CalciteConnectionConfig cfg) {
+ return true;
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
index b91e491,0000000..3dfb7a7
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexExecutorImpl.java
@@@ -1,186 -1,0 +1,186 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 at
+ *
+ * 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.
+ */
+package org.apache.ignite.internal.processors.query.calcite.exec.exp;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.calcite.DataContext;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.config.CalciteSystemProperty;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.IndexExpression;
+import org.apache.calcite.linq4j.tree.MethodCallExpression;
+import org.apache.calcite.linq4j.tree.MethodDeclaration;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexExecutable;
+import org.apache.calcite.rex.RexExecutor;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.rex.RexProgramBuilder;
+import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.Util;
+
+/**
+ * Evaluates a {@link RexNode} expression.
+ *
+ * <p>For this impl, all the public methods should be
+ * static except that it inherits from {@link RexExecutor}.
+ * This pretends that other code in the project assumes
+ * the executor instance is {@link RexExecutorImpl}.
+*/
+public class RexExecutorImpl implements RexExecutor {
+ /** Data context. */
+ private final DataContext dataCtx;
+
+ /**
+ * @param dataCtx Data context.
+ */
+ public RexExecutorImpl(DataContext dataCtx) {
+ this.dataCtx = dataCtx;
+ }
+
+ /** */
+ private static String compile(RexBuilder rexBuilder, List<RexNode> constExps,
+ RexToLixTranslator.InputGetter getter) {
+ final RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
+ final RelDataType emptyRowType = typeFactory.builder().build();
+ return compile(rexBuilder, constExps, getter, emptyRowType);
+ }
+
+ /** */
+ private static String compile(RexBuilder rexBuilder, List<RexNode> constExps,
+ RexToLixTranslator.InputGetter getter, RelDataType rowType) {
+ final RexProgramBuilder programBuilder =
+ new RexProgramBuilder(rowType, rexBuilder);
+ for (RexNode node : constExps) {
+ programBuilder.addProject(
+ node, "c" + programBuilder.getProjectList().size());
+ }
+ final JavaTypeFactoryImpl javaTypeFactory =
+ new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
+ final BlockBuilder blockBuilder = new BlockBuilder();
+ final ParameterExpression root0_ =
+ Expressions.parameter(Object.class, "root0");
+ final ParameterExpression root_ = DataContext.ROOT;
+ blockBuilder.add(
+ Expressions.declare(
+ Modifier.FINAL, root_,
+ Expressions.convert_(root0_, DataContext.class)));
+ final SqlConformance conformance = SqlConformanceEnum.DEFAULT;
+ final RexProgram program = programBuilder.getProgram();
+ final List<Expression> expressions =
+ RexToLixTranslator.translateProjects(program, javaTypeFactory,
+ conformance, blockBuilder, null, root_, getter, null);
+ blockBuilder.add(
+ Expressions.return_(null,
+ Expressions.newArrayInit(Object[].class, expressions)));
+ final MethodDeclaration mtdDecl =
+ Expressions.methodDecl(Modifier.PUBLIC, Object[].class,
+ BuiltInMethod.FUNCTION1_APPLY.method.getName(),
+ ImmutableList.of(root0_), blockBuilder.toBlock());
+ String code = Expressions.toString(mtdDecl);
+ if (CalciteSystemProperty.DEBUG.value())
+ Util.debugCode(System.out, code);
+ return code;
+ }
+
+ /**
+ * Creates an {@link RexExecutable} that allows to apply the
+ * generated code during query processing (filter, projection).
+ *
+ * @param rexBuilder Rex builder
+ * @param exps Expressions
+ * @param rowType describes the structure of the input row.
+ */
+ public static RexExecutable getExecutable(RexBuilder rexBuilder, List<RexNode> exps,
+ RelDataType rowType) {
+ final JavaTypeFactoryImpl typeFactory =
+ new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
+ final RexToLixTranslator.InputGetter getter = new DataContextInputGetter(rowType, typeFactory);
+ final String code = compile(rexBuilder, exps, getter, rowType);
+ return new RexExecutable(code, "generated Rex code");
+ }
+
+ /**
+ * Do constant reduction using generated code.
+ */
+ @Override public void reduce(RexBuilder rexBuilder, List<RexNode> constExps,
+ List<RexNode> reducedValues) {
+ final String code = compile(rexBuilder, constExps,
+ (list, index, storageType) -> {
+ throw new UnsupportedOperationException();
+ });
+
+ final RexExecutable executable = new RexExecutable(code, constExps);
+ executable.setDataContext(dataCtx);
+ executable.reduce(rexBuilder, constExps, reducedValues);
+ }
+
+ /**
+ * Implementation of
+ * {@link org.apache.calcite.adapter.enumerable.RexToLixTranslator.InputGetter}
+ * that reads the values of input fields by calling
+ * <code>{@link org.apache.calcite.DataContext#get}("inputRecord")</code>.
+ */
+ private static class DataContextInputGetter implements RexToLixTranslator.InputGetter {
+
+ /** Type factory. */
+ private final RelDataTypeFactory typeFactory;
+
+ /** Row type. */
+ private final RelDataType rowType;
+
+ /**
+ * @param rowType Row type.
+ * @param typeFactory Type factory.
+ */
+ DataContextInputGetter(RelDataType rowType,
+ RelDataTypeFactory typeFactory) {
+ this.rowType = rowType;
+ this.typeFactory = typeFactory;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Expression field(BlockBuilder list, int idx, Type storageType) {
+ MethodCallExpression recFromCtx = Expressions.call(
+ DataContext.ROOT,
+ BuiltInMethod.DATA_CONTEXT_GET.method,
+ Expressions.constant("inputRecord"));
+ Expression recFromCtxCasted =
+ ConverterUtils.convert(recFromCtx, Object[].class);
+ IndexExpression recordAccess = Expressions.arrayIndex(recFromCtxCasted,
+ Expressions.constant(idx));
+ if (storageType == null) {
+ final RelDataType fieldType =
+ rowType.getFieldList().get(idx).getType();
- storageType = ((JavaTypeFactory) typeFactory).getJavaClass(fieldType);
++ storageType = ((JavaTypeFactory)typeFactory).getJavaClass(fieldType);
+ }
+ return ConverterUtils.convert(recordAccess, storageType);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
index efdf857,0000000..539b34d
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
@@@ -1,100 -1,0 +1,100 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec.exp.agg;
+
+import java.util.Arrays;
+import org.apache.ignite.internal.util.typedef.X;
+
+/**
+ *
+ */
+public class GroupKey {
+ /** */
+ public static final GroupKey EMPTY_GRP_KEY = new GroupKey(X.EMPTY_OBJECT_ARRAY);
+
+ /** */
+ private final Object[] fields;
+
+ /** */
+ public GroupKey(Object[] fields) {
+ this.fields = fields;
+ }
+
+ /** */
+ public Object field(int idx) {
+ return fields[idx];
+ }
+
+ /** */
+ public int fieldsCount() {
+ return fields.length;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
- GroupKey groupKey = (GroupKey) o;
++ GroupKey groupKey = (GroupKey)o;
+
+ return Arrays.equals(fields, groupKey.fields);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Arrays.hashCode(fields);
+ }
+
+ /** */
+ public static Builder builder(int rowLen) {
+ return new Builder(rowLen);
+ }
+
+ /** */
+ public static class Builder {
+ /** */
+ private final Object[] fields;
+
+ /** */
+ private int idx;
+
+ /** */
+ private Builder(int rowLen) {
+ fields = new Object[rowLen];
+ }
+
+ /** */
+ public Builder add(Object val) {
+ if (idx == fields.length)
+ throw new IndexOutOfBoundsException();
+
+ fields[idx++] = val;
+
+ return this;
+ }
+
+ /** */
+ public GroupKey build() {
+ assert idx == fields.length;
+
+ return new GroupKey(fields);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/Inbox.java
index ba2a146,0000000..2f068c1
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/Inbox.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/Inbox.java
@@@ -1,519 -1,0 +1,519 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.exec.rel;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.util.Pair;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExchangeService;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
+import org.apache.ignite.internal.processors.query.calcite.exec.MailboxRegistry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A part of exchange.
+ */
+public class Inbox<Row> extends AbstractNode<Row> implements Mailbox<Row>, SingleNode<Row> {
+ /** */
+ private final ExchangeService exchange;
+
+ /** */
+ private final MailboxRegistry registry;
+
+ /** */
+ private final long exchangeId;
+
+ /** */
+ private final long srcFragmentId;
+
+ /** */
+ private final Map<UUID, Buffer> perNodeBuffers;
+
+ /** */
+ private volatile Collection<UUID> srcNodeIds;
+
+ /** */
+ private Comparator<Row> comp;
+
+ /** */
+ private List<Buffer> buffers;
+
+ /** */
+ private int requested;
+
+ /** */
+ private boolean inLoop;
+
+ /**
+ * @param ctx Execution context.
+ * @param exchange Exchange service.
+ * @param registry Mailbox registry.
+ * @param exchangeId Exchange ID.
+ * @param srcFragmentId Source fragment ID.
+ */
+ public Inbox(
+ ExecutionContext<Row> ctx,
+ ExchangeService exchange,
+ MailboxRegistry registry,
+ long exchangeId,
+ long srcFragmentId
+ ) {
+ super(ctx, ctx.getTypeFactory().createUnknownType());
+ this.exchange = exchange;
+ this.registry = registry;
+
+ this.srcFragmentId = srcFragmentId;
+ this.exchangeId = exchangeId;
+
+ perNodeBuffers = new HashMap<>();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long exchangeId() {
+ return exchangeId;
+ }
+
+ /**
+ * Inits this Inbox.
+ *
+ * @param ctx Execution context.
+ * @param srcNodeIds Source node IDs.
+ * @param comp Optional comparator for merge exchange.
+ */
+ public void init(ExecutionContext<Row> ctx, RelDataType rowType, Collection<UUID> srcNodeIds, @Nullable Comparator<Row> comp) {
+ assert context().fragmentId() == ctx.fragmentId() : "different fragments unsupported: previous=" + context().fragmentId() +
+ " current=" + ctx.fragmentId();
+
+ // It's important to set proper context here because
+ // the one, that is created on a first message
+ // received doesn't have all context variables in place.
+ context(ctx);
+ rowType(rowType);
+
+ this.comp = comp;
+
+ // memory barier
+ this.srcNodeIds = new HashSet<>(srcNodeIds);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void request(int rowsCnt) throws Exception {
+ assert srcNodeIds != null;
+ assert rowsCnt > 0 && requested == 0;
+
+ checkState();
+
+ requested = rowsCnt;
+
+ if (!inLoop)
+ context().execute(this::doPush, this::onError);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void closeInternal() {
+ super.closeInternal();
+
+ registry.unregister(this);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Downstream<Row> requestDownstream(int idx) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void register(List<Node<Row>> sources) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void rewindInternal() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Pushes a batch into a buffer.
+ *
+ * @param src Source node.
+ * @param batchId Batch ID.
+ * @param last Last batch flag.
+ * @param rows Rows.
+ */
+ public void onBatchReceived(UUID src, int batchId, boolean last, List<Row> rows) throws Exception {
+ Buffer buf = getOrCreateBuffer(src);
+
+ boolean waitingBefore = buf.check() == State.WAITING;
+
+ buf.offer(batchId, last, rows);
+
+ if (requested > 0 && waitingBefore && buf.check() != State.WAITING)
+ push();
+ }
+
+ /** */
+ private void doPush() throws Exception {
+ checkState();
+
+ push();
+ }
+
+ /** */
+ private void push() throws Exception {
+ if (buffers == null) {
+ for (UUID node : srcNodeIds)
+ checkNode(node);
+
+ buffers = srcNodeIds.stream()
+ .map(this::getOrCreateBuffer)
+ .collect(Collectors.toList());
+
+ assert buffers.size() == perNodeBuffers.size();
+ }
+
+ if (comp != null)
+ pushOrdered();
+ else
+ pushUnordered();
+ }
+
+ /** */
+ private void pushOrdered() throws Exception {
+ PriorityQueue<Pair<Row, Buffer>> heap =
+ new PriorityQueue<>(Math.max(buffers.size(), 1), Map.Entry.comparingByKey(comp));
+
+ Iterator<Buffer> it = buffers.iterator();
+
+ while (it.hasNext()) {
+ Buffer buf = it.next();
+
+ switch (buf.check()) {
+ case END:
+ it.remove();
+
+ break;
+ case READY:
+ heap.offer(Pair.of(buf.peek(), buf));
+
+ break;
+ case WAITING:
+
+ return;
+ }
+ }
+
+ inLoop = true;
+ try {
+ while (requested > 0 && !heap.isEmpty()) {
+ checkState();
+
+ Buffer buf = heap.poll().right;
+
+ requested--;
+ downstream().push(buf.remove());
+
+ switch (buf.check()) {
+ case END:
+ buffers.remove(buf);
+
+ break;
+ case READY:
+ heap.offer(Pair.of(buf.peek(), buf));
+
+ break;
+ case WAITING:
+
+ return;
+ }
+ }
+ }
+ finally {
+ inLoop = false;
+ }
+
+ if (requested > 0 && heap.isEmpty()) {
+ assert buffers.isEmpty();
+
+ requested = 0;
+ downstream().end();
+ }
+ }
+
+ /** */
+ private void pushUnordered() throws Exception {
+ int idx = 0, noProgress = 0;
+
+ inLoop = true;
+ try {
+ while (requested > 0 && !buffers.isEmpty()) {
+ checkState();
+
+ Buffer buf = buffers.get(idx);
+
+ switch (buf.check()) {
+ case END:
+ buffers.remove(idx--);
+
+ break;
+ case READY:
+ noProgress = 0;
+ requested--;
+ downstream().push(buf.remove());
+
+ break;
+ case WAITING:
+ if (++noProgress >= buffers.size())
+ return;
+
+ break;
+ }
+
+ if (++idx == buffers.size())
+ idx = 0;
+ }
+ }
+ finally {
+ inLoop = false;
+ }
+
+ if (requested > 0 && buffers.isEmpty()) {
+ requested = 0;
+ downstream().end();
+ }
+ }
+
+ /** */
+ private void acknowledge(UUID nodeId, int batchId) throws IgniteCheckedException {
+ exchange.acknowledge(nodeId, queryId(), srcFragmentId, exchangeId, batchId);
+ }
+
+ /** */
+ private Buffer getOrCreateBuffer(UUID nodeId) {
+ return perNodeBuffers.computeIfAbsent(nodeId, this::createBuffer);
+ }
+
+ /** */
+ private Buffer createBuffer(UUID nodeId) {
+ return new Buffer(nodeId);
+ }
+
+ /** */
+ public void onNodeLeft(UUID nodeId) {
+ if (context().originatingNodeId().equals(nodeId) && srcNodeIds == null)
+ context().execute(this::close, this::onError);
+ else if (srcNodeIds != null && srcNodeIds.contains(nodeId))
+ context().execute(() -> onNodeLeft0(nodeId), this::onError);
+ }
+
+ /** */
+ private void onNodeLeft0(UUID nodeId) throws Exception {
+ checkState();
+
+ if (getOrCreateBuffer(nodeId).check() != State.END)
+ throw new ClusterTopologyCheckedException("Failed to execute query, node left [nodeId=" + nodeId + ']');
+ }
+
+ /** */
+ private void checkNode(UUID nodeId) throws ClusterTopologyCheckedException {
+ if (!exchange.alive(nodeId))
+ throw new ClusterTopologyCheckedException("Failed to execute query, node left [nodeId=" + nodeId + ']');
+ }
+
+ /** */
+ private static final class Batch<Row> implements Comparable<Batch<Row>> {
+ /** */
+ private final int batchId;
+
+ /** */
+ private final boolean last;
+
+ /** */
+ private final List<Row> rows;
+
+ /** */
+ private int idx;
+
+ /** */
+ private Batch(int batchId, boolean last, List<Row> rows) {
+ this.batchId = batchId;
+ this.last = last;
+ this.rows = rows;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
- Batch<Row> batch = (Batch<Row>) o;
++ Batch<Row> batch = (Batch<Row>)o;
+
+ return batchId == batch.batchId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return batchId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int compareTo(@NotNull Inbox.Batch<Row> o) {
+ return Integer.compare(batchId, o.batchId);
+ }
+ }
+
+ /** */
+ private enum State {
+ /** */
+ END,
+
+ /** */
+ READY,
+
+ /** */
+ WAITING
+ }
+
+ /** */
+ private static final Batch<?> WAITING = new Batch<>(0, false, null);
+
+ /** */
+ private static final Batch<?> END = new Batch<>(0, false, null);
+
+ /** */
+ private final class Buffer {
+ /** */
+ private final UUID nodeId;
+
+ /** */
+ private int lastEnqueued = -1;
+
+ /** */
+ private final PriorityQueue<Batch<Row>> batches = new PriorityQueue<>(IO_BATCH_CNT);
+
+ /** */
+ private Batch<Row> curr = waitingMark();
+
+ /** */
+ private Buffer(UUID nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ /** */
+ private void offer(int id, boolean last, List<Row> rows) {
+ batches.offer(new Batch<>(id, last, rows));
+ }
+
+ /** */
+ private Batch<Row> pollBatch() {
+ if (batches.isEmpty() || batches.peek().batchId != lastEnqueued + 1)
+ return waitingMark();
+
+ Batch<Row> batch = batches.poll();
+
+ assert batch != null && batch.batchId == lastEnqueued + 1;
+
+ lastEnqueued = batch.batchId;
+
+ return batch;
+ }
+
+ /** */
+ private State check() {
+ if (finished())
+ return State.END;
+
+ if (waiting())
+ return State.WAITING;
+
+ if (isEnd()) {
+ curr = finishedMark();
+
+ return State.END;
+ }
+
+ return State.READY;
+ }
+
+ /** */
+ private Row peek() {
+ assert curr != null;
+ assert curr != WAITING;
+ assert curr != END;
+ assert !isEnd();
+
+ return curr.rows.get(curr.idx);
+ }
+
+ /** */
+ private Row remove() throws IgniteCheckedException {
+ assert curr != null;
+ assert curr != WAITING;
+ assert curr != END;
+ assert !isEnd();
+
+ Row row = curr.rows.set(curr.idx++, null);
+
+ if (curr.idx == curr.rows.size()) {
+ acknowledge(nodeId, curr.batchId);
+
+ if (!isEnd())
+ curr = pollBatch();
+ }
+
+ return row;
+ }
+
+ /** */
+ private boolean finished() {
+ return curr == END;
+ }
+
+ /** */
+ private boolean waiting() {
+ return curr == WAITING && (curr = pollBatch()) == WAITING;
+ }
+
+ /** */
+ private boolean isEnd() {
+ return curr.last && curr.idx == curr.rows.size();
+ }
+
+ /** */
+ private Batch<Row> finishedMark() {
- return (Batch<Row>) END;
++ return (Batch<Row>)END;
+ }
+
+ /** */
+ private Batch<Row> waitingMark() {
- return (Batch<Row>) WAITING;
++ return (Batch<Row>)WAITING;
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
index aa2d454,0000000..e01c1d1
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageServiceImpl.java
@@@ -1,282 -1,0 +1,282 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.message;
+
+import java.util.EnumMap;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.failure.FailureContext;
+import org.apache.ignite.failure.FailureType;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.GridTopic;
+import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
+import org.apache.ignite.internal.managers.communication.GridIoManager;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.internal.managers.communication.GridMessageListener;
+import org.apache.ignite.internal.processors.failure.FailureProcessor;
+import org.apache.ignite.internal.processors.query.calcite.CalciteQueryProcessor;
+import org.apache.ignite.internal.processors.query.calcite.exec.QueryTaskExecutor;
+import org.apache.ignite.internal.processors.query.calcite.util.AbstractService;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.marshaller.MarshallerUtils;
+import org.apache.ignite.plugin.extensions.communication.Message;
+
+/**
+ *
+ */
+public class MessageServiceImpl extends AbstractService implements MessageService, MarshallingContext {
+ /** */
+ private final GridMessageListener msgLsnr;
+
+ /** */
+ private UUID localNodeId;
+
+ /** */
+ private GridIoManager ioManager;
+
+ /** */
+ private ClassLoader classLoader;
+
+ /** */
+ private QueryTaskExecutor taskExecutor;
+
+ /** */
+ private FailureProcessor failureProcessor;
+
+ /** */
+ private Marshaller marsh;
+
+ /** */
+ private EnumMap<MessageType, MessageListener> lsnrs;
+
+ /** */
+ public MessageServiceImpl(GridKernalContext ctx) {
+ super(ctx);
+
+ msgLsnr = this::onMessage;
+ }
+
+ /**
+ * @param localNodeId Local node ID.
+ */
+ public void localNodeId(UUID localNodeId) {
+ this.localNodeId = localNodeId;
+ }
+
+ /**
+ * @return Local node ID.
+ */
+ public UUID localNodeId() {
+ return localNodeId;
+ }
+
+ /**
+ * @param ioManager IO manager.
+ */
+ public void ioManager(GridIoManager ioManager) {
+ this.ioManager = ioManager;
+ }
+
+ /**
+ * @return IO manager.
+ */
+ public GridIoManager ioManager() {
+ return ioManager;
+ }
+
+ /**
+ * @param classLoader Class loader.
+ */
+ public void classLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /** {@inheritDoc} */
+ @Override public ClassLoader classLoader() {
+ return classLoader;
+ }
+
+ /**
+ * @param taskExecutor Task executor.
+ */
+ public void taskExecutor(QueryTaskExecutor taskExecutor) {
+ this.taskExecutor = taskExecutor;
+ }
+
+ /**
+ * @return Task executor.
+ */
+ public QueryTaskExecutor taskExecutor() {
+ return taskExecutor;
+ }
+
+ /**
+ * @param marsh Marshaller.
+ */
+ public void marshaller(Marshaller marsh) {
+ this.marsh = marsh;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Marshaller marshaller() {
+ return marsh;
+ }
+
+ /**
+ * @param failureProcessor Failure processor.
+ */
+ public void failureProcessor(FailureProcessor failureProcessor) {
+ this.failureProcessor = failureProcessor;
+ }
+
+ /**
+ * @return Failure processor.
+ */
+ public FailureProcessor failureProcessor() {
+ return failureProcessor;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onStart(GridKernalContext ctx) {
+ localNodeId(ctx.localNodeId());
+ classLoader(U.resolveClassLoader(ctx.config()));
+ ioManager(ctx.io());
+
+ @SuppressWarnings("deprecation")
+ Marshaller marsh0 = ctx.config().getMarshaller();
+
+ if (marsh0 == null) // Stubbed context doesn't have a marshaller
+ marsh0 = MarshallerUtils.jdkMarshaller(ctx.igniteInstanceName());
+
+ marshaller(marsh0);
+
+ CalciteQueryProcessor proc = Objects.requireNonNull(Commons.lookupComponent(ctx, CalciteQueryProcessor.class));
+
+ taskExecutor(proc.taskExecutor());
+ failureProcessor(proc.failureProcessor());
+
+ init();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void init() {
+ ioManager().addMessageListener(GridTopic.TOPIC_QUERY, msgLsnr);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void tearDown() {
+ ioManager().removeMessageListener(GridTopic.TOPIC_QUERY, msgLsnr);
+ lsnrs = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void send(UUID nodeId, CalciteMessage msg) throws IgniteCheckedException {
+ if (localNodeId().equals(nodeId))
+ onMessage(nodeId, msg);
+ else {
+ prepareMarshal(msg);
+
+ ioManager().sendToGridTopic(nodeId, GridTopic.TOPIC_QUERY, msg, GridIoPolicy.CALLER_THREAD);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void register(MessageListener lsnr, MessageType type) {
+ if (lsnrs == null)
+ lsnrs = new EnumMap<>(MessageType.class);
+
+ MessageListener old = lsnrs.put(type, lsnr);
+
+ assert old == null : old;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean alive(UUID nodeId) {
+ try {
+ return !ioManager().checkNodeLeft(nodeId, null, false);
+ }
+ catch (IgniteClientDisconnectedCheckedException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /** */
+ protected void prepareMarshal(Message msg) throws IgniteCheckedException {
+ try {
+ if (msg instanceof MarshalableMessage)
- ((MarshalableMessage) msg).prepareMarshal(this);
++ ((MarshalableMessage)msg).prepareMarshal(this);
+ }
+ catch (Exception e) {
+ failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
+
+ throw e;
+ }
+ }
+
+ /** */
+ protected void prepareUnmarshal(Message msg) throws IgniteCheckedException {
+ try {
+ if (msg instanceof MarshalableMessage)
- ((MarshalableMessage) msg).prepareUnmarshal(this);
++ ((MarshalableMessage)msg).prepareUnmarshal(this);
+ }
+ catch (Exception e) {
+ failureProcessor().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
+
+ throw e;
+ }
+ }
+
+ /** */
+ protected void onMessage(UUID nodeId, CalciteMessage msg) {
+ if (msg instanceof ExecutionContextAware) {
- ExecutionContextAware msg0 = (ExecutionContextAware) msg;
++ ExecutionContextAware msg0 = (ExecutionContextAware)msg;
+ taskExecutor().execute(msg0.queryId(), msg0.fragmentId(), () -> onMessageInternal(nodeId, msg));
+ }
+ else
+ taskExecutor().execute(
+ IgniteUuid.VM_ID,
+ ThreadLocalRandom.current().nextLong(1024),
+ () -> onMessageInternal(nodeId, msg)
+ );
+ }
+
+ /** */
+ private void onMessage(UUID nodeId, Object msg, byte plc) {
+ if (msg instanceof CalciteMessage)
- onMessage(nodeId, (CalciteMessage) msg);
++ onMessage(nodeId, (CalciteMessage)msg);
+ }
+
+ /** */
+ private void onMessageInternal(UUID nodeId, CalciteMessage msg) {
+ try {
+ prepareUnmarshal(msg);
+
+ MessageListener lsnr = Objects.requireNonNull(lsnrs.get(msg.type()));
+ lsnr.onMessage(nodeId, msg);
+ }
+ catch (IgniteCheckedException e) {
+ throw U.convertException(e);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageType.java
index b330e12,0000000..d327753
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageType.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/message/MessageType.java
@@@ -1,89 -1,0 +1,89 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.message;
+
+import java.util.function.Supplier;
+import org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
+import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentDescription;
+import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentMapping;
+
+/**
+ *
+ */
+public enum MessageType {
+ /** */
+ QUERY_START_REQUEST(300, QueryStartRequest::new),
+
+ /** */
+ QUERY_START_RESPONSE(301, QueryStartResponse::new),
+
+ /** */
+ QUERY_ERROR_MESSAGE(302, ErrorMessage::new),
+
+ /** */
+ QUERY_BATCH_MESSAGE(303, QueryBatchMessage::new),
+
+ /** */
+ QUERY_ACKNOWLEDGE_MESSAGE(304, QueryBatchAcknowledgeMessage::new),
+
+ /** */
+ QUERY_INBOX_CANCEL_MESSAGE(305, InboxCloseMessage::new),
+
+ /** */
+ QUERY_CLOSE_MESSAGE(306, QueryCloseMessage::new),
+
+ /** */
+ GENERIC_VALUE_MESSAGE(307, GenericValueMessage::new),
+
+ /** */
+ FRAGMENT_MAPPING(350, FragmentMapping::new),
+
+ /** */
+ COLOCATION_GROUP(351, ColocationGroup::new),
+
+ /** */
+ FRAGMENT_DESCRIPTION(352, FragmentDescription::new);
+
+ /** */
+ private final int directType;
+
+ /** */
+ private final Supplier<CalciteMessage> factory;
+
+ /**
+ * @param directType Message direct type.
+ */
+ MessageType(int directType, Supplier<CalciteMessage> factory) {
+ this.directType = directType;
+ this.factory = factory;
+ }
+
+ /**
+ * @return Message direct type;
+ */
+ public short directType() {
- return (short) directType;
++ return (short)directType;
+ }
+
+ /**
+ * @return Message factory.
+ */
+ public Supplier<CalciteMessage> factory() {
+ return factory;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
index b3c3697,0000000..37b22a2
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
@@@ -1,408 -1,0 +1,408 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.metadata;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Ordering;
+import org.apache.calcite.adapter.jdbc.JdbcToEnumerableConverter;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.hep.HepRelVertex;
+import org.apache.calcite.plan.volcano.RelSubset;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Match;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.SortExchange;
+import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.core.TableScan;
+import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.core.Window;
+import org.apache.calcite.rel.metadata.BuiltInMetadata;
+import org.apache.calcite.rel.metadata.MetadataDef;
+import org.apache.calcite.rel.metadata.MetadataHandler;
+import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMdCollation;
+import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexCallBinding;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Implementation class for {@link RelMetadataQuery#collations(RelNode)} method call.
+ * See {@link org.apache.calcite.rel.metadata.RelMdCollation}
+ */
+@SuppressWarnings("unused") // actually all methods are used by runtime generated classes
+public class IgniteMdCollation implements MetadataHandler<BuiltInMetadata.Collation> {
+ /** */
+ public static final RelMetadataProvider SOURCE =
+ ReflectiveRelMetadataProvider.reflectiveSource(
+ BuiltInMethod.COLLATIONS.method, new IgniteMdCollation());
+
+ //~ Constructors -----------------------------------------------------------
+
+ /** */
+ private IgniteMdCollation() {}
+
+ //~ Methods ----------------------------------------------------------------
+
+ /** {@inheritDoc} */
+ @Override public MetadataDef<BuiltInMetadata.Collation> getDef() {
+ return BuiltInMetadata.Collation.DEF;
+ }
+
+ /** Catch-all implementation for
+ * {@link BuiltInMetadata.Collation#collations()},
+ * invoked using reflection, for any relational expression not
+ * handled by a more specific method.
+ *
+ * <p>{@link org.apache.calcite.rel.core.Union},
+ * {@link org.apache.calcite.rel.core.Intersect},
+ * {@link org.apache.calcite.rel.core.Minus},
+ * {@link org.apache.calcite.rel.core.Join},
+ * {@link org.apache.calcite.rel.core.Correlate}
+ * do not in general return sorted results
+ * (but implementations using particular algorithms may).
+ *
+ * @param rel Relational expression
+ * @return Relational expression's collations
+ *
+ * @see org.apache.calcite.rel.metadata.RelMetadataQuery#collations(RelNode)
+ */
+ public ImmutableList<RelCollation> collations(RelNode rel,
+ RelMetadataQuery mq) {
+ return ImmutableList.of();
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(
+ IgniteRel rel,
+ RelMetadataQuery mq
+ ) {
+ RelCollation collation = rel.collation();
+ if (collation == null || F.isEmpty(collation.getFieldCollations()))
+ return ImmutableList.of();
+
+ return ImmutableList.of(collation);
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Window rel,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(window(mq, rel.getInput(), rel.groups));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Match rel,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ match(mq, rel.getInput(), rel.getRowType(), rel.getPattern(),
+ rel.isStrictStart(), rel.isStrictEnd(),
+ rel.getPatternDefinitions(), rel.getMeasures(), rel.getAfter(),
+ rel.getSubsets(), rel.isAllRows(), rel.getPartitionKeys(),
+ rel.getOrderKeys(), rel.getInterval()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Filter rel,
+ RelMetadataQuery mq) {
+ return mq.collations(rel.getInput());
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(TableModify rel,
+ RelMetadataQuery mq) {
+ return mq.collations(rel.getInput());
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(TableScan scan,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(table(scan.getTable()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Sort sort,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ RelMdCollation.sort(sort.getCollation()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(SortExchange sort,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ RelMdCollation.sort(sort.getCollation()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Project project,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ project(mq, project.getInput(), project.getProjects()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Calc calc,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(calc(mq, calc.getInput(), calc.getProgram()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(Values values,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ values(mq, values.getRowType(), values.getTuples()));
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(JdbcToEnumerableConverter rel,
+ RelMetadataQuery mq) {
+ return mq.collations(rel.getInput());
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(HepRelVertex rel,
+ RelMetadataQuery mq) {
+ return mq.collations(rel.getCurrentRel());
+ }
+
+ /** */
+ public ImmutableList<RelCollation> collations(RelSubset rel,
+ RelMetadataQuery mq) {
+ return ImmutableList.copyOf(
+ Objects.requireNonNull(
+ rel.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE)));
+ }
+
+ // Helper methods
+
+ /** Helper method to determine a
+ * {@link org.apache.calcite.rel.core.TableScan}'s collation. */
+ public static List<RelCollation> table(RelOptTable table) {
+ return table.getCollationList();
+ }
+
+ /** Helper method to determine a
+ * {@link org.apache.calcite.rel.core.Calc}'s collation. */
+ public static List<RelCollation> calc(RelMetadataQuery mq, RelNode input,
+ RexProgram program) {
+ final List<RexNode> projects =
+ program
+ .getProjectList()
+ .stream()
+ .map(program::expandLocalRef)
+ .collect(Collectors.toList());
+ return project(mq, input, projects);
+ }
+
+ /** Helper method to determine a {@link Project}'s collation. */
+ public static List<RelCollation> project(RelMetadataQuery mq,
+ RelNode input, List<? extends RexNode> projects) {
+ final SortedSet<RelCollation> collations = new TreeSet<>();
+ final List<RelCollation> inputCollations = mq.collations(input);
+ if (inputCollations == null || inputCollations.isEmpty()) {
+ return ImmutableList.of();
+ }
+ final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
+ final Map<Integer, SqlMonotonicity> targetsWithMonotonicity =
+ new HashMap<>();
+ for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
+ if (project.e instanceof RexInputRef) {
- targets.put(((RexInputRef) project.e).getIndex(), project.i);
++ targets.put(((RexInputRef)project.e).getIndex(), project.i);
+ } else if (project.e instanceof RexCall) {
- final RexCall call = (RexCall) project.e;
++ final RexCall call = (RexCall)project.e;
+ final RexCallBinding binding =
+ RexCallBinding.create(Commons.typeFactory(input), call, inputCollations);
+ targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
+ }
+ }
+ final List<RelFieldCollation> fieldCollations = new ArrayList<>();
+ loop:
+ for (RelCollation ic : inputCollations) {
+ if (ic.getFieldCollations().isEmpty()) {
+ continue;
+ }
+ fieldCollations.clear();
+ for (RelFieldCollation ifc : ic.getFieldCollations()) {
+ final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
+ if (integers.isEmpty()) {
+ continue loop; // cannot do this collation
+ }
+ fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
+ }
+ assert !fieldCollations.isEmpty();
+ collations.add(RelCollations.of(fieldCollations));
+ }
+
+ final List<RelFieldCollation> fieldCollationsForRexCalls =
+ new ArrayList<>();
+ for (Map.Entry<Integer, SqlMonotonicity> entry
+ : targetsWithMonotonicity.entrySet()) {
+ final SqlMonotonicity value = entry.getValue();
+ switch (value) {
+ case NOT_MONOTONIC:
+ case CONSTANT:
+ break;
+ default:
+ fieldCollationsForRexCalls.add(
+ new RelFieldCollation(entry.getKey(),
+ RelFieldCollation.Direction.of(value)));
+ break;
+ }
+ }
+
+ if (!fieldCollationsForRexCalls.isEmpty()) {
+ collations.add(RelCollations.of(fieldCollationsForRexCalls));
+ }
+
+ return ImmutableList.copyOf(collations);
+ }
+
+ /** Helper method to determine a
+ * {@link org.apache.calcite.rel.core.Window}'s collation.
+ *
+ * <p>A Window projects the fields of its input first, followed by the output
+ * from each of its windows. Assuming (quite reasonably) that the
+ * implementation does not re-order its input rows, then any collations of its
+ * input are preserved. */
+ public static List<RelCollation> window(RelMetadataQuery mq, RelNode input,
+ ImmutableList<Window.Group> groups) {
+ return mq.collations(input);
+ }
+
+ /** Helper method to determine a
+ * {@link org.apache.calcite.rel.core.Match}'s collation. */
+ public static List<RelCollation> match(RelMetadataQuery mq, RelNode input,
+ RelDataType rowType, RexNode pattern,
+ boolean strictStart, boolean strictEnd,
+ Map<String, RexNode> patternDefinitions, Map<String, RexNode> measures,
+ RexNode after, Map<String, ? extends SortedSet<String>> subsets,
+ boolean allRows, ImmutableBitSet partitionKeys, RelCollation orderKeys,
+ RexNode interval) {
+ return mq.collations(input);
+ }
+
+ /** Helper method to determine a
+ * {@link org.apache.calcite.rel.core.Values}'s collation.
+ *
+ * <p>We actually under-report the collations. A Values with 0 or 1 rows - an
+ * edge case, but legitimate and very common - is ordered by every permutation
+ * of every subset of the columns.
+ *
+ * <p>So, our algorithm aims to:<ul>
+ * <li>produce at most N collations (where N is the number of columns);
+ * <li>make each collation as long as possible;
+ * <li>do not repeat combinations already emitted -
+ * if we've emitted {@code (a, b)} do not later emit {@code (b, a)};
+ * <li>probe the actual values and make sure that each collation is
+ * consistent with the data
+ * </ul>
+ *
+ * <p>So, for an empty Values with 4 columns, we would emit
+ * {@code (a, b, c, d), (b, c, d), (c, d), (d)}. */
+ public static List<RelCollation> values(RelMetadataQuery mq,
+ RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) {
+ Util.discard(mq); // for future use
+ final List<RelCollation> list = new ArrayList<>();
+ final int n = rowType.getFieldCount();
+ final List<Pair<RelFieldCollation, Ordering<List<RexLiteral>>>> pairs =
+ new ArrayList<>();
+ outer:
+ for (int i = 0; i < n; i++) {
+ pairs.clear();
+ for (int j = i; j < n; j++) {
+ final RelFieldCollation fieldCollation = new RelFieldCollation(j);
+ Ordering<List<RexLiteral>> comparator = comparator(fieldCollation);
+ Ordering<List<RexLiteral>> ordering;
+ if (pairs.isEmpty()) {
+ ordering = comparator;
+ } else {
+ ordering = Util.last(pairs).right.compound(comparator);
+ }
+ pairs.add(Pair.of(fieldCollation, ordering));
+ if (!ordering.isOrdered(tuples)) {
+ if (j == i) {
+ continue outer;
+ }
+ pairs.remove(pairs.size() - 1);
+ }
+ }
+ if (!pairs.isEmpty()) {
+ list.add(RelCollations.of(Pair.left(pairs)));
+ }
+ }
+ return list;
+ }
+
+ /** */
+ private static Ordering<List<RexLiteral>> comparator(
+ RelFieldCollation fieldCollation) {
+ final int nullComparison = fieldCollation.nullDirection.nullComparison;
+ final int x = fieldCollation.getFieldIndex();
+ switch (fieldCollation.direction) {
+ case ASCENDING:
+ return new Ordering<List<RexLiteral>>() {
+ public int compare(List<RexLiteral> o1, List<RexLiteral> o2) {
+ final Comparable c1 = o1.get(x).getValueAs(Comparable.class);
+ final Comparable c2 = o2.get(x).getValueAs(Comparable.class);
+ return RelFieldCollation.compare(c1, c2, nullComparison);
+ }
+ };
+ default:
+ return new Ordering<List<RexLiteral>>() {
+ public int compare(List<RexLiteral> o1, List<RexLiteral> o2) {
+ final Comparable c1 = o1.get(x).getValueAs(Comparable.class);
+ final Comparable c2 = o2.get(x).getValueAs(Comparable.class);
+ return RelFieldCollation.compare(c2, c1, -nullComparison);
+ }
+ };
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdColumnOrigins.java
index 47315a5,0000000..3606dc3
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdColumnOrigins.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdColumnOrigins.java
@@@ -1,386 -1,0 +1,386 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.metadata;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.core.Exchange;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.SetOp;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableFunctionScan;
+import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.metadata.BuiltInMetadata;
+import org.apache.calcite.rel.metadata.MetadataDef;
+import org.apache.calcite.rel.metadata.MetadataHandler;
+import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelColumnMapping;
+import org.apache.calcite.rel.metadata.RelColumnOrigin;
+import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLocalRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.rex.RexSlot;
+import org.apache.calcite.rex.RexVisitor;
+import org.apache.calcite.rex.RexVisitorImpl;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.ignite.internal.processors.query.calcite.rel.ProjectableFilterableTableScan;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * RelMdColumnOrigins supplies a default implementation of
+ * {@link RelMetadataQuery#getColumnOrigins} for the standard logical algebra.
+ */
+public class IgniteMdColumnOrigins implements MetadataHandler<BuiltInMetadata.ColumnOrigin> {
+ /** */
+ public static final RelMetadataProvider SOURCE = ReflectiveRelMetadataProvider.reflectiveSource(
+ BuiltInMethod.COLUMN_ORIGIN.method, new IgniteMdColumnOrigins());
+
+ /** {@inheritDoc} */
+ @Override public MetadataDef<BuiltInMetadata.ColumnOrigin> getDef() {
+ return BuiltInMetadata.ColumnOrigin.DEF;
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Aggregate rel, RelMetadataQuery mq, int iOutputColumn) {
+ if (iOutputColumn < rel.getGroupCount()) {
+ // get actual index of Group columns.
+ return mq.getColumnOrigins(rel.getInput(), rel.getGroupSet().asList().get(iOutputColumn));
+ }
+
+ // Aggregate columns are derived from input columns
+ AggregateCall call = rel.getAggCallList().get(iOutputColumn - rel.getGroupCount());
+
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ for (Integer iInput : call.getArgList()) {
+ Set<RelColumnOrigin> inputSet = mq.getColumnOrigins(rel.getInput(), iInput);
+ inputSet = createDerivedColumnOrigins(inputSet);
+
+ if (inputSet != null)
+ set.addAll(inputSet);
+
+ }
+ return set;
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Join rel, RelMetadataQuery mq,
+ int iOutputColumn) {
+ int nLeftColumns = rel.getLeft().getRowType().getFieldList().size();
+ Set<RelColumnOrigin> set;
+ boolean derived = false;
+
+ if (iOutputColumn < nLeftColumns) {
+ set = mq.getColumnOrigins(rel.getLeft(), iOutputColumn);
+
+ if (rel.getJoinType().generatesNullsOnLeft())
+ derived = true;
+
+ }
+ else {
+ set = mq.getColumnOrigins(rel.getRight(), iOutputColumn - nLeftColumns);
+
+ if (rel.getJoinType().generatesNullsOnRight())
+ derived = true;
+ }
+
+ if (derived) {
+ // nulls are generated due to outer join; that counts
+ // as derivation
+ set = createDerivedColumnOrigins(set);
+ }
+ return set;
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(SetOp rel, RelMetadataQuery mq, int iOutputColumn) {
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ for (RelNode input : rel.getInputs()) {
+ Set<RelColumnOrigin> inputSet = mq.getColumnOrigins(input, iOutputColumn);
+
+ if (inputSet == null)
+ return null;
+
+ set.addAll(inputSet);
+ }
+
+ return set;
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Project rel,
+ final RelMetadataQuery mq, int iOutputColumn) {
+ final RelNode input = rel.getInput();
+ RexNode rexNode = rel.getProjects().get(iOutputColumn);
+
+ if (rexNode instanceof RexInputRef) {
+ // Direct reference: no derivation added.
- RexInputRef inputRef = (RexInputRef) rexNode;
++ RexInputRef inputRef = (RexInputRef)rexNode;
+
+ return mq.getColumnOrigins(input, inputRef.getIndex());
+ }
+ // Anything else is a derivation, possibly from multiple columns.
+ final Set<RelColumnOrigin> set = getMultipleColumns(rexNode, input, mq);
+
+ return createDerivedColumnOrigins(set);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Calc rel, final RelMetadataQuery mq, int iOutputColumn) {
+ final RelNode input = rel.getInput();
+ final RexShuttle rexShuttle = new RexShuttle() {
+ @Override public RexNode visitLocalRef(RexLocalRef localRef) {
+ return rel.getProgram().expandLocalRef(localRef);
+ }
+ };
+ final List<RexNode> projects = new ArrayList<>();
+
+ for (RexNode rex: rexShuttle.apply(rel.getProgram().getProjectList()))
+ projects.add(rex);
+
+ final RexNode rexNode = projects.get(iOutputColumn);
+
+ if (rexNode instanceof RexInputRef) {
+ // Direct reference: no derivation added.
- RexInputRef inputRef = (RexInputRef) rexNode;
++ RexInputRef inputRef = (RexInputRef)rexNode;
+
+ return mq.getColumnOrigins(input, inputRef.getIndex());
+ }
+
+ // Anything else is a derivation, possibly from multiple columns.
+ final Set<RelColumnOrigin> set = getMultipleColumns(rexNode, input, mq);
+
+ return createDerivedColumnOrigins(set);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Filter rel, RelMetadataQuery mq, int iOutputColumn) {
+ return mq.getColumnOrigins(rel.getInput(), iOutputColumn);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Sort rel, RelMetadataQuery mq, int iOutputColumn) {
+ return mq.getColumnOrigins(rel.getInput(), iOutputColumn);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(TableModify rel, RelMetadataQuery mq, int iOutputColumn) {
+ return mq.getColumnOrigins(rel.getInput(), iOutputColumn);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(Exchange rel, RelMetadataQuery mq, int iOutputColumn) {
+ return mq.getColumnOrigins(rel.getInput(), iOutputColumn);
+ }
+
+ /** */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(
+ TableFunctionScan rel,
+ RelMetadataQuery mq,
+ int iOutputColumn
+ ) {
+ Set<RelColumnMapping> mappings = rel.getColumnMappings();
+
+ if (mappings == null) {
+ if (!rel.getInputs().isEmpty()) {
+ // This is a non-leaf transformation: say we don't
+ // know about origins, because there are probably
+ // columns below.
+ return null;
+ }
+ else {
+ // This is a leaf transformation: say there are for sure no
+ // column origins.
+ return Collections.emptySet();
+ }
+ }
+
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ for (RelColumnMapping mapping : mappings) {
+ if (mapping.iOutputColumn != iOutputColumn)
+ continue;
+
+ final RelNode input = rel.getInputs().get(mapping.iInputRel);
+ final int column = mapping.iInputColumn;
+ Set<RelColumnOrigin> origins = mq.getColumnOrigins(input, column);
+
+ if (origins == null)
+ return null;
+
+ if (mapping.derived)
+ origins = createDerivedColumnOrigins(origins);
+
+ set.addAll(origins);
+ }
+
+ return set;
+ }
+
+ /**
+ * Get column origins.
+ *
+ * @param rel Rel to get origins from.
+ * @param mq Rel metadata query.
+ * @param iOutputColumn Column idx.
+ * @return Set of column origins.
+ */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(
+ ProjectableFilterableTableScan rel,
+ RelMetadataQuery mq,
+ int iOutputColumn
+ ) {
+ if (rel.projects() != null) {
+ RexNode proj = rel.projects().get(iOutputColumn);
+ Set<RexSlot> sources = new HashSet<>();
+
+ getOperands(proj, RexSlot.class, sources);
+
+ boolean derived = sources.size() > 1;
+ Set<RelColumnOrigin> res = new HashSet<>();
+
+ for (RexSlot slot : sources) {
+ if (slot instanceof RexLocalRef) {
+ RelColumnOrigin slotOrigin = rel.columnOriginsByRelLocalRef(slot.getIndex());
+
+ res.add(new RelColumnOrigin(slotOrigin.getOriginTable(), slotOrigin.getOriginColumnOrdinal(),
+ derived));
+ }
+ }
+
+ return res;
+ }
+
+ return Collections.singleton(rel.columnOriginsByRelLocalRef(iOutputColumn));
+ }
+
+ /**
+ * Get operands of specified type from RexCall nodes.
+ *
+ * @param rn RexNode to get operands
+ * @param cls Target class.
+ * @param res Set to store results into.
+ */
+ private <T> void getOperands(RexNode rn, Class<T> cls, Set<T> res) {
+ if (cls.isAssignableFrom(rn.getClass()))
+ res.add((T)rn);
+
+ if (rn instanceof RexCall) {
+ List<RexNode> operands = ((RexCall)rn).getOperands();
+
+ for (RexNode op : operands)
+ getOperands(op, cls, res);
+ }
+ }
+
+ /**
+ * Catch-all rule when none of the others apply.
+ *
+ * @param rel RelNode.
+ * @param mq RelMetadataQuery.
+ * @param iOutputColumn output column idx.
+ * @return Set of column origins.
+ */
+ public @Nullable Set<RelColumnOrigin> getColumnOrigins(RelNode rel, RelMetadataQuery mq, int iOutputColumn) {
+ // NOTE jvs 28-Mar-2006: We may get this wrong for a physical table
+ // expression which supports projections. In that case,
+ // it's up to the plugin writer to override with the
+ // correct information.
+
+ if (!rel.getInputs().isEmpty()) {
+ // No generic logic available for non-leaf rels.
+ return null;
+ }
+
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ RelOptTable table = rel.getTable();
+ if (table == null) {
+ // Somebody is making column values up out of thin air, like a
+ // VALUES clause, so we return an empty set.
+ return set;
+ }
+
+ // Detect the case where a physical table expression is performing
+ // projection, and say we don't know instead of making any assumptions.
+ // (Theoretically we could try to map the projection using column
+ // names.) This detection assumes the table expression doesn't handle
+ // rename as well.
+ if (table.getRowType() != rel.getRowType())
+ return null;
+
+ set.add(new RelColumnOrigin(table, iOutputColumn, false));
+
+ return set;
+ }
+
+ /**
+ * Create derived set of column origins from specified.
+ *
+ * @param inputSet RelColumnOrigin set to derive from.
+ * @return derived RelColumnOrigin or {@code null}.
+ */
+ private static Set<RelColumnOrigin> createDerivedColumnOrigins(Set<RelColumnOrigin> inputSet) {
+ if (inputSet == null)
+ return null;
+
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ for (RelColumnOrigin rco : inputSet) {
+ RelColumnOrigin derived = new RelColumnOrigin(rco.getOriginTable(), rco.getOriginColumnOrdinal(), true);
+ set.add(derived);
+ }
+
+ return set;
+ }
+
+ /** */
+ private static Set<RelColumnOrigin> getMultipleColumns(RexNode rexNode, RelNode input, final RelMetadataQuery mq) {
+ final Set<RelColumnOrigin> set = new HashSet<>();
+
+ final RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {
+ @Override public Void visitInputRef(RexInputRef inputRef) {
+ Set<RelColumnOrigin> inputSet = mq.getColumnOrigins(input, inputRef.getIndex());
+
+ if (inputSet != null)
+ set.addAll(inputSet);
+
+ return null;
+ }
+ };
+
+ rexNode.accept(visitor);
+
+ return set;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
index c68ab89,0000000..c832235
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdDistribution.java
@@@ -1,111 -1,0 +1,111 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.metadata;
+
+import org.apache.calcite.plan.hep.HepRelVertex;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Exchange;
+import org.apache.calcite.rel.core.TableScan;
+import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.metadata.BuiltInMetadata;
+import org.apache.calcite.rel.metadata.MetadataDef;
+import org.apache.calcite.rel.metadata.MetadataHandler;
+import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
+import org.apache.ignite.internal.processors.query.calcite.trait.TraitUtils;
+
+/**
+ * Implementation class for {@link RelMetadataQuery#distribution(RelNode)} method call.
+ */
+@SuppressWarnings("unused") // actually all methods are used by runtime generated classes
+public class IgniteMdDistribution implements MetadataHandler<BuiltInMetadata.Distribution> {
+ /**
+ * Metadata provider, responsible for distribution type request. It uses this implementation class under the hood.
+ */
+ public static final RelMetadataProvider SOURCE =
+ ReflectiveRelMetadataProvider.reflectiveSource(
+ BuiltInMethod.DISTRIBUTION.method, new IgniteMdDistribution());
+
+ /** {@inheritDoc} */
+ @Override public MetadataDef<BuiltInMetadata.Distribution> getDef() {
+ return BuiltInMetadata.Distribution.DEF;
+ }
+
+ /**
+ * Requests actual distribution type of the given relational node.
+ * @param rel Relational node.
+ * @param mq Metadata query instance. Used to request appropriate metadata from node children.
+ * @return Distribution type of the given relational node.
+ */
+ public IgniteDistribution distribution(RelNode rel, RelMetadataQuery mq) {
+ return TraitUtils.distribution(rel.getTraitSet());
+ }
+
+ /**
+ * See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
+ */
+ public IgniteDistribution distribution(IgniteRel rel, RelMetadataQuery mq) {
+ return rel.distribution();
+ }
+
+ /**
+ * See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
+ */
+ public IgniteDistribution distribution(TableScan rel, RelMetadataQuery mq) {
+ return rel.getTable().unwrap(IgniteTable.class).distribution();
+ }
+
+ /**
+ * See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
+ */
+ public IgniteDistribution distribution(Values rel, RelMetadataQuery mq) {
+ return IgniteDistributions.broadcast();
+ }
+
+ /**
+ * See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
+ */
+ public IgniteDistribution distribution(Exchange rel, RelMetadataQuery mq) {
- return (IgniteDistribution) rel.distribution;
++ return (IgniteDistribution)rel.distribution;
+ }
+
+ /**
+ * See {@link IgniteMdDistribution#distribution(RelNode, RelMetadataQuery)}
+ */
+ public IgniteDistribution distribution(HepRelVertex rel, RelMetadataQuery mq) {
+ return _distribution(rel.getCurrentRel(), mq);
+ }
+
+ /**
+ * Distribution request entry point.
+ * @param rel Relational node.
+ * @param mq Metadata query instance.
+ * @return Actual distribution of the given relational node.
+ */
+ public static IgniteDistribution _distribution(RelNode rel, RelMetadataQuery mq) {
+ assert mq instanceof RelMetadataQueryEx;
+
- return (IgniteDistribution) mq.distribution(rel);
++ return (IgniteDistribution)mq.distribution(rel);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
index a1c5bf9,0000000..35e48db
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/CacheKey.java
@@@ -1,78 -1,0 +1,78 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import java.util.Objects;
+
+/**
+ *
+ */
+public class CacheKey {
+ /** */
+ private final String schemaName;
+
+ /** */
+ private final String query;
+
+ /** */
+ private final Object contextKey;
+
+ /**
+ * @param schemaName Schema name.
+ * @param query Query string.
+ * @param contextKey Optional context key to differ queries with and without/different flags, having an impact
+ * on result plan (like LOCAL flag)
+ */
+ public CacheKey(String schemaName, String query, Object contextKey) {
+ this.schemaName = schemaName;
+ this.query = query;
+ this.contextKey = contextKey;
+ }
+
+ /**
+ * @param schemaName Schema name.
+ * @param query Query string.
+ */
+ public CacheKey(String schemaName, String query) {
+ this(schemaName, query, null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
- CacheKey cacheKey = (CacheKey) o;
++ CacheKey cacheKey = (CacheKey)o;
+
+ if (!schemaName.equals(cacheKey.schemaName))
+ return false;
+ if (!query.equals(cacheKey.query))
+ return false;
+ return Objects.equals(contextKey, cacheKey.contextKey);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int result = schemaName.hashCode();
+ result = 31 * result + query.hashCode();
+ result = 31 * result + (contextKey != null ? contextKey.hashCode() : 0);
+ return result;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/Cloner.java
index 6241243,0000000..146d760
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/Cloner.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/Cloner.java
@@@ -1,244 -1,0 +1,244 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteExchange;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteHashIndexSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteLimit;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteMergeJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteNestedLoopJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteProject;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteReceiver;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRelVisitor;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSender;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSort;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSortedIndexSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableFunctionScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableModify;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTrimExchange;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteUnionAll;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteValues;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteMapHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteMapSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteReduceHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteReduceSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteSingleHashAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.agg.IgniteSingleSortAggregate;
+import org.apache.ignite.internal.processors.query.calcite.rel.set.IgniteSetOp;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.util.typedef.F;
+
+/** */
+public class Cloner implements IgniteRelVisitor<IgniteRel> {
+ /** */
+ private final RelOptCluster cluster;
+
+ /** */
+ private ImmutableList.Builder<IgniteReceiver> remotes;
+
+ /** */
+ Cloner(RelOptCluster cluster) {
+ this.cluster = cluster;
+ }
+
+ /**
+ * Clones and associates a plan with a new cluster.
+ *
+ * @param src Fragment to clone.
+ * @return New plan.
+ */
+ public Fragment go(Fragment src) {
+ try {
+ remotes = ImmutableList.builder();
+
+ IgniteRel newRoot = visit(src.root());
+ ImmutableList<IgniteReceiver> remotes = this.remotes.build();
+
+ return new Fragment(src.fragmentId(), newRoot, remotes, src.serialized(), src.mapping());
+ }
+ finally {
+ remotes = null;
+ }
+ }
+
+ /** */
+ public static IgniteRel clone(IgniteRel r) {
+ Cloner c = new Cloner(r.getCluster());
+
+ return c.visit(r);
+ }
+
+ /** */
+ private IgniteReceiver collect(IgniteReceiver receiver) {
+ if (remotes != null)
+ remotes.add(receiver);
+
+ return receiver;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSender rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteFilter rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteTrimExchange rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteProject rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteTableModify rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteNestedLoopJoin rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getLeft()),
- visit((IgniteRel) rel.getRight())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getLeft()),
++ visit((IgniteRel)rel.getRight())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteCorrelatedNestedLoopJoin rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getLeft()),
- visit((IgniteRel) rel.getRight())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getLeft()),
++ visit((IgniteRel)rel.getRight())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteMergeJoin rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getLeft()),
- visit((IgniteRel) rel.getRight())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getLeft()),
++ visit((IgniteRel)rel.getRight())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteIndexScan rel) {
+ return rel.clone(cluster, F.asList());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteTableScan rel) {
+ return rel.clone(cluster, F.asList());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteValues rel) {
+ return rel.clone(cluster, F.asList());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteUnionAll rel) {
- return rel.clone(cluster, Commons.transform(rel.getInputs(), rel0 -> visit((IgniteRel) rel0)));
++ return rel.clone(cluster, Commons.transform(rel.getInputs(), rel0 -> visit((IgniteRel)rel0)));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSort rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteTableSpool rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSortedIndexSpool rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteLimit rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteReceiver rel) {
+ return collect((IgniteReceiver)rel.clone(cluster, F.asList()));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteExchange rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSingleHashAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteMapHashAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteReduceHashAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSingleSortAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteMapSortAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteReduceSortAggregate rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteHashIndexSpool rel) {
- return rel.clone(cluster, F.asList(visit((IgniteRel) rel.getInput())));
++ return rel.clone(cluster, F.asList(visit((IgniteRel)rel.getInput())));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteSetOp rel) {
- return rel.clone(cluster, Commons.transform(rel.getInputs(), rel0 -> visit((IgniteRel) rel0)));
++ return rel.clone(cluster, Commons.transform(rel.getInputs(), rel0 -> visit((IgniteRel)rel0)));
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteTableFunctionScan rel) {
+ return rel.clone(cluster, F.asList());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteRel visit(IgniteRel rel) {
+ return rel.accept(this);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteConvertletTable.java
index 235c6d0,0000000..9709285
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteConvertletTable.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteConvertletTable.java
@@@ -1,133 -1,0 +1,133 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import java.math.BigDecimal;
+import com.google.common.collect.ImmutableList;
+import org.apache.calcite.avatica.util.DateTimeUtils;
+import org.apache.calcite.avatica.util.TimeUnit;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.type.SqlTypeUtil;
+import org.apache.calcite.sql2rel.ReflectiveConvertletTable;
+import org.apache.calcite.sql2rel.SqlRexContext;
+import org.apache.calcite.sql2rel.SqlRexConvertlet;
+import org.apache.calcite.sql2rel.StandardConvertletTable;
+import org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteOwnSqlOperatorTable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+/**
+ * Ignite convertlet table.
+ */
+public class IgniteConvertletTable extends ReflectiveConvertletTable {
+ /** Instance. */
+ public static final IgniteConvertletTable INSTANCE = new IgniteConvertletTable();
+
+ /** */
+ private IgniteConvertletTable() {
+ // Replace Calcite's convertlet with our own.
+ registerOp(SqlStdOperatorTable.TIMESTAMP_DIFF, new TimestampDiffConvertlet());
+
+ addAlias(IgniteOwnSqlOperatorTable.LENGTH, SqlStdOperatorTable.CHAR_LENGTH);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable
+ @Override public SqlRexConvertlet get(SqlCall call) {
+ SqlRexConvertlet res = super.get(call);
+
+ return res == null ? StandardConvertletTable.INSTANCE.get(call) : res;
+ }
+
+ /** Convertlet that handles the {@code TIMESTAMPDIFF} function. */
+ private static class TimestampDiffConvertlet implements SqlRexConvertlet {
+ /** {@inheritDoc} */
+ @Override public RexNode convertCall(SqlRexContext cx, SqlCall call) {
+ // TIMESTAMPDIFF(unit, t1, t2)
+ // => (t2 - t1) UNIT
+ final RexBuilder rexBuilder = cx.getRexBuilder();
+ final SqlLiteral unitLiteral = call.operand(0);
+ TimeUnit unit = unitLiteral.getValueAs(TimeUnit.class);
+ BigDecimal multiplier = BigDecimal.ONE;
+ BigDecimal divider = BigDecimal.ONE;
+ SqlTypeName sqlTypeName = unit == TimeUnit.NANOSECOND
+ ? SqlTypeName.BIGINT
+ : SqlTypeName.INTEGER;
+ switch (unit) {
+ case MICROSECOND:
+ case MILLISECOND:
+ case NANOSECOND:
+ divider = unit.multiplier;
+ unit = TimeUnit.MILLISECOND;
+ break;
+ case WEEK:
+ multiplier = BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND);
+ divider = unit.multiplier;
+ unit = TimeUnit.SECOND;
+ break;
+ case QUARTER:
+ divider = unit.multiplier;
+ unit = TimeUnit.MONTH;
+ break;
+ default:
+ break;
+ }
+ final SqlIntervalQualifier qualifier =
+ new SqlIntervalQualifier(unit, null, SqlParserPos.ZERO);
+ final RexNode op2 = cx.convertExpression(call.operand(2));
+ final RexNode op1 = cx.convertExpression(call.operand(1));
+ final RelDataType intervalType =
+ cx.getTypeFactory().createTypeWithNullability(
+ cx.getTypeFactory().createSqlIntervalType(qualifier),
+ op1.getType().isNullable() || op2.getType().isNullable());
- final RexCall rexCall = (RexCall) rexBuilder.makeCall(
++ final RexCall rexCall = (RexCall)rexBuilder.makeCall(
+ intervalType, SqlStdOperatorTable.MINUS_DATE,
+ ImmutableList.of(op2, op1));
+ final RelDataType intType =
+ cx.getTypeFactory().createTypeWithNullability(
+ cx.getTypeFactory().createSqlType(sqlTypeName),
+ SqlTypeUtil.containsNullable(rexCall.getType()));
+
+ RexNode e;
+
+ // Since Calcite converts internal time representation to seconds during cast we need our own cast
+ // method to keep fraction of seconds.
+ if (unit == TimeUnit.MILLISECOND)
+ e = makeCastMilliseconds(rexBuilder, intType, rexCall);
+ else
+ e = rexBuilder.makeCast(intType, rexCall);
+
+ return rexBuilder.multiplyDivide(e, multiplier, divider);
+ }
+
+ /**
+ * Creates a call to cast milliseconds interval.
+ */
+ static RexNode makeCastMilliseconds(RexBuilder builder, RelDataType type, RexNode exp) {
+ return builder.ensureType(type, builder.decodeIntervalOrDecimal(exp), false);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
index 30c8bf2,0000000..a456e5f
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgnitePlanner.java
@@@ -1,384 -1,0 +1,384 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import com.google.common.collect.ImmutableList;
+import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptCostFactory;
+import org.apache.calcite.plan.RelOptLattice;
+import org.apache.calcite.plan.RelOptMaterialization;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.volcano.VolcanoPlanner;
+import org.apache.calcite.prepare.CalciteCatalogReader;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelRoot;
+import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexExecutor;
+import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOperatorTable;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql2rel.SqlRexConvertletTable;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.calcite.tools.FrameworkConfig;
+import org.apache.calcite.tools.Planner;
+import org.apache.calcite.tools.Program;
+import org.apache.calcite.tools.RuleSets;
+import org.apache.calcite.tools.ValidationException;
+import org.apache.calcite.util.Pair;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.calcite.metadata.IgniteMetadata;
+import org.apache.ignite.internal.processors.query.calcite.metadata.RelMetadataQueryEx;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+
+/**
+ * Query planer.
+ */
+public class IgnitePlanner implements Planner, RelOptTable.ViewExpander {
+ /** */
+ private final SqlOperatorTable operatorTbl;
+
+ /** */
+ private final ImmutableList<Program> programs;
+
+ /** */
+ private final FrameworkConfig frameworkCfg;
+
+ /** */
+ private final PlanningContext ctx;
+
+ /** */
+ @SuppressWarnings("rawtypes")
+ private final ImmutableList<RelTraitDef> traitDefs;
+
+ /** */
+ private final SqlParser.Config parserCfg;
+
+ /** */
+ private final SqlToRelConverter.Config sqlToRelConverterCfg;
+
+ /** */
+ private final SqlValidator.Config validatorCfg;
+
+ /** */
+ private final SqlRexConvertletTable convertletTbl;
+
+ /** */
+ private final RexExecutor rexExecutor;
+
+ /** */
+ private final IgniteTypeFactory typeFactory;
+
+ /** */
+ private final CalciteCatalogReader catalogReader;
+
+ /** */
+ private RelOptPlanner planner;
+
+ /** */
+ private SqlValidator validator;
+
+ /** */
+ private RelOptCluster cluster;
+
+ /**
+ * @param ctx Planner context.
+ */
+ IgnitePlanner(PlanningContext ctx) {
+ this.ctx = ctx;
+
+ typeFactory = ctx.typeFactory();
+ catalogReader = ctx.catalogReader();
+ operatorTbl = ctx.opTable();
+ frameworkCfg = ctx.config();
+
+ programs = frameworkCfg.getPrograms();
+ parserCfg = frameworkCfg.getParserConfig();
+ sqlToRelConverterCfg = frameworkCfg.getSqlToRelConverterConfig();
+ validatorCfg = frameworkCfg.getSqlValidatorConfig();
+ convertletTbl = frameworkCfg.getConvertletTable();
+ rexExecutor = frameworkCfg.getExecutor();
+ traitDefs = frameworkCfg.getTraitDefs();
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelTraitSet getEmptyTraitSet() {
+ return planner().emptyTraitSet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void close() {
+ reset();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void reset() {
+ planner = null;
+ validator = null;
+ cluster = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public SqlNode parse(Reader reader) throws SqlParseException {
+ SqlNodeList sqlNodes = Commons.parse(reader, parserCfg);
+
+ return sqlNodes.size() == 1 ? sqlNodes.get(0) : sqlNodes;
+ }
+
+ /** {@inheritDoc} */
+ @Override public SqlNode validate(SqlNode sqlNode) throws ValidationException {
+ try {
+ return validator().validate(sqlNode);
+ }
+ catch (RuntimeException e) {
+ throw new ValidationException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public Pair<SqlNode, RelDataType> validateAndGetType(SqlNode sqlNode) {
+ SqlNode validatedNode = validator().validate(sqlNode);
+ RelDataType type = validator().getValidatedNodeType(validatedNode);
+ return Pair.of(validatedNode, type);
+ }
+
+ /**
+ * Converts a SQL data type specification to a relational data type.
+ *
+ * @param typeSpec Spec to convert from.
+ * @return Relational type representation of given SQL type.
+ */
+ public RelDataType convert(SqlDataTypeSpec typeSpec) {
+ return typeSpec.deriveType(validator());
+ }
+
+ /**
+ * Validates a SQL statement.
+ *
+ * @param sqlNode Root node of the SQL parse tree.
+ * @return Validated node, its validated type and type's origins.
+ */
+ public ValidationResult validateAndGetTypeMetadata(SqlNode sqlNode) {
+ SqlNode validatedNode = validator().validate(sqlNode);
+ RelDataType type = validator().getValidatedNodeType(validatedNode);
+ List<List<String>> origins = validator().getFieldOrigins(validatedNode);
+
+ return new ValidationResult(validatedNode, type, origins);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelNode convert(SqlNode sql) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelRoot rel(SqlNode sql) {
+ SqlToRelConverter sqlToRelConverter = sqlToRelConverter(validator(), catalogReader, sqlToRelConverterCfg);
+
+ return sqlToRelConverter.convertQuery(sql, false, true);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelRoot expandView(
+ RelDataType rowType,
+ String qryStr,
+ List<String> schemaPath,
+ List<String> viewPath
+ ) {
+ SqlParser parser = SqlParser.create(qryStr, parserCfg);
+ SqlNode sqlNode;
+ try {
+ sqlNode = parser.parseQuery();
+ }
+ catch (SqlParseException e) {
+ throw new IgniteSQLException("parse failed", IgniteQueryErrorCode.PARSING, e);
+ }
+
+ CalciteCatalogReader catalogReader = this.catalogReader.withSchemaPath(schemaPath);
+ SqlValidator validator = new IgniteSqlValidator(operatorTbl, catalogReader, typeFactory, validatorCfg, ctx.parameters());
+ SqlToRelConverter sqlToRelConverter = sqlToRelConverter(validator, catalogReader, sqlToRelConverterCfg);
+ RelRoot root = sqlToRelConverter.convertQuery(sqlNode, true, false);
+ root = root.withRel(sqlToRelConverter.decorrelate(sqlNode, root.rel));
+
+ return root;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelNode transform(int programIdx, RelTraitSet targetTraits, RelNode rel) {
+ return programs.get(programIdx).run(planner(), rel, targetTraits.simplify(), materializations(), latices());
+ }
+
+ /**
+ * Converts one relational nodes tree into another relational nodes tree
+ * based on a particular planner type, planning phase and required set of traits.
+ * @param phase Planner phase.
+ * @param targetTraits Target traits.
+ * @param rel Root node of relational tree.
+ * @return The root of the new RelNode tree.
+ */
+ public <T extends RelNode> T transform(PlannerPhase phase, RelTraitSet targetTraits, RelNode rel) {
- return (T) phase.getProgram(ctx).run(planner(), rel, targetTraits.simplify(), materializations(), latices());
++ return (T)phase.getProgram(ctx).run(planner(), rel, targetTraits.simplify(), materializations(), latices());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTypeFactory getTypeFactory() {
+ return typeFactory;
+ }
+
+ /** */
+ private RelOptPlanner planner() {
+ if (planner == null) {
+ VolcanoPlannerExt planner = new VolcanoPlannerExt(frameworkCfg.getCostFactory(), ctx);
+ planner.setExecutor(rexExecutor);
+ this.planner = planner;
+
+ for (RelTraitDef<?> def : traitDefs)
+ this.planner.addRelTraitDef(def);
+ }
+
+ return planner;
+ }
+
+ /** */
+ public String dump() {
+ StringWriter w = new StringWriter();
+
+ ((VolcanoPlanner)planner).dump(new PrintWriter(w));
+
+ return w.toString();
+ }
+
+ /** */
+ private SqlValidator validator() {
+ if (validator == null)
+ validator = new IgniteSqlValidator(operatorTbl, catalogReader, typeFactory, validatorCfg, ctx.parameters());
+
+ return validator;
+ }
+
+ /** Creates a cluster. */
+ RelOptCluster cluster() {
+ if (cluster == null) {
+ cluster = RelOptCluster.create(planner(), ctx.rexBuilder());
+ cluster.setMetadataProvider(new CachingRelMetadataProvider(IgniteMetadata.METADATA_PROVIDER, planner()));
+ cluster.setMetadataQuerySupplier(RelMetadataQueryEx::create);
+ }
+
+ return cluster;
+ }
+
+ /** */
+ private List<RelOptLattice> latices() {
+ return ImmutableList.of(); // TODO
+ }
+
+ /**
+ * Returns all applicable materializations (i.e. secondary indexes) for the given rel node,
+ * @return Materializations.
+ */
+ private List<RelOptMaterialization> materializations() {
+ return ImmutableList.of(); // TODO
+ }
+
+ /**
+ * Walks over a tree of relational expressions, replacing each
+ * {@link org.apache.calcite.rel.RelNode} with a 'slimmed down' relational
+ * expression that projects
+ * only the columns required by its consumer.
+ *
+ * @param root Root of relational expression tree
+ * @return Trimmed relational expression
+ */
+ public RelRoot trimUnusedFields(RelRoot root) {
+ // For now, don't trim if there are more than 3 joins. The projects
+ // near the leaves created by trim migrate past joins and seem to
+ // prevent join-reordering.
+ final SqlToRelConverter.Config config = sqlToRelConverterCfg
+ .withExpand(false)
+ .withTrimUnusedFields(RelOptUtil.countJoins(root.rel) < 2);
+ SqlToRelConverter converter = sqlToRelConverter(validator(), catalogReader, config);
+ boolean ordered = !root.collation.getFieldCollations().isEmpty();
+ boolean dml = SqlKind.DML.contains(root.kind);
+ return root.withRel(converter.trimUnusedFields(dml || ordered, root.rel));
+ }
+
+ /** */
+ private SqlToRelConverter sqlToRelConverter(SqlValidator validator, CalciteCatalogReader reader,
+ SqlToRelConverter.Config config) {
+ return new IgniteSqlToRelConvertor(this, validator, reader, cluster(), convertletTbl, config);
+ }
+
+ /** */
+ public void setDisabledRules(Set<String> disabledRuleNames) {
+ ctx.rulesFilter(rulesSet -> {
+ List<RelOptRule> newSet = new ArrayList<>();
+
+ for (RelOptRule r : rulesSet) {
+ if (!disabledRuleNames.contains(shortRuleName(r.toString())))
+ newSet.add(r);
+ }
+
+ return RuleSets.ofList(newSet);
+ });
+ }
+
+ /** */
+ private static String shortRuleName(String ruleDesc) {
+ int pos = ruleDesc.indexOf('(');
+
+ if (pos == -1)
+ return ruleDesc;
+
+ return ruleDesc.substring(0, pos);
+ }
+
+ /** */
+ private static class VolcanoPlannerExt extends VolcanoPlanner {
+ /** */
+ protected VolcanoPlannerExt(RelOptCostFactory costFactory, Context externalCtx) {
+ super(costFactory, externalCtx);
+ setTopDownOpt(true);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelOptCost getCost(RelNode rel, RelMetadataQuery mq) {
+ return mq.getCumulativeCost(rel);
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlToRelConvertor.java
index 1800743,0000000..7963a67
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlToRelConvertor.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlToRelConvertor.java
@@@ -1,168 -1,0 +1,168 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.prepare.Prepare;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelRoot;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.logical.LogicalJoin;
+import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.logical.LogicalTableModify;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlMerge;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlUpdate;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.calcite.sql2rel.SqlRexConvertletTable;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.calcite.tools.RelBuilder;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Converts a SQL parse tree into a relational algebra operators.
+ */
+public class IgniteSqlToRelConvertor extends SqlToRelConverter {
+ /** */
+ public IgniteSqlToRelConvertor(
+ RelOptTable.ViewExpander viewExpander,
+ @Nullable SqlValidator validator,
+ Prepare.CatalogReader catalogReader, RelOptCluster cluster,
+ SqlRexConvertletTable convertletTable,
+ Config cfg
+ ) {
+ super(viewExpander, validator, catalogReader, cluster, convertletTable, cfg);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected RelRoot convertQueryRecursive(SqlNode qry, boolean top, @Nullable RelDataType targetRowType) {
+ if (qry.getKind() == SqlKind.MERGE)
+ return RelRoot.of(convertMerge((SqlMerge)qry), qry.getKind());
+ else
+ return super.convertQueryRecursive(qry, top, targetRowType);
+ }
+
+ /**
+ * This method was copy-pasted from super-method except this changes:
+ * - For updateCall we require all columns in the project and should not skip anything.
+ * - If there is no updateCall, LEFT JOIN converted to ANTI JOIN.
+ */
+ private RelNode convertMerge(SqlMerge call) {
+ RelOptTable targetTable = getTargetTable(call);
+
+ // convert update column list from SqlIdentifier to String
+ final List<String> targetColumnNameList = new ArrayList<>();
+ final RelDataType targetRowType = targetTable.getRowType();
+ SqlUpdate updateCall = call.getUpdateCall();
+ if (updateCall != null) {
+ for (SqlNode targetColumn : updateCall.getTargetColumnList()) {
- SqlIdentifier id = (SqlIdentifier) targetColumn;
++ SqlIdentifier id = (SqlIdentifier)targetColumn;
+ RelDataTypeField field =
+ SqlValidatorUtil.getTargetField(
+ targetRowType, typeFactory, id, catalogReader, targetTable);
+ assert field != null : "column " + id.toString() + " not found";
+ targetColumnNameList.add(field.getName());
+ }
+ }
+
+ // replace the projection of the source select with a
+ // projection that contains the following:
+ // 1) the expressions corresponding to the new insert row (if there is
+ // an insert)
+ // 2) all columns from the target table (if there is an update)
+ // 3) the set expressions in the update call (if there is an update)
+
+ // first, convert the merge's source select to construct the columns
+ // from the target table and the set expressions in the update call
+ RelNode mergeSourceRel = convertSelect(
+ requireNonNull(call.getSourceSelect(), () -> "sourceSelect for " + call), false);
+
+ // then, convert the insert statement so we can get the insert
+ // values expressions
+ SqlInsert insertCall = call.getInsertCall();
+ int nLevel1Exprs = 0;
+ List<RexNode> level1InsertExprs = null;
+ List<RexNode> level2InsertExprs = null;
+ if (insertCall != null) {
+ RelNode insertRel = convertInsert(insertCall);
+
+ // if there are 2 level of projections in the insert source, combine
+ // them into a single project; level1 refers to the topmost project;
+ // the level1 projection contains references to the level2
+ // expressions, except in the case where no target expression was
+ // provided, in which case, the expression is the default value for
+ // the column; or if the expressions directly map to the source
+ // table
+ level1InsertExprs =
- ((LogicalProject) insertRel.getInput(0)).getProjects();
++ ((LogicalProject)insertRel.getInput(0)).getProjects();
+ if (insertRel.getInput(0).getInput(0) instanceof LogicalProject) {
+ level2InsertExprs =
- ((LogicalProject) insertRel.getInput(0).getInput(0))
++ ((LogicalProject)insertRel.getInput(0).getInput(0))
+ .getProjects();
+ }
+ nLevel1Exprs = level1InsertExprs.size();
+ }
+
- LogicalJoin join = (LogicalJoin) mergeSourceRel.getInput(0);
++ LogicalJoin join = (LogicalJoin)mergeSourceRel.getInput(0);
+
+ final List<RexNode> projects = new ArrayList<>();
+
+ for (int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) {
+ requireNonNull(level1InsertExprs, "level1InsertExprs");
+ if ((level2InsertExprs != null)
+ && (level1InsertExprs.get(level1Idx) instanceof RexInputRef)) {
+ int level2Idx =
- ((RexInputRef) level1InsertExprs.get(level1Idx)).getIndex();
++ ((RexInputRef)level1InsertExprs.get(level1Idx)).getIndex();
+ projects.add(level2InsertExprs.get(level2Idx));
+ } else
+ projects.add(level1InsertExprs.get(level1Idx));
+ }
+ if (updateCall != null) {
- final LogicalProject project = (LogicalProject) mergeSourceRel;
++ final LogicalProject project = (LogicalProject)mergeSourceRel;
+ projects.addAll(project.getProjects());
+ }
+ else {
+ // Convert to ANTI join if there is no UPDATE clause.
+ join = join.copy(join.getTraitSet(), join.getCondition(), join.getLeft(), join.getRight(), JoinRelType.ANTI,
+ false);
+ }
+
+ RelBuilder relBuilder = config.getRelBuilderFactory().create(cluster, null)
+ .transform(config.getRelBuilderConfigTransform());
+
+ relBuilder.push(join)
+ .project(projects);
+
+ return LogicalTableModify.create(targetTable, catalogReader,
+ relBuilder.build(), LogicalTableModify.Operation.MERGE,
+ targetColumnNameList, null, false);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
index 5bd31f2,0000000..8c16cc5
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java
@@@ -1,389 -1,0 +1,389 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.prepare;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.prepare.CalciteCatalogReader;
+import org.apache.calcite.prepare.Prepare;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.sql.SqlAggFunction;
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlDelete;
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlInsert;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOperatorTable;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.SqlUpdate;
+import org.apache.calcite.sql.SqlUtil;
+import org.apache.calcite.sql.dialect.CalciteSqlDialect;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.validate.SelectScope;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql.validate.SqlValidatorImpl;
+import org.apache.calcite.sql.validate.SqlValidatorNamespace;
+import org.apache.calcite.sql.validate.SqlValidatorScope;
+import org.apache.calcite.sql.validate.SqlValidatorTable;
+import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.ignite.internal.processors.query.QueryUtils;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTableImpl;
+import org.apache.ignite.internal.processors.query.calcite.schema.TableDescriptor;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
+import org.apache.ignite.internal.processors.query.calcite.util.IgniteResource;
+import org.apache.ignite.internal.util.typedef.F;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.calcite.util.Static.RESOURCE;
+
+/** Validator. */
+public class IgniteSqlValidator extends SqlValidatorImpl {
+ /** Decimal of Integer.MAX_VALUE for fetch/offset bounding. */
+ private static final BigDecimal DEC_INT_MAX = BigDecimal.valueOf(Integer.MAX_VALUE);
+
+ /** **/
+ private static final int MAX_LENGTH_OF_ALIASES = 256;
+
+ /** **/
+ private static final Set<SqlKind> HUMAN_READABLE_ALIASES_FOR;
+
+ static {
+ EnumSet<SqlKind> kinds = EnumSet.noneOf(SqlKind.class);
+
+ kinds.addAll(SqlKind.AGGREGATE);
+ kinds.addAll(SqlKind.BINARY_ARITHMETIC);
+ kinds.addAll(SqlKind.FUNCTION);
+
+ kinds.add(SqlKind.CEIL);
+ kinds.add(SqlKind.FLOOR);
+ kinds.add(SqlKind.LITERAL);
+
+ HUMAN_READABLE_ALIASES_FOR = Collections.unmodifiableSet(kinds);
+ }
+
+ /** Dynamic parameters. */
+ Object[] parameters;
+
+ /**
+ * Creates a validator.
+ *
+ * @param opTab Operator table
+ * @param catalogReader Catalog reader
+ * @param typeFactory Type factory
+ * @param config Config
+ * @param parameters Dynamic parameters
+ */
+ public IgniteSqlValidator(SqlOperatorTable opTab, CalciteCatalogReader catalogReader,
+ IgniteTypeFactory typeFactory, SqlValidator.Config config, Object[] parameters) {
+ super(opTab, catalogReader, typeFactory, config);
+
+ this.parameters = parameters;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void validateInsert(SqlInsert insert) {
+ if (insert.getTargetColumnList() == null)
+ insert.setOperand(3, inferColumnList(insert));
+
+ super.validateInsert(insert);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void validateUpdate(SqlUpdate call) {
+ validateUpdateFields(call);
+
+ super.validateUpdate(call);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void validateLiteral(SqlLiteral literal) {
+ if (literal.getTypeName() != SqlTypeName.DECIMAL)
+ super.validateLiteral(literal);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected SqlSelect createSourceSelectForUpdate(SqlUpdate call) {
+ final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
+ final SqlIdentifier targetTable = (SqlIdentifier)call.getTargetTable();
+ final SqlValidatorTable table = getCatalogReader().getTable(targetTable.names);
+
+ SqlIdentifier alias = call.getAlias() != null ? call.getAlias() :
+ new SqlIdentifier(deriveAlias(targetTable, 0), SqlParserPos.ZERO);
+
+ table.unwrap(IgniteTable.class).descriptor().selectForUpdateRowType((IgniteTypeFactory)typeFactory)
+ .getFieldNames().stream()
+ .map(name -> alias.plus(name, SqlParserPos.ZERO))
+ .forEach(selectList::add);
+
+ int ordinal = 0;
+ // Force unique aliases to avoid a duplicate for Y with SET X=Y
+ for (SqlNode exp : call.getSourceExpressionList())
+ selectList.add(SqlValidatorUtil.addAlias(exp, SqlUtil.deriveAliasFromOrdinal(ordinal++)));
+
+ SqlNode sourceTable = call.getTargetTable();
+
+ if (call.getAlias() != null) {
+ sourceTable =
+ SqlValidatorUtil.addAlias(
+ sourceTable,
+ call.getAlias().getSimple());
+ }
+
+ return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
+ call.getCondition(), null, null, null, null, null, null, null);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected SqlSelect createSourceSelectForDelete(SqlDelete call) {
+ final SqlNodeList selectList = SqlNodeList.of(
+ new SqlIdentifier(QueryUtils.KEY_FIELD_NAME, SqlParserPos.ZERO));
+
+ SqlNode sourceTable = call.getTargetTable();
+
+ if (call.getAlias() != null) {
+ sourceTable =
+ SqlValidatorUtil.addAlias(
+ sourceTable,
+ call.getAlias().getSimple());
+ }
+
+ return new SqlSelect(SqlParserPos.ZERO, null, selectList, sourceTable,
+ call.getCondition(), null, null, null, null, null, null, null);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void validateSelect(SqlSelect select, RelDataType targetRowType) {
+ checkIntegerLimit(select.getFetch(), "fetch / limit");
+ checkIntegerLimit(select.getOffset(), "offset");
+
+ super.validateSelect(select, targetRowType);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void validateNamespace(SqlValidatorNamespace namespace, RelDataType targetRowType) {
+ SqlValidatorTable table = namespace.getTable();
+
+ if (table != null) {
+ IgniteTableImpl igniteTable = table.unwrap(IgniteTableImpl.class);
+
+ if (igniteTable != null)
+ igniteTable.ensureCacheStarted();
+ }
+
+ super.validateNamespace(namespace, targetRowType);
+ }
+
+ /**
+ * @param n Node to check limit.
+ * @param nodeName Node name.
+ */
+ private void checkIntegerLimit(SqlNode n, String nodeName) {
+ if (n instanceof SqlLiteral) {
+ BigDecimal offFetchLimit = ((SqlLiteral)n).bigDecimalValue();
+
+ if (offFetchLimit.compareTo(DEC_INT_MAX) > 0 || offFetchLimit.compareTo(BigDecimal.ZERO) < 0)
+ throw newValidationError(n, IgniteResource.INSTANCE.correctIntegerLimit(nodeName));
+ }
+ else if (n instanceof SqlDynamicParam) {
+ // will fail in params check.
+ if (F.isEmpty(parameters))
+ return;
+
- int idx = ((SqlDynamicParam) n).getIndex();
++ int idx = ((SqlDynamicParam)n).getIndex();
+
+ if (idx < parameters.length) {
+ Object param = parameters[idx];
+ if (parameters[idx] instanceof Integer) {
+ if ((Integer)param < 0)
+ throw newValidationError(n, IgniteResource.INSTANCE.correctIntegerLimit(nodeName));
+ }
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void validateCall(SqlCall call, SqlValidatorScope scope) {
+ if (call.getKind() == SqlKind.AS) {
+ final String alias = deriveAlias(call, 0);
+
+ if (isSystemFieldName(alias))
+ throw newValidationError(call, IgniteResource.INSTANCE.illegalAlias(alias));
+ }
+
+ super.validateCall(call, scope);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String deriveAlias(SqlNode node, int ordinal) {
+ if (node.isA(HUMAN_READABLE_ALIASES_FOR)) {
+ String alias = node.toSqlString(c -> c.withDialect(CalciteSqlDialect.DEFAULT)
+ .withQuoteAllIdentifiers(false)
+ .withAlwaysUseParentheses(false)
+ .withClauseStartsLine(false)
+ ).getSql();
+
+ return alias.substring(0, Math.min(alias.length(), MAX_LENGTH_OF_ALIASES));
+ }
+
+ return super.deriveAlias(node, ordinal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void validateAggregateParams(SqlCall aggCall,
+ @Nullable SqlNode filter, @Nullable SqlNodeList distinctList,
+ @Nullable SqlNodeList orderList, SqlValidatorScope scope) {
- validateAggregateFunction(aggCall, (SqlAggFunction) aggCall.getOperator());
++ validateAggregateFunction(aggCall, (SqlAggFunction)aggCall.getOperator());
+
+ super.validateAggregateParams(aggCall, filter, null, orderList, scope);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void addToSelectList(List<SqlNode> list, Set<String> aliases,
+ List<Map.Entry<String, RelDataType>> fieldList, SqlNode exp, SelectScope scope, boolean includeSystemVars) {
+ if (includeSystemVars || exp.getKind() != SqlKind.IDENTIFIER || !isSystemFieldName(deriveAlias(exp, 0)))
+ super.addToSelectList(list, aliases, fieldList, exp, scope, includeSystemVars);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSystemField(RelDataTypeField field) {
+ return isSystemFieldName(field.getName());
+ }
+
+ /** */
+ private void validateAggregateFunction(SqlCall call, SqlAggFunction aggFunction) {
+ if (!SqlKind.AGGREGATE.contains(aggFunction.kind))
+ throw newValidationError(call,
+ IgniteResource.INSTANCE.unsupportedAggregationFunction(aggFunction.getName()));
+
+ switch (aggFunction.kind) {
+ case COUNT:
+ case SUM:
+ case AVG:
+ case MIN:
+ case MAX:
+ case ANY_VALUE:
+
+ return;
+ default:
+ throw newValidationError(call,
+ IgniteResource.INSTANCE.unsupportedAggregationFunction(aggFunction.getName()));
+ }
+ }
+
+ /** */
+ private SqlNodeList inferColumnList(SqlInsert call) {
+ final SqlValidatorTable table = table(validatedNamespace(call, unknownType));
+
+ if (table == null)
+ return null;
+
+ final TableDescriptor desc = table.unwrap(TableDescriptor.class);
+
+ if (desc == null)
+ return null;
+
+ final SqlNodeList columnList = new SqlNodeList(SqlParserPos.ZERO);
+
+ for (RelDataTypeField field : desc.insertRowType(typeFactory()).getFieldList())
+ columnList.add(new SqlIdentifier(field.getName(), SqlParserPos.ZERO));
+
+ return columnList;
+ }
+
+ /** */
+ private void validateUpdateFields(SqlUpdate call) {
+ if (call.getTargetColumnList() == null)
+ return;
+
+ final SqlValidatorNamespace ns = validatedNamespace(call, unknownType);
+
+ final SqlValidatorTable table = table(ns);
+
+ if (table == null)
+ return;
+
+ final TableDescriptor desc = table.unwrap(TableDescriptor.class);
+
+ if (desc == null)
+ return;
+
+ final RelDataType baseType = table.getRowType();
+ final RelOptTable relOptTable = relOptTable(ns);
+
+ for (SqlNode node : call.getTargetColumnList()) {
- SqlIdentifier id = (SqlIdentifier) node;
++ SqlIdentifier id = (SqlIdentifier)node;
+
+ RelDataTypeField target = SqlValidatorUtil.getTargetField(
+ baseType, typeFactory(), id, getCatalogReader(), relOptTable);
+
+ if (target == null)
+ throw newValidationError(id,
+ RESOURCE.unknownTargetColumn(id.toString()));
+
+ if (!desc.isUpdateAllowed(relOptTable, target.getIndex()))
+ throw newValidationError(id,
+ IgniteResource.INSTANCE.cannotUpdateField(id.toString()));
+ }
+ }
+
+ /** */
+ private SqlValidatorTable table(SqlValidatorNamespace ns) {
+ RelOptTable relOptTable = relOptTable(ns);
+
+ if (relOptTable != null)
+ return relOptTable.unwrap(SqlValidatorTable.class);
+
+ return ns.getTable();
+ }
+
+ /** */
+ private RelOptTable relOptTable(SqlValidatorNamespace ns) {
+ return SqlValidatorUtil.getRelOptTable(
+ ns, getCatalogReader().unwrap(Prepare.CatalogReader.class), null, null);
+ }
+
+ /** */
+ private SqlValidatorNamespace validatedNamespace(SqlNode node, RelDataType targetType) {
+ SqlValidatorNamespace ns = getNamespace(node);
+ validateNamespace(ns, targetType);
+ return ns;
+ }
+
+ /** */
+ private IgniteTypeFactory typeFactory() {
- return (IgniteTypeFactory) typeFactory;
++ return (IgniteTypeFactory)typeFactory;
+ }
+
+ /** */
+ private boolean isSystemFieldName(String alias) {
+ return QueryUtils.KEY_FIELD_NAME.equalsIgnoreCase(alias)
+ || QueryUtils.VAL_FIELD_NAME.equalsIgnoreCase(alias);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
index 525d11d,0000000..cbcdcf8
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java
@@@ -1,190 -1,0 +1,190 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.rule;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.PhysicalNode;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.core.CorrelationId;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexLocalRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.mapping.Mapping;
+import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.ProjectableFilterableTableScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalIndexScan;
+import org.apache.ignite.internal.processors.query.calcite.rel.logical.IgniteLogicalTableScan;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteIndex;
+import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable;
+import org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait;
+import org.apache.ignite.internal.processors.query.calcite.trait.RewindabilityTrait;
+import org.apache.ignite.internal.processors.query.calcite.util.RexUtils;
+import org.apache.ignite.internal.util.typedef.F;
+
+/** */
+public abstract class LogicalScanConverterRule<T extends ProjectableFilterableTableScan> extends AbstractIgniteConverterRule<T> {
+ /** Instance. */
+ public static final LogicalScanConverterRule<IgniteLogicalIndexScan> INDEX_SCAN =
+ new LogicalScanConverterRule<IgniteLogicalIndexScan>(IgniteLogicalIndexScan.class, "LogicalIndexScanConverterRule") {
+ /** {@inheritDoc} */
+ @Override protected PhysicalNode convert(
+ RelOptPlanner planner,
+ RelMetadataQuery mq,
+ IgniteLogicalIndexScan rel
+ ) {
+ RelOptCluster cluster = rel.getCluster();
+ IgniteTable table = rel.getTable().unwrap(IgniteTable.class);
+ IgniteIndex index = table.getIndex(rel.indexName());
+
+ RelDistribution distribution = table.distribution();
+ RelCollation collation = index.collation();
+ if (rel.projects() != null || rel.requiredColumns() != null) {
+ Mappings.TargetMapping mapping = createMapping(
+ rel.projects(),
+ rel.requiredColumns(),
+ table.getRowType(cluster.getTypeFactory()).getFieldCount()
+ );
+
+ distribution = distribution.apply(mapping);
+ collation = collation.apply(mapping);
+ }
+
+ RelTraitSet traits = rel.getCluster().traitSetOf(IgniteConvention.INSTANCE)
+ .replace(RewindabilityTrait.REWINDABLE)
+ .replace(distribution)
+ .replace(collation);
+
+ Set<CorrelationId> corrIds = RexUtils.extractCorrelationIds(rel.condition());
+
+ if (!F.isEmpty(rel.projects())) {
+ corrIds = new HashSet<>(corrIds);
+ corrIds.addAll(RexUtils.extractCorrelationIds(rel.projects()));
+ }
+
+ if (!corrIds.isEmpty())
+ traits = traits.replace(CorrelationTrait.correlations(corrIds));
+
+ return new IgniteIndexScan(
+ cluster,
+ traits,
+ rel.getTable(),
+ rel.indexName(),
+ rel.projects(),
+ rel.condition(),
+ rel.indexConditions(),
+ rel.requiredColumns()
+ );
+ }
+ };
+
+ /** Instance. */
+ public static final LogicalScanConverterRule<IgniteLogicalTableScan> TABLE_SCAN =
+ new LogicalScanConverterRule<IgniteLogicalTableScan>(IgniteLogicalTableScan.class, "LogicalTableScanConverterRule") {
+ /** {@inheritDoc} */
+ @Override protected PhysicalNode convert(
+ RelOptPlanner planner,
+ RelMetadataQuery mq,
+ IgniteLogicalTableScan rel
+ ) {
+ RelOptCluster cluster = rel.getCluster();
+ IgniteTable table = rel.getTable().unwrap(IgniteTable.class);
+
+ RelDistribution distribution = table.distribution();
+ if (rel.requiredColumns() != null) {
+ Mappings.TargetMapping mapping = createMapping(
+ rel.projects(),
+ rel.requiredColumns(),
+ table.getRowType(cluster.getTypeFactory()).getFieldCount()
+ );
+
+ distribution = distribution.apply(mapping);
+ }
+
+ RelTraitSet traits = cluster.traitSetOf(IgniteConvention.INSTANCE)
+ .replace(RewindabilityTrait.REWINDABLE)
+ .replace(distribution);
+
+ Set<CorrelationId> corrIds = RexUtils.extractCorrelationIds(rel.condition());
+
+ if (!F.isEmpty(rel.projects())) {
+ corrIds = new HashSet<>(corrIds);
+ corrIds.addAll(RexUtils.extractCorrelationIds(rel.projects()));
+ }
+
+ if (!corrIds.isEmpty())
+ traits = traits.replace(CorrelationTrait.correlations(corrIds));
+
+ return new IgniteTableScan(rel.getCluster(), traits,
+ rel.getTable(), rel.projects(), rel.condition(), rel.requiredColumns());
+ }
+ };
+
+ /** */
+ private LogicalScanConverterRule(Class<T> clazz, String descPrefix) {
+ super(clazz, descPrefix);
+ }
+
+ /** */
+ private static Mappings.TargetMapping createMapping(
+ List<RexNode> projects,
+ ImmutableBitSet requiredColumns,
+ int tableRowSize
+ ) {
+ if (projects != null) {
+ Mapping trimmingMapping = requiredColumns != null
+ ? Mappings.invert(Mappings.source(requiredColumns.asList(), tableRowSize))
+ : Mappings.createIdentity(tableRowSize);
+
+ Map<Integer, Integer> mappingMap = new HashMap<>();
+
+ for (int i = 0; i < projects.size(); i++) {
+ RexNode rex = projects.get(i);
+ if (!(rex instanceof RexLocalRef))
+ continue;
+
- RexLocalRef ref = (RexLocalRef) rex;
++ RexLocalRef ref = (RexLocalRef)rex;
+
+ mappingMap.put(trimmingMapping.getSource(ref.getIndex()), i);
+ }
+
+ return Mappings.target(
+ mappingMap,
+ tableRowSize,
+ projects.size()
+ );
+ }
+
+ if (requiredColumns != null)
+ return Mappings.target(requiredColumns.asList(), tableRowSize);
+
+ return Mappings.createIdentity(tableRowSize);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/TableDescriptorImpl.java
index ea7dd4f,0000000..633cf8d
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/TableDescriptorImpl.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/TableDescriptorImpl.java
@@@ -1,769 -1,0 +1,769 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.schema;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.rel.core.TableModify;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.ColumnStrategy;
+import org.apache.calcite.sql2rel.InitializerContext;
+import org.apache.calcite.sql2rel.NullInitializerExpressionFactory;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.binary.BinaryObjectBuilder;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheStoppedException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContextInfo;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology;
+import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
+import org.apache.ignite.internal.processors.query.GridQueryProperty;
+import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
+import org.apache.ignite.internal.processors.query.QueryUtils;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
+import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler;
+import org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
+import org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
+import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
+import org.apache.ignite.internal.processors.query.calcite.util.TypeUtils;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+/**
+ *
+ */
+public class TableDescriptorImpl extends NullInitializerExpressionFactory
+ implements TableDescriptor {
+ /** */
+ private static final ColumnDescriptor[] DUMMY = new ColumnDescriptor[0];
+
+ /** */
+ private final GridCacheContextInfo<?, ?> cacheInfo;
+
+ /** */
+ private final GridQueryTypeDescriptor typeDesc;
+
+ /** */
+ private final Object affinityIdentity;
+
+ /** */
+ private final ColumnDescriptor[] descriptors;
+
+ /** */
+ private final Map<String, ColumnDescriptor> descriptorsMap;
+
+ /** */
+ private final int keyField;
+
+ /** */
+ private final int valField;
+
+ /** */
+ private final ImmutableIntList affFields;
+
+ /** */
+ private final ImmutableBitSet insertFields;
+
+ /** */
+ public TableDescriptorImpl(GridCacheContextInfo<?, ?> cacheInfo, GridQueryTypeDescriptor typeDesc,
+ Object affinityIdentity) {
+ this.cacheInfo = cacheInfo;
+ this.typeDesc = typeDesc;
+ this.affinityIdentity = affinityIdentity;
+
+ Set<String> fields = this.typeDesc.fields().keySet();
+
+ List<ColumnDescriptor> descriptors = new ArrayList<>(fields.size() + 2);
+
+ // A _key/_val field is virtual in case there is an alias or a property(es) mapped to the _key/_val field.
+ BitSet virtualFields = new BitSet();
+
+ if (typeDesc.implicitPk()) {
+ // pk is not set, thus we need to provide default value for autogenerated key
+ descriptors.add(
+ new KeyValDescriptor(QueryUtils.KEY_FIELD_NAME, typeDesc.keyClass(), true, QueryUtils.KEY_COL) {
+ @Override public Object defaultValue() {
+ return IgniteUuid.randomUuid();
+ }
+ }
+ );
+
+ virtualFields.set(0);
+ }
+ else {
+ descriptors.add(
+ new KeyValDescriptor(QueryUtils.KEY_FIELD_NAME, typeDesc.keyClass(), true, QueryUtils.KEY_COL));
+ }
+
+ descriptors.add(
+ new KeyValDescriptor(QueryUtils.VAL_FIELD_NAME, typeDesc.valueClass(), false, QueryUtils.VAL_COL));
+
+ int fldIdx = QueryUtils.VAL_COL + 1;
+
+ int keyField = QueryUtils.KEY_COL;
+ int valField = QueryUtils.VAL_COL;
+
+ for (String field : fields) {
+ if (Objects.equals(field, typeDesc.keyFieldAlias())) {
+ keyField = descriptors.size();
+
+ virtualFields.set(0);
+
+ descriptors.add(new KeyValDescriptor(typeDesc.keyFieldAlias(), typeDesc.keyClass(), true, fldIdx++));
+ }
+ else if (Objects.equals(field, typeDesc.valueFieldAlias())) {
+ valField = descriptors.size();
+
+ virtualFields.set(1);
+
+ descriptors.add(new KeyValDescriptor(typeDesc.valueFieldAlias(), typeDesc.valueClass(), false, fldIdx++));
+ }
+ else {
+ GridQueryProperty prop = typeDesc.property(field);
+
+ virtualFields.set(prop.key() ? 0 : 1);
+
+ descriptors.add(new FieldDescriptor(prop, fldIdx++));
+ }
+ }
+
+ Map<String, ColumnDescriptor> descriptorsMap = U.newHashMap(descriptors.size());
+ for (ColumnDescriptor descriptor : descriptors)
+ descriptorsMap.put(descriptor.name(), descriptor);
+
+ List<Integer> affFields = new ArrayList<>();
+ if (!F.isEmpty(typeDesc.affinityKey()))
+ affFields.add(descriptorsMap.get(typeDesc.affinityKey()).fieldIndex());
+ else if (!F.isEmpty(typeDesc.keyFieldAlias()))
+ affFields.add(descriptorsMap.get(typeDesc.keyFieldAlias()).fieldIndex());
+ else if (!F.isEmpty(typeDesc.primaryKeyFields())) {
+ affFields.addAll(
+ descriptors.stream()
+ .filter(desc -> typeDesc.primaryKeyFields().contains(desc.name()))
+ .map(ColumnDescriptor::fieldIndex)
+ .collect(Collectors.toList())
+ );
+ }
+ else {
+ affFields.addAll(
+ descriptors.stream()
+ .filter(desc -> typeDesc.fields().containsKey(desc.name()) && typeDesc.property(desc.name()).key())
+ .map(ColumnDescriptor::fieldIndex)
+ .collect(Collectors.toList())
+ );
+ }
+
+ if (affFields.stream().map(descriptors::get).map(ColumnDescriptor::storageType)
+ .anyMatch(TypeUtils::isConvertableType))
+ affFields.clear();
+
+ this.keyField = keyField;
+ this.valField = valField;
+ this.affFields = ImmutableIntList.copyOf(affFields);
+ this.descriptors = descriptors.toArray(DUMMY);
+ this.descriptorsMap = descriptorsMap;
+
+ virtualFields.flip(0, descriptors.size());
+ insertFields = ImmutableBitSet.fromBitSet(virtualFields);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType insertRowType(IgniteTypeFactory factory) {
+ return rowType(factory, insertFields);
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridCacheContext cacheContext() {
+ return cacheInfo.cacheContext();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridCacheContextInfo cacheInfo() {
+ return cacheInfo;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteDistribution distribution() {
+ if (affinityIdentity == null)
+ return IgniteDistributions.broadcast();
+ else if (affFields.isEmpty())
+ return IgniteDistributions.random();
+ else
+ return IgniteDistributions.affinity(affFields, cacheInfo.cacheId(), affinityIdentity);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean match(CacheDataRow row) {
+ return typeDesc.matchType(row.value());
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Row toRow(
+ ExecutionContext<Row> ectx,
+ CacheDataRow row,
+ RowHandler.RowFactory<Row> factory,
+ @Nullable ImmutableBitSet requiredColumns
+ ) throws IgniteCheckedException {
+ RowHandler<Row> handler = factory.handler();
+
+ assert handler == ectx.rowHandler();
+
+ Row res = factory.create();
+
+ assert handler.columnCount(res) == (requiredColumns == null ? descriptors.length : requiredColumns.cardinality());
+
+ if (requiredColumns == null) {
+ for (int i = 0; i < descriptors.length; i++) {
+ ColumnDescriptor desc = descriptors[i];
+
+ handler.set(i, res, TypeUtils.toInternal(ectx,
+ desc.value(ectx, cacheContext(), row), desc.storageType()));
+ }
+ }
+ else {
+ for (int i = 0, j = requiredColumns.nextSetBit(0); j != -1; j = requiredColumns.nextSetBit(j + 1), i++) {
+ ColumnDescriptor desc = descriptors[j];
+
+ handler.set(i, res, TypeUtils.toInternal(ectx,
+ desc.value(ectx, cacheContext(), row), desc.storageType()));
+ }
+ }
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isUpdateAllowed(RelOptTable tbl, int colIdx) {
+ final ColumnDescriptor desc = descriptors[colIdx];
+
+ return !desc.key() && (desc.field() || QueryUtils.isSqlType(desc.storageType()));
+ }
+
+ /** {@inheritDoc} */
+ @Override public ColumnStrategy generationStrategy(RelOptTable tbl, int colIdx) {
+ if (descriptors[colIdx].hasDefaultValue())
+ return ColumnStrategy.DEFAULT;
+
+ return super.generationStrategy(tbl, colIdx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RexNode newColumnDefaultValue(RelOptTable tbl, int colIdx, InitializerContext ctx) {
+ final ColumnDescriptor desc = descriptors[colIdx];
+
+ if (!desc.hasDefaultValue())
+ return super.newColumnDefaultValue(tbl, colIdx, ctx);
+
+ final RexBuilder rexBuilder = ctx.getRexBuilder();
- final IgniteTypeFactory typeFactory = (IgniteTypeFactory) rexBuilder.getTypeFactory();
++ final IgniteTypeFactory typeFactory = (IgniteTypeFactory)rexBuilder.getTypeFactory();
+
+ return rexBuilder.makeLiteral(desc.defaultValue(), desc.logicalType(typeFactory), false);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> ModifyTuple toTuple(ExecutionContext<Row> ectx, Row row,
+ TableModify.Operation op, Object arg) throws IgniteCheckedException {
+ switch (op) {
+ case INSERT:
+ return insertTuple(row, ectx);
+ case DELETE:
+ return deleteTuple(row, ectx);
+ case UPDATE:
- return updateTuple(row, (List<String>) arg, 0, ectx);
++ return updateTuple(row, (List<String>)arg, 0, ectx);
+ case MERGE:
- return mergeTuple(row, (List<String>) arg, ectx);
++ return mergeTuple(row, (List<String>)arg, ectx);
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /** */
+ private <Row> ModifyTuple insertTuple(Row row, ExecutionContext<Row> ectx) throws IgniteCheckedException {
+ Object key = insertKey(row, ectx);
+ Object val = insertVal(row, ectx);
+
+ if (cacheContext().binaryMarshaller()) {
+ if (key instanceof BinaryObjectBuilder)
- key = ((BinaryObjectBuilder) key).build();
++ key = ((BinaryObjectBuilder)key).build();
+
+ if (val instanceof BinaryObjectBuilder)
- val = ((BinaryObjectBuilder) val).build();
++ val = ((BinaryObjectBuilder)val).build();
+ }
+
+ typeDesc.validateKeyAndValue(key, val);
+
+ return new ModifyTuple(key, val, TableModify.Operation.INSERT);
+ }
+
+ /** */
+ private <Row> Object insertKey(Row row, ExecutionContext<Row> ectx) throws IgniteCheckedException {
+ RowHandler<Row> handler = ectx.rowHandler();
+
+ Object key = handler.get(keyField, row);
+
+ if (key != null)
+ return TypeUtils.fromInternal(ectx, key, descriptors[QueryUtils.KEY_COL].storageType());
+
+ // skip _key and _val
+ for (int i = 2; i < descriptors.length; i++) {
+ final ColumnDescriptor desc = descriptors[i];
+
+ if (!desc.field() || !desc.key())
+ continue;
+
+ Object fieldVal = handler.get(i, row);
+
+ if (fieldVal != null) {
+ if (key == null)
+ key = newVal(typeDesc.keyTypeName(), typeDesc.keyClass());
+
+ desc.set(key, TypeUtils.fromInternal(ectx, fieldVal, desc.storageType()));
+ }
+ }
+
+ if (key == null)
+ key = descriptors[QueryUtils.KEY_COL].defaultValue();
+
+ return key;
+ }
+
+ /** */
+ private <Row> Object insertVal(Row row, ExecutionContext<Row> ectx) throws IgniteCheckedException {
+ RowHandler<Row> handler = ectx.rowHandler();
+
+ Object val = handler.get(valField, row);
+
+ if (val == null) {
+ val = newVal(typeDesc.valueTypeName(), typeDesc.valueClass());
+
+ // skip _key and _val
+ for (int i = 2; i < descriptors.length; i++) {
+ final ColumnDescriptor desc = descriptors[i];
+
+ Object fieldVal = handler.get(i, row);
+
+ if (desc.field() && !desc.key() && fieldVal != null)
+ desc.set(val, TypeUtils.fromInternal(ectx, fieldVal, desc.storageType()));
+ }
+ }
+ else
+ val = TypeUtils.fromInternal(ectx, val, descriptors[QueryUtils.VAL_COL].storageType());
+
+ return val;
+ }
+
+ /** */
+ private Object newVal(String typeName, Class<?> typeCls) throws IgniteCheckedException {
+ GridCacheContext<?, ?> cctx = cacheContext();
+
+ if (cctx.binaryMarshaller()) {
+ BinaryObjectBuilder builder = cctx.grid().binary().builder(typeName);
+ cctx.prepareAffinityField(builder);
+
+ return builder;
+ }
+
+ Class<?> cls = U.classForName(typeName, typeCls);
+
+ try {
+ Constructor<?> ctor = cls.getDeclaredConstructor();
+ ctor.setAccessible(true);
+
+ return ctor.newInstance();
+ }
+ catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
+ throw instantiationException(typeName, e);
+ }
+ catch (NoSuchMethodException | SecurityException e) {
+ try {
+ return GridUnsafe.allocateInstance(cls);
+ }
+ catch (InstantiationException e0) {
+ e0.addSuppressed(e);
+
+ throw instantiationException(typeName, e0);
+ }
+ }
+ }
+
+ /** */
+ private IgniteCheckedException instantiationException(String typeName, ReflectiveOperationException e) {
+ return S.includeSensitive()
+ ? new IgniteCheckedException("Failed to instantiate key [type=" + typeName + ']', e)
+ : new IgniteCheckedException("Failed to instantiate key", e);
+ }
+
+ /** */
+ private <Row> ModifyTuple updateTuple(Row row, List<String> updateColList, int offset, ExecutionContext<Row> ectx)
+ throws IgniteCheckedException {
+ RowHandler<Row> handler = ectx.rowHandler();
+
+ Object key = Objects.requireNonNull(handler.get(offset + QueryUtils.KEY_COL, row));
+ Object val = clone(Objects.requireNonNull(handler.get(offset + QueryUtils.VAL_COL, row)));
+
+ offset += descriptorsMap.size();
+
+ for (int i = 0; i < updateColList.size(); i++) {
+ final ColumnDescriptor desc = Objects.requireNonNull(descriptorsMap.get(updateColList.get(i)));
+
+ assert !desc.key();
+
+ Object fieldVal = handler.get(i + offset, row);
+
+ if (desc.field())
+ desc.set(val, TypeUtils.fromInternal(ectx, fieldVal, desc.storageType()));
+ else
+ val = TypeUtils.fromInternal(ectx, fieldVal, desc.storageType());
+ }
+
+ if (cacheContext().binaryMarshaller() && val instanceof BinaryObjectBuilder)
- val = ((BinaryObjectBuilder) val).build();
++ val = ((BinaryObjectBuilder)val).build();
+
+ typeDesc.validateKeyAndValue(key, val);
+
+ return new ModifyTuple(key, val, TableModify.Operation.UPDATE);
+ }
+
+ /** */
+ private <Row> ModifyTuple mergeTuple(Row row, List<String> updateColList, ExecutionContext<Row> ectx)
+ throws IgniteCheckedException {
+ RowHandler<Row> hnd = ectx.rowHandler();
+
+ int rowColumnsCnt = hnd.columnCount(row);
+
+ if (rowColumnsCnt == descriptors.length)
+ return insertTuple(row, ectx); // Only WHEN NOT MATCHED clause in MERGE.
+ else if (rowColumnsCnt == descriptors.length + updateColList.size())
+ return updateTuple(row, updateColList, 0, ectx); // Only WHEN MATCHED clause in MERGE.
+ else {
+ // Both WHEN MATCHED and WHEN NOT MATCHED clauses in MERGE.
+ assert rowColumnsCnt == descriptors.length * 2 + updateColList.size() : "Unexpected columns count: " +
+ rowColumnsCnt;
+
+ int updateOffset = descriptors.length; // Offset of fields for update statement.
+
+ if (hnd.get(updateOffset + QueryUtils.KEY_COL, row) != null)
+ return updateTuple(row, updateColList, updateOffset, ectx);
+ else
+ return insertTuple(row, ectx);
+ }
+ }
+
+ /** */
+ private Object clone(Object val) throws IgniteCheckedException {
+ if (val == null || QueryUtils.isSqlType(val.getClass()))
+ return val;
+
+ GridCacheContext<?, ?> cctx = cacheContext();
+
+ if (!cctx.binaryMarshaller())
+ return cctx.marshaller().unmarshal(cctx.marshaller().marshal(val), U.resolveClassLoader(cctx.gridConfig()));
+
+ BinaryObjectBuilder builder = cctx.grid().binary().builder(
+ cctx.grid().binary().<BinaryObject>toBinary(val));
+
+ cctx.prepareAffinityField(builder);
+
+ return builder;
+ }
+
+ /** */
+ private <Row> ModifyTuple deleteTuple(Row row, ExecutionContext<Row> ectx) {
+ Object key = TypeUtils.fromInternal(ectx,
+ ectx.rowHandler().get(QueryUtils.KEY_COL, row), descriptors[QueryUtils.KEY_COL].storageType());
+ return new ModifyTuple(Objects.requireNonNull(key), null, TableModify.Operation.DELETE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType rowType(IgniteTypeFactory factory, ImmutableBitSet usedColumns) {
+ RelDataTypeFactory.Builder b = new RelDataTypeFactory.Builder(factory);
+
+ if (usedColumns == null) {
+ for (int i = 0; i < descriptors.length; i++)
+ b.add(descriptors[i].name(), descriptors[i].logicalType(factory));
+ }
+ else {
+ for (int i = usedColumns.nextSetBit(0); i != -1; i = usedColumns.nextSetBit(i + 1))
+ b.add(descriptors[i].name(), descriptors[i].logicalType(factory));
+ }
+
+ return TypeUtils.sqlType(factory, b.build());
+ }
+
+ /** {@inheritDoc} */
+ @Override public ColumnDescriptor columnDescriptor(String fieldName) {
+ return fieldName == null ? null : descriptorsMap.get(fieldName);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ColocationGroup colocationGroup(MappingQueryContext ctx) {
+ GridCacheContext<?, ?> cctx = cacheContext();
+
+ if (!cctx.gate().enterIfNotStopped())
+ throw U.convertException(new CacheStoppedException(cctx.name()));
+
+ try {
+ return cctx.isReplicated()
+ ? replicatedGroup(ctx.topologyVersion())
+ : partitionedGroup(ctx.topologyVersion());
+
+ }
+ finally {
+ cctx.gate().leave();
+ }
+ }
+
+ /** */
+ private ColocationGroup partitionedGroup(@NotNull AffinityTopologyVersion topVer) {
+ GridCacheContext<?, ?> cctx = cacheContext();
+
+ List<List<ClusterNode>> assignments = cctx.affinity().assignments(topVer);
+ List<List<UUID>> assignments0;
+
+ if (cctx.config().getWriteSynchronizationMode() != CacheWriteSynchronizationMode.PRIMARY_SYNC)
+ assignments0 = Commons.transform(assignments, nodes -> Commons.transform(nodes, ClusterNode::id));
+ else {
+ assignments0 = new ArrayList<>(assignments.size());
+
+ for (List<ClusterNode> partNodes : assignments)
+ assignments0.add(F.isEmpty(partNodes) ? emptyList() : singletonList(F.first(partNodes).id()));
+ }
+
+ return ColocationGroup.forAssignments(assignments0);
+ }
+
+ /** */
+ private ColocationGroup replicatedGroup(@NotNull AffinityTopologyVersion topVer) {
+ GridCacheContext<?, ?> cctx = cacheContext();
+
+ GridDhtPartitionTopology top = cctx.topology();
+
+ List<ClusterNode> nodes = cctx.discovery().discoCache(topVer).cacheGroupAffinityNodes(cctx.groupId());
+ List<UUID> nodes0;
+
+ if (!top.rebalanceFinished(topVer)) {
+ nodes0 = new ArrayList<>(nodes.size());
+
+ int parts = top.partitions();
+
+ for (ClusterNode node : nodes) {
+ if (isOwner(node.id(), top, parts))
+ nodes0.add(node.id());
+ }
+ }
+ else
+ nodes0 = Commons.transform(nodes, ClusterNode::id);
+
+ return ColocationGroup.forNodes(nodes0);
+ }
+
+ /** */
+ private boolean isOwner(UUID nodeId, GridDhtPartitionTopology top, int parts) {
+ for (int p = 0; p < parts; p++) {
+ if (top.partitionState(nodeId, p) != GridDhtPartitionState.OWNING)
+ return false;
+ }
+ return true;
+ }
+
+ /** */
+ private static class KeyValDescriptor implements ColumnDescriptor {
+ /** */
+ private final String name;
+
+ /** */
+ private final boolean isKey;
+
+ /** */
+ private final int fieldIdx;
+
+ /** */
+ private final Class<?> storageType;
+
+ /** */
+ private KeyValDescriptor(String name, Class<?> type, boolean isKey, int fieldIdx) {
+ this.name = name;
+ this.isKey = isKey;
+ this.fieldIdx = fieldIdx;
+
+ storageType = type;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean field() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean key() {
+ return isKey;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasDefaultValue() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object defaultValue() {
+ throw new AssertionError();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int fieldIndex() {
+ return fieldIdx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType logicalType(IgniteTypeFactory f) {
+ return f.createJavaType(storageType);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> storageType() {
+ return storageType;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object value(ExecutionContext<?> ectx, GridCacheContext<?, ?> cctx, CacheDataRow src) {
+ return cctx.unwrapBinaryIfNeeded(isKey ? src.key() : src.value(), ectx.keepBinary(), null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(Object dst, Object val) {
+ throw new AssertionError();
+ }
+ }
+
+ /** */
+ private static class FieldDescriptor implements ColumnDescriptor {
+ /** */
+ private final GridQueryProperty desc;
+
+ /** */
+ private final Object dfltVal;
+
+ /** */
+ private final int fieldIdx;
+
+ /** */
+ private final Class<?> storageType;
+
+ /** */
+ private FieldDescriptor(GridQueryProperty desc, int fieldIdx) {
+ this.desc = desc;
+ this.fieldIdx = fieldIdx;
+
+ dfltVal = desc.defaultValue();
+ storageType = desc.type();
+ }
+
+ /** */
+ @Override public boolean field() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean key() {
+ return desc.key();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasDefaultValue() {
+ return dfltVal != null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object defaultValue() {
+ return dfltVal;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return desc.name();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int fieldIndex() {
+ return fieldIdx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType logicalType(IgniteTypeFactory f) {
+ return f.createJavaType(storageType);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<?> storageType() {
+ return storageType;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object value(ExecutionContext<?> ectx, GridCacheContext<?, ?> cctx, CacheDataRow src)
+ throws IgniteCheckedException {
+ return cctx.unwrapBinaryIfNeeded(desc.value(src.key(), src.value()), ectx.keepBinary(), null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(Object dst, Object val) throws IgniteCheckedException {
+ final Object key0 = key() ? dst : null;
+ final Object val0 = key() ? null : dst;
+
+ desc.setValue(key0, val0, val);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridQueryTypeDescriptor typeDescription() {
+ return typeDesc;
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlIntervalTypeNameSpec.java
index c6535b1,0000000..b9e1f52
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlIntervalTypeNameSpec.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/IgniteSqlIntervalTypeNameSpec.java
@@@ -1,62 -1,0 +1,62 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+package org.apache.ignite.internal.processors.query.calcite.sql;
+
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlTypeNameSpec;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.util.Litmus;
+
+/**
+ * A SQL type name specification of interval types.
+ */
+public class IgniteSqlIntervalTypeNameSpec extends SqlTypeNameSpec {
+ /** */
+ private final SqlIntervalQualifier sqlIntervalQualifier;
+
+ /** Constructor. */
+ public IgniteSqlIntervalTypeNameSpec(SqlIntervalQualifier intervalQualifier, SqlParserPos pos) {
+ super(new SqlIdentifier(intervalQualifier.typeName().name(), pos), pos);
+ sqlIntervalQualifier = intervalQualifier;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDataType deriveType(SqlValidator validator) {
+ return validator.getTypeFactory().createSqlIntervalType(sqlIntervalQualifier);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("INTERVAL");
+
+ getTypeName().unparse(writer, leftPrec, rightPrec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equalsDeep(SqlTypeNameSpec spec, Litmus litmus) {
+ if (!(spec instanceof IgniteSqlIntervalTypeNameSpec))
+ return false;
+
- IgniteSqlIntervalTypeNameSpec that = (IgniteSqlIntervalTypeNameSpec) spec;
++ IgniteSqlIntervalTypeNameSpec that = (IgniteSqlIntervalTypeNameSpec)spec;
+
+ return getTypeName().equalsDeep(that.getTypeName(), litmus);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/CorrelationTrait.java
index 523a701,0000000..e61cf3b
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/CorrelationTrait.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/CorrelationTrait.java
@@@ -1,122 -1,0 +1,122 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.trait;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import com.google.common.collect.ImmutableSet;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTrait;
+import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.CorrelationId;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Correlation trait is created by node that creates and sets correlation variables {@link RelNode#getVariablesSet()}}
+ * (e.g. {@link IgniteCorrelatedNestedLoopJoin}) and pass through this trait to input that uses correlation variable(s).
+ *
+ * The correlation trait is used to prevent the insertion of nodes that cannot preserve correlation in
+ * the correlated data stream. e.g. these nodes are IgniteExchange, IgniteTableSpool, etc.
+ *
+ * Let's describe more details:
+ * IgniteExchange: current implementation is not rewindable and not send values of the correlation variables to
+ * Senders.
+ * (see {@link ExecutionContext#getCorrelated(int)})
+ * TableSpool: stores the input data stream and rewind it many times So. it cannot be depends on the value of the
+ * correlation variables.
+ */
+public class CorrelationTrait implements RelTrait {
+ /** */
+ public static final CorrelationTrait UNCORRELATED = canonize(new CorrelationTrait(Collections.emptyList()));
+
+ /** */
+ private final ImmutableSet<CorrelationId> correlations;
+
+ /** */
+ public CorrelationTrait(Collection<CorrelationId> correlationIds) {
+ correlations = ImmutableSet.copyOf(correlationIds);
+ }
+
+ /** */
+ public boolean correlated() {
+ return !F.isEmpty(correlations);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (!(o instanceof CorrelationTrait))
+ return false;
+
+ return correlations.equals(((CorrelationTrait)o).correlations);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return correlations.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return correlated() ? "correlated" + correlations : "uncorrelated";
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelTraitDef<CorrelationTrait> getTraitDef() {
+ return CorrelationTraitDef.INSTANCE;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean satisfies(RelTrait trait) {
+ if (trait == this || this == UNCORRELATED)
+ return true;
+
+ if (!(trait instanceof CorrelationTrait))
+ return false;
+
- CorrelationTrait other = (CorrelationTrait) trait;
++ CorrelationTrait other = (CorrelationTrait)trait;
+
+ return other.correlated() && other.correlationIds().containsAll(correlationIds());
+ }
+
+ /** {@inheritDoc} */
+ @Override public void register(RelOptPlanner planner) {
+ // no-op
+ }
+
+ /** */
+ private static CorrelationTrait canonize(CorrelationTrait trait) {
+ return CorrelationTraitDef.INSTANCE.canonize(trait);
+ }
+
+ /** */
+ public Set<CorrelationId> correlationIds() {
+ return correlations;
+ }
+
+ /** */
+ public static CorrelationTrait correlations(Collection<CorrelationId> correlationIds) {
+ return canonize(new CorrelationTrait(correlationIds));
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionFunction.java
index 2b30a41,0000000..c06de6c
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionFunction.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionFunction.java
@@@ -1,314 -1,0 +1,314 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.trait;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Distribution function.
+ */
+public abstract class DistributionFunction {
+ /** */
+ private String name;
+
+ /** */
+ private DistributionFunction() {
+ // No-op.
+ }
+
+ /**
+ * @return Distribution function type.
+ */
+ public abstract RelDistribution.Type type();
+
+ /**
+ * @return Function name. This name used for equality checking and in {@link RelNode#getDigest()}.
+ */
+ public final String name() {
+ if (name != null)
+ return name;
+
+ return name = name0().intern();
+ }
+
+ /** */
+ public boolean affinity() {
+ return false;
+ }
+
+ /** */
+ public int cacheId() {
+ return CU.UNDEFINED_CACHE_ID;
+ }
+
+ /**
+ * Creates a destination based on this function algorithm, given nodes mapping and given distribution keys.
+ *
+ * @param ctx Execution context.
+ * @param affinityService Affinity function source.
+ * @param group Target mapping.
+ * @param keys Distribution keys.
+ * @return Destination function.
+ */
+ abstract <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affinityService,
+ ColocationGroup group, ImmutableIntList keys);
+
+ /**
+ * @return Function name. This name used for equality checking and in {@link RelNode#getDigest()}.
+ */
+ protected String name0() {
+ return type().shortName;
+ }
+
+ /** {@inheritDoc} */
+ @Override public final int hashCode() {
+ return Objects.hashCode(name());
+ }
+
+ /** {@inheritDoc} */
+ @Override public final boolean equals(Object obj) {
+ if (obj instanceof DistributionFunction)
+ //noinspection StringEquality
- return name() == ((DistributionFunction) obj).name();
++ return name() == ((DistributionFunction)obj).name();
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public final String toString() {
+ return name();
+ }
+
+ /** */
+ public static DistributionFunction any() {
+ return AnyDistribution.INSTANCE;
+ }
+
+ /** */
+ public static DistributionFunction broadcast() {
+ return BroadcastDistribution.INSTANCE;
+ }
+
+ /** */
+ public static DistributionFunction singleton() {
+ return SingletonDistribution.INSTANCE;
+ }
+
+ /** */
+ public static DistributionFunction random() {
+ return RandomDistribution.INSTANCE;
+ }
+
+ /** */
+ public static DistributionFunction hash() {
+ return HashDistribution.INSTANCE;
+ }
+
+ /** */
+ public static DistributionFunction affinity(int cacheId, Object identity) {
+ return new AffinityDistribution(cacheId, identity);
+ }
+
+ /** */
+ public static boolean satisfy(DistributionFunction f0, DistributionFunction f1) {
+ if (f0 == f1 || f0.name() == f1.name())
+ return true;
+
+ return f0 instanceof AffinityDistribution && f1 instanceof AffinityDistribution &&
+ Objects.equals(((AffinityDistribution)f0).identity(), ((AffinityDistribution)f1).identity());
+ }
+
+ /** */
+ private static final class AnyDistribution extends DistributionFunction {
+ /** */
+ public static final DistributionFunction INSTANCE = new AnyDistribution();
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.ANY;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affinityService,
+ ColocationGroup m, ImmutableIntList k) {
+ throw new AssertionError();
+ }
+ }
+
+ /** */
+ private static final class BroadcastDistribution extends DistributionFunction {
+ /** */
+ public static final DistributionFunction INSTANCE = new BroadcastDistribution();
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.BROADCAST_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affinityService,
+ ColocationGroup m, ImmutableIntList k) {
+ assert m != null && !F.isEmpty(m.nodeIds());
+
+ return new AllNodes<>(m.nodeIds());
+ }
+ }
+
+ /** */
+ private static final class RandomDistribution extends DistributionFunction {
+ /** */
+ public static final DistributionFunction INSTANCE = new RandomDistribution();
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.RANDOM_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affinityService,
+ ColocationGroup m, ImmutableIntList k) {
+ assert m != null && !F.isEmpty(m.nodeIds());
+
+ return new RandomNode<>(m.nodeIds());
+ }
+ }
+
+ /** */
+ private static final class SingletonDistribution extends DistributionFunction {
+ /** */
+ public static final DistributionFunction INSTANCE = new SingletonDistribution();
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.SINGLETON;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affinityService,
+ ColocationGroup m, ImmutableIntList k) {
+ if (m == null || m.nodeIds() == null || m.nodeIds().size() != 1)
+ throw new AssertionError();
+
+ return new AllNodes<>(Collections
+ .singletonList(Objects
+ .requireNonNull(F
+ .first(m.nodeIds()))));
+ }
+ }
+
+ /** */
+ private static final class HashDistribution extends DistributionFunction {
+ /** Singleton instance. */
+ public static final DistributionFunction INSTANCE = new HashDistribution();
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.HASH_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affSrvc,
+ ColocationGroup m, ImmutableIntList k) {
+ assert m != null && !F.isEmpty(m.assignments()) && !k.isEmpty();
+
+ List<List<UUID>> assignments = m.assignments();
+
+ if (U.assertionsEnabled()) {
+ for (List<UUID> assignment : assignments)
+ assert F.isEmpty(assignment) || assignment.size() == 1;
+ }
+
+ AffinityAdapter<Row> affinity = new AffinityAdapter<>(affSrvc.affinity(CU.UNDEFINED_CACHE_ID), k.toIntArray(),
+ ctx.rowHandler());
+
+ return new Partitioned<>(assignments, affinity);
+ }
+ }
+
+ /** */
+ private static final class AffinityDistribution extends DistributionFunction {
+ /** */
+ private final int cacheId;
+
+ /** */
+ private final Object identity;
+
+ /**
+ * @param cacheId Cache ID.
+ * @param identity Affinity identity key.
+ */
+ public AffinityDistribution(int cacheId, Object identity) {
+ this.cacheId = cacheId;
+ this.identity = identity;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean affinity() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int cacheId() {
+ return cacheId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type type() {
+ return RelDistribution.Type.HASH_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ctx, AffinityService affSrvc,
+ ColocationGroup m, ImmutableIntList k) {
+ assert m != null && !F.isEmpty(m.assignments()) && k.size() == 1;
+
+ List<List<UUID>> assignments = m.assignments();
+
+ if (U.assertionsEnabled()) {
+ for (List<UUID> assignment : assignments)
+ assert F.isEmpty(assignment) || assignment.size() == 1;
+ }
+
+ AffinityAdapter<Row> affinity = new AffinityAdapter<>(affSrvc.affinity(cacheId), k.toIntArray(), ctx.rowHandler());
+
+ return new Partitioned<>(assignments, affinity);
+ }
+
+ /** */
+ public Object identity() {
+ return identity;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected String name0() {
+ return "affinity[identity=" + identity + ", cacheId=" + cacheId + ']';
+ }
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTrait.java
index 7c1f4a0,0000000..9e16870
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTrait.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/DistributionTrait.java
@@@ -1,185 -1,0 +1,185 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.trait;
+
+import java.util.List;
+import java.util.Objects;
+import com.google.common.collect.Ordering;
+import org.apache.calcite.plan.RelMultipleTrait;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTrait;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.mapping.Mapping;
+import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
+import org.apache.ignite.internal.processors.query.calcite.metadata.AffinityService;
+import org.apache.ignite.internal.processors.query.calcite.metadata.ColocationGroup;
+
+import static org.apache.calcite.rel.RelDistribution.Type.ANY;
+import static org.apache.calcite.rel.RelDistribution.Type.BROADCAST_DISTRIBUTED;
+import static org.apache.calcite.rel.RelDistribution.Type.HASH_DISTRIBUTED;
+import static org.apache.calcite.rel.RelDistribution.Type.RANDOM_DISTRIBUTED;
+import static org.apache.calcite.rel.RelDistribution.Type.SINGLETON;
+
+/**
+ * Description of the physical distribution of a relational expression.
+ */
+public final class DistributionTrait implements IgniteDistribution {
+ /** */
+ private static final Ordering<Iterable<Integer>> ORDERING =
+ Ordering.<Integer>natural().lexicographical();
+
+ /** */
+ private final DistributionFunction function;
+
+ /** */
+ private final ImmutableIntList keys;
+
+ /**
+ * @param function Distribution function.
+ */
+ DistributionTrait(DistributionFunction function) {
+ assert function.type() != HASH_DISTRIBUTED;
+
+ this.function = function;
+
+ keys = ImmutableIntList.of();
+ }
+
+ /**
+ * @param keys Distribution keys.
+ * @param function Distribution function.
+ */
+ DistributionTrait(ImmutableIntList keys, DistributionFunction function) {
+ this.keys = keys;
+ this.function = function;
+ }
+
+ /** {@inheritDoc} */
+ @Override public RelDistribution.Type getType() {
+ return function.type();
+ }
+
+ /** {@inheritDoc} */
+ @Override public DistributionFunction function() {
+ return function;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <Row> Destination<Row> destination(ExecutionContext<Row> ectx, AffinityService affSrvc, ColocationGroup target) {
+ return function.destination(ectx, affSrvc, target, keys);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ImmutableIntList getKeys() {
+ return keys;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void register(RelOptPlanner planner) {}
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o instanceof DistributionTrait) {
- DistributionTrait that = (DistributionTrait) o;
++ DistributionTrait that = (DistributionTrait)o;
+
+ return Objects.equals(function, that.function) && Objects.equals(keys, that.keys);
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Objects.hash(function, keys);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return function.name() + (function.type() == HASH_DISTRIBUTED ? keys : "");
+ }
+
+ /** {@inheritDoc} */
+ @Override public DistributionTraitDef getTraitDef() {
+ return DistributionTraitDef.INSTANCE;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean satisfies(RelTrait trait) {
+ if (trait == this)
+ return true;
+
+ if (!(trait instanceof DistributionTrait))
+ return false;
+
- DistributionTrait other = (DistributionTrait) trait;
++ DistributionTrait other = (DistributionTrait)trait;
+
+ if (other.getType() == ANY)
+ return true;
+
+ if (getType() == other.getType())
+ return getType() != HASH_DISTRIBUTED
+ || (Objects.equals(keys, other.keys)
+ && DistributionFunction.satisfy(function, other.function));
+
+ if (other.getType() == RANDOM_DISTRIBUTED)
+ return getType() == HASH_DISTRIBUTED;
+
+ return other.getType() == SINGLETON && getType() == BROADCAST_DISTRIBUTED;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteDistribution apply(Mappings.TargetMapping mapping) {
+ if (getType() != HASH_DISTRIBUTED)
+ return this;
+
+ for (int key : keys) {
+ if (mapping.getTargetOpt(key) == -1)
+ return IgniteDistributions.random(); // Some distribution keys are not mapped => any.
+ }
+
- List<Integer> res = Mappings.apply2((Mapping) mapping, keys);
++ List<Integer> res = Mappings.apply2((Mapping)mapping, keys);
+
+ return IgniteDistributions.hash(ImmutableIntList.copyOf(res), function);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isTop() {
+ return getType() == Type.ANY;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int compareTo(RelMultipleTrait o) {
- final IgniteDistribution distribution = (IgniteDistribution) o;
++ final IgniteDistribution distribution = (IgniteDistribution)o;
+
+ if (getType() == distribution.getType() && getType() == Type.HASH_DISTRIBUTED) {
+ int cmp = ORDERING.compare(getKeys(), distribution.getKeys());
+
+ if (cmp == 0)
+ cmp = function.name().compareTo(distribution.function().name());
+
+ return cmp;
+ }
+
+ return getType().compareTo(distribution.getType());
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
index 9bc73fc,0000000..0758dd2
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
@@@ -1,540 -1,0 +1,540 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.trait;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelTrait;
+import org.apache.calcite.plan.RelTraitDef;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelInput;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.AggregateCall;
+import org.apache.calcite.rel.core.Spool;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.ControlFlowException;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteConvention;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteExchange;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteSort;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTrimExchange;
+import org.apache.ignite.internal.util.typedef.F;
+import org.jetbrains.annotations.Nullable;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+import static org.apache.calcite.plan.RelOptUtil.permutationPushDownProject;
+import static org.apache.calcite.rel.RelDistribution.Type.BROADCAST_DISTRIBUTED;
+import static org.apache.calcite.rel.RelDistribution.Type.HASH_DISTRIBUTED;
+import static org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions.any;
+import static org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions.single;
+
+/**
+ *
+ */
+public class TraitUtils {
+ /** */
+ @Nullable public static RelNode enforce(RelNode rel, RelTraitSet toTraits) {
+ RelOptPlanner planner = rel.getCluster().getPlanner();
+ RelTraitSet fromTraits = rel.getTraitSet();
+ int size = Math.min(fromTraits.size(), toTraits.size());
+
+ if (!fromTraits.satisfies(toTraits)) {
+ RelNode old = null;
+
+ for (int i = 0; rel != null && i < size; i++) {
+ RelTrait fromTrait = rel.getTraitSet().getTrait(i);
+ RelTrait toTrait = toTraits.getTrait(i);
+
+ if (fromTrait.satisfies(toTrait))
+ continue;
+
+ if (old != null && old != rel)
+ rel = planner.register(rel, old);
+
+ old = rel;
+
+ rel = convertTrait(planner, fromTrait, toTrait, rel);
+
+ assert rel == null || rel.getTraitSet().getTrait(i).satisfies(toTrait);
+ }
+
+ assert rel == null || rel.getTraitSet().satisfies(toTraits);
+ }
+
+ return rel;
+ }
+
+ /** */
+ @SuppressWarnings({"rawtypes"})
+ @Nullable private static RelNode convertTrait(RelOptPlanner planner, RelTrait fromTrait, RelTrait toTrait, RelNode rel) {
+ assert fromTrait.getTraitDef() == toTrait.getTraitDef();
+
+ RelTraitDef converter = fromTrait.getTraitDef();
+
+ if (converter == RelCollationTraitDef.INSTANCE)
+ return convertCollation(planner, (RelCollation)toTrait, rel);
+ else if (converter == DistributionTraitDef.INSTANCE)
+ return convertDistribution(planner, (IgniteDistribution)toTrait, rel);
+ else if (converter == RewindabilityTraitDef.INSTANCE)
+ return convertRewindability(planner, (RewindabilityTrait)toTrait, rel);
+ else
+ return convertOther(planner, converter, toTrait, rel);
+ }
+
+ /** */
+ @Nullable public static RelNode convertCollation(RelOptPlanner planner,
+ RelCollation toTrait, RelNode rel) {
+ RelCollation fromTrait = collation(rel);
+
+ if (fromTrait.satisfies(toTrait))
+ return rel;
+
+ RelTraitSet traits = rel.getTraitSet().replace(toTrait);
+
+ return new IgniteSort(rel.getCluster(), traits, rel, toTrait);
+ }
+
+ /** */
+ @Nullable public static RelNode convertDistribution(RelOptPlanner planner,
+ IgniteDistribution toTrait, RelNode rel) {
+ IgniteDistribution fromTrait = distribution(rel);
+
+ if (fromTrait.satisfies(toTrait))
+ return rel;
+
+ // right now we cannot create a multi-column affinity
+ // key object, thus this conversion is impossible
+ if (toTrait.function().affinity() && toTrait.getKeys().size() > 1)
+ return null;
+
+ RelTraitSet traits = rel.getTraitSet().replace(toTrait);
+ if (fromTrait.getType() == BROADCAST_DISTRIBUTED && toTrait.getType() == HASH_DISTRIBUTED)
+ return new IgniteTrimExchange(rel.getCluster(), traits, rel, toTrait);
+ else {
+ return new IgniteExchange(
+ rel.getCluster(),
+ traits
+ .replace(RewindabilityTrait.ONE_WAY)
+ .replace(CorrelationTrait.UNCORRELATED),
+ RelOptRule.convert(
+ rel,
+ rel.getTraitSet()
+ .replace(CorrelationTrait.UNCORRELATED)
+ ),
+ toTrait);
+ }
+ }
+
+ /** */
+ @Nullable public static RelNode convertRewindability(RelOptPlanner planner,
+ RewindabilityTrait toTrait, RelNode rel) {
+ RewindabilityTrait fromTrait = rewindability(rel);
+
+ if (fromTrait.satisfies(toTrait))
+ return rel;
+
+ RelTraitSet traits = rel.getTraitSet()
+ .replace(toTrait)
+ .replace(CorrelationTrait.UNCORRELATED);
+
+ return new IgniteTableSpool(
+ rel.getCluster(),
+ traits,
+ Spool.Type.LAZY,
+ RelOptRule.convert(rel, rel.getTraitSet().replace(CorrelationTrait.UNCORRELATED))
+ );
+ }
+
+ /** */
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Nullable private static RelNode convertOther(RelOptPlanner planner, RelTraitDef converter,
+ RelTrait toTrait, RelNode rel) {
+ RelTrait fromTrait = rel.getTraitSet().getTrait(converter);
+
+ if (fromTrait.satisfies(toTrait))
+ return rel;
+
+ if (!converter.canConvert(planner, fromTrait, toTrait))
+ return null;
+
+ return converter.convert(planner, rel, toTrait, true);
+ }
+
+ /** Change distribution and Convention. */
+ public static RelTraitSet fixTraits(RelTraitSet traits) {
+ if (distribution(traits) == any())
+ traits = traits.replace(single());
+
+ return traits.replace(IgniteConvention.INSTANCE);
+ }
+
+ /** */
+ public static IgniteDistribution distribution(RelNode rel) {
+ return rel instanceof IgniteRel
+ ? ((IgniteRel)rel).distribution()
+ : distribution(rel.getTraitSet());
+ }
+
+ /** */
+ public static IgniteDistribution distribution(RelTraitSet traits) {
+ return traits.getTrait(DistributionTraitDef.INSTANCE);
+ }
+
+ /** */
+ public static RelCollation collation(RelNode rel) {
+ return rel instanceof IgniteRel
+ ? ((IgniteRel)rel).collation()
+ : collation(rel.getTraitSet());
+ }
+
+ /** */
+ public static RelCollation collation(RelTraitSet traits) {
+ return traits.getTrait(RelCollationTraitDef.INSTANCE);
+ }
+
+ /** */
+ public static RewindabilityTrait rewindability(RelNode rel) {
+ return rel instanceof IgniteRel
+ ? ((IgniteRel)rel).rewindability()
+ : rewindability(rel.getTraitSet());
+ }
+
+ /** */
+ public static RewindabilityTrait rewindability(RelTraitSet traits) {
+ return traits.getTrait(RewindabilityTraitDef.INSTANCE);
+ }
+
+ /** */
+ public static CorrelationTrait correlation(RelNode rel) {
+ return rel instanceof IgniteRel
+ ? ((IgniteRel)rel).correlation()
+ : correlation(rel.getTraitSet());
+ }
+
+ /** */
+ public static CorrelationTrait correlation(RelTraitSet traits) {
+ return traits.getTrait(CorrelationTraitDef.INSTANCE);
+ }
+
+ /** */
+ public static RelInput changeTraits(RelInput input, RelTrait... traits) {
+ RelTraitSet traitSet = input.getTraitSet();
+
+ for (RelTrait trait : traits)
+ traitSet = traitSet.replace(trait);
+
+ RelTraitSet traitSet0 = traitSet;
+
+ return new RelInput() {
+ @Override public RelOptCluster getCluster() {
+ return input.getCluster();
+ }
+
+ @Override public RelTraitSet getTraitSet() {
+ return traitSet0;
+ }
+
+ @Override public RelOptTable getTable(String table) {
+ return input.getTable(table);
+ }
+
+ @Override public RelNode getInput() {
+ return input.getInput();
+ }
+
+ @Override public List<RelNode> getInputs() {
+ return input.getInputs();
+ }
+
+ @Override public RexNode getExpression(String tag) {
+ return input.getExpression(tag);
+ }
+
+ @Override public ImmutableBitSet getBitSet(String tag) {
+ return input.getBitSet(tag);
+ }
+
+ @Override public List<ImmutableBitSet> getBitSetList(String tag) {
+ return input.getBitSetList(tag);
+ }
+
+ @Override public List<AggregateCall> getAggregateCalls(String tag) {
+ return input.getAggregateCalls(tag);
+ }
+
+ @Override public Object get(String tag) {
+ return input.get(tag);
+ }
+
+ @Override public String getString(String tag) {
+ return input.getString(tag);
+ }
+
+ @Override public float getFloat(String tag) {
+ return input.getFloat(tag);
+ }
+
+ @Override public <E extends Enum<E>> E getEnum(String tag, Class<E> enumClass) {
+ return input.getEnum(tag, enumClass);
+ }
+
+ @Override public List<RexNode> getExpressionList(String tag) {
+ return input.getExpressionList(tag);
+ }
+
+ @Override public List<String> getStringList(String tag) {
+ return input.getStringList(tag);
+ }
+
+ @Override public List<Integer> getIntegerList(String tag) {
+ return input.getIntegerList(tag);
+ }
+
+ @Override public List<List<Integer>> getIntegerListList(String tag) {
+ return input.getIntegerListList(tag);
+ }
+
+ @Override public RelDataType getRowType(String tag) {
+ return input.getRowType(tag);
+ }
+
+ @Override public RelDataType getRowType(String expressionsTag, String fieldsTag) {
+ return input.getRowType(expressionsTag, fieldsTag);
+ }
+
+ @Override public RelCollation getCollation() {
+ return input.getCollation();
+ }
+
+ @Override public RelDistribution getDistribution() {
+ return input.getDistribution();
+ }
+
+ @Override public ImmutableList<ImmutableList<RexLiteral>> getTuples(
+ String tag) {
+ return input.getTuples(tag);
+ }
+
+ @Override public boolean getBoolean(String tag, boolean default_) {
+ return input.getBoolean(tag, default_);
+ }
+ };
+ }
+
+ /** */
+ public static RelCollation projectCollation(RelCollation collation, List<RexNode> projects, RelDataType inputRowType) {
+ if (collation.getFieldCollations().isEmpty())
+ return RelCollations.EMPTY;
+
+ Mappings.TargetMapping mapping = permutationPushDownProject(projects, inputRowType, 0, 0);
+
+ return collation.apply(mapping);
+ }
+
+ /** */
+ public static IgniteDistribution projectDistribution(IgniteDistribution distribution, List<RexNode> projects,
+ RelDataType inputRowType) {
+ if (distribution.getType() != HASH_DISTRIBUTED)
+ return distribution;
+
+ Mappings.TargetMapping mapping = createProjectionMapping(inputRowType.getFieldCount(), projects);
+
+ return distribution.apply(mapping);
+ }
+
+ /** */
+ public static Pair<RelTraitSet, List<RelTraitSet>> passThrough(TraitsAwareIgniteRel rel, RelTraitSet requiredTraits) {
+ if (requiredTraits.getConvention() != IgniteConvention.INSTANCE || rel.getInputs().isEmpty())
+ return null;
+
+ List<RelTraitSet> inTraits = Collections.nCopies(rel.getInputs().size(),
+ rel.getCluster().traitSetOf(IgniteConvention.INSTANCE));
+
+ List<Pair<RelTraitSet, List<RelTraitSet>>> traits = new PropagationContext(ImmutableSet.of(Pair.of(requiredTraits, inTraits)))
+ .propagate((in, outs) -> singletonListFromNullable(rel.passThroughCollation(in, outs)))
+ .propagate((in, outs) -> singletonListFromNullable(rel.passThroughDistribution(in, outs)))
+ .propagate((in, outs) -> singletonListFromNullable(rel.passThroughRewindability(in, outs)))
+ .propagate((in, outs) -> singletonListFromNullable(rel.passThroughCorrelation(in, outs)))
+ .combinations();
+
+ assert traits.size() <= 1;
+
+ return F.first(traits);
+ }
+
+ /** */
+ public static List<RelNode> derive(TraitsAwareIgniteRel rel, List<List<RelTraitSet>> inTraits) {
+ assert !F.isEmpty(inTraits);
+
+ RelTraitSet outTraits = rel.getCluster().traitSetOf(IgniteConvention.INSTANCE);
+ Set<Pair<RelTraitSet, List<RelTraitSet>>> combinations = combinations(outTraits, inTraits);
+
+ if (combinations.isEmpty())
+ return ImmutableList.of();
+
+ return new PropagationContext(combinations)
+ .propagate(rel::deriveCollation)
+ .propagate(rel::deriveDistribution)
+ .propagate(rel::deriveRewindability)
+ .propagate(rel::deriveCorrelation)
+ .nodes(rel::createNode);
+ }
+
+ /**
+ * @param elem Elem.
+ */
+ private static <T> List<T> singletonListFromNullable(@Nullable T elem) {
+ return elem == null ? emptyList() : singletonList(elem);
+ }
+
+ /** */
+ private static Set<Pair<RelTraitSet, List<RelTraitSet>>> combinations(RelTraitSet outTraits, List<List<RelTraitSet>> inTraits) {
+ Set<Pair<RelTraitSet, List<RelTraitSet>>> out = new HashSet<>();
+ fillRecursive(outTraits, inTraits, out, new RelTraitSet[inTraits.size()], 0);
+ return out;
+ }
+
+ /** */
+ private static boolean fillRecursive(RelTraitSet outTraits, List<List<RelTraitSet>> inTraits,
+ Set<Pair<RelTraitSet, List<RelTraitSet>>> result, RelTraitSet[] combination, int idx) throws ControlFlowException {
+ boolean processed = false, last = idx == inTraits.size() - 1;
+ for (RelTraitSet t : inTraits.get(idx)) {
+ if (t.getConvention() != IgniteConvention.INSTANCE)
+ continue;
+
+ processed = true;
+ combination[idx] = t;
+
+ if (last)
+ result.add(Pair.of(outTraits, ImmutableList.copyOf(combination)));
+ else if (!fillRecursive(outTraits, inTraits, result, combination, idx + 1))
+ return false;
+ }
+ return processed;
+ }
+
+ /**
+ * Creates collations from provided keys.
+ *
+ * @param keys The keys to create collation from.
+ * @return New collation.
+ */
+ public static RelCollation createCollation(List<Integer> keys) {
+ return RelCollations.of(
+ keys.stream().map(RelFieldCollation::new).collect(Collectors.toList())
+ );
+ }
+
+ /**
+ * Creates mapping from provided projects that maps a source column idx
+ * to idx in a row after applying projections.
+ *
+ * @param inputFieldCount Size of a source row.
+ * @param projects Projections.
+ */
+ private static Mappings.TargetMapping createProjectionMapping(int inputFieldCount, List<? extends RexNode> projects) {
+ Map<Integer, Integer> src2target = new HashMap<>();
+
+ for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) {
+ if (exp.e instanceof RexInputRef)
- src2target.putIfAbsent(((RexInputRef) exp.e).getIndex(), exp.i);
++ src2target.putIfAbsent(((RexInputRef)exp.e).getIndex(), exp.i);
+ }
+
+ return Mappings.target(src -> src2target.getOrDefault(src, -1), inputFieldCount, projects.size());
+ }
+
+ /** */
+ private static class PropagationContext {
+ /** */
+ private final Set<Pair<RelTraitSet, List<RelTraitSet>>> combinations;
+
+ /** */
+ private PropagationContext(Set<Pair<RelTraitSet, List<RelTraitSet>>> combinations) {
+ this.combinations = combinations;
+ }
+
+ /**
+ * Propagates traits in bottom-up or up-to-bottom manner using given traits propagator.
+ */
+ public PropagationContext propagate(TraitsPropagator processor) {
+ if (combinations.isEmpty())
+ return this;
+
+ ImmutableSet.Builder<Pair<RelTraitSet, List<RelTraitSet>>> b = ImmutableSet.builder();
+ for (Pair<RelTraitSet, List<RelTraitSet>> variant : combinations)
+ b.addAll(processor.propagate(variant.left, variant.right));
+ return new PropagationContext(b.build());
+ }
+
+ /**
+ * Creates nodes using given factory.
+ */
+ public List<RelNode> nodes(RelFactory nodesCreator) {
+ if (combinations.isEmpty())
+ return ImmutableList.of();
+
+ ImmutableList.Builder<RelNode> b = ImmutableList.builder();
+ for (Pair<RelTraitSet, List<RelTraitSet>> variant : combinations)
+ b.add(nodesCreator.create(variant.left, variant.right));
+ return b.build();
+ }
+
+ /** */
+ public List<Pair<RelTraitSet, List<RelTraitSet>>> combinations() {
+ return ImmutableList.copyOf(combinations);
+ }
+ }
+
+ /** */
+ private interface TraitsPropagator {
+ /**
+ * Propagates traits in bottom-up or up-to-bottom manner.
+ *
+ * @param outTraits Relational node traits.
+ * @param inTraits Relational node input traits.
+ * @return List of possible input-output traits combinations.
+ */
+ List<Pair<RelTraitSet, List<RelTraitSet>>> propagate(RelTraitSet outTraits, List<RelTraitSet> inTraits);
+ }
+}
diff --cc modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
index 826538e,0000000..f25fa87
mode 100644,000000..100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
@@@ -1,447 -1,0 +1,447 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.query.calcite.util;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.calcite.config.CalciteSystemProperty;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.SourceStringReader;
+import org.apache.calcite.util.Util;
+import org.apache.calcite.util.mapping.Mapping;
+import org.apache.calcite.util.mapping.MappingType;
+import org.apache.calcite.util.mapping.Mappings;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.GridComponent;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.QueryContext;
+import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler;
+import org.apache.ignite.internal.processors.query.calcite.exec.exp.ExpressionFactoryImpl;
+import org.apache.ignite.internal.processors.query.calcite.prepare.BaseQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext;
+import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.codehaus.commons.compiler.CompilerFactoryFactory;
+import org.codehaus.commons.compiler.IClassBodyEvaluator;
+import org.codehaus.commons.compiler.ICompilerFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Utility methods.
+ */
+public final class Commons {
+ /** */
+ private Commons() {
+ // No-op.
+ }
+
+ /**
+ * Converts a QueryContext into a planner context.
+ * @param ctx QueryContext.
+ * @return Planner context.
+ */
+ public static Context convert(QueryContext ctx) {
+ return ctx == null ? Contexts.empty() : Contexts.of(ctx.unwrap(Object[].class));
+ }
+
+ /**
+ * Gets appropriate field from two rows by offset.
+ * @param hnd RowHandler impl.
+ * @param offset Current offset.
+ * @param row1 row1.
+ * @param row2 row2.
+ * @return Returns field by offset.
+ */
+ public static <Row> Object getFieldFromBiRows(RowHandler<Row> hnd, int offset, Row row1, Row row2) {
+ return offset < hnd.columnCount(row1) ? hnd.get(offset, row1) :
+ hnd.get(offset - hnd.columnCount(row1), row2);
+ }
+
+ /**
+ * Combines two lists.
+ */
+ public static <T> List<T> combine(List<T> left, List<T> right) {
+ Set<T> set = new HashSet<>(left.size() + right.size());
+
+ set.addAll(left);
+ set.addAll(right);
+
+ return new ArrayList<>(set);
+ }
+
+ /**
+ * Intersects two lists.
+ */
+ public static <T> List<T> intersect(List<T> left, List<T> right) {
+ if (F.isEmpty(left) || F.isEmpty(right))
+ return Collections.emptyList();
+
+ return left.size() > right.size()
+ ? intersect(new HashSet<>(right), left)
+ : intersect(new HashSet<>(left), right);
+ }
+
+ /**
+ * Intersects a set and a list.
+ *
+ * @return A List of unique entries that presented in both the given set and the given list.
+ */
+ public static <T> List<T> intersect(Set<T> set, List<T> list) {
+ if (F.isEmpty(set) || F.isEmpty(list))
+ return Collections.emptyList();
+
+ return list.stream()
+ .filter(set::contains)
+ .collect(Collectors.toList());
... 3821 lines suppressed ...