1 5 package org.h2.test.synth; 6 7 import java.sql.Types ; 8 import java.util.ArrayList ; 9 10 public class Expression { 11 boolean isCondition; 12 13 private String sql; 14 private TestSynth config; 15 private Command command; 16 17 public static String [] getRandomSelectList(TestSynth config, Command command) { 18 if (config.random().getBoolean(30)) { 19 return new String [] { "*" }; 20 } 21 ArrayList exp = new ArrayList (); 22 String sql = ""; 23 if (config.random().getBoolean(10)) { 24 sql += "DISTINCT "; 25 } 26 int len = config.random().getLog(8) + 1; 27 for (int i = 0; i < len; i++) { 28 sql += getRandomExpression(config, command).getSQL(); 29 sql += " AS A" + i + " "; 30 exp.add(sql); 31 sql = ""; 32 } 33 String [] list = new String [exp.size()]; 34 exp.toArray(list); 35 return list; 36 } 37 38 public static Expression getRandomCondition(TestSynth config, Command command) { 39 Expression condition = new Expression(config, command, true); 40 if (config.random().getBoolean(50)) { 41 condition.create(); 42 } 43 return condition; 44 } 45 46 public static Expression getRandomExpression(TestSynth config, Command command) { 47 Expression expression = new Expression(config, command, false); 48 String alias = command.getRandomTableAlias(); 49 Column column = command.getTable(alias).getRandomConditionColumn(); 50 if(column == null) { 51 expression.createValue(); 52 } else { 53 expression.createExpression(alias, column); 54 } 55 return expression; 56 } 57 58 private void createValue() { 59 Value v = Column.getRandomColumn(config).getRandomValue(); 60 sql = v.getSQL(); 61 } 62 63 public static Expression getRandomJoinOn(TestSynth config, Command command, String alias) { 64 Expression expression = new Expression(config, command, true); 65 expression.createJoinComparison(alias); 66 return expression; 67 } 68 69 public static String getRandomOrder(TestSynth config, Command command) { 70 int len = config.random().getLog(6); 71 String sql = ""; 72 for (int i = 0; i < len; i++) { 73 if (i > 0) { 74 sql += ", "; 75 } 76 int max = command.selectList.length; 77 int idx = config.random().getInt(max); 78 sql += "A" + idx; 81 if (config.random().getBoolean(50)) { 85 if (config.random().getBoolean(10)) { 86 sql += " ASC"; 87 } else { 88 sql += " DESC"; 89 } 90 } 91 } 92 return sql; 93 } 94 95 public String getSQL() { 96 return sql.trim().length() == 0 ? null : sql.trim(); 97 } 98 99 private Expression(TestSynth config, Command command, boolean isCondition) { 100 this.config = config; 101 this.isCondition = isCondition; 102 this.command = command; 103 sql = ""; 104 } 105 106 private boolean is(int percent) { 107 return config.random().getBoolean(percent); 108 } 109 110 private String oneOf(String [] list) { 111 int i = config.random().getInt(list.length); 112 if (!sql.endsWith(" ")) { 113 sql += " "; 114 } 115 sql += list[i] + " "; 116 return list[i]; 117 } 118 119 private String getColumnName(String alias, Column column) { 120 if (alias == null) { 121 return column.getName(); 122 } 123 return alias + "." + column.getName(); 124 } 125 126 private void createJoinComparison(String alias) { 127 int len = config.random().getLog(5) + 1; 128 for (int i = 0; i < len; i++) { 129 if (i > 0) { 130 sql += "AND "; 131 } 132 Column column = command.getTable(alias).getRandomConditionColumn(); 133 if(column==null) { 134 sql += "1=1"; 135 return; 136 } 137 sql += getColumnName(alias, column); 138 sql += "="; 139 String a2; 140 do { 141 a2 = command.getRandomTableAlias(); 142 } while (a2.equals(alias)); 143 Table t2 = command.getTable(a2); 144 Column c2 = t2.getRandomColumnOfType(column.getType()); 145 if (c2 == null) { 146 sql += column.getRandomValue().getSQL(); 147 } else { 148 sql += getColumnName(a2, c2); 149 } 150 sql += " "; 151 } 152 } 153 154 private void create() { 155 createComparison(); 156 while (is(50)) { 157 oneOf(new String [] { "AND", "OR" }); 158 createComparison(); 159 } 160 } 161 162 174 private void createComparison() { 175 if (is(5)) { 176 sql += " NOT( "; 177 createComparisonSub(); 178 sql += ")"; 179 } else { 180 createComparisonSub(); 181 } 182 } 183 184 private void createComparisonSub() { 185 if (is(10)) { 192 sql += "("; 193 create(); 194 sql += ")"; 195 return; 196 } 197 String alias = command.getRandomTableAlias(); 198 Column column = command.getTable(alias).getRandomConditionColumn(); 199 if(column==null) { 200 if(is(50)) { 201 sql += "1=1"; 202 } else { 203 sql += "1=0"; 204 } 205 return; 206 } 207 boolean columnFirst = is(90); 208 if (columnFirst) { 209 sql += getColumnName(alias, column); 210 } else { 211 Value v = column.getRandomValue(); 212 sql += v.getSQL(); 213 } 214 if (is(10)) { 215 oneOf(new String [] { "IS NULL", "IS NOT NULL" }); 216 } else if (is(10)) { 217 oneOf(new String [] { "BETWEEN", "NOT BETWEEN" }); 218 Value v = column.getRandomValue(); 219 sql += v.getSQL(); 220 sql += " AND "; 221 v = column.getRandomValue(); 222 sql += v.getSQL(); 223 } else { 236 if(column.getType()==Types.VARCHAR) { 237 oneOf(new String [] { "=", "=", "=", "<", ">", "<=", ">=", "<>", "LIKE", 238 "NOT LIKE" }); 239 } else { 240 oneOf(new String [] { "=", "=", "=", "<", ">", "<=", ">=", "<>" }); 241 } 242 if (columnFirst) { 243 Value v = column.getRandomValue(); 244 sql += v.getSQL(); 245 } else { 246 sql += getColumnName(alias, column); 247 } 248 } 249 } 250 251 public boolean isEmpty() { 252 return sql == null || sql.trim().length() == 0; 253 } 254 255 void createExpression(String alias, Column type) { 256 boolean op = is(20); 257 boolean allowNull = !op; 259 261 createTerm(alias, type, true); 262 if (op) { 263 switch (type.getType()) { 264 case Types.INTEGER: 265 if(config.is(TestSynth.POSTGRESQL)) { 266 oneOf(new String [] { "+", "-", "/" }); 267 } else { 268 oneOf(new String [] { "+", "-", "*", "/" }); 269 } 270 createTerm(alias, type, allowNull); 271 break; 272 case Types.DECIMAL: 273 oneOf(new String [] { "+", "-", "*" }); 274 createTerm(alias, type, allowNull); 275 break; 276 case Types.VARCHAR: 277 sql += " || "; 278 createTerm(alias, type, allowNull); 279 break; 280 case Types.BLOB: 281 case Types.CLOB: 282 case Types.DATE: 283 break; 284 } 285 } 286 } 287 288 void createTerm(String alias, Column type, boolean allowNull) { 289 int dt = type.getType(); 290 if (is(5) && (dt == Types.INTEGER) || (dt == Types.DECIMAL)) { 291 sql += " - "; 292 allowNull = false; 293 } 294 if (is(10)) { 295 sql += "("; 296 createTerm(alias, type, allowNull); 297 sql += ")"; 298 return; 299 } 300 if (is(20)) { 301 switch (dt) { 312 case Types.VARCHAR: 319 oneOf(new String [] { "LOWER", "UPPER" }); 320 sql += "("; 321 createTerm(alias, type, allowNull); 322 sql += ")"; 323 break; 324 default: 325 createTerm(alias, type, allowNull); 326 } 327 return; 328 } 329 if (is(60)) { 330 String a2 = command.getRandomTableAlias(); 331 Column column = command.getTable(a2).getRandomColumnOfType(dt); 332 if (column != null) { 333 sql += getColumnName(a2, column); 334 return; 335 } 336 } 337 338 Value v = Value.getRandom(config, dt, 20, 2, allowNull); 339 sql += v.getSQL(); 340 } 341 342 public String toString() { 343 throw new Error ("hey!"); 344 } 345 346 } 347 | Popular Tags |