/*
 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed 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 com.hazelcast.sql;

import com.hazelcast.nio.serialization.Portable;
import com.hazelcast.nio.serialization.PortableWriter;

import javax.annotation.Nonnull;

/**
 * Service to execute distributed SQL queries.
 * <h1>Overview</h1>
 * Hazelcast is able to execute distributed SQL queries over the following entities:
 * <ul>
 *     <li>IMap</li>
 * </ul>
 * When a query is submitted to a member, it is parsed and optimized by the {@code hazelcast-sql} module, that is based on
 * <a href="https://calcite.apache.org">Apache Calcite</a>. The {@code hazelcast-sql} must be in the classpath, otherwise
 * an exception will be thrown.
 * <p>
 * During optimization a query is converted into a direct acyclic graph (DAG) that is sent to cluster members for execution.
 * Query results are sent back to the originating member asynchronously, and returned to the user via {@link SqlResult}.
 *
 * <h1>Querying IMap</h1>
 * Every IMap instance is exposed as a table with the same name in the {@code partitioned} schema. The {@code partitioned}
 * schema is included into a default search path, therefore an IMap could be referenced in an SQL query with or without schema
 * name.
 * <h2>Column resolution</h2>
 * Every table backed by an IMap has a set of columns that are resolved automatically. Column resolution uses IMap entries
 * located on the member that initiates the query. The engine extracts columns from a key and a value, and then merges them
 * into a single column set. In case the key and the value have columns with the same name, the key takes precedence.
 * <p>
 * Columns are extracted from objects as follows:
 * <ul>
 *     <li>For non-Portable objects, public getters and fields are used to populate the column list. For getters, the first
 *     letter is converted to lower case. A getter takes precedence over a field in case of naming conflict</li>
 *     <li>For {@link Portable} objects, field names used in {@link Portable#writePortable(PortableWriter)}</li> method
 *     are used to populate the column list
 * </ul>
 * The whole key and value objects could be accessed through a special fields {@code __key} and {@code this} respectively. If
 * key (value) object has fields, then the whole key (value) field is exposed as normal field. Otherwise the field is hidden.
 * Hidden fields could be accessed directly, but are not returned by {@code SELECT * FROM ...} queries.
 * <p>
 * If the member that initiates a query doesn't have local entries for the given IMap, the query fails.
 * <p>
 * Consider the following key/value model:
 * <pre>
 *     class PersonKey {
 *         private long personId;
 *         private long deptId;
 *
 *         public long getPersonId() { ... }
 *         public long getDepartmentId() { ... }
 *     }
 *
 *     class Person {
 *         public String name;
 *     }
 * </pre>
 * This model will be resolved to the following table columns:
 * <ul>
 *     <li>personId BIGINT</li>
 *     <li>departmentId BIGINT</li>
 *     <li>name VARCHAR</li>
 *     <li>__key OBJECT (hidden)</li>
 *     <li>this OBJECT (hidden)</li>
 * </ul>
 * <h2>Consistency</h2>
 * Results returned from IMap query are weakly consistent:
 * <ul>
 *     <li>If an entry was not updated during iteration, it is guaranteed to be returned exactly once. If an en</li>
 *     <li>If an entry was modified during iteration, it might be returned zero, one or several time</li>
 * </ul>
 * <h1>Usage</h1>
 * When query is executed, an {@link SqlResult} is returned. You may get row iterator from the result. The result must be closed
 * in the end. The code snippet below demonstrates a typical usage pattern:
 * <pre>
 *     HazelcastInstance instance = ...;
 *
 *     try (SqlResult result = instance.sql().query("SELECT * FROM person")) {
 *         for (SqlRow row : result) {
 *             long personId = row.getObject("personId");
 *             String name = row.getObject("name");
 *             ...
 *         }
 *     }
 * </pre>
 */
public interface SqlService {
    /**
     * Convenient method to execute a distributed query with the given parameters.
     * <p>
     * Converts passed SQL string and parameters into an {@link SqlQuery} object and invokes {@link #query(SqlQuery)}.
     *
     * @see SqlService
     * @see SqlQuery
     * @see #query(SqlQuery)
     * @param sql SQL.
     * @param params Parameters.
     * @return Result.
     * @throws NullPointerException If sql is null
     * @throws IllegalArgumentException If sql is empty
     * @throws SqlException In case of execution error
     */
    @Nonnull
    default SqlResult query(@Nonnull String sql, Object... params) {
        SqlQuery query = new SqlQuery(sql);

        if (params != null) {
            for (Object param : params) {
                query.addParameter(param);
            }
        }

        return query(query);
    }

    /**
     * Executes a distributed query.
     *
     * @see SqlService
     * @param query Query object
     * @return Result.
     * @throws NullPointerException If query is null
     * @throws SqlException In case of execution error
     */
    @Nonnull
    SqlResult query(@Nonnull SqlQuery query);
}

@@ -1323,16 +1323,18 @@
 a direct
+ed
  acyclic
@@ -1464,17 +1464,16 @@
 ronously
-,
  and ret
@@ -1532,16 +1532,19 @@
 uerying 
+an 
 IMap%3C/h1
@@ -1791,18 +1791,22 @@
 hout
+ the%0A *
  schema
-%0A *
  nam
@@ -2062,17 +2062,16 @@
  a value
-,
  and the
@@ -2565,16 +2565,20 @@
 used in 
+the 
 %7B@link P
@@ -2615,21 +2615,16 @@
 Writer)%7D
-%3C/li%3E
  method%0A
@@ -2666,16 +2666,21 @@
 umn list
+%3C/li%3E
 %0A * %3C/ul
@@ -2789,16 +2789,17 @@
 de this%7D
+,
  respect
@@ -2889,16 +2889,18 @@
 osed as 
+a 
 normal f
@@ -2954,20 +2954,18 @@
 fields c
-ould
+an
  be acce
@@ -3928,18 +3928,8 @@
 once
-. If an en
 %3C/li
@@ -4030,16 +4030,17 @@
 ral time
+s
 %3C/li%3E%0A *
@@ -4072,16 +4072,18 @@
  * When 
+a 
 query is
@@ -4198,18 +4198,18 @@
 osed%0A * 
-in
+at
  the end

Fix typos