Skip to content
Permalink
Browse files

PostgresToJavaRegexTranslator

  • Loading branch information...
jgaleotti committed Jun 25, 2019
1 parent 55c5770 commit 50939aeb231ac6582b2d3c2d7b216517e126cac4
@@ -0,0 +1,30 @@
package org.evomaster.core.database

class PostgresToJavaRegExTranslator {

/**
* Translates postgres wildcards to their corresponding
* Java regex wildcard. This is, "_" -> ".", "%" -> ".*".
* If a wildcard is escaped with \, it is not replaced.
* For example, "\%" -> "%", "\_" -> "_", "\\" -> "\"
*/
fun translate(postgresPattern: String): String {
val escapeSymbol: String = "\\"
val replacements = mapOf("%" to ".*", "_" to ".")
val builder = StringBuilder()
var i = 0
while (i < postgresPattern.length) {
val currentSymbol = postgresPattern[i].toString()
if (currentSymbol == escapeSymbol && i < postgresPattern.length - 1) {
i++;
builder.append(postgresPattern[i])
} else if (currentSymbol in replacements.keys) {
builder.append(replacements[currentSymbol])
} else {
builder.append(currentSymbol)
}
i++;
}
return builder.toString()
}
}
@@ -3,6 +3,7 @@ package org.evomaster.core.database
import org.evomaster.core.search.gene.Gene
import org.evomaster.core.search.gene.NumberGene
import org.evomaster.dbconstraint.*
import java.util.regex.Pattern

class TableConstraintEvaluator(val previousActions: List<DbAction> = listOf())
: TableConstraintVisitor<Boolean, DbAction> {
@@ -197,15 +198,42 @@ class TableConstraintEvaluator(val previousActions: List<DbAction> = listOf())
override fun visit(constraint: LikeConstraint, dbAction: DbAction): Boolean {
val tableName = constraint.tableName
val columnName = constraint.columnName
val patternValue = constraint.pattern
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
val databaseType = constraint.databaseType
val patternDb = constraint.pattern

return visitPatternConstraint(tableName, columnName, patternDb, databaseType, dbAction)
}

override fun visit(constraint: SimilarToConstraint, dbAction: DbAction): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
private fun visitPatternConstraint(tableName: String, columnName: String, patternDb: String, databaseType: ConstraintDatabaseType, dbAction: DbAction): Boolean {
// if the action is not referred to this action, we conclude
// the action does not invalidate the constraint
if (dbAction.table.name != tableName) {
return true
}


val gene = dbAction.seeGenes().firstOrNull { it.name == columnName } ?: return false
val instance = gene.getValueAsRawString()

val javaRegexPattern = when (databaseType) {
ConstraintDatabaseType.POSTGRES -> PostgresToJavaRegExTranslator().translate(patternDb)
else -> throw UnsupportedOperationException("Must implement java regex translation from %s".format(databaseType))
}
val pattern = Pattern.compile(javaRegexPattern)
val matcher = pattern.matcher(instance)

return matcher.find()
}


override fun visit(constraint: SimilarToConstraint, dbAction: DbAction): Boolean {
val tableName = constraint.tableName
val columnName = constraint.columnName
val databaseType = constraint.databaseType
val patternDb = constraint.pattern

return visitPatternConstraint(tableName, columnName, patternDb, databaseType, dbAction)
}


}
@@ -0,0 +1,43 @@
package org.evomaster.core.database

import org.junit.Assert
import org.junit.jupiter.api.Test

class PostgresToJavaRegExTranslatorTest {

@Test
fun testPostgresToJavaRegex() {
val outcome = PostgresToJavaRegExTranslator().translate("hello world")
Assert.assertEquals("hello world", outcome)
}

@Test
fun testWildcard1() {
val outcome = PostgresToJavaRegExTranslator().translate("%hello%")
Assert.assertEquals(".*hello.*", outcome)
}

@Test
fun testWildcard2() {
val outcome = PostgresToJavaRegExTranslator().translate("_hello_")
Assert.assertEquals(".hello.", outcome)
}

@Test
fun testEscape1() {
val outcome = PostgresToJavaRegExTranslator().translate("\\%hello\\%")
Assert.assertEquals("%hello%", outcome)
}

@Test
fun testEscape2() {
val outcome = PostgresToJavaRegExTranslator().translate("\\_hello\\_")
Assert.assertEquals("_hello_", outcome)
}

@Test
fun testEscape3() {
val outcome = PostgresToJavaRegExTranslator().translate("\\\\")
Assert.assertEquals("\\", outcome)
}
}
@@ -416,4 +416,73 @@ class TableConstraintEvaluatorTest {
assertTrue(constraintValue)
}

@Test
fun testLikeConstraint() {
val column = Column("column0", ColumnDataType.TEXT, databaseType = DatabaseType.POSTGRES)
val table = Table("table0", setOf(column), setOf(), setOf())
val constraint = LikeConstraint("table0", "column0", "%hi_", ConstraintDatabaseType.POSTGRES)

val action = DbAction(table = table, selectedColumns = setOf(column), id = 0L)
(action.seeGenes()[0] as StringGene).copyValueFrom(StringGene("status", value = "hiX"))

val evaluator = TableConstraintEvaluator()
val constraintValue = constraint.accept(evaluator, action)
assertTrue(constraintValue)
}

@Test
fun testLikeConstraintFalse() {
val column = Column("column0", ColumnDataType.TEXT, databaseType = DatabaseType.POSTGRES)
val table = Table("table0", setOf(column), setOf(), setOf())
val constraint = LikeConstraint("table0", "column0", "%hi_", ConstraintDatabaseType.POSTGRES)

val action = DbAction(table = table, selectedColumns = setOf(column), id = 0L)
(action.seeGenes()[0] as StringGene).copyValueFrom(StringGene("status", value = "not matches"))

val evaluator = TableConstraintEvaluator()
val constraintValue = constraint.accept(evaluator, action)
assertFalse(constraintValue)
}

@Test
fun testSimilarToConstraintTrue() {
val column = Column("column0", ColumnDataType.TEXT, databaseType = DatabaseType.POSTGRES)
val table = Table("table0", setOf(column), setOf(), setOf())
val constraint = SimilarToConstraint("table0", "column0", "/foo/__/bar/(left|right)/[0-9]{4}-[0-9]{2}-[0-9]{2}(/[0-9]*)?", ConstraintDatabaseType.POSTGRES)

val action = DbAction(table = table, selectedColumns = setOf(column), id = 0L)
(action.seeGenes()[0] as StringGene).copyValueFrom(StringGene("column0", value = "/foo/XX/bar/left/0000-00-000"))

val evaluator = TableConstraintEvaluator()
val constraintValue = constraint.accept(evaluator, action)
assertTrue(constraintValue)
}

@Test
fun testSimilarToConstraintFalse() {
val column = Column("column0", ColumnDataType.TEXT, databaseType = DatabaseType.POSTGRES)
val table = Table("table0", setOf(column), setOf(), setOf())
val constraint = SimilarToConstraint("table0", "column0", "/foo/__/bar/(left|right)/[0-9]{4}-[0-9]{2}-[0-9]{2}(/[0-9]*)?", ConstraintDatabaseType.POSTGRES)

val action = DbAction(table = table, selectedColumns = setOf(column), id = 0L)
(action.seeGenes()[0] as StringGene).copyValueFrom(StringGene("column0", value = "/foo/XXXX/bar/left/0000-00-000"))

val evaluator = TableConstraintEvaluator()
val constraintValue = constraint.accept(evaluator, action)
assertFalse(constraintValue)
}

@Test
fun testSimilarToConstraintDiffTable() {
val column = Column("column0", ColumnDataType.TEXT, databaseType = DatabaseType.POSTGRES)
val table = Table("table0", setOf(column), setOf(), setOf())
val constraint = SimilarToConstraint("table1", "column0", "/foo/__/bar/(left|right)/[0-9]{4}-[0-9]{2}-[0-9]{2}(/[0-9]*)?", ConstraintDatabaseType.POSTGRES)

val action = DbAction(table = table, selectedColumns = setOf(column), id = 0L)
(action.seeGenes()[0] as StringGene).copyValueFrom(StringGene("column0", value = "/foo/XXXX/bar/left/0000-00-000"))

val evaluator = TableConstraintEvaluator()
val constraintValue = constraint.accept(evaluator, action)
assertTrue(constraintValue)
}
}
@@ -5,12 +5,16 @@
public class SimilarToConstraint extends TableConstraint {

private final /* non-null*/ String columnName;

private final /*non-null*/ String pattern;

public SimilarToConstraint(String tableName, String columnName, String pattern) {
private final /*non-null*/ ConstraintDatabaseType databaseType;

public SimilarToConstraint(String tableName, String columnName, String pattern, ConstraintDatabaseType databaseType) {
super(tableName);
this.columnName = Objects.requireNonNull(columnName);
this.pattern = Objects.requireNonNull(pattern);
this.databaseType = Objects.requireNonNull(databaseType);
}

public String getColumnName() {
@@ -21,6 +25,10 @@ public String getPattern() {
return pattern;
}

public ConstraintDatabaseType getDatabaseType() {
return databaseType;
}

@Override
public <K, V> K accept(TableConstraintVisitor<K, V> visitor, V argument) {
return visitor.visit(this, argument);
@@ -219,7 +219,7 @@ public TableConstraint visit(SqlBinaryDataLiteralValue e, Void argument) {
public TableConstraint visit(SqlSimilarToCondition e, Void argument) {
String tableName = getTableName(e.getColumn());
final String pattern = e.getPattern().getStringValue();
return new SimilarToConstraint(tableName, e.getColumn().getColumnName(), pattern);
return new SimilarToConstraint(tableName, e.getColumn().getColumnName(), pattern, translationContext.getDatabaseType());
}

@Override

0 comments on commit 50939ae

Please sign in to comment.
You can’t perform that action at this time.