/* * 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 2015 Cloudius Systems * * Modified by Cloudius Systems */ #include "cql3/column_condition.hh" #include "unimplemented.hh" #include "lists.hh" #include "maps.hh" #include namespace cql3 { bool column_condition::uses_function(const sstring& ks_name, const sstring& function_name) { if (bool(_collection_element) && _collection_element->uses_function(ks_name, function_name)) { return true; } if (bool(_value) && _value->uses_function(ks_name, function_name)) { return true; } if (!_in_values.empty()) { for (auto&& value : _in_values) { if (bool(value) && value->uses_function(ks_name, function_name)) { return true; } } } return false; } void column_condition::collect_marker_specificaton(::shared_ptr bound_names) { if (_collection_element) { _collection_element->collect_marker_specification(bound_names); } if (!_in_values.empty()) { for (auto&& value : _in_values) { value->collect_marker_specification(bound_names); } } _value->collect_marker_specification(bound_names); } ::shared_ptr column_condition::raw::prepare(database& db, const sstring& keyspace, const column_definition& receiver) { if (receiver.type->is_counter()) { throw exceptions::invalid_request_exception("Conditions on counters are not supported"); } if (!_collection_element) { if (_op == operator_type::IN) { if (_in_values.empty()) { // ? return column_condition::in_condition(receiver, _in_marker->prepare(db, keyspace, receiver.column_specification)); } std::vector<::shared_ptr> terms; for (auto&& value : _in_values) { terms.push_back(value->prepare(db, keyspace, receiver.column_specification)); } return column_condition::in_condition(receiver, std::move(terms)); } else { return column_condition::condition(receiver, _value->prepare(db, keyspace, receiver.column_specification), _op); } } if (!receiver.type->is_collection()) { throw exceptions::invalid_request_exception(sprint("Invalid element access syntax for non-collection column %s", receiver.name_as_text())); } shared_ptr element_spec, value_spec; auto ctype = static_cast(receiver.type.get()); if (&ctype->_kind == &collection_type_impl::kind::list) { element_spec = lists::index_spec_of(receiver.column_specification); value_spec = lists::value_spec_of(receiver.column_specification); } else if (&ctype->_kind == &collection_type_impl::kind::map) { element_spec = maps::key_spec_of(*receiver.column_specification); value_spec = maps::value_spec_of(*receiver.column_specification); } else if (&ctype->_kind == &collection_type_impl::kind::set) { throw exceptions::invalid_request_exception(sprint("Invalid element access syntax for set column %s", receiver.name())); } else { abort(); } if (_op == operator_type::IN) { if (_in_values.empty()) { return column_condition::in_condition(receiver, _collection_element->prepare(db, keyspace, element_spec), _in_marker->prepare(db, keyspace, value_spec)); } std::vector> terms; terms.reserve(_in_values.size()); boost::push_back(terms, _in_values | boost::adaptors::transformed(std::bind(&term::raw::prepare, std::placeholders::_1, std::ref(db), std::ref(keyspace), value_spec))); return column_condition::in_condition(receiver, _collection_element->prepare(db, keyspace, element_spec), terms); } else { return column_condition::condition(receiver, _collection_element->prepare(db, keyspace, element_spec), _value->prepare(db, keyspace, value_spec), _op); } } }