-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Adding QueryType to AccessControlContext #23663
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ | |
import java.util.Optional; | ||
import java.util.concurrent.Executor; | ||
|
||
import static com.facebook.presto.Session.SessionBuilder; | ||
import static com.facebook.presto.SystemSessionProperties.getAnalyzerType; | ||
import static com.facebook.presto.spi.StandardErrorCode.QUERY_TEXT_TOO_LARGE; | ||
import static com.facebook.presto.util.AnalyzerUtil.createAnalyzerOptions; | ||
|
@@ -259,6 +260,7 @@ public ListenableFuture<?> createQuery(QueryId queryId, String slug, int retryCo | |
private <C> void createQueryInternal(QueryId queryId, String slug, int retryCount, SessionContext sessionContext, String query, ResourceGroupManager<C> resourceGroupManager) | ||
{ | ||
Session session = null; | ||
SessionBuilder sessionBuilder = null; | ||
PreparedQuery preparedQuery; | ||
try { | ||
if (query.length() > maxQueryLength) { | ||
|
@@ -268,16 +270,18 @@ private <C> void createQueryInternal(QueryId queryId, String slug, int retryCoun | |
} | ||
|
||
// decode session | ||
session = sessionSupplier.createSession(queryId, sessionContext, warningCollectorFactory); | ||
sessionBuilder = sessionSupplier.createSessionBuilder(queryId, sessionContext, warningCollectorFactory); | ||
session = sessionBuilder.build(); | ||
|
||
// prepare query | ||
AnalyzerOptions analyzerOptions = createAnalyzerOptions(session, session.getWarningCollector()); | ||
AnalyzerOptions analyzerOptions = createAnalyzerOptions(session, sessionBuilder.getWarningCollector()); | ||
QueryPreparerProvider queryPreparerProvider = queryPreparerProviderManager.getQueryPreparerProvider(getAnalyzerType(session)); | ||
preparedQuery = queryPreparerProvider.getQueryPreparer().prepareQuery(analyzerOptions, query, session.getPreparedStatements(), session.getWarningCollector()); | ||
preparedQuery = queryPreparerProvider.getQueryPreparer().prepareQuery(analyzerOptions, query, sessionBuilder.getPreparedStatements(), sessionBuilder.getWarningCollector()); | ||
query = preparedQuery.getFormattedQuery().orElse(query); | ||
|
||
// select resource group | ||
Optional<QueryType> queryType = preparedQuery.getQueryType(); | ||
sessionBuilder.setQueryType(queryType); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why make all these changes instead when you can just do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
SelectionContext<C> selectionContext = resourceGroupManager.selectGroup(new SelectionCriteria( | ||
sessionContext.getIdentity().getPrincipal().isPresent(), | ||
sessionContext.getIdentity().getUser(), | ||
|
@@ -290,7 +294,12 @@ private <C> void createQueryInternal(QueryId queryId, String slug, int retryCoun | |
sessionContext.getIdentity().getPrincipal().map(Principal::getName))); | ||
|
||
// apply system default session properties (does not override user set properties) | ||
session = sessionPropertyDefaults.newSessionWithDefaultProperties(session, queryType.map(Enum::name), Optional.of(selectionContext.getResourceGroupId())); | ||
sessionPropertyDefaults.applyDefaultProperties(sessionBuilder, queryType.map(Enum::name), Optional.of(selectionContext.getResourceGroupId())); | ||
|
||
session = sessionBuilder.build(); | ||
if (sessionContext.getTransactionId().isPresent()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a difference here in that previously, SessionSupplier.createSession() was calling beginTransaction up at line 285. I don't know if that makes a difference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reviewed the tasks that happen within beginTransactionId and I don't believe there is any dependency between what happens in there and the work done to create preparedQuery. This implies that the order does not matter on if we prepare the query or if we begin the transaction. From testing, I also found no impact in performance or functionality. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we starting a transaction here ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The transaction was never started after I refactored the code to use SessionBuilder instead of Session. In the original construction of Session, the transaction was started once Session was built. Since we need queryType in the session, I moved the transaction piece out so we could utilize SessionBuilder to add the necessary field. Since the transaction hasn't started, I moved it out and placed it as early as I could while including the addition of queryType. |
||
session = session.beginTransactionId(sessionContext.getTransactionId().get(), transactionManager, accessControl); | ||
} | ||
|
||
// mark existing transaction as active | ||
transactionManager.activateTransaction(session, preparedQuery.isTransactionControlStatement(), accessControl); | ||
|
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.
why is this optional ? can a session have this empty ?
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 don't believe there is an instance where queryType can be empty. If my understanding is correct, all queries that make it to DispatchManager will have some enum of QueryType. However, as a precaution, I wrapped QueryType in an optional.
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.
so then lets have it as NOT optional. And fix any issues that my arise.
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.
After making the changes, I realized that there are some areas where I put an empty optional instead of null.
Example
Since the session ctor requires all fields to be non-null, I believe it may be the design appropriate choice to keep the queryType as an Optional.
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.
Why are we not adding QueryType to SessionRepresentation as well ? Then we need NOT send Optional.empty() or null right ?
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.
After making the change in SessionRepresentation and other places, there is another issue if we don't use an Optional. queryType is not defined when we build session. We pass in session in a few places before we even have queryType. So if we want to maintain the non-null rule in session ctor, I believe using an Optional is the best bet.
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.
It is a little confusing but I am more than happy to discuss the thought process!
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.
@NikhilCollooru the challenge here is the Session usage in DispatchManager#createQueryInternal:
So currently session is being used before we know what the QueryType actually is. Now the Session usage in (1) and (2) is only to extract system property values, so we could try to separate that concern from the Session representation itself, pulling out SystemPropertyManager and the Map<String, String> of system properties. But that looks like a big refactoring as the use of Session as an interface to system properties seems pretty deeply embedded.
Any thoughts on how we can better clean this up? The current use of Session in DispatchManager#createQueryInternal is a bit wonky to begin with as Session is first created from SessionSupplier (not the builder for some reason), then recreated by SessionPropertyDefaults#newSessionQithDefaultProperties. I don't really understand why the SessionPropertyDefaults part happens after the analyzer and query preparer setup.