-
Notifications
You must be signed in to change notification settings - Fork 459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adapter: Restrict the queries that can run on mz_introspection #18312
adapter: Restrict the queries that can run on mz_introspection #18312
Conversation
Note: This PR is stacked on top of #18310 but I couldn't figure out how to get GitHub to only recognize the changes made to this branch, and not the changes since main Unfortunately GH has no support for stacked PRs. What you've done here is about the best you can do. Recommend just mentioning in the PR description the title of the commit at which to start reviewing. That's what most folks do. |
The code here looks 👌🏽. I suspect that the reason you're still seeing this failure in the dbt tests...
...is because the version check is for v0.47, but what you actually need is a version check for v0.48-dev, since this PR did not make it into v0.47. Looks like we forgot to update main to v0.48-dev; I'll do that now. |
Here's the PR to bump to v0.48-dev: #18319. Feel free to merge tomorrow. If you merge that PR, then rebase this PR on top of it, and then update the version check to v0.48-dev, I think the dbt tests will start passing. 🤞🏽 |
Darn, stacked PRs are a great feature, thanks for the heads up though! I'll update the description |
First, sorry about the comment edit, I clicked too quickly and thought I was replying not editing 😅 Thanks for the heads up about the version and the PR! I'll update my branch and push 🤞 |
dfd90f3
to
392460d
Compare
Note: this PR is on hold for the moment because we need #18310 to land first, and the LaunchDarkly gate to be rolled out to 100% |
if not versions_compatible(mz_version, SUPPORTED_MATERIALIZE_VERSIONS): | ||
raise dbt.exceptions.DbtRuntimeError( | ||
f"Detected unsupported Materialize version {mz_version}\n" | ||
f" Supported versions: {SUPPORTED_MATERIALIZE_VERSIONS}" | ||
) | ||
elif not versions_compatible(mz_version, AUTO_MZ_INTROSPECTION_VERSION): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all user environments are upgraded in tandem, we could just bump SUPPORTED_MATERIALIZE_VERSIONS
to >=0.48.0
and avoid the extra conditional logic altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless CI is testing a version range that goes further into the past, and we want to keep it around for that reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not aware of anything in CI that tests the version range, let's see if anything breaks! :)
7bca5bd
to
6535665
Compare
src/pgwire/src/message.rs
Outdated
@@ -362,6 +362,7 @@ impl ErrorResponse { | |||
AdapterError::SqlCatalog(_) => SqlState::INTERNAL_ERROR, | |||
AdapterError::SubscribeOnlyTransaction => SqlState::INVALID_TRANSACTION_STATE, | |||
AdapterError::Transform(_) => SqlState::INTERNAL_ERROR, | |||
AdapterError::UnallowedOnCluster { .. } => SqlState::INTERNAL_ERROR, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem like an INTERNAL_ERROR
to me. I'm not sure what the best error code to use here is since this scenario is not possible in PostgreSQL. Maybe SqlState::INSUFFICIENT_PRIVILEGE
? Though that one maybe implies there's some privilege that would allow the user to execute this. Maybe Never mind, that's specifically for SQL Routines.SqlState::S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED
Whatever you pick it should indicate that the user did something they weren't allowed to, not that it was an internal error. (For reference: https://www.postgresql.org/docs/current/errcodes-appendix.html).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense to me! I updated it to be SqlState::S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED
, nothing else seemed to be a great fit. Maaaaaybe INSUFFICIENT_RESOURCES
but that's not really correct either
AdapterError::UnallowedOnCluster { .. } => { | ||
SqlState::S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I know I suggested this one, but right after I realized that this is not correct either. These are meant for SQL routines (https://www.postgresql.org/docs/current/infoschema-routines.html), which are functions and procedures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries! Looking through all of the error codes the following seem to be somewhat decent:
protocol_violation
- Class 08 — Connection Exceptioninvalid_parameter_value
- Class 22 — Data Exception (not sure what classifies as a "parameter" though)system_error
- Class 58 — System Error (errors external to PostgreSQL itself)
system_error
seems to be the most generic, so that's what I'm leaning towards, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, invalid_param_value
wouldn't work because param
refers to parameterized queries like SELECT * FROM $1
.
I don't think system_error
makes sense either because the error is not external to Materialize. protocol_violation
refers to the pgwire protocol, which this query isn't in violation of.
I actually think the privilege error is the best one the more I think about it. There's nothing inherently wrong with the query, we have just made it forbidden when using a specific cluster.
Sorry to be nit-picky on this.
} | ||
|
||
// Allows explain queries. | ||
if let Plan::Explain(_) = plan { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor concern: I'm not convinced this is helpful? We'd let them run an explain and then when they do a real query it'd error? Also fine leaving as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I opted to allow all explain queries was because I pictured a flow where we reject a query because it references non-system tables, and I wanted the user to be able to better understand why we rejected it, i.e. use EXPLAIN
, without having to switch clusters. It's a minor detail and I'm totally fine with removing it if we think it'll cause more confusion because of the inconsistency
src/adapter/src/error.rs
Outdated
write!( | ||
f, | ||
"querying the following items {items} is not allowed from the {} cluster. \ | ||
Use `SET CLUSTER = <cluster-name>` to change your cluster and re-run the query.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This second sentence should probably be a hint or detail. See https://github.com/MaterializeInc/materialize/blob/main/doc/developer/style.md#error-message-style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking care of the dbt changes, @parker-timmerman! Only missing a changelog note, but I can push that in.
f230d0e
to
d9bca89
Compare
31ce8a9
to
da2abec
Compare
Co-authored-by: morsapaes <marta.paes.moreira@gmail.com> Co-authored-by: Matt Jibson <matt.jibson@gmail.com>
da2abec
to
526b384
Compare
de5c117
to
2fe15fc
Compare
…on` cluster (#19041) ### Motivation #18312 restricted queries that depend on non-system objects, from being run on the `mz_introspection` cluster. The changes it introduced though were too restrictive. This PR relaxes those restrictions, allowing any query to run on mz_introspection, as long as it's not a `SELECT` or `SUBSCRIBE`. ### Tips for reviewer I think I gated against the correct `Plan`s, but two I was unsure about were `Plan::Fetch` and `Plan::Insert`. I'm not sure if we also want to prevent those from running on `mz_introspection`. ### Checklist - [ ] This PR has adequate test coverage / QA involvement has been duly considered. - [ ] This PR has an associated up-to-date [design doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md), is a design doc ([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)), or is sufficiently small to not require a design. <!-- Reference the design in the description. --> - [ ] This PR evolves [an existing `$T ⇔ Proto$T` mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md) (possibly in a backwards-incompatible way) and therefore is tagged with a `T-proto` label. - [ ] If this PR will require changes to cloud orchestration, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label ([example](MaterializeInc/cloud#5021)). <!-- Ask in #team-cloud on Slack if you need help preparing the cloud PR. --> - [ ] This PR includes the following [user-facing behavior changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note): - <!-- Add release notes here or explicitly state that there are no user-facing behavior changes. -->
Motivation
mz_introspection
cluster #18075This PR restricts what queries can get run on the
mz_introspection
cluster. Specifically only queries that depend on system tables can get run. As part of this change, we also update the dbt-adapter to set theauto_route_introspection_queries
session var to make sure all of its introspection queries automatically get run on the mz_introspection cluster, regardless of what cluster is currently set.Checklist
$T ⇔ Proto$T
mapping (possibly in a backwards-incompatible way) and therefore is tagged with aT-proto
label.