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-22717 SQL Calcite: User defined SQL views #11467

Closed
wants to merge 7 commits into from

Conversation

alex-plekhanov
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.

@alex-plekhanov alex-plekhanov force-pushed the ignite-22717 branch 2 times, most recently from 0eec8ce to 30fc18d Compare August 8, 2024 08:44
igniteSchemas.forEach(newCalciteSchema::add);
newCalciteSchema.add(QueryUtils.DFLT_SCHEMA, new IgniteSchema(QueryUtils.DFLT_SCHEMA));

for (IgniteSchema schema : igniteSchemas.values())
Copy link
Contributor

Choose a reason for hiding this comment

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

I like similar to the previous: igniteSchemas.values().forEach(sch->sch.register(newCalciteSchema));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a matter of taste. sch->sch.register(newCalciteSchema) creates one additional object on each call for lambda.

}

/**
* Drop view.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same: descriptor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We drop view by descriptor.

new StatisticsTarget(schemaName, typeDesc.tableName(), cols.toArray(EMPTY_STRINGS))
),
false
mgmtBusyExecutor.execute(() ->
Copy link
Contributor

Choose a reason for hiding this comment

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

Can a related statistic survive for long if the executor is busy for long by an active statistics collection tasks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. I think it's not so critical. If column doesn't exists, statistics for this column will no hurt anyone.
  2. Statistics update is done via the same executor (but statistics update after table creation or modification is more critical than statistics delete).

@@ -451,6 +454,9 @@ public void onCacheDestroyed(String cacheName, boolean rmvIdx, boolean clearIdx)
if (schema.decrementUsageCount()) {
schemas.remove(schemaName);

if (destroy)
Copy link
Contributor

@Vladsz83 Vladsz83 Aug 14, 2024

Choose a reason for hiding this comment

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

We just removed local schema and called onSchemaDropped(). Why do we keep cluster schema if cache was only stopped? Looks wierd.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't get this comment.
We drop views on cache destroy, on cache stop we shouldn't drop the views.

# Conflicts:
#	modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java
@@ -41,6 +41,9 @@ public class IgniteSchema extends AbstractSchema {
/** */
private final Multimap<String, Function> funcMap = Multimaps.synchronizedMultimap(HashMultimap.create());

/** */
private final Map<String, String> viewMap = new ConcurrentHashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

For the tables and the functions we store interfaces like Function or IgniteTable. For views a string/sql/request instead. Could we similary keep something like TableMacro. If I'm right, function register would not be required in that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TableMacro requires schamaPlus. We don't have a schemaPlus until register method, so we can't use table macro here.


while (true) {
if (F.isEmpty(origin) || cnt++ >= 100)
return typeFactory.getResultClass(type);
Copy link
Contributor

Choose a reason for hiding this comment

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

An exception may be like "Unsupported views depth"? Should we limit this threshold somewhere at a view creation? Like MAX_VIEW_DEPTH = 10?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We already have a check for recursive views, I'm not sure we should limit count of inner views.
I think this case will never happens (since we prohibit recursive views), but this condition is just for our own peace of mind.
I've indroduced new variable MAX_VIEW_DEPTH instead of hardcoded value.

Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if the threshold is reached? A wrong type? A type coercion or a cast error? Do we have a test for it? I tried MAX_VIEW_DEPTH == 1, MAX_VIEW_DEPTH == 0. All the related tests seem to work.

}

/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
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 remove this method

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to override this method, since we need to control grids lifecycle in each test

client.destroyCache("CACHE1");

assertViewsCount("PUBLIC", "MY_VIEW", 1);
assertViewsCount("CACHE1", "MY_VIEW", 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we remove a schema when it contains a view which requests an existing tabe/cache? There a VIEW which calls existing public.my_table

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have dedicated schema management procedures, except cache create/destroy. When schema is dropped (force by cache destroy) - it's assumed that schema objects is dropped too.

initGrids(3);
initTable(3);

assertThrows("CREATE VIEW my_schema.my_view AS SELECT * FROM public.my_table", IgniteSQLException.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 check full message or at least a part from it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are different messages for calcite and H2 engines, so only common part is checked here

* Tests views information distribution on node join.
*/
@Test
public void testNodeJoin() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

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

What if only non-baseline node left? Will a view exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Distributed metastorage is stored on non-baseline nodes too (AFAIK)


/** */
public void clearSchemaViews(String schemaName) {
if (!U.isLocalNodeCoordinator(ctx.discovery()))
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 use !U.isLocalNodeCoordinator(ctx.discovery()) outside

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I disagree here.
SchemaSqlViewManager - it's a global manager, it's his responsibility to control global views state.
SchemaManager it's a local-node manager and shouldn't know about ways, how SchemaSqlViewManager store the views.

# Conflicts:
#	modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/generated/IgniteSqlParserImpl.java
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
13 New Code Smells (required ≤ 1)

See analysis details on SonarCloud

Catch issues before they fail your Quality Gate with our IDE extension SonarLint

@asfgit asfgit closed this in d92c4a3 Sep 24, 2024
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