Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/Storages/prepareReadingFromFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,19 +260,23 @@ Names filterTupleColumnsToRead(NamesAndTypesList & requested_columns)

ReadFromFormatInfo updateFormatPrewhereInfo(const ReadFromFormatInfo & info, const FilterDAGInfoPtr & row_level_filter, const PrewhereInfoPtr & prewhere_info)
{
chassert(prewhere_info);
chassert(prewhere_info || row_level_filter);

if (info.prewhere_info || info.row_level_filter)
if (info.prewhere_info)
throw Exception(ErrorCodes::LOGICAL_ERROR, "updateFormatPrewhereInfo called more than once");

ReadFromFormatInfo new_info;
new_info.prewhere_info = prewhere_info;
new_info.row_level_filter = row_level_filter;

/// Removes columns that are only used as prewhere input.
/// Adds prewhere outputs (the actual prewhere filter column is only added if
/// !remove_prewhere_column; but there may also be subexpressions computed by prewhere
/// expression and preserved for use further down the query pipeline).
new_info.format_header = SourceStepWithFilter::applyPrewhereActions(info.format_header, row_level_filter, prewhere_info);
/// If row_level_filter was already applied in a previous call, don't re-apply it;
/// only apply the new prewhere_info on top.
new_info.format_header = SourceStepWithFilter::applyPrewhereActions(
info.format_header, info.row_level_filter ? nullptr : row_level_filter, prewhere_info);

/// We assume that any format that supports prewhere also supports subset of subcolumns, so we
/// don't need to replace subcolumns with their nested columns etc.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--- Row policy filters URL Parquet table ---
1 a
2 b
--- Row policy with WHERE on URL Parquet table ---
1 a
--- Row policy count on URL Parquet table ---
2
46 changes: 46 additions & 0 deletions tests/queries/0_stateless/04053_row_policy_object_storage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Tags: no-replicated-database, no-fasttest

# Regression test: row policy on a URL table with Parquet format caused
# "Logical error: 'prewhere_info'" because updateFormatPrewhereInfo asserted
# prewhere_info was non-null, but only row_level_filter was set.

CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh

user="user04053_${CLICKHOUSE_DATABASE}_$RANDOM"
db=${CLICKHOUSE_DATABASE}

${CLICKHOUSE_CLIENT} <<EOF
DROP TABLE IF EXISTS ${db}.source_data;
CREATE TABLE ${db}.source_data (id UInt32, value String) ENGINE = MergeTree ORDER BY id;
INSERT INTO ${db}.source_data VALUES (1, 'a'), (2, 'b'), (3, 'c');

DROP TABLE IF EXISTS ${db}.url_parquet;
CREATE TABLE ${db}.url_parquet (id UInt32, value String)
ENGINE = URL('http://127.0.0.1:${CLICKHOUSE_PORT_HTTP}/?query=SELECT+*+FROM+${db}.source_data+FORMAT+Parquet', 'Parquet');

DROP USER IF EXISTS ${user};
CREATE USER ${user} IDENTIFIED WITH no_password;
GRANT SELECT ON ${db}.url_parquet TO ${user};

DROP ROW POLICY IF EXISTS rp_04053 ON ${db}.url_parquet;
CREATE ROW POLICY rp_04053 ON ${db}.url_parquet FOR SELECT USING id <= 2 TO ${user};
EOF

echo "--- Row policy filters URL Parquet table ---"
${CLICKHOUSE_CLIENT} --user ${user} --query "SELECT * FROM ${db}.url_parquet ORDER BY id"

echo "--- Row policy with WHERE on URL Parquet table ---"
${CLICKHOUSE_CLIENT} --user ${user} --query "SELECT * FROM ${db}.url_parquet WHERE value = 'a' ORDER BY id"

echo "--- Row policy count on URL Parquet table ---"
${CLICKHOUSE_CLIENT} --user ${user} --query "SELECT count() FROM ${db}.url_parquet"

${CLICKHOUSE_CLIENT} <<EOF
DROP ROW POLICY IF EXISTS rp_04053 ON ${db}.url_parquet;
DROP USER IF EXISTS ${user};
DROP TABLE IF EXISTS ${db}.url_parquet;
DROP TABLE IF EXISTS ${db}.source_data;
EOF
Loading