mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-03 13:37:04 +00:00
cql3: expr: prepare_expr: support subscripted lists
Infer the type of a list index as int32_type. The error message when a non-subscriptable type is provided is changed, so the corresponding test is changed too.
This commit is contained in:
@@ -128,6 +128,14 @@ map_key_spec_of(const column_specification& column) {
|
||||
dynamic_cast<const map_type_impl&>(column.type->without_reversed()).get_keys_type());
|
||||
}
|
||||
|
||||
static
|
||||
lw_shared_ptr<column_specification>
|
||||
list_key_spec_of(const column_specification& column) {
|
||||
return make_lw_shared<column_specification>(column.ks_name, column.cf_name,
|
||||
::make_shared<column_identifier>(format("index({})", *column.name), true),
|
||||
int32_type);
|
||||
}
|
||||
|
||||
static
|
||||
lw_shared_ptr<column_specification>
|
||||
map_value_spec_of(const column_specification& column) {
|
||||
@@ -982,13 +990,19 @@ static expression prepare_binop_lhs(const expression& lhs, data_dictionary::data
|
||||
}, sub.val);
|
||||
|
||||
const abstract_type& sub_col_type = sub_col->column_specification->type->without_reversed();
|
||||
if (!sub_col_type.is_map()) {
|
||||
throw exceptions::invalid_request_exception(format("Column {} is not a map, cannot be used as a map", sub_col->name_as_text()));
|
||||
|
||||
lw_shared_ptr<column_specification> subscript_column_spec;
|
||||
if (sub_col_type.is_map()) {
|
||||
subscript_column_spec = map_key_spec_of(*sub_col->column_specification);
|
||||
} else if (sub_col_type.is_list()) {
|
||||
subscript_column_spec = list_key_spec_of(*sub_col->column_specification);
|
||||
} else {
|
||||
throw exceptions::invalid_request_exception(format("Column {} is not a map/list, cannot be subscripted", sub_col->name_as_text()));
|
||||
}
|
||||
|
||||
return subscript {
|
||||
.val = column_value(sub_col),
|
||||
.sub = prepare_expression(sub.sub, db, schema.ks_name(), map_key_spec_of(*sub_col->column_specification))
|
||||
.sub = prepare_expression(sub.sub, db, schema.ks_name(), std::move(subscript_column_spec))
|
||||
};
|
||||
},
|
||||
[](const auto& e) -> expression {
|
||||
@@ -1005,7 +1019,11 @@ static lw_shared_ptr<column_specification> get_lhs_receiver(const expression& pr
|
||||
},
|
||||
[](const subscript& col_val) -> lw_shared_ptr<column_specification> {
|
||||
const column_value& sub_col = get_subscripted_column(col_val);
|
||||
return map_value_spec_of(*sub_col.col->column_specification);
|
||||
if (sub_col.col->type->is_map()) {
|
||||
return map_value_spec_of(*sub_col.col->column_specification);
|
||||
} else {
|
||||
return list_value_spec_of(*sub_col.col->column_specification);
|
||||
}
|
||||
},
|
||||
[&](const tuple_constructor& tup) -> lw_shared_ptr<column_specification> {
|
||||
std::ostringstream tuple_name;
|
||||
|
||||
@@ -194,7 +194,7 @@ def test_filtering_with_subscript(cql, test_keyspace, cassandra_bug):
|
||||
# expression - because there will be no rows to filter.
|
||||
|
||||
# A subscript is not allowed on a non-map column (in this case, a set)
|
||||
with pytest.raises(InvalidRequest, match='cannot be used as a map'):
|
||||
with pytest.raises(InvalidRequest, match='cannot be subscripted'):
|
||||
cql.execute(f"SELECT p FROM {table} WHERE s[2] = 3 ALLOW FILTERING")
|
||||
# A wrong type is passed for the subscript is not allowed
|
||||
with pytest.raises(InvalidRequest, match=re.escape('key(m1)')):
|
||||
|
||||
Reference in New Issue
Block a user