@@ -14,6 +14,7 @@ import org.evomaster.core.logging.LoggingUtil
1414import org.evomaster.core.utils.StringUtils
1515import org.evomaster.dbconstraint.ConstraintDatabaseType
1616import org.evomaster.dbconstraint.ast.SqlCondition
17+ import net.sf.jsqlparser.JSQLParserException
1718import org.evomaster.dbconstraint.parser.SqlConditionParserException
1819import org.evomaster.dbconstraint.parser.jsql.JSqlConditionParser
1920import org.evomaster.solver.smtlib.*
@@ -114,7 +115,9 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
114115 smt.addNode(constraint)
115116 }
116117 } catch (e: SqlConditionParserException ) {
117- throw RuntimeException (" Error parsing check expression: " + check.sqlCheckExpression, e)
118+ LoggingUtil .getInfoLogger().warn(" Could not translate CHECK constraint to SMT-LIB, skipping: ${check.sqlCheckExpression} . Reason: ${e.message} " )
119+ } catch (e: JSQLParserException ) {
120+ LoggingUtil .getInfoLogger().warn(" Could not translate CHECK constraint to SMT-LIB, skipping: ${check.sqlCheckExpression} . Reason: ${e.message} " )
118121 }
119122 }
120123 }
@@ -276,7 +279,7 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
276279 for (foreignKey in table.foreignKeys) {
277280 val referencedTable = findReferencedTable(foreignKey)
278281 val referencedTableName = referencedTable.id.name.lowercase()
279- val referencedColumnSelector = findReferencedPKSelector(referencedTable, foreignKey)
282+ val referencedColumnSelector = findReferencedPKSelector(table, referencedTable, foreignKey)
280283
281284 for (sourceColumn in foreignKey.sourceColumns) {
282285 val nodes = assertForEqualsAny(
@@ -328,13 +331,24 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
328331 * @param foreignKey The foreign key constraint.
329332 * @return The primary key column name in the referenced table.
330333 */
331- private fun findReferencedPKSelector (referencedTable : TableDto , foreignKey : ForeignKeyDto ): String {
334+ private fun findReferencedPKSelector (sourceTable : TableDto , referencedTable : TableDto , foreignKey : ForeignKeyDto ): String {
332335 val referencedPrimaryKeys = referencedTable.columns.filter { it.primaryKey }
333- if (referencedPrimaryKeys.isEmpty()) {
334- throw RuntimeException (" Referenced table has no primary key: ${foreignKey.targetTable} " )
336+ val sourceColumnName = foreignKey.sourceColumns.firstOrNull()
337+ val sourceSmtType = sourceColumnName?.let { scn ->
338+ sourceTable.columns.firstOrNull { it.name.equals(scn, ignoreCase = true ) }
339+ ?.let { TYPE_MAP [it.type.uppercase()] }
335340 }
336- // Assuming single-column primary keys
337- return referencedPrimaryKeys[0 ].name
341+ if (referencedPrimaryKeys.isNotEmpty() &&
342+ (sourceSmtType == null || TYPE_MAP [referencedPrimaryKeys[0 ].type.uppercase()] == sourceSmtType)) {
343+ return referencedPrimaryKeys[0 ].name
344+ }
345+ // No PK or type mismatch: find a type-compatible column
346+ if (sourceSmtType != null ) {
347+ referencedTable.columns.firstOrNull { TYPE_MAP [it.type.uppercase()] == sourceSmtType }
348+ ?.let { return it.name }
349+ }
350+ return referencedTable.columns.firstOrNull()?.name
351+ ? : throw RuntimeException (" Referenced table has no columns: ${foreignKey.targetTable} " )
338352 }
339353
340354 /* *
@@ -364,11 +378,15 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
364378 val where = plainSelect.where
365379
366380 if (where != null ) {
367- val condition = parser.parse(where.toString(), toDBType(schema.databaseType))
368- val tableFromQuery = TablesNamesFinder ().getTables(sqlQuery as Statement ).first()
369- for (i in 1 .. numberOfRows) {
370- val constraint = parseQueryCondition(tableAliases, tableFromQuery, condition, i)
371- smt.addNode(constraint)
381+ try {
382+ val condition = parser.parse(where.toString(), toDBType(schema.databaseType))
383+ val tableFromQuery = TablesNamesFinder ().getTables(sqlQuery as Statement ).first()
384+ for (i in 1 .. numberOfRows) {
385+ val constraint = parseQueryCondition(tableAliases, tableFromQuery, condition, i)
386+ smt.addNode(constraint)
387+ }
388+ } catch (e: RuntimeException ) {
389+ LoggingUtil .getInfoLogger().warn(" Could not translate WHERE clause to SMT-LIB, skipping: ${where} . Reason: ${e.message} " )
372390 }
373391 }
374392 }
@@ -390,11 +408,15 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
390408 val onExpressions = join.onExpressions
391409 if (onExpressions.isNotEmpty()) {
392410 val onExpression = onExpressions.elementAt(0 )
393- val condition = parser.parse(onExpression.toString(), toDBType(schema.databaseType))
394- val tableFromQuery = TablesNamesFinder ().getTables(sqlQuery as Statement ).first()
395- for (i in 1 .. numberOfRows) {
396- val constraint = parseQueryCondition(tableAliases, tableFromQuery, condition, i)
397- smt.addNode(constraint)
411+ try {
412+ val condition = parser.parse(onExpression.toString(), toDBType(schema.databaseType))
413+ val tableFromQuery = TablesNamesFinder ().getTables(sqlQuery as Statement ).first()
414+ for (i in 1 .. numberOfRows) {
415+ val constraint = parseQueryCondition(tableAliases, tableFromQuery, condition, i)
416+ smt.addNode(constraint)
417+ }
418+ } catch (e: RuntimeException ) {
419+ LoggingUtil .getInfoLogger().warn(" Could not translate JOIN ON clause to SMT-LIB, skipping: ${onExpression} . Reason: ${e.message} " )
398420 }
399421 }
400422 }
@@ -525,8 +547,12 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
525547 " BIGINT" to " Int" ,
526548 " BIT" to " Int" ,
527549 " INTEGER" to " Int" ,
550+ " INT2" to " Int" ,
551+ " INT4" to " Int" ,
552+ " INT8" to " Int" ,
528553 " TINYINT" to " Int" ,
529554 " SMALLINT" to " Int" ,
555+ " NUMERIC" to " Int" ,
530556 " TIMESTAMP" to " Int" ,
531557 " DATE" to " Int" ,
532558 " FLOAT" to " Real" ,
@@ -539,6 +565,10 @@ class SmtLibGenerator(private val schema: DbInfoDto, private val numberOfRows: I
539565 " TEXT" to " String" ,
540566 " CHARACTER LARGE OBJECT" to " String" ,
541567 " BOOLEAN" to " String" ,
568+ " BOOL" to " String" ,
569+ " UUID" to " String" ,
570+ " JSONB" to " String" ,
571+ " BYTEA" to " String" ,
542572 )
543573 }
544574}
0 commit comments