Make all DDL statements idempotent and not dependent on global state patch by Aleksey Yeschenko; reviewed by Sam Tunnicliffe for CASSANDRA-13426
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/207c80c1 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/207c80c1 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/207c80c1 Branch: refs/heads/trunk Commit: 207c80c1fd63dfbd8ca7e615ec8002ee8983c5d6 Parents: d3a994b Author: Aleksey Yeschenko <[email protected]> Authored: Thu Nov 10 01:17:36 2016 +0000 Committer: Aleksey Yeshchenko <[email protected]> Committed: Tue Jul 17 16:39:41 2018 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + NEWS.txt | 3 + src/antlr/Cql.g | 10 +- src/antlr/Parser.g | 324 +++++++------- .../apache/cassandra/audit/AuditLogContext.java | 42 ++ .../apache/cassandra/audit/AuditLogManager.java | 8 +- .../cassandra/audit/IAuditLogContext.java | 53 --- .../org/apache/cassandra/auth/AuthKeyspace.java | 2 +- .../cassandra/auth/AuthenticatedUser.java | 2 +- .../cassandra/auth/CassandraAuthorizer.java | 20 +- .../auth/CassandraNetworkAuthorizer.java | 2 +- .../cassandra/auth/CassandraRoleManager.java | 3 +- .../apache/cassandra/auth/FunctionResource.java | 10 + .../cassandra/auth/PasswordAuthenticator.java | 2 +- .../cassandra/auth/jmx/AuthorizationProxy.java | 2 +- src/java/org/apache/cassandra/cql3/CFName.java | 39 -- .../org/apache/cassandra/cql3/CQL3Type.java | 97 ++-- .../org/apache/cassandra/cql3/CQLStatement.java | 64 ++- .../CustomPayloadMirroringQueryHandler.java | 3 +- .../org/apache/cassandra/cql3/IndexName.java | 47 -- .../cassandra/cql3/KeyspaceElementName.java | 74 ---- .../cassandra/cql3/MultiColumnRelation.java | 23 + .../apache/cassandra/cql3/QualifiedName.java | 116 +++++ .../org/apache/cassandra/cql3/QueryHandler.java | 29 +- .../apache/cassandra/cql3/QueryProcessor.java | 131 +++--- .../org/apache/cassandra/cql3/ResultSet.java | 9 +- .../cassandra/cql3/SingleColumnRelation.java | 25 +- src/java/org/apache/cassandra/cql3/Term.java | 12 + .../apache/cassandra/cql3/TokenRelation.java | 20 + .../cassandra/cql3/VariableSpecifications.java | 20 +- .../org/apache/cassandra/cql3/WhereClause.java | 74 +++- .../cql3/functions/AbstractFunction.java | 4 +- .../cassandra/cql3/functions/Function.java | 10 +- .../cassandra/cql3/functions/UDAggregate.java | 170 ++++--- .../cassandra/cql3/functions/UDFunction.java | 106 ++++- .../restrictions/CustomIndexExpression.java | 36 +- .../cql3/restrictions/IndexRestrictions.java | 18 +- .../restrictions/StatementRestrictions.java | 33 +- .../cassandra/cql3/selection/Selectable.java | 12 + .../cql3/statements/AlterKeyspaceStatement.java | 129 ------ .../cql3/statements/AlterRoleStatement.java | 5 +- .../cql3/statements/AlterTableStatement.java | 317 ------------- .../statements/AlterTableStatementColumn.java | 74 ---- .../cql3/statements/AlterTypeStatement.java | 195 -------- .../cql3/statements/AlterViewStatement.java | 103 ----- .../statements/AuthenticationStatement.java | 18 +- .../cql3/statements/AuthorizationStatement.java | 17 +- .../cql3/statements/BatchStatement.java | 80 ++-- .../cassandra/cql3/statements/CFProperties.java | 64 --- .../cassandra/cql3/statements/CFStatement.java | 74 ---- .../statements/CreateAggregateStatement.java | 281 ------------ .../statements/CreateFunctionStatement.java | 202 --------- .../cql3/statements/CreateIndexStatement.java | 275 ------------ .../statements/CreateKeyspaceStatement.java | 152 ------- .../cql3/statements/CreateRoleStatement.java | 7 +- .../cql3/statements/CreateTableStatement.java | 431 ------------------ .../cql3/statements/CreateTriggerStatement.java | 116 ----- .../cql3/statements/CreateTypeStatement.java | 152 ------- .../cql3/statements/CreateViewStatement.java | 390 ---------------- .../cql3/statements/DeleteStatement.java | 15 +- .../cql3/statements/DropAggregateStatement.java | 167 ------- .../cql3/statements/DropFunctionStatement.java | 203 --------- .../cql3/statements/DropIndexStatement.java | 131 ------ .../cql3/statements/DropKeyspaceStatement.java | 92 ---- .../cql3/statements/DropRoleStatement.java | 5 +- .../cql3/statements/DropTableStatement.java | 122 ----- .../cql3/statements/DropTriggerStatement.java | 100 ----- .../cql3/statements/DropTypeStatement.java | 138 ------ .../cql3/statements/DropViewStatement.java | 84 ---- .../statements/GrantPermissionsStatement.java | 1 + .../cql3/statements/GrantRoleStatement.java | 1 + .../cql3/statements/IndexPropDefs.java | 76 ---- .../cassandra/cql3/statements/IndexTarget.java | 135 ------ .../cql3/statements/KeyspaceAttributes.java | 91 ---- .../statements/ListPermissionsStatement.java | 3 +- .../cql3/statements/ListRolesStatement.java | 3 +- .../cql3/statements/ModificationStatement.java | 83 ++-- .../cql3/statements/ParsedStatement.java | 88 ---- .../PermissionsManagementStatement.java | 10 +- .../cql3/statements/QualifiedStatement.java | 76 ++++ .../statements/RevokePermissionsStatement.java | 1 + .../cql3/statements/RevokeRoleStatement.java | 1 + .../statements/RoleManagementStatement.java | 2 +- .../statements/SchemaAlteringStatement.java | 123 ------ .../cql3/statements/SelectStatement.java | 82 ++-- .../cql3/statements/TableAttributes.java | 195 -------- .../cql3/statements/TruncateStatement.java | 32 +- .../cql3/statements/UpdateStatement.java | 42 +- .../cassandra/cql3/statements/UseStatement.java | 16 +- .../schema/AlterKeyspaceStatement.java | 114 +++++ .../statements/schema/AlterSchemaStatement.java | 153 +++++++ .../statements/schema/AlterTableStatement.java | 441 +++++++++++++++++++ .../statements/schema/AlterTypeStatement.java | 229 ++++++++++ .../statements/schema/AlterViewStatement.java | 112 +++++ .../schema/CreateAggregateStatement.java | 329 ++++++++++++++ .../schema/CreateFunctionStatement.java | 250 +++++++++++ .../statements/schema/CreateIndexStatement.java | 233 ++++++++++ .../schema/CreateKeyspaceStatement.java | 115 +++++ .../statements/schema/CreateTableStatement.java | 348 +++++++++++++++ .../schema/CreateTriggerStatement.java | 120 +++++ .../statements/schema/CreateTypeStatement.java | 151 +++++++ .../statements/schema/CreateViewStatement.java | 413 +++++++++++++++++ .../schema/DropAggregateStatement.java | 174 ++++++++ .../schema/DropFunctionStatement.java | 182 ++++++++ .../statements/schema/DropIndexStatement.java | 110 +++++ .../schema/DropKeyspaceStatement.java | 83 ++++ .../statements/schema/DropTableStatement.java | 112 +++++ .../statements/schema/DropTriggerStatement.java | 104 +++++ .../statements/schema/DropTypeStatement.java | 149 +++++++ .../statements/schema/DropViewStatement.java | 98 +++++ .../cql3/statements/schema/IndexAttributes.java | 77 ++++ .../cql3/statements/schema/IndexTarget.java | 133 ++++++ .../statements/schema/KeyspaceAttributes.java | 85 ++++ .../cql3/statements/schema/TableAttributes.java | 196 +++++++++ src/java/org/apache/cassandra/db/Keyspace.java | 9 +- .../org/apache/cassandra/db/SystemKeyspace.java | 2 +- .../org/apache/cassandra/db/TableCQLHelper.java | 2 +- .../db/marshal/AbstractCompositeType.java | 6 - .../cassandra/db/marshal/AbstractType.java | 36 +- .../cassandra/db/marshal/CollectionType.java | 7 +- .../cassandra/db/marshal/CompositeType.java | 42 +- .../db/marshal/DynamicCompositeType.java | 44 +- .../apache/cassandra/db/marshal/ListType.java | 43 +- .../apache/cassandra/db/marshal/MapType.java | 37 +- .../cassandra/db/marshal/ReversedType.java | 42 +- .../apache/cassandra/db/marshal/SetType.java | 34 +- .../apache/cassandra/db/marshal/TupleType.java | 26 +- .../apache/cassandra/db/marshal/UserType.java | 83 ++-- .../apache/cassandra/db/view/TableViews.java | 2 +- src/java/org/apache/cassandra/db/view/View.java | 108 ++--- .../apache/cassandra/db/view/ViewManager.java | 6 +- .../hadoop/cql3/CqlBulkRecordWriter.java | 2 +- .../cassandra/index/SecondaryIndexManager.java | 2 +- .../apache/cassandra/index/TargetParser.java | 2 +- .../index/internal/CassandraIndex.java | 2 +- .../apache/cassandra/index/sasi/SASIIndex.java | 2 +- .../cassandra/io/sstable/CQLSSTableWriter.java | 46 +- .../apache/cassandra/repair/RepairRunnable.java | 3 +- .../repair/SystemDistributedKeyspace.java | 2 +- .../apache/cassandra/schema/ColumnMetadata.java | 30 +- .../cassandra/schema/CompressionParams.java | 22 +- src/java/org/apache/cassandra/schema/Diff.java | 59 +++ .../org/apache/cassandra/schema/Difference.java | 38 ++ .../org/apache/cassandra/schema/Functions.java | 146 ++++-- .../apache/cassandra/schema/IndexMetadata.java | 14 +- .../org/apache/cassandra/schema/Indexes.java | 30 -- .../cassandra/schema/KeyspaceMetadata.java | 136 +++++- .../apache/cassandra/schema/KeyspaceParams.java | 4 +- .../org/apache/cassandra/schema/Keyspaces.java | 85 +++- .../cassandra/schema/MigrationManager.java | 219 ++------- .../org/apache/cassandra/schema/Schema.java | 250 ++++++----- .../apache/cassandra/schema/SchemaKeyspace.java | 277 +++++------- .../cassandra/schema/SchemaTransformation.java | 31 ++ .../org/apache/cassandra/schema/TableId.java | 2 +- .../apache/cassandra/schema/TableMetadata.java | 145 ++++-- .../cassandra/schema/TableMetadataRef.java | 2 +- .../apache/cassandra/schema/TableParams.java | 2 +- .../org/apache/cassandra/schema/Tables.java | 91 +++- src/java/org/apache/cassandra/schema/Types.java | 74 +++- .../apache/cassandra/schema/ViewMetadata.java | 135 +++--- src/java/org/apache/cassandra/schema/Views.java | 117 +++-- .../apache/cassandra/service/ClientState.java | 74 ++-- .../cassandra/service/StorageService.java | 6 +- .../cassandra/tools/SSTableOfflineRelevel.java | 2 +- .../apache/cassandra/tracing/TraceKeyspace.java | 2 +- .../org/apache/cassandra/transport/Event.java | 13 + .../transport/messages/BatchMessage.java | 28 +- .../transport/messages/ExecuteMessage.java | 14 +- .../transport/messages/PrepareMessage.java | 8 +- .../transport/messages/QueryMessage.java | 10 +- .../transport/messages/ResultMessage.java | 3 - .../cassandra/triggers/TriggerExecutor.java | 8 +- .../test/microbench/MutationBench.java | 2 +- .../unit/org/apache/cassandra/SchemaLoader.java | 16 +- .../auth/CassandraNetworkAuthorizerTest.java | 10 +- .../org/apache/cassandra/cql3/CQLTester.java | 20 +- .../cassandra/cql3/PstmtPersistenceTest.java | 9 +- .../apache/cassandra/cql3/ViewComplexTest.java | 12 +- .../cassandra/cql3/ViewFilteringTest.java | 2 +- .../apache/cassandra/cql3/ViewSchemaTest.java | 6 +- .../org/apache/cassandra/cql3/ViewTest.java | 39 +- .../selection/SelectionColumnMappingTest.java | 8 +- .../cql3/statements/AlterRoleStatementTest.java | 3 +- .../statements/CreateRoleStatementTest.java | 3 +- .../statements/CreateUserStatementTest.java | 3 +- .../validation/entities/CollectionsTest.java | 10 +- .../cql3/validation/entities/CountersTest.java | 2 +- .../entities/FrozenCollectionsTest.java | 4 +- .../validation/entities/SecondaryIndexTest.java | 116 ++--- .../cql3/validation/entities/TypeTest.java | 4 +- .../cql3/validation/entities/UFAuthTest.java | 32 +- .../entities/UFIdentificationTest.java | 9 +- .../cql3/validation/entities/UFJavaTest.java | 4 +- .../cql3/validation/entities/UFTest.java | 53 ++- .../cql3/validation/entities/UFTypesTest.java | 30 +- .../cql3/validation/entities/UserTypesTest.java | 6 +- .../validation/entities/VirtualTableTest.java | 20 +- .../validation/operations/AggregationTest.java | 109 ++--- .../cql3/validation/operations/AlterTest.java | 19 +- .../cql3/validation/operations/CreateTest.java | 67 +-- .../cql3/validation/operations/DropTest.java | 4 +- .../operations/InsertUpdateIfConditionTest.java | 6 +- .../SelectSingleColumnRelationTest.java | 2 +- .../cql3/validation/operations/SelectTest.java | 4 +- .../apache/cassandra/db/DirectoriesTest.java | 2 +- .../apache/cassandra/db/RangeTombstoneTest.java | 2 +- .../apache/cassandra/db/RowIndexEntryTest.java | 2 +- .../apache/cassandra/db/SecondaryIndexTest.java | 2 +- .../apache/cassandra/db/TableCQLHelperTest.java | 4 +- .../compaction/AbstractPendingRepairTest.java | 8 +- .../db/compaction/CompactionTaskTest.java | 2 +- .../db/compaction/CompactionsPurgeTest.java | 2 +- ...tionManagerGetSSTablesForValidationTest.java | 5 +- .../db/repair/PendingAntiCompactionTest.java | 6 +- .../db/streaming/CassandraStreamHeaderTest.java | 2 +- .../streaming/CassandraStreamManagerTest.java | 2 +- .../cassandra/hints/HintWriteTTLTest.java | 2 +- .../apache/cassandra/index/CustomIndexTest.java | 8 +- .../index/internal/CassandraIndexTest.java | 4 +- .../index/internal/CustomCassandraIndex.java | 2 +- .../cassandra/index/sasi/SASIIndexTest.java | 2 +- .../repair/StreamingRepairTaskTest.java | 2 +- .../consistent/CoordinatorSessionsTest.java | 4 +- .../repair/consistent/LocalSessionTest.java | 4 +- .../cassandra/schema/IndexMetadataTest.java | 7 +- .../cassandra/schema/MigrationManagerTest.java | 2 +- .../cassandra/schema/SchemaKeyspaceTest.java | 2 +- .../cassandra/service/QueryPagerTest.java | 2 +- .../cassandra/transport/MessagePayloadTest.java | 3 +- .../cassandra/triggers/TriggersSchemaTest.java | 2 +- .../io/sstable/StressCQLSSTableWriter.java | 59 +-- .../cassandra/stress/CompactionStress.java | 4 +- .../apache/cassandra/stress/StressProfile.java | 14 +- 233 files changed, 7806 insertions(+), 7024 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index b66a1f6..63831d7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0 + * Make all DDL statements idempotent and not dependent on global state (CASSANDRA-13426) * Bump the hints messaging version to match the current one (CASSANDRA-14536) * OffsetAwareConfigurationLoader doesn't set ssl storage port causing bind errors in CircleCI (CASSANDRA-14546) * Report why native_transport_port fails to bind (CASSANDRA-14544) http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/NEWS.txt ---------------------------------------------------------------------- diff --git a/NEWS.txt b/NEWS.txt index e1e76de..da94422 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -172,6 +172,9 @@ Materialized Views now be logged when they are created. (See https://www.mail-archive.com/[email protected]/msg11511.html) - An 'enable_materialized_views' flag has been added to cassandra.yaml to allow operators to prevent creation of views + - CREATE MATERIALIZED VIEW syntax has become stricter. Partition key columns are no longer implicitly considered + to be NOT NULL, and no base primary key columns get automatically included in view definition. You have to + specify them explicitly now. 3.11.3 ===== http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/antlr/Cql.g ---------------------------------------------------------------------- diff --git a/src/antlr/Cql.g b/src/antlr/Cql.g index 17a11aa..272c63b 100644 --- a/src/antlr/Cql.g +++ b/src/antlr/Cql.g @@ -28,25 +28,21 @@ import Parser,Lexer; @header { package org.apache.cassandra.cql3; - import java.util.ArrayList; - import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; - import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.cassandra.auth.*; - import org.apache.cassandra.cql3.*; import org.apache.cassandra.cql3.conditions.*; import org.apache.cassandra.cql3.functions.*; import org.apache.cassandra.cql3.restrictions.CustomIndexExpression; import org.apache.cassandra.cql3.selection.*; import org.apache.cassandra.cql3.statements.*; - import org.apache.cassandra.db.marshal.CollectionType; + import org.apache.cassandra.cql3.statements.schema.*; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.exceptions.SyntaxException; @@ -95,8 +91,6 @@ import Parser,Lexer; @lexer::header { package org.apache.cassandra.cql3; - - import org.apache.cassandra.exceptions.SyntaxException; } @lexer::members { @@ -135,6 +129,6 @@ import Parser,Lexer; } } -query returns [ParsedStatement stmnt] +query returns [CQLStatement.Raw stmnt] : st=cqlStatement (';')* EOF { $stmnt = st; } ; http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/antlr/Parser.g ---------------------------------------------------------------------- diff --git a/src/antlr/Parser.g b/src/antlr/Parser.g index f32fd48..1cfc7d1 100644 --- a/src/antlr/Parser.g +++ b/src/antlr/Parser.g @@ -204,8 +204,8 @@ options { /** STATEMENTS **/ -cqlStatement returns [ParsedStatement stmt] - @after{ if (stmt != null) stmt.setBoundVariables(bindVariables); } +cqlStatement returns [CQLStatement.Raw stmt] + @after{ if (stmt != null) stmt.setBindVariables(bindVariables); } : st1= selectStatement { $stmt = st1; } | st2= insertStatement { $stmt = st2; } | st3= updateStatement { $stmt = st3; } @@ -436,8 +436,8 @@ selectionFunctionArgs returns [List<Selectable.Raw> a] sident returns [Selectable.Raw id] : t=IDENT { $id = Selectable.RawIdentifier.forUnquoted($t.text); } - | t=QUOTED_NAME { $id = ColumnMetadata.RawIdentifier.forQuoted($t.text); } - | k=unreserved_keyword { $id = ColumnMetadata.RawIdentifier.forUnquoted(k); } + | t=QUOTED_NAME { $id = Selectable.RawIdentifier.forQuoted($t.text); } + | k=unreserved_keyword { $id = Selectable.RawIdentifier.forUnquoted(k); } ; whereClause returns [WhereClause.Builder clause] @@ -451,7 +451,7 @@ relationOrExpression [WhereClause.Builder clause] ; customIndexExpression [WhereClause.Builder clause] - @init{IndexName name = new IndexName();} + @init{QualifiedName name = new QualifiedName();} : 'expr(' idxName[name] ',' t=term ')' { clause.add(new CustomIndexExpression(name, t));} ; @@ -478,7 +478,7 @@ insertStatement returns [ModificationStatement.Parsed expr] | K_JSON st2=jsonInsertStatement[cf] { $expr = st2; }) ; -normalInsertStatement [CFName cf] returns [UpdateStatement.ParsedInsert expr] +normalInsertStatement [QualifiedName qn] returns [UpdateStatement.ParsedInsert expr] @init { Attributes.Raw attrs = new Attributes.Raw(); List<ColumnMetadata.Raw> columnNames = new ArrayList<>(); @@ -491,11 +491,11 @@ normalInsertStatement [CFName cf] returns [UpdateStatement.ParsedInsert expr] ( K_IF K_NOT K_EXISTS { ifNotExists = true; } )? ( usingClause[attrs] )? { - $expr = new UpdateStatement.ParsedInsert(cf, attrs, columnNames, values, ifNotExists); + $expr = new UpdateStatement.ParsedInsert(qn, attrs, columnNames, values, ifNotExists); } ; -jsonInsertStatement [CFName cf] returns [UpdateStatement.ParsedInsertJson expr] +jsonInsertStatement [QualifiedName qn] returns [UpdateStatement.ParsedInsertJson expr] @init { Attributes.Raw attrs = new Attributes.Raw(); boolean ifNotExists = false; @@ -506,7 +506,7 @@ jsonInsertStatement [CFName cf] returns [UpdateStatement.ParsedInsertJson expr] ( K_IF K_NOT K_EXISTS { ifNotExists = true; } )? ( usingClause[attrs] )? { - $expr = new UpdateStatement.ParsedInsertJson(cf, attrs, val, defaultUnset, ifNotExists); + $expr = new UpdateStatement.ParsedInsertJson(qn, attrs, val, defaultUnset, ifNotExists); } ; @@ -649,12 +649,12 @@ batchStatementObjective returns [ModificationStatement.Parsed statement] | d=deleteStatement { $statement = d; } ; -createAggregateStatement returns [CreateAggregateStatement expr] +createAggregateStatement returns [CreateAggregateStatement.Raw stmt] @init { boolean orReplace = false; boolean ifNotExists = false; - List<CQL3Type.Raw> argsTypes = new ArrayList<>(); + List<CQL3Type.Raw> argTypes = new ArrayList<>(); } : K_CREATE (K_OR K_REPLACE { orReplace = true; })? K_AGGREGATE @@ -662,8 +662,8 @@ createAggregateStatement returns [CreateAggregateStatement expr] fn=functionName '(' ( - v=comparatorType { argsTypes.add(v); } - ( ',' v=comparatorType { argsTypes.add(v); } )* + v=comparatorType { argTypes.add(v); } + ( ',' v=comparatorType { argTypes.add(v); } )* )? ')' K_SFUNC sfunc = allowedFunctionName @@ -674,14 +674,14 @@ createAggregateStatement returns [CreateAggregateStatement expr] ( K_INITCOND ival = term )? - { $expr = new CreateAggregateStatement(fn, argsTypes, sfunc, stype, ffunc, ival, orReplace, ifNotExists); } + { $stmt = new CreateAggregateStatement.Raw(fn, argTypes, stype, sfunc, ffunc, ival, orReplace, ifNotExists); } ; -dropAggregateStatement returns [DropAggregateStatement expr] +dropAggregateStatement returns [DropAggregateStatement.Raw stmt] @init { boolean ifExists = false; - List<CQL3Type.Raw> argsTypes = new ArrayList<>(); - boolean argsPresent = false; + List<CQL3Type.Raw> argTypes = new ArrayList<>(); + boolean argsSpecified = false; } : K_DROP K_AGGREGATE (K_IF K_EXISTS { ifExists = true; } )? @@ -689,22 +689,22 @@ dropAggregateStatement returns [DropAggregateStatement expr] ( '(' ( - v=comparatorType { argsTypes.add(v); } - ( ',' v=comparatorType { argsTypes.add(v); } )* + v=comparatorType { argTypes.add(v); } + ( ',' v=comparatorType { argTypes.add(v); } )* )? ')' - { argsPresent = true; } + { argsSpecified = true; } )? - { $expr = new DropAggregateStatement(fn, argsTypes, argsPresent, ifExists); } + { $stmt = new DropAggregateStatement.Raw(fn, argTypes, argsSpecified, ifExists); } ; -createFunctionStatement returns [CreateFunctionStatement expr] +createFunctionStatement returns [CreateFunctionStatement.Raw stmt] @init { boolean orReplace = false; boolean ifNotExists = false; - List<ColumnIdentifier> argsNames = new ArrayList<>(); - List<CQL3Type.Raw> argsTypes = new ArrayList<>(); + List<ColumnIdentifier> argNames = new ArrayList<>(); + List<CQL3Type.Raw> argTypes = new ArrayList<>(); boolean calledOnNullInput = false; } : K_CREATE (K_OR K_REPLACE { orReplace = true; })? @@ -713,23 +713,24 @@ createFunctionStatement returns [CreateFunctionStatement expr] fn=functionName '(' ( - k=noncol_ident v=comparatorType { argsNames.add(k); argsTypes.add(v); } - ( ',' k=noncol_ident v=comparatorType { argsNames.add(k); argsTypes.add(v); } )* + k=noncol_ident v=comparatorType { argNames.add(k); argTypes.add(v); } + ( ',' k=noncol_ident v=comparatorType { argNames.add(k); argTypes.add(v); } )* )? ')' ( (K_RETURNS K_NULL) | (K_CALLED { calledOnNullInput=true; })) K_ON K_NULL K_INPUT - K_RETURNS rt = comparatorType + K_RETURNS returnType = comparatorType K_LANGUAGE language = IDENT K_AS body = STRING_LITERAL - { $expr = new CreateFunctionStatement(fn, $language.text.toLowerCase(), $body.text, - argsNames, argsTypes, rt, calledOnNullInput, orReplace, ifNotExists); } + { $stmt = new CreateFunctionStatement.Raw( + fn, argNames, argTypes, returnType, calledOnNullInput, $language.text.toLowerCase(), $body.text, orReplace, ifNotExists); + } ; -dropFunctionStatement returns [DropFunctionStatement expr] +dropFunctionStatement returns [DropFunctionStatement.Raw stmt] @init { boolean ifExists = false; - List<CQL3Type.Raw> argsTypes = new ArrayList<>(); - boolean argsPresent = false; + List<CQL3Type.Raw> argTypes = new ArrayList<>(); + boolean argsSpecified = false; } : K_DROP K_FUNCTION (K_IF K_EXISTS { ifExists = true; } )? @@ -737,72 +738,71 @@ dropFunctionStatement returns [DropFunctionStatement expr] ( '(' ( - v=comparatorType { argsTypes.add(v); } - ( ',' v=comparatorType { argsTypes.add(v); } )* + v=comparatorType { argTypes.add(v); } + ( ',' v=comparatorType { argTypes.add(v); } )* )? ')' - { argsPresent = true; } + { argsSpecified = true; } )? - { $expr = new DropFunctionStatement(fn, argsTypes, argsPresent, ifExists); } + { $stmt = new DropFunctionStatement.Raw(fn, argTypes, argsSpecified, ifExists); } ; /** * CREATE KEYSPACE [IF NOT EXISTS] <KEYSPACE> WITH attr1 = value1 AND attr2 = value2; */ -createKeyspaceStatement returns [CreateKeyspaceStatement expr] +createKeyspaceStatement returns [CreateKeyspaceStatement.Raw stmt] @init { KeyspaceAttributes attrs = new KeyspaceAttributes(); boolean ifNotExists = false; } : K_CREATE K_KEYSPACE (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? ks=keyspaceName - K_WITH properties[attrs] { $expr = new CreateKeyspaceStatement(ks, attrs, ifNotExists); } + K_WITH properties[attrs] { $stmt = new CreateKeyspaceStatement.Raw(ks, attrs, ifNotExists); } ; /** - * CREATE COLUMNFAMILY [IF NOT EXISTS] <CF> ( + * CREATE TABLE [IF NOT EXISTS] <CF> ( * <name1> <type>, * <name2> <type>, * <name3> <type> * ) WITH <property> = <value> AND ...; */ -createTableStatement returns [CreateTableStatement.RawStatement expr] +createTableStatement returns [CreateTableStatement.Raw stmt] @init { boolean ifNotExists = false; } : K_CREATE K_COLUMNFAMILY (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? - cf=columnFamilyName { $expr = new CreateTableStatement.RawStatement(cf, ifNotExists); } - cfamDefinition[expr] + cf=columnFamilyName { $stmt = new CreateTableStatement.Raw(cf, ifNotExists); } + tableDefinition[stmt] ; -cfamDefinition[CreateTableStatement.RawStatement expr] - : '(' cfamColumns[expr] ( ',' cfamColumns[expr]? )* ')' - ( K_WITH cfamProperty[expr.properties] ( K_AND cfamProperty[expr.properties] )*)? +tableDefinition[CreateTableStatement.Raw stmt] + : '(' tableColumns[stmt] ( ',' tableColumns[stmt]? )* ')' + ( K_WITH tableProperty[stmt] ( K_AND tableProperty[stmt] )*)? ; -cfamColumns[CreateTableStatement.RawStatement expr] +tableColumns[CreateTableStatement.Raw stmt] @init { boolean isStatic = false; } - : k=ident v=comparatorType (K_STATIC {isStatic = true;})? { $expr.addDefinition(k, v, isStatic); } - (K_PRIMARY K_KEY { $expr.addKeyAliases(Collections.singletonList(k)); })? - | K_PRIMARY K_KEY '(' pkDef[expr] (',' c=ident { $expr.addColumnAlias(c); } )* ')' + : k=ident v=comparatorType (K_STATIC { isStatic = true; })? { $stmt.addColumn(k, v, isStatic); } + (K_PRIMARY K_KEY { $stmt.setPartitionKeyColumn(k); })? + | K_PRIMARY K_KEY '(' tablePartitionKey[stmt] (',' c=ident { $stmt.markClusteringColumn(c); } )* ')' ; -pkDef[CreateTableStatement.RawStatement expr] +tablePartitionKey[CreateTableStatement.Raw stmt] @init {List<ColumnIdentifier> l = new ArrayList<ColumnIdentifier>();} - @after{ $expr.addKeyAliases(l); } + @after{ $stmt.setPartitionKeyColumns(l); } : k1=ident { l.add(k1);} | '(' k1=ident { l.add(k1); } ( ',' kn=ident { l.add(kn); } )* ')' ; -cfamProperty[CFProperties props] - : property[props.properties] - | K_COMPACT K_STORAGE { throw new SyntaxException("Compact tables are not allowed in Cassandra starting with 4.0 version."); } - | K_CLUSTERING K_ORDER K_BY '(' cfamOrdering[props] (',' cfamOrdering[props])* ')' +tableProperty[CreateTableStatement.Raw stmt] + : property[stmt.attrs] + | K_COMPACT K_STORAGE { throw new SyntaxException("COMPACT STORAGE tables are not allowed starting with version 4.0"); } + | K_CLUSTERING K_ORDER K_BY '(' tableClusteringOrder[stmt] (',' tableClusteringOrder[stmt])* ')' ; -cfamOrdering[CFProperties props] - @init{ boolean reversed=false; } - : k=ident (K_ASC | K_DESC { reversed=true;} ) { $props.setOrdering(k, reversed); } +tableClusteringOrder[CreateTableStatement.Raw stmt] + @init{ boolean ascending = true; } + : k=ident (K_ASC | K_DESC { ascending = false; } ) { $stmt.extendClusteringOrder(k, ascending); } ; - /** * CREATE TYPE foo ( * <name1> <type1>, @@ -810,34 +810,33 @@ cfamOrdering[CFProperties props] * .... * ) */ -createTypeStatement returns [CreateTypeStatement expr] +createTypeStatement returns [CreateTypeStatement.Raw stmt] @init { boolean ifNotExists = false; } : K_CREATE K_TYPE (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? - tn=userTypeName { $expr = new CreateTypeStatement(tn, ifNotExists); } - '(' typeColumns[expr] ( ',' typeColumns[expr]? )* ')' + tn=userTypeName { $stmt = new CreateTypeStatement.Raw(tn, ifNotExists); } + '(' typeColumns[stmt] ( ',' typeColumns[stmt]? )* ')' ; -typeColumns[CreateTypeStatement expr] - : k=fident v=comparatorType { $expr.addDefinition(k, v); } +typeColumns[CreateTypeStatement.Raw stmt] + : k=fident v=comparatorType { $stmt.addField(k, v); } ; - /** * CREATE INDEX [IF NOT EXISTS] [indexName] ON <columnFamily> (<columnName>); * CREATE CUSTOM INDEX [IF NOT EXISTS] [indexName] ON <columnFamily> (<columnName>) USING <indexClass>; */ -createIndexStatement returns [CreateIndexStatement expr] +createIndexStatement returns [CreateIndexStatement.Raw stmt] @init { - IndexPropDefs props = new IndexPropDefs(); + IndexAttributes props = new IndexAttributes(); boolean ifNotExists = false; - IndexName name = new IndexName(); + QualifiedName name = new QualifiedName(); List<IndexTarget.Raw> targets = new ArrayList<>(); } : K_CREATE (K_CUSTOM { props.isCustom = true; })? K_INDEX (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? (idxName[name])? K_ON cf=columnFamilyName '(' (indexIdent[targets] (',' indexIdent[targets])*)? ')' (K_USING cls=STRING_LITERAL { props.customClass = $cls.text; })? (K_WITH properties[props])? - { $expr = new CreateIndexStatement(cf, name, targets, props, ifNotExists); } + { $stmt = new CreateIndexStatement.Raw(cf, name, targets, props, ifNotExists); } ; indexIdent [List<IndexTarget.Raw> targets] @@ -856,106 +855,114 @@ indexIdent [List<IndexTarget.Raw> targets] * PRIMARY KEY (<pkColumns>) * WITH <property> = <value> AND ...; */ -createMaterializedViewStatement returns [CreateViewStatement expr] +createMaterializedViewStatement returns [CreateViewStatement.Raw stmt] @init { boolean ifNotExists = false; - List<ColumnMetadata.Raw> partitionKeys = new ArrayList<>(); - List<ColumnMetadata.Raw> compositeKeys = new ArrayList<>(); } : K_CREATE K_MATERIALIZED K_VIEW (K_IF K_NOT K_EXISTS { ifNotExists = true; })? cf=columnFamilyName K_AS K_SELECT sclause=selectors K_FROM basecf=columnFamilyName (K_WHERE wclause=whereClause)? - K_PRIMARY K_KEY ( - '(' '(' k1=cident { partitionKeys.add(k1); } ( ',' kn=cident { partitionKeys.add(kn); } )* ')' ( ',' c1=cident { compositeKeys.add(c1); } )* ')' - | '(' k1=cident { partitionKeys.add(k1); } ( ',' cn=cident { compositeKeys.add(cn); } )* ')' - ) { WhereClause where = wclause == null ? WhereClause.empty() : wclause.build(); - $expr = new CreateViewStatement(cf, basecf, sclause, where, partitionKeys, compositeKeys, ifNotExists); + $stmt = new CreateViewStatement.Raw(basecf, cf, sclause, where, ifNotExists); } - ( K_WITH cfamProperty[expr.properties] ( K_AND cfamProperty[expr.properties] )*)? + viewPrimaryKey[stmt] + ( K_WITH viewProperty[stmt] ( K_AND viewProperty[stmt] )*)? + ; + +viewPrimaryKey[CreateViewStatement.Raw stmt] + : K_PRIMARY K_KEY '(' viewPartitionKey[stmt] (',' c=ident { $stmt.markClusteringColumn(c); } )* ')' + ; + +viewPartitionKey[CreateViewStatement.Raw stmt] + @init {List<ColumnIdentifier> l = new ArrayList<ColumnIdentifier>();} + @after{ $stmt.setPartitionKeyColumns(l); } + : k1=ident { l.add(k1);} + | '(' k1=ident { l.add(k1); } ( ',' kn=ident { l.add(kn); } )* ')' + ; + +viewProperty[CreateViewStatement.Raw stmt] + : property[stmt.attrs] + | K_COMPACT K_STORAGE { throw new SyntaxException("COMPACT STORAGE tables are not allowed starting with version 4.0"); } + | K_CLUSTERING K_ORDER K_BY '(' viewClusteringOrder[stmt] (',' viewClusteringOrder[stmt])* ')' + ; + +viewClusteringOrder[CreateViewStatement.Raw stmt] + @init{ boolean ascending = true; } + : k=ident (K_ASC | K_DESC { ascending = false; } ) { $stmt.extendClusteringOrder(k, ascending); } ; /** * CREATE TRIGGER triggerName ON columnFamily USING 'triggerClass'; */ -createTriggerStatement returns [CreateTriggerStatement expr] +createTriggerStatement returns [CreateTriggerStatement.Raw stmt] @init { boolean ifNotExists = false; } : K_CREATE K_TRIGGER (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? (name=ident) K_ON cf=columnFamilyName K_USING cls=STRING_LITERAL - { $expr = new CreateTriggerStatement(cf, name.toString(), $cls.text, ifNotExists); } + { $stmt = new CreateTriggerStatement.Raw(cf, name.toString(), $cls.text, ifNotExists); } ; /** * DROP TRIGGER [IF EXISTS] triggerName ON columnFamily; */ -dropTriggerStatement returns [DropTriggerStatement expr] +dropTriggerStatement returns [DropTriggerStatement.Raw stmt] @init { boolean ifExists = false; } : K_DROP K_TRIGGER (K_IF K_EXISTS { ifExists = true; } )? (name=ident) K_ON cf=columnFamilyName - { $expr = new DropTriggerStatement(cf, name.toString(), ifExists); } + { $stmt = new DropTriggerStatement.Raw(cf, name.toString(), ifExists); } ; /** * ALTER KEYSPACE <KS> WITH <property> = <value>; */ -alterKeyspaceStatement returns [AlterKeyspaceStatement expr] +alterKeyspaceStatement returns [AlterKeyspaceStatement.Raw stmt] @init { KeyspaceAttributes attrs = new KeyspaceAttributes(); } : K_ALTER K_KEYSPACE ks=keyspaceName - K_WITH properties[attrs] { $expr = new AlterKeyspaceStatement(ks, attrs); } + K_WITH properties[attrs] { $stmt = new AlterKeyspaceStatement.Raw(ks, attrs); } ; /** - * ALTER COLUMN FAMILY <CF> ALTER <column> TYPE <newtype>; - * ALTER COLUMN FAMILY <CF> ADD <column> <newtype>; | ALTER COLUMN FAMILY <CF> ADD (<column> <newtype>,<column1> <newtype1>..... <column n> <newtype n>) - * ALTER COLUMN FAMILY <CF> DROP <column>; | ALTER COLUMN FAMILY <CF> DROP ( <column>,<column1>.....<column n>) - * ALTER COLUMN FAMILY <CF> WITH <property> = <value>; - * ALTER COLUMN FAMILY <CF> RENAME <column> TO <column>; + * ALTER TABLE <table> ALTER <column> TYPE <newtype>; + * ALTER TABLE <table> ADD <column> <newtype>; | ALTER TABLE <table> ADD (<column> <newtype>,<column1> <newtype1>..... <column n> <newtype n>) + * ALTER TABLE <table> DROP <column>; | ALTER TABLE <table> DROP ( <column>,<column1>.....<column n>) + * ALTER TABLE <table> RENAME <column> TO <column>; + * ALTER TABLE <table> WITH <property> = <value>; */ -alterTableStatement returns [AlterTableStatement expr] - @init { - AlterTableStatement.Type type = null; - TableAttributes attrs = new TableAttributes(); - Map<ColumnMetadata.Raw, ColumnMetadata.Raw> renames = new HashMap<ColumnMetadata.Raw, ColumnMetadata.Raw>(); - List<AlterTableStatementColumn> colNameList = new ArrayList<AlterTableStatementColumn>(); - Long deleteTimestamp = null; - } - : K_ALTER K_COLUMNFAMILY cf=columnFamilyName - ( K_ALTER id=schema_cident K_TYPE v=comparatorType { type = AlterTableStatement.Type.ALTER; } { colNameList.add(new AlterTableStatementColumn(id,v)); } - | K_ADD ( (aid=schema_cident v=comparatorType b1=cfisStatic { colNameList.add(new AlterTableStatementColumn(aid,v,b1)); }) - | ('(' id1=schema_cident v1=comparatorType b1=cfisStatic { colNameList.add(new AlterTableStatementColumn(id1,v1,b1)); } - ( ',' idn=schema_cident vn=comparatorType bn=cfisStatic { colNameList.add(new AlterTableStatementColumn(idn,vn,bn)); } )* ')' ) ) { type = AlterTableStatement.Type.ADD; } - | K_DROP ( ( id=schema_cident { colNameList.add(new AlterTableStatementColumn(id)); } - | ('(' id1=schema_cident { colNameList.add(new AlterTableStatementColumn(id1)); } - ( ',' idn=schema_cident { colNameList.add(new AlterTableStatementColumn(idn)); } )* ')') ) - ( K_USING K_TIMESTAMP t=INTEGER { deleteTimestamp = Long.parseLong(Constants.Literal.integer($t.text).getText()); })? ) { type = AlterTableStatement.Type.DROP; } - | K_WITH properties[attrs] { type = AlterTableStatement.Type.OPTS; } - | K_RENAME { type = AlterTableStatement.Type.RENAME; } - id1=schema_cident K_TO toId1=schema_cident { renames.put(id1, toId1); } - ( K_AND idn=schema_cident K_TO toIdn=schema_cident { renames.put(idn, toIdn); } )* - ) - { - $expr = new AlterTableStatement(cf, type, colNameList, attrs, renames, deleteTimestamp); - } +alterTableStatement returns [AlterTableStatement.Raw stmt] + : K_ALTER K_COLUMNFAMILY cf=columnFamilyName { $stmt = new AlterTableStatement.Raw(cf); } + ( + K_ALTER id=cident K_TYPE v=comparatorType { $stmt.alter(id, v); } + + | K_ADD ( id=schema_cident v=comparatorType b=isStaticColumn { $stmt.add(id, v, b); } + | ('(' id1=schema_cident v1=comparatorType b1=isStaticColumn { $stmt.add(id1, v1, b1); } + ( ',' idn=schema_cident vn=comparatorType bn=isStaticColumn { $stmt.add(idn, vn, bn); } )* ')') ) + + | K_DROP ( id=schema_cident { $stmt.drop(id); } + | ('(' id1=schema_cident { $stmt.drop(id1); } + ( ',' idn=schema_cident { $stmt.drop(idn); } )* ')') ) + ( K_USING K_TIMESTAMP t=INTEGER { $stmt.timestamp(Long.parseLong(Constants.Literal.integer($t.text).getText())); } )? + + | K_RENAME id1=schema_cident K_TO toId1=schema_cident { $stmt.rename(id1, toId1); } + ( K_AND idn=schema_cident K_TO toIdn=schema_cident { $stmt.rename(idn, toIdn); } )* + + | K_WITH properties[$stmt.attrs] { $stmt.attrs(); } + ) ; -cfisStatic returns [boolean isStaticColumn] - @init{ - boolean isStatic = false; - } - : (K_STATIC { isStatic=true; })? { $isStaticColumn = isStatic; - } +isStaticColumn returns [boolean isStaticColumn] + @init { boolean isStatic = false; } + : (K_STATIC { isStatic=true; })? { $isStaticColumn = isStatic; } ; -alterMaterializedViewStatement returns [AlterViewStatement expr] +alterMaterializedViewStatement returns [AlterViewStatement.Raw stmt] @init { TableAttributes attrs = new TableAttributes(); } : K_ALTER K_MATERIALIZED K_VIEW name=columnFamilyName K_WITH properties[attrs] { - $expr = new AlterViewStatement(name, attrs); + $stmt = new AlterViewStatement.Raw(name, attrs); } ; @@ -965,59 +972,58 @@ alterMaterializedViewStatement returns [AlterViewStatement expr] * ALTER TYPE <name> ADD <field> <newtype>; * ALTER TYPE <name> RENAME <field> TO <newtype> AND ...; */ -alterTypeStatement returns [AlterTypeStatement expr] - : K_ALTER K_TYPE name=userTypeName - ( K_ALTER f=fident K_TYPE v=comparatorType { $expr = AlterTypeStatement.alter(name, f, v); } - | K_ADD f=fident v=comparatorType { $expr = AlterTypeStatement.addition(name, f, v); } - | K_RENAME r=renamedColumns { $expr = AlterTypeStatement.renames(name, r); } - ) - ; +alterTypeStatement returns [AlterTypeStatement.Raw stmt] + : K_ALTER K_TYPE name=userTypeName { $stmt = new AlterTypeStatement.Raw(name); } + ( + K_ALTER f=fident K_TYPE v=comparatorType { $stmt.alter(f, v); } + + | K_ADD f=fident v=comparatorType { $stmt.add(f, v); } -renamedColumns returns [Map<FieldIdentifier, FieldIdentifier> renames] - @init {$renames = new HashMap<>();} - : id1=fident K_TO toId1=fident { renames.put(id1, toId1); } ( K_AND idn=fident K_TO toIdn=fident { renames.put(idn, toIdn); } )* + | K_RENAME f1=fident K_TO toF1=fident { $stmt.rename(f1, toF1); } + ( K_AND fn=fident K_TO toFn=fident { $stmt.rename(fn, toFn); } )* + ) ; /** * DROP KEYSPACE [IF EXISTS] <KSP>; */ -dropKeyspaceStatement returns [DropKeyspaceStatement ksp] +dropKeyspaceStatement returns [DropKeyspaceStatement.Raw stmt] @init { boolean ifExists = false; } - : K_DROP K_KEYSPACE (K_IF K_EXISTS { ifExists = true; } )? ks=keyspaceName { $ksp = new DropKeyspaceStatement(ks, ifExists); } + : K_DROP K_KEYSPACE (K_IF K_EXISTS { ifExists = true; } )? ks=keyspaceName { $stmt = new DropKeyspaceStatement.Raw(ks, ifExists); } ; /** - * DROP COLUMNFAMILY [IF EXISTS] <CF>; + * DROP TABLE [IF EXISTS] <table>; */ -dropTableStatement returns [DropTableStatement stmt] +dropTableStatement returns [DropTableStatement.Raw stmt] @init { boolean ifExists = false; } - : K_DROP K_COLUMNFAMILY (K_IF K_EXISTS { ifExists = true; } )? cf=columnFamilyName { $stmt = new DropTableStatement(cf, ifExists); } + : K_DROP K_COLUMNFAMILY (K_IF K_EXISTS { ifExists = true; } )? name=columnFamilyName { $stmt = new DropTableStatement.Raw(name, ifExists); } ; /** * DROP TYPE <name>; */ -dropTypeStatement returns [DropTypeStatement stmt] +dropTypeStatement returns [DropTypeStatement.Raw stmt] @init { boolean ifExists = false; } - : K_DROP K_TYPE (K_IF K_EXISTS { ifExists = true; } )? name=userTypeName { $stmt = new DropTypeStatement(name, ifExists); } + : K_DROP K_TYPE (K_IF K_EXISTS { ifExists = true; } )? name=userTypeName { $stmt = new DropTypeStatement.Raw(name, ifExists); } ; /** * DROP INDEX [IF EXISTS] <INDEX_NAME> */ -dropIndexStatement returns [DropIndexStatement expr] +dropIndexStatement returns [DropIndexStatement.Raw stmt] @init { boolean ifExists = false; } : K_DROP K_INDEX (K_IF K_EXISTS { ifExists = true; } )? index=indexName - { $expr = new DropIndexStatement(index, ifExists); } + { $stmt = new DropIndexStatement.Raw(index, ifExists); } ; /** * DROP MATERIALIZED VIEW [IF EXISTS] <view_name> */ -dropMaterializedViewStatement returns [DropViewStatement expr] +dropMaterializedViewStatement returns [DropViewStatement.Raw stmt] @init { boolean ifExists = false; } : K_DROP K_MATERIALIZED K_VIEW (K_IF K_EXISTS { ifExists = true; } )? cf=columnFamilyName - { $expr = new DropViewStatement(cf, ifExists); } + { $stmt = new DropViewStatement.Raw(cf, ifExists); } ; /** @@ -1110,7 +1116,7 @@ dataResource returns [DataResource res] : K_ALL K_KEYSPACES { $res = DataResource.root(); } | K_KEYSPACE ks = keyspaceName { $res = DataResource.keyspace($ks.id); } | ( K_COLUMNFAMILY )? cf = columnFamilyName - { $res = DataResource.table($cf.name.getKeyspace(), $cf.name.getColumnFamily()); } + { $res = DataResource.table($cf.name.getKeyspace(), $cf.name.getName()); } ; jmxResource returns [JMXResource res] @@ -1336,17 +1342,17 @@ noncol_ident returns [ColumnIdentifier id] // Keyspace & Column family names keyspaceName returns [String id] - @init { CFName name = new CFName(); } + @init { QualifiedName name = new QualifiedName(); } : ksName[name] { $id = name.getKeyspace(); } ; -indexName returns [IndexName name] - @init { $name = new IndexName(); } +indexName returns [QualifiedName name] + @init { $name = new QualifiedName(); } : (ksName[name] '.')? idxName[name] ; -columnFamilyName returns [CFName name] - @init { $name = new CFName(); } +columnFamilyName returns [QualifiedName name] + @init { $name = new QualifiedName(); } : (ksName[name] '.')? cfName[name] ; @@ -1359,24 +1365,24 @@ userOrRoleName returns [RoleName name] : roleName[role] {$name = role;} ; -ksName[KeyspaceElementName name] +ksName[QualifiedName name] : t=IDENT { $name.setKeyspace($t.text, false);} | t=QUOTED_NAME { $name.setKeyspace($t.text, true);} | k=unreserved_keyword { $name.setKeyspace(k, false);} | QMARK {addRecognitionError("Bind variables cannot be used for keyspace names");} ; -cfName[CFName name] - : t=IDENT { $name.setColumnFamily($t.text, false); } - | t=QUOTED_NAME { $name.setColumnFamily($t.text, true); } - | k=unreserved_keyword { $name.setColumnFamily(k, false); } +cfName[QualifiedName name] + : t=IDENT { $name.setName($t.text, false); } + | t=QUOTED_NAME { $name.setName($t.text, true); } + | k=unreserved_keyword { $name.setName(k, false); } | QMARK {addRecognitionError("Bind variables cannot be used for table names");} ; -idxName[IndexName name] - : t=IDENT { $name.setIndex($t.text, false); } - | t=QUOTED_NAME { $name.setIndex($t.text, true);} - | k=unreserved_keyword { $name.setIndex(k, false); } +idxName[QualifiedName name] + : t=IDENT { $name.setName($t.text, false); } + | t=QUOTED_NAME { $name.setName($t.text, true);} + | k=unreserved_keyword { $name.setName(k, false); } | QMARK {addRecognitionError("Bind variables cannot be used for index names");} ; @@ -1714,7 +1720,7 @@ comparatorType returns [CQL3Type.Raw t] | K_FROZEN '<' f=comparatorType '>' { try { - $t = CQL3Type.Raw.frozen(f); + $t = f.freeze(); } catch (InvalidRequestException e) { addRecognitionError(e.getMessage()); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/audit/AuditLogContext.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/audit/AuditLogContext.java b/src/java/org/apache/cassandra/audit/AuditLogContext.java new file mode 100644 index 0000000..9b44cf3 --- /dev/null +++ b/src/java/org/apache/cassandra/audit/AuditLogContext.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.audit; + +public class AuditLogContext +{ + public final AuditLogEntryType auditLogEntryType; + public final String keyspace; + public final String scope; + + public AuditLogContext(AuditLogEntryType auditLogEntryType) + { + this(auditLogEntryType, null, null); + } + + public AuditLogContext(AuditLogEntryType auditLogEntryType, String keyspace) + { + this(auditLogEntryType, keyspace, null); + } + + public AuditLogContext(AuditLogEntryType auditLogEntryType, String keyspace, String scope) + { + this.auditLogEntryType = auditLogEntryType; + this.keyspace = keyspace; + this.scope = scope; + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/audit/AuditLogManager.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/audit/AuditLogManager.java b/src/java/org/apache/cassandra/audit/AuditLogManager.java index 090499c..9e6a0a1 100644 --- a/src/java/org/apache/cassandra/audit/AuditLogManager.java +++ b/src/java/org/apache/cassandra/audit/AuditLogManager.java @@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.CQLStatement; +import org.apache.cassandra.cql3.QueryHandler; import org.apache.cassandra.cql3.QueryOptions; -import org.apache.cassandra.cql3.statements.ParsedStatement; import org.apache.cassandra.exceptions.AuthenticationException; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.UnauthorizedException; @@ -187,7 +187,7 @@ public class AuditLogManager /** * Logs Batch queries to both FQL and standard audit logger. */ - public void logBatch(String batchTypeName, List<Object> queryOrIdList, List<List<ByteBuffer>> values, List<ParsedStatement.Prepared> prepared, QueryOptions options, QueryState state, long queryStartTimeMillis) + public void logBatch(String batchTypeName, List<Object> queryOrIdList, List<List<ByteBuffer>> values, List<QueryHandler.Prepared> prepared, QueryOptions options, QueryState state, long queryStartTimeMillis) { if (isAuditingEnabled()) { @@ -201,7 +201,7 @@ public class AuditLogManager if (isFQLEnabled()) { List<String> queryStrings = new ArrayList<>(queryOrIdList.size()); - for (ParsedStatement.Prepared prepStatment : prepared) + for (QueryHandler.Prepared prepStatment : prepared) { queryStrings.add(prepStatment.rawCQLStatement); } @@ -209,7 +209,7 @@ public class AuditLogManager } } - private static List<AuditLogEntry> buildEntriesForBatch(List<Object> queryOrIdList, List<ParsedStatement.Prepared> prepared, QueryState state, QueryOptions options, long queryStartTimeMillis) + private static List<AuditLogEntry> buildEntriesForBatch(List<Object> queryOrIdList, List<QueryHandler.Prepared> prepared, QueryState state, QueryOptions options, long queryStartTimeMillis) { List<AuditLogEntry> auditLogEntries = new ArrayList<>(queryOrIdList.size() + 1); UUID batchId = UUID.randomUUID(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/audit/IAuditLogContext.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/audit/IAuditLogContext.java b/src/java/org/apache/cassandra/audit/IAuditLogContext.java deleted file mode 100644 index 55c3e04..0000000 --- a/src/java/org/apache/cassandra/audit/IAuditLogContext.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.audit; - -import org.apache.cassandra.cql3.CQLStatement; - -/** - * Provides the context needed for audit logging statements. - * {@link CQLStatement} implements this interface such that every CQL command provides the context needed for AuditLog. - */ -public interface IAuditLogContext -{ - AuditLogContext getAuditLogContext(); - - static class AuditLogContext - { - public final AuditLogEntryType auditLogEntryType; - public final String keyspace; - public final String scope; - - public AuditLogContext(AuditLogEntryType auditLogEntryType) - { - this(auditLogEntryType,null,null); - } - - public AuditLogContext(AuditLogEntryType auditLogEntryType, String keyspace) - { - this(auditLogEntryType,keyspace,null); - } - - public AuditLogContext(AuditLogEntryType auditLogEntryType, String keyspace, String scope) - { - this.auditLogEntryType = auditLogEntryType; - this.keyspace = keyspace; - this.scope = scope; - } - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/AuthKeyspace.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/AuthKeyspace.java b/src/java/org/apache/cassandra/auth/AuthKeyspace.java index 1f71bdc..3f95b19 100644 --- a/src/java/org/apache/cassandra/auth/AuthKeyspace.java +++ b/src/java/org/apache/cassandra/auth/AuthKeyspace.java @@ -19,7 +19,7 @@ package org.apache.cassandra.auth; import java.util.concurrent.TimeUnit; -import org.apache.cassandra.cql3.statements.CreateTableStatement; +import org.apache.cassandra.cql3.statements.schema.CreateTableStatement; import org.apache.cassandra.schema.TableId; import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.schema.SchemaConstants; http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/AuthenticatedUser.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/AuthenticatedUser.java b/src/java/org/apache/cassandra/auth/AuthenticatedUser.java index c608068..3d7c078 100644 --- a/src/java/org/apache/cassandra/auth/AuthenticatedUser.java +++ b/src/java/org/apache/cassandra/auth/AuthenticatedUser.java @@ -84,7 +84,7 @@ public class AuthenticatedUser /** * Some internal operations are performed on behalf of Cassandra itself, in those cases * the system user should be used where an identity is required - * see CreateRoleStatement#execute() and overrides of SchemaAlteringStatement#grantPermissionsToCreator() + * see CreateRoleStatement#execute() and overrides of AlterSchemaStatement#createdResources() */ public boolean isSystem() { http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java index 5140bcf..cebde13 100644 --- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java +++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java @@ -27,7 +27,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.DatabaseDescriptor; -import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.cql3.*; import org.apache.cassandra.cql3.statements.BatchStatement; import org.apache.cassandra.cql3.statements.ModificationStatement; @@ -35,11 +34,8 @@ import org.apache.cassandra.cql3.statements.SelectStatement; import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.exceptions.*; +import org.apache.cassandra.schema.SchemaConstants; import org.apache.cassandra.service.ClientState; - -import org.apache.cassandra.cql3.QueryOptions; -import org.apache.cassandra.cql3.QueryProcessor; -import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.messages.ResultMessage; import org.apache.cassandra.utils.ByteBufferUtil; @@ -115,7 +111,7 @@ public class CassandraAuthorizer implements IAuthorizer AuthKeyspace.RESOURCE_ROLE_INDEX, escape(row.getString("resource")), escape(revokee.getRoleName())), - ClientState.forInternalCalls()).statement); + ClientState.forInternalCalls())); } @@ -123,7 +119,7 @@ public class CassandraAuthorizer implements IAuthorizer SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.ROLE_PERMISSIONS, escape(revokee.getRoleName())), - ClientState.forInternalCalls()).statement); + ClientState.forInternalCalls())); executeLoggedBatch(statements); } @@ -153,14 +149,14 @@ public class CassandraAuthorizer implements IAuthorizer AuthKeyspace.ROLE_PERMISSIONS, escape(row.getString("role")), escape(droppedResource.getName())), - ClientState.forInternalCalls()).statement); + ClientState.forInternalCalls())); } statements.add(QueryProcessor.getStatement(String.format("DELETE FROM %s.%s WHERE resource = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.RESOURCE_ROLE_INDEX, escape(droppedResource.getName())), - ClientState.forInternalCalls()).statement); + ClientState.forInternalCalls())); executeLoggedBatch(statements); } @@ -173,8 +169,8 @@ public class CassandraAuthorizer implements IAuthorizer private void executeLoggedBatch(List<CQLStatement> statements) throws RequestExecutionException, RequestValidationException { - BatchStatement batch = new BatchStatement(0, - BatchStatement.Type.LOGGED, + BatchStatement batch = new BatchStatement(BatchStatement.Type.LOGGED, + VariableSpecifications.empty(), Lists.newArrayList(Iterables.filter(statements, ModificationStatement.class)), Attributes.none()); processBatch(batch); @@ -331,7 +327,7 @@ public class CassandraAuthorizer implements IAuthorizer SchemaConstants.AUTH_KEYSPACE_NAME, permissionsTable, entityname); - return (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()).statement; + return (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()); } // We only worry about one character ('). Make sure it's properly escaped. http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/CassandraNetworkAuthorizer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/CassandraNetworkAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraNetworkAuthorizer.java index 9faa423..34a0140 100644 --- a/src/java/org/apache/cassandra/auth/CassandraNetworkAuthorizer.java +++ b/src/java/org/apache/cassandra/auth/CassandraNetworkAuthorizer.java @@ -46,7 +46,7 @@ public class CassandraNetworkAuthorizer implements INetworkAuthorizer String query = String.format("SELECT dcs FROM %s.%s WHERE role = ?", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.NETWORK_PERMISSIONS); - authorizeUserStatement = (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()).statement; + authorizeUserStatement = (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()); } @VisibleForTesting http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/CassandraRoleManager.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java index 1271699..f5dd457 100644 --- a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java +++ b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java @@ -39,6 +39,7 @@ import org.apache.cassandra.cql3.statements.SelectStatement; import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.exceptions.*; +import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.transport.messages.ResultMessage; @@ -364,7 +365,7 @@ public class CassandraRoleManager implements IRoleManager { try { - return QueryProcessor.parseStatement(String.format(template, keyspace, table)).prepare().statement; + return QueryProcessor.parseStatement(String.format(template, keyspace, table)).prepare(ClientState.forInternalCalls()); } catch (RequestValidationException e) { http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/FunctionResource.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/FunctionResource.java b/src/java/org/apache/cassandra/auth/FunctionResource.java index 2c09c05..61c6a29 100644 --- a/src/java/org/apache/cassandra/auth/FunctionResource.java +++ b/src/java/org/apache/cassandra/auth/FunctionResource.java @@ -134,6 +134,11 @@ public class FunctionResource implements IResource return new FunctionResource(keyspace, name, argTypes); } + public static FunctionResource function(Function function) + { + return new FunctionResource(function.name().keyspace, function.name().name, function.argTypes()); + } + /** * Creates a FunctionResource representing a specific, keyspace-scoped function. * This variant is used to create an instance during parsing of a CQL statement. @@ -157,6 +162,11 @@ public class FunctionResource implements IResource return new FunctionResource(keyspace, name, abstractTypes); } + public static FunctionResource functionFromCql(FunctionName name, List<CQL3Type.Raw> argTypes) + { + return functionFromCql(name.keyspace, name.name, argTypes); + } + /** * Parses a resource name into a FunctionResource instance. * http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java index b1604e7..27a68a0 100644 --- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java +++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java @@ -160,7 +160,7 @@ public class PasswordAuthenticator implements IAuthenticator private static SelectStatement prepare(String query) { - return (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()).statement; + return (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls()); } private class PlainTextSaslAuthenticator implements SaslNegotiator http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java b/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java index d9b63c6..ef00027 100644 --- a/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java +++ b/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java @@ -53,7 +53,7 @@ import org.apache.cassandra.service.StorageService; * * Because an ObjectName may contain wildcards, meaning it represents a set of individual MBeans, * JMX resources don't fit well with the hierarchical approach modelled by other IResource - * implementations and utilised by ClientState::ensureHasPermission etc. To enable grants to use + * implementations and utilised by ClientState::ensurePermission etc. To enable grants to use * pattern-type ObjectNames, this class performs its own custom matching and filtering of resources * rather than pushing that down to the configured IAuthorizer. To that end, during authorization * it pulls back all permissions for the active subject, filtering them to retain only grants on http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/CFName.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/CFName.java b/src/java/org/apache/cassandra/cql3/CFName.java deleted file mode 100644 index 3f4a118..0000000 --- a/src/java/org/apache/cassandra/cql3/CFName.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.cql3; - -public class CFName extends KeyspaceElementName -{ - private String cfName; - - public void setColumnFamily(String cf, boolean keepCase) - { - cfName = toInternalName(cf, keepCase); - } - - public String getColumnFamily() - { - return cfName; - } - - @Override - public String toString() - { - return super.toString() + cfName; - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/CQL3Type.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java index d387a25..340a992 100644 --- a/src/java/org/apache/cassandra/cql3/CQL3Type.java +++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java @@ -37,6 +37,8 @@ import org.apache.cassandra.serializers.MarshalException; import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.utils.ByteBufferUtil; +import static java.util.stream.Collectors.toList; + public interface CQL3Type { static final Logger logger = LoggerFactory.getLogger(CQL3Type.class); @@ -88,7 +90,7 @@ public interface CQL3Type private final AbstractType<?> type; - private Native(AbstractType<?> type) + Native(AbstractType<?> type) { this.type = type; } @@ -482,7 +484,12 @@ public interface CQL3Type // actual type used, so Raw is a "not yet prepared" CQL3Type. public abstract class Raw { - protected boolean frozen = false; + protected final boolean frozen; + + protected Raw(boolean frozen) + { + this.frozen = frozen; + } public abstract boolean supportsFreezing(); @@ -491,11 +498,6 @@ public interface CQL3Type return this.frozen; } - public boolean canBeNonFrozen() - { - return true; - } - public boolean isDuration() { return false; @@ -516,7 +518,7 @@ public interface CQL3Type return null; } - public void freeze() throws InvalidRequestException + public Raw freeze() { String message = String.format("frozen<> is only allowed on collections, tuples, and user-defined types (got %s)", this); throw new InvalidRequestException(message); @@ -544,46 +546,41 @@ public interface CQL3Type public static Raw from(CQL3Type type) { - return new RawType(type); + return new RawType(type, false); } public static Raw userType(UTName name) { - return new RawUT(name); + return new RawUT(name, false); } public static Raw map(CQL3Type.Raw t1, CQL3Type.Raw t2) { - return new RawCollection(CollectionType.Kind.MAP, t1, t2); + return new RawCollection(CollectionType.Kind.MAP, t1, t2, false); } public static Raw list(CQL3Type.Raw t) { - return new RawCollection(CollectionType.Kind.LIST, null, t); + return new RawCollection(CollectionType.Kind.LIST, null, t, false); } public static Raw set(CQL3Type.Raw t) { - return new RawCollection(CollectionType.Kind.SET, null, t); + return new RawCollection(CollectionType.Kind.SET, null, t, false); } public static Raw tuple(List<CQL3Type.Raw> ts) { - return new RawTuple(ts); - } - - public static Raw frozen(CQL3Type.Raw t) throws InvalidRequestException - { - t.freeze(); - return t; + return new RawTuple(ts, false); } private static class RawType extends Raw { private final CQL3Type type; - private RawType(CQL3Type type) + private RawType(CQL3Type type, boolean frozen) { + super(frozen); this.type = type; } @@ -620,20 +617,28 @@ public interface CQL3Type private final CQL3Type.Raw keys; private final CQL3Type.Raw values; - private RawCollection(CollectionType.Kind kind, CQL3Type.Raw keys, CQL3Type.Raw values) + private RawCollection(CollectionType.Kind kind, CQL3Type.Raw keys, CQL3Type.Raw values, boolean frozen) { + super(frozen); this.kind = kind; this.keys = keys; this.values = values; } - public void freeze() throws InvalidRequestException + @Override + public RawCollection freeze() { - if (keys != null && keys.supportsFreezing()) - keys.freeze(); - if (values != null && values.supportsFreezing()) - values.freeze(); - frozen = true; + CQL3Type.Raw frozenKeys = + null != keys && keys.supportsFreezing() + ? keys.freeze() + : keys; + + CQL3Type.Raw frozenValues = + null != values && values.supportsFreezing() + ? values.freeze() + : values; + + return new RawCollection(kind, frozenKeys, frozenValues, true); } public boolean supportsFreezing() @@ -727,8 +732,9 @@ public interface CQL3Type { private final UTName name; - private RawUT(UTName name) + private RawUT(UTName name, boolean frozen) { + super(frozen); this.name = name; } @@ -737,14 +743,10 @@ public interface CQL3Type return name.getKeyspace(); } - public void freeze() - { - frozen = true; - } - - public boolean canBeNonFrozen() + @Override + public RawUT freeze() { - return true; + return new RawUT(name, true); } public CQL3Type prepare(String keyspace, Types udts) throws InvalidRequestException @@ -801,8 +803,9 @@ public interface CQL3Type { private final List<CQL3Type.Raw> types; - private RawTuple(List<CQL3Type.Raw> types) + private RawTuple(List<CQL3Type.Raw> types, boolean frozen) { + super(frozen); this.types = types; } @@ -811,22 +814,22 @@ public interface CQL3Type return true; } - public void freeze() throws InvalidRequestException + @Override + public RawTuple freeze() { - for (CQL3Type.Raw t : types) - if (t.supportsFreezing()) - t.freeze(); - - frozen = true; + List<CQL3Type.Raw> frozenTypes = + types.stream() + .map(t -> t.supportsFreezing() ? t.freeze() : t) + .collect(toList()); + return new RawTuple(frozenTypes, true); } public CQL3Type prepare(String keyspace, Types udts) throws InvalidRequestException { - if (!frozen) - freeze(); + RawTuple raw = frozen ? this : freeze(); - List<AbstractType<?>> ts = new ArrayList<>(types.size()); - for (CQL3Type.Raw t : types) + List<AbstractType<?>> ts = new ArrayList<>(raw.types.size()); + for (CQL3Type.Raw t : raw.types) { if (t.isCounter()) throw new InvalidRequestException("Counters are not allowed inside tuples"); http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/CQLStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/CQLStatement.java b/src/java/org/apache/cassandra/cql3/CQLStatement.java index 1e4dad3..c34e27f 100644 --- a/src/java/org/apache/cassandra/cql3/CQLStatement.java +++ b/src/java/org/apache/cassandra/cql3/CQLStatement.java @@ -17,34 +17,58 @@ */ package org.apache.cassandra.cql3; -import org.apache.cassandra.audit.IAuditLogContext; +import java.util.Collections; +import java.util.List; + +import org.apache.cassandra.audit.AuditLogContext; import org.apache.cassandra.cql3.functions.Function; -import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.messages.ResultMessage; -public interface CQLStatement extends IAuditLogContext +public interface CQLStatement { /** - * Returns the number of bound terms in this statement. + * Returns all bind variables for the statement */ - public int getBoundTerms(); + default List<ColumnSpecification> getBindVariables() + { + return Collections.emptyList(); + } + + /** + * Returns an array with the same length as the number of partition key columns for the table corresponding + * to table. Each short in the array represents the bind index of the marker that holds the value for that + * partition key column. If there are no bind markers for any of the partition key columns, null is returned. + */ + default short[] getPartitionKeyBindVariableIndexes() + { + return null; + } + + /** + * Return an Iterable over all of the functions (both native and user-defined) used by any component of the statement + * + * @return functions all functions found (may contain duplicates) + */ + default Iterable<Function> getFunctions() + { + return Collections.emptyList(); + } /** * Perform any access verification necessary for the statement. * * @param state the current client state */ - public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException; + public void authorize(ClientState state); /** - * Perform additional validation required by the statment. - * To be overriden by subclasses if needed. + * Perform additional validation required by the statment. To be overriden by subclasses if needed. * * @param state the current client state */ - public void validate(ClientState state) throws RequestValidationException; + public void validate(ClientState state); /** * Execute the statement and return the resulting result or null if there is no result. @@ -53,21 +77,19 @@ public interface CQLStatement extends IAuditLogContext * @param options options for this query (consistency, variables, pageSize, ...) * @param queryStartNanoTime the timestamp returned by System.nanoTime() when this statement was received */ - public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime) throws RequestValidationException, RequestExecutionException; + public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime); /** * Variant of execute used for internal query against the system tables, and thus only query the local node. * * @param state the current query state */ - public ResultMessage executeInternal(QueryState state, QueryOptions options) throws RequestValidationException, RequestExecutionException; + public ResultMessage executeLocally(QueryState state, QueryOptions options); /** - * Return an Iterable over all of the functions (both native and user-defined) used by any component - * of the statement - * @return functions all functions found (may contain duplicates) + * Provides the context needed for audit logging statements. */ - public Iterable<Function> getFunctions(); + AuditLogContext getAuditLogContext(); /** * Whether or not this CQL Statement has LWT conditions @@ -76,4 +98,16 @@ public interface CQLStatement extends IAuditLogContext { return false; } + + public static abstract class Raw + { + protected VariableSpecifications bindVariables; + + public void setBindVariables(List<ColumnIdentifier> variables) + { + bindVariables = new VariableSpecifications(variables); + } + + public abstract CQLStatement prepare(ClientState state); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java b/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java index 32cddba..0906d2a 100644 --- a/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java +++ b/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.Map; import org.apache.cassandra.cql3.statements.BatchStatement; -import org.apache.cassandra.cql3.statements.ParsedStatement; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.QueryState; import org.apache.cassandra.transport.messages.ResultMessage; @@ -54,7 +53,7 @@ public class CustomPayloadMirroringQueryHandler implements QueryHandler return prepared; } - public ParsedStatement.Prepared getPrepared(MD5Digest id) + public QueryProcessor.Prepared getPrepared(MD5Digest id) { return queryProcessor.getPrepared(id); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/IndexName.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/IndexName.java b/src/java/org/apache/cassandra/cql3/IndexName.java deleted file mode 100644 index d7ff8ff..0000000 --- a/src/java/org/apache/cassandra/cql3/IndexName.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.cql3; - -public final class IndexName extends KeyspaceElementName -{ - private String idxName; - - public void setIndex(String idx, boolean keepCase) - { - idxName = toInternalName(idx, keepCase); - } - - public String getIdx() - { - return idxName; - } - - public CFName getCfName() - { - CFName cfName = new CFName(); - if (hasKeyspace()) - cfName.setKeyspace(getKeyspace(), true); - return cfName; - } - - @Override - public String toString() - { - return super.toString() + idxName; - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/KeyspaceElementName.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/KeyspaceElementName.java b/src/java/org/apache/cassandra/cql3/KeyspaceElementName.java deleted file mode 100644 index 0a68997..0000000 --- a/src/java/org/apache/cassandra/cql3/KeyspaceElementName.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.cql3; - -import java.util.Locale; - -/** - * Base class for the names of the keyspace elements (e.g. table, index ...) - */ -abstract class KeyspaceElementName -{ - /** - * The keyspace name as stored internally. - */ - private String ksName; - - /** - * Sets the keyspace. - * - * @param ks the keyspace name - * @param keepCase <code>true</code> if the case must be kept, <code>false</code> otherwise. - */ - public final void setKeyspace(String ks, boolean keepCase) - { - ksName = toInternalName(ks, keepCase); - } - - /** - * Checks if the keyspace is specified. - * @return <code>true</code> if the keyspace is specified, <code>false</code> otherwise. - */ - public final boolean hasKeyspace() - { - return ksName != null; - } - - public final String getKeyspace() - { - return ksName; - } - - /** - * Converts the specified name into the name used internally. - * - * @param name the name - * @param keepCase <code>true</code> if the case must be kept, <code>false</code> otherwise. - * @return the name used internally. - */ - protected static String toInternalName(String name, boolean keepCase) - { - return keepCase ? name : name.toLowerCase(Locale.US); - } - - @Override - public String toString() - { - return hasKeyspace() ? (getKeyspace() + ".") : ""; - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java b/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java index 411af07..2d239fb 100644 --- a/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java +++ b/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java @@ -19,6 +19,7 @@ package org.apache.cassandra.cql3; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import org.apache.cassandra.schema.ColumnMetadata; @@ -240,4 +241,26 @@ public class MultiColumnRelation extends Relation .append(valuesOrMarker) .toString(); } + + @Override + public int hashCode() + { + return Objects.hash(relationType, entities, valuesOrMarker, inValues, inMarker); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + + if (!(o instanceof MultiColumnRelation)) + return false; + + MultiColumnRelation mcr = (MultiColumnRelation) o; + return Objects.equals(entities, mcr.entities) + && Objects.equals(valuesOrMarker, mcr.valuesOrMarker) + && Objects.equals(inValues, mcr.inValues) + && Objects.equals(inMarker, mcr.inMarker); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
