From 1fcce7cdcb9bbf69cf4330decd193d94ed1059af Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 5 Mar 2015 13:34:40 +0200 Subject: [PATCH] cql3: convert operation::set_element --- configure.py | 1 + cql3/operation.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++ cql3/operation.hh | 59 +++++++++++++----------------------------- 3 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 cql3/operation.cc diff --git a/configure.py b/configure.py index a210fe0545..84bcee2ff1 100755 --- a/configure.py +++ b/configure.py @@ -254,6 +254,7 @@ urchin_core = (['database.cc', 'cql3/abstract_marker.cc', 'cql3/cql3.cc', 'cql3/cql3_type.cc', + 'cql3/operation.cc', 'cql3/functions/functions.cc', 'cql3/statements/modification_statement.cc', 'cql3/statements/update_statement.cc', diff --git a/cql3/operation.cc b/cql3/operation.cc new file mode 100644 index 0000000000..6f826e0920 --- /dev/null +++ b/cql3/operation.cc @@ -0,0 +1,65 @@ +/* + * 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. + */ + +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#include "operation.hh" +#include "operation_impl.hh" +#include "maps.hh" + +namespace cql3 { + + +shared_ptr +operation::set_element::prepare(const sstring& keyspace, column_definition& receiver) { + using exceptions::invalid_request_exception; + auto rtype = dynamic_pointer_cast(receiver.type); + if (!rtype) { + throw invalid_request_exception(sprint("Invalid operation (%s) for non collection column %s", receiver, receiver.name())); + } else if (!rtype->is_multi_cell()) { + throw invalid_request_exception(sprint("Invalid operation (%s) for frozen collection column %s", receiver, receiver.name())); + } + + if (&rtype->_kind == &collection_type_impl::kind::list) { + abort(); + // FIXME: +#if 0 + Term idx = selector.prepare(keyspace, Lists.indexSpecOf(receiver)); + Term lval = value.prepare(keyspace, Lists.valueSpecOf(receiver)); + return new Lists.SetterByIndex(receiver, idx, lval); +#endif + } else if (&rtype->_kind == &collection_type_impl::kind::set) { + throw invalid_request_exception(sprint("Invalid operation (%s) for set column %s", receiver, receiver.name())); + } else if (&rtype->_kind == &collection_type_impl::kind::map) { + auto key = _selector->prepare(keyspace, maps::key_spec_of(*receiver.column_specification)); + auto mval = _value->prepare(keyspace, maps::value_spec_of(*receiver.column_specification)); + return make_shared(receiver, key, mval); + } + abort(); +} + +bool +operation::set_element::is_compatible_with(shared_ptr other) { + // TODO: we could check that the other operation is not setting the same element + // too (but since the index/key set may be a bind variables we can't always do it at this point) + return !dynamic_pointer_cast(std::move(other)); +} + +} diff --git a/cql3/operation.hh b/cql3/operation.hh index 97f390cebe..d3698d8520 100644 --- a/cql3/operation.hh +++ b/cql3/operation.hh @@ -26,13 +26,16 @@ #define CQL3_OPERATION_HH #include "core/shared_ptr.hh" - +#include "exceptions/exceptions.hh" #include "database.hh" +#include "term.hh" #include namespace cql3 { +class update_parameters; + #if 0 package org.apache.cassandra.cql3; @@ -174,54 +177,26 @@ public: class set_value; + class set_element : public raw_update { + const shared_ptr _selector; + const shared_ptr _value; + public: + set_element(shared_ptr selector, shared_ptr value) + : _selector(std::move(selector)), _value(std::move(value)) { + } + + virtual shared_ptr prepare(const sstring& keyspace, column_definition& receiver); #if 0 - public static class SetElement implements RawUpdate - { - private final Term.Raw selector; - private final Term.Raw value; - - public SetElement(Term.Raw selector, Term.Raw value) - { - this.selector = selector; - this.value = value; - } - - public Operation prepare(String keyspace, ColumnDefinition receiver) throws InvalidRequestException - { - if (!(receiver.type instanceof CollectionType)) - throw new InvalidRequestException(String.format("Invalid operation (%s) for non collection column %s", toString(receiver), receiver.name)); - else if (!(receiver.type.isMultiCell())) - throw new InvalidRequestException(String.format("Invalid operation (%s) for frozen collection column %s", toString(receiver), receiver.name)); - - switch (((CollectionType)receiver.type).kind) - { - case LIST: - Term idx = selector.prepare(keyspace, Lists.indexSpecOf(receiver)); - Term lval = value.prepare(keyspace, Lists.valueSpecOf(receiver)); - return new Lists.SetterByIndex(receiver, idx, lval); - case SET: - throw new InvalidRequestException(String.format("Invalid operation (%s) for set column %s", toString(receiver), receiver.name)); - case MAP: - Term key = selector.prepare(keyspace, Maps.keySpecOf(receiver)); - Term mval = value.prepare(keyspace, Maps.valueSpecOf(receiver)); - return new Maps.SetterByKey(receiver, key, mval); - } - throw new AssertionError(); - } - protected String toString(ColumnSpecification column) { return String.format("%s[%s] = %s", column.name, selector, value); } - public boolean isCompatibleWith(RawUpdate other) - { - // TODO: we could check that the other operation is not setting the same element - // too (but since the index/key set may be a bind variables we can't always do it at this point) - return !(other instanceof SetValue); - } - } +#endif + virtual bool is_compatible_with(shared_ptr other) override; + }; +#if 0 public static class Addition implements RawUpdate { private final Term.Raw value;