Add CTE Function to Postgres System by yaojiejia · Pull Request #1253 · sqlancer/sqlancer
public class PostgresExpressionGenerator implements ExpressionGenerator<PostgresExpression>, NoRECGenerator<PostgresSelect, PostgresJoin, PostgresExpression, PostgresTable, PostgresColumn>,
public static PostgresCTE generateCTE(PostgresGlobalState globalState, String cteName) { PostgresTables tables = globalState.getSchema().getRandomTableNonEmptyTables(); PostgresSelect subquery = new PostgresSelect();
// Generate a simple subquery for the CTE List<PostgresExpression> columns = new ArrayList<>(); PostgresExpressionGenerator gen = new PostgresExpressionGenerator(globalState).setColumns(tables.getColumns());
// Select 1-3 columns int numColumns = Randomly.smallNumber() + 1; for (int i = 0; i < numColumns; i++) { columns.add(gen.generateExpression(0)); }
subquery.setSelectType(SelectType.getRandom()); subquery.setFromList(tables.getTables().stream() .map(t -> new PostgresFromTable(t, Randomly.getBoolean())) .collect(Collectors.toList())); subquery.setFetchColumns(columns);
// Optionally add WHERE clause if (Randomly.getBoolean()) { subquery.setWhereClause(gen.generateExpression(0, PostgresDataType.BOOLEAN)); }
// Optionally add LIMIT if (Randomly.getBoolean()) { subquery.setLimitClause(PostgresConstant.createIntConstant(Randomly.getPositiveOrZeroNonCachedInteger())); }
return new PostgresCTE(cteName, subquery); }
/** * Generates a WITH clause containing 1-3 CTEs. * * @param globalState the global state * @return a PostgresWithClause instance */ public static PostgresWithClause generateWithClause(PostgresGlobalState globalState) { List<PostgresCTE> cteList = new ArrayList<>(); int numCTEs = Randomly.smallNumber() + 1; // 1-3 CTEs
for (int i = 0; i < numCTEs; i++) { String cteName = "cte_" + i; PostgresCTE cte = generateCTE(globalState, cteName); cteList.add(cte); }
return new PostgresWithClause(cteList); } }