-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
IGNITE-22557 Create system view for SQL query plans history #11425
Conversation
"; key column index=" + (keyColIdx < 0 ? "N/A" : keyColIdx) + | ||
"; value column index=" + (valColIdx < 0 ? "N/A" : valColIdx) + | ||
"; row count=" + rowsNum + | ||
"; values=" + (rows == null ? "N/A" : "[" + rowsToString(rows) + "]") + |
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.
Not sure we should add rows to plan. Plan will be different each time and it will wash out all other plan. For me value of DML plans are not clear. Perhaps it will be useful to have only plan for selectQry, but looks like we don't have this plan during update. Perhaps these queries are tracked on map phase.
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 concept of plans for DML commands has been completely changed.
@@ -472,6 +473,17 @@ private void onQueryRequest0( | |||
); | |||
} | |||
|
|||
SqlPlanHistoryTracker planHistTracker = ctx.query().runningQueryManager().planHistoryTracker(); |
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.
h2.runningQueryManager().planHistoryTracker().addPlan(...)?
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.
Corrected.
@@ -522,6 +523,17 @@ else if (QueryUtils.wasCancelled(err)) | |||
); | |||
} | |||
|
|||
SqlPlanHistoryTracker planHistTracker = ctx.query().runningQueryManager().planHistoryTracker(); |
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.
h2.runningQueryManager().planHistoryTracker().addPlan(...)?
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.
Corrected.
this.schema = schema; | ||
this.loc = loc; | ||
|
||
hash = 31 * (31 * plan.hashCode() + qry.hashCode() + schema.hashCode()) + (loc ? 1 : 0); |
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.
Objects.hash(...)?
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 Objects.hash()
method has been implemented.
private final SqlPlanKey key; | ||
|
||
/** */ | ||
private final SqlPlanValue val; |
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 do we need extra SqlPlanValue class? Looks like everithing can be stored in SqlPlan
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.
All SQL plan history data is now stored in the SqlPlan
class; the SqlPlanKey
and SqlPlanValue
classes have been removed.
if (historySize <= 0) | ||
return; | ||
|
||
SqlPlan sqlPlan = new SqlPlan(plan, qry, schema, loc, startTs, engine); |
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 think instead of three entities SqlPlan
, SqlPlanKey
, SqlPlanValue
only one can be used (SqlPlan
)
sqlPlanHistory
can be just a map from SqlPlan
to timestamp and we can add entries like:
sqlPlanHistory.put(sqlPlan.key(), U.currentTimeMillis());
We don't need extra parameter startTs
since almost always it will be equals to U.currentTimeMillis().
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.
Done (see previous comment).
} | ||
|
||
/** */ | ||
public enum SqlEngine { |
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 core module shouldn't know about list of query engines. Let's use String instead of this enum. Use IndexingQueryEngineConfiguration.ENGINE_NAME and CalciteQueryEngineConfiguration.ENGINE_NAME from indexing and calcite modules.
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.
Done.
@@ -80,10 +80,10 @@ public final class UpdatePlan { | |||
|
|||
/** Number of rows in rows based MERGE or INSERT. */ | |||
private final int rowsNum; | |||
|
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.
Redundant changes (all in this file)
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.
Corrected.
|
||
SqlPlan sqlPlan = new SqlPlan(plan, qry, schema, loc, engine); | ||
|
||
sqlPlanHistory.put(sqlPlan, sqlPlan.startTime()); |
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.
Are you sure key will be updated after this call.
You use information only from key (including startTime) in the view, if key is not updated, than view will contain a wrong startTime field value.
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.
Yes, the key wasn't updated during the put()
operation. To fix it, I changed the SQL plan history data structure from GridBoundedConcurrentLinkedHashMap
to GridBoundedConcurrentLinkedHashSet
and edited the addPlan()
method, so that newer entries would replace older ones with the same SQL plan.
* @param historySize History size. | ||
*/ | ||
public void setHistorySize(int historySize) { | ||
this.historySize = historySize; |
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.
Let's recreate sqlPlanHistory here. Now this method used only once in test with value 0, but if someone will use this method (perhaps in test too) with another value, result can be unpredicted.
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.
Done.
import org.junit.Test; | ||
|
||
/** Test for Sql plan history configuration. */ | ||
public class SqlPlanHistoryConfigIntegrationTest extends GridCommonAbstractTest { |
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.
Let's move this test to ignite-spring module, instead of adding new dependency to ignite-calcite.
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.
SqlPlanHistoryConfigIntegrationTest
has been moved to the ignite-spring
module.
* @return Cache configuration. | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
private CacheConfiguration configureCahce(String name, Class<?>... idxTypes) { |
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.
Typo: Cahce
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.
Corrected.
|
||
/** Tests for SQL plan history (Calcite engine). */ | ||
@RunWith(Parameterized.class) | ||
public class SqlPlanHistoryIntegrationTest extends GridCommonAbstractTest { |
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.
Test already Parameterized. Perhaps it's worth to add parameters queryEngine and clientMode instead of creating child classes?
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.
queryEngine
and clientMode
have been added to the list of parameters. Test subclasses for H2 and clients have been removed.
queryNode().context().query().runningQueryManager().resetPlanHistoryMetrics(); | ||
|
||
mapNode().context().query().runningQueryManager().resetPlanHistoryMetrics(); |
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.
for (IgniteEx ignite: G.allGrids())
ignite.context().query().runningQueryManager().resetPlanHistoryMetrics();
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.
Done.
/** Checks successful JDBC queries. */ | ||
@Test | ||
public void testJdbcQuery() throws SQLException { | ||
if (loc) |
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.
To ignore test it's better to use assumeTrue/assumeFalse statements. In your case assumeFalse(loc)
.
Tests will be marked as ignored instead of passed (and we can also provide a reason, why they are ignored).
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.
SqlPlanHistoryIntegrationTest
has been refactored using the assumeFalse
statements.
Please resolve also merge conflicts |
CdcConfigurationTest.class | ||
CdcConfigurationTest.class, | ||
|
||
SqlPlanHistoryConfigTest.class |
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.
Let's add comma at the end
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.
Comma added.
…tyPlanHistory added, minor Javadoc changes
…g#executeUpdate0 to IgniteH2Indexing#executeUpdate
…dConcurrentLinkedHashSet, SqlPlanHistoryTracker#addPlan changed, SqlPlanHistoryIntegrationTest#testEntryReplacement added
This reverts commit fb2a47c.
…HistoryIntegrationTest refactored with assumeFalse(), SqlPlanHistoryTracker#setHistorySize edited
… to GridBoundedConcurrentLinkedHashMap
@@ -195,6 +213,11 @@ public RunningQueryManager(GridKernalContext ctx) { | |||
qryHistTracker.queryHistory().values(), | |||
SqlQueryHistoryView::new); | |||
|
|||
ctx.systemView().registerView(SQL_PLAN_HIST_VIEW, SQL_PLAN_HIST_VIEW_DESC, |
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.
You need to use method registerView
with dataSupplier
, since planHistTracker
can be changed and planHistTracker.sqlPlanHistory()
also can be changed, but you rely on the first created instances.
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.
Done.
* @param engine SQL engine. | ||
*/ | ||
public void addPlan(String plan, String qry, String schema, boolean loc, String engine) { | ||
if (historySize <= 0) |
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's not thread-safe and there is race possible. If method setHistorySize
will be exposed (for example via JMX) someone can call this method with 0 value as historySize, and, in the same time addPlan will be called for query by another thead. In this case we can pass current line, face with null sqlPlanHistory field.
I propose do not store historySize at all.
Instead create instance emptyMap if we got historySize == 0:
public void setHistorySize(int historySize) {
sqlPlanHistory = (historySize > 0) ? new GridBoundedConcurrentLinkedHashMap<>(historySize) : Collections.emptyMap();
}
In method addPlan
we can check:
Map<SqlPlan, Long> sqlPlanHistory0 = sqlPlanHistory;
if (sqlPlanHistory0 == Collections.emptyMap())
return;
sqlPlanHistory0.put(sqlPlan, U.currentTimeMillis());
This approach will be thread safe.
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.
Done. Tests verifying correct performance when history size is zero or less have been extended.
* @param idxTypes Index types. | ||
* @return Cache configuration. | ||
*/ | ||
@SuppressWarnings("unchecked") |
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.
Remove it and change method to:
private CacheConfiguration<?, ?> configureCache(String name, Class<?>... idxTypes) {
return new CacheConfiguration<>()
...
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.
Done.
if (isClient) | ||
assertTrue(node.context().clientNode()); | ||
else | ||
assertFalse(node.context().clientNode()); |
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.
assertEquals(isClient, node.context().clientNode());
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.
Done.
{CalciteQueryEngineConfiguration.ENGINE_NAME}, | ||
{IndexingQueryEngineConfiguration.ENGINE_NAME} | ||
}).flatMap(sqlEngine -> Arrays.stream(new Boolean[]{true, false}) | ||
.flatMap(isClient -> Arrays.stream(new Boolean[]{true, false}) |
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.
// Local queries can't be executed on client nodes
.flatMap(isClient -> Arrays.stream(isClient ? new Boolean[]{false} : new Boolean[]{true, false})
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.
Done.
/** Checks TextQuery. */ | ||
@Test | ||
public void testTextQuery() { | ||
runQueryWithoutPlan(textQry); |
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.
As far as I know text query requires text (lucene) index to work. How does it work without index?
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.
Apparently, for caches with built-in classes as data types, marking those classes as indexed types in the cache configuration is sufficient for text queries to work.
However, this is insufficient when custom classes are used as cache data types. In such cases, @QueryTextField
annotations for the corresponding custom class fields will indeed be required.
There is a check in the cacheQuery()
method that ensures all queries return a result, including those executed without a plan. If necessary, I can rewrite the text query test so that it uses a query from the Person
cache and therefore a @QueryTextField
annotation will be needed.
|
||
task.accept(cmds); | ||
|
||
checkSqlPlanHistoryDml(3, qrysInfo.get2()); |
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.
checkSqlPlanHistoryDml(cmds.size(), qrysInfo.get2());
?
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.
Done.
check = "the following " + (loc ? "local " : "") + "query has been executed:"; | ||
|
||
plans = plans.entrySet().stream() | ||
.filter(e -> e.getKey().plan().contains(check)) |
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 do we filter these queries? Do we have another queries in the view?
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.
Yes, in some cases we may also have plans for those select queries that are executed as part of the DML operation (with the H2 engine only).
String plan1 = sortedPlans.get(0).getKey().plan(); | ||
String plan2 = sortedPlans.get(1).getKey().plan(); | ||
|
||
assertTrue(plan2.contains(plan1) && plan2.contains("/* scanCount")); |
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 do we have two plans?
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 scanCount
suffix issue has been resolved, the SqlPlanHistoryIntegrationTest#checkMetrics
method has been refactored.
* @param size Number of SQL plan entries expected to be in the history. | ||
*/ | ||
public void checkSqlPlanHistory(int size) { | ||
if (!isReducePhase && isClient && sqlEngine == IndexingQueryEngineConfiguration.ENGINE_NAME) |
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's strange that we don't have plans in history for regular queries for client node and H2 engine. Do we need to check H2 & client at all? Map/reduce queries are only applicable to H2 engine and can be reproduced with two server nodes (even without distributed joins, for example with aggregation)
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 isClient=TRUE
parameter has been deleted from the H2 engine tests and the map/reduce query test has been refactored.
…ze and SqlPlanHistoryIntegrationTest#testResetPlanHistoryMetrics
…toryTracker#addPlan thread-safe
- get rid of '@SuppressWarnings("unchecked")' in configureCache() - improve readability of queryNode() by shortening the code - optimize params() by omitting TRUE for the isClient parameter - get rid of a hard-coded argument in executeDml()
… and refactor SqlPlanHistoryIntegrationTest#testSqlFieldsQueryWithReducePhase; refactor SqlPlanHistoryIntegrationTest#checkReset
…hat it returns the actual view content
…ier (not a collection) is passed to GridSystemViewManager#registerView
…tionTest#getSqlPlanHistory (order of entries is essential for testing local queries)
…iction - add assertion for waitForCondition() - remove redundant plan history check - change failed function queries to queries with unique placeholders
- move starting 3 grids for checking map nodes to testSqlFieldsQueryWithReducePhase - bring back testSqlFieldsQueryWithReducePhaseFailed - make javadoc for testSqlFieldsQueryWithReducePhase and testSqlFieldsQueryWithReducePhaseFailed more informative - change waiting mechanism in testEntryReplacement
…SqlPlanHistoryIntegrationTest
…hase and testSqlFieldsQueryWithReducePhaseFailed
- fix minor formatting issues - edit javadoc - remove redundant assumeFalse in startTestGrid
…ntegrationTest#checkReset
…= 0 condition, extend tests for verifying correct performance with histSize <= 0
|
||
sqlPlanHistory = (historySize > 0) ? new GridBoundedConcurrentLinkedHashMap<>(historySize) : null; | ||
public SqlPlanHistoryTracker(int histSize) { | ||
sqlPlanHistory = (histSize > 0) ? new GridBoundedConcurrentLinkedHashMap<>(histSize) : Collections.emptyMap(); |
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.
setHistorySize(histSize)
to reduce duplication?
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.
Done.
@@ -47,7 +42,7 @@ public SqlPlanHistoryTracker(int historySize) { | |||
* @param engine SQL engine. | |||
*/ | |||
public void addPlan(String plan, String qry, String schema, boolean loc, String engine) { | |||
if (historySize <= 0) | |||
if (sqlPlanHistory.getClass().equals(Collections.emptyMap().getClass())) |
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 not just sqlPlanHistory == Collections.emptyMap()
?
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.
We can't use sqlPlanHistory == Collections.emptyMap()
because
Operator '==' cannot be applied to 'java.util.Map<org.apache.ignite.internal.processors.query.running.SqlPlan,java.lang.Long>', 'java.util.Map<java.lang.Object,java.lang.Object>'
We also can't use sqlPlanHistory.equals(Collections.emptyMap())
because AbstractMap#equals
identifies two map as equal if they are both empty. So sqlPlanHistory.equals(Collections.emptyMap())
will return TRUE
for a newly created sqlPlanHistory
with size=0
, and the method won't work correctly.
If however we compare classes of sqlPlanHistory
and Collections.emptyMap()
, then the method works as we intended and sqlPlanHistory.getClass().equals(Collections.emptyMap().getClass())
doesn't return TRUE
for a newly created sqlPlanHistory
.
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.
Something like
Map<SqlPlan, Long> emptyMap = Collections.emptyMap();
if (sqlPlanHistory == emptyMap)
return;
?
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.
Yes, this options works. Change applied.
/** | ||
* @return SQL plan entry. | ||
*/ | ||
public Map.Entry<SqlPlan, Long> sqlPlan() { |
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 method gives access to internals via public API. We should avoid this. Method used only once in test method getSqlPlanHistory
. In this method it's more convinient to return something like List<SqlPlanHistoryView>
than Map<SqlPlan, Long>
. In case of List<SqlPlanHistoryView>
- all columns can be checked thats exposed via public API (not only internal representation).
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.
Method SqlPlanHistoryView#sqlPlan
deleted. SqlPlanHistoryIntegrationTest#getSqlPlanHistory
now returns List<SqlPlanHistoryView>
.
}); | ||
} | ||
|
||
/** Checks failed SqlFieldsQuery with reduce phase. */ | ||
/** | ||
* Checks failed SqlFieldsQuery with reduce phase. If the fisrt subquery fails, there should be only one entry in |
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.
Typo: fisrt
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.
Test deleted.
/** Checks failed SqlFieldsQuery with reduce phase. */ | ||
/** | ||
* Checks failed SqlFieldsQuery with reduce phase. If the fisrt subquery fails, there should be only one entry in | ||
* SQL plan history. If the fisrt subquery is successfully executed but the second one fails, the history should |
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.
Typo: fisrt
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.
Test deleted.
|
||
cacheQuery(new SqlFieldsQuery(SQL + " where _val='STR" + i + "'").setLocal(loc), "A"); | ||
|
||
qryText[i - 1] = getSqlPlanHistory().keySet().stream().findFirst().map(SqlPlan::query).orElse(""); |
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.
Check history size?
F.first?
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.
History check added, F.first
used instead of findFirst
.
*/ | ||
public void runQueryWithReducePhase(Runnable task) { | ||
public void runQueryWithReducePhase(Runnable task) throws Exception { | ||
assumeFalse("Map/reduce queries are only applicable to H2 engine", |
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.
assumeFalse(..., x != y)
-> assumeTrue(..., x == y)
for better readability
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.
Done.
@@ -572,19 +622,27 @@ public void runSqlFieldsDml(IgniteBiTuple<List<String>, Boolean> qrysInfo) { | |||
* @param qrysInfo DML commands info (queries, simple query flag). | |||
* @param task Task to be executed. | |||
*/ | |||
public void executeDml(IgniteBiTuple<List<String>, Boolean> qrysInfo, Consumer<List<String>> task) { | |||
public void executeDml(IgniteBiTuple<List<String>, Boolean> qrysInfo, Consumer<List<String>> task) throws Exception { | |||
assumeFalse("There is no lazy mode for DML operations", !isFullyFetched); |
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.
assumeFalse(..., !x)
-> assumeTrue(..., x)
for better readability
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.
Done.
|
||
checkSqlPlanHistory((!isClient && sqlEngine == IndexingQueryEngineConfiguration.ENGINE_NAME) ? 3 : 1); | ||
for (int i = 1; i <= 2; i++) { | ||
Map<SqlPlan, Long> sqlPlansOnMapNode = grid(i).context().query().runningQueryManager() |
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.
Use view, not direct access to tracker.
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.
Done.
// No-op. | ||
} | ||
|
||
checkSqlPlanHistory( i + 1); |
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's not intuitive clear that map-subqueries are executed one by one. It's not stated anywhere and subqueries can be run in parallel with some tuning or after some change in future. So, perhaps we should remove this test at all, since can't assert correct behaviour.
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.
Test deleted.
…g setter in constructor
- remove test for failed query with reduce phase - change return type of getSqlPlanHistory to List<SqlPlanHistoryView> (and remove SqlPlanHistoryView#sqlPlan) - increase readability of assume statements - add overloaded getSqlPlanHistory with node as argument - add plan history check to checkReset - minor code corrections
# Conflicts: # modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
- remove query variables that are used only once - edit javadoc - remove code duplication by moving setLocal to cacheQuery
…l empty map variable in SqlPlanHistoryTracker#add
…lPlanHistoryIntegrationTest
# Conflicts: # modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
…he#11425. Signed-off-by: Aleksey Plekhanov <[email protected]>
Thank you for submitting the pull request to the Apache Ignite.
In order to streamline the review of the contribution
we ask you to ensure the following steps have been taken:
The Contribution Checklist
The description explains WHAT and WHY was made instead of HOW.
The following pattern must be used:
IGNITE-XXXX Change summary
whereXXXX
- number of JIRA issue.(see the Maintainers list)
the
green visa
attached to the JIRA ticket (see TC.Bot: Check PR)Notes
If you need any help, please email [email protected] or ask anу advice on http://asf.slack.com #ignite channel.