/* * 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.h2.twostep.msg; import java.io.Externalizable; import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.GridDirectCollection; import org.apache.ignite.internal.GridDirectMap; import org.apache.ignite.internal.GridDirectTransient; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.query.GridCacheQueryMarshallable; import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType; import org.apache.ignite.plugin.extensions.communication.MessageReader; import org.apache.ignite.plugin.extensions.communication.MessageWriter; import static org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery.EMPTY_PARAMS; /** * Query request. */ public class GridH2QueryRequest implements Message, GridCacheQueryMarshallable { /** */ private static final long serialVersionUID = 0L; /** * Map query will not destroy context until explicit query cancel request will be received because distributed join * requests can be received. */ public static final int FLAG_DISTRIBUTED_JOINS = 1; /** * Remote map query executor will enforce join order for the received map queries. */ public static final int FLAG_ENFORCE_JOIN_ORDER = 1 << 1; /** * Restrict distributed joins range-requests to local index segments. Range requests to other nodes will not be sent. */ public static final int FLAG_IS_LOCAL = 1 << 2; /** * If it is an EXPLAIN command. */ public static final int FLAG_EXPLAIN = 1 << 3; /** * If it is a REPLICATED query. */ public static final int FLAG_REPLICATED = 1 << 4; /** */ private long reqId; /** */ @GridToStringInclude @GridDirectCollection(Integer.class) private List<Integer> caches; /** Topology version. */ private AffinityTopologyVersion topVer; /** Explicit partitions mappings for nodes. */ @GridToStringInclude @GridDirectMap(keyType = UUID.class, valueType = int[].class) private Map<UUID, int[]> parts; /** Query partitions. */ @GridToStringInclude private int[] qryParts; /** */ private int pageSize; /** */ @GridToStringInclude @GridDirectCollection(Message.class) private List<GridCacheSqlQuery> qrys; /** */ private byte flags; /** */ @GridToStringInclude @GridDirectCollection(String.class) private Collection<String> tbls; /** */ private int timeout; /** */ @GridToStringInclude(sensitive = true) @GridDirectTransient private Object[] params; /** */ private byte[] paramsBytes; /** * Required by {@link Externalizable} */ public GridH2QueryRequest() { // No-op. } /** * @param req Request. */ public GridH2QueryRequest(GridH2QueryRequest req) { reqId = req.reqId; caches = req.caches; topVer = req.topVer; parts = req.parts; qryParts = req.qryParts; pageSize = req.pageSize; qrys = req.qrys; flags = req.flags; tbls = req.tbls; timeout = req.timeout; params = req.params; paramsBytes = req.paramsBytes; } /** * @return Parameters. */ public Object[] parameters() { return params; } /** * @param params Parameters. * @return {@code this}. */ public GridH2QueryRequest parameters(Object[] params) { if (params == null) params = EMPTY_PARAMS; this.params = params; return this; } /** * @param tbls Tables. * @return {@code this}. */ public GridH2QueryRequest tables(Collection<String> tbls) { this.tbls = tbls; return this; } /** * @return Tables. */ public Collection<String> tables() { return tbls; } /** * @param reqId Request ID. * @return {@code this}. */ public GridH2QueryRequest requestId(long reqId) { this.reqId = reqId; return this; } /** * @return Request ID. */ public long requestId() { return reqId; } /** * @param caches Caches. * @return {@code this}. */ public GridH2QueryRequest caches(List<Integer> caches) { this.caches = caches; return this; } /** * @return Caches. */ public List<Integer> caches() { return caches; } /** * @param topVer Topology version. * @return {@code this}. */ public GridH2QueryRequest topologyVersion(AffinityTopologyVersion topVer) { this.topVer = topVer; return this; } /** * @return Topology version. */ public AffinityTopologyVersion topologyVersion() { return topVer; } /** * @return Explicit partitions mapping. */ public Map<UUID, int[]> partitions() { return parts; } /** * @param parts Explicit partitions mapping. * @return {@code this}. */ public GridH2QueryRequest partitions(Map<UUID, int[]> parts) { this.parts = parts; return this; } /** * @return Query partitions. */ public int[] queryPartitions() { return qryParts; } /** * @param qryParts Query partitions. * @return {@code this}. */ public GridH2QueryRequest queryPartitions(int[] qryParts) { this.qryParts = qryParts; return this; } /** * @param pageSize Page size. * @return {@code this}. */ public GridH2QueryRequest pageSize(int pageSize) { this.pageSize = pageSize; return this; } /** * @return Page size. */ public int pageSize() { return pageSize; } /** * @param qrys SQL Queries. * @return {@code this}. */ public GridH2QueryRequest queries(List<GridCacheSqlQuery> qrys) { this.qrys = qrys; return this; } /** * @return SQL Queries. */ public List<GridCacheSqlQuery> queries() { return qrys; } /** * @param flags Flags. * @return {@code this}. */ public GridH2QueryRequest flags(int flags) { assert flags >= 0 && flags <= 255: flags; this.flags = (byte)flags; return this; } /** * @param flags Flags to check. * @return {@code true} If all the requested flags are set to {@code true}. */ public boolean isFlagSet(int flags) { return (this.flags & flags) == flags; } /** * @return Timeout. */ public int timeout() { return timeout; } /** * @param timeout New timeout. * @return {@code this}. */ public GridH2QueryRequest timeout(int timeout) { this.timeout = timeout; return this; } /** {@inheritDoc} */ @Override public void marshall(Marshaller m) { if (paramsBytes != null) return; assert params != null; try { paramsBytes = U.marshal(m, params); } catch (IgniteCheckedException e) { throw new IgniteException(e); } } /** {@inheritDoc} */ @SuppressWarnings("IfMayBeConditional") @Override public void unmarshall(Marshaller m, GridKernalContext ctx) { if (params != null) return; assert paramsBytes != null; try { final ClassLoader ldr = U.resolveClassLoader(ctx.config()); if (m instanceof BinaryMarshaller) // To avoid deserializing of enum types. params = ((BinaryMarshaller)m).binaryMarshaller().unmarshal(paramsBytes, ldr); else params = U.unmarshal(m, paramsBytes, ldr); } catch (IgniteCheckedException e) { throw new IgniteException(e); } } /** {@inheritDoc} */ @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) { writer.setBuffer(buf); if (!writer.isHeaderWritten()) { if (!writer.writeHeader(directType(), fieldsCount())) return false; writer.onHeaderWritten(); } switch (writer.state()) { case 0: if (!writer.writeCollection("caches", caches, MessageCollectionItemType.INT)) return false; writer.incrementState(); case 1: if (!writer.writeByte("flags", flags)) return false; writer.incrementState(); case 2: if (!writer.writeInt("pageSize", pageSize)) return false; writer.incrementState(); case 3: if (!writer.writeByteArray("paramsBytes", paramsBytes)) return false; writer.incrementState(); case 4: if (!writer.writeMap("parts", parts, MessageCollectionItemType.UUID, MessageCollectionItemType.INT_ARR)) return false; writer.incrementState(); case 5: if (!writer.writeCollection("qrys", qrys, MessageCollectionItemType.MSG)) return false; writer.incrementState(); case 6: if (!writer.writeLong("reqId", reqId)) return false; writer.incrementState(); case 7: if (!writer.writeCollection("tbls", tbls, MessageCollectionItemType.STRING)) return false; writer.incrementState(); case 8: if (!writer.writeInt("timeout", timeout)) return false; writer.incrementState(); case 9: if (!writer.writeMessage("topVer", topVer)) return false; writer.incrementState(); case 10: if (!writer.writeIntArray("qryParts", qryParts)) return false; writer.incrementState(); } return true; } /** {@inheritDoc} */ @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) { reader.setBuffer(buf); if (!reader.beforeMessageRead()) return false; switch (reader.state()) { case 0: caches = reader.readCollection("caches", MessageCollectionItemType.INT); if (!reader.isLastRead()) return false; reader.incrementState(); case 1: flags = reader.readByte("flags"); if (!reader.isLastRead()) return false; reader.incrementState(); case 2: pageSize = reader.readInt("pageSize"); if (!reader.isLastRead()) return false; reader.incrementState(); case 3: paramsBytes = reader.readByteArray("paramsBytes"); if (!reader.isLastRead()) return false; reader.incrementState(); case 4: parts = reader.readMap("parts", MessageCollectionItemType.UUID, MessageCollectionItemType.INT_ARR, false); if (!reader.isLastRead()) return false; reader.incrementState(); case 5: qrys = reader.readCollection("qrys", MessageCollectionItemType.MSG); if (!reader.isLastRead()) return false; reader.incrementState(); case 6: reqId = reader.readLong("reqId"); if (!reader.isLastRead()) return false; reader.incrementState(); case 7: tbls = reader.readCollection("tbls", MessageCollectionItemType.STRING); if (!reader.isLastRead()) return false; reader.incrementState(); case 8: timeout = reader.readInt("timeout"); if (!reader.isLastRead()) return false; reader.incrementState(); case 9: topVer = reader.readMessage("topVer"); if (!reader.isLastRead()) return false; reader.incrementState(); case 10: qryParts = reader.readIntArray("qryParts"); if (!reader.isLastRead()) return false; reader.incrementState(); } return reader.afterMessageRead(GridH2QueryRequest.class); } /** {@inheritDoc} */ @Override public short directType() { return -33; } /** {@inheritDoc} */ @Override public byte fieldsCount() { return 11; } /** {@inheritDoc} */ @Override public void onAckReceived() { // No-op. } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridH2QueryRequest.class, this); } }