Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,9 @@
/** */
private boolean isSystemFieldName(String alias) {
return QueryUtils.KEY_FIELD_NAME.equalsIgnoreCase(alias)
|| QueryUtils.VAL_FIELD_NAME.equalsIgnoreCase(alias);
|| QueryUtils.VAL_FIELD_NAME.equalsIgnoreCase(alias)
// TODO: IGNITE-28223 Похоже что тут надо будет поменять

Check warning on line 546 in modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/IgniteSqlValidator.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this TODO comment.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZzr1GVppV0X0E10limS&open=AZzr1GVppV0X0E10limS&pullRequest=12893
|| "KEY_TO_STRING".equalsIgnoreCase(alias);
}

/** {@inheritDoc} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,12 @@
private RelDataType tableRowType;

/** */
public CacheTableDescriptorImpl(GridCacheContextInfo<?, ?> cacheInfo, GridQueryTypeDescriptor typeDesc,
Object affinityIdentity) {
public CacheTableDescriptorImpl(
GridCacheContextInfo<?, ?> cacheInfo,
GridQueryTypeDescriptor typeDesc,
Object affinityIdentity,
VirtualColumnProvider virtColProv
) {
this.cacheInfo = cacheInfo;
this.typeDesc = typeDesc;
this.affinityIdentity = affinityIdentity;
Expand Down Expand Up @@ -150,6 +154,13 @@

int fldIdx = QueryUtils.VAL_COL + 1;

// TODO: IGNITE-28223 Проверить, что не будет дублирования имен виртуальных колонок

Check warning on line 157 in modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this TODO comment.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZzr6ogSnvODKcpvOGVr&open=AZzr6ogSnvODKcpvOGVr&pullRequest=12893
// TODO: IGNITE-28223 Подумать, что будет если пользователь захочет создать колонку с именем виртуальной колонки

Check warning on line 158 in modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableDescriptorImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this TODO comment.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZzr6ogSnvODKcpvOGVs&open=AZzr6ogSnvODKcpvOGVs&pullRequest=12893
List<CacheColumnDescriptor> virtCols = virtColProv.provideVirtualColumns(fldIdx);
descriptors.addAll(virtCols);
fldIdx += virtCols.size();
virtCols.forEach(c -> virtualFields.set(c.fieldIndex()));

int keyField = QueryUtils.KEY_COL;
int valField = QueryUtils.VAL_COL;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,12 @@ private IgniteCacheTable createTable(
GridQueryTypeDescriptor typeDesc,
GridCacheContextInfo<?, ?> cacheInfo
) {
CacheTableDescriptorImpl desc =
new CacheTableDescriptorImpl(cacheInfo, typeDesc, affinityIdentity(cacheInfo.config()));
CacheTableDescriptorImpl desc = new CacheTableDescriptorImpl(
cacheInfo,
typeDesc,
affinityIdentity(cacheInfo.config()),
ctx.plugins().createComponentOrDefault(VirtualColumnProvider.class, VirtualColumnProvider.EMPTY)
);

return new CacheTableImpl(ctx, desc);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.schema;

import java.util.List;
import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor;
import org.apache.ignite.plugin.PluginProvider;

/**
* Virtual table column provider from {@link PluginProvider plugin} created via {@link IgnitePluginProcessor#createComponent(Class)} for
* {@link CalciteQueryEngineConfiguration calcite engine}.
*/
@FunctionalInterface
public interface VirtualColumnProvider {
VirtualColumnProvider EMPTY = nextColumnIndex -> List.of();

/**
* Returns a list of virtual columns to add to the table.
*
* @param nxtColIdx Next column index.
*/
List<CacheColumnDescriptor> provideVirtualColumns(int nxtColIdx);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* 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.schema;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
import org.apache.ignite.internal.processors.query.calcite.util.TypeUtils;

import static org.apache.calcite.rel.type.RelDataType.PRECISION_NOT_SPECIFIED;
import static org.apache.calcite.rel.type.RelDataType.SCALE_NOT_SPECIFIED;

/** Abstract class for tests which allows to avoid redundant boilerplate code. */
public abstract class AbstractTestCacheColumnDescriptor implements CacheColumnDescriptor {
/** */
private final int idx;

/** */
private final String name;

/** */
private final Type type;

/** */
private final boolean isKey;

/** */
private final boolean isField;

/** */
private volatile RelDataType logicalType;

/** */
protected AbstractTestCacheColumnDescriptor(int idx, String name, Type type, boolean isKey, boolean isField) {
this.idx = idx;
this.name = name;
this.type = type;
this.isKey = isKey;
this.isField = isField;
}

/** {@inheritDoc} */
@Override public boolean field() {
return isField;
}

/** {@inheritDoc} */
@Override public boolean key() {
return isKey;
}

/** {@inheritDoc} */
@Override public String name() {
return name;
}

/** {@inheritDoc} */
@Override public int fieldIndex() {
return idx;
}

/** {@inheritDoc} */
@Override public RelDataType logicalType(IgniteTypeFactory f) {
if (logicalType == null) {
logicalType = TypeUtils.sqlType(
f,
type.cls,
type.precision != Type.NOT_SPECIFIED ? type.precision : PRECISION_NOT_SPECIFIED,
type.scale != Type.NOT_SPECIFIED ? type.scale : SCALE_NOT_SPECIFIED,
type.nullable
);
}

return logicalType;
}

/** {@inheritDoc} */
@Override public Class<?> storageType() {
return type.cls;
}

/** */
public static class Type {
/** */
public static final int NOT_SPECIFIED = -1;

/** */
private final Class<?> cls;

/** */
private final int precision;

/** */
private final int scale;

/** */
private final boolean nullable;

/** */
private Type(Class<?> cls, int precision, int scale, boolean nullable) {
this.cls = cls;
this.precision = precision;
this.scale = scale;
this.nullable = nullable;
}

/** */
public static Type nullable(Class<?> cls) {
return new Type(cls, NOT_SPECIFIED, NOT_SPECIFIED, true);
}

/** */
public static Type notNull(Class<?> cls) {
return new Type(cls, NOT_SPECIFIED, NOT_SPECIFIED, false);
}

/** */
public static Type of(Class<?> cls, int precision, int scale, boolean nullable) {
return new Type(cls, precision, scale, nullable);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* 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.schema;

import java.util.List;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.SqlConfiguration;
import org.apache.ignite.indexing.IndexingQueryEngineConfiguration;
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.internal.processors.query.calcite.integration.AbstractBasicIntegrationTest;
import org.apache.ignite.plugin.AbstractTestPluginProvider;
import org.apache.ignite.plugin.PluginContext;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;

/** For {@link VirtualColumnProvider} testing. */
public class VirtualColumnProviderTest extends AbstractBasicIntegrationTest {
/** */
private static final String KEY_TO_STRING_COLUMN_NAME = "KEY_TO_STRING";

/** {@inheritDoc} */
@Override protected int nodeCount() {
return 1;
}

/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
SqlConfiguration sqlCfg = new SqlConfiguration().setQueryEnginesConfiguration(
new CalciteQueryEngineConfiguration().setDefault(true),
new IndexingQueryEngineConfiguration()
);

return super.getConfiguration(igniteInstanceName)
.setSqlConfiguration(sqlCfg)
.setPluginProviders(new TestVirtualColumnPluginProvider());
}

/** */
@Test
public void test() {
sql("create table PUBLIC.PERSON(id int primary key, name varchar)");

for (int i = 0; i < 2; i++)
sql("insert into PUBLIC.PERSON(id, name) values (?, ?)", i, "foo" + i);

// Let's make sure that when using '*' there will be no virtual column.
assertQuery("select * from PUBLIC.PERSON order by id")
.columnNames("ID", "NAME")
.returns(0, "foo0")
.returns(1, "foo1")
.check();

// Let's make sure that when we specify a virtual column, we get it.
assertQuery(String.format("select id, name, %s from PUBLIC.PERSON order by id", KEY_TO_STRING_COLUMN_NAME))
.columnNames("ID", "NAME", KEY_TO_STRING_COLUMN_NAME)
.returns(0, "foo0", "0")
.returns(1, "foo1", "1")
.check();

// Let's check the use of a virtual column in where.
assertQuery(String.format(
"select id, name, %1$s from PUBLIC.PERSON where %1$s = %2$s order by id",
KEY_TO_STRING_COLUMN_NAME, "1"
))
.columnNames("ID", "NAME", KEY_TO_STRING_COLUMN_NAME)
.returns(1, "foo1", "1")
.check();

// Let's check the use of a virtual column in order by.
assertQuery(String.format("select id, name, %1$s from PUBLIC.PERSON order by %1$s", KEY_TO_STRING_COLUMN_NAME))
.columnNames("ID", "NAME", KEY_TO_STRING_COLUMN_NAME)
.returns(0, "foo0", "0")
.returns(1, "foo1", "1")
.check();
}

/** */
private static class TestVirtualColumnPluginProvider extends AbstractTestPluginProvider {
/** {@inheritDoc} */
@Override public String name() {
return getClass().getSimpleName();
}

/** {@inheritDoc} */
@Override public <T> @Nullable T createComponent(PluginContext ctx, Class<T> cls) {
if (VirtualColumnProvider.class.equals(cls)) {
return (T) (VirtualColumnProvider) nxtColIdx -> List.of(new KeyToStingVirtualColumn(nxtColIdx));
}

return super.createComponent(ctx, cls);
}
}

/** */
private static class KeyToStingVirtualColumn extends AbstractTestCacheColumnDescriptor {
/** */
private KeyToStingVirtualColumn(int idx) {
super(idx, KEY_TO_STRING_COLUMN_NAME, Type.nullable(String.class), false, false);
}

/** {@inheritDoc} */
@Override public Object value(
ExecutionContext<?> ectx,
GridCacheContext<?, ?> cctx,
CacheDataRow src
) throws IgniteCheckedException {
return cctx.unwrapBinaryIfNeeded(src.key(), false, null).toString();
}

/** {@inheritDoc} */
@Override public void set(Object dst, Object val) {
throw new UnsupportedOperationException();
}

/** {@inheritDoc} */
@Override public boolean hasDefaultValue() {
return false;
}

/** {@inheritDoc} */
@Override public Object defaultValue() {
throw new UnsupportedOperationException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import org.apache.ignite.internal.processors.query.calcite.rules.JoinOrderOptimizationTest;
import org.apache.ignite.internal.processors.query.calcite.rules.OrToUnionRuleTest;
import org.apache.ignite.internal.processors.query.calcite.rules.ProjectScanMergeRuleTest;
import org.apache.ignite.internal.processors.query.calcite.schema.VirtualColumnProviderTest;
import org.apache.ignite.internal.processors.query.calcite.thin.MultiLineQueryTest;
import org.apache.ignite.internal.processors.tx.TxWithExceptionalInterceptorTest;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -174,7 +175,8 @@
QueryEntityValueColumnAliasTest.class,
CacheStoreTest.class,
MultiDcQueryMappingTest.class,
TxWithExceptionalInterceptorTest.class
TxWithExceptionalInterceptorTest.class,
VirtualColumnProviderTest.class
})
public class IntegrationTestSuite {
}
Loading
Loading