diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalAccess.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalAccess.java index 4f8cd83c8..194d0d8c2 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalAccess.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalAccess.java @@ -67,7 +67,6 @@ public class EbeanLocalAccess implements IEbeanLocalAccess private final EbeanLocalRelationshipWriterDAO _localRelationshipWriterDAO; private LocalRelationshipBuilderRegistry _localRelationshipBuilderRegistry; private final SchemaEvolutionManager _schemaEvolutionManager; - private final boolean _nonDollarVirtualColumnsEnabled; // TODO confirm if the default page size is 1000 in other code context. private static final int DEFAULT_PAGE_SIZE = 1000; @@ -86,7 +85,7 @@ public EbeanLocalAccess(EbeanServer server, ServerConfig serverConfig, @Nonnull _entityType = ModelUtils.getEntityTypeFromUrnClass(_urnClass); _localRelationshipWriterDAO = new EbeanLocalRelationshipWriterDAO(_server); _schemaEvolutionManager = createSchemaEvolutionManager(serverConfig); - _nonDollarVirtualColumnsEnabled = nonDollarVirtualColumnsEnabled; + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnsEnabled); } public void setUrnPathExtractor(@Nonnull UrnPathExtractor urnPathExtractor) { @@ -339,7 +338,7 @@ public ListResult list(@Nonnull Class countAggregate(@Nullable IndexFilter indexFilter, @Nonnull IndexGroupByCriterion indexGroupByCriterion) { final String tableName = SQLSchemaUtils.getTableName(_entityType); - final String groupByColumn = getGeneratedColumnName(indexGroupByCriterion.getAspect(), indexGroupByCriterion.getPath(), _nonDollarVirtualColumnsEnabled); + final String groupByColumn = getGeneratedColumnName(indexGroupByCriterion.getAspect(), indexGroupByCriterion.getPath()); // first, check for existence of the column we want to GROUP BY if (!checkColumnExists(tableName, groupByColumn)) { // if we are trying to GROUP BY the results on a column that does not exist, just return an empty map @@ -347,7 +346,7 @@ public Map countAggregate(@Nullable IndexFilter indexFilter, } // now run the actual GROUP BY query - final String groupBySql = SQLStatementUtils.createGroupBySql(tableName, indexFilter, indexGroupByCriterion, _nonDollarVirtualColumnsEnabled); + final String groupBySql = SQLStatementUtils.createGroupBySql(tableName, indexFilter, indexGroupByCriterion); final SqlQuery sqlQuery = _server.createSqlQuery(groupBySql); final List sqlRows = sqlQuery.findList(); Map resultMap = new HashMap<>(); @@ -376,9 +375,9 @@ private SqlQuery createFilterSqlQuery(@Nullable IndexFilter indexFilter, final String tableName = SQLSchemaUtils.getTableName(_entityType); StringBuilder filterSql = new StringBuilder(); - filterSql.append(SQLStatementUtils.createFilterSql(tableName, indexFilter, true, _nonDollarVirtualColumnsEnabled)); + filterSql.append(SQLStatementUtils.createFilterSql(tableName, indexFilter, true)); filterSql.append("\n"); - filterSql.append(parseSortCriteria(indexSortCriterion, _nonDollarVirtualColumnsEnabled)); + filterSql.append(parseSortCriteria(indexSortCriterion)); filterSql.append(String.format(" LIMIT %d", Math.max(pageSize, 0))); filterSql.append(String.format(" OFFSET %d", Math.max(offset, 0))); return _server.createSqlQuery(filterSql.toString()); @@ -391,7 +390,7 @@ private SqlQuery createFilterSqlQuery(@Nullable IndexFilter indexFilter, @Nullable IndexSortCriterion indexSortCriterion, @Nullable URN lastUrn, int pageSize) { StringBuilder filterSql = new StringBuilder(); final String tableName = SQLSchemaUtils.getTableName(_entityType); - filterSql.append(SQLStatementUtils.createFilterSql(tableName, indexFilter, false, _nonDollarVirtualColumnsEnabled)); + filterSql.append(SQLStatementUtils.createFilterSql(tableName, indexFilter, false)); if (lastUrn != null) { // because createFilterSql will only include a WHERE clause if there are non-urn filters, we need to make sure @@ -408,7 +407,7 @@ private SqlQuery createFilterSqlQuery(@Nullable IndexFilter indexFilter, } filterSql.append("\n"); - filterSql.append(parseSortCriteria(indexSortCriterion, _nonDollarVirtualColumnsEnabled)); + filterSql.append(parseSortCriteria(indexSortCriterion)); filterSql.append(String.format(" LIMIT %d", Math.max(pageSize, 0))); return _server.createSqlQuery(filterSql.toString()); } diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalRelationshipQueryDAO.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalRelationshipQueryDAO.java index 832d4f8d6..97da382e7 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalRelationshipQueryDAO.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/EbeanLocalRelationshipQueryDAO.java @@ -34,17 +34,14 @@ public class EbeanLocalRelationshipQueryDAO { private final EbeanServer _server; private final MultiHopsTraversalSqlGenerator _sqlGenerator; - private final EBeanDAOConfig _eBeanDAOConfig; - public EbeanLocalRelationshipQueryDAO(EbeanServer server, EBeanDAOConfig eBeanDAOConfig) { _server = server; - _eBeanDAOConfig = eBeanDAOConfig; + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(eBeanDAOConfig.isNonDollarVirtualColumnsEnabled()); _sqlGenerator = new MultiHopsTraversalSqlGenerator(SUPPORTED_CONDITIONS); } public EbeanLocalRelationshipQueryDAO(EbeanServer server) { _server = server; - _eBeanDAOConfig = new EBeanDAOConfig(); _sqlGenerator = new MultiHopsTraversalSqlGenerator(SUPPORTED_CONDITIONS); } @@ -79,8 +76,7 @@ public List findEntities(@Nonnull Cl final StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.append("SELECT * FROM ").append(tableName); if (filter.hasCriteria() && filter.getCriteria().size() > 0) { - sqlBuilder.append(" WHERE ").append(SQLStatementUtils.whereClause(filter, SUPPORTED_CONDITIONS, null, - _eBeanDAOConfig.isNonDollarVirtualColumnsEnabled())); + sqlBuilder.append(" WHERE ").append(SQLStatementUtils.whereClause(filter, SUPPORTED_CONDITIONS, null)); } sqlBuilder.append(" ORDER BY urn LIMIT ").append(Math.max(1, count)).append(" OFFSET ").append(Math.max(0, offset)); @@ -105,8 +101,7 @@ public (sourceEntityFilter, "st"), new Pair<>(destinationEntityFilter, "dt"), new Pair<>(relationshipFilter, "rt")); diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/MultiHopsTraversalSqlGenerator.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/MultiHopsTraversalSqlGenerator.java index 7b26e9c85..4b62cc73a 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/MultiHopsTraversalSqlGenerator.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/MultiHopsTraversalSqlGenerator.java @@ -27,7 +27,7 @@ public MultiHopsTraversalSqlGenerator(Map supportedConditions @ParametersAreNonnullByDefault public String multiHopTraversalSql(int minHop, int maxHop, int count, int offset, String relationshipTable, String srcEntityTable, String destEntityTable, LocalRelationshipFilter relationshipFilter, LocalRelationshipFilter srcFilter, - LocalRelationshipFilter destFilter, boolean nonDollarVirtualColumnsEnabled) { + LocalRelationshipFilter destFilter) { /* * For now, only one-hop traversal is supported because multi-hops traversal using SQL is expensive @@ -48,13 +48,13 @@ public String multiHopTraversalSql(int minHop, int maxHop, int count, int offset if (relationshipFilter.getDirection() == RelationshipDirection.INCOMING || relationshipFilter.getDirection() == RelationshipDirection.OUTGOING) { String urnSql = firstHopUrnsDirected(relationshipTable, srcEntityTable, destEntityTable, relationshipFilter, srcFilter, - destFilter, relationshipFilter.getDirection(), nonDollarVirtualColumnsEnabled); + destFilter, relationshipFilter.getDirection()); return String.format("SELECT * FROM %s WHERE urn IN (%s) ORDER BY urn LIMIT %d OFFSET %d", entityTable, urnSql, count, offset); } // Relationship is undirected. - String urnSql = firstHopUrnsUndirected(relationshipTable, entityTable, relationshipFilter, srcFilter, nonDollarVirtualColumnsEnabled); - return findEntitiesUndirected(entityTable, relationshipTable, urnSql, destFilter, nonDollarVirtualColumnsEnabled); + String urnSql = firstHopUrnsUndirected(relationshipTable, entityTable, relationshipFilter, srcFilter); + return findEntitiesUndirected(entityTable, relationshipTable, urnSql, destFilter); } /** @@ -64,8 +64,7 @@ public String multiHopTraversalSql(int minHop, int maxHop, int count, int offset @Nonnull @ParametersAreNonnullByDefault private String firstHopUrnsDirected(String relationshipTable, String srcEntityTable, String destEntityTable, - LocalRelationshipFilter relationshipFilter, LocalRelationshipFilter srcFilter, LocalRelationshipFilter destFilter, RelationshipDirection direction, - boolean nonDollarVirtualColumnsEnabled) { + LocalRelationshipFilter relationshipFilter, LocalRelationshipFilter srcFilter, LocalRelationshipFilter destFilter, RelationshipDirection direction) { String urnColumn = "destination"; if (direction == RelationshipDirection.INCOMING) { @@ -76,7 +75,7 @@ private String firstHopUrnsDirected(String relationshipTable, String srcEntityTa String.format("SELECT rt.%s FROM %s rt INNER JOIN %s dt ON rt.destination=dt.urn INNER JOIN %s st ON rt.source=st.urn WHERE rt.deleted_ts IS NULL", urnColumn, relationshipTable, destEntityTable, srcEntityTable)); - String whereClause = SQLStatementUtils.whereClause(_supportedConditions, nonDollarVirtualColumnsEnabled, + String whereClause = SQLStatementUtils.whereClause(_supportedConditions, new Pair<>(relationshipFilter, "rt"), new Pair<>(destFilter, "dt"), new Pair<>(srcFilter, "st")); @@ -94,7 +93,7 @@ private String firstHopUrnsDirected(String relationshipTable, String srcEntityTa @Nonnull @ParametersAreNonnullByDefault private String firstHopUrnsUndirected(String relationshipTable, String entityTable, LocalRelationshipFilter relationshipFilter, - LocalRelationshipFilter srcFilter, boolean nonDollarVirtualColumnsEnabled) { + LocalRelationshipFilter srcFilter) { StringBuilder sourceUrnsSql = new StringBuilder( String.format("SELECT rt.source FROM %s rt INNER JOIN %s et ON rt.source=et.urn WHERE rt.deleted_ts IS NULL", @@ -104,7 +103,7 @@ private String firstHopUrnsUndirected(String relationshipTable, String entityTab String.format("SELECT rt.destination FROM %s rt INNER JOIN %s et ON rt.destination=et.urn WHERE rt.deleted_ts IS NULL", relationshipTable, entityTable)); - String whereClause = SQLStatementUtils.whereClause(_supportedConditions, nonDollarVirtualColumnsEnabled, + String whereClause = SQLStatementUtils.whereClause(_supportedConditions, new Pair<>(relationshipFilter, "rt"), new Pair<>(srcFilter, "et")); @@ -121,9 +120,8 @@ private String firstHopUrnsUndirected(String relationshipTable, String entityTab */ @Nonnull @ParametersAreNonnullByDefault - private String findEntitiesUndirected(String entityTable, String relationshipTable, String firstHopUrnSql, LocalRelationshipFilter destFilter, - boolean nonDollarVirtualColumnsEnabled) { - String whereClause = SQLStatementUtils.whereClause(_supportedConditions, nonDollarVirtualColumnsEnabled, new Pair<>(destFilter, "et")); + private String findEntitiesUndirected(String entityTable, String relationshipTable, String firstHopUrnSql, LocalRelationshipFilter destFilter) { + String whereClause = SQLStatementUtils.whereClause(_supportedConditions, new Pair<>(destFilter, "et")); StringBuilder sourceEntitySql = new StringBuilder( String.format("SELECT et.* FROM %s et INNER JOIN %s rt ON et.urn=rt.source WHERE rt.destination IN (%s)", diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtils.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtils.java index 7dc864783..b525464a5 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtils.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtils.java @@ -66,17 +66,15 @@ private static String parseIndexValue(@Nullable IndexValue indexValue) { /** * Parse {@link IndexSortCriterion} into SQL syntax. * @param indexSortCriterion filter sorting criterion - * @param nonDollarVirtualColumnsEnabled true if virtual column does not contain $, false otherwise * @return SQL statement of sorting, e.g. ORDER BY ... DESC ..etc. */ - public static String parseSortCriteria(@Nullable IndexSortCriterion indexSortCriterion, boolean nonDollarVirtualColumnsEnabled) { + public static String parseSortCriteria(@Nullable IndexSortCriterion indexSortCriterion) { if (indexSortCriterion == null) { // Default to order by urn if user does not provide sort criterion. return "ORDER BY URN"; } final String indexColumn = - SQLSchemaUtils.getGeneratedColumnName(indexSortCriterion.getAspect(), indexSortCriterion.getPath(), - nonDollarVirtualColumnsEnabled); + SQLSchemaUtils.getGeneratedColumnName(indexSortCriterion.getAspect(), indexSortCriterion.getPath()); if (!indexSortCriterion.hasOrder()) { return "ORDER BY " + indexColumn; @@ -89,10 +87,9 @@ public static String parseSortCriteria(@Nullable IndexSortCriterion indexSortCri * Parse {@link IndexFilter} into MySQL syntax. * * @param indexFilter index filter - * @param nonDollarVirtualColumnsEnabled whether to enable non-dollar virtual columns * @return translated SQL condition expression, e.g. WHERE ... */ - public static String parseIndexFilter(@Nullable IndexFilter indexFilter, boolean nonDollarVirtualColumnsEnabled) { + public static String parseIndexFilter(@Nullable IndexFilter indexFilter) { List sqlFilters = new ArrayList<>(); if (indexFilter == null || !indexFilter.hasCriteria()) { @@ -112,7 +109,7 @@ public static String parseIndexFilter(@Nullable IndexFilter indexFilter, boolean if (pathParams != null) { validateConditionAndValue(indexCriterion); final Condition condition = pathParams.getCondition(); - final String indexColumn = getGeneratedColumnName(aspect, pathParams.getPath(), nonDollarVirtualColumnsEnabled); + final String indexColumn = getGeneratedColumnName(aspect, pathParams.getPath()); sqlFilters.add(parseSqlFilter(indexColumn, condition, pathParams.getValue())); } } diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLSchemaUtils.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLSchemaUtils.java index 8db56ad42..8c86d1cf7 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLSchemaUtils.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLSchemaUtils.java @@ -8,6 +8,8 @@ import com.linkedin.metadata.dao.exception.MissingAnnotationException; import java.util.Map; import javax.annotation.Nonnull; +import lombok.Getter; +import lombok.Setter; /** @@ -23,6 +25,10 @@ public class SQLSchemaUtils { private static final int MYSQL_MAX_COLUMN_NAME_LENGTH = 64 - ASPECT_PREFIX.length(); + @Getter + @Setter + private static boolean nonDollarVirtualColumnsEnabled = false; // default value + private SQLSchemaUtils() { } @@ -88,13 +94,13 @@ public static String getAspectColumnName(@Nonnul * Get generated column name from aspect and path. */ @Nonnull - public static String getGeneratedColumnName(@Nonnull String aspect, @Nonnull String path, boolean nonDollarVirtualColumnsEnabled) { + public static String getGeneratedColumnName(@Nonnull String aspect, @Nonnull String path) { char delimiter = nonDollarVirtualColumnsEnabled ? '0' : '$'; if (isUrn(aspect)) { - return INDEX_PREFIX + "urn" + processPath(path, delimiter); + return INDEX_PREFIX + "urn" + processPath(path); } - return INDEX_PREFIX + getColumnNameFromAnnotation(aspect) + processPath(path, delimiter); + return INDEX_PREFIX + getColumnNameFromAnnotation(aspect) + processPath(path); } /** @@ -107,11 +113,11 @@ public static boolean isUrn(@Nonnull String className) { /** * process 'path' into mysql column name convention. * @param path path in string e.g. /name/value, /name - * @param delimiter delimiter i.e '$' or '0' * @return $name$value or $name or 0name$value or 0name */ @Nonnull - public static String processPath(@Nonnull String path, char delimiter) { + public static String processPath(@Nonnull String path) { + char delimiter = nonDollarVirtualColumnsEnabled ? '0' : '$'; path = path.replace("/", String.valueOf(delimiter)); if (!path.startsWith(String.valueOf(delimiter))) { path = delimiter + path; diff --git a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLStatementUtils.java b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLStatementUtils.java index a55a1f1e1..d7ac3412e 100644 --- a/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLStatementUtils.java +++ b/dao-impl/ebean-dao/src/main/java/com/linkedin/metadata/dao/utils/SQLStatementUtils.java @@ -234,11 +234,10 @@ public static String createAspectUpdateWithOptim * @param tableName table name * @param indexFilter index filter * @param hasTotalCount whether to calculate total count in SQL. - * @param nonDollarVirtualColumnsEnabled true if virtual column does not contain $, false otherwise * @return translated SQL where statement */ - public static String createFilterSql(String tableName, @Nullable IndexFilter indexFilter, boolean hasTotalCount, boolean nonDollarVirtualColumnsEnabled) { - String whereClause = parseIndexFilter(indexFilter, nonDollarVirtualColumnsEnabled); + public static String createFilterSql(String tableName, @Nullable IndexFilter indexFilter, boolean hasTotalCount) { + String whereClause = parseIndexFilter(indexFilter); String totalCountSql = String.format("SELECT COUNT(urn) FROM %s %s", tableName, whereClause); StringBuilder sb = new StringBuilder(); @@ -258,16 +257,16 @@ public static String createFilterSql(String tableName, @Nullable IndexFilter ind * @param tableName table name * @param indexFilter index filter * @param indexGroupByCriterion group by - * @param nonDollarVirtualColumnsEnabled true if virtual column does not contain $, false otherwise * @return translated group by SQL */ public static String createGroupBySql(String tableName, @Nullable IndexFilter indexFilter, - @Nonnull IndexGroupByCriterion indexGroupByCriterion, boolean nonDollarVirtualColumnsEnabled) { - final String columnName = getGeneratedColumnName(indexGroupByCriterion.getAspect(), indexGroupByCriterion.getPath(), nonDollarVirtualColumnsEnabled); + @Nonnull IndexGroupByCriterion indexGroupByCriterion) { + final String columnName = + getGeneratedColumnName(indexGroupByCriterion.getAspect(), indexGroupByCriterion.getPath()); StringBuilder sb = new StringBuilder(); sb.append(String.format(INDEX_GROUP_BY_CRITERION, columnName, tableName)); sb.append("\n"); - sb.append(parseIndexFilter(indexFilter, nonDollarVirtualColumnsEnabled)); + sb.append(parseIndexFilter(indexFilter)); sb.append("\nGROUP BY "); sb.append(columnName); return sb.toString(); @@ -327,18 +326,17 @@ public static String deleteLocaRelationshipSQL(final String tableName, final Bas /** * Construct where clause SQL from multiple filters. Return null if all filters are empty. * @param supportedCondition contains supported conditions such as EQUAL. - * @param nonDollarVirtualColumnsEnabled true if virtual column does not contain $, false otherwise * @param filters An array of pairs which are filter and table prefix. * @return sql that can be appended after where clause. */ @SafeVarargs @Nullable - public static String whereClause(@Nonnull Map supportedCondition, boolean nonDollarVirtualColumnsEnabled, + public static String whereClause(@Nonnull Map supportedCondition, @Nonnull Pair... filters) { List andClauses = new ArrayList<>(); for (Pair filter : filters) { if (filter.getValue0().hasCriteria() && filter.getValue0().getCriteria().size() > 0) { - andClauses.add("(" + whereClause(filter.getValue0(), supportedCondition, filter.getValue1(), nonDollarVirtualColumnsEnabled) + ")"); + andClauses.add("(" + whereClause(filter.getValue0(), supportedCondition, filter.getValue1()) + ")"); } } if (andClauses.isEmpty()) { @@ -355,13 +353,11 @@ public static String whereClause(@Nonnull Map supportedCondit * @param filter contains field, condition and value * @param supportedCondition contains supported conditions such as EQUAL. * @param tablePrefix Table prefix append to the field name. Useful during SQL joining across multiple tables. - * @param nonDollarVirtualColumnsEnabled whether to use dollar sign in virtual column names. * @return sql that can be appended after where clause. */ @Nonnull public static String whereClause(@Nonnull LocalRelationshipFilter filter, - @Nonnull Map supportedCondition, @Nullable String tablePrefix, - boolean nonDollarVirtualColumnsEnabled) { + @Nonnull Map supportedCondition, @Nullable String tablePrefix) { if (!filter.hasCriteria() || filter.getCriteria().size() == 0) { throw new IllegalArgumentException("Empty filter cannot construct where clause."); } @@ -369,7 +365,7 @@ public static String whereClause(@Nonnull LocalRelationshipFilter filter, // Group the conditions by field. Map>> groupByField = new HashMap<>(); filter.getCriteria().forEach(criterion -> { - String field = parseLocalRelationshipField(criterion, tablePrefix, nonDollarVirtualColumnsEnabled); + String field = parseLocalRelationshipField(criterion, tablePrefix); List> group = groupByField.getOrDefault(field, new ArrayList<>()); group.add(new Pair<>(criterion.getCondition(), criterion.getValue())); groupByField.put(field, group); @@ -383,7 +379,7 @@ public static String whereClause(@Nonnull LocalRelationshipFilter filter, if (!pair.getValue1().isArray()) { throw new IllegalArgumentException("IN condition must be paired with array value"); } - orClauses.add(entry.getKey() + " IN " + parseLocalRelationshipValue(pair.getValue1())); + orClauses.add(entry.getKey() + " IN " + parseLocalRelationshipValue(pair.getValue1())); } else { orClauses.add(entry.getKey() + supportedCondition.get(pair.getValue0()) + "'" + parseLocalRelationshipValue(pair.getValue1()) + "'"); } @@ -407,23 +403,21 @@ public static String whereClause(@Nonnull LocalRelationshipFilter filter, } private static String parseLocalRelationshipField( - @Nonnull final LocalRelationshipCriterion localRelationshipCriterion, @Nullable String tablePrefix, - boolean nonDollarVirtualColumnsEnabled) { + @Nonnull final LocalRelationshipCriterion localRelationshipCriterion, @Nullable String tablePrefix) { tablePrefix = tablePrefix == null ? "" : tablePrefix + "."; LocalRelationshipCriterion.Field field = localRelationshipCriterion.getField(); - char delimiter = nonDollarVirtualColumnsEnabled ? '0' : '$'; - if (field.isUrnField()) { return tablePrefix + field.getUrnField().getName(); } if (field.isRelationshipField()) { - return tablePrefix + field.getRelationshipField().getName() + SQLSchemaUtils.processPath(field.getRelationshipField().getPath(), delimiter); + return tablePrefix + field.getRelationshipField().getName() + SQLSchemaUtils.processPath( + field.getRelationshipField().getPath()); } if (field.isAspectField()) { return tablePrefix + SQLSchemaUtils.getGeneratedColumnName(field.getAspectField().getAspect(), - field.getAspectField().getPath(), nonDollarVirtualColumnsEnabled); + field.getAspectField().getPath()); } throw new IllegalArgumentException("Unrecognized field type"); diff --git a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/EbeanLocalDAOTest.java b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/EbeanLocalDAOTest.java index c795f3c89..7b292b967 100644 --- a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/EbeanLocalDAOTest.java +++ b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/EbeanLocalDAOTest.java @@ -142,6 +142,7 @@ public class EbeanLocalDAOTest { public EbeanLocalDAOTest(SchemaConfig schemaConfig, FindMethodology findMethodology, boolean enableChangeLog, boolean nonDollarVirtualColumnEnabled) { _eBeanDAOConfig.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnEnabled); + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnEnabled); _schemaConfig = schemaConfig; _findMethodology = findMethodology; _enableChangeLog = enableChangeLog; @@ -3070,8 +3071,7 @@ private void addIndex(Urn urn, String aspectName, String pathName, Object val) { */ String aspectColumnName = isUrn(aspectName) ? null : SQLSchemaUtils.getAspectColumnName(aspectName); // e.g. a_aspectfoo; - String fullIndexColumnName = SQLSchemaUtils.getGeneratedColumnName(aspectName, pathName, - _eBeanDAOConfig.isNonDollarVirtualColumnsEnabled()); // e.g. i_aspectfoo$path1$value1 + String fullIndexColumnName = SQLSchemaUtils.getGeneratedColumnName(aspectName, pathName); // e.g. i_aspectfoo$path1$value1 String checkColumnExistance = String.format("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '%s' AND" + " TABLE_NAME = '%s' AND COLUMN_NAME = '%s'", _server.getName(), getTableName(urn), fullIndexColumnName); diff --git a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtilsTest.java b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtilsTest.java index 6db7a6d44..dd749ea30 100644 --- a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtilsTest.java +++ b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLIndexFilterUtilsTest.java @@ -8,6 +8,8 @@ import com.linkedin.metadata.query.IndexValue; import com.linkedin.metadata.query.SortOrder; import com.linkedin.testing.AspectFoo; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; import org.testng.annotations.Test; import static org.testng.Assert.*; @@ -15,6 +17,19 @@ public class SQLIndexFilterUtilsTest { + @Factory(dataProvider = "inputList") + public SQLIndexFilterUtilsTest(boolean nonDollarVirtualColumnsEnabled) { + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnsEnabled); + } + + @DataProvider(name = "inputList") + public static Object[][] inputList() { + return new Object[][] { + { true }, + { false } + }; + } + @Test public void testParseSortCriteria() { IndexSortCriterion indexSortCriterion = @@ -22,18 +37,20 @@ public void testParseSortCriteria() { assertEquals(indexSortCriterion.getOrder(), SortOrder.ASCENDING); assertEquals(indexSortCriterion.getAspect(), AspectFoo.class.getCanonicalName()); - String sql1 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion, false); - assertEquals(sql1, "ORDER BY i_aspectfoo$id ASC"); - - String sql2 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion, true); - assertEquals(sql2, "ORDER BY i_aspectfoo0id ASC"); + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + String sql1 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion); + assertEquals(sql1, "ORDER BY i_aspectfoo$id ASC"); - indexSortCriterion.setOrder(SortOrder.DESCENDING); - sql1 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion, false); - assertEquals(sql1, "ORDER BY i_aspectfoo$id DESC"); + indexSortCriterion.setOrder(SortOrder.DESCENDING); + sql1 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion); + assertEquals(sql1, "ORDER BY i_aspectfoo$id DESC"); + } else { + String sql2 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion); + assertEquals(sql2, "ORDER BY i_aspectfoo0id ASC"); - sql2 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion, true); - assertEquals(sql2, "ORDER BY i_aspectfoo0id DESC"); + sql2 = SQLIndexFilterUtils.parseSortCriteria(indexSortCriterion); + assertEquals(sql2, "ORDER BY i_aspectfoo0id DESC"); + } } @Test @@ -45,10 +62,14 @@ public void testParseIndexFilter() { indexCriterionArray.add(indexCriterion); indexFilter.setCriteria(indexCriterionArray); - String sql = SQLIndexFilterUtils.parseIndexFilter(indexFilter, false); - assertEquals(sql, "WHERE a_aspectfoo IS NOT NULL\nAND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\nAND i_aspectfoo$id < 12"); - - sql = SQLIndexFilterUtils.parseIndexFilter(indexFilter, true); - assertEquals(sql, "WHERE a_aspectfoo IS NOT NULL\nAND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\nAND i_aspectfoo0id < 12"); + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + String sql1 = SQLIndexFilterUtils.parseIndexFilter(indexFilter); + assertEquals(sql1, + "WHERE a_aspectfoo IS NOT NULL\nAND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\nAND i_aspectfoo$id < 12"); + } else { + String sql2 = SQLIndexFilterUtils.parseIndexFilter(indexFilter); + assertEquals(sql2, + "WHERE a_aspectfoo IS NOT NULL\nAND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\nAND i_aspectfoo0id < 12"); + } } } \ No newline at end of file diff --git a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLSchemaUtilsTest.java b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLSchemaUtilsTest.java index b874303b6..f902b58b2 100644 --- a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLSchemaUtilsTest.java +++ b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLSchemaUtilsTest.java @@ -1,6 +1,8 @@ package com.linkedin.metadata.dao.utils; import com.linkedin.testing.AspectFoo; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; import org.testng.annotations.Test; import static com.linkedin.metadata.dao.utils.SQLSchemaUtils.*; @@ -9,13 +11,27 @@ public class SQLSchemaUtilsTest { + @Factory(dataProvider = "inputList") + public SQLSchemaUtilsTest(boolean nonDollarVirtualColumnsEnabled) { + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnsEnabled); + } + + @DataProvider(name = "inputList") + public static Object[][] inputList() { + return new Object[][] { + { true }, + { false } + }; + } + @Test public void testGetGeneratedColumnName() { - String generatedColumnName = getGeneratedColumnName(AspectFoo.class.getCanonicalName(), "/value", false); - assertEquals(generatedColumnName, "i_aspectfoo$value"); - - generatedColumnName = getGeneratedColumnName(AspectFoo.class.getCanonicalName(), "/value", true); - assertEquals(generatedColumnName, "i_aspectfoo0value"); + String generatedColumnName = getGeneratedColumnName(AspectFoo.class.getCanonicalName(), "/value"); + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + assertEquals(generatedColumnName, "i_aspectfoo$value"); + } else { + assertEquals(generatedColumnName, "i_aspectfoo0value"); + } } @Test diff --git a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLStatementUtilsTest.java b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLStatementUtilsTest.java index 5ae2c453e..a7afe7305 100644 --- a/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLStatementUtilsTest.java +++ b/dao-impl/ebean-dao/src/test/java/com/linkedin/metadata/dao/utils/SQLStatementUtilsTest.java @@ -24,6 +24,8 @@ import java.util.List; import java.util.Set; import org.javatuples.Pair; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; import org.testng.annotations.Test; import static com.linkedin.testing.TestUtils.*; @@ -31,21 +33,34 @@ public class SQLStatementUtilsTest { + @Factory(dataProvider = "inputList") + public SQLStatementUtilsTest(boolean nonDollarVirtualColumnsEnabled) { + SQLSchemaUtils.setNonDollarVirtualColumnsEnabled(nonDollarVirtualColumnsEnabled); + } + @DataProvider(name = "inputList") + public static Object[][] inputList() { + return new Object[][] { + { true }, + { false } + }; + } @Test public void testCreateUpsertAspectSql() { FooUrn fooUrn = makeFooUrn(1); - String expectedSql = - "INSERT INTO metadata_entity_foo (urn, a_urn, a_aspectfoo, lastmodifiedon, lastmodifiedby) VALUE (:urn, " - + ":a_urn, :metadata, :lastmodifiedon, :lastmodifiedby) ON DUPLICATE KEY UPDATE a_aspectfoo = :metadata," - + " lastmodifiedon = :lastmodifiedon;"; + String expectedSql; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectedSql = + "INSERT INTO metadata_entity_foo (urn, a_urn, a_aspectfoo, lastmodifiedon, lastmodifiedby) VALUE (:urn, " + + ":a_urn, :metadata, :lastmodifiedon, :lastmodifiedby) ON DUPLICATE KEY UPDATE a_aspectfoo = :metadata," + + " lastmodifiedon = :lastmodifiedon;"; + + } else { + expectedSql = "INSERT INTO metadata_entity_foo (urn, a_aspectfoo, lastmodifiedon, lastmodifiedby) VALUE (:urn, " + + ":metadata, :lastmodifiedon, :lastmodifiedby) ON DUPLICATE KEY UPDATE a_aspectfoo = :metadata," + + " lastmodifiedon = :lastmodifiedon;"; + } assertEquals(SQLStatementUtils.createAspectUpsertSql(fooUrn, AspectFoo.class, true), expectedSql); - - expectedSql = - "INSERT INTO metadata_entity_foo (urn, a_aspectfoo, lastmodifiedon, lastmodifiedby) VALUE (:urn, " - + ":metadata, :lastmodifiedon, :lastmodifiedby) ON DUPLICATE KEY UPDATE a_aspectfoo = :metadata," - + " lastmodifiedon = :lastmodifiedon;"; - assertEquals(SQLStatementUtils.createAspectUpsertSql(fooUrn, AspectFoo.class, false), expectedSql); } @Test @@ -78,27 +93,26 @@ public void testCreateFilterSql() { indexCriterionArray.add(indexCriterion2); indexFilter.setCriteria(indexCriterionArray); - String sql1 = SQLStatementUtils.createFilterSql("metadata_entity_foo", indexFilter, true, false); - String expectedSql1 = "SELECT *, (SELECT COUNT(urn) FROM metadata_entity_foo WHERE a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value >= 25\n" - + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo$value < 50) as _total_count FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value >= 25\n" - + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo$value < 50"; - - assertEquals(sql1, expectedSql1); - - String sql2 = SQLStatementUtils.createFilterSql("metadata_entity_foo", indexFilter, true, true); - String expectedSql2 = "SELECT *, (SELECT COUNT(urn) FROM metadata_entity_foo WHERE a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value >= 25\n" - + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo0value < 50) as _total_count FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value >= 25\n" - + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo0value < 50"; - - assertEquals(sql2, expectedSql2); + String sql = SQLStatementUtils.createFilterSql("metadata_entity_foo", indexFilter, true); + String expectedSql; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectedSql = "SELECT *, (SELECT COUNT(urn) FROM metadata_entity_foo WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo$value < 50) as _total_count FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo$value < 50"; + } else { + expectedSql = "SELECT *, (SELECT COUNT(urn) FROM metadata_entity_foo WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo0value < 50) as _total_count FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo0value < 50"; + } + assertEquals(sql, expectedSql); } @Test @@ -119,20 +133,22 @@ public void testCreateGroupBySql() { IndexGroupByCriterion indexGroupByCriterion = new IndexGroupByCriterion(); indexGroupByCriterion.setAspect(AspectFoo.class.getCanonicalName()); indexGroupByCriterion.setPath("/value"); - - String sql1 = SQLStatementUtils.createGroupBySql("metadata_entity_foo", indexFilter, indexGroupByCriterion, false); - assertEquals(sql1, "SELECT count(*) as COUNT, i_aspectfoo$value FROM metadata_entity_foo\n" - + "WHERE a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo$value >= 25\n" + "AND a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value < 50\n" - + "GROUP BY i_aspectfoo$value"); - - String sql2 = SQLStatementUtils.createGroupBySql("metadata_entity_foo", indexFilter, indexGroupByCriterion, true); - assertEquals(sql2, "SELECT count(*) as COUNT, i_aspectfoo0value FROM metadata_entity_foo\n" - + "WHERE a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" - + "AND i_aspectfoo0value >= 25\n" + "AND a_aspectfoo IS NOT NULL\n" - + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value < 50\n" - + "GROUP BY i_aspectfoo0value"); + String sql = SQLStatementUtils.createGroupBySql("metadata_entity_foo", indexFilter, indexGroupByCriterion); + String expectSQL; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectSQL = + "SELECT count(*) as COUNT, i_aspectfoo$value FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo$value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo$value < 50\n" + "GROUP BY i_aspectfoo$value"; + } else { + expectSQL = + "SELECT count(*) as COUNT, i_aspectfoo0value FROM metadata_entity_foo\n" + "WHERE a_aspectfoo IS NOT NULL\n" + + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + "AND i_aspectfoo0value >= 25\n" + + "AND a_aspectfoo IS NOT NULL\n" + "AND JSON_EXTRACT(a_aspectfoo, '$.gma_deleted') IS NULL\n" + + "AND i_aspectfoo0value < 50\n" + "GROUP BY i_aspectfoo0value"; + } + assertEquals(sql, expectSQL); } @Test @@ -145,8 +161,7 @@ public void testWhereClauseSingleCondition() { .setValue(LocalRelationshipValue.create("value1")); LocalRelationshipCriterionArray criteria = new LocalRelationshipCriterionArray(criterion); LocalRelationshipFilter filter = new LocalRelationshipFilter().setCriteria(criteria); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, false), "urn='value1'"); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, true), "urn='value1'"); + assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null), "urn='value1'"); } @Test @@ -167,8 +182,7 @@ public void testWhereClauseMultiConditionSameName() { LocalRelationshipCriterionArray criteria = new LocalRelationshipCriterionArray(criterion1, criterion2); LocalRelationshipFilter filter = new LocalRelationshipFilter().setCriteria(criteria); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, false), "urn='value1' OR urn='value2'"); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, true), "urn='value1' OR urn='value2'"); + assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null), "urn='value1' OR urn='value2'"); } @Test @@ -189,10 +203,14 @@ public void testWhereClauseMultiConditionDifferentName() { LocalRelationshipCriterionArray criteria = new LocalRelationshipCriterionArray(criterion1, criterion2); LocalRelationshipFilter filter = new LocalRelationshipFilter().setCriteria(criteria); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, false), - "urn='value1' AND i_aspectfoo$value='value2'"); - assertEquals(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, true), - "urn='value1' AND i_aspectfoo0value='value2'"); + String sql = SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null); + String expectedSQL; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectedSQL = "urn='value1' AND i_aspectfoo$value='value2'"; + } else { + expectedSQL = "urn='value1' AND i_aspectfoo0value='value2'"; + } + assertEquals(sql, expectedSQL); } @Test @@ -227,10 +245,14 @@ public void testWhereClauseMultiConditionMixedName() { LocalRelationshipCriterionArray criteria = new LocalRelationshipCriterionArray(criterion1, criterion2, criterion3, criterion4); LocalRelationshipFilter filter = new LocalRelationshipFilter().setCriteria(criteria); - assertConditionsEqual(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, false), - "(urn='value1' OR urn='value3') AND metadata$value='value4' AND i_aspectfoo$value='value2'"); - assertConditionsEqual(SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null, true), - "(urn='value1' OR urn='value3') AND metadata0value='value4' AND i_aspectfoo0value='value2'"); + String sql = SQLStatementUtils.whereClause(filter, Collections.singletonMap(Condition.EQUAL, "="), null); + String expectedSQL; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectedSQL = "(urn='value1' OR urn='value3') AND metadata$value='value4' AND i_aspectfoo$value='value2'"; + } else { + expectedSQL = "(urn='value1' OR urn='value3') AND metadata0value='value4' AND i_aspectfoo0value='value2'"; + } + assertConditionsEqual(sql, expectedSQL); } @Test @@ -282,18 +304,18 @@ public void testWhereClauseMultiFilters() { LocalRelationshipCriterionArray criteria2 = new LocalRelationshipCriterionArray(criterion5, criterion6); LocalRelationshipFilter filter2 = new LocalRelationshipFilter().setCriteria(criteria2); - //test for multi filters with dollar virtual columns names - assertConditionsEqual(SQLStatementUtils.whereClause(Collections.singletonMap(Condition.EQUAL, "="), false, new Pair<>(filter1, "foo"), - new Pair<>(filter2, "bar")), "(foo.i_aspectfoo$value='value2' AND (foo.urn='value1' OR foo.urn='value3') " - + "AND foo.metadata$value='value4') AND (bar.urn='value1' OR bar.urn='value2')" - ); - - //test for multi filters with non dollar virtual columns names - assertConditionsEqual(SQLStatementUtils.whereClause(Collections.singletonMap(Condition.EQUAL, "="), true, new Pair<>(filter1, "foo"), - new Pair<>(filter2, "bar")), "(foo.i_aspectfoo0value='value2' AND (foo.urn='value1' OR foo.urn='value3') " - + "AND foo.metadata0value='value4') AND (bar.urn='value1' OR bar.urn='value2')" - ); + String sql = SQLStatementUtils.whereClause(Collections.singletonMap(Condition.EQUAL, "="), new Pair<>(filter1, "foo"), + new Pair<>(filter2, "bar")); + String expectedSQL; + if (!SQLSchemaUtils.isNonDollarVirtualColumnsEnabled()) { + expectedSQL = "(foo.i_aspectfoo$value='value2' AND (foo.urn='value1' OR foo.urn='value3') " + + "AND foo.metadata$value='value4') AND (bar.urn='value1' OR bar.urn='value2')"; + } else { + expectedSQL = "(foo.i_aspectfoo0value='value2' AND (foo.urn='value1' OR foo.urn='value3') " + + "AND foo.metadata0value='value4') AND (bar.urn='value1' OR bar.urn='value2')"; + } + assertConditionsEqual(sql, expectedSQL); } private void assertConditionsEqual(String actualWhereClause, String expectedWhereClause) { @@ -303,7 +325,8 @@ private void assertConditionsEqual(String actualWhereClause, String expectedWher } private List splitAndSortConditions(String whereClause) { - List conditions = new ArrayList<>(Arrays.asList(whereClause.replace("(", "").replace(")", "").split(" AND "))); + List conditions = + new ArrayList<>(Arrays.asList(whereClause.replace("(", "").replace(")", "").split(" AND "))); Collections.sort(conditions); return conditions; }