// 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.
= SQL and Scan Queries

== Operation codes

Upon a successful handshake with an Ignite server node, a client can start performing various SQL and scan queries by sending a request (see request/response structure below) with a specific operation code:


[cols="2,1",opts="header"]
|===
|Operation |   OP_CODE
|OP_QUERY_SQL|    2002
|OP_QUERY_SQL_CURSOR_GET_PAGE|    2003
|OP_QUERY_SQL_FIELDS| 2004
|OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE| 2005
|OP_QUERY_SCAN|   2000
|OP_QUERY_SCAN_CURSOR_GET_PAGE|   2001
|OP_RESOURCE_CLOSE|   0
|===


Note that the above mentioned op_codes are part of the request header, as explained link:binary-client-protocol/binary-client-protocol#standard-message-header[here].

[NOTE]
====
[discrete]
=== Customs Methods Used in Sample Code Snippets Implementation

Some of the code snippets below use `readDataObject(...)` introduced in link:binary-client-protocol/binary-client-protocol#data-objects[this section] and little-endian versions of methods for reading and writing multiple-byte values that are covered in link:binary-client-protocol/binary-client-protocol#data-objects[this example].
====


== OP_QUERY_SQL

Executes an SQL query over data stored in the cluster. The query returns the whole record (key and value).


[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|int| Cache ID: Java-style hash code of the cache name
|byte|    Use 0. This field is deprecated and will be removed in the future.
|String|  Name of a type or SQL table.
|String|  SQL query string.
|int| Query argument count.
|Data Object| Query argument.

Repeat for as many times as the query argument count that is passed in the previous parameter.
|bool|    Distributed joins.
|bool|    Local query.
|bool|    Replicated only - Whether query contains only replicated tables or not.
|int| Cursor page size.
|long|    Timeout (miliseconds).

Timeout value should be non-negative. Zero value disables timeout.
|===


Response includes the first page of the result.

[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|long|    Cursor id. Can be closed with OP_RESOURSE_CLOSE.
|int| Row count for the first page.
|Key Data Object + Value Data Object| Records in the form of key-value pairs.

Repeat for as many times as the row count obtained in the previous parameter.
|bool|    Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.
When true, query cursor is closed automatically.
|===


[tabs]
--
tab:Request[]

[source, java]
----
String entityName = "Person";
int entityNameLength = getStrLen(entityName); // UTF-8 bytes

String sql = "Select * from Person";
int sqlLength = getStrLen(sql);

DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(34 + entityNameLength + sqlLength, OP_QUERY_SQL, 1, out);

// Cache id
String queryCacheName = "personCache";
writeIntLittleEndian(queryCacheName.hashCode(), out);

// Flag = none
writeByteLittleEndian(0, out);

// Query Entity
writeString(entityName, out);

// SQL query
writeString(sql, out);

// Argument count
writeIntLittleEndian(0, out);

// Joins
out.writeBoolean(false);

// Local query
out.writeBoolean(false);

// Replicated
out.writeBoolean(false);

// cursor page size
writeIntLittleEndian(1, out);

// Timeout
writeLongLittleEndian(5000, out);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

// Response header
readResponseHeader(in);

long cursorId = readLongLittleEndian(in);

int rowCount = readIntLittleEndian(in);

// Read entries (as user objects)
for (int i = 0; i < rowCount; i++) {
  Object key = readDataObject(in);
  Object val = readDataObject(in);

  System.out.println("CacheEntry: " + key + ", " + val);
}

boolean moreResults = readBooleanLittleEndian(in);

----

--



== OP_QUERY_SQL_CURSOR_GET_PAGE

Retrieves the next SQL query cursor page by cursor id from OP_QUERY_SQL.

[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|long|    Cursor id.
|===


Response format looks as follows:

[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|long|    Cursor id.
|int| Row count.
|Key Data Object + Value Data Object| Records in the form of key-value pairs.

Repeat for as many times as the row count obtained in the previous parameter.
|bool|    Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.
When true, query cursor is closed automatically.

|===

[tabs]
--
tab:Request[]

[source, java]
----
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(8, OP_QUERY_SQL_CURSOR_GET_PAGE, 1, out);

// Cursor Id (received from Sql query operation)
writeLongLittleEndian(cursorId, out);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

// Response header
readResponseHeader(in);

int rowCount = readIntLittleEndian(in);

// Read entries (as user objects)
for (int i = 0; i < rowCount; i++){
  Object key = readDataObject(in);
  Object val = readDataObject(in);

  System.out.println("CacheEntry: " + key + ", " + val);
}

boolean moreResults = readBooleanLittleEndian(in);

----

--


== OP_QUERY_SQL_FIELDS

Performs SQL fields query.

[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|int| Cache ID: Java-style hash code of the cache name.
|byte|    Use 0. This field is deprecated and will be removed in the future.
|String|  Schema for the query; can be null, in which case default PUBLIC schema will be used.
|int| Query cursor page size.
|int| Max rows.
|String|  SQL
|int| Argument count.
|Data Object| Query argument.

Repeat for as many times as the query argument count that is passed in the previous parameter.

|byte|    Statement type.

ANY = 0

SELECT = 1

UPDATE = 2

|bool|    Distributed joins
|bool|    Local query.
|bool|    Replicated only - Whether query contains only replicated tables or not.
|bool|    Enforce join order.
|bool|    Collocated - Whether your data is co-located or not.
|bool|    [Deprecated] Lazy query execution. This flag is not used anymore on server side.
|long|    Timeout (milliseconds).
|bool|    Include field names.
|===


[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|long|    Cursor id. Can be closed with OP_RESOURCE_CLOSE.
|int| Field (column) count.
|String (optional)|   Needed only when IncludeFieldNames is true in the request.

Column name.

Repeat for as many times as the field count that is retrieved in the previous parameter.

|int| First page row count.
Data Object Column (field) value. Repeat for as many times as the field count.

Repeat for as many times as the row count that is retrieved in the previous parameter.
|bool|    Indicates whether more results are available to be retrieved with OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE.
|===

[tabs]
--
tab:Request[]

[source, java]
----
String sql = "Select id, salary from Person";
int sqlLength = sql.getBytes("UTF-8").length;

String sqlSchema = "PUBLIC";
int sqlSchemaLength = sqlSchema.getBytes("UTF-8").length;

DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(43 + sqlLength + sqlSchemaLength, OP_QUERY_SQL_FIELDS, 1, out);

// Cache id
String queryCacheName = "personCache";
int cacheId = queryCacheName.hashCode();
writeIntLittleEndian(cacheId, out);

// Flag = none
writeByteLittleEndian(0, out);

// Schema
writeByteLittleEndian(9, out);
writeIntLittleEndian(sqlSchemaLength, out);
out.writeBytes(sqlSchema); //sqlSchemaLength

// cursor page size
writeIntLittleEndian(2, out);

// Max Rows
writeIntLittleEndian(5, out);

// SQL query
writeByteLittleEndian(9, out);
writeIntLittleEndian(sqlLength, out);
out.writeBytes(sql);//sqlLength

// Argument count
writeIntLittleEndian(0, out);

// Statement type
writeByteLittleEndian(1, out);

// Joins
out.writeBoolean(false);

// Local query
out.writeBoolean(false);

// Replicated
out.writeBoolean(false);

// Enforce join order
out.writeBoolean(false);

// collocated
out.writeBoolean(false);

// Lazy
out.writeBoolean(true);

// Timeout
writeLongLittleEndian(5000, out);

// Replicated
out.writeBoolean(false);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

// Response header
readResponseHeader(in);

long cursorId = readLongLittleEndian(in);

int colCount = readIntLittleEndian(in);

int rowCount = readIntLittleEndian(in);

// Read entries
for (int i = 0; i < rowCount; i++) {
  long id = (long) readDataObject(in);
  int salary = (int) readDataObject(in);

  System.out.println("Person id: " + id + "; Person Salary: " + salary);
}

boolean moreResults = readBooleanLittleEndian(in);

----

--


== OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE

Retrieves the next query result page by cursor id from OP_QUERY_SQL_FIELDS .

[cols="1,2",opts="header"]
|===
|Request Type|    Description
|Header|  Request header.
|long|    Cursor id received from OP_QUERY_SQL_FIELDS
|===


[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|int| Row count.
|Data Object| Column (field) value. Repeat for as many times as the field count.

Repeat for as many times as the row count that is retrieved in the previous parameter.
|bool|    Indicates whether more results are available to be retrieved with OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE
|===

[tabs]
--
tab:Request[]

[source, java]
----
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(8, QUERY_SQL_FIELDS_CURSOR_GET_PAGE, 1, out);

// Cursor Id
writeLongLittleEndian(1, out);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

// Response header
readResponseHeader(in);

int rowCount = readIntLittleEndian(in);

// Read entries (as user objects)
for (int i = 0; i < rowCount; i++){
   // read data objects * column count.
}

boolean moreResults = readBooleanLittleEndian(in);

----

--


== OP_QUERY_SCAN

Performs scan query.

[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|int| Cache ID: Java-style hash code of the cache name.
|byte|    Flag. Pass 0 for default, or 1 to keep the value in binary form.
|Data Object| Filter object. Can be null if you are not going to filter data on the cluster. The filter class has to be added to the classpath of the server nodes.
|byte|    Filter platform:

JAVA = 1

DOTNET = 2

CPP = 3

Pass this parameter only if filter object is not null.
|int| Cursor page size.
|int| Number of partitions to query (negative to query entire cache).
|bool|    Local flag - whether this query should be executed on local node only.
|===


[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|long|    Cursor id.
|int| Row count.
|Key Data Object + Value Data Object| Records in the form of key-value pairs.

Repeat for as many times as the row count obtained in the previous parameter.
|bool|    Indicates whether more results are available to be fetched with OP_QUERY_SCAN_CURSOR_GET_PAGE.
When true, query cursor is closed automatically.
|===

[tabs]
--
tab:Request[]

[source, java]
----
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(15, OP_QUERY_SCAN, 1, out);

// Cache id
String queryCacheName = "personCache";
writeIntLittleEndian(queryCacheName.hashCode(), out);

// flags
writeByteLittleEndian(0, out);

// Filter Object
writeByteLittleEndian(101, out); // null

// Cursor page size
writeIntLittleEndian(1, out);

// Partition to query
writeIntLittleEndian(-1, out);

// local flag
out.writeBoolean(false);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

//Response header
readResponseHeader(in);

// Cursor id
long cursorId = readLongLittleEndian(in);

int rowCount = readIntLittleEndian(in);

// Read entries (as user objects)
for (int i = 0; i < rowCount; i++) {
  Object key = readDataObject(in);
  Object val = readDataObject(in);

  System.out.println("CacheEntry: " + key + ", " + val);
}

boolean moreResults = readBooleanLittleEndian(in);

----

--


== OP_QUERY_SCAN_CURSOR_GET_PAGE


Fetches the next SQL query cursor page by cursor id that is obtained from OP_QUERY_SCAN.

[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|long|    Cursor id.
|===


[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header.
|long|    Cursor id.
|long|    Row count.
|Key Data Object + Value Data Object | Records in the form of key-value pairs.

Repeat for as many times as the row count obtained in the previous parameter.
|bool|    Indicates whether more results are available to be fetched with OP_QUERY_SCAN_CURSOR_GET_PAGE.
When true, query cursor is closed automatically.
|===


== OP_RESOURCE_CLOSE

Closes a resource, such as query cursor.

[cols="1,2",opts="header"]
|===
|Request Type |    Description
|Header|  Request header.
|long|    Resource id.
|===


[cols="1,2",opts="header"]
|===
|Response Type |   Description
|Header|  Response header
|===

[tabs]
--
tab:Request[]

[source, java]
----
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Request header
writeRequestHeader(8, OP_RESOURCE_CLOSE, 1, out);

// Resource id
long cursorId = 1;
writeLongLittleEndian(cursorId, out);
----

tab:Response[]

[source, java]
----
// Read result
DataInputStream in = new DataInputStream(socket.getInputStream());

// Response header
readResponseHeader(in);

----

--
