Skip to content
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

Closed
wants to merge 59 commits into from

Conversation

oleg-vlsk
Copy link
Contributor

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

  • There is a single JIRA ticket related to the pull request.
  • The web-link to the pull request is attached to the JIRA ticket.
  • The JIRA ticket has the Patch Available state.
  • The pull request body describes changes that have been made.
    The description explains WHAT and WHY was made instead of HOW.
  • The pull request title is treated as the final commit message.
    The following pattern must be used: IGNITE-XXXX Change summary where XXXX - number of JIRA issue.
  • A reviewer has been mentioned through the JIRA comments
    (see the Maintainers list)
  • The pull request has been checked by the Teamcity Bot and
    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.

"; 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) + "]") +
Copy link
Contributor

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.

Copy link
Contributor Author

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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h2.runningQueryManager().planHistoryTracker().addPlan(...)?

Copy link
Contributor Author

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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h2.runningQueryManager().planHistoryTracker().addPlan(...)?

Copy link
Contributor Author

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Objects.hash(...)?

Copy link
Contributor Author

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;
Copy link
Contributor

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

Copy link
Contributor Author

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);
Copy link
Contributor

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().

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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;

Copy link
Contributor

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)

Copy link
Contributor Author

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());
Copy link
Contributor

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.

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Sep 25, 2024

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;
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: Cahce

Copy link
Contributor Author

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 {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Comment on lines 276 to 278
queryNode().context().query().runningQueryManager().resetPlanHistoryMetrics();

mapNode().context().query().runningQueryManager().resetPlanHistoryMetrics();
Copy link
Contributor

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();

Copy link
Contributor Author

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)
Copy link
Contributor

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).

Copy link
Contributor Author

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.

@alex-plekhanov
Copy link
Contributor

Please resolve also merge conflicts

CdcConfigurationTest.class
CdcConfigurationTest.class,

SqlPlanHistoryConfigTest.class
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comma added.

oleg-vlsk and others added 25 commits October 8, 2024 07:17
…g#executeUpdate0 to IgniteH2Indexing#executeUpdate
…dConcurrentLinkedHashSet, SqlPlanHistoryTracker#addPlan changed, SqlPlanHistoryIntegrationTest#testEntryReplacement added
…HistoryIntegrationTest refactored with assumeFalse(), SqlPlanHistoryTracker#setHistorySize edited
@@ -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,
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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.

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Nov 8, 2024

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")
Copy link
Contributor

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<>()
    ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 220 to 223
if (isClient)
assertTrue(node.context().clientNode());
else
assertFalse(node.context().clientNode());
Copy link
Contributor

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());

Copy link
Contributor Author

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})
Copy link
Contributor

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})

Copy link
Contributor Author

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);
Copy link
Contributor

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?

Copy link
Contributor Author

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());
Copy link
Contributor

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());?

Copy link
Contributor Author

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))
Copy link
Contributor

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?

Copy link
Contributor Author

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"));
Copy link
Contributor

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?

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Nov 8, 2024

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)
Copy link
Contributor

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)

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Nov 8, 2024

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
- 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
…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
…hase and testSqlFieldsQueryWithReducePhaseFailed
- fix minor formatting issues
- edit javadoc
- remove redundant assumeFalse in startTestGrid
…= 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();
Copy link
Contributor

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?

Copy link
Contributor Author

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()))
Copy link
Contributor

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()?

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Dec 14, 2024

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.

Copy link
Contributor

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;

?

Copy link
Contributor Author

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() {
Copy link
Contributor

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).

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: fisrt

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: fisrt

Copy link
Contributor Author

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("");
Copy link
Contributor

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?

Copy link
Contributor Author

@oleg-vlsk oleg-vlsk Dec 15, 2024

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",
Copy link
Contributor

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

Copy link
Contributor Author

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);
Copy link
Contributor

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

Copy link
Contributor Author

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()
Copy link
Contributor

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.

Copy link
Contributor Author

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);
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test deleted.

- 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
# Conflicts:
#	modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java
@asfgit asfgit closed this in 2d69600 Dec 23, 2024
luchnikovbsk pushed a commit to luchnikovbsk/ignite that referenced this pull request Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants