@@ -1346,6 +1346,304 @@ the entry processor in the ``Map`` methods. See the following example.
13461346
13471347 print (distributed_map.get(" key" )) # Outputs 'processed'
13481348
1349+ SQL
1350+ ---
1351+
1352+ The SQL service provided by Hazelcast Python client allows you to query
1353+ data stored in ``Map `` declaratively.
1354+
1355+ .. warning ::
1356+
1357+ The SQL feature is currently in beta. The compatibility between versions
1358+ is not guaranteed. API might change between versions without notice.
1359+ While in beta, the SQL feature is tested against the same major versions
1360+ of the client and the server.
1361+
1362+ **Example: How to Query a Map using SQL **
1363+
1364+ Consider that we have a map called ``emp `` that contains values of type
1365+ ``Employee ``:
1366+
1367+ .. code :: python
1368+
1369+ class Employee (Portable ):
1370+ def __init__ (self , name = None , age = None ):
1371+ self .name = name
1372+ self .age = age
1373+
1374+ def write_portable (self , writer ):
1375+ writer.write_string(" name" , self .name)
1376+ writer.write_int(" age" , self .age)
1377+
1378+ def read_portable (self , reader ):
1379+ self .name = reader.read_string(" name" )
1380+ self .age = reader.read_int(" age" )
1381+
1382+ def get_factory_id (self ):
1383+ return 1
1384+
1385+ def get_class_id (self ):
1386+ return 1
1387+
1388+ The following code prints names of the employees whose age is less than 30:
1389+
1390+ .. code :: python
1391+
1392+ result = client.sql.execute(" SELECT name FROM emp WHERE age < ?" , 30 )
1393+
1394+ for row in result:
1395+ name = row.get_object(" name" )
1396+ print (name)
1397+
1398+
1399+ Querying Map
1400+ ~~~~~~~~~~~~
1401+
1402+ The following subsections describe how you can access Hazelcast ``Map `` objects
1403+ and perform queries on them.
1404+
1405+ **Names **
1406+
1407+ The SQL service exposes ``Map `` objects as tables in the predefined
1408+ ``partitioned `` schema using exact names. This schema is in the SQL service
1409+ search path so that you can access the ``Map `` objects with or without the
1410+ schema name.
1411+
1412+ Schema and table names are case-sensitive; you can access the ``employee `` map,
1413+ for example, as ``employee `` or ``partitioned.employee ``, but not as
1414+ ``Employee ``:
1415+
1416+ .. code :: sql
1417+
1418+ SELECT * FROM employee
1419+ SELECT * FROM partitioned.employee
1420+
1421+ **Fields **
1422+
1423+ The SQL service resolves fields accessible from the SQL automatically. The
1424+ service reads the first local entry pair of the ``Map `` to construct the list
1425+ of fields. If the ``Map `` does not have local entries on the member where the
1426+ query is started, then the list of fields cannot be resolved, and an exception
1427+ is thrown.
1428+
1429+ Field names are case-sensitive.
1430+
1431+ **Key and Value Objects **
1432+
1433+ A ``Map `` entry consists of a key and a value. These are accessible through
1434+ the ``__key `` and ``this `` aliases. The following query returns the keys and
1435+ values of all entries in a map:
1436+
1437+ .. code :: sql
1438+
1439+ SELECT __key, this FROM employee
1440+
1441+ **Key and Value Fields **
1442+
1443+ You may also access the nested fields of a key or a value. The list of exposed
1444+ fields depends on the serialization format, as described below:
1445+
1446+ - For :ref: `Portable<serialization:Portable Serialization> ` objects, the fields
1447+ that are written in the
1448+ :func: `write_portable<hazelcast.serialization.api.Portable.write_portable> `
1449+ method are exposed using their exact names.
1450+ - For
1451+ :ref: `IdentifiedDataSerializable<serialization:IdentifiedDataSerializable Serialization> `
1452+ objects, the object is deserialized if needed and then analyzed using the
1453+ reflection mechanism (on the server-side). Only public fields and getters
1454+ are taken into account. See the `IMDG Reference Manual
1455+ <https://docs.hazelcast.com/imdg/latest/sql/querying-imap.html#key-and-value-fields> `__
1456+ for details.
1457+
1458+ .. note ::
1459+
1460+ You cannot query JSON fields in SQL. If you want to query JSON, see
1461+ :ref: `using_python_client_with_hazelcast_imdg:Querying with JSON Strings `
1462+ section.
1463+
1464+
1465+ Consider the ``Employee `` class from the example above; the SQL service can
1466+ access the following fields:
1467+
1468+ ==== =======
1469+ Name Type
1470+ ==== =======
1471+ name VARCHAR
1472+ age INTEGER
1473+ ==== =======
1474+
1475+ Together with the key and value objects, you may query the following fields
1476+ from the map:
1477+
1478+ .. code :: sql
1479+
1480+ SELECT __key, this, name, age FROM employee
1481+
1482+ If both the key and value have fields with the same name, then the field of
1483+ the value is exposed.
1484+
1485+ **"SELECT *" Queries **
1486+
1487+ You may use the ``SELECT * FROM <table> `` syntax to get all the table fields.
1488+
1489+ The ``__key `` and ``this `` fields are returned by the ``SELECT * `` queries if
1490+ they do not have nested fields. For the ``employee `` map, the following query
1491+ does not return the ``this `` field, because the value has nested fields
1492+ ``name `` and ``age ``:
1493+
1494+ .. code :: sql
1495+
1496+ -- Returns __key, name, age
1497+ SELECT * FROM employee
1498+
1499+ **Indexes **
1500+
1501+ The SQL service can use ``Map `` indexes to speed up the execution of certain
1502+ queries. ``SORTED `` and ``HASH `` indexes are supported.
1503+
1504+ Data Types
1505+ ~~~~~~~~~~
1506+
1507+ The SQL service supports a set of SQL data types. Every data type is mapped to
1508+ a Python type that represents the type’s value.
1509+
1510+ ======================== ===============
1511+ Type Name Python Type
1512+ ======================== ===============
1513+ BOOLEAN bool
1514+ VARCHAR str
1515+ TINYINT int
1516+ SMALLINT int
1517+ INTEGER int
1518+ BIGINT int
1519+ DECIMAL str
1520+ REAL float
1521+ DOUBLE float
1522+ DATE str
1523+ TIME str
1524+ TIMESTAMP str
1525+ TIMESTAMP_WITH_TIME_ZONE str
1526+ OBJECT Any Python type
1527+ ======================== ===============
1528+
1529+ Note that, the following types are returned as strings, with the following
1530+ formats.
1531+
1532+ - ``DATE `` with the ``YYYY-MM-DD `` format.
1533+ - ``TIME `` with the ``HH:MM:SS[.ffffff] `` format.
1534+ - ``TIMESTAMP `` with the ``YYYY-MM-DDTHH:MM:SS[.ffffff] `` format.
1535+ - ``TIMESTAMP_WITH_TIME_ZONE `` with the ``YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS] ``
1536+ - ``DECIMAL `` with the floating point number format.
1537+
1538+ If you want to use these types in queries, you have to send them as strings
1539+ and add explicit ``CAST `` to queries.
1540+
1541+ ``CAST `` operator has the following syntax:
1542+
1543+ .. code :: sql
1544+
1545+ CAST(? AS TYPE)
1546+
1547+ An example usage is shown below:
1548+
1549+ .. code :: python
1550+
1551+ client.sql.execute(" SELECT * FROM map WHERE date < CAST(? AS DATE)" , " 2021-06-02" )
1552+
1553+ SELECT
1554+ ~~~~~~
1555+
1556+ **Synopsis **
1557+
1558+ .. code :: sql
1559+
1560+ SELECT [ * | expression [ [ AS ] expression_alias ] [, ...] ]
1561+ FROM table_name [ [ AS ] table_alias ]
1562+ [WHERE condition]
1563+
1564+
1565+ **Description **
1566+
1567+ The ``SELECT `` command retrieves rows from a table. A row is a sequence of
1568+ expressions defined after the ``SELECT `` keyword. Expressions may have
1569+ optional aliases.
1570+
1571+ ``table_name `` refers to a single ``Map `` data structure. A table may have an
1572+ optional alias.
1573+
1574+ An optional ``WHERE `` clause defines a condition, that is any expression that
1575+ evaluates to a result of type boolean. Any row that doesn’t satisfy the
1576+ condition is eliminated from the result.
1577+
1578+ **Sorting **
1579+
1580+ You can use the standard SQL clauses ``ORDER BY ``, ``LIMIT ``, and ``OFFSET ``
1581+ to sort and limit the result set.
1582+
1583+
1584+ .. warning ::
1585+
1586+ Note that, you must add sorted indexes to the map object’s fields to be
1587+ sorted by. For example, for the ``SELECT * FROM persons ORDER BY name ASC ``
1588+ query, there has to be a sorted index on the ``name `` field as shown below:
1589+
1590+ .. code :: python
1591+
1592+ persons = client.get_map(" persons" )
1593+ persons.add_index(attributes = [" name" ], index_type = IndexType.SORTED )
1594+
1595+ See the below examples for sorting.
1596+
1597+ The following statement gets the top five employees ordered by the
1598+ ``first_name `` field and skipping the first three ones:
1599+
1600+ .. code :: sql
1601+
1602+ SELECT
1603+ employee_id, first_name, last_name
1604+ FROM
1605+ employees
1606+ ORDER BY first_name
1607+ LIMIT 5 OFFSET 3;
1608+
1609+
1610+ The following statement gets the top five employees with the highest salaries.
1611+
1612+ .. code :: sql
1613+
1614+ SELECT
1615+ employee_id, first_name, last_name, salary
1616+ FROM
1617+ employees
1618+ ORDER BY salary DESC
1619+ LIMIT 5;
1620+
1621+ **Unsupported Features **
1622+
1623+ The following features are **not supported ** and are planned for future releases:
1624+
1625+ - ``GROUP BY `` / ``HAVING ``
1626+ - ``JOIN ``
1627+ - set operators (``UNION ``, ``INTERSECT ``, ``MINUS ``)
1628+ - subqueries (``SELECT ... FROM table WHERE x = (SELECT …) ``)
1629+
1630+ Expressions
1631+ ~~~~~~~~~~~
1632+
1633+ Hazelcast SQL supports logical predicates, `IS ` predicates, comparison
1634+ operators, mathematical functions and operators, string functions, and special
1635+ functions.
1636+
1637+ See `IMDG Reference Manual
1638+ <https://docs.hazelcast.com/imdg/latest/sql/querying-imap.html#key-and-value-fields> `__
1639+ for details.
1640+
1641+ Lite Members
1642+ ~~~~~~~~~~~~
1643+
1644+ You cannot start SQL queries on lite members. This limitation will be removed
1645+ in future releases.
1646+
13491647Distributed Query
13501648-----------------
13511649
0 commit comments