Finish fixing the CQL doc

This commit is contained in:
Sylvain Lebresne 2016-06-24 17:01:37 +02:00
parent 7dfb25e3c2
commit 0e624238c1
18 changed files with 1506 additions and 1910 deletions

2
.gitignore vendored
View File

@ -74,4 +74,4 @@ lib/jsr223/scala/*.jar
/.ant-targets-build.xml
# Generated files from the documentation
doc/source/cassandra_config_file.rst
doc/source/configuration/cassandra_config_file.rst

View File

@ -59,7 +59,7 @@ def convert(yaml_file, dest_file):
with open(dest_file, 'w') as outfile:
outfile.write("Cassandra Configuration File\n")
outfile.write("=====================\n")
outfile.write("============================\n")
# since comments preceed an option, this holds all of the comment
# lines we've seen since the last option

View File

@ -300,8 +300,6 @@ names as their name.
+-----------------+
| ``complex`` |
+-----------------+
| ``date`` |
+-----------------+
| ``enum`` |
+-----------------+
| ``interval`` |

View File

@ -24,234 +24,166 @@ The following describes the changes in each version of CQL.
3.4.2
^^^^^
- ```INSERT/UPDATE options`` <#updateOptions>`__ for tables having a
default\_time\_to\_live specifying a TTL of 0 will remove the TTL
from the inserted or updated values
- ```ALTER TABLE`` <#alterTableStmt>`__ ``ADD`` and ``DROP`` now allow
mutiple columns to be added/removed
- New ```PER PARTITION LIMIT`` <#selectLimit>`__ option (see
`CASSANDRA-7017 <https://issues.apache.org/jira/browse/CASSANDRA-7017)>`__.
- `User-defined functions <#udfs>`__ can now instantiate ``UDTValue``
and ``TupleValue`` instances via the new ``UDFContext`` interface
(see
`CASSANDRA-10818 <https://issues.apache.org/jira/browse/CASSANDRA-10818)>`__.
- “User-defined types”#createTypeStmt may now be stored in a non-frozen
form, allowing individual fields to be updated and deleted in
```UPDATE`` statements <#updateStmt>`__ and ```DELETE``
statements <#deleteStmt>`__, respectively.
(`CASSANDRA-7423 <https://issues.apache.org/jira/browse/CASSANDRA-7423)>`__
- If a table has a non zero ``default_time_to_live``, then explicitly specifying a TTL of 0 in an ``INSERT`` or
``UPDATE`` statement will result in the new writes not having any expiration (that is, an explicit TTL of 0 cancels
the ``default_time_to_live``). This wasn't the case before and the ``default_time_to_live`` was applied even though a
TTL had been explicitly set.
- ``ALTER TABLE`` ``ADD`` and ``DROP`` now allow multiple columns to be added/removed.
- New ``PER PARTITION LIMIT`` option for ``SELECT`` statements (see `CASSANDRA-7017
<https://issues.apache.org/jira/browse/CASSANDRA-7017)>`__.
- :ref:`User-defined functions <cql-functions>` can now instantiate ``UDTValue`` and ``TupleValue`` instances via the
new ``UDFContext`` interface (see `CASSANDRA-10818 <https://issues.apache.org/jira/browse/CASSANDRA-10818)>`__.
- :ref:`User-defined types <udts>` may now be stored in a non-frozen form, allowing individual fields to be updated and
deleted in ``UPDATE`` statements and ``DELETE`` statements, respectively. (`CASSANDRA-7423
<https://issues.apache.org/jira/browse/CASSANDRA-7423)>`__).
3.4.1
^^^^^
- Adds ``CAST`` functions. See ```Cast`` <#castFun>`__.
- Adds ``CAST`` functions.
3.4.0
^^^^^
- Support for `materialized views <#createMVStmt>`__
- ```DELETE`` <#deleteStmt>`__ support for inequality expressions and
``IN`` restrictions on any primary key columns
- ```UPDATE`` <#updateStmt>`__ support for ``IN`` restrictions on any
primary key columns
- Support for :ref:`materialized views <materialized-views>`.
- ``DELETE`` support for inequality expressions and ``IN`` restrictions on any primary key columns.
- ``UPDATE`` support for ``IN`` restrictions on any primary key columns.
3.3.1
^^^^^
- The syntax ``TRUNCATE TABLE X`` is now accepted as an alias for
``TRUNCATE X``
- The syntax ``TRUNCATE TABLE X`` is now accepted as an alias for ``TRUNCATE X``.
3.3.0
^^^^^
- Adds new `aggregates <#aggregates>`__
- User-defined functions are now supported through
```CREATE FUNCTION`` <#createFunctionStmt>`__ and
```DROP FUNCTION`` <#dropFunctionStmt>`__.
- User-defined aggregates are now supported through
```CREATE AGGREGATE`` <#createAggregateStmt>`__ and
```DROP AGGREGATE`` <#dropAggregateStmt>`__.
- Allows double-dollar enclosed strings literals as an alternative to
single-quote enclosed strings.
- Introduces Roles to supercede user based authentication and access
control
- ```Date`` <#usingdates>`__ and ```Time`` <usingtime>`__ data types
have been added
- ```JSON`` <#json>`__ support has been added
- ``Tinyint`` and ``Smallint`` data types have been added
- Adds new time conversion functions and deprecate ``dateOf`` and
``unixTimestampOf``. See ```Time conversion functions`` <#timeFun>`__
- :ref:`User-defined functions and aggregates <cql-functions>` are now supported.
- Allows double-dollar enclosed strings literals as an alternative to single-quote enclosed strings.
- Introduces Roles to supersede user based authentication and access control
- New ``date``, ``time``, ``tinyint`` and ``smallint`` :ref:`data types <data-types>` have been added.
- :ref:`JSON support <cql-json>` has been added
- Adds new time conversion functions and deprecate ``dateOf`` and ``unixTimestampOf``.
3.2.0
^^^^^
- User-defined types are now supported through
```CREATE TYPE`` <#createTypeStmt>`__,
```ALTER TYPE`` <#alterTypeStmt>`__, and
```DROP TYPE`` <#dropTypeStmt>`__
- ```CREATE INDEX`` <#createIndexStmt>`__ now supports indexing
collection columns, including indexing the keys of map collections
through the ``keys()`` function
- Indexes on collections may be queried using the new ``CONTAINS`` and
``CONTAINS KEY`` operators
- Tuple types were added to hold fixed-length sets of typed positional
fields (see the section on `types <#types>`__ )
- ```DROP INDEX`` <#dropIndexStmt>`__ now supports optionally
specifying a keyspace
- :ref:`User-defined types <udts>` supported.
- ``CREATE INDEX`` now supports indexing collection columns, including indexing the keys of map collections through the
``keys()`` function
- Indexes on collections may be queried using the new ``CONTAINS`` and ``CONTAINS KEY`` operators
- :ref:`Tuple types <tuples>` were added to hold fixed-length sets of typed positional fields.
- ``DROP INDEX`` now supports optionally specifying a keyspace.
3.1.7
^^^^^
- ``SELECT`` statements now support selecting multiple rows in a single
partition using an ``IN`` clause on combinations of clustering
columns. See `SELECT WHERE <#selectWhere>`__ clauses.
- ``IF NOT EXISTS`` and ``IF EXISTS`` syntax is now supported by
``CREATE USER`` and ``DROP USER`` statmenets, respectively.
- ``SELECT`` statements now support selecting multiple rows in a single partition using an ``IN`` clause on combinations
of clustering columns.
- ``IF NOT EXISTS`` and ``IF EXISTS`` syntax is now supported by ``CREATE USER`` and ``DROP USER`` statements,
respectively.
3.1.6
^^^^^
- A new ```uuid`` method <#uuidFun>`__ has been added.
- Support for ``DELETE ... IF EXISTS`` syntax.
- A new ``uuid()`` method has been added.
- Support for ``DELETE ... IF EXISTS`` syntax.
3.1.5
^^^^^
- It is now possible to group clustering columns in a relatiion, see
`SELECT WHERE <#selectWhere>`__ clauses.
- Added support for ``STATIC`` columns, see `static in CREATE
TABLE <#createTableStatic>`__.
- It is now possible to group clustering columns in a relation, see :ref:`WHERE <where-clause>` clauses.
- Added support for :ref:`static columns <static-columns>`.
3.1.4
^^^^^
- ``CREATE INDEX`` now allows specifying options when creating CUSTOM
indexes (see `CREATE INDEX reference <#createIndexStmt>`__ ).
- ``CREATE INDEX`` now allows specifying options when creating CUSTOM indexes.
3.1.3
^^^^^
- Millisecond precision formats have been added to the timestamp parser
(see `working with dates <#usingtimestamps>`__ ).
- Millisecond precision formats have been added to the :ref:`timestamp <timestamps>` parser.
3.1.2
^^^^^
- ``NaN`` and ``Infinity`` has been added as valid float contants. They
are now reserved keywords. In the unlikely case you we using them as
a column identifier (or keyspace/table one), you will noew need to
double quote them (see `quote identifiers <#identifiers>`__ ).
- ``NaN`` and ``Infinity`` has been added as valid float constants. They are now reserved keywords. In the unlikely case
you we using them as a column identifier (or keyspace/table one), you will now need to double quote them.
3.1.1
^^^^^
- ``SELECT`` statement now allows listing the partition keys (using the
``DISTINCT`` modifier). See
`CASSANDRA-4536 <https://issues.apache.org/jira/browse/CASSANDRA-4536>`__.
- The syntax ``c IN ?`` is now supported in ``WHERE`` clauses. In that
case, the value expected for the bind variable will be a list of
whatever type ``c`` is.
- It is now possible to use named bind variables (using ``:name``
instead of ``?``).
- ``SELECT`` statement now allows listing the partition keys (using the ``DISTINCT`` modifier). See `CASSANDRA-4536
<https://issues.apache.org/jira/browse/CASSANDRA-4536>`__.
- The syntax ``c IN ?`` is now supported in ``WHERE`` clauses. In that case, the value expected for the bind variable
will be a list of whatever type ``c`` is.
- It is now possible to use named bind variables (using ``:name`` instead of ``?``).
3.1.0
^^^^^
- `ALTER TABLE <#alterTableStmt>`__ ``DROP`` option has been reenabled
for CQL3 tables and has new semantics now: the space formerly used by
dropped columns will now be eventually reclaimed (post-compaction).
You should not readd previously dropped columns unless you use
timestamps with microsecond precision (see
`CASSANDRA-3919 <https://issues.apache.org/jira/browse/CASSANDRA-3919>`__
for more details).
- ``SELECT`` statement now supports aliases in select clause. Aliases
in WHERE and ORDER BY clauses are not supported. See the `section on
select <#selectStmt>`__ for details.
- ``CREATE`` statements for ``KEYSPACE``, ``TABLE`` and ``INDEX`` now
supports an ``IF NOT EXISTS`` condition. Similarly, ``DROP``
statements support a ``IF EXISTS`` condition.
- ``INSERT`` statements optionally supports a ``IF NOT EXISTS``
condition and ``UPDATE`` supports ``IF`` conditions.
- ``ALTER TABLE`` ``DROP`` option added.
- ``SELECT`` statement now supports aliases in select clause. Aliases in WHERE and ORDER BY clauses are not supported.
- ``CREATE`` statements for ``KEYSPACE``, ``TABLE`` and ``INDEX`` now supports an ``IF NOT EXISTS`` condition.
Similarly, ``DROP`` statements support a ``IF EXISTS`` condition.
- ``INSERT`` statements optionally supports a ``IF NOT EXISTS`` condition and ``UPDATE`` supports ``IF`` conditions.
3.0.5
^^^^^
- ``SELECT``, ``UPDATE``, and ``DELETE`` statements now allow empty
``IN`` relations (see
`CASSANDRA-5626 <https://issues.apache.org/jira/browse/CASSANDRA-5626)>`__.
- ``SELECT``, ``UPDATE``, and ``DELETE`` statements now allow empty ``IN`` relations (see `CASSANDRA-5626
<https://issues.apache.org/jira/browse/CASSANDRA-5626)>`__.
3.0.4
^^^^^
- Updated the syntax for custom `secondary
indexes <#createIndexStmt>`__.
- Non-equal condition on the partition key are now never supported,
even for ordering partitioner as this was not correct (the order was
**not** the one of the type of the partition key). Instead, the
``token`` method should always be used for range queries on the
partition key (see `WHERE clauses <#selectWhere>`__ ).
- Updated the syntax for custom :ref:`secondary indexes <secondary-indexes>`.
- Non-equal condition on the partition key are now never supported, even for ordering partitioner as this was not
correct (the order was **not** the one of the type of the partition key). Instead, the ``token`` method should always
be used for range queries on the partition key (see :ref:`WHERE clauses <where-clause>`).
3.0.3
^^^^^
- Support for custom `secondary indexes <#createIndexStmt>`__ has been
added.
- Support for custom :ref:`secondary indexes <secondary-indexes>` has been added.
3.0.2
^^^^^
- Type validation for the `constants <#constants>`__ has been fixed.
For instance, the implementation used to allow ``'2'`` as a valid
value for an ``int`` column (interpreting it has the equivalent of
``2``), or ``42`` as a valid ``blob`` value (in which case ``42`` was
interpreted as an hexadecimal representation of the blob). This is no
longer the case, type validation of constants is now more strict. See
the `data types <#types>`__ section for details on which constant is
allowed for which type.
- The type validation fixed of the previous point has lead to the
introduction of `blobs constants <#constants>`__ to allow inputing
blobs. Do note that while inputing blobs as strings constant is still
supported by this version (to allow smoother transition to blob
constant), it is now deprecated (in particular the `data
types <#types>`__ section does not list strings constants as valid
blobs) and will be removed by a future version. If you were using
strings as blobs, you should thus update your client code ASAP to
switch blob constants.
- A number of functions to convert native types to blobs have also been
introduced. Furthermore the token function is now also allowed in
select clauses. See the `section on functions <#functions>`__ for
details.
- Type validation for the :ref:`constants <constants>` has been fixed. For instance, the implementation used to allow
``'2'`` as a valid value for an ``int`` column (interpreting it has the equivalent of ``2``), or ``42`` as a valid
``blob`` value (in which case ``42`` was interpreted as an hexadecimal representation of the blob). This is no longer
the case, type validation of constants is now more strict. See the :ref:`data types <data-types>` section for details
on which constant is allowed for which type.
- The type validation fixed of the previous point has lead to the introduction of blobs constants to allow the input of
blobs. Do note that while the input of blobs as strings constant is still supported by this version (to allow smoother
transition to blob constant), it is now deprecated and will be removed by a future version. If you were using strings
as blobs, you should thus update your client code ASAP to switch blob constants.
- A number of functions to convert native types to blobs have also been introduced. Furthermore the token function is
now also allowed in select clauses. See the :ref:`section on functions <cql-functions>` for details.
3.0.1
^^^^^
- `Date strings <#usingtimestamps>`__ (and timestamps) are no longer
accepted as valid ``timeuuid`` values. Doing so was a bug in the
sense that date string are not valid ``timeuuid``, and it was thus
resulting in `confusing
behaviors <https://issues.apache.org/jira/browse/CASSANDRA-4936>`__.
However, the following new methods have been added to help working
with ``timeuuid``: ``now``, ``minTimeuuid``, ``maxTimeuuid`` ,
``dateOf`` and ``unixTimestampOf``. See the `section dedicated to
these methods <#timeuuidFun>`__ for more detail.
- “Float constants”#constants now support the exponent notation. In
other words, ``4.2E10`` is now a valid floating point value.
- Date strings (and timestamps) are no longer accepted as valid ``timeuuid`` values. Doing so was a bug in the sense
that date string are not valid ``timeuuid``, and it was thus resulting in `confusing behaviors
<https://issues.apache.org/jira/browse/CASSANDRA-4936>`__. However, the following new methods have been added to help
working with ``timeuuid``: ``now``, ``minTimeuuid``, ``maxTimeuuid`` ,
``dateOf`` and ``unixTimestampOf``.
- Float constants now support the exponent notation. In other words, ``4.2E10`` is now a valid floating point value.
Versioning
^^^^^^^^^^
Versioning of the CQL language adheres to the `Semantic
Versioning <http://semver.org>`__ guidelines. Versions take the form
X.Y.Z where X, Y, and Z are integer values representing major, minor,
and patch level respectively. There is no correlation between Cassandra
release versions and the CQL language version.
Versioning of the CQL language adheres to the `Semantic Versioning <http://semver.org>`__ guidelines. Versions take the
form X.Y.Z where X, Y, and Z are integer values representing major, minor, and patch level respectively. There is no
correlation between Cassandra release versions and the CQL language version.
+-----------+-------------------------------------------------------------------------------------------------------------------+
| version | description |
+===========+===================================================================================================================+
| Major | The major version *must* be bumped when backward incompatible changes are introduced. This should rarely occur. |
+-----------+-------------------------------------------------------------------------------------------------------------------+
| Minor | Minor version increments occur when new, but backward compatible, functionality is introduced. |
+-----------+-------------------------------------------------------------------------------------------------------------------+
| Patch | The patch version is incremented when bugs are fixed. |
+-----------+-------------------------------------------------------------------------------------------------------------------+
========= =============================================================================================================
version description
========= =============================================================================================================
Major The major version *must* be bumped when backward incompatible changes are introduced. This should rarely
occur.
Minor Minor version increments occur when new, but backward compatible, functionality is introduced.
Patch The patch version is incremented when bugs are fixed.
========= =============================================================================================================

View File

@ -76,7 +76,6 @@ For instance::
AND durable_writes = false;
.. _create-keyspace-options:
The supported ``options`` are:
=================== ========== =========== ========= ===================================================================
@ -127,9 +126,9 @@ An ``ALTER KEYSPACE`` statement allows to modify the options of a keyspace:
For instance::
ALTER KEYSPACE Excelsior
WITH replication = {class: SimpleStrategy, replication_factor : 4};
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 4};
The supported options are the same than for :ref:`creating a keyspace <create-keyspace-options>`.
The supported options are the same than for :ref:`creating a keyspace <create-keyspace-statement>`.
.. _drop-keyspace-statement:
@ -182,7 +181,7 @@ For instance::
common_name text,
population varint,
average_size int
) WITH comment=Important biological records
) WITH comment='Important biological records'
AND read_repair_chance = 1.0;
CREATE TABLE timeline (
@ -192,7 +191,7 @@ For instance::
body text,
posted_by text,
PRIMARY KEY (userid, posted_month, posted_time)
) WITH compaction = { class : LeveledCompactionStrategy };
) WITH compaction = { 'class' : 'LeveledCompactionStrategy' };
CREATE TABLE loads (
machine inet,
@ -373,7 +372,7 @@ retrieval of a range of rows within a partition (for instance, in the example ab
> 1 and b <= 3``) very efficient.
.. _create-table-options
.. _create-table-options:
Table options
~~~~~~~~~~~~~
@ -385,7 +384,7 @@ Amongst those options, two important ones cannot be changed after creation and i
against the table: the ``COMPACT STORAGE`` option and the ``CLUSTERING ORDER`` option. Those, as well as the other
options of a table are described in the following sections.
.. _compact-storage:
.. _compact-tables:
Compact tables
``````````````
@ -393,7 +392,7 @@ Compact tables
.. warning:: Since Cassandra 3.0, compact tables have the exact same layout internally than non compact ones (for the
same schema obviously), and declaring a table compact **only** creates artificial limitations on the table definition
and usage that are necessary to ensure backward compatibility with the deprecated Thrift API. And as ``COMPACT
STORAGE`` cannot, as of Cassandra |3.8|, be removed, it is strongly discouraged to create new table with the
STORAGE`` cannot, as of Cassandra |version|, be removed, it is strongly discouraged to create new table with the
``COMPACT STORAGE`` option.
A *compact* table is one defined with the ``COMPACT STORAGE`` option. This option is mainly targeted towards backward
@ -445,116 +444,108 @@ Other table options
A table supports the following options:
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| option | kind | default | description |
+==================================+============+===============+=================================================================================================================================================================================================================================+
| ``comment`` | *simple* | none | A free-form, human-readable comment. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``read_repair_chance`` | *simple* | 0.1 | The probability with which to query extra nodes (e.g. more nodes than required by the consistency level) for the purpose of read repairs. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``dclocal_read_repair_chance`` | *simple* | 0 | The probability with which to query extra nodes (e.g. more nodes than required by the consistency level) belonging to the same data center than the read coordinator for the purpose of read repairs. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``gc_grace_seconds`` | *simple* | 864000 | Time to wait before garbage collecting tombstones (deletion markers). |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``bloom_filter_fp_chance`` | *simple* | 0.00075 | The target probability of false positive of the sstable bloom filters. Said bloom filters will be sized to provide the provided probability (thus lowering this value impact the size of bloom filters in-memory and on-disk) |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``default_time_to_live`` | *simple* | 0 | The default expiration time (“TTL”) in seconds for a table. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``compaction`` | *map* | *see below* | Compaction options, see “below”:#compactionOptions. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``compression`` | *map* | *see below* | Compression options, see “below”:#compressionOptions. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``caching`` | *map* | *see below* | Caching options, see “below”:#cachingOptions. |
+----------------------------------+------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| option | kind | default | description |
+================================+==========+=============+===========================================================+
| ``comment`` | *simple* | none | A free-form, human-readable comment. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``read_repair_chance`` | *simple* | 0.1 | The probability with which to query extra nodes (e.g. |
| | | | more nodes than required by the consistency level) for |
| | | | the purpose of read repairs. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``dclocal_read_repair_chance`` | *simple* | 0 | The probability with which to query extra nodes (e.g. |
| | | | more nodes than required by the consistency level) |
| | | | belonging to the same data center than the read |
| | | | coordinator for the purpose of read repairs. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``gc_grace_seconds`` | *simple* | 864000 | Time to wait before garbage collecting tombstones |
| | | | (deletion markers). |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``bloom_filter_fp_chance`` | *simple* | 0.00075 | The target probability of false positive of the sstable |
| | | | bloom filters. Said bloom filters will be sized to provide|
| | | | the provided probability (thus lowering this value impact |
| | | | the size of bloom filters in-memory and on-disk) |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``default_time_to_live`` | *simple* | 0 | The default expiration time (“TTL”) in seconds for a |
| | | | table. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``compaction`` | *map* | *see below* | :ref:`Compaction options <cql-compaction-options>`. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``compression`` | *map* | *see below* | :ref:`Compression options <cql-compression-options>`. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
| ``caching`` | *map* | *see below* | :ref:`Caching options <cql-caching-options>`. |
+--------------------------------+----------+-------------+-----------------------------------------------------------+
.. _cql-compaction-options:
Compaction options
##################
The ``compaction`` property must at least define the ``'class'``
sub-option, that defines the compaction strategy class to use. The
default supported class are ``'SizeTieredCompactionStrategy'``,
``'LeveledCompactionStrategy'``, ``'DateTieredCompactionStrategy'`` and
``'TimeWindowCompactionStrategy'``. Custom strategy can be provided by
specifying the full class name as a `string constant <#constants>`__.
The rest of the sub-options depends on the chosen class. The sub-options
supported by the default classes are:
The ``compaction`` options must at least define the ``'class'`` sub-option, that defines the compaction strategy class
to use. The default supported class are ``'SizeTieredCompactionStrategy'`` (:ref:`STCS <STCS>`),
``'LeveledCompactionStrategy'`` (:ref:`LCS <LCS>`) and ``'TimeWindowCompactionStrategy'`` (:ref:`TWCS <TWCS>`) (the
``'DateTieredCompactionStrategy'`` is also supported but is deprecated and ``'TimeWindowCompactionStrategy'`` should be
preferred instead). Custom strategy can be provided by specifying the full class name as a :ref:`string constant
<constants>`.
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| option | supported compaction strategy | default | description |
+======================================+=================================+================+========================================================================================================================================================================================================================================================================================================================================+
| ``enabled`` | *all* | true | A boolean denoting whether compaction should be enabled or not. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``tombstone_threshold`` | *all* | 0.2 | A ratio such that if a sstable has more than this ratio of gcable tombstones over all contained columns, the sstable will be compacted (with no other sstables) for the purpose of purging those tombstones. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``tombstone_compaction_interval`` | *all* | 1 day | The minimum time to wait after an sstable creation time before considering it for “tombstone compaction”, where “tombstone compaction” is the compaction triggered if the sstable has more gcable tombstones than ``tombstone_threshold``. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``unchecked_tombstone_compaction`` | *all* | false | Setting this to true enables more aggressive tombstone compactions - single sstable tombstone compactions will run without checking how likely it is that they will be successful. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``min_sstable_size`` | SizeTieredCompactionStrategy | 50MB | The size tiered strategy groups SSTables to compact in buckets. A bucket groups SSTables that differs from less than 50% in size. However, for small sizes, this would result in a bucketing that is too fine grained. ``min_sstable_size`` defines a size threshold (in bytes) below which all SSTables belong to one unique bucket |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``min_threshold`` | SizeTieredCompactionStrategy | 4 | Minimum number of SSTables needed to start a minor compaction. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``max_threshold`` | SizeTieredCompactionStrategy | 32 | Maximum number of SSTables processed by one minor compaction. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``bucket_low`` | SizeTieredCompactionStrategy | 0.5 | Size tiered consider sstables to be within the same bucket if their size is within [average\_size \* ``bucket_low``, average\_size \* ``bucket_high`` ] (i.e the default groups sstable whose sizes diverges by at most 50%) |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``bucket_high`` | SizeTieredCompactionStrategy | 1.5 | Size tiered consider sstables to be within the same bucket if their size is within [average\_size \* ``bucket_low``, average\_size \* ``bucket_high`` ] (i.e the default groups sstable whose sizes diverges by at most 50%). |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``sstable_size_in_mb`` | LeveledCompactionStrategy | 5MB | The target size (in MB) for sstables in the leveled strategy. Note that while sstable sizes should stay less or equal to ``sstable_size_in_mb``, it is possible to exceptionally have a larger sstable as during compaction, data for a given partition key are never split into 2 sstables |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``timestamp_resolution`` | DateTieredCompactionStrategy | MICROSECONDS | The timestamp resolution used when inserting data, could be MILLISECONDS, MICROSECONDS etc (should be understandable by Java TimeUnit) - dont change this unless you do mutations with USING TIMESTAMP (or equivalent directly in the client) |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``base_time_seconds`` | DateTieredCompactionStrategy | 60 | The base size of the time windows. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``max_sstable_age_days`` | DateTieredCompactionStrategy | 365 | SSTables only containing data that is older than this will never be compacted. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``timestamp_resolution`` | TimeWindowCompactionStrategy | MICROSECONDS | The timestamp resolution used when inserting data, could be MILLISECONDS, MICROSECONDS etc (should be understandable by Java TimeUnit) - dont change this unless you do mutations with USING TIMESTAMP (or equivalent directly in the client) |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``compaction_window_unit`` | TimeWindowCompactionStrategy | DAYS | The Java TimeUnit used for the window size, set in conjunction with ``compaction_window_size``. Must be one of DAYS, HOURS, MINUTES |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``compaction_window_size`` | TimeWindowCompactionStrategy | 1 | The number of ``compaction_window_unit`` units that make up a time window. |
+--------------------------------------+---------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
All default strategies support a number of :ref:`common options <compaction-options>`, as well as options specific to
the strategy chosen (see the section corresponding to your strategy for details: :ref:`STCS <stcs-options>`, :ref:`LCS
<lcs-options>` and :ref:`TWCS <TWCS>`).
.. _cql-compression-options:
Compression options
###################
For the ``compression`` property, the following sub-options are
The ``compression`` options define if and how the sstables of the table are compressed. The following sub-options are
available:
+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| option | default | description |
+========================+=================+=======================================================================================================================================================================================================================================================================================================================================================================================================================+
| ``class`` | LZ4Compressor | The compression algorithm to use. Default compressor are: LZ4Compressor, SnappyCompressor and DeflateCompressor. Use ``'enabled' : false`` to disable compression. Custom compressor can be provided by specifying the full class name as a “string constant”:#constants. |
+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``enabled`` | true | By default compression is enabled. To disable it, set ``enabled`` to ``false`` |
+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|`` chunk_length_in_kb`` | 64KB | On disk SSTables are compressed by block (to allow random reads). This defines the size (in KB) of said block. Bigger values may improve the compression rate, but increases the minimum size of data to be read from disk for a read |
+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``crc_check_chance`` | 1.0 | When compression is enabled, each compressed block includes a checksum of that block for the purpose of detecting disk bitrot and avoiding the propagation of corruption to other replica. This option defines the probability with which those checksums are checked during read. By default they are always checked. Set to 0 to disable checksum checking and to 0.5 for instance to check them every other read |
+------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
========================= =============== =============================================================================
Option Default Description
========================= =============== =============================================================================
``class`` LZ4Compressor The compression algorithm to use. Default compressor are: LZ4Compressor,
SnappyCompressor and DeflateCompressor. Use ``'enabled' : false`` to disable
compression. Custom compressor can be provided by specifying the full class
name as a “string constant”:#constants.
``enabled`` true Enable/disable sstable compression.
``chunk_length_in_kb`` 64KB On disk SSTables are compressed by block (to allow random reads). This
defines the size (in KB) of said block. Bigger values may improve the
compression rate, but increases the minimum size of data to be read from disk
for a read
``crc_check_chance`` 1.0 When compression is enabled, each compressed block includes a checksum of
that block for the purpose of detecting disk bitrot and avoiding the
propagation of corruption to other replica. This option defines the
probability with which those checksums are checked during read. By default
they are always checked. Set to 0 to disable checksum checking and to 0.5 for
instance to check them every other read |
========================= =============== =============================================================================
.. _cql-caching-options:
Caching options
###############
For the ``caching`` property, the following sub-options are available:
The ``caching`` options allows to configure both the *key cache* and the *row cache* for the table. The following
sub-options are available:
+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| option | default | description |
+==========================+===========+============================================================================================================================================================================================================================================================================+
| ``keys`` | ALL | Whether to cache keys (“key cache”) for this table. Valid values are: ``ALL`` and ``NONE``. |
+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``rows_per_partition`` | NONE | The amount of rows to cache per partition (“row cache”). If an integer ``n`` is specified, the first ``n`` queried rows of a partition will be cached. Other possible options are ``ALL``, to cache all rows of a queried partition, or ``NONE`` to disable row caching. |
+--------------------------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
======================== ========= ====================================================================================
Option Default Description
======================== ========= ====================================================================================
``keys`` ALL Whether to cache keys (“key cache”) for this table. Valid values are: ``ALL`` and
``NONE``.
``rows_per_partition`` NONE The amount of rows to cache per partition (“row cache”). If an integer ``n`` is
specified, the first ``n`` queried rows of a partition will be cached. Other
possible options are ``ALL``, to cache all rows of a queried partition, or ``NONE``
to disable row caching.
======================== ========= ====================================================================================
Other considerations:
#####################
- When `inserting <#insertStmt>`__ / `updating <#updateStmt>`__ a given
row, not all columns needs to be defined (except for those part of
the key), and missing columns occupy no space on disk. Furthermore,
adding new columns (see \ ``ALTER TABLE``\ ) is a constant time
operation. There is thus no need to try to anticipate future usage
(or to cry when you havent) when creating a table.
- Adding new columns (see ``ALTER TABLE`` below) is a constant time operation. There is thus no need to try to
anticipate future usage when creating a table.
.. _alter-table-statement:
ALTER TABLE
^^^^^^^^^^^
@ -575,7 +566,7 @@ For instance::
ALTER TABLE addamsFamily ADD gravesite varchar;
ALTER TABLE addamsFamily
WITH comment = A most excellent and useful table
WITH comment = 'A most excellent and useful table'
AND read_repair_chance = 0.2;
The ``ALTER TABLE`` statement can:
@ -587,10 +578,12 @@ The ``ALTER TABLE`` statement can:
compatibility table <alter-table-type-compatibility>` below for detail on which type changes are accepted.
- Add new column(s) to the table (through the ``ADD`` instruction). Note that the primary key of a table cannot be
changed and thus newly added column will, by extension, never be part of the primary key. Also note that :ref:`compact
tables <compact-tables>` have restrictions regarding column addition.
tables <compact-tables>` have restrictions regarding column addition. Note that this is constant (in the amount of
data the cluster contains) time operation.
- Remove column(s) from the table. This drops both the column and all its content, but note that while the column
becomes immediately unavailable, its content is only removed lazily during compaction. Please also see the warnings
below.
below. Due to lazy removal, the altering itself is a constant (in the amount of data removed or contained in the
cluster) time operation.
- Change some of the table options (through the ``WITH`` instruction). The :ref:`supported options
<create-table-options>` are the same that when creating a table (outside of ``COMPACT STORAGE`` and ``CLUSTERING
ORDER`` that cannot be changed after creation). Note that setting any ``compaction`` sub-options has the effect of
@ -603,7 +596,7 @@ The ``ALTER TABLE`` statement can:
convention. Please be aware that if you do so, dropping a column will not work correctly.
.. warning:: Once a column is dropped, it is allowed to re-add a column with the same name than the dropped one
**unless* the type of the dropped column was a (non-frozen) column (due to an internal technical limitation).
**unless** the type of the dropped column was a (non-frozen) column (due to an internal technical limitation).
.. _alter-table-type-compatibility:
@ -648,35 +641,32 @@ Clustering columns have stricter requirements, only the following conversions ar
| ascii, text | varchar |
+------------------------+-------------------+
.. _drop-table-statement:
DROP TABLE
^^^^^^^^^^
*Syntax:*
Dropping a table uses the ``DROP TABLE`` statement:
bc(syntax). ::= DROP TABLE ( IF EXISTS )?
.. productionlist::
drop_table_statement: DROP TABLE [ IF EXISTS ] `table_name`
*Sample:*
Dropping a table results in the immediate, irreversible removal of the table, including all data it contains.
bc(sample). DROP TABLE worldSeriesAttendees;
If the table does not exist, the statement will return an error, unless ``IF EXISTS`` is used in which case the
operation is a no-op.
The ``DROP TABLE`` statement results in the immediate, irreversible
removal of a table, including all data contained in it. As for table
creation, ``DROP COLUMNFAMILY`` is allowed as an alias for
``DROP TABLE``.
If the table does not exist, the statement will return an error, unless
``IF EXISTS`` is used in which case the operation is a no-op.
.. _truncate-statement:
TRUNCATE
^^^^^^^^
*Syntax:*
A table can be truncated using the ``TRUNCATE`` statement:
bc(syntax). ::= TRUNCATE ( TABLE \| COLUMNFAMILY )?
.. productionlist::
truncate_statement: TRUNCATE [ TABLE ] `table_name`
*Sample:*
bc(sample). TRUNCATE superImportantData;
The ``TRUNCATE`` statement permanently removes all data from a table.
Note that ``TRUNCATE TABLE foo`` is allowed for consistency with other DDL statements but tables are the only object
that can be truncated currently and so the ``TABLE`` keyword can be omitted.
Truncating a table permanently removes all existing data from the table, but without removing the table itself.

View File

@ -14,6 +14,8 @@
.. See the License for the specific language governing permissions and
.. limitations under the License.
.. _UUID: https://en.wikipedia.org/wiki/Universally_unique_identifier
Definitions
-----------
@ -126,8 +128,8 @@ A term is thus one of:
- A :ref:`constant <constants>`.
- A literal for either :ref:`a collection <collections>`, :ref:`a user-defined type <udts>` or :ref:`a tuple <tuples>`
(see the linked sections for details).
- A function call: see :ref:`the section on functions <functions>` for details on which :ref:`native function
<native-functions>` exists and how to define your own :ref:`user-defined ones <user-defined-functions>`.
- A function call: see :ref:`the section on functions <cql-functions>` for details on which :ref:`native function
<native-functions>` exists and how to define your own :ref:`user-defined ones <udfs>`.
- A *type hint*: see the :ref:`related section <type-hints>` for details.
- A bind marker, which denotes a variable to be bound at execution time. See the section on :ref:`prepared-statements`
for details. A bind marker can be either anonymous (``?``) or named (``:some_name``). The latter form provides a more
@ -155,11 +157,13 @@ CQL consists of statements that can be divided in the following categories:
- :ref:`data-definition` statements, to define and change how the data is stored (keyspaces and tables).
- :ref:`data-manipulation` statements, for selecting, inserting and deleting data.
- :ref:`index-and-views` statements.
- :ref:`roles-and-permissions` statements.
- :ref:`udfs` statements.
- :ref:`secondary-indexes` statements.
- :ref:`materialized-views` statements.
- :ref:`cql-roles` statements.
- :ref:`cql-permissions` statements.
- :ref:`User-Defined Functions <udfs>` statements.
- :ref:`udts` statements.
- :ref:`triggers` statements.
- :ref:`cql-triggers` statements.
All the statements are listed below and are described in the rest of this documentation (see links above):
@ -167,7 +171,8 @@ All the statements are listed below and are described in the rest of this docume
cql_statement: `statement` [ ';' ]
statement: `ddl_statement`
: | `dml_statement`
: | `index_or_view_statement`
: | `secondary_index_statement`
: | `materialized_view_statement`
: | `role_or_permission_statement`
: | `udf_statement`
: | `udt_statement`
@ -185,10 +190,10 @@ All the statements are listed below and are described in the rest of this docume
: | `update_statement`
: | `delete_statement`
: | `batch_statement`
index_or_view_statement: `create_index_statement`
: | `drop_index_statement`
: | `create_materialized_view_statement`
: | `drop_materialized_view_statement`
secondary_index_statement: `create_index_statement`
: | `drop_index_statement`
materialized_view_statement: `create_materialized_view_statement`
: | `drop_materialized_view_statement`
role_or_permission_statement: `create_role_statement`
: | `alter_role_statement`
: | `drop_role_statement`

View File

@ -21,586 +21,478 @@
Data Manipulation
-----------------
This section describes the statements supported by CQL to insert, update, delete and query data.
.. _select-statement:
SELECT
^^^^^^
*Syntax:*
Querying data from data is done using a ``SELECT`` statement:
| bc(syntax)..
| ::= SELECT ( JSON )?
| FROM
| ( WHERE )?
| ( ORDER BY )?
| ( PER PARTITION LIMIT )?
| ( LIMIT )?
| ( ALLOW FILTERING )?
.. productionlist::
select_statement: SELECT [ JSON | DISTINCT ] ( `select_clause` | '*' )
: FROM `table_name`
: [ WHERE `where_clause` ]
: [ ORDER BY `ordering_clause` ]
: [ PER PARTITION LIMIT (`integer` | `bind_marker`) ]
: [ LIMIT (`integer` | `bind_marker`) ]
: [ ALLOW FILTERING ]
select_clause: `selector` [ AS `identifier` ] ( ',' `selector` [ AS `identifier` ] )
selector: `identifier`
: | `term`
: | CAST '(' `selector` AS `cql_type` ')'
: | `function_name` '(' [ `selector` ( ',' `selector` )* ] ')'
: | COUNT '(' '*' ')'
where_clause: `relation` ( AND `relation` )*
relation: `identifier` `operator` `term`
: '(' `identifier` ( ',' `identifier` )* ')' `operator` `tuple_literal`
: TOKEN '(' `identifier` ( ',' `identifier` )* ')' `operator` `term`
operator: '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | CONTAINS | CONTAINS KEY
ordering_clause: `identifier` [ ASC | DESC ] ( ',' `identifier` [ ASC | DESC ] )*
| ::= DISTINCT?
| \| COUNT ( ( \* \| 1 ) ) (AS )?
For instance::
| ::= (AS )? ( , (AS )? )\*
| \| \*
SELECT name, occupation FROM users WHERE userid IN (199, 200, 207);
SELECT JSON name, occupation FROM users WHERE userid = 199;
SELECT name AS user_name, occupation AS user_occupation FROM users;
| ::=
| \| WRITETIME ( )
| \| TTL ( )
| \| CAST ( AS )
| \| ( ( (, )\*)? )
SELECT time, value
FROM events
WHERE event_type = 'myEvent'
AND time > '2011-02-03'
AND time <= '2012-01-01'
::= ( AND )\*
SELECT COUNT (*) AS user_count FROM users;
| ::=
| \| ( (, )\* )
| \| IN ( ( ( , )\* )? )
| \| ( (, )\* ) IN ( ( ( , )\* )? )
| \| TOKEN ( ( , )\* )
The ``SELECT`` statements reads one or more columns for one or more rows in a table. It returns a result-set of the rows
matching the request, where each row contains the values for the selection corresponding to the query. Additionally,
:ref:`functions <cql-functions>` including :ref:`aggregation <aggregate-functions>` ones can be applied to the result.
| ::= = \| < \| > \| <= \| >= \| CONTAINS \| CONTAINS KEY
| ::= ( , )\*
| ::= ( ASC \| DESC )?
| ::= ( (, )\* )
| p.
| *Sample:*
A ``SELECT`` statement contains at least a :ref:`selection clause <selection-clause>` and the name of the table on which
the selection is on (note that CQL does **not** joins or sub-queries and thus a select statement only apply to a single
table). In most case, a select will also have a :ref:`where clause <where-clause>` and it can optionally have additional
clauses to :ref:`order <ordering-clause>` or :ref:`limit <limit-clause>` the results. Lastly, :ref:`queries that require
filtering <allow-filtering>` can be allowed if the ``ALLOW FILTERING`` flag is provided.
| bc(sample)..
| SELECT name, occupation FROM users WHERE userid IN (199, 200, 207);
.. _selection-clause:
SELECT JSON name, occupation FROM users WHERE userid = 199;
Selection clause
~~~~~~~~~~~~~~~~
SELECT name AS user\_name, occupation AS user\_occupation FROM users;
The :token:`select_clause` determines which columns needs to be queried and returned in the result-set, as well as any
transformation to apply to this result before returning. It consists of a comma-separated list of *selectors* or,
alternatively, of the wildcard character (``*``) to select all the columns defined in the table.
| SELECT time, value
| FROM events
| WHERE event\_type = myEvent
| AND time > 2011-02-03
| AND time <= 2012-01-01
Selectors
`````````
SELECT COUNT (\*) FROM users;
A :token:`selector` can be one of:
SELECT COUNT (\*) AS user\_count FROM users;
- A column name of the table selected, to retrieve the values for that column.
- A term, which is usually used nested inside other selectors like functions (if a term is selected directly, then the
corresponding column of the result-set will simply have the value of this term for every row returned).
- A casting, which allows to convert a nested selector to a (compatible) type.
- A function call, where the arguments are selector themselves. See the section on :ref:`functions <cql-functions>` for
more details.
- The special call ``COUNT(*)`` to the :ref:`COUNT function <count-function>`, which counts all non-null results.
The ``SELECT`` statements reads one or more columns for one or more rows
in a table. It returns a result-set of rows, where each row contains the
collection of columns corresponding to the query. If the ``JSON``
keyword is used, the results for each row will contain only a single
column named “json”. See the section on
```SELECT JSON`` <#selectJson>`__ for more details.
Aliases
```````
``<select-clause>``
~~~~~~~~~~~~~~~~~~~
Every *top-level* selector can also be aliased (using `AS`). If so, the name of the corresponding column in the result
set will be that of the alias. For instance::
The ``<select-clause>`` determines which columns needs to be queried and
returned in the result-set. It consists of either the comma-separated
list of or the wildcard character (``*``) to select all the columns
defined for the table.
// Without alias
SELECT intAsBlob(4) FROM t;
A ``<selector>`` is either a column name to retrieve or a ``<function>``
of one or more ``<term>``\ s. The function allowed are the same as for
``<term>`` and are described in the `function section <#functions>`__.
In addition to these generic functions, the ``WRITETIME`` (resp.
``TTL``) function allows to select the timestamp of when the column was
inserted (resp. the time to live (in seconds) for the column (or null if
the column has no expiration set)) and the ```CAST`` <#castFun>`__
function can be used to convert one data type to another.
// intAsBlob(4)
// --------------
// 0x00000004
Any ``<selector>`` can be aliased using ``AS`` keyword (see examples).
Please note that ``<where-clause>`` and ``<order-by>`` clause should
refer to the columns by their original names and not by their aliases.
// With alias
SELECT intAsBlob(4) AS four FROM t;
The ``COUNT`` keyword can be used with parenthesis enclosing ``*``. If
so, the query will return a single result: the number of rows matching
the query. Note that ``COUNT(1)`` is supported as an alias.
// four
// ------------
// 0x00000004
``<where-clause>``
.. note:: Currently, aliases aren't recognized anywhere else in the statement where they are used (not in the ``WHERE``
clause, not in the ``ORDER BY`` clause, ...). You must use the orignal column name instead.
``WRITETIME`` and ``TTL`` function
```````````````````````````````````
Selection supports two special functions (that aren't allowed anywhere else): ``WRITETIME`` and ``TTL``. Both function
take only one argument and that argument *must* be a column name (so for instance ``TTL(3)`` is invalid).
Those functions allow to retrieve meta-information that are stored internally for each column, namely:
- the timestamp of the value of the column for ``WRITETIME``.
- the remaining time to live (in seconds) for the value of the column if it set to expire (and ``null`` otherwise).
.. _where-clause:
The ``WHERE`` clause
~~~~~~~~~~~~~~~~~~~~
The ``WHERE`` clause specifies which rows must be queried. It is composed of relations on the columns that are part of
the ``PRIMARY KEY`` and/or have a `secondary index <#createIndexStmt>`__ defined on them.
Not all relations are allowed in a query. For instance, non-equal relations (where ``IN`` is considered as an equal
relation) on a partition key are not supported (but see the use of the ``TOKEN`` method below to do non-equal queries on
the partition key). Moreover, for a given partition key, the clustering columns induce an ordering of rows and relations
on them is restricted to the relations that allow to select a **contiguous** (for the ordering) set of rows. For
instance, given::
CREATE TABLE posts (
userid text,
blog_title text,
posted_at timestamp,
entry_title text,
content text,
category int,
PRIMARY KEY (userid, blog_title, posted_at)
)
The following query is allowed::
SELECT entry_title, content FROM posts
WHERE userid = 'john doe'
AND blog_title='John''s Blog'
AND posted_at >= '2012-01-01' AND posted_at < '2012-01-31'
But the following one is not, as it does not select a contiguous set of rows (and we suppose no secondary indexes are
set)::
// Needs a blog_title to be set to select ranges of posted_at
SELECT entry_title, content FROM posts
WHERE userid = 'john doe'
AND posted_at >= '2012-01-01' AND posted_at < '2012-01-31'
When specifying relations, the ``TOKEN`` function can be used on the ``PARTITION KEY`` column to query. In that case,
rows will be selected based on the token of their ``PARTITION_KEY`` rather than on the value. Note that the token of a
key depends on the partitioner in use, and that in particular the RandomPartitioner won't yield a meaningful order. Also
note that ordering partitioners always order token values by bytes (so even if the partition key is of type int,
``token(-1) > token(0)`` in particular). Example::
SELECT * FROM posts
WHERE token(userid) > token('tom') AND token(userid) < token('bob')
Moreover, the ``IN`` relation is only allowed on the last column of the partition key and on the last column of the full
primary key.
It is also possible to “group” ``CLUSTERING COLUMNS`` together in a relation using the tuple notation. For instance::
SELECT * FROM posts
WHERE userid = 'john doe'
AND (blog_title, posted_at) > ('John''s Blog', '2012-01-01')
will request all rows that sorts after the one having “John's Blog” as ``blog_tile`` and '2012-01-01' for ``posted_at``
in the clustering order. In particular, rows having a ``post_at <= '2012-01-01'`` will be returned as long as their
``blog_title > 'John''s Blog'``, which would not be the case for::
SELECT * FROM posts
WHERE userid = 'john doe'
AND blog_title > 'John''s Blog'
AND posted_at > '2012-01-01'
The tuple notation may also be used for ``IN`` clauses on clustering columns::
SELECT * FROM posts
WHERE userid = 'john doe'
AND (blog_title, posted_at) IN (('John''s Blog', '2012-01-01), ('Extreme Chess', '2014-06-01'))
The ``CONTAINS`` operator may only be used on collection columns (lists, sets, and maps). In the case of maps,
``CONTAINS`` applies to the map values. The ``CONTAINS KEY`` operator may only be used on map columns and applies to the
map keys.
.. _ordering-clause:
Ordering results
~~~~~~~~~~~~~~~~
The ``ORDER BY`` clause allows to select the order of the returned results. It takes as argument a list of column names
along with the order for the column (``ASC`` for ascendant and ``DESC`` for descendant, omitting the order being
equivalent to ``ASC``). Currently the possible orderings are limited by the :ref:`clustering order <clustering-order>`
defined on the table:
- if the table has been defined without any specific ``CLUSTERING ORDER``, then then allowed orderings are the order
induced by the clustering columns and the reverse of that one.
- otherwise, the orderings allowed are the order of the ``CLUSTERING ORDER`` option and the reversed one.
.. _limit-clause:
Limiting results
~~~~~~~~~~~~~~~~
The ``LIMIT`` option to a ``SELECT`` statement limits the number of rows returned by a query, while the ``PER PARTITION
LIMIT`` option limits the number of rows returned for a given partition by the query. Note that both type of limit can
used in the same statement.
.. _allow-filtering:
Allowing filtering
~~~~~~~~~~~~~~~~~~
The ``<where-clause>`` specifies which rows must be queried. It is
composed of relations on the columns that are part of the
``PRIMARY KEY`` and/or have a `secondary index <#createIndexStmt>`__
defined on them.
By default, CQL only allows select queries that don't involve “filtering” server side, i.e. queries where we know that
all (live) record read will be returned (maybe partly) in the result set. The reasoning is that those “non filtering”
queries have predictable performance in the sense that they will execute in a time that is proportional to the amount of
data **returned** by the query (which can be controlled through ``LIMIT``).
Not all relations are allowed in a query. For instance, non-equal
relations (where ``IN`` is considered as an equal relation) on a
partition key are not supported (but see the use of the ``TOKEN`` method
below to do non-equal queries on the partition key). Moreover, for a
given partition key, the clustering columns induce an ordering of rows
and relations on them is restricted to the relations that allow to
select a **contiguous** (for the ordering) set of rows. For instance,
given
The ``ALLOW FILTERING`` option allows to explicitly allow (some) queries that require filtering. Please note that a
query using ``ALLOW FILTERING`` may thus have unpredictable performance (for the definition above), i.e. even a query
that selects a handful of records **may** exhibit performance that depends on the total amount of data stored in the
cluster.
| bc(sample).
| CREATE TABLE posts (
| userid text,
| blog\_title text,
| posted\_at timestamp,
| entry\_title text,
| content text,
| category int,
| PRIMARY KEY (userid, blog\_title, posted\_at)
| )
For instance, considering the following table holding user profiles with their year of birth (with a secondary index on
it) and country of residence::
The following query is allowed:
CREATE TABLE users (
username text PRIMARY KEY,
firstname text,
lastname text,
birth_year int,
country text
)
| bc(sample).
| SELECT entry\_title, content FROM posts WHERE userid=john doe AND
blog\_title=Johns Blog AND posted\_at >= 2012-01-01 AND
posted\_at < 2012-01-31
CREATE INDEX ON users(birth_year);
But the following one is not, as it does not select a contiguous set of
rows (and we suppose no secondary indexes are set):
Then the following queries are valid::
| bc(sample).
| // Needs a blog\_title to be set to select ranges of posted\_at
| SELECT entry\_title, content FROM posts WHERE userid=john doe AND
posted\_at >= 2012-01-01 AND posted\_at < 2012-01-31
SELECT * FROM users;
SELECT * FROM users WHERE birth_year = 1981;
When specifying relations, the ``TOKEN`` function can be used on the
``PARTITION KEY`` column to query. In that case, rows will be selected
based on the token of their ``PARTITION_KEY`` rather than on the value.
Note that the token of a key depends on the partitioner in use, and that
in particular the RandomPartitioner wont yield a meaningful order. Also
note that ordering partitioners always order token values by bytes (so
even if the partition key is of type int, ``token(-1) > token(0)`` in
particular). Example:
because in both case, Cassandra guarantees that these queries performance will be proportional to the amount of data
returned. In particular, if no users are born in 1981, then the second query performance will not depend of the number
of user profile stored in the database (not directly at least: due to secondary index implementation consideration, this
query may still depend on the number of node in the cluster, which indirectly depends on the amount of data stored.
Nevertheless, the number of nodes will always be multiple number of magnitude lower than the number of user profile
stored). Of course, both query may return very large result set in practice, but the amount of data returned can always
be controlled by adding a ``LIMIT``.
| bc(sample).
| SELECT \* FROM posts WHERE token(userid) > token(tom) AND
token(userid) < token(bob)
However, the following query will be rejected::
Moreover, the ``IN`` relation is only allowed on the last column of the
partition key and on the last column of the full primary key.
SELECT * FROM users WHERE birth_year = 1981 AND country = 'FR';
It is also possible to “group” ``CLUSTERING COLUMNS`` together in a
relation using the tuple notation. For instance:
because Cassandra cannot guarantee that it won't have to scan large amount of data even if the result to those query is
small. Typically, it will scan all the index entries for users born in 1981 even if only a handful are actually from
France. However, if you “know what you are doing”, you can force the execution of this query by using ``ALLOW
FILTERING`` and so the following query is valid::
| bc(sample).
| SELECT \* FROM posts WHERE userid=john doe AND (blog\_title,
posted\_at) > (Johns Blog, 2012-01-01)
SELECT * FROM users WHERE birth_year = 1981 AND country = 'FR' ALLOW FILTERING;
will request all rows that sorts after the one having “Johns Blog” as
``blog_tile`` and 2012-01-01 for ``posted_at`` in the clustering
order. In particular, rows having a ``post_at <= '2012-01-01'`` will be
returned as long as their ``blog_title > 'John''s Blog'``, which
wouldnt be the case for:
| bc(sample).
| SELECT \* FROM posts WHERE userid=john doe AND blog\_title >
Johns Blog AND posted\_at > 2012-01-01
The tuple notation may also be used for ``IN`` clauses on
``CLUSTERING COLUMNS``:
| bc(sample).
| SELECT \* FROM posts WHERE userid=john doe AND (blog\_title,
posted\_at) IN ((Johns Blog, 2012-01-01), (Extreme Chess,
2014-06-01))
The ``CONTAINS`` operator may only be used on collection columns (lists,
sets, and maps). In the case of maps, ``CONTAINS`` applies to the map
values. The ``CONTAINS KEY`` operator may only be used on map columns
and applies to the map keys.
``<order-by>``
~~~~~~~~~~~~~~
The ``ORDER BY`` option allows to select the order of the returned
results. It takes as argument a list of column names along with the
order for the column (``ASC`` for ascendant and ``DESC`` for descendant,
omitting the order being equivalent to ``ASC``). Currently the possible
orderings are limited (which depends on the table
```CLUSTERING ORDER`` <#createTableOptions>`__ ):
- if the table has been defined without any specific
``CLUSTERING ORDER``, then then allowed orderings are the order
induced by the clustering columns and the reverse of that one.
- otherwise, the orderings allowed are the order of the
``CLUSTERING ORDER`` option and the reversed one.
``LIMIT`` and ``PER PARTITION LIMIT``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``LIMIT`` option to a ``SELECT`` statement limits the number of rows
returned by a query, while the ``PER PARTITION LIMIT`` option limits the
number of rows returned for a given partition by the query. Note that
both type of limit can used in the same statement.
``ALLOW FILTERING``
~~~~~~~~~~~~~~~~~~~
By default, CQL only allows select queries that dont involve
“filtering” server side, i.e. queries where we know that all (live)
record read will be returned (maybe partly) in the result set. The
reasoning is that those “non filtering” queries have predictable
performance in the sense that they will execute in a time that is
proportional to the amount of data **returned** by the query (which can
be controlled through ``LIMIT``).
The ``ALLOW FILTERING`` option allows to explicitly allow (some) queries
that require filtering. Please note that a query using
``ALLOW FILTERING`` may thus have unpredictable performance (for the
definition above), i.e. even a query that selects a handful of records
**may** exhibit performance that depends on the total amount of data
stored in the cluster.
For instance, considering the following table holding user profiles with
their year of birth (with a secondary index on it) and country of
residence:
| bc(sample)..
| CREATE TABLE users (
| username text PRIMARY KEY,
| firstname text,
| lastname text,
| birth\_year int,
| country text
| )
| CREATE INDEX ON users(birth\_year);
| p.
Then the following queries are valid:
| bc(sample).
| SELECT \* FROM users;
| SELECT firstname, lastname FROM users WHERE birth\_year = 1981;
because in both case, Cassandra guarantees that these queries
performance will be proportional to the amount of data returned. In
particular, if no users are born in 1981, then the second query
performance will not depend of the number of user profile stored in the
database (not directly at least: due to secondary index implementation
consideration, this query may still depend on the number of node in the
cluster, which indirectly depends on the amount of data stored.
Nevertheless, the number of nodes will always be multiple number of
magnitude lower than the number of user profile stored). Of course, both
query may return very large result set in practice, but the amount of
data returned can always be controlled by adding a ``LIMIT``.
However, the following query will be rejected:
| bc(sample).
| SELECT firstname, lastname FROM users WHERE birth\_year = 1981 AND
country = FR;
because Cassandra cannot guarantee that it wont have to scan large
amount of data even if the result to those query is small. Typically, it
will scan all the index entries for users born in 1981 even if only a
handful are actually from France. However, if you “know what you are
doing”, you can force the execution of this query by using
``ALLOW FILTERING`` and so the following query is valid:
| bc(sample).
| SELECT firstname, lastname FROM users WHERE birth\_year = 1981 AND
country = FR ALLOW FILTERING;
.. _insert-statement:
INSERT
^^^^^^
*Syntax:*
Inserting data for a row is done using an ``INSERT`` statement:
| bc(syntax)..
| ::= INSERT INTO
| ( ( VALUES )
| \| ( JSON ))
| ( IF NOT EXISTS )?
| ( USING ( AND )\* )?
.. productionlist::
insert_statement: INSERT INTO `table_name` ( `names_values` | `json_clause` )
: [ IF NOT EXISTS ]
: [ USING `update_parameter` ( AND `update_parameter` )* ]
names_values: `names` VALUES `tuple_literal`
names: '(' `identifier` ( ',' `identifier` )* ')'
::= ( ( , )\* )
For instance::
::= ( ( , )\* )
INSERT INTO NerdMovies (movie, director, main_actor, year)
VALUES ('Serenity', 'Joss Whedon', 'Nathan Fillion', 2005)
USING TTL 86400;
| ::=
| \|
INSERT INTO NerdMovies JSON '{"movie": "Serenity",
"director": "Joss Whedon",
"year": 2005}';
| ::= TIMESTAMP
| \| TTL
| p.
| *Sample:*
The ``INSERT`` statement writes one or more columns for a given row in a table. Note that since a row is identified by
its ``PRIMARY KEY``, at least the columns composing it must be specified. The list of columns to insert to must be
supplied when using the ``VALUES`` syntax. When using the ``JSON`` syntax, they are optional. See the
section on :ref:`JSON support <cql-json>` for more detail.
| bc(sample)..
| INSERT INTO NerdMovies (movie, director, main\_actor, year)
| VALUES (Serenity, Joss Whedon, Nathan Fillion, 2005)
| USING TTL 86400;
Note that unlike in SQL, ``INSERT`` does not check the prior existence of the row by default: the row is created if none
existed before, and updated otherwise. Furthermore, there is no mean to know which of creation or update happened.
| INSERT INTO NerdMovies JSON {`movie <>`__ “Serenity”, `director <>`__
“Joss Whedon”, `year <>`__ 2005}
| p.
| The ``INSERT`` statement writes one or more columns for a given row in
a table. Note that since a row is identified by its ``PRIMARY KEY``,
at least the columns composing it must be specified. The list of
columns to insert to must be supplied when using the ``VALUES``
syntax. When using the ``JSON`` syntax, they are optional. See the
section on ```INSERT JSON`` <#insertJson>`__ for more details.
Note that unlike in SQL, ``INSERT`` does not check the prior existence
of the row by default: the row is created if none existed before, and
updated otherwise. Furthermore, there is no mean to know which of
creation or update happened.
It is however possible to use the ``IF NOT EXISTS`` condition to only
insert if the row does not exist prior to the insertion. But please note
that using ``IF NOT EXISTS`` will incur a non negligible performance
cost (internally, Paxos will be used) so this should be used sparingly.
It is however possible to use the ``IF NOT EXISTS`` condition to only insert if the row does not exist prior to the
insertion. But please note that using ``IF NOT EXISTS`` will incur a non negligible performance cost (internally, Paxos
will be used) so this should be used sparingly.
All updates for an ``INSERT`` are applied atomically and in isolation.
Please refer to the ```UPDATE`` <#updateOptions>`__ section for
information on the ``<option>`` available and to the
`collections <#collections>`__ section for use of
``<collection-literal>``. Also note that ``INSERT`` does not support
counters, while ``UPDATE`` does.
Please refer to the :ref:`UPDATE <update-parameters>` section for informations on the :token:`update_parameter`.
Also note that ``INSERT`` does not support counters, while ``UPDATE`` does.
.. _update-statement:
UPDATE
^^^^^^
*Syntax:*
Updating a row is done using an ``UPDATE`` statement:
| bc(syntax)..
| ::= UPDATE
| ( USING ( AND )\* )?
| SET ( , )\*
| WHERE
| ( IF ( AND condition )\* )?
.. productionlist::
update_statement: UPDATE `table_name`
: [ USING `update_parameter` ( AND `update_parameter` )* ]
: SET `assignment` ( ',' `assignment` )*
: WHERE `where_clause`
: [ IF ( EXISTS | `condition` ( AND `condition` )*) ]
update_parameter: ( TIMESTAMP | TTL ) ( `integer` | `bind_marker` )
assignment: `simple_selection` '=' `term`
:| `column_name` '=' `column_name` ( '+' | '-' ) `term`
:| `column_name` '=' `list_literal` '+' `column_name`
simple_selection: `column_name`
:| `column_name` '[' `term` ']'
:| `column_name` '.' `field_name
condition: `simple_selection` `operator` `term`
| ::= =
| \| = (+ \| -) ( \| \| )
| \| = +
| \| [ ] =
| \| . =
For instance::
| ::=
| \| IN
| \| [ ]
| \| [ ] IN
| \| .
| \| . IN
UPDATE NerdMovies USING TTL 400
SET director = 'Joss Whedon',
main_actor = 'Nathan Fillion',
year = 2005
WHERE movie = 'Serenity';
| ::= < \| <= \| = \| != \| >= \| >
| ::= ( \| ( ( ( , )\* )? ))
UPDATE UserActions
SET total = total + 2
WHERE user = B70DE1D0-9908-4AE3-BE34-5573E5B09F14
AND action = 'click';
::= ( AND )\*
The ``UPDATE`` statement writes one or more columns for a given row in a table. The :token:`where_clause` is used to
select the row to update and must include all columns composing the ``PRIMARY KEY``. Non primary key columns are then
set using the ``SET`` keyword.
| ::= =
| \| ( (, )\* ) =
| \| IN ( ( ( , )\* )? )
| \| IN
| \| ( (, )\* ) IN ( ( ( , )\* )? )
| \| ( (, )\* ) IN
Note that unlike in SQL, ``UPDATE`` does not check the prior existence of the row by default (except through ``IF``, see
below): the row is created if none existed before, and updated otherwise. Furthermore, there are no means to know
whether a creation or update occurred.
| ::= TIMESTAMP
| \| TTL
| p.
| *Sample:*
It is however possible to use the conditions on some columns through ``IF``, in which case the row will not be updated
unless the conditions are met. But, please note that using ``IF`` conditions will incur a non-negligible performance
cost (internally, Paxos will be used) so this should be used sparingly.
| bc(sample)..
| UPDATE NerdMovies USING TTL 400
| SET director = Joss Whedon,
| main\_actor = Nathan Fillion,
| year = 2005
| WHERE movie = Serenity;
In an ``UPDATE`` statement, all updates within the same partition key are applied atomically and in isolation.
| UPDATE UserActions SET total = total + 2 WHERE user =
B70DE1D0-9908-4AE3-BE34-5573E5B09F14 AND action = click;
| p.
| The ``UPDATE`` statement writes one or more columns for a given row in
a table. The ``<where-clause>`` is used to select the row to update
and must include all columns composing the ``PRIMARY KEY``. Other
columns values are specified through ``<assignment>`` after the
``SET`` keyword.
Regarding the :token:`assignment`:
Note that unlike in SQL, ``UPDATE`` does not check the prior existence
of the row by default (except through the use of ``<condition>``, see
below): the row is created if none existed before, and updated
otherwise. Furthermore, there are no means to know whether a creation or
update occurred.
- ``c = c + 3`` is used to increment/decrement counters. The column name after the '=' sign **must** be the same than
the one before the '=' sign. Note that increment/decrement is only allowed on counters, and are the *only* update
operations allowed on counters. See the section on :ref:`counters <counters>` for details.
- ``id = id + <some-collection>`` and ``id[value1] = value2`` are for collections, see the :ref:`relevant section
<collections>` for details.
- ``id.field = 3`` is for setting the value of a field on a non-frozen user-defined types. see the :ref:`relevant section
<udts>` for details.
It is however possible to use the conditions on some columns through
``IF``, in which case the row will not be updated unless the conditions
are met. But, please note that using ``IF`` conditions will incur a
non-negligible performance cost (internally, Paxos will be used) so this
should be used sparingly.
.. _update-parameters:
In an ``UPDATE`` statement, all updates within the same partition key
are applied atomically and in isolation.
Update parameters
~~~~~~~~~~~~~~~~~
The ``c = c + 3`` form of ``<assignment>`` is used to
increment/decrement counters. The identifier after the = sign **must**
be the same than the one before the = sign (Only increment/decrement
is supported on counters, not the assignment of a specific value).
The ``UPDATE``, ``INSERT`` (and ``DELETE`` and ``BATCH`` for the ``TIMESTAMP``) statements support the following
parameters:
The ``id = id + <collection-literal>`` and ``id[value1] = value2`` forms
of ``<assignment>`` are for collections. Please refer to the `relevant
section <#collections>`__ for more details.
- ``TIMESTAMP``: sets the timestamp for the operation. If not specified, the coordinator will use the current time (in
microseconds) at the start of statement execution as the timestamp. This is usually a suitable default.
- ``TTL``: specifies an optional Time To Live (in seconds) for the inserted values. If set, the inserted values are
automatically removed from the database after the specified time. Note that the TTL concerns the inserted values, not
the columns themselves. This means that any subsequent update of the column will also reset the TTL (to whatever TTL
is specified in that update). By default, values never expire. A TTL of 0 is equivalent to no TTL. If the table has a
default_time_to_live, a TTL of 0 will remove the TTL for the inserted or updated values.
The ``id.field = <term>`` form of ``<assignemt>`` is for setting the
value of a single field on a non-frozen user-defined types.
``<options>``
~~~~~~~~~~~~~
The ``UPDATE`` and ``INSERT`` statements support the following options:
- ``TIMESTAMP``: sets the timestamp for the operation. If not
specified, the coordinator will use the current time (in
microseconds) at the start of statement execution as the timestamp.
This is usually a suitable default.
- ``TTL``: specifies an optional Time To Live (in seconds) for the
inserted values. If set, the inserted values are automatically
removed from the database after the specified time. Note that the TTL
concerns the inserted values, not the columns themselves. This means
that any subsequent update of the column will also reset the TTL (to
whatever TTL is specified in that update). By default, values never
expire. A TTL of 0 is equivalent to no TTL. If the table has a
default\_time\_to\_live, a TTL of 0 will remove the TTL for the
inserted or updated values.
.. _delete_statement:
DELETE
^^^^^^
*Syntax:*
Deleting rows or parts of rows uses the ``DELETE`` statement:
| bc(syntax)..
| ::= DELETE ( ( , )\* )?
| FROM
| ( USING TIMESTAMP )?
| WHERE
| ( IF ( EXISTS \| ( ( AND )\*) ) )?
.. productionlist::
delete_statement: DELETE [ `simple_selection` ( ',' `simple_selection` ) ]
: FROM `table_name`
: [ USING `update_parameter` ( AND `update_parameter` )* ]
: WHERE `where_clause`
: [ IF ( EXISTS | `condition` ( AND `condition` )*) ]
| ::=
| \| [ ]
| \| .
For instance::
::= ( AND )\*
DELETE FROM NerdMovies USING TIMESTAMP 1240003134
WHERE movie = 'Serenity';
| ::=
| \| ( (, )\* )
| \| IN ( ( ( , )\* )? )
| \| IN
| \| ( (, )\* ) IN ( ( ( , )\* )? )
| \| ( (, )\* ) IN
DELETE phone FROM Users
WHERE userid IN (C73DE1D3-AF08-40F3-B124-3FF3E5109F22, B70DE1D0-9908-4AE3-BE34-5573E5B09F14);
| ::= = \| < \| > \| <= \| >=
| ::= ( \| ( ( ( , )\* )? ))
The ``DELETE`` statement deletes columns and rows. If column names are provided directly after the ``DELETE`` keyword,
only those columns are deleted from the row indicated by the ``WHERE`` clause. Otherwise, whole rows are removed.
| ::= ( \| !=)
| \| IN
| \| [ ] ( \| !=)
| \| [ ] IN
| \| . ( \| !=)
| \| . IN
The ``WHERE`` clause specifies which rows are to be deleted. Multiple rows may be deleted with one statement by using an
``IN`` operator. A range of rows may be deleted using an inequality operator (such as ``>=``).
*Sample:*
``DELETE`` supports the ``TIMESTAMP`` option with the same semantics as in :ref:`updates <update-parameters>`.
| bc(sample)..
| DELETE FROM NerdMovies USING TIMESTAMP 1240003134 WHERE movie =
Serenity;
In a ``DELETE`` statement, all deletions within the same partition key are applied atomically and in isolation.
| DELETE phone FROM Users WHERE userid IN
(C73DE1D3-AF08-40F3-B124-3FF3E5109F22,
B70DE1D0-9908-4AE3-BE34-5573E5B09F14);
| p.
| The ``DELETE`` statement deletes columns and rows. If column names are
provided directly after the ``DELETE`` keyword, only those columns are
deleted from the row indicated by the ``<where-clause>``. The
``id[value]`` syntax in ``<selection>`` is for non-frozen collections
(please refer to the `collection section <#collections>`__ for more
details). The ``id.field`` syntax is for the deletion of non-frozen
user-defined types. Otherwise, whole rows are removed. The
``<where-clause>`` specifies which rows are to be deleted. Multiple
rows may be deleted with one statement by using an ``IN`` clause. A
range of rows may be deleted using an inequality operator (such as
``>=``).
A ``DELETE`` operation can be conditional through the use of an ``IF`` clause, similar to ``UPDATE`` and ``INSERT``
statements. However, as with ``INSERT`` and ``UPDATE`` statements, this will incur a non-negligible performance cost
(internally, Paxos will be used) and so should be used sparingly.
``DELETE`` supports the ``TIMESTAMP`` option with the same semantics as
the ```UPDATE`` <#updateStmt>`__ statement.
In a ``DELETE`` statement, all deletions within the same partition key
are applied atomically and in isolation.
A ``DELETE`` operation can be conditional through the use of an ``IF``
clause, similar to ``UPDATE`` and ``INSERT`` statements. However, as
with ``INSERT`` and ``UPDATE`` statements, this will incur a
non-negligible performance cost (internally, Paxos will be used) and so
should be used sparingly.
.. _batch_statement:
BATCH
^^^^^
*Syntax:*
Multiple ``INSERT``, ``UPDATE`` and ``DELETE`` can be executed in a single statement by grouping them through a
``BATCH`` statement:
| bc(syntax)..
| ::= BEGIN ( UNLOGGED \| COUNTER ) BATCH
| ( USING ( AND )\* )?
| ( ; )\*
| APPLY BATCH
.. productionlist::
batch_statement: BEGIN [ UNLOGGED | COUNTER ] BATCH
: [ USING `update_parameter` ( AND `update_parameter` )* ]
: `modification_statement` ( ';' `modification_statement` )*
: APPLY BATCH
modification_statement: `insert_statement` | `update_statement` | `delete_statement`
| ::=
| \|
| \|
For instance::
| ::= TIMESTAMP
| p.
| *Sample:*
BEGIN BATCH
INSERT INTO users (userid, password, name) VALUES ('user2', 'ch@ngem3b', 'second user');
UPDATE users SET password = 'ps22dhds' WHERE userid = 'user3';
INSERT INTO users (userid, password) VALUES ('user4', 'ch@ngem3c');
DELETE name FROM users WHERE userid = 'user1';
APPLY BATCH;
| bc(sample).
| BEGIN BATCH
| INSERT INTO users (userid, password, name) VALUES (user2,
ch@ngem3b, second user);
| UPDATE users SET password = ps22dhds WHERE userid = user3;
| INSERT INTO users (userid, password) VALUES (user4, ch@ngem3c);
| DELETE name FROM users WHERE userid = user1;
| APPLY BATCH;
The ``BATCH`` statement group multiple modification statements (insertions/updates and deletions) into a single
statement. It serves several purposes:
The ``BATCH`` statement group multiple modification statements
(insertions/updates and deletions) into a single statement. It serves
several purposes:
#. It saves network round-trips between the client and the server (and
sometimes between the server coordinator and the replicas) when
batching multiple updates.
#. All updates in a ``BATCH`` belonging to a given partition key are
performed in isolation.
#. By default, all operations in the batch are performed as ``LOGGED``,
to ensure all mutations eventually complete (or none will). See the
notes on ```UNLOGGED`` <#unloggedBatch>`__ for more details.
- It saves network round-trips between the client and the server (and sometimes between the server coordinator and the
replicas) when batching multiple updates.
- All updates in a ``BATCH`` belonging to a given partition key are performed in isolation.
- By default, all operations in the batch are performed as *logged*, to ensure all mutations eventually complete (or
none will). See the notes on :ref:`UNLOGGED batches <unlogged-batches>` for more details.
Note that:
- ``BATCH`` statements may only contain ``UPDATE``, ``INSERT`` and
``DELETE`` statements.
- Batches are *not* a full analogue for SQL transactions.
- If a timestamp is not specified for each operation, then all
operations will be applied with the same timestamp. Due to
Cassandras conflict resolution procedure in the case of `timestamp
ties <http://wiki.apache.org/cassandra/FAQ#clocktie>`__, operations
may be applied in an order that is different from the order they are
listed in the ``BATCH`` statement. To force a particular operation
ordering, you must specify per-operation timestamps.
- ``BATCH`` statements may only contain ``UPDATE``, ``INSERT`` and ``DELETE`` statements (not other batches for instance).
- Batches are *not* a full analogue for SQL transactions.
- If a timestamp is not specified for each operation, then all operations will be applied with the same timestamp
(either one generated automatically, or the timestamp provided at the batch level). Due to Cassandra's conflict
resolution procedure in the case of `timestamp ties <http://wiki.apache.org/cassandra/FAQ#clocktie>`__, operations may
be applied in an order that is different from the order they are listed in the ``BATCH`` statement. To force a
particular operation ordering, you must specify per-operation timestamps.
``UNLOGGED``
~~~~~~~~~~~~
.. _unlogged-batches:
By default, Cassandra uses a batch log to ensure all operations in a
batch eventually complete or none will (note however that operations are
only isolated within a single partition).
``UNLOGGED`` batches
~~~~~~~~~~~~~~~~~~~~
There is a performance penalty for batch atomicity when a batch spans
multiple partitions. If you do not want to incur this penalty, you can
tell Cassandra to skip the batchlog with the ``UNLOGGED`` option. If the
``UNLOGGED`` option is used, a failed batch might leave the patch only
partly applied.
By default, Cassandra uses a batch log to ensure all operations in a batch eventually complete or none will (note
however that operations are only isolated within a single partition).
``COUNTER``
~~~~~~~~~~~
There is a performance penalty for batch atomicity when a batch spans multiple partitions. If you do not want to incur
this penalty, you can tell Cassandra to skip the batchlog with the ``UNLOGGED`` option. If the ``UNLOGGED`` option is
used, a failed batch might leave the patch only partly applied.
``COUNTER`` batches
~~~~~~~~~~~~~~~~~~~
Use the ``COUNTER`` option for batched counter updates. Unlike other
updates in Cassandra, counter updates are not idempotent.
``<option>``
~~~~~~~~~~~~
``BATCH`` supports both the ``TIMESTAMP`` option, with similar semantic
to the one described in the ```UPDATE`` <#updateOptions>`__ statement
(the timestamp applies to all the statement inside the batch). However,
if used, ``TIMESTAMP`` **must not** be used in the statements within the
batch.

View File

@ -16,109 +16,113 @@
.. highlight:: sql
.. _cql_functions:
.. _cql-functions:
.. Need some intro for UDF and native functions in general and point those to it.
.. _udfs:
.. _native-functions:
Functions
---------
CQL3 distinguishes between built-in functions (so called native
functions) and `user-defined functions <#udfs>`__. CQL3 includes
several native functions, described below:
CQL supports 2 main categories of functions:
- the :ref:`scalar functions <scalar-functions>`, which simply take a number of values and produce an output with it.
- the :ref:`aggregate functions <aggregate-functions>`, which are used to aggregate multiple rows results from a
``SELECT`` statement.
In both cases, CQL provides a number of native "hard-coded" functions as well as the ability to create new user-defined
functions.
.. note:: By default, the use of user-defined functions is disabled by default for security concerns (even when
enabled, the execution of user-defined functions is sandboxed and a "rogue" function should not be allowed to do
evil, but no sandbox is perfect so using user-defined functions is opt-in). See the ``enable_user_defined_functions``
in ``cassandra.yaml`` to enable them.
.. _scalar-functions:
Scalar functions
^^^^^^^^^^^^^^^^
.. _scalar-native-functions:
Native functions
~~~~~~~~~~~~~~~~
Cast
````
The ``cast`` function can be used to converts one native datatype to
another.
The ``cast`` function can be used to converts one native datatype to another.
The following table describes the conversions supported by the ``cast``
function. Cassandra will silently ignore any cast converting a datatype
into its own datatype.
The following table describes the conversions supported by the ``cast`` function. Cassandra will silently ignore any
cast converting a datatype into its own datatype.
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| from | to |
+=================+=========================================================================================================================+
| ``ascii`` | ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``bigint`` | ``tinyint``, ``smallint``, ``int``, ``float``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``boolean`` | ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``counter`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``date`` | ``timestamp`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``decimal`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``double`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``float`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``inet`` | ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``int`` | ``tinyint``, ``smallint``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``smallint`` | ``tinyint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``time`` | ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``timestamp`` | ``date``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``timeuuid`` | ``timestamp``, ``date``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``tinyint`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``uuid`` | ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
| ``varint`` | ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``text``, ``varchar`` |
+-----------------+-------------------------------------------------------------------------------------------------------------------------+
=============== =======================================================================================================
From To
=============== =======================================================================================================
``ascii`` ``text``, ``varchar``
``bigint`` ``tinyint``, ``smallint``, ``int``, ``float``, ``double``, ``decimal``, ``varint``, ``text``,
``varchar``
``boolean`` ``text``, ``varchar``
``counter`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``,
``text``, ``varchar``
``date`` ``timestamp``
``decimal`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``varint``, ``text``,
``varchar``
``double`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``decimal``, ``varint``, ``text``,
``varchar``
``float`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``double``, ``decimal``, ``varint``, ``text``,
``varchar``
``inet`` ``text``, ``varchar``
``int`` ``tinyint``, ``smallint``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``,
``varchar``
``smallint`` ``tinyint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``, ``text``,
``varchar``
``time`` ``text``, ``varchar``
``timestamp`` ``date``, ``text``, ``varchar``
``timeuuid`` ``timestamp``, ``date``, ``text``, ``varchar``
``tinyint`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``varint``,
``text``, ``varchar``
``uuid`` ``text``, ``varchar``
``varint`` ``tinyint``, ``smallint``, ``int``, ``bigint``, ``float``, ``double``, ``decimal``, ``text``,
``varchar``
=============== =======================================================================================================
The conversions rely strictly on Javas semantics. For example, the
double value 1 will be converted to the text value 1.0.
The conversions rely strictly on Java's semantics. For example, the double value 1 will be converted to the text value
'1.0'. For instance::
| bc(sample).
| SELECT avg(cast(count as double)) FROM myTable
SELECT avg(cast(count as double)) FROM myTable
Token
`````
The ``token`` function allows to compute the token for a given partition
key. The exact signature of the token function depends on the table
concerned and of the partitioner used by the cluster.
The ``token`` function allows to compute the token for a given partition key. The exact signature of the token function
depends on the table concerned and of the partitioner used by the cluster.
The type of the arguments of the ``token`` depend on the type of the
partition key columns. The return type depend on the partitioner in use:
The type of the arguments of the ``token`` depend on the type of the partition key columns. The return type depend on
the partitioner in use:
- For Murmur3Partitioner, the return type is ``bigint``.
- For RandomPartitioner, the return type is ``varint``.
- For ByteOrderedPartitioner, the return type is ``blob``.
- For Murmur3Partitioner, the return type is ``bigint``.
- For RandomPartitioner, the return type is ``varint``.
- For ByteOrderedPartitioner, the return type is ``blob``.
For instance, in a cluster using the default Murmur3Partitioner, if a
table is defined by
For instance, in a cluster using the default Murmur3Partitioner, if a table is defined by::
| bc(sample).
| CREATE TABLE users (
| userid text PRIMARY KEY,
| username text,
| …
| )
CREATE TABLE users (
userid text PRIMARY KEY,
username text,
)
then the ``token`` function will take a single argument of type ``text``
(in that case, the partition key is ``userid`` (there is no clustering
columns so the partition key is the same than the primary key)), and the
return type will be ``bigint``.
then the ``token`` function will take a single argument of type ``text`` (in that case, the partition key is ``userid``
(there is no clustering columns so the partition key is the same than the primary key)), and the return type will be
``bigint``.
Uuid
````
The ``uuid`` function takes no parameters and generates a random type 4 uuid suitable for use in ``INSERT`` or
``UPDATE`` statements.
The ``uuid`` function takes no parameters and generates a random type 4
uuid suitable for use in INSERT or SET statements.
.. _timeuuid-functions:
Timeuuid functions
``````````````````
@ -126,252 +130,199 @@ Timeuuid functions
``now``
#######
The ``now`` function takes no arguments and generates, on the
coordinator node, a new unique timeuuid (at the time where the statement
using it is executed). Note that this method is useful for insertion but
is largely non-sensical in ``WHERE`` clauses. For instance, a query of
the form
The ``now`` function takes no arguments and generates, on the coordinator node, a new unique timeuuid (at the time where
the statement using it is executed). Note that this method is useful for insertion but is largely non-sensical in
``WHERE`` clauses. For instance, a query of the form::
| bc(sample).
| SELECT \* FROM myTable WHERE t = now()
SELECT * FROM myTable WHERE t = now()
will never return any result by design, since the value returned by
``now()`` is guaranteed to be unique.
will never return any result by design, since the value returned by ``now()`` is guaranteed to be unique.
``minTimeuuid`` and ``maxTimeuuid``
###################################
The ``minTimeuuid`` (resp. ``maxTimeuuid``) function takes a
``timestamp`` value ``t`` (which can be `either a timestamp or a date
string <#usingtimestamps>`__ ) and return a *fake* ``timeuuid``
corresponding to the *smallest* (resp. *biggest*) possible ``timeuuid``
having for timestamp ``t``. So for instance:
The ``minTimeuuid`` (resp. ``maxTimeuuid``) function takes a ``timestamp`` value ``t`` (which can be `either a timestamp
or a date string <timestamps>`) and return a *fake* ``timeuuid`` corresponding to the *smallest* (resp. *biggest*)
possible ``timeuuid`` having for timestamp ``t``. So for instance::
| bc(sample).
| SELECT \* FROM myTable WHERE t > maxTimeuuid(2013-01-01 00:05+0000)
AND t < minTimeuuid(2013-02-02 10:00+0000)
SELECT * FROM myTable
WHERE t > maxTimeuuid('2013-01-01 00:05+0000')
AND t < minTimeuuid('2013-02-02 10:00+0000')
will select all rows where the ``timeuuid`` column ``t`` is strictly
older than 2013-01-01 00:05+0000 but strictly younger than 2013-02-02
10:00+0000. Please note that
``t >= maxTimeuuid('2013-01-01 00:05+0000')`` would still *not* select a
``timeuuid`` generated exactly at 2013-01-01 00:05+0000 and is
essentially equivalent to ``t > maxTimeuuid('2013-01-01 00:05+0000')``.
will select all rows where the ``timeuuid`` column ``t`` is strictly older than ``'2013-01-01 00:05+0000'`` but strictly
younger than ``'2013-02-02 10:00+0000'``. Please note that ``t >= maxTimeuuid('2013-01-01 00:05+0000')`` would still
*not* select a ``timeuuid`` generated exactly at '2013-01-01 00:05+0000' and is essentially equivalent to ``t >
maxTimeuuid('2013-01-01 00:05+0000')``.
*Warning*: We called the values generated by ``minTimeuuid`` and
``maxTimeuuid`` *fake* UUID because they do no respect the Time-Based
UUID generation process specified by the `RFC
4122 <http://www.ietf.org/rfc/rfc4122.txt>`__. In particular, the value
returned by these 2 methods will not be unique. This means you should
only use those methods for querying (as in the example above). Inserting
the result of those methods is almost certainly *a bad idea*.
.. note:: We called the values generated by ``minTimeuuid`` and ``maxTimeuuid`` *fake* UUID because they do no respect
the Time-Based UUID generation process specified by the `RFC 4122 <http://www.ietf.org/rfc/rfc4122.txt>`__. In
particular, the value returned by these 2 methods will not be unique. This means you should only use those methods
for querying (as in the example above). Inserting the result of those methods is almost certainly *a bad idea*.
Time conversion functions
`````````````````````````
A number of functions are provided to “convert” a ``timeuuid``, a
``timestamp`` or a ``date`` into another ``native`` type.
A number of functions are provided to “convert” a ``timeuuid``, a ``timestamp`` or a ``date`` into another ``native``
type.
+-----------------------+-----------------+-------------------------------------------------------------------+
| function name | input type | description |
+=======================+=================+===================================================================+
| ``toDate`` | ``timeuuid`` | Converts the ``timeuuid`` argument into a ``date`` type |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toDate`` | ``timestamp`` | Converts the ``timestamp`` argument into a ``date`` type |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toTimestamp`` | ``timeuuid`` | Converts the ``timeuuid`` argument into a ``timestamp`` type |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toTimestamp`` | ``date`` | Converts the ``date`` argument into a ``timestamp`` type |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toUnixTimestamp`` | ``timeuuid`` | Converts the ``timeuuid`` argument into a ``bigInt`` raw value |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toUnixTimestamp`` | ``timestamp`` | Converts the ``timestamp`` argument into a ``bigInt`` raw value |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``toUnixTimestamp`` | ``date`` | Converts the ``date`` argument into a ``bigInt`` raw value |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``dateOf`` | ``timeuuid`` | Similar to ``toTimestamp(timeuuid)`` (DEPRECATED) |
+-----------------------+-----------------+-------------------------------------------------------------------+
| ``unixTimestampOf`` | ``timeuuid`` | Similar to ``toUnixTimestamp(timeuuid)`` (DEPRECATED) |
+-----------------------+-----------------+-------------------------------------------------------------------+
===================== =============== ===================================================================
Function name Input type Description
===================== =============== ===================================================================
``toDate`` ``timeuuid`` Converts the ``timeuuid`` argument into a ``date`` type
``toDate`` ``timestamp`` Converts the ``timestamp`` argument into a ``date`` type
``toTimestamp`` ``timeuuid`` Converts the ``timeuuid`` argument into a ``timestamp`` type
``toTimestamp`` ``date`` Converts the ``date`` argument into a ``timestamp`` type
``toUnixTimestamp`` ``timeuuid`` Converts the ``timeuuid`` argument into a ``bigInt`` raw value
``toUnixTimestamp`` ``timestamp`` Converts the ``timestamp`` argument into a ``bigInt`` raw value
``toUnixTimestamp`` ``date`` Converts the ``date`` argument into a ``bigInt`` raw value
``dateOf`` ``timeuuid`` Similar to ``toTimestamp(timeuuid)`` (DEPRECATED)
``unixTimestampOf`` ``timeuuid`` Similar to ``toUnixTimestamp(timeuuid)`` (DEPRECATED)
===================== =============== ===================================================================
Blob conversion functions
`````````````````````````
A number of functions are provided to “convert” the native types into binary data (``blob``). For every
``<native-type>`` ``type`` supported by CQL (a notable exceptions is ``blob``, for obvious reasons), the function
``typeAsBlob`` takes a argument of type ``type`` and return it as a ``blob``. Conversely, the function ``blobAsType``
takes a 64-bit ``blob`` argument and convert it to a ``bigint`` value. And so for instance, ``bigintAsBlob(3)`` is
``0x0000000000000003`` and ``blobAsBigint(0x0000000000000003)`` is ``3``.
A number of functions are provided to “convert” the native types into
binary data (``blob``). For every ``<native-type>`` ``type`` supported
by CQL3 (a notable exceptions is ``blob``, for obvious reasons), the
function ``typeAsBlob`` takes a argument of type ``type`` and return it
as a ``blob``. Conversely, the function ``blobAsType`` takes a 64-bit
``blob`` argument and convert it to a ``bigint`` value. And so for
instance, ``bigintAsBlob(3)`` is ``0x0000000000000003`` and
``blobAsBigint(0x0000000000000003)`` is ``3``.
.. _user-defined-scalar-functions:
User-defined functions
~~~~~~~~~~~~~~~~~~~~~~
User-defined functions allow execution of user-provided code in
Cassandra. By default, Cassandra supports defining functions in *Java*
and *JavaScript*. Support for other JSR 223 compliant scripting
languages (such as Python, Ruby, and Scala) can be added by adding a JAR
to the classpath.
User-defined functions allow execution of user-provided code in Cassandra. By default, Cassandra supports defining
functions in *Java* and *JavaScript*. Support for other JSR 223 compliant scripting languages (such as Python, Ruby, and
Scala) can be added by adding a JAR to the classpath.
UDFs are part of the Cassandra schema. As such, they are automatically
propagated to all nodes in the cluster.
UDFs are part of the Cassandra schema. As such, they are automatically propagated to all nodes in the cluster.
UDFs can be *overloaded* - i.e. multiple UDFs with different argument
types but the same function name. Example:
UDFs can be *overloaded* - i.e. multiple UDFs with different argument types but the same function name. Example::
| bc(sample).
| CREATE FUNCTION sample ( arg int ) …;
| CREATE FUNCTION sample ( arg text ) …;
CREATE FUNCTION sample ( arg int ) ...;
CREATE FUNCTION sample ( arg text ) ...;
User-defined functions are susceptible to all of the normal problems
with the chosen programming language. Accordingly, implementations
should be safe against null pointer exceptions, illegal arguments, or
any other potential source of exceptions. An exception during function
execution will result in the entire statement failing.
User-defined functions are susceptible to all of the normal problems with the chosen programming language. Accordingly,
implementations should be safe against null pointer exceptions, illegal arguments, or any other potential source of
exceptions. An exception during function execution will result in the entire statement failing.
It is valid to use *complex* types like collections, tuple types and
user-defined types as argument and return types. Tuple types and
user-defined types are handled by the conversion functions of the
DataStax Java Driver. Please see the documentation of the Java Driver
for details on handling tuple types and user-defined types.
It is valid to use *complex* types like collections, tuple types and user-defined types as argument and return types.
Tuple types and user-defined types are handled by the conversion functions of the DataStax Java Driver. Please see the
documentation of the Java Driver for details on handling tuple types and user-defined types.
Arguments for functions can be literals or terms. Prepared statement
placeholders can be used, too.
Arguments for functions can be literals or terms. Prepared statement placeholders can be used, too.
Note that you can use the double-quoted string syntax to enclose the UDF
source code. For example:
Note that you can use the double-quoted string syntax to enclose the UDF source code. For example::
| bc(sample)..
| CREATE FUNCTION some\_function ( arg int )
| RETURNS NULL ON NULL INPUT
| RETURNS int
| LANGUAGE java
| AS $$ return arg; $$;
CREATE FUNCTION some_function ( arg int )
RETURNS NULL ON NULL INPUT
RETURNS int
LANGUAGE java
AS $$ return arg; $$;
| SELECT some\_function(column) FROM atable …;
| UPDATE atable SET col = some\_function(?) …;
| p.
SELECT some_function(column) FROM atable ...;
UPDATE atable SET col = some_function(?) ...;
| bc(sample).
| CREATE TYPE custom\_type (txt text, i int);
| CREATE FUNCTION fct\_using\_udt ( udtarg frozen )
| RETURNS NULL ON NULL INPUT
| RETURNS text
| LANGUAGE java
| AS $$ return udtarg.getString(“txt”); $$;
CREATE TYPE custom_type (txt text, i int);
CREATE FUNCTION fct_using_udt ( udtarg frozen )
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$ return udtarg.getString("txt"); $$;
User-defined functions can be used in ```SELECT`` <#selectStmt>`__,
```INSERT`` <#insertStmt>`__ and ```UPDATE`` <#updateStmt>`__
statements.
User-defined functions can be used in ``SELECT``, ``INSERT`` and ``UPDATE`` statements.
The implicitly available ``udfContext`` field (or binding for script
UDFs) provides the neccessary functionality to create new UDT and tuple
values.
The implicitly available ``udfContext`` field (or binding for script UDFs) provides the necessary functionality to
create new UDT and tuple values::
| bc(sample).
| CREATE TYPE custom\_type (txt text, i int);
| CREATE FUNCTION fct\_using\_udt ( somearg int )
| RETURNS NULL ON NULL INPUT
| RETURNS custom\_type
| LANGUAGE java
| AS $$
| UDTValue udt = udfContext.newReturnUDTValue();
| udt.setString(“txt”, “some string”);
| udt.setInt(“i”, 42);
| return udt;
| $$;
CREATE TYPE custom\_type (txt text, i int);
CREATE FUNCTION fct\_using\_udt ( somearg int )
RETURNS NULL ON NULL INPUT
RETURNS custom\_type
LANGUAGE java
AS $$
UDTValue udt = udfContext.newReturnUDTValue();
udt.setString(“txt”, “some string”);
udt.setInt(“i”, 42);
return udt;
$$;
The definition of the ``UDFContext`` interface can be found in the
Apache Cassandra source code for
The definition of the ``UDFContext`` interface can be found in the Apache Cassandra source code for
``org.apache.cassandra.cql3.functions.UDFContext``.
| bc(sample).
| public interface UDFContext
| {
| UDTValue newArgUDTValue(String argName);
| UDTValue newArgUDTValue(int argNum);
| UDTValue newReturnUDTValue();
| UDTValue newUDTValue(String udtName);
| TupleValue newArgTupleValue(String argName);
| TupleValue newArgTupleValue(int argNum);
| TupleValue newReturnTupleValue();
| TupleValue newTupleValue(String cqlDefinition);
| }
.. code-block:: java
| Java UDFs already have some imports for common interfaces and classes
defined. These imports are:
| Please note, that these convenience imports are not available for
script UDFs.
public interface UDFContext
{
UDTValue newArgUDTValue(String argName);
UDTValue newArgUDTValue(int argNum);
UDTValue newReturnUDTValue();
UDTValue newUDTValue(String udtName);
TupleValue newArgTupleValue(String argName);
TupleValue newArgTupleValue(int argNum);
TupleValue newReturnTupleValue();
TupleValue newTupleValue(String cqlDefinition);
}
| bc(sample).
| import java.nio.ByteBuffer;
| import java.util.List;
| import java.util.Map;
| import java.util.Set;
| import org.apache.cassandra.cql3.functions.UDFContext;
| import com.datastax.driver.core.TypeCodec;
| import com.datastax.driver.core.TupleValue;
| import com.datastax.driver.core.UDTValue;
Java UDFs already have some imports for common interfaces and classes defined. These imports are:
See ```CREATE FUNCTION`` <#createFunctionStmt>`__ and
```DROP FUNCTION`` <#dropFunctionStmt>`__.
.. code-block:: java
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cassandra.cql3.functions.UDFContext;
import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.core.TupleValue;
import com.datastax.driver.core.UDTValue;
Please note, that these convenience imports are not available for script UDFs.
.. _create-function-statement:
CREATE FUNCTION
```````````````
*Syntax:*
Creating a new user-defined function uses the ``CREATE FUNCTION`` statement:
| bc(syntax)..
| ::= CREATE ( OR REPLACE )?
| FUNCTION ( IF NOT EXISTS )?
| ( . )?
| ( ( , )\* )
| ( CALLED \| RETURNS NULL ) ON NULL INPUT
| RETURNS
| LANGUAGE
| AS
| p.
| *Sample:*
.. productionlist::
create_function_statement: CREATE [ OR REPLACE ] FUNCTION [ IF NOT EXISTS]
: `function_name` '(' `arguments_declaration` ')'
: [ CALLED | RETURNS NULL ] ON NULL INPUT
: RETURNS `cql_type`
: LANGUAGE `identifier`
: AS `string`
arguments_declaration: `identifier` `cql_type` ( ',' `identifier` `cql_type` )*
| bc(sample).
| CREATE OR REPLACE FUNCTION somefunction
| ( somearg int, anotherarg text, complexarg frozen, listarg list )
| RETURNS NULL ON NULL INPUT
| RETURNS text
| LANGUAGE java
| AS $$
| // some Java code
| $$;
| CREATE FUNCTION akeyspace.fname IF NOT EXISTS
| ( someArg int )
| CALLED ON NULL INPUT
| RETURNS text
| LANGUAGE java
| AS $$
| // some Java code
| $$;
For instance::
``CREATE FUNCTION`` creates or replaces a user-defined function.
CREATE OR REPLACE FUNCTION somefunction(somearg int, anotherarg text, complexarg frozen<someUDT>, listarg list)
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$
// some Java code
$$;
Function Signature
##################
CREATE FUNCTION IF NOT EXISTS akeyspace.fname(someArg int)
CALLED ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$
// some Java code
$$;
Signatures are used to distinguish individual functions. The signature
consists of:
``CREATE FUNCTION`` with the optional ``OR REPLACE`` keywords either creates a function or replaces an existing one with
the same signature. A ``CREATE FUNCTION`` without ``OR REPLACE`` fails if a function with the same signature already
exists.
#. The fully qualified function name - i.e *keyspace* plus
*function-name*
#. The concatenated list of all argument types
If the optional ``IF NOT EXISTS`` keywords are used, the function will
only be created if another function with the same signature does not
exist.
Note that keyspace names, function names and argument types are subject
to the default naming conventions and case-sensitivity rules.
``CREATE FUNCTION`` with the optional ``OR REPLACE`` keywords either
creates a function or replaces an existing one with the same signature.
A ``CREATE FUNCTION`` without ``OR REPLACE`` fails if a function with
the same signature already exists.
``OR REPLACE`` and ``IF NOT EXISTS`` cannot be used together.
Behavior on invocation with ``null`` values must be defined for each
function. There are two options:
@ -381,281 +332,222 @@ function. There are two options:
#. ``CALLED ON NULL INPUT`` declares that the function will always be
executed.
If the optional ``IF NOT EXISTS`` keywords are used, the function will
only be created if another function with the same signature does not
exist.
Function Signature
##################
``OR REPLACE`` and ``IF NOT EXISTS`` cannot be used together.
Signatures are used to distinguish individual functions. The signature consists of:
Functions belong to a keyspace. If no keyspace is specified in
``<function-name>``, the current keyspace is used (i.e. the keyspace
specified using the ```USE`` <#useStmt>`__ statement). It is not
possible to create a user-defined function in one of the system
keyspaces.
#. The fully qualified function name - i.e *keyspace* plus *function-name*
#. The concatenated list of all argument types
See the section on `user-defined functions <#udfs>`__ for more
information.
Note that keyspace names, function names and argument types are subject to the default naming conventions and
case-sensitivity rules.
Functions belong to a keyspace. If no keyspace is specified in ``<function-name>``, the current keyspace is used (i.e.
the keyspace specified using the ``USE`` statement). It is not possible to create a user-defined function in one of the
system keyspaces.
.. _drop-function-statement:
DROP FUNCTION
`````````````
*Syntax:*
Dropping a function uses the ``DROP FUNCTION`` statement:
| bc(syntax)..
| ::= DROP FUNCTION ( IF EXISTS )?
| ( . )?
| ( ( ( , )\* ) )?
.. productionlist::
drop_function_statement: DROP FUNCTION [ IF EXISTS ] `function_name` [ '(' `arguments_signature` ')' ]
arguments_signature: `cql_type` ( ',' `cql_type` )*
*Sample:*
For instance::
| bc(sample).
| DROP FUNCTION myfunction;
| DROP FUNCTION mykeyspace.afunction;
| DROP FUNCTION afunction ( int );
| DROP FUNCTION afunction ( text );
DROP FUNCTION myfunction;
DROP FUNCTION mykeyspace.afunction;
DROP FUNCTION afunction ( int );
DROP FUNCTION afunction ( text );
| ``DROP FUNCTION`` statement removes a function created using
``CREATE FUNCTION``.
| You must specify the argument types
(`signature <#functionSignature>`__ ) of the function to drop if there
are multiple functions with the same name but a different signature
(overloaded functions).
You must specify the argument types (:token:`arguments_signature`) of the function to drop if there are multiple
functions with the same name but a different signature (overloaded functions).
``DROP FUNCTION`` with the optional ``IF EXISTS`` keywords drops a
function if it exists.
``DROP FUNCTION`` with the optional ``IF EXISTS`` keywords drops a function if it exists, but does not throw an error if
it doesn't
.. _aggregate-functions:
Aggregate functions
^^^^^^^^^^^^^^^^^^^
| Aggregate functions work on a set of rows. They receive values for
each row and returns one value for the whole set.
| If ``normal`` columns, ``scalar functions``, ``UDT`` fields,
``writetime`` or ``ttl`` are selected together with aggregate
functions, the values returned for them will be the ones of the first
row matching the query.
Aggregate functions work on a set of rows. They receive values for each row and returns one value for the whole set.
CQL3 distinguishes between built-in aggregates (so called native
aggregates) and `user-defined aggregates <#udas>`__. CQL3 includes
several native aggregates, described below:
If ``normal`` columns, ``scalar functions``, ``UDT`` fields, ``writetime`` or ``ttl`` are selected together with
aggregate functions, the values returned for them will be the ones of the first row matching the query.
Native aggregates
~~~~~~~~~~~~~~~~~
.. _count-function:
Count
`````
The ``count`` function can be used to count the rows returned by a
query. Example:
The ``count`` function can be used to count the rows returned by a query. Example::
| bc(sample).
| SELECT COUNT (\*) FROM plays;
| SELECT COUNT (1) FROM plays;
SELECT COUNT (*) FROM plays;
SELECT COUNT (1) FROM plays;
It also can be used to count the non null value of a given column.
Example:
It also can be used to count the non null value of a given column::
| bc(sample).
| SELECT COUNT (scores) FROM plays;
SELECT COUNT (scores) FROM plays;
Max and Min
```````````
The ``max`` and ``min`` functions can be used to compute the maximum and
the minimum value returned by a query for a given column.
The ``max`` and ``min`` functions can be used to compute the maximum and the minimum value returned by a query for a
given column. For instance::
| bc(sample).
| SELECT MIN (players), MAX (players) FROM plays WHERE game = quake;
SELECT MIN (players), MAX (players) FROM plays WHERE game = 'quake';
Sum
```
The ``sum`` function can be used to sum up all the values returned by a
query for a given column.
The ``sum`` function can be used to sum up all the values returned by a query for a given column. For instance::
| bc(sample).
| SELECT SUM (players) FROM plays;
SELECT SUM (players) FROM plays;
Avg
```
The ``avg`` function can be used to compute the average of all the
values returned by a query for a given column.
The ``avg`` function can be used to compute the average of all the values returned by a query for a given column. For
instance::
| bc(sample).
| SELECT AVG (players) FROM plays;
SELECT AVG (players) FROM plays;
.. _user-defined-aggregates-functions:
User-Defined Aggregates
~~~~~~~~~~~~~~~~~~~~~~~
User-defined aggregates allow creation of custom aggregate functions
using `UDFs <#udfs>`__. Common examples of aggregate functions are
User-defined aggregates allow the creation of custom aggregate functions. Common examples of aggregate functions are
*count*, *min*, and *max*.
Each aggregate requires an *initial state* (``INITCOND``, which defaults
to ``null``) of type ``STYPE``. The first argument of the state function
must have type ``STYPE``. The remaining arguments of the state function
must match the types of the user-defined aggregate arguments. The state
function is called once for each row, and the value returned by the
state function becomes the new state. After all rows are processed, the
optional ``FINALFUNC`` is executed with last state value as its
argument.
Each aggregate requires an *initial state* (``INITCOND``, which defaults to ``null``) of type ``STYPE``. The first
argument of the state function must have type ``STYPE``. The remaining arguments of the state function must match the
types of the user-defined aggregate arguments. The state function is called once for each row, and the value returned by
the state function becomes the new state. After all rows are processed, the optional ``FINALFUNC`` is executed with last
state value as its argument.
``STYPE`` is mandatory in order to be able to distinguish possibly
overloaded versions of the state and/or final function (since the
overload can appear after creation of the aggregate).
``STYPE`` is mandatory in order to be able to distinguish possibly overloaded versions of the state and/or final
function (since the overload can appear after creation of the aggregate).
User-defined aggregates can be used in ```SELECT`` <#selectStmt>`__
statement.
User-defined aggregates can be used in ``SELECT`` statement.
A complete working example for user-defined aggregates (assuming that a
keyspace has been selected using the ```USE`` <#useStmt>`__ statement):
A complete working example for user-defined aggregates (assuming that a keyspace has been selected using the ``USE``
statement)::
| bc(sample)..
| CREATE OR REPLACE FUNCTION averageState ( state tuple, val int )
| CALLED ON NULL INPUT
| RETURNS tuple
| LANGUAGE java
| AS
if (val != null) {
state.setInt(0, state.getInt(0)+1);
state.setLong(1, state.getLong(1)+val.intValue());
}
return state;
;
CREATE OR REPLACE FUNCTION averageState(state tuple<int,bigint>, val int)
CALLED ON NULL INPUT
RETURNS tuple
LANGUAGE java
AS '
if (val != null) {
state.setInt(0, state.getInt(0)+1);
state.setLong(1, state.getLong(1)+val.intValue());
}
return state;
';
| CREATE OR REPLACE FUNCTION averageFinal ( state tuple )
| CALLED ON NULL INPUT
| RETURNS double
| LANGUAGE java
| AS
double r = 0;
if (state.getInt(0) == 0) return null;
r = state.getLong(1);
r /= state.getInt(0);
return Double.valueOf®;
;
CREATE OR REPLACE FUNCTION averageFinal (state tuple<int,bigint>)
CALLED ON NULL INPUT
RETURNS double
LANGUAGE java
AS '
double r = 0;
if (state.getInt(0) == 0) return null;
r = state.getLong(1);
r /= state.getInt(0);
return Double.valueOf®;
';
| CREATE OR REPLACE AGGREGATE average ( int )
| SFUNC averageState
| STYPE tuple
| FINALFUNC averageFinal
| INITCOND (0, 0);
CREATE OR REPLACE AGGREGATE average(int)
SFUNC averageState
STYPE tuple
FINALFUNC averageFinal
INITCOND (0, 0);
| CREATE TABLE atable (
| pk int PRIMARY KEY,
| val int);
| INSERT INTO atable (pk, val) VALUES (1,1);
| INSERT INTO atable (pk, val) VALUES (2,2);
| INSERT INTO atable (pk, val) VALUES (3,3);
| INSERT INTO atable (pk, val) VALUES (4,4);
| SELECT average(val) FROM atable;
| p.
CREATE TABLE atable (
pk int PRIMARY KEY,
val int
);
See ```CREATE AGGREGATE`` <#createAggregateStmt>`__ and
```DROP AGGREGATE`` <#dropAggregateStmt>`__.
INSERT INTO atable (pk, val) VALUES (1,1);
INSERT INTO atable (pk, val) VALUES (2,2);
INSERT INTO atable (pk, val) VALUES (3,3);
INSERT INTO atable (pk, val) VALUES (4,4);
SELECT average(val) FROM atable;
.. _create-aggregate-statement:
CREATE AGGREGATE
````````````````
*Syntax:*
Creating (or replacing) a user-defined aggregate function uses the ``CREATE AGGREGATE`` statement:
| bc(syntax)..
| ::= CREATE ( OR REPLACE )?
| AGGREGATE ( IF NOT EXISTS )?
| ( . )?
| ( ( , )\* )
| SFUNC
| STYPE
| ( FINALFUNC )?
| ( INITCOND )?
| p.
| *Sample:*
.. productionlist::
create_aggregate_statement: CREATE [ OR REPLACE ] AGGREGATE [ IF NOT EXISTS ]
: `function_name` '(' `arguments_signature` ')'
: SFUNC `function_name`
: STYPE `cql_type`
: [ FINALFUNC `function_name` ]
: [ INITCOND `term` ]
| bc(sample).
| CREATE AGGREGATE myaggregate ( val text )
| SFUNC myaggregate\_state
| STYPE text
| FINALFUNC myaggregate\_final
| INITCOND foo;
See above for a complete example.
See the section on `user-defined aggregates <#udas>`__ for a complete
example.
``CREATE AGGREGATE`` with the optional ``OR REPLACE`` keywords either creates an aggregate or replaces an existing one
with the same signature. A ``CREATE AGGREGATE`` without ``OR REPLACE`` fails if an aggregate with the same signature
already exists.
``CREATE AGGREGATE`` creates or replaces a user-defined aggregate.
``CREATE AGGREGATE`` with the optional ``OR REPLACE`` keywords either
creates an aggregate or replaces an existing one with the same
signature. A ``CREATE AGGREGATE`` without ``OR REPLACE`` fails if an
aggregate with the same signature already exists.
``CREATE AGGREGATE`` with the optional ``IF NOT EXISTS`` keywords either
creates an aggregate if it does not already exist.
``CREATE AGGREGATE`` with the optional ``IF NOT EXISTS`` keywords either creates an aggregate if it does not already
exist.
``OR REPLACE`` and ``IF NOT EXISTS`` cannot be used together.
Aggregates belong to a keyspace. If no keyspace is specified in
``<aggregate-name>``, the current keyspace is used (i.e. the keyspace
specified using the ```USE`` <#useStmt>`__ statement). It is not
possible to create a user-defined aggregate in one of the system
keyspaces.
Signatures for user-defined aggregates follow the `same
rules <#functionSignature>`__ as for user-defined functions.
``STYPE`` defines the type of the state value and must be specified.
The optional ``INITCOND`` defines the initial state value for the
aggregate. It defaults to ``null``. A non-\ ``null`` ``INITCOND`` must
be specified for state functions that are declared with
``RETURNS NULL ON NULL INPUT``.
The optional ``INITCOND`` defines the initial state value for the aggregate. It defaults to ``null``. A non-\ ``null``
``INITCOND`` must be specified for state functions that are declared with ``RETURNS NULL ON NULL INPUT``.
``SFUNC`` references an existing function to be used as the state
modifying function. The type of first argument of the state function
must match ``STYPE``. The remaining argument types of the state function
must match the argument types of the aggregate function. State is not
updated for state functions declared with ``RETURNS NULL ON NULL INPUT``
and called with ``null``.
``SFUNC`` references an existing function to be used as the state modifying function. The type of first argument of the
state function must match ``STYPE``. The remaining argument types of the state function must match the argument types of
the aggregate function. State is not updated for state functions declared with ``RETURNS NULL ON NULL INPUT`` and called
with ``null``.
The optional ``FINALFUNC`` is called just before the aggregate result is
returned. It must take only one argument with type ``STYPE``. The return
type of the ``FINALFUNC`` may be a different type. A final function
declared with ``RETURNS NULL ON NULL INPUT`` means that the aggregates
return value will be ``null``, if the last state is ``null``.
The optional ``FINALFUNC`` is called just before the aggregate result is returned. It must take only one argument with
type ``STYPE``. The return type of the ``FINALFUNC`` may be a different type. A final function declared with ``RETURNS
NULL ON NULL INPUT`` means that the aggregate's return value will be ``null``, if the last state is ``null``.
If no ``FINALFUNC`` is defined, the overall return type of the aggregate
function is ``STYPE``. If a ``FINALFUNC`` is defined, it is the return
type of that function.
If no ``FINALFUNC`` is defined, the overall return type of the aggregate function is ``STYPE``. If a ``FINALFUNC`` is
defined, it is the return type of that function.
See the section on `user-defined aggregates <#udas>`__ for more
information.
.. _drop-aggregate-statement:
DROP AGGREGATE
``````````````
*Syntax:*
Dropping an user-defined aggregate function uses the ``DROP AGGREGATE`` statement:
| bc(syntax)..
| ::= DROP AGGREGATE ( IF EXISTS )?
| ( . )?
| ( ( ( , )\* ) )?
| p.
.. productionlist::
drop_aggregate_statement: DROP AGGREGATE [ IF EXISTS ] `function_name` [ '(' `arguments_signature` ')' ]
*Sample:*
For instance::
| bc(sample).
| DROP AGGREGATE myAggregate;
| DROP AGGREGATE myKeyspace.anAggregate;
| DROP AGGREGATE someAggregate ( int );
| DROP AGGREGATE someAggregate ( text );
DROP AGGREGATE myAggregate;
DROP AGGREGATE myKeyspace.anAggregate;
DROP AGGREGATE someAggregate ( int );
DROP AGGREGATE someAggregate ( text );
The ``DROP AGGREGATE`` statement removes an aggregate created using
``CREATE AGGREGATE``. You must specify the argument types of the
aggregate to drop if there are multiple aggregates with the same name
but a different signature (overloaded aggregates).
The ``DROP AGGREGATE`` statement removes an aggregate created using ``CREATE AGGREGATE``. You must specify the argument
types of the aggregate to drop if there are multiple aggregates with the same name but a different signature (overloaded
aggregates).
``DROP AGGREGATE`` with the optional ``IF EXISTS`` keywords drops an
aggregate if it exists, and does nothing if a function with the
signature does not exist.
Signatures for user-defined aggregates follow the `same
rules <#functionSignature>`__ as for user-defined functions.
``DROP AGGREGATE`` with the optional ``IF EXISTS`` keywords drops an aggregate if it exists, and does nothing if a
function with the signature does not exist.

View File

@ -14,8 +14,6 @@
.. See the License for the specific language governing permissions and
.. limitations under the License.
.. _UUID: https://en.wikipedia.org/wiki/Universally_unique_identifier
The Cassandra Query Language (CQL)
==================================

View File

@ -16,69 +16,60 @@
.. highlight:: sql
Indexes
-------
.. _secondary-indexes:
Secondary Indexes
-----------------
.. _create-index-statement:
CREATE INDEX
^^^^^^^^^^^^
*Syntax:*
Creating a secondary index on a table uses the ``CREATE INDEX`` statement:
| bc(syntax)..
| ::= CREATE ( CUSTOM )? INDEX ( IF NOT EXISTS )? ( )?
| ON ( )
| ( USING ( WITH OPTIONS = )? )?
.. productionlist::
create_index_statement: CREATE [ CUSTOM ] INDEX [ IF NOT EXISTS ] [ `index_name` ]
: ON `table_name` '(' `index_identifier` ')'
: [ USING `string` [ WITH OPTIONS = `map_literal` ] ]
index_identifier: `column_name`
:| ( KEYS | VALUES | ENTRIES | FULL ) '(' `column_name` ')'
| ::=
| \| keys( )
| p.
| *Sample:*
For instance::
| bc(sample).
| CREATE INDEX userIndex ON NerdMovies (user);
| CREATE INDEX ON Mutants (abilityId);
| CREATE INDEX ON users (keys(favs));
| CREATE CUSTOM INDEX ON users (email) USING path.to.the.IndexClass;
| CREATE CUSTOM INDEX ON users (email) USING path.to.the.IndexClass
WITH OPTIONS = {storage: /mnt/ssd/indexes/};
CREATE INDEX userIndex ON NerdMovies (user);
CREATE INDEX ON Mutants (abilityId);
CREATE INDEX ON users (keys(favs));
CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass';
CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass' WITH OPTIONS = {'storage': '/mnt/ssd/indexes/'};
The ``CREATE INDEX`` statement is used to create a new (automatic)
secondary index for a given (existing) column in a given table. A name
for the index itself can be specified before the ``ON`` keyword, if
desired. If data already exists for the column, it will be indexed
asynchronously. After the index is created, new data for the column is
indexed automatically at insertion time.
The ``CREATE INDEX`` statement is used to create a new (automatic) secondary index for a given (existing) column in a
given table. A name for the index itself can be specified before the ``ON`` keyword, if desired. If data already exists
for the column, it will be indexed asynchronously. After the index is created, new data for the column is indexed
automatically at insertion time.
Attempting to create an already existing index will return an error
unless the ``IF NOT EXISTS`` option is used. If it is used, the
statement will be a no-op if the index already exists.
Attempting to create an already existing index will return an error unless the ``IF NOT EXISTS`` option is used. If it
is used, the statement will be a no-op if the index already exists.
Indexes on Map Keys
~~~~~~~~~~~~~~~~~~~
When creating an index on a `map column <#map>`__, you may index either
the keys or the values. If the column identifier is placed within the
``keys()`` function, the index will be on the map keys, allowing you to
use ``CONTAINS KEY`` in ``WHERE`` clauses. Otherwise, the index will be
on the map values.
When creating an index on a :ref:`maps <maps>`, you may index either the keys or the values. If the column identifier is
placed within the ``keys()`` function, the index will be on the map keys, allowing you to use ``CONTAINS KEY`` in
``WHERE`` clauses. Otherwise, the index will be on the map values.
.. _drop-index-statement:
DROP INDEX
^^^^^^^^^^
*Syntax:*
Dropping a secondary index uses the ``DROP INDEX`` statement:
bc(syntax). ::= DROP INDEX ( IF EXISTS )? ( . )?
.. productionlist::
drop_index_statement: DROP INDEX [ IF EXISTS ] `index_name`
*Sample:*
The ``DROP INDEX`` statement is used to drop an existing secondary index. The argument of the statement is the index
name, which may optionally specify the keyspace of the index.
| bc(sample)..
| DROP INDEX userIndex;
| DROP INDEX userkeyspace.address\_index;
| p.
| The ``DROP INDEX`` statement is used to drop an existing secondary
index. The argument of the statement is the index name, which may
optionally specify the keyspace of the index.
If the index does not exists, the statement will return an error, unless
``IF EXISTS`` is used in which case the operation is a no-op.
If the index does not exists, the statement will return an error, unless ``IF EXISTS`` is used in which case the
operation is a no-op.

View File

@ -16,131 +16,97 @@
.. highlight:: sql
.. _cql-json:
JSON Support
------------
Cassandra 2.2 introduces JSON support to ```SELECT`` <#selectStmt>`__
and ```INSERT`` <#insertStmt>`__ statements. This support does not
fundamentally alter the CQL API (for example, the schema is still
enforced), it simply provides a convenient way to work with JSON
documents.
Cassandra 2.2 introduces JSON support to :ref:`SELECT <select-statement>` and :ref:`INSERT <insert-statement>`
statements. This support does not fundamentally alter the CQL API (for example, the schema is still enforced), it simply
provides a convenient way to work with JSON documents.
SELECT JSON
^^^^^^^^^^^
With ``SELECT`` statements, the new ``JSON`` keyword can be used to
return each row as a single ``JSON`` encoded map. The remainder of the
``SELECT`` statment behavior is the same.
With ``SELECT`` statements, the ``JSON`` keyword can be used to return each row as a single ``JSON`` encoded map. The
remainder of the ``SELECT`` statement behavior is the same.
The result map keys are the same as the column names in a normal result
set. For example, a statement like “``SELECT JSON a, ttl(b) FROM ...``
would result in a map with keys ``"a"`` and ``"ttl(b)"``. However, this
is one notable exception: for symmetry with ``INSERT JSON`` behavior,
case-sensitive column names with upper-case letters will be surrounded
with double quotes. For example, “``SELECT JSON myColumn FROM ...``
would result in a map key ``"\"myColumn\""`` (note the escaped quotes).
The result map keys are the same as the column names in a normal result set. For example, a statement like ``SELECT JSON
a, ttl(b) FROM ...`` would result in a map with keys ``"a"`` and ``"ttl(b)"``. However, this is one notable exception:
for symmetry with ``INSERT JSON`` behavior, case-sensitive column names with upper-case letters will be surrounded with
double quotes. For example, ``SELECT JSON myColumn FROM ...`` would result in a map key ``"\"myColumn\""`` (note the
escaped quotes).
The map values will ``JSON``-encoded representations (as described
below) of the result set values.
The map values will ``JSON``-encoded representations (as described below) of the result set values.
INSERT JSON
^^^^^^^^^^^
With ``INSERT`` statements, the new ``JSON`` keyword can be used to
enable inserting a ``JSON`` encoded map as a single row. The format of
the ``JSON`` map should generally match that returned by a
``SELECT JSON`` statement on the same table. In particular,
case-sensitive column names should be surrounded with double quotes. For
example, to insert into a table with two columns named “myKey” and
“value”, you would do the following:
With ``INSERT`` statements, the new ``JSON`` keyword can be used to enable inserting a ``JSON`` encoded map as a single
row. The format of the ``JSON`` map should generally match that returned by a ``SELECT JSON`` statement on the same
table. In particular, case-sensitive column names should be surrounded with double quotes. For example, to insert into a
table with two columns named "myKey" and "value", you would do the following::
| bc(sample).
| INSERT INTO mytable JSON {“\\”myKey\\“”: 0, `value <>`__ 0}
INSERT INTO mytable JSON '{ "\"myKey\"": 0, "value": 0}'
Any columns which are ommitted from the ``JSON`` map will be defaulted
to a ``NULL`` value (which will result in a tombstone being created).
Any columns which are omitted from the ``JSON`` map will be defaulted to a ``NULL`` value (which will result in a
tombstone being created).
JSON Encoding of Cassandra Data Types
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Where possible, Cassandra will represent and accept data types in their
native ``JSON`` representation. Cassandra will also accept string
representations matching the CQL literal format for all single-field
types. For example, floats, ints, UUIDs, and dates can be represented by
CQL literal strings. However, compound types, such as collections,
tuples, and user-defined types must be represented by native ``JSON``
collections (maps and lists) or a JSON-encoded string representation of
the collection.
Where possible, Cassandra will represent and accept data types in their native ``JSON`` representation. Cassandra will
also accept string representations matching the CQL literal format for all single-field types. For example, floats,
ints, UUIDs, and dates can be represented by CQL literal strings. However, compound types, such as collections, tuples,
and user-defined types must be represented by native ``JSON`` collections (maps and lists) or a JSON-encoded string
representation of the collection.
The following table describes the encodings that Cassandra will accept
in ``INSERT JSON`` values (and ``fromJson()`` arguments) as well as the
format Cassandra will use when returning data for ``SELECT JSON``
statements (and ``fromJson()``):
The following table describes the encodings that Cassandra will accept in ``INSERT JSON`` values (and ``fromJson()``
arguments) as well as the format Cassandra will use when returning data for ``SELECT JSON`` statements (and
``fromJson()``):
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| type | formats accepted | return format | notes |
+=================+==========================+=================+===============================================================================================================================================================================================================+
| ``ascii`` | string | string | Uses JSONs ``\u`` character escape |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``bigint`` | integer, string | integer | String must be valid 64 bit integer |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``blob`` | string | string | String should be 0x followed by an even number of hex digits |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``boolean`` | boolean, string | boolean | String must be “true” or “false” |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``date`` | string | string | Date in format ``YYYY-MM-DD``, timezone UTC |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``decimal`` | integer, float, string | float | May exceed 32 or 64-bit IEEE-754 floating point precision in client-side decoder |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``double`` | integer, float, string | float | String must be valid integer or float |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``float`` | integer, float, string | float | String must be valid integer or float |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``inet`` | string | string | IPv4 or IPv6 address |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``int`` | integer, string | integer | String must be valid 32 bit integer |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``list`` | list, string | list | Uses JSONs native list representation |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``map`` | map, string | map | Uses JSONs native map representation |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``smallint`` | integer, string | integer | String must be valid 16 bit integer |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``set`` | list, string | list | Uses JSONs native list representation |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``text`` | string | string | Uses JSONs ``\u`` character escape |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``time`` | string | string | Time of day in format ``HH-MM-SS[.fffffffff]`` |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``timestamp`` | integer, string | string | A timestamp. Strings constant are allow to input timestamps as dates, see `Working with dates <#usingdates>`__ below for more information. Datestamps with format ``YYYY-MM-DD HH:MM:SS.SSS`` are returned. |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``timeuuid`` | string | string | Type 1 UUID. See `Constants <#constants>`__ for the UUID format |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``tinyint`` | integer, string | integer | String must be valid 8 bit integer |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``tuple`` | list, string | list | Uses JSONs native list representation |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``UDT`` | map, string | map | Uses JSONs native map representation with field names as keys |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``uuid`` | string | string | See `Constants <#constants>`__ for the UUID format |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``varchar`` | string | string | Uses JSONs ``\u`` character escape |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``varint`` | integer, string | integer | Variable length; may overflow 32 or 64 bit integers in client-side decoder |
+-----------------+--------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
=============== ======================== =============== ==============================================================
Type Formats accepted Return format Notes
=============== ======================== =============== ==============================================================
``ascii`` string string Uses JSON's ``\u`` character escape
``bigint`` integer, string integer String must be valid 64 bit integer
``blob`` string string String should be 0x followed by an even number of hex digits
``boolean`` boolean, string boolean String must be "true" or "false"
``date`` string string Date in format ``YYYY-MM-DD``, timezone UTC
``decimal`` integer, float, string float May exceed 32 or 64-bit IEEE-754 floating point precision in
client-side decoder
``double`` integer, float, string float String must be valid integer or float
``float`` integer, float, string float String must be valid integer or float
``inet`` string string IPv4 or IPv6 address
``int`` integer, string integer String must be valid 32 bit integer
``list`` list, string list Uses JSON's native list representation
``map`` map, string map Uses JSON's native map representation
``smallint`` integer, string integer String must be valid 16 bit integer
``set`` list, string list Uses JSON's native list representation
``text`` string string Uses JSON's ``\u`` character escape
``time`` string string Time of day in format ``HH-MM-SS[.fffffffff]``
``timestamp`` integer, string string A timestamp. Strings constant allows to input :ref:`timestamps
as dates <timestamps>`. Datestamps with format ``YYYY-MM-DD
HH:MM:SS.SSS`` are returned.
``timeuuid`` string string Type 1 UUID. See :token:`constant` for the UUID format
``tinyint`` integer, string integer String must be valid 8 bit integer
``tuple`` list, string list Uses JSON's native list representation
``UDT`` map, string map Uses JSON's native map representation with field names as keys
``uuid`` string string See :token:`constant` for the UUID format
``varchar`` string string Uses JSON's ``\u`` character escape
``varint`` integer, string integer Variable length; may overflow 32 or 64 bit integers in
client-side decoder
=============== ======================== =============== ==============================================================
The fromJson() Function
^^^^^^^^^^^^^^^^^^^^^^^
The ``fromJson()`` function may be used similarly to ``INSERT JSON``,
but for a single column value. It may only be used in the ``VALUES``
clause of an ``INSERT`` statement or as one of the column values in an
``UPDATE``, ``DELETE``, or ``SELECT`` statement. For example, it cannot
be used in the selection clause of a ``SELECT`` statement.
The ``fromJson()`` function may be used similarly to ``INSERT JSON``, but for a single column value. It may only be used
in the ``VALUES`` clause of an ``INSERT`` statement or as one of the column values in an ``UPDATE``, ``DELETE``, or
``SELECT`` statement. For example, it cannot be used in the selection clause of a ``SELECT`` statement.
The toJson() Function
^^^^^^^^^^^^^^^^^^^^^
The ``toJson()`` function may be used similarly to ``SELECT JSON``, but
for a single column value. It may only be used in the selection clause
of a ``SELECT`` statement.
The ``toJson()`` function may be used similarly to ``SELECT JSON``, but for a single column value. It may only be used
in the selection clause of a ``SELECT`` statement.

View File

@ -16,80 +16,145 @@
.. highlight:: sql
.. _materialized-views:
Materialized Views
------------------
.. _create-materialized-view-statement:
CREATE MATERIALIZED VIEW
^^^^^^^^^^^^^^^^^^^^^^^^
*Syntax:*
You can create a materialized view on a table using a ``CREATE MATERIALIZED VIEW`` statement:
| bc(syntax)..
| ::= CREATE MATERIALIZED VIEW ( IF NOT EXISTS )? AS
| SELECT ( ( ( , ) \* ) \| \* )
| FROM
| ( WHERE )?
| PRIMARY KEY ( ( , )\* )
| ( WITH ( AND )\* )?
| p.
| *Sample:*
.. productionlist::
create_materialized_view_statement: CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] `view_name` AS
: `select_statement`
: PRIMARY KEY '(' `primary_key` ')'
: WITH `table_options`
| bc(sample)..
| CREATE MATERIALIZED VIEW monkeySpecies\_by\_population AS
| SELECT \*
| FROM monkeySpecies
| WHERE population IS NOT NULL AND species IS NOT NULL
| PRIMARY KEY (population, species)
| WITH comment=Allow query by population instead of species;
| p.
| The ``CREATE MATERIALIZED VIEW`` statement creates a new materialized
view. Each such view is a set of *rows* which corresponds to rows
which are present in the underlying, or base, table specified in the
``SELECT`` statement. A materialized view cannot be directly updated,
but updates to the base table will cause corresponding updates in the
view.
For instance::
Attempting to create an already existing materialized view will return
an error unless the ``IF NOT EXISTS`` option is used. If it is used, the
statement will be a no-op if the materialized view already exists.
CREATE MATERIALIZED VIEW monkeySpecies_by_population AS
SELECT * FROM monkeySpecies
WHERE population IS NOT NULL AND species IS NOT NULL
PRIMARY KEY (population, species)
WITH comment=Allow query by population instead of species;
``WHERE`` Clause
~~~~~~~~~~~~~~~~
The ``CREATE MATERIALIZED VIEW`` statement creates a new materialized view. Each such view is a set of *rows* which
corresponds to rows which are present in the underlying, or base, table specified in the ``SELECT`` statement. A
materialized view cannot be directly updated, but updates to the base table will cause corresponding updates in the
view.
The ``<where-clause>`` is similar to the `where clause of a ``SELECT``
statement <#selectWhere>`__, with a few differences. First, the where
clause must contain an expression that disallows ``NULL`` values in
columns in the views primary key. If no other restriction is desired,
this can be accomplished with an ``IS NOT NULL`` expression. Second,
only columns which are in the base tables primary key may be restricted
with expressions other than ``IS NOT NULL``. (Note that this second
restriction may be lifted in the future.)
Creating a materialized view has 3 main parts:
- The :ref:`select statement <mv-select>` that restrict the data included in the view.
- The :ref:`primary key <mv-primary-key>` definition for the view.
- The :ref:`options <mv-options>` for the view.
Attempting to create an already existing materialized view will return an error unless the ``IF NOT EXISTS`` option is
used. If it is used, the statement will be a no-op if the materialized view already exists.
.. _mv-select:
MV select statement
```````````````````
The select statement of a materialized view creation defines which of the base table is included in the view. That
statement is limited in a number of ways:
- the :ref:`selection <selection-clause>` is limited to those that only select columns of the base table. In other
words, you can't use any function (aggregate or not), casting, term, etc. Aliases are also not supported. You can
however use `*` as a shortcut of selecting all columns. Further, :ref:`static columns <static-columns>` cannot be
included in a materialized view (which means ``SELECT *`` isn't allowed if the base table has static columns).
- the ``WHERE`` clause have the following restrictions:
- it cannot include any :token:`bind_marker`.
- the columns that are not part of the *base table* primary key can only be restricted by an ``IS NOT NULL``
restriction. No other restriction is allowed.
- as the columns that are part of the *view* primary key cannot be null, they must always be at least restricted by a
``IS NOT NULL`` restriction (or any other restriction, but they must have one).
- it cannot have neither an :ref:`ordering clause <ordering-clause>`, nor a :ref:`limit <limit-clause>`, nor :ref:`ALLOW
FILTERING <allow-filtering>`.
.. _mv-primary-key:
MV primary key
``````````````
A view must have a primary key and that primary key must conform to the following restrictions:
- it must contain all the primary key columns of the base table. This ensures that every row of the view correspond to
exactly one row of the base table.
- it can only contain a single column that is not a primary key column in the base table.
So for instance, give the following base table definition::
CREATE TABLE t (
k int,
c1 int,
c2 int,
v1 int,
v2 int,
PRIMARY KEY (k, c1, c2)
)
then the following view definitions are allowed::
CREATE MATERIALIZED VIEW mv1 AS
SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL
PRIMARY KEY (c1, k, c2)
CREATE MATERIALIZED VIEW mv1 AS
SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL
PRIMARY KEY (v1, k, c1, c2)
but the following ones are **not** allowed::
// Error: cannot include both v1 and v2 in the primary key as both are not in the base table primary key
CREATE MATERIALIZED VIEW mv1 AS
SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL AND v1 IS NOT NULL
PRIMARY KEY (v1, v2, k, c1, c2)
// Error: must include k in the primary as it's a base table primary key column
CREATE MATERIALIZED VIEW mv1 AS
SELECT * FROM t WHERE c1 IS NOT NULL AND c2 IS NOT NULL
PRIMARY KEY (c1, c2)
.. _mv-options:
MV options
``````````
A materialized view is internally implemented by a table and as such, creating a MV allows the :ref:`same options than
creating a table <create-table-options>`.
.. _alter-materialized-view-statement:
ALTER MATERIALIZED VIEW
^^^^^^^^^^^^^^^^^^^^^^^
*Syntax:*
After creation, you can alter the options of a materialized view using the ``ALTER MATERIALIZED VIEW`` statement:
| bc(syntax). ::= ALTER MATERIALIZED VIEW
| WITH ( AND )\*
.. productionlist::
alter_materialized_view_statement: ALTER MATERIALIZED VIEW `view_name` WITH `table_options`
The ``ALTER MATERIALIZED VIEW`` statement allows options to be update;
these options are the same as \ ``CREATE TABLE``\ s options.
The options that can be updated are the same than at creation time and thus the :ref:`same than for tables
<create-table-options>`.
.. _drop-materialized-view-statement:
DROP MATERIALIZED VIEW
^^^^^^^^^^^^^^^^^^^^^^
*Syntax:*
Dropping a materialized view users the ``DROP MATERIALIZED VIEW`` statement:
bc(syntax). ::= DROP MATERIALIZED VIEW ( IF EXISTS )?
.. productionlist::
drop_materialized_view_statement: DROP MATERIALIZED VIEW [ IF EXISTS ] `view_name`;
*Sample:*
bc(sample). DROP MATERIALIZED VIEW monkeySpecies\_by\_population;
The ``DROP MATERIALIZED VIEW`` statement is used to drop an existing
materialized view.
If the materialized view does not exists, the statement will return an
error, unless ``IF EXISTS`` is used in which case the operation is a
no-op.
If the materialized view does not exists, the statement will return an error, unless ``IF EXISTS`` is used in which case
the operation is a no-op.

View File

@ -21,53 +21,47 @@
Security
--------
.. _roles:
.. _cql-roles:
Database Roles
^^^^^^^^^^^^^^
.. _create-role-statement:
CREATE ROLE
~~~~~~~~~~~
*Syntax:*
Creating a role uses the ``CREATE ROLE`` statement:
| bc(syntax)..
| ::= CREATE ROLE ( IF NOT EXISTS )? ( WITH ( AND )\* )?
.. productionlist::
create_role_statement: CREATE ROLE [ IF NOT EXISTS ] `role_name`
: [ WITH `role_options` ]
role_options: `role_option` ( AND `role_option` )*
role_option: PASSWORD '=' `string`
:| LOGIN '=' `boolean`
:| SUPERUSER '=' `boolean`
:| OPTIONS '=' `map_literal`
| ::= PASSWORD =
| \| LOGIN =
| \| SUPERUSER =
| \| OPTIONS =
| p.
For instance::
*Sample:*
CREATE ROLE new_role;
CREATE ROLE alice WITH PASSWORD = 'password_a' AND LOGIN = true;
CREATE ROLE bob WITH PASSWORD = 'password_b' AND LOGIN = true AND SUPERUSER = true;
CREATE ROLE carlos WITH OPTIONS = { 'custom_option1' : 'option1_value', 'custom_option2' : 99 };
| bc(sample).
| CREATE ROLE new\_role;
| CREATE ROLE alice WITH PASSWORD = password\_a AND LOGIN = true;
| CREATE ROLE bob WITH PASSWORD = password\_b AND LOGIN = true AND
SUPERUSER = true;
| CREATE ROLE carlos WITH OPTIONS = { custom\_option1 :
option1\_value, custom\_option2 : 99 };
By default roles do not possess ``LOGIN`` privileges or ``SUPERUSER`` status.
By default roles do not possess ``LOGIN`` privileges or ``SUPERUSER``
status.
:ref:`Permissions <cql-permissions>` on database resources are granted to roles; types of resources include keyspaces,
tables, functions and roles themselves. Roles may be granted to other roles to create hierarchical permissions
structures; in these hierarchies, permissions and ``SUPERUSER`` status are inherited, but the ``LOGIN`` privilege is
not.
`Permissions <#permissions>`__ on database resources are granted to
roles; types of resources include keyspaces, tables, functions and roles
themselves. Roles may be granted to other roles to create hierarchical
permissions structures; in these hierarchies, permissions and
``SUPERUSER`` status are inherited, but the ``LOGIN`` privilege is not.
If a role has the ``LOGIN`` privilege, clients may identify as that role when connecting. For the duration of that
connection, the client will acquire any roles and privileges granted to that role.
If a role has the ``LOGIN`` privilege, clients may identify as that role
when connecting. For the duration of that connection, the client will
acquire any roles and privileges granted to that role.
Only a client with with the ``CREATE`` permission on the database roles
resource may issue ``CREATE ROLE`` requests (see the `relevant
section <#permissions>`__ below), unless the client is a ``SUPERUSER``.
Role management in Cassandra is pluggable and custom implementations may
support only a subset of the listed options.
Only a client with with the ``CREATE`` permission on the database roles resource may issue ``CREATE ROLE`` requests (see
the :ref:`relevant section <cql-permissions>` below), unless the client is a ``SUPERUSER``. Role management in Cassandra
is pluggable and custom implementations may support only a subset of the listed options.
Role names should be quoted if they contain non-alphanumeric characters.
@ -76,562 +70,428 @@ Role names should be quoted if they contain non-alphanumeric characters.
Setting credentials for internal authentication
```````````````````````````````````````````````
| Use the ``WITH PASSWORD`` clause to set a password for internal
authentication, enclosing the password in single quotation marks.
| If internal authentication has not been set up or the role does not
have ``LOGIN`` privileges, the ``WITH PASSWORD`` clause is not
necessary.
Use the ``WITH PASSWORD`` clause to set a password for internal authentication, enclosing the password in single
quotation marks.
If internal authentication has not been set up or the role does not have ``LOGIN`` privileges, the ``WITH PASSWORD``
clause is not necessary.
Creating a role conditionally
`````````````````````````````
Attempting to create an existing role results in an invalid query
condition unless the ``IF NOT EXISTS`` option is used. If the option is
used and the role exists, the statement is a no-op.
Attempting to create an existing role results in an invalid query condition unless the ``IF NOT EXISTS`` option is used.
If the option is used and the role exists, the statement is a no-op::
| bc(sample).
| CREATE ROLE other\_role;
| CREATE ROLE IF NOT EXISTS other\_role;
CREATE ROLE other_role;
CREATE ROLE IF NOT EXISTS other_role;
.. _alter-role-statement:
ALTER ROLE
~~~~~~~~~~
*Syntax:*
Altering a role options uses the ``ALTER ROLE`` statement:
| bc(syntax)..
| ::= ALTER ROLE ( WITH ( AND )\* )?
.. productionlist::
alter_role_statement: ALTER ROLE `role_name` WITH `role_options`
| ::= PASSWORD =
| \| LOGIN =
| \| SUPERUSER =
| \| OPTIONS =
| p.
For instance::
*Sample:*
| bc(sample).
| ALTER ROLE bob WITH PASSWORD = PASSWORD\_B AND SUPERUSER = false;
ALTER ROLE bob WITH PASSWORD = 'PASSWORD_B' AND SUPERUSER = false;
Conditions on executing ``ALTER ROLE`` statements:
- A client must have ``SUPERUSER`` status to alter the ``SUPERUSER``
status of another role
- A client cannot alter the ``SUPERUSER`` status of any role it
currently holds
- A client can only modify certain properties of the role with which it
identified at login (e.g. ``PASSWORD``)
- To modify properties of a role, the client must be granted ``ALTER``
`permission <#permissions>`__ on that role
- A client must have ``SUPERUSER`` status to alter the ``SUPERUSER`` status of another role
- A client cannot alter the ``SUPERUSER`` status of any role it currently holds
- A client can only modify certain properties of the role with which it identified at login (e.g. ``PASSWORD``)
- To modify properties of a role, the client must be granted ``ALTER`` :ref:`permission <cql-permissions>` on that role
.. _drop-role-statement:
DROP ROLE
~~~~~~~~~
*Syntax:*
Dropping a role uses the ``DROP ROLE`` statement:
| bc(syntax)..
| ::= DROP ROLE ( IF EXISTS )?
| p.
.. productionlist::
drop_role_statement: DROP ROLE [ IF EXISTS ] `role_name`
*Sample:*
``DROP ROLE`` requires the client to have ``DROP`` :ref:`permission <cql-permissions>` on the role in question. In
addition, client may not ``DROP`` the role with which it identified at login. Finally, only a client with ``SUPERUSER``
status may ``DROP`` another ``SUPERUSER`` role.
| bc(sample).
| DROP ROLE alice;
| DROP ROLE IF EXISTS bob;
Attempting to drop a role which does not exist results in an invalid query condition unless the ``IF EXISTS`` option is
used. If the option is used and the role does not exist the statement is a no-op.
| ``DROP ROLE`` requires the client to have ``DROP``
`permission <#permissions>`__ on the role in question. In addition,
client may not ``DROP`` the role with which it identified at login.
Finaly, only a client with ``SUPERUSER`` status may ``DROP`` another
``SUPERUSER`` role.
| Attempting to drop a role which does not exist results in an invalid
query condition unless the ``IF EXISTS`` option is used. If the option
is used and the role does not exist the statement is a no-op.
.. _grant-role-statement:
GRANT ROLE
~~~~~~~~~~
*Syntax:*
Granting a role to another uses the ``GRANT ROLE`` statement:
| bc(syntax).
| ::= GRANT TO
.. productionlist::
grant_role_statement: GRANT `role_name` TO `role_name`
*Sample:*
For instance::
| bc(sample).
| GRANT report\_writer TO alice;
GRANT report_writer TO alice;
| This statement grants the ``report_writer`` role to ``alice``. Any
permissions granted to ``report_writer`` are also acquired by
``alice``.
| Roles are modelled as a directed acyclic graph, so circular grants are
not permitted. The following examples result in error conditions:
This statement grants the ``report_writer`` role to ``alice``. Any permissions granted to ``report_writer`` are also
acquired by ``alice``.
| bc(sample).
| GRANT role\_a TO role\_b;
| GRANT role\_b TO role\_a;
Roles are modelled as a directed acyclic graph, so circular grants are not permitted. The following examples result in
error conditions::
| bc(sample).
| GRANT role\_a TO role\_b;
| GRANT role\_b TO role\_c;
| GRANT role\_c TO role\_a;
GRANT role_a TO role_b;
GRANT role_b TO role_a;
GRANT role_a TO role_b;
GRANT role_b TO role_c;
GRANT role_c TO role_a;
.. _revoke-role-statement:
REVOKE ROLE
~~~~~~~~~~~
*Syntax:*
Revoking a role uses the ``REVOKE ROLE`` statement:
| bc(syntax).
| ::= REVOKE FROM
.. productionlist::
revoke_role_statement: REVOKE `role_name` FROM `role_name`
*Sample:*
For instance::
| bc(sample).
| REVOKE report\_writer FROM alice;
REVOKE report_writer FROM alice;
This statement revokes the ``report_writer`` role from ``alice``. Any
permissions that ``alice`` has acquired via the ``report_writer`` role
are also revoked.
This statement revokes the ``report_writer`` role from ``alice``. Any permissions that ``alice`` has acquired via the
``report_writer`` role are also revoked.
.. _list-roles-statement:
LIST ROLES
~~~~~~~~~~
*Syntax:*
All the known roles (in the system or granted to specific role) can be listed using the ``LIST ROLES`` statement:
| bc(syntax).
| ::= LIST ROLES ( OF )? ( NORECURSIVE )?
.. productionlist::
list_roles_statement: LIST ROLES [ OF `role_name` ] [ NORECURSIVE ]
*Sample:*
For instance::
| bc(sample).
| LIST ROLES;
LIST ROLES;
Return all known roles in the system, this requires ``DESCRIBE``
permission on the database roles resource.
returns all known roles in the system, this requires ``DESCRIBE`` permission on the database roles resource. And::
| bc(sample).
| LIST ROLES OF ``alice``;
LIST ROLES OF alice;
Enumerate all roles granted to ``alice``, including those transitively
aquired.
enumerates all roles granted to ``alice``, including those transitively acquired. But::
| bc(sample).
| LIST ROLES OF ``bob`` NORECURSIVE
LIST ROLES OF bob NORECURSIVE
List all roles directly granted to ``bob``.
lists all roles directly granted to ``bob`` without including any of the transitively acquired ones.
Users
^^^^^
Prior to the introduction of roles in Cassandra 2.2, authentication and authorization were based around the concept of a
``USER``. For backward compatibility, the legacy syntax has been preserved with ``USER`` centric statements becoming
synonyms for the ``ROLE`` based equivalents. In other words, creating/updating a user is just a different syntax for
creating/updating a role.
.. _create-user-statement:
CREATE USER
~~~~~~~~~~~
Prior to the introduction of roles in Cassandra 2.2, authentication and
authorization were based around the concept of a ``USER``. For backward
compatibility, the legacy syntax has been preserved with ``USER``
centric statments becoming synonyms for the ``ROLE`` based equivalents.
Creating a user uses the ``CREATE USER`` statement:
*Syntax:*
.. productionlist::
create_user_statement: CREATE USER [ IF NOT EXISTS ] `role_name` [ WITH PASSWORD `string` ] [ `user_option` ]
user_option: SUPERUSER | NOSUPERUSER
| bc(syntax)..
| ::= CREATE USER ( IF NOT EXISTS )? ( WITH PASSWORD )? ()?
For instance::
| ::= SUPERUSER
| \| NOSUPERUSER
| p.
CREATE USER alice WITH PASSWORD 'password_a' SUPERUSER;
CREATE USER bob WITH PASSWORD 'password_b' NOSUPERUSER;
*Sample:*
``CREATE USER`` is equivalent to ``CREATE ROLE`` where the ``LOGIN`` option is ``true``. So, the following pairs of
statements are equivalent::
| bc(sample).
| CREATE USER alice WITH PASSWORD password\_a SUPERUSER;
| CREATE USER bob WITH PASSWORD password\_b NOSUPERUSER;
CREATE USER alice WITH PASSWORD 'password_a' SUPERUSER;
CREATE ROLE alice WITH PASSWORD = 'password_a' AND LOGIN = true AND SUPERUSER = true;
``CREATE USER`` is equivalent to ``CREATE ROLE`` where the ``LOGIN``
option is ``true``. So, the following pairs of statements are
equivalent:
CREATE USER IF EXISTS alice WITH PASSWORD 'password_a' SUPERUSER;
CREATE ROLE IF EXISTS alice WITH PASSWORD = 'password_a' AND LOGIN = true AND SUPERUSER = true;
| bc(sample)..
| CREATE USER alice WITH PASSWORD password\_a SUPERUSER;
| CREATE ROLE alice WITH PASSWORD = password\_a AND LOGIN = true AND
SUPERUSER = true;
CREATE USER alice WITH PASSWORD 'password_a' NOSUPERUSER;
CREATE ROLE alice WITH PASSWORD = 'password_a' AND LOGIN = true AND SUPERUSER = false;
| CREATE USER IF EXISTS alice WITH PASSWORD password\_a SUPERUSER;
| CREATE ROLE IF EXISTS alice WITH PASSWORD = password\_a AND LOGIN =
true AND SUPERUSER = true;
CREATE USER alice WITH PASSWORD 'password_a' NOSUPERUSER;
CREATE ROLE alice WITH PASSWORD = 'password_a' WITH LOGIN = true;
| CREATE USER alice WITH PASSWORD password\_a NOSUPERUSER;
| CREATE ROLE alice WITH PASSWORD = password\_a AND LOGIN = true AND
SUPERUSER = false;
CREATE USER alice WITH PASSWORD 'password_a';
CREATE ROLE alice WITH PASSWORD = 'password_a' WITH LOGIN = true;
| CREATE USER alice WITH PASSWORD password\_a NOSUPERUSER;
| CREATE ROLE alice WITH PASSWORD = password\_a WITH LOGIN = true;
| CREATE USER alice WITH PASSWORD password\_a;
| CREATE ROLE alice WITH PASSWORD = password\_a WITH LOGIN = true;
| p.
.. _alter-user-statement:
ALTER USER
~~~~~~~~~~
*Syntax:*
Altering the options of a user uses the ``ALTER USER`` statement:
| bc(syntax)..
| ::= ALTER USER ( WITH PASSWORD )? ( )?
.. productionlist::
alter_user_statement: ALTER USER `role_name` [ WITH PASSWORD `string` ] [ `user_option` ]
| ::= SUPERUSER
| \| NOSUPERUSER
| p.
For instance::
| bc(sample).
| ALTER USER alice WITH PASSWORD PASSWORD\_A;
| ALTER USER bob SUPERUSER;
ALTER USER alice WITH PASSWORD 'PASSWORD_A';
ALTER USER bob SUPERUSER;
.. _drop-user-statement:
DROP USER
~~~~~~~~~
*Syntax:*
Dropping a user uses the ``DROP USER`` statement:
| bc(syntax)..
| ::= DROP USER ( IF EXISTS )?
| p.
.. productionlist::
drop_user_statement: DROP USER [ IF EXISTS ] `role_name`
*Sample:*
| bc(sample).
| DROP USER alice;
| DROP USER IF EXISTS bob;
.. _list-users-statement:
LIST USERS
~~~~~~~~~~
*Syntax:*
Existing users can be listed using the ``LIST USERS`` statement:
| bc(syntax).
| ::= LIST USERS;
.. productionlist::
list_users_statement: LIST USERS
*Sample:*
Note that this statement is equivalent to::
| bc(sample).
| LIST USERS;
This statement is equivalent to
| bc(sample).
| LIST ROLES;
LIST ROLES;
but only roles with the ``LOGIN`` privilege are included in the output.
Data Control
^^^^^^^^^^^^
.. _permissions:
.. _cql-permissions:
Permissions
~~~~~~~~~~~
Permissions on resources are granted to roles; there are several
different types of resources in Cassandra and each type is modelled
hierarchically:
Permissions on resources are granted to roles; there are several different types of resources in Cassandra and each type
is modelled hierarchically:
- The hierarchy of Data resources, Keyspaces and Tables has the
structure ``ALL KEYSPACES`` [STRIKEOUT:> ``KEYSPACE``]> ``TABLE``
- Function resources have the structure ``ALL FUNCTIONS`` [STRIKEOUT:>
``KEYSPACE``]> ``FUNCTION``
- Resources representing roles have the structure ``ALL ROLES`` ->
``ROLE``
- Resources representing JMX ObjectNames, which map to sets of
MBeans/MXBeans, have the structure ``ALL MBEANS`` -> ``MBEAN``
- The hierarchy of Data resources, Keyspaces and Tables has the structure ``ALL KEYSPACES`` -> ``KEYSPACE`` ->
``TABLE``.
- Function resources have the structure ``ALL FUNCTIONS`` -> ``KEYSPACE`` -> ``FUNCTION``
- Resources representing roles have the structure ``ALL ROLES`` -> ``ROLE``
- Resources representing JMX ObjectNames, which map to sets of MBeans/MXBeans, have the structure ``ALL MBEANS`` ->
``MBEAN``
Permissions can be granted at any level of these hierarchies and they
flow downwards. So granting a permission on a resource higher up the
chain automatically grants that same permission on all resources lower
down. For example, granting ``SELECT`` on a ``KEYSPACE`` automatically
grants it on all ``TABLES`` in that ``KEYSPACE``. Likewise, granting a
permission on ``ALL FUNCTIONS`` grants it on every defined function,
regardless of which keyspace it is scoped in. It is also possible to
grant permissions on all functions scoped to a particular keyspace.
Permissions can be granted at any level of these hierarchies and they flow downwards. So granting a permission on a
resource higher up the chain automatically grants that same permission on all resources lower down. For example,
granting ``SELECT`` on a ``KEYSPACE`` automatically grants it on all ``TABLES`` in that ``KEYSPACE``. Likewise, granting
a permission on ``ALL FUNCTIONS`` grants it on every defined function, regardless of which keyspace it is scoped in. It
is also possible to grant permissions on all functions scoped to a particular keyspace.
Modifications to permissions are visible to existing client sessions;
that is, connections need not be re-established following permissions
changes.
Modifications to permissions are visible to existing client sessions; that is, connections need not be re-established
following permissions changes.
The full set of available permissions is:
- ``CREATE``
- ``ALTER``
- ``DROP``
- ``SELECT``
- ``MODIFY``
- ``AUTHORIZE``
- ``DESCRIBE``
- ``EXECUTE``
- ``CREATE``
- ``ALTER``
- ``DROP``
- ``SELECT``
- ``MODIFY``
- ``AUTHORIZE``
- ``DESCRIBE``
- ``EXECUTE``
Not all permissions are applicable to every type of resource. For
instance, ``EXECUTE`` is only relevant in the context of functions or
mbeans; granting ``EXECUTE`` on a resource representing a table is
nonsensical. Attempting to ``GRANT`` a permission on resource to which
it cannot be applied results in an error response. The following
illustrates which permissions can be granted on which types of resource,
and which statements are enabled by that permission.
Not all permissions are applicable to every type of resource. For instance, ``EXECUTE`` is only relevant in the context
of functions or mbeans; granting ``EXECUTE`` on a resource representing a table is nonsensical. Attempting to ``GRANT``
a permission on resource to which it cannot be applied results in an error response. The following illustrates which
permissions can be granted on which types of resource, and which statements are enabled by that permission.
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| permission | resource | operations |
+=================+=================================+======================================================================================================================================================================+
| ``CREATE`` | ``ALL KEYSPACES`` | ``CREATE KEYSPACE`` <br> ``CREATE TABLE`` in any keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``CREATE`` | ``KEYSPACE`` | ``CREATE TABLE`` in specified keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``CREATE`` | ``ALL FUNCTIONS`` | ``CREATE FUNCTION`` in any keyspace <br> ``CREATE AGGREGATE`` in any keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``CREATE`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``CREATE FUNCTION`` in keyspace <br> ``CREATE AGGREGATE`` in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``CREATE`` | ``ALL ROLES`` | ``CREATE ROLE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``ALL KEYSPACES`` | ``ALTER KEYSPACE`` <br> ``ALTER TABLE`` in any keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``KEYSPACE`` | ``ALTER KEYSPACE`` <br> ``ALTER TABLE`` in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``TABLE`` | ``ALTER TABLE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``ALL FUNCTIONS`` | ``CREATE FUNCTION`` replacing any existing <br> ``CREATE AGGREGATE`` replacing any existing |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``CREATE FUNCTION`` replacing existing in keyspace <br> ``CREATE AGGREGATE`` replacing any existing in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``FUNCTION`` | ``CREATE FUNCTION`` replacing existing <br> ``CREATE AGGREGATE`` replacing existing |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``ALL ROLES`` | ``ALTER ROLE`` on any role |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``ALTER`` | ``ROLE`` | ``ALTER ROLE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``ALL KEYSPACES`` | ``DROP KEYSPACE`` <br> ``DROP TABLE`` in any keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``KEYSPACE`` | ``DROP TABLE`` in specified keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``TABLE`` | ``DROP TABLE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``ALL FUNCTIONS`` | ``DROP FUNCTION`` in any keyspace <br> ``DROP AGGREGATE`` in any existing |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``DROP FUNCTION`` in keyspace <br> ``DROP AGGREGATE`` in existing |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``FUNCTION`` | ``DROP FUNCTION`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``ALL ROLES`` | ``DROP ROLE`` on any role |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DROP`` | ``ROLE`` | ``DROP ROLE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``ALL KEYSPACES`` | ``SELECT`` on any table |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``KEYSPACE`` | ``SELECT`` on any table in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``TABLE`` | ``SELECT`` on specified table |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``ALL MBEANS`` | Call getter methods on any mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``MBEANS`` | Call getter methods on any mbean matching a wildcard pattern |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``SELECT`` | ``MBEAN`` | Call getter methods on named mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``ALL KEYSPACES`` | ``INSERT`` on any table <br> ``UPDATE`` on any table <br> ``DELETE`` on any table <br> ``TRUNCATE`` on any table |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``KEYSPACE`` | ``INSERT`` on any table in keyspace <br> ``UPDATE`` on any table in keyspace <br> ``DELETE`` on any table in keyspace <br> ``TRUNCATE`` on any table in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``TABLE`` | ``INSERT`` <br> ``UPDATE`` <br> ``DELETE`` <br> ``TRUNCATE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``ALL MBEANS`` | Call setter methods on any mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``MBEANS`` | Call setter methods on any mbean matching a wildcard pattern |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``MODIFY`` | ``MBEAN`` | Call setter methods on named mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL KEYSPACES`` | ``GRANT PERMISSION`` on any table <br> ``REVOKE PERMISSION`` on any table |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``KEYSPACE`` | ``GRANT PERMISSION`` on table in keyspace <br> ``REVOKE PERMISSION`` on table in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``TABLE`` | ``GRANT PERMISSION`` <br> ``REVOKE PERMISSION`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL FUNCTIONS`` | ``GRANT PERMISSION`` on any function <br> ``REVOKE PERMISSION`` on any function |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``GRANT PERMISSION`` in keyspace <br> ``REVOKE PERMISSION`` in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``GRANT PERMISSION`` in keyspace <br> ``REVOKE PERMISSION`` in keyspace |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``FUNCTION`` | ``GRANT PERMISSION`` <br> ``REVOKE PERMISSION`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL MBEANS`` | ``GRANT PERMISSION`` on any mbean <br> ``REVOKE PERMISSION`` on any mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``MBEANS`` | ``GRANT PERMISSION`` on any mbean matching a wildcard pattern <br> ``REVOKE PERMISSION`` on any mbean matching a wildcard pattern |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``MBEAN`` | ``GRANT PERMISSION`` on named mbean <br> ``REVOKE PERMISSION`` on named mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ALL ROLES`` | ``GRANT ROLE`` grant any role <br> ``REVOKE ROLE`` revoke any role |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``AUTHORIZE`` | ``ROLES`` | ``GRANT ROLE`` grant role <br> ``REVOKE ROLE`` revoke role |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DESCRIBE`` | ``ALL ROLES`` | ``LIST ROLES`` all roles or only roles granted to another, specified role |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DESCRIBE`` | @ALL MBEANS | Retrieve metadata about any mbean from the platforms MBeanServer |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DESCRIBE`` | @MBEANS | Retrieve metadata about any mbean matching a wildcard patter from the platforms MBeanServer |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``DESCRIBE`` | @MBEAN | Retrieve metadata about a named mbean from the platforms MBeanServer |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``ALL FUNCTIONS`` | ``SELECT``, ``INSERT``, ``UPDATE`` using any function <br> use of any function in ``CREATE AGGREGATE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``ALL FUNCTIONS IN KEYSPACE`` | ``SELECT``, ``INSERT``, ``UPDATE`` using any function in keyspace <br> use of any function in keyspace in ``CREATE AGGREGATE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``FUNCTION`` | ``SELECT``, ``INSERT``, ``UPDATE`` using function <br> use of function in ``CREATE AGGREGATE`` |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``ALL MBEANS`` | Execute operations on any mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``MBEANS`` | Execute operations on any mbean matching a wildcard pattern |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``EXECUTE`` | ``MBEAN`` | Execute operations on named mbean |
+-----------------+---------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
=============== =============================== =======================================================================
Permission Resource Operations
=============== =============================== =======================================================================
``CREATE`` ``ALL KEYSPACES`` ``CREATE KEYSPACE`` and ``CREATE TABLE`` in any keyspace
``CREATE`` ``KEYSPACE`` ``CREATE TABLE`` in specified keyspace
``CREATE`` ``ALL FUNCTIONS`` ``CREATE FUNCTION`` in any keyspace and ``CREATE AGGREGATE`` in any
keyspace
``CREATE`` ``ALL FUNCTIONS IN KEYSPACE`` ``CREATE FUNCTION`` and ``CREATE AGGREGATE`` in specified keyspace
``CREATE`` ``ALL ROLES`` ``CREATE ROLE``
``ALTER`` ``ALL KEYSPACES`` ``ALTER KEYSPACE`` and ``ALTER TABLE`` in any keyspace
``ALTER`` ``KEYSPACE`` ``ALTER KEYSPACE`` and ``ALTER TABLE`` in specified keyspace
``ALTER`` ``TABLE`` ``ALTER TABLE``
``ALTER`` ``ALL FUNCTIONS`` ``CREATE FUNCTION`` and ``CREATE AGGREGATE``: replacing any existing
``ALTER`` ``ALL FUNCTIONS IN KEYSPACE`` ``CREATE FUNCTION`` and ``CREATE AGGREGATE``: replacing existing in
specified keyspace
``ALTER`` ``FUNCTION`` ``CREATE FUNCTION`` and ``CREATE AGGREGATE``: replacing existing
``ALTER`` ``ALL ROLES`` ``ALTER ROLE`` on any role
``ALTER`` ``ROLE`` ``ALTER ROLE``
``DROP`` ``ALL KEYSPACES`` ``DROP KEYSPACE`` and ``DROP TABLE`` in any keyspace
``DROP`` ``KEYSPACE`` ``DROP TABLE`` in specified keyspace
``DROP`` ``TABLE`` ``DROP TABLE``
``DROP`` ``ALL FUNCTIONS`` ``DROP FUNCTION`` and ``DROP AGGREGATE`` in any keyspace
``DROP`` ``ALL FUNCTIONS IN KEYSPACE`` ``DROP FUNCTION`` and ``DROP AGGREGATE`` in specified keyspace
``DROP`` ``FUNCTION`` ``DROP FUNCTION``
``DROP`` ``ALL ROLES`` ``DROP ROLE`` on any role
``DROP`` ``ROLE`` ``DROP ROLE``
``SELECT`` ``ALL KEYSPACES`` ``SELECT`` on any table
``SELECT`` ``KEYSPACE`` ``SELECT`` on any table in specified keyspace
``SELECT`` ``TABLE`` ``SELECT`` on specified table
``SELECT`` ``ALL MBEANS`` Call getter methods on any mbean
``SELECT`` ``MBEANS`` Call getter methods on any mbean matching a wildcard pattern
``SELECT`` ``MBEAN`` Call getter methods on named mbean
``MODIFY`` ``ALL KEYSPACES`` ``INSERT``, ``UPDATE``, ``DELETE`` and ``TRUNCATE`` on any table
``MODIFY`` ``KEYSPACE`` ``INSERT``, ``UPDATE``, ``DELETE`` and ``TRUNCATE`` on any table in
specified keyspace
``MODIFY`` ``TABLE`` ``INSERT``, ``UPDATE``, ``DELETE`` and ``TRUNCATE`` on specified table
``MODIFY`` ``ALL MBEANS`` Call setter methods on any mbean
``MODIFY`` ``MBEANS`` Call setter methods on any mbean matching a wildcard pattern
``MODIFY`` ``MBEAN`` Call setter methods on named mbean
``AUTHORIZE`` ``ALL KEYSPACES`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on any table
``AUTHORIZE`` ``KEYSPACE`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on any table in
specified keyspace
``AUTHORIZE`` ``TABLE`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on specified table
``AUTHORIZE`` ``ALL FUNCTIONS`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on any function
``AUTHORIZE`` ``ALL FUNCTIONS IN KEYSPACE`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` in specified keyspace
``AUTHORIZE`` ``FUNCTION`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on specified function
``AUTHORIZE`` ``ALL MBEANS`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on any mbean
``AUTHORIZE`` ``MBEANS`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on any mbean matching
a wildcard pattern
``AUTHORIZE`` ``MBEAN`` ``GRANT PERMISSION`` and ``REVOKE PERMISSION`` on named mbean
``AUTHORIZE`` ``ALL ROLES`` ``GRANT ROLE`` and ``REVOKE ROLE`` on any role
``AUTHORIZE`` ``ROLES`` ``GRANT ROLE`` and ``REVOKE ROLE`` on specified roles
``DESCRIBE`` ``ALL ROLES`` ``LIST ROLES`` on all roles or only roles granted to another,
specified role
``DESCRIBE`` ``ALL MBEANS`` Retrieve metadata about any mbean from the platform's MBeanServer
``DESCRIBE`` ``MBEANS`` Retrieve metadata about any mbean matching a wildcard patter from the
platform's MBeanServer
``DESCRIBE`` ``MBEAN`` Retrieve metadata about a named mbean from the platform's MBeanServer
``EXECUTE`` ``ALL FUNCTIONS`` ``SELECT``, ``INSERT`` and ``UPDATE`` using any function, and use of
any function in ``CREATE AGGREGATE``
``EXECUTE`` ``ALL FUNCTIONS IN KEYSPACE`` ``SELECT``, ``INSERT`` and ``UPDATE`` using any function in specified
keyspace and use of any function in keyspace in ``CREATE AGGREGATE``
``EXECUTE`` ``FUNCTION`` ``SELECT``, ``INSERT`` and ``UPDATE`` using specified function and use
of the function in ``CREATE AGGREGATE``
``EXECUTE`` ``ALL MBEANS`` Execute operations on any mbean
``EXECUTE`` ``MBEANS`` Execute operations on any mbean matching a wildcard pattern
``EXECUTE`` ``MBEAN`` Execute operations on named mbean
=============== =============================== =======================================================================
.. _grant-permission-statement:
GRANT PERMISSION
~~~~~~~~~~~~~~~~
*Syntax:*
Granting a permission uses the ``GRANT PERMISSION`` statement:
| bc(syntax)..
| ::= GRANT ( ALL ( PERMISSIONS )? \| ( PERMISSION )? ) ON TO
.. productionlist::
grant_permission_statement: GRANT `permissions` ON `resource` TO `role_name`
permissions: ALL [ PERMISSIONS ] | `permission` [ PERMISSION ]
permission: CREATE | ALTER | DROP | SELECT | MODIFY | AUTHORIZE | DESCRIBE | EXECUTE
resource: ALL KEYSPACES
:| KEYSPACE `keyspace_name`
:| [ TABLE ] `table_name`
:| ALL ROLES
:| ROLE `role_name`
:| ALL FUNCTIONS [ IN KEYSPACE `keyspace_name` ]
:| FUNCTION `function_name` '(' [ `cql_type` ( ',' `cql_type` )* ] ')'
:| ALL MBEANS
:| ( MBEAN | MBEANS ) `string`
::= CREATE \| ALTER \| DROP \| SELECT \| MODIFY \| AUTHORIZE \| DESCRIBE \| EXECUTE
For instance::
| ::= ALL KEYSPACES
| \| KEYSPACE
| \| ( TABLE )?
| \| ALL ROLES
| \| ROLE
| \| ALL FUNCTIONS ( IN KEYSPACE )?
| \| FUNCTION
| \| ALL MBEANS
| \| ( MBEAN \| MBEANS )
| p.
GRANT SELECT ON ALL KEYSPACES TO data_reader;
*Sample:*
This gives any user with the role ``data_reader`` permission to execute ``SELECT`` statements on any table across all
keyspaces::
| bc(sample).
| GRANT SELECT ON ALL KEYSPACES TO data\_reader;
GRANT MODIFY ON KEYSPACE keyspace1 TO data_writer;
This gives any user with the role ``data_reader`` permission to execute
``SELECT`` statements on any table across all keyspaces
This give any user with the role ``data_writer`` permission to perform ``UPDATE``, ``INSERT``, ``UPDATE``, ``DELETE``
and ``TRUNCATE`` queries on all tables in the ``keyspace1`` keyspace::
| bc(sample).
| GRANT MODIFY ON KEYSPACE keyspace1 TO data\_writer;
GRANT DROP ON keyspace1.table1 TO schema_owner;
This give any user with the role ``data_writer`` permission to perform
``UPDATE``, ``INSERT``, ``UPDATE``, ``DELETE`` and ``TRUNCATE`` queries
on all tables in the ``keyspace1`` keyspace
This gives any user with the ``schema_owner`` role permissions to ``DROP`` ``keyspace1.table1``::
| bc(sample).
| GRANT DROP ON keyspace1.table1 TO schema\_owner;
GRANT EXECUTE ON FUNCTION keyspace1.user_function( int ) TO report_writer;
This gives any user with the ``schema_owner`` role permissions to
``DROP`` ``keyspace1.table1``.
This grants any user with the ``report_writer`` role permission to execute ``SELECT``, ``INSERT`` and ``UPDATE`` queries
which use the function ``keyspace1.user_function( int )``::
| bc(sample).
| GRANT EXECUTE ON FUNCTION keyspace1.user\_function( int ) TO
report\_writer;
GRANT DESCRIBE ON ALL ROLES TO role_admin;
This grants any user with the ``report_writer`` role permission to
execute ``SELECT``, ``INSERT`` and ``UPDATE`` queries which use the
function ``keyspace1.user_function( int )``
| bc(sample).
| GRANT DESCRIBE ON ALL ROLES TO role\_admin;
This grants any user with the ``role_admin`` role permission to view any
and all roles in the system with a ``LIST ROLES`` statement
This grants any user with the ``role_admin`` role permission to view any and all roles in the system with a ``LIST
ROLES`` statement
.. _grant-all:
GRANT ALL
`````````
When the ``GRANT ALL`` form is used, the appropriate set of permissions
is determined automatically based on the target resource.
When the ``GRANT ALL`` form is used, the appropriate set of permissions is determined automatically based on the target
resource.
Automatic Granting
``````````````````
When a resource is created, via a ``CREATE KEYSPACE``, ``CREATE TABLE``,
``CREATE FUNCTION``, ``CREATE AGGREGATE`` or ``CREATE ROLE`` statement,
the creator (the role the database user who issues the statement is
identified as), is automatically granted all applicable permissions on
the new resource.
When a resource is created, via a ``CREATE KEYSPACE``, ``CREATE TABLE``, ``CREATE FUNCTION``, ``CREATE AGGREGATE`` or
``CREATE ROLE`` statement, the creator (the role the database user who issues the statement is identified as), is
automatically granted all applicable permissions on the new resource.
.. _revoke-permission-statement:
REVOKE PERMISSION
~~~~~~~~~~~~~~~~~
*Syntax:*
Revoking a permission from a role uses the ``REVOKE PERMISSION`` statement:
| bc(syntax)..
| ::= REVOKE ( ALL ( PERMISSIONS )? \| ( PERMISSION )? ) ON FROM
.. productionlist::
revoke_permission_statement: REVOKE `permissions` ON `resource` FROM `role_name`
::= CREATE \| ALTER \| DROP \| SELECT \| MODIFY \| AUTHORIZE \| DESCRIBE \| EXECUTE
For instance::
| ::= ALL KEYSPACES
| \| KEYSPACE
| \| ( TABLE )?
| \| ALL ROLES
| \| ROLE
| \| ALL FUNCTIONS ( IN KEYSPACE )?
| \| FUNCTION
| \| ALL MBEANS
| \| ( MBEAN \| MBEANS )
| p.
REVOKE SELECT ON ALL KEYSPACES FROM data_reader;
REVOKE MODIFY ON KEYSPACE keyspace1 FROM data_writer;
REVOKE DROP ON keyspace1.table1 FROM schema_owner;
REVOKE EXECUTE ON FUNCTION keyspace1.user_function( int ) FROM report_writer;
REVOKE DESCRIBE ON ALL ROLES FROM role_admin;
*Sample:*
| bc(sample)..
| REVOKE SELECT ON ALL KEYSPACES FROM data\_reader;
| REVOKE MODIFY ON KEYSPACE keyspace1 FROM data\_writer;
| REVOKE DROP ON keyspace1.table1 FROM schema\_owner;
| REVOKE EXECUTE ON FUNCTION keyspace1.user\_function( int ) FROM
report\_writer;
| REVOKE DESCRIBE ON ALL ROLES FROM role\_admin;
| p.
.. _list-permissions-statement:
LIST PERMISSIONS
~~~~~~~~~~~~~~~~
*Syntax:*
Listing granted permissions uses the ``LIST PERMISSIONS`` statement:
| bc(syntax)..
| ::= LIST ( ALL ( PERMISSIONS )? \| )
| ( ON )?
| ( OF ( NORECURSIVE )? )?
.. productionlist::
list_permissions_statement: LIST `permissions` [ ON `resource` ] [ OF `role_name` [ NORECURSIVE ] ]
| ::= ALL KEYSPACES
| \| KEYSPACE
| \| ( TABLE )?
| \| ALL ROLES
| \| ROLE
| \| ALL FUNCTIONS ( IN KEYSPACE )?
| \| FUNCTION
| \| ALL MBEANS
| \| ( MBEAN \| MBEANS )
| p.
For instance::
*Sample:*
LIST ALL PERMISSIONS OF alice;
| bc(sample).
| LIST ALL PERMISSIONS OF alice;
Show all permissions granted to ``alice``, including those acquired transitively from any other roles::
Show all permissions granted to ``alice``, including those acquired
transitively from any other roles.
LIST ALL PERMISSIONS ON keyspace1.table1 OF bob;
| bc(sample).
| LIST ALL PERMISSIONS ON keyspace1.table1 OF bob;
Show all permissions on ``keyspace1.table1`` granted to ``bob``, including those acquired transitively from any other
roles. This also includes any permissions higher up the resource hierarchy which can be applied to ``keyspace1.table1``.
For example, should ``bob`` have ``ALTER`` permission on ``keyspace1``, that would be included in the results of this
query. Adding the ``NORECURSIVE`` switch restricts the results to only those permissions which were directly granted to
``bob`` or one of ``bob``'s roles::
Show all permissions on ``keyspace1.table1`` granted to ``bob``,
including those acquired transitively from any other roles. This also
includes any permissions higher up the resource hierarchy which can be
applied to ``keyspace1.table1``. For example, should ``bob`` have
``ALTER`` permission on ``keyspace1``, that would be included in the
results of this query. Adding the ``NORECURSIVE`` switch restricts the
results to only those permissions which were directly granted to ``bob``
or one of ``bob``\ s roles.
LIST SELECT PERMISSIONS OF carlos;
| bc(sample).
| LIST SELECT PERMISSIONS OF carlos;
Show any permissions granted to ``carlos`` or any of ``carlos``\ s
roles, limited to ``SELECT`` permissions on any resource.
Show any permissions granted to ``carlos`` or any of ``carlos``'s roles, limited to ``SELECT`` permissions on any
resource.

View File

@ -16,46 +16,42 @@
.. highlight:: sql
.. _cql-triggers:
Triggers
--------
.. _create-trigger-statement:
CREATE TRIGGER
^^^^^^^^^^^^^^
*Syntax:*
Creating a new trigger uses the ``CREATE TRIGGER`` statement:
| bc(syntax)..
| ::= CREATE TRIGGER ( IF NOT EXISTS )? ( )?
| ON
| USING
.. productionlist::
create_trigger_statement: CREATE TRIGGER [ IF NOT EXISTS ] `trigger_name`
: ON `table_name`
: USING `string`
*Sample:*
For instance::
| bc(sample).
| CREATE TRIGGER myTrigger ON myTable USING
org.apache.cassandra.triggers.InvertedIndex;
CREATE TRIGGER myTrigger ON myTable USING 'org.apache.cassandra.triggers.InvertedIndex';
The actual logic that makes up the trigger can be written in any Java
(JVM) language and exists outside the database. You place the trigger
code in a ``lib/triggers`` subdirectory of the Cassandra installation
directory, it loads during cluster startup, and exists on every node
that participates in a cluster. The trigger defined on a table fires
before a requested DML statement occurs, which ensures the atomicity of
the transaction.
The actual logic that makes up the trigger can be written in any Java (JVM) language and exists outside the database.
You place the trigger code in a ``lib/triggers`` subdirectory of the Cassandra installation directory, it loads during
cluster startup, and exists on every node that participates in a cluster. The trigger defined on a table fires before a
requested DML statement occurs, which ensures the atomicity of the transaction.
.. _drop-trigger-statement:
DROP TRIGGER
^^^^^^^^^^^^
*Syntax:*
Dropping a trigger uses the ``DROP TRIGGER`` statement:
| bc(syntax)..
| ::= DROP TRIGGER ( IF EXISTS )? ( )?
| ON
| p.
| *Sample:*
.. productionlist::
drop_trigger_statement: DROP TRIGGER [ IF EXISTS ] `trigger_name` ON `table_name`
| bc(sample).
| DROP TRIGGER myTrigger ON myTable;
For instance::
``DROP TRIGGER`` statement removes the registration of a trigger created
using ``CREATE TRIGGER``.
DROP TRIGGER myTrigger ON myTable;

View File

@ -16,6 +16,8 @@
.. highlight:: sql
.. _UUID: https://en.wikipedia.org/wiki/Universally_unique_identifier
.. _data-types:
Data Types
@ -279,7 +281,7 @@ A ``set`` is a (sorted) collection of unique values. You can define and insert a
VALUES ('cat.jpg', 'jsmith', { 'pet', 'cute' });
// Replace the existing set entirely
UPDATE images SET tags = { 'kitten', 'cat, 'lol' } WHERE id = 'jsmith';
UPDATE images SET tags = { 'kitten', 'cat', 'lol' } WHERE id = 'jsmith';
Further, sets support:
@ -450,7 +452,7 @@ An existing user-defined type can be modified using an ``ALTER TYPE`` statement:
You can:
- modify the type of particular field (``ALTER TYPE address ALTER zip TYPE bigint``). The restrictions for such change
are the same than when :ref:`altering the type of column <alter-table>`.
are the same than when :ref:`altering the type of column <alter-table-statement>`.
- add a new field to the type (``ALTER TYPE address ADD country text``). That new field will be ``null`` for any values
of the type created before the addition.
- rename the fields of the type (``ALTER TYPE address RENAME zip TO zipcode``).

View File

@ -223,6 +223,8 @@ There is a number of common options for all the compaction strategies;
``max_threshold`` (default: 32)
Upper limit of number of sstables before a compaction is triggered. Not used for ``LeveledCompactionStrategy``.
Further, see the section on each strategy for specific additional options.
Compaction nodetool commands
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -267,6 +269,8 @@ More detailed compaction logging
Enable with the compaction option ``log_all`` and a more detailed compaction log file will be produced in your log
directory.
.. _STCS:
Size Tiered Compaction Strategy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -305,6 +309,8 @@ Defragmentation
Defragmentation is done when many sstables are touched during a read. The result of the read is put in to the memtable
so that the next read will not have to touch as many sstables. This can cause writes on a read-only-cluster.
.. _LCS:
Leveled Compaction Strategy
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -370,7 +376,7 @@ LCS options
LCS also support the ``cassandra.disable_stcs_in_l0`` startup option (``-Dcassandra.disable_stcs_in_l0=true``) to avoid
doing STCS in L0.
.. _twcs:
.. _TWCS:
Time Window CompactionStrategy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -75,7 +75,7 @@ permissions management. Role management is an extension point in Cassandra and m
``role_manager`` setting in ``cassandra.yaml``. The default setting uses ``CassandraRoleManager``, an implementation
which stores role information in the tables of the ``system_auth`` keyspace.
See also the :ref:`CQL documentation on roles <roles>`.
See also the :ref:`CQL documentation on roles <cql-roles>`.
Authentication
^^^^^^^^^^^^^^
@ -156,8 +156,8 @@ fully enabled throughout the cluster.
Note that using ``PasswordAuthenticator`` also requires the use of :ref:`CassandraRoleManager <operation-roles>`.
See also: :ref:`setting-credentials-for-internal-authentication`, :ref:`CREATE ROLE <create-role-statement>`,
:ref:`ALTER ROLE <alter-role-statement>`, :ref:`ALTER KEYSPACE <calter-keyspace-statement>` and :ref:`GRANT PERMISSION
<create-permission-statement>`,
:ref:`ALTER ROLE <alter-role-statement>`, :ref:`ALTER KEYSPACE <alter-keyspace-statement>` and :ref:`GRANT PERMISSION
<grant-permission-statement>`,
Authorization
^^^^^^^^^^^^^
@ -317,7 +317,7 @@ to switch to integrated auth once the node has joined the ring and initial setup
With this option, the same database roles used for CQL authentication can be used to control access to JMX, so updates
can be managed centrally using just ``cqlsh``. Furthermore, fine grained control over exactly which operations are
permitted on particular MBeans can be acheived via :ref:`GRANT PERMISSION <cgrant-permission-statement>`.
permitted on particular MBeans can be acheived via :ref:`GRANT PERMISSION <grant-permission-statement>`.
To enable integrated authentication, edit ``cassandra-env.sh`` to uncomment these lines:
@ -373,7 +373,7 @@ granting the same permission for all table level MBeans in that keyspace to the
Adding/removing roles and granting/revoking of permissions is handled dynamically once the initial setup is complete, so
no further restarts are required if permissions are altered.
See also: :ref:`Permissions <permissions>`.
See also: :ref:`Permissions <cql-permissions>`.
.. _jmx-with-ssl:

View File

@ -250,13 +250,16 @@ public class CreateViewStatement extends SchemaAlteringStatement
throw new InvalidRequestException(String.format("Unable to include static column '%s' which would be included by Materialized View SELECT * statement", identifier));
}
if (includeDef && !targetClusteringColumns.contains(identifier) && !targetPartitionKeys.contains(identifier))
boolean defInTargetPrimaryKey = targetClusteringColumns.contains(identifier)
|| targetPartitionKeys.contains(identifier);
if (includeDef && !defInTargetPrimaryKey)
{
includedColumns.add(identifier);
}
if (!def.isPrimaryKeyColumn()) continue;
if (!targetClusteringColumns.contains(identifier) && !targetPartitionKeys.contains(identifier))
if (!defInTargetPrimaryKey)
{
if (missingClusteringColumns)
columnNames.append(',');
@ -320,7 +323,7 @@ public class CreateViewStatement extends SchemaAlteringStatement
// We don't need to include the "IS NOT NULL" filter on a non-composite partition key
// because we will never allow a single partition key to be NULL
boolean isSinglePartitionKey = cfm.getColumnDefinition(identifier).isPartitionKey()
boolean isSinglePartitionKey = def.isPartitionKey()
&& cfm.partitionKeyColumns().size() == 1;
if (!isSinglePartitionKey && !restrictions.isRestricted(def))
throw new InvalidRequestException(String.format("Primary key column '%s' is required to be filtered by 'IS NOT NULL'", identifier));