-
Notifications
You must be signed in to change notification settings - Fork 1.9k
IGNITE-28223 Provide the ability to add pseudo columns to tables for Calcite engine #12893
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
Changes from all commits
c03e0e2
85bef41
1d1def0
40556af
13b3f8f
2bedd50
538af66
a12728e
c75729f
0612683
3abb3dc
4365d05
50d790f
11b48be
34ae7ae
f66f416
a723307
eacf0ee
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 |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.ignite.calcite; | ||
|
|
||
| import org.apache.ignite.IgniteCheckedException; | ||
| import org.apache.ignite.lang.IgniteExperimental; | ||
|
|
||
| /** Pseudocolumn descriptor. */ | ||
| @IgniteExperimental | ||
| public interface PseudoColumnDescriptor { | ||
| /** */ | ||
| int NOT_SPECIFIED = -1; | ||
|
|
||
| /** @return Name of pseudocolumn. */ | ||
| String name(); | ||
|
|
||
| /** @return Pseudocolumn type. */ | ||
| Class<?> type(); | ||
|
|
||
| /** @return Scale of pseudocolumn type, {@value #NOT_SPECIFIED} if not specified. */ | ||
| int scale(); | ||
|
|
||
| /** @return Precision of pseudocolumn type, {@value #NOT_SPECIFIED} if not specified. */ | ||
| int precision(); | ||
|
|
||
| /** | ||
| * @param ctx Context to extract value. | ||
| * @return Value of a pseudocolumn. | ||
| * @throws IgniteCheckedException If there are errors when getting value. | ||
| */ | ||
| Object value(PseudoColumnValueExtractorContext ctx) throws IgniteCheckedException; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.ignite.calcite; | ||
|
|
||
| import java.util.List; | ||
| import org.apache.ignite.lang.IgniteExperimental; | ||
| import org.apache.ignite.plugin.PluginContext; | ||
| import org.apache.ignite.plugin.PluginProvider; | ||
|
|
||
| /** | ||
| * Table pseudocolumn provider from {@link PluginProvider plugin} created via | ||
| * {@link PluginProvider#createComponent(PluginContext, Class)} for Calcite-based query engine. | ||
| */ | ||
| @FunctionalInterface | ||
| @IgniteExperimental | ||
| public interface PseudoColumnProvider { | ||
| /** */ | ||
| PseudoColumnProvider EMPTY = List::of; | ||
|
|
||
| /** | ||
| * Returns a list of pseudocolumn descriptions to add to tables. | ||
| * | ||
| * <p>NOTES:</p> | ||
| * <ul> | ||
| * <li>When used in "SELECT", the pseudocolumn is applied to the table and not to the entire result.</li> | ||
| * <li>Added only for user tables, not for system views.</li> | ||
| * <li>{@link PseudoColumnDescriptor#name()} - it is recommended to return in uppercase.</li> | ||
| * <li>{@link PseudoColumnDescriptor#name()} - it is forbidden to use system names {@code "_KEY"} and | ||
| * {@code "_VAL"}.</li> | ||
| * <li>User will get an error when trying to create a column with name of one of pseudo ones.</li> | ||
| * <li>Updating or inserting into a pseudocolumn is prohibited.</li> | ||
| * </ul> | ||
| * @return Pseudocolumn descriptors. | ||
| */ | ||
| List<PseudoColumnDescriptor> provideDescriptors(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.ignite.calcite; | ||
|
|
||
| import org.apache.ignite.binary.BinaryObject; | ||
| import org.apache.ignite.lang.IgniteExperimental; | ||
|
|
||
| /** Context for extracting value of a pseudocolumn. */ | ||
| @IgniteExperimental | ||
| public interface PseudoColumnValueExtractorContext { | ||
| /** @return Cache ID. */ | ||
| int cacheId(); | ||
|
|
||
| /** @return Cache name. */ | ||
| String cacheName(); | ||
|
|
||
| /** @return Partition ID. */ | ||
| int partition(); | ||
|
|
||
| /** | ||
| * @param keyOrValue {@code true} if a cache key (primary key) is needed, {@code false} if a cache value is needed. | ||
| * @param keepBinary {@code true} if returned as {@link BinaryObject}. If key or value is not composite, it may | ||
| * return not as {@link BinaryObject}, but as a simple type. | ||
| * @return Source for getting value of pseudocolumn. | ||
| */ | ||
| Object source(boolean keyOrValue, boolean keepBinary); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.ignite.internal.processors.query.calcite; | ||
|
|
||
| import org.apache.ignite.calcite.PseudoColumnValueExtractorContext; | ||
| import org.apache.ignite.internal.processors.cache.GridCacheContext; | ||
| import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; | ||
| import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext; | ||
| import org.apache.ignite.lang.IgniteExperimental; | ||
|
|
||
| /** Internal extension with additional methods and constants. */ | ||
| @IgniteExperimental | ||
| public interface PseudoColumnValueExtractorContextEx extends PseudoColumnValueExtractorContext { | ||
| /** Returns execution context. */ | ||
| ExecutionContext<?> executionCtx(); | ||
|
Check failure on line 30 in modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/PseudoColumnValueExtractorContextEx.java
|
||
|
|
||
| /** Returns cache context. */ | ||
| GridCacheContext<?, ?> cacheCtx(); | ||
|
Check failure on line 33 in modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/PseudoColumnValueExtractorContextEx.java
|
||
|
|
||
| /** Returns source cache data row. */ | ||
| CacheDataRow source(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,8 @@ | |
| import org.apache.calcite.schema.Table; | ||
| import org.apache.ignite.IgniteCheckedException; | ||
| import org.apache.ignite.cache.QueryEntity; | ||
| import org.apache.ignite.calcite.PseudoColumnDescriptor; | ||
| import org.apache.ignite.calcite.PseudoColumnProvider; | ||
| import org.apache.ignite.configuration.CacheConfiguration; | ||
| import org.apache.ignite.internal.processors.cache.GridCacheContext; | ||
| import org.apache.ignite.internal.processors.cache.GridCacheContextInfo; | ||
|
|
@@ -62,6 +64,7 @@ | |
| import org.apache.ignite.lang.IgniteUuid; | ||
| import org.apache.ignite.plugin.security.SecurityPermission; | ||
|
|
||
| import static java.util.stream.Collectors.toSet; | ||
| import static org.apache.ignite.internal.processors.query.QueryUtils.convert; | ||
| import static org.apache.ignite.internal.processors.query.QueryUtils.isDdlOnSchemaSupported; | ||
|
|
||
|
|
@@ -129,6 +132,8 @@ private void handle0(CreateTableCommand cmd) throws IgniteCheckedException { | |
|
|
||
| isDdlOnSchemaSupported(cmd.schemaName()); | ||
|
|
||
| checkPseudoColumns(cmd); | ||
|
|
||
| if (schemaSupp.get().getSubSchema(cmd.schemaName()).getTable(cmd.tableName()) != null) { | ||
| if (cmd.ifNotExists()) | ||
| return; | ||
|
|
@@ -399,4 +404,21 @@ else if (!F.isEmpty(cmd.primaryKeyColumns()) && cmd.primaryKeyColumns().size() = | |
|
|
||
| return res; | ||
| } | ||
|
|
||
| /** */ | ||
| private void checkPseudoColumns(CreateTableCommand cmd) { | ||
| PseudoColumnProvider pseudoColProv = cacheProc.context().kernalContext().plugins().createComponentOrDefault( | ||
|
Contributor
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. Same default in all places where you call
Contributor
Author
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. Into which method? Please give more specifics.
Contributor
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 think it might not be necessary to carry around the EMPTY constant. Is there really no way to encapsulate it in the method createComponent?
Contributor
Author
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 don't think so, or can you show me how this can be done? |
||
| PseudoColumnProvider.class, PseudoColumnProvider.EMPTY | ||
| ); | ||
|
|
||
| Set<String> tblColNameSet = cmd.columns().stream().map(ColumnDefinition::name).collect(toSet()); | ||
|
|
||
| for (PseudoColumnDescriptor desc : pseudoColProv.provideDescriptors()) { | ||
| if (tblColNameSet.contains(desc.name())) { | ||
| throw new IgniteSQLException( | ||
| String.format("Pseudocolumn name must not overlap with user ones: [name=%s]", desc.name()) | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.