1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-02-09 12:03:44 +02:00

#792 Улучшение проверки ql-temp-table-index

This commit is contained in:
Dmitriy Marmyshev 2021-09-26 23:24:11 +03:00
parent c924fd73eb
commit 415e382f1e
7 changed files with 172 additions and 5 deletions

View File

@ -39,6 +39,7 @@ final class Messages
public static String JoinToSubQuery_Query_join_to_sub_query_not_allowed;
public static String JoinToSubQuery_title;
public static String TempTableHasIndex_description;
public static String TempTableHasIndex_Exclude_table_name_pattern;
public static String TempTableHasIndex_New_temporary_table_should_have_indexes;
public static String TempTableHasIndex_title;
static

View File

@ -17,6 +17,7 @@ import static com._1c.g5.v8.dt.ql.model.QlPackage.Literals.ABSTRACT_QUERY_SCHEMA
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.ql.model.AbstractQuerySchemaTable;
import com._1c.g5.v8.dt.ql.model.QuerySchemaSelectQuery;
import com.e1c.g5.v8.dt.check.CheckComplexity;
@ -38,6 +39,10 @@ public class TempTableHasIndex
private static final String CHECK_ID = "ql-temp-table-index"; //$NON-NLS-1$
private static final String PARAMETER_EXCLUDE_TABLE_NAME_PATTERN = "excludeObjectNamePattern"; //$NON-NLS-1$
private static final int MAX_TOP = 1000;
@Override
public String getCheckId()
{
@ -53,6 +58,8 @@ public class TempTableHasIndex
.severity(IssueSeverity.MAJOR)
.issueType(IssueType.PERFORMANCE)
.delegate(QuerySchemaSelectQuery.class);
builder.parameter(PARAMETER_EXCLUDE_TABLE_NAME_PATTERN, String.class, StringUtils.EMPTY,
Messages.TempTableHasIndex_Exclude_table_name_pattern);
}
@Override
@ -60,7 +67,7 @@ public class TempTableHasIndex
ICheckParameters parameters, IProgressMonitor monitor)
{
QuerySchemaSelectQuery selectQuery = (QuerySchemaSelectQuery)object;
if (selectQuery.getPlacementTable() == null)
if (selectQuery.getPlacementTable() == null || isTopLessThenThousand(selectQuery))
{
return;
}
@ -68,9 +75,33 @@ public class TempTableHasIndex
if (selectQuery.getIndexes() == null || selectQuery.getIndexes().isEmpty())
{
AbstractQuerySchemaTable table = selectQuery.getPlacementTable();
String excludeTableNamePattern = parameters.getString(PARAMETER_EXCLUDE_TABLE_NAME_PATTERN);
if (excludeTableNamePattern != null && !excludeTableNamePattern.isBlank()
&& table.getFullTableName().matches(excludeTableNamePattern))
{
return;
}
resultAceptor.addIssue(Messages.TempTableHasIndex_New_temporary_table_should_have_indexes, table,
ABSTRACT_QUERY_SCHEMA_TABLE__TABLE_NAME);
}
}
private boolean isTopLessThenThousand(QuerySchemaSelectQuery selectQuery)
{
if (!selectQuery.getOperators().isEmpty() && selectQuery.getOperators().get(0).getGetRecordsCount() != null)
{
String count = selectQuery.getOperators().get(0).getGetRecordsCount();
try
{
int top = Integer.parseInt(count);
return top < MAX_TOP;
}
catch (NumberFormatException e)
{
// do nothing
}
}
return false;
}
}

View File

@ -24,5 +24,6 @@ JoinToSubQuery_description=Query join with sub query
JoinToSubQuery_Query_join_to_sub_query_not_allowed=Query join to sub query not allowed
JoinToSubQuery_title=Query join with sub query
TempTableHasIndex_description=Temporary table should have indexes
TempTableHasIndex_Exclude_table_name_pattern=Exclude table name pattern
TempTableHasIndex_New_temporary_table_should_have_indexes=New temporary table should have indexes
TempTableHasIndex_title=Temporary table should have indexes

View File

@ -39,6 +39,8 @@ JoinToSubQuery_description = Соединение запроса с подзап
JoinToSubQuery_title = Соединение запроса с подзапросом
TempTableHasIndex_Exclude_table_name_pattern = Выражения исключения имени таблицы
TempTableHasIndex_New_temporary_table_should_have_indexes = Новая временная таблица должна содержать индексы
TempTableHasIndex_description = Временная таблица должна содержать индексы

View File

@ -0,0 +1,12 @@
SELECT TOP 100000
1 AS Field
INTO T
;
////////////////////////////////////////////////////////////////////////////////
SELECT TOP 100
T.Field
FROM
T AS T
INTO T2
;

View File

@ -18,6 +18,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.ecore.EObject;
@ -46,10 +47,14 @@ public class TempTableHasIndexTest
private static final String FOLDER = "/resources/";
private static final String PARAMETER_EXCLUDE_TABLE_NAME_PATTERN = "excludeObjectNamePattern";
private TestingCheckResultAcceptor resultAcceptor;
private TestingQlResultAcceptor qlResultAcceptor;
private TestingCheckParameters emptyParameters;
private TempTableHasIndex check;
@Override
@ -63,6 +68,7 @@ public class TempTableHasIndexTest
{
resultAcceptor = new TestingCheckResultAcceptor();
qlResultAcceptor = new TestingQlResultAcceptor();
emptyParameters = new TestingCheckParameters(Map.of(PARAMETER_EXCLUDE_TABLE_NAME_PATTERN, ""));
QlBasicDelegateCheck.setResultAcceptor((o, f) -> qlResultAcceptor);
check = new TempTableHasIndex();
}
@ -84,14 +90,45 @@ public class TempTableHasIndexTest
EObject selectQuery = querySchema.getQueries().get(1);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, null, new NullProgressMonitor());
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertTrue(qlResultAcceptor.featuredMessages.isEmpty());
selectQuery = querySchema.getQueries().get(0);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, null, new NullProgressMonitor());
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertFalse(qlResultAcceptor.featuredMessages.isEmpty());
}
@Test
public void testTempTableWithoutIndexWithRecordCount() throws Exception
{
IDtProject project = dtProjectManager.getDtProject(PROJECT_NAME);
String queryText =
new String(getClass().getResourceAsStream(FOLDER + "temp-table-has-no-index-top.ql").readAllBytes(),
StandardCharsets.UTF_8);
QuerySchema querySchema = DcsUtil.getQuerySchema(queryText, project);
assertNotNull(querySchema);
assertEquals(2, querySchema.getQueries().size());
QlBasicDelegateCheck.setOwner(new QueryOwner(querySchema, null));
EObject selectQuery = querySchema.getQueries().get(1);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertTrue(qlResultAcceptor.featuredMessages.isEmpty());
selectQuery = querySchema.getQueries().get(0);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertFalse(qlResultAcceptor.featuredMessages.isEmpty());
@ -115,14 +152,14 @@ public class TempTableHasIndexTest
EObject selectQuery = querySchema.getQueries().get(1);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, null, new NullProgressMonitor());
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertTrue(qlResultAcceptor.featuredMessages.isEmpty());
selectQuery = querySchema.getQueries().get(0);
assertTrue(selectQuery instanceof QuerySchemaSelectQuery);
check.check(selectQuery, resultAcceptor, null, new NullProgressMonitor());
check.check(selectQuery, resultAcceptor, emptyParameters, new NullProgressMonitor());
assertTrue(qlResultAcceptor.messages.isEmpty());
assertTrue(qlResultAcceptor.featuredMessages.isEmpty());

View File

@ -0,0 +1,83 @@
/**
*
*/
package com.e1c.v8codestyle.ql.check.itests;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.WrongParameterException;
/**
* @author Dmitriy Marmyshev
*
*/
public class TestingCheckParameters
implements ICheckParameters
{
private final Map<String, Object> data;
public TestingCheckParameters(Map<String, Object> data)
{
this.data = Objects.requireNonNull(data);
}
@Override
public int getInt(String name)
{
return get(name, Integer.class).intValue();
}
@Override
public long getLong(String name)
{
return get(name, Long.class).longValue();
}
@Override
public boolean getBoolean(String name)
{
return get(name, Boolean.class).booleanValue();
}
@Override
public double getDouble(String name)
{
return get(name, Double.class).doubleValue();
}
@Override
public String getString(String name)
{
return get(name, String.class);
}
@Override
public Set<String> keySet()
{
return this.data.keySet();
}
@Override
public String toString()
{
return this.data.toString();
}
private <T> T get(String name, Class<T> type) throws WrongParameterException
{
Object value = this.data.get(name);
if (value == null)
throw new WrongParameterException(name, "Parameter not found");
if (type.isInstance(value))
return type.cast(value);
if (value instanceof WrongParameterException)
throw new WrongParameterException(name, ((WrongParameterException)value).getMessage());
throw new WrongParameterException(name,
MessageFormat.format("Parameter has a different type {0}", value.getClass().getSimpleName()));
}
}