cql3: Convert backend for 'delete' statement

This commit is contained in:
Tomasz Grabiec
2015-03-27 18:35:12 +01:00
parent 30c821d585
commit d143f68898
6 changed files with 88 additions and 84 deletions

View File

@@ -136,4 +136,15 @@ constants::literal::prepare(const sstring& keyspace, ::shared_ptr<column_specifi
return ::make_shared<value>(std::experimental::make_optional(parsed_value(receiver->type)));
}
void constants::deleter::execute(mutation& m, const exploded_clustering_prefix& prefix, const update_parameters& params) {
if (column.type->is_multi_cell()) {
collection_type_impl::mutation coll_m;
coll_m.tomb = params.make_tombstone();
auto ctype = static_pointer_cast<collection_type_impl>(column.type);
m.set_cell(prefix, column, atomic_cell_or_collection::from_collection_mutation(ctype->serialize_mutation_form(coll_m)));
} else {
m.set_cell(prefix, column, params.make_dead_cell());
}
}
}

View File

@@ -240,26 +240,16 @@ public:
cf.addColumn(params.makeCounter(cname, -increment));
}
}
// This happens to also handle collection because it doesn't felt worth
// duplicating this further
public static class Deleter extends Operation
{
public Deleter(ColumnDefinition column)
{
super(column, null);
}
public void execute(ByteBuffer rowKey, ColumnFamily cf, Composite prefix, UpdateParameters params) throws InvalidRequestException
{
CellName cname = cf.getComparator().create(prefix, column);
if (column.type.isMultiCell())
cf.addAtom(params.makeRangeTombstone(cname.slice()));
else
cf.addColumn(params.makeTombstone(cname));
}
};
#endif
class deleter : public operation {
public:
deleter(const column_definition& column)
: operation(column, {})
{ }
virtual void execute(mutation& m, const exploded_clustering_prefix& prefix, const update_parameters& params) override;
};
};
std::ostream& operator<<(std::ostream&out, constants::type t);

View File

@@ -159,7 +159,7 @@ public:
/**
* The name of the column affected by this delete operation.
*/
virtual ::shared_ptr<column_identifier::raw> affectedColumn() = 0;
virtual ::shared_ptr<column_identifier::raw> affected_column() = 0;
/**
* This method validates the operation (i.e. validate it is well typed)
@@ -252,28 +252,9 @@ public:
virtual bool is_compatible_with(shared_ptr<raw_update> other) override;
};
class column_deletion;
#if 0
public static class ColumnDeletion implements RawDeletion
{
private final ColumnIdentifier.Raw id;
public ColumnDeletion(ColumnIdentifier.Raw id)
{
this.id = id;
}
public ColumnIdentifier.Raw affectedColumn()
{
return id;
}
public Operation prepare(String keyspace, ColumnDefinition receiver) throws InvalidRequestException
{
// No validation, deleting a column is always "well typed"
return new Constants.Deleter(receiver);
}
}
public static class ElementDeletion implements RawDeletion
{
private final ColumnIdentifier.Raw id;

View File

@@ -50,4 +50,22 @@ public:
virtual bool is_compatible_with(::shared_ptr <raw_update> other) override;
};
class operation::column_deletion : public raw_deletion {
private:
::shared_ptr<column_identifier::raw> _id;
public:
column_deletion(::shared_ptr<column_identifier::raw> id)
: _id(std::move(id))
{ }
virtual ::shared_ptr<column_identifier::raw> affected_column() override {
return _id;
}
::shared_ptr<operation> prepare(const sstring& keyspace, const column_definition& receiver) {
// No validation, deleting a column is always "well typed"
return ::make_shared<constants::deleter>(receiver);
}
};
}

View File

@@ -51,6 +51,33 @@ void delete_statement::add_update_for_key(mutation& m, const exploded_clustering
}
}
::shared_ptr<modification_statement>
delete_statement::parsed::prepare_internal(schema_ptr schema, ::shared_ptr<variable_specifications> bound_names,
std::unique_ptr<attributes> attrs) {
auto stmt = ::make_shared<delete_statement>(statement_type::DELETE, bound_names->size(), schema, std::move(attrs));
for (auto&& deletion : _deletions) {
auto&& id = deletion->affected_column()->prepare_column_identifier(schema);
auto def = get_column_definition(schema, *id);
if (!def) {
throw exceptions::invalid_request_exception(sprint("Unknown identifier %s", *id));
}
// For compact, we only have one value except the key, so the only form of DELETE that make sense is without a column
// list. However, we support having the value name for coherence with the static/sparse case
if (def->is_primary_key()) {
throw exceptions::invalid_request_exception(sprint("Invalid identifier %s for deletion (should not be a PRIMARY KEY part)", def->name_as_text()));
}
auto&& op = deletion->prepare(schema->ks_name, *def);
op->collect_marker_specification(bound_names);
stmt->add_operation(op);
}
stmt->process_where_clause(_where_clause, std::move(bound_names));
return stmt;
}
}
}

View File

@@ -81,50 +81,27 @@ public:
}
}
public static class Parsed extends ModificationStatement.Parsed
{
private final List<Operation.RawDeletion> deletions;
private final List<Relation> whereClause;
public Parsed(CFName name,
Attributes.Raw attrs,
List<Operation.RawDeletion> deletions,
List<Relation> whereClause,
List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>> conditions,
boolean ifExists)
{
super(name, attrs, conditions, false, ifExists);
this.deletions = deletions;
this.whereClause = whereClause;
}
protected ModificationStatement prepareInternal(CFMetaData cfm, VariableSpecifications boundNames, Attributes attrs) throws InvalidRequestException
{
DeleteStatement stmt = new DeleteStatement(ModificationStatement.StatementType.DELETE, boundNames.size(), cfm, attrs);
for (Operation.RawDeletion deletion : deletions)
{
ColumnIdentifier id = deletion.affectedColumn().prepare(cfm);
ColumnDefinition def = cfm.getColumnDefinition(id);
if (def == null)
throw new InvalidRequestException(String.format("Unknown identifier %s", id));
// For compact, we only have one value except the key, so the only form of DELETE that make sense is without a column
// list. However, we support having the value name for coherence with the static/sparse case
if (def.isPrimaryKeyColumn())
throw new InvalidRequestException(String.format("Invalid identifier %s for deletion (should not be a PRIMARY KEY part)", def.name));
Operation op = deletion.prepare(cfm.ksName, def);
op.collectMarkerSpecification(boundNames);
stmt.addOperation(op);
}
stmt.processWhereClause(whereClause, boundNames);
return stmt;
}
}
#endif
class parsed : public modification_statement::parsed {
private:
std::vector<::shared_ptr<operation::raw_deletion>> _deletions;
std::vector<::shared_ptr<relation>> _where_clause;
public:
parsed(::shared_ptr<cf_name> name,
::shared_ptr<attributes::raw> attrs,
std::vector<::shared_ptr<operation::raw_deletion>> deletions,
std::vector<::shared_ptr<relation>> where_clause,
conditions_vector conditions,
bool if_exists)
: modification_statement::parsed(std::move(name), std::move(attrs), std::move(conditions), false, if_exists)
, _deletions(std::move(deletions))
, _where_clause(std::move(where_clause))
{ }
protected:
virtual ::shared_ptr<modification_statement> prepare_internal(schema_ptr schema,
::shared_ptr<variable_specifications> bound_names, std::unique_ptr<attributes> attrs);
};
};
}