Skip to content

Commit b11633b

Browse files
CASSANDRA-20943 Introducing comments and security labels for schema elements
1 parent dc89b8c commit b11633b

File tree

47 files changed

+4749
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4749
-118
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
5.1
2+
* Introducing comments and security labels for schema elements (CASSANDRA-20943)
23
* Extend nodetool tablestats for dictionary memory usage (CASSANDRA-20940)
34
* Introduce separate GCInspector thresholds for concurrent GC events (CASSANDRA-20980)
45
* Reduce contention in MemtableAllocator.allocate (CASSANDRA-20226)

conf/cassandra.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,14 @@ drop_compact_storage_enabled: false
26102610
# Defaults to true, which means that reconfiguration of password validator via JMX is possible.
26112611
#password_policy_reconfiguration_enabled: true
26122612

2613+
# Maximum allowed length for comments on schema elements (keyspaces, tables, columns, types, type fields).
2614+
# Comments exceeding this length will be rejected. Defaults to 128 characters.
2615+
max_comment_length: 128
2616+
2617+
# Maximum allowed length for security labels on schema elements (tables, columns).
2618+
# Security labels exceeding this length will be rejected. Defaults to 48 characters.
2619+
max_security_label_length: 48
2620+
26132621
# Guardrail to enable a CREATE or ALTER TABLE statement when default_time_to_live is set to 0
26142622
# and the table is using TimeWindowCompactionStrategy compaction or a subclass of it.
26152623
# It is suspicious to use default_time_to_live set to 0 with such compaction strategy.

doc/modules/cassandra/pages/developing/cql/ddl.adoc

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,192 @@ statements.
803803
However, tables are the only object that can be truncated currently, and the `TABLE` keyword can be omitted.
804804

805805
Truncating a table permanently removes all existing data from the table, but without removing the table itself.
806+
807+
[[comment-statement]]
808+
== COMMENT
809+
810+
The `COMMENT` statement allows you to add descriptive comments to schema elements for documentation purposes.
811+
Comments are stored in the schema metadata and displayed when using `DESCRIBE` statements.
812+
813+
=== COMMENT ON KEYSPACE
814+
815+
Add or modify a comment on a keyspace:
816+
817+
[source,cql]
818+
----
819+
COMMENT ON KEYSPACE keyspace_name IS 'comment text';
820+
COMMENT ON KEYSPACE keyspace_name IS NULL; -- Remove comment
821+
----
822+
823+
Example:
824+
825+
[source,cql]
826+
----
827+
COMMENT ON KEYSPACE cycling IS 'Keyspace for cycling application data';
828+
----
829+
830+
=== COMMENT ON TABLE
831+
832+
Add or modify a comment on a table:
833+
834+
[source,cql]
835+
----
836+
COMMENT ON TABLE keyspace_name.table_name IS 'comment text';
837+
COMMENT ON TABLE keyspace_name.table_name IS NULL; -- Remove comment
838+
----
839+
840+
Example:
841+
842+
[source,cql]
843+
----
844+
COMMENT ON TABLE cycling.cyclist_name IS 'Table storing cyclist names and basic information';
845+
----
846+
847+
=== COMMENT ON COLUMN
848+
849+
Add or modify a comment on a column:
850+
851+
[source,cql]
852+
----
853+
COMMENT ON COLUMN keyspace_name.table_name.column_name IS 'comment text';
854+
COMMENT ON COLUMN keyspace_name.table_name.column_name IS NULL; -- Remove comment
855+
----
856+
857+
Example:
858+
859+
[source,cql]
860+
----
861+
COMMENT ON COLUMN cycling.cyclist_name.id IS 'Unique identifier for each cyclist';
862+
----
863+
864+
=== COMMENT ON TYPE
865+
866+
Add or modify a comment on a user-defined type:
867+
868+
[source,cql]
869+
----
870+
COMMENT ON TYPE keyspace_name.type_name IS 'comment text';
871+
COMMENT ON TYPE keyspace_name.type_name IS NULL; -- Remove comment
872+
----
873+
874+
Example:
875+
876+
[source,cql]
877+
----
878+
COMMENT ON TYPE cycling.address IS 'User-defined type for storing address information';
879+
----
880+
881+
=== COMMENT ON FIELD
882+
883+
Add or modify a comment on a field within a user-defined type:
884+
885+
[source,cql]
886+
----
887+
COMMENT ON FIELD keyspace_name.type_name.field_name IS 'comment text';
888+
COMMENT ON FIELD keyspace_name.type_name.field_name IS NULL; -- Remove comment
889+
----
890+
891+
Example:
892+
893+
[source,cql]
894+
----
895+
COMMENT ON FIELD cycling.address.street IS 'Street address line';
896+
----
897+
898+
NOTE: Comments can be removed by setting them to `NULL`. Comments are displayed when using `DESCRIBE` statements
899+
and are useful for documenting the purpose and structure of your schema elements.
900+
901+
[[security-label-statement]]
902+
== SECURITY LABEL
903+
904+
The `SECURITY LABEL` statement allows you to add security classification labels to schema elements.
905+
Security labels are stored in the schema metadata and displayed when using `DESCRIBE` statements.
906+
These labels can be used to mark data sensitivity levels or compliance requirements.
907+
908+
=== SECURITY LABEL ON KEYSPACE
909+
910+
Add or modify a security label on a keyspace:
911+
912+
[source,cql]
913+
----
914+
SECURITY LABEL ON KEYSPACE keyspace_name IS 'label';
915+
SECURITY LABEL ON KEYSPACE keyspace_name IS NULL; -- Remove label
916+
----
917+
918+
Example:
919+
920+
[source,cql]
921+
----
922+
SECURITY LABEL ON KEYSPACE cycling IS 'CONFIDENTIAL';
923+
----
924+
925+
=== SECURITY LABEL ON TABLE
926+
927+
Add or modify a security label on a table:
928+
929+
[source,cql]
930+
----
931+
SECURITY LABEL ON TABLE keyspace_name.table_name IS 'label';
932+
SECURITY LABEL ON TABLE keyspace_name.table_name IS NULL; -- Remove label
933+
----
934+
935+
Example:
936+
937+
[source,cql]
938+
----
939+
SECURITY LABEL ON TABLE cycling.cyclist_name IS 'PII';
940+
----
941+
942+
=== SECURITY LABEL ON COLUMN
943+
944+
Add or modify a security label on a column:
945+
946+
[source,cql]
947+
----
948+
SECURITY LABEL ON COLUMN keyspace_name.table_name.column_name IS 'label';
949+
SECURITY LABEL ON COLUMN keyspace_name.table_name.column_name IS NULL; -- Remove label
950+
----
951+
952+
Example:
953+
954+
[source,cql]
955+
----
956+
SECURITY LABEL ON COLUMN cycling.cyclist_name.email IS 'PII-EMAIL';
957+
----
958+
959+
=== SECURITY LABEL ON TYPE
960+
961+
Add or modify a security label on a user-defined type:
962+
963+
[source,cql]
964+
----
965+
SECURITY LABEL ON TYPE keyspace_name.type_name IS 'label';
966+
SECURITY LABEL ON TYPE keyspace_name.type_name IS NULL; -- Remove label
967+
----
968+
969+
Example:
970+
971+
[source,cql]
972+
----
973+
SECURITY LABEL ON TYPE cycling.address IS 'SENSITIVE';
974+
----
975+
976+
=== SECURITY LABEL ON FIELD
977+
978+
Add or modify a security label on a field within a user-defined type:
979+
980+
[source,cql]
981+
----
982+
SECURITY LABEL ON FIELD keyspace_name.type_name.field_name IS 'label';
983+
SECURITY LABEL ON FIELD keyspace_name.type_name.field_name IS NULL; -- Remove label
984+
----
985+
986+
Example:
987+
988+
[source,cql]
989+
----
990+
SECURITY LABEL ON FIELD cycling.personal_info.ssn IS 'PII-SSN';
991+
----
992+
993+
NOTE: Security labels can be removed by setting them to `NULL`. Security labels are displayed when using `DESCRIBE` statements
994+
and can be used in conjunction with custom authorization plugins or audit systems to enforce data access policies.

pylib/cqlshlib/cql3handling.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,14 @@ def dequote_value(cqlword):
299299
| <alterTableStatement>
300300
| <alterKeyspaceStatement>
301301
| <alterUserTypeStatement>
302+
| <commentOnKeyspaceStatement>
303+
| <commentOnTableStatement>
304+
| <commentOnColumnStatement>
305+
| <commentOnTypeStatement>
306+
| <securityLabelOnKeyspaceStatement>
307+
| <securityLabelOnTableStatement>
308+
| <securityLabelOnColumnStatement>
309+
| <securityLabelOnTypeStatement>
302310
;
303311
304312
<authenticationStatement> ::= <createUserStatement>
@@ -402,6 +410,8 @@ def dequote_value(cqlword):
402410
;
403411
<propertyOrOption> ::= <property>
404412
| "INDEXES"
413+
| "COMMENTS"
414+
| "SECURITY" "LABELS"
405415
;
406416
407417
'''
@@ -1593,6 +1603,32 @@ def alter_type_field_completer(ctxt, cass):
15931603
;
15941604
'''
15951605

1606+
syntax_rules += r'''
1607+
<commentOnKeyspaceStatement> ::= "COMMENT" "ON" "KEYSPACE" ks=<keyspaceName> "IS" comment=( <stringLiteral> | "NULL" )
1608+
;
1609+
1610+
<commentOnTableStatement> ::= "COMMENT" "ON" wat=( "COLUMNFAMILY" | "TABLE" ) cf=<columnFamilyName> "IS" comment=( <stringLiteral> | "NULL" )
1611+
;
1612+
1613+
<commentOnColumnStatement> ::= "COMMENT" "ON" "COLUMN" cf=<columnFamilyName> dot="." col=<cident> "IS" comment=( <stringLiteral> | "NULL" )
1614+
;
1615+
1616+
<commentOnTypeStatement> ::= "COMMENT" "ON" "TYPE" ut=<userTypeName> "IS" comment=( <stringLiteral> | "NULL" )
1617+
;
1618+
1619+
<securityLabelOnKeyspaceStatement> ::= "SECURITY" "LABEL" "ON" "KEYSPACE" ks=<keyspaceName> "IS" label=( <stringLiteral> | "NULL" )
1620+
;
1621+
1622+
<securityLabelOnTableStatement> ::= "SECURITY" "LABEL" "ON" wat=( "COLUMNFAMILY" | "TABLE" ) cf=<columnFamilyName> "IS" label=( <stringLiteral> | "NULL" )
1623+
;
1624+
1625+
<securityLabelOnColumnStatement> ::= "SECURITY" "LABEL" "ON" "COLUMN" cf=<columnFamilyName> dot="." col=<cident> "IS" label=( <stringLiteral> | "NULL" )
1626+
;
1627+
1628+
<securityLabelOnTypeStatement> ::= "SECURITY" "LABEL" "ON" "TYPE" ut=<userTypeName> "IS" label=( <stringLiteral> | "NULL" )
1629+
;
1630+
'''
1631+
15961632
syntax_rules += r'''
15971633
<username> ::= name=( <identifier> | <stringLiteral> )
15981634
;

pylib/cqlshlib/test/test_cqlsh_completion.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ class TestCqlshCompletion(CqlshCompletionCase):
166166
cqlver = '3.1.6'
167167

168168
def test_complete_on_empty_string(self):
169-
self.trycompletions('', choices=('?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY',
169+
self.trycompletions('', choices=('?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'COMMENT', 'CONSISTENCY',
170170
'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE',
171171
'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE',
172-
'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'ELAPSED', 'EXPAND', 'SERIAL', 'TRUNCATE',
172+
'SECURITY', 'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'ELAPSED', 'EXPAND', 'SERIAL', 'TRUNCATE',
173173
'UPDATE', 'USE', 'exit', 'quit', 'CLEAR', 'CLS', 'history'))
174174

175175
def test_complete_command_words(self):
@@ -288,10 +288,10 @@ def test_complete_in_insert(self):
288288
self.trycompletions(
289289
("INSERT INTO twenty_rows_composite_table (a, b, c) "
290290
"VALUES ( 'eggs', 'sausage', 'spam');"),
291-
choices=['?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY',
291+
choices=['?', 'ADD', 'ALTER', 'BEGIN', 'CAPTURE', 'COMMENT', 'CONSISTENCY', 'COPY',
292292
'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP',
293293
'ELAPSED', 'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING',
294-
'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'SERIAL', 'TRACING',
294+
'REVOKE', 'SECURITY', 'SELECT', 'SHOW', 'SOURCE', 'SERIAL', 'TRACING',
295295
'TRUNCATE', 'UPDATE', 'USE', 'exit', 'history', 'quit',
296296
'CLEAR', 'CLS'])
297297

@@ -856,7 +856,7 @@ def test_complete_in_create_table_like(self):
856856
'min_index_interval',
857857
'speculative_retry', 'additional_write_policy',
858858
'cdc', 'read_repair',
859-
'INDEXES'])
859+
'INDEXES', 'COMMENTS', 'SECURITY'])
860860
self.trycompletions('CREATE TABLE new_table LIKE old_table WITH INDEXES ',
861861
choices=[';' , '=', 'AND'])
862862
self.trycompletions('CREATE TABLE ' + 'new_table LIKE old_table WITH bloom_filter_fp_chance ',
@@ -909,7 +909,7 @@ def test_complete_in_create_table_like(self):
909909
'min_index_interval',
910910
'speculative_retry', 'additional_write_policy',
911911
'cdc', 'read_repair',
912-
'INDEXES'])
912+
'INDEXES', 'COMMENTS', 'SECURITY'])
913913
self.trycompletions('CREATE TABLE ' + "new_table LIKE old_table WITH compaction = "
914914
+ "{'class': 'TimeWindowCompactionStrategy', '",
915915
choices=['compaction_window_unit', 'compaction_window_size',

src/antlr/Lexer.g

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ K_KEYSPACE: ( K E Y S P A C E
9696
K_KEYSPACES: K E Y S P A C E S;
9797
K_COLUMNFAMILY:( C O L U M N F A M I L Y
9898
| T A B L E );
99+
K_COLUMN: C O L U M N;
99100
K_TABLES: ( C O L U M N F A M I L I E S
100101
| T A B L E S );
101102
K_MATERIALIZED:M A T E R I A L I Z E D;
@@ -209,6 +210,8 @@ K_TUPLE: T U P L E;
209210
K_TRIGGER: T R I G G E R;
210211
K_STATIC: S T A T I C;
211212
K_FROZEN: F R O Z E N;
213+
K_FOR: F O R;
214+
K_FIELD: F I E L D;
212215

213216
K_FUNCTION: F U N C T I O N;
214217
K_FUNCTIONS: F U N C T I O N S;
@@ -237,6 +240,12 @@ K_SELECT_MASKED: S E L E C T '_' M A S K E D;
237240
K_VECTOR: V E C T O R;
238241
K_ANN: A N N;
239242

243+
K_COMMENT: C O M M E N T;
244+
K_COMMENTS: C O M M E N T S;
245+
K_SECURITY: S E C U R I T Y;
246+
K_LABEL: L A B E L;
247+
K_LABELS: L A B E L S;
248+
240249
// Case-insensitive alpha characters
241250
fragment A: ('a'|'A');
242251
fragment B: ('b'|'B');

0 commit comments

Comments
 (0)