1 65 66 67 package org.hsqldb; 68 69 import org.hsqldb.lib.StringUtil; 70 71 80 81 class Like { 84 85 private char[] cLike; 86 private int[] wildCardType; 87 private int iLen; 88 private boolean isIgnoreCase; 89 private int iFirstWildCard; 90 private boolean isNull; 91 Character escapeChar; 92 boolean hasCollation; 93 boolean optimised; 94 static final int UNDERSCORE_CHAR = 1; 95 static final int PERCENT_CHAR = 2; 96 97 Like(Character escape, boolean collation) { 98 escapeChar = escape; 99 hasCollation = collation; 100 } 101 102 108 void setParams(Session session, String s, boolean ignorecase) { 109 110 isIgnoreCase = ignorecase; 111 112 normalize(session, s); 113 114 optimised = true; 115 } 116 117 120 void resetPattern(Session session, String s) { 121 normalize(session, s); 122 } 123 124 private String getStartsWith() { 125 126 if (iLen == 0) { 127 return ""; 128 } 129 130 StringBuffer s = new StringBuffer (); 131 int i = 0; 132 133 for (; (i < iLen) && (wildCardType[i] == 0); i++) { 134 s.append(cLike[i]); 135 } 136 137 if (i == 0) { 138 return null; 139 } 140 141 return s.toString(); 142 } 143 144 152 Boolean compare(Session session, String s) { 153 154 if (s == null) { 155 return null; 156 } 157 158 if (isIgnoreCase) { 159 s = session.database.collation.toUpperCase(s); 160 } 161 162 return compareAt(s, 0, 0, s.length()) ? Boolean.TRUE 163 : Boolean.FALSE; 164 } 165 166 177 private boolean compareAt(String s, int i, int j, int jLen) { 178 179 for (; i < iLen; i++) { 180 switch (wildCardType[i]) { 181 182 case 0 : if ((j >= jLen) || (cLike[i] != s.charAt(j++))) { 184 return false; 185 } 186 break; 187 188 case UNDERSCORE_CHAR : if (j++ >= jLen) { 190 return false; 191 } 192 break; 193 194 case PERCENT_CHAR : if (++i >= iLen) { 196 return true; 197 } 198 199 while (j < jLen) { 200 if ((cLike[i] == s.charAt(j)) 201 && compareAt(s, i, j, jLen)) { 202 return true; 203 } 204 205 j++; 206 } 207 208 return false; 209 } 210 } 211 212 if (j != jLen) { 213 return false; 214 } 215 216 return true; 217 } 218 219 226 private void normalize(Session session, String pattern) { 227 228 isNull = pattern == null; 229 230 if (!isNull && isIgnoreCase) { 231 pattern = session.database.collation.toUpperCase(pattern); 232 } 233 234 iLen = 0; 235 iFirstWildCard = -1; 236 237 int l = pattern == null ? 0 238 : pattern.length(); 239 240 cLike = new char[l]; 241 wildCardType = new int[l]; 242 243 boolean bEscaping = false, 244 bPercent = false; 245 246 for (int i = 0; i < l; i++) { 247 char c = pattern.charAt(i); 248 249 if (bEscaping == false) { 250 if (escapeChar != null && escapeChar.charValue() == c) { 251 bEscaping = true; 252 253 continue; 254 } else if (c == '_') { 255 wildCardType[iLen] = UNDERSCORE_CHAR; 256 257 if (iFirstWildCard == -1) { 258 iFirstWildCard = iLen; 259 } 260 } else if (c == '%') { 261 if (bPercent) { 262 continue; 263 } 264 265 bPercent = true; 266 wildCardType[iLen] = PERCENT_CHAR; 267 268 if (iFirstWildCard == -1) { 269 iFirstWildCard = iLen; 270 } 271 } else { 272 bPercent = false; 273 } 274 } else { 275 bPercent = false; 276 bEscaping = false; 277 } 278 279 cLike[iLen++] = c; 280 } 281 282 for (int i = 0; i < iLen - 1; i++) { 283 if ((wildCardType[i] == PERCENT_CHAR) 284 && (wildCardType[i + 1] == UNDERSCORE_CHAR)) { 285 wildCardType[i] = UNDERSCORE_CHAR; 286 wildCardType[i + 1] = PERCENT_CHAR; 287 } 288 } 289 } 290 291 boolean hasWildcards() { 292 return iFirstWildCard != -1; 293 } 294 295 boolean isEquivalentToFalsePredicate() { 296 return isNull; 297 } 298 299 boolean isEquivalentToEqualsPredicate() { 300 return iFirstWildCard == -1; 301 } 302 303 boolean isEquivalentToNotNullPredicate() { 304 305 if (isNull ||!hasWildcards()) { 306 return false; 307 } 308 309 for (int i = 0; i < wildCardType.length; i++) { 310 if (wildCardType[i] != PERCENT_CHAR) { 311 return false; 312 } 313 } 314 315 return true; 316 } 317 318 boolean isEquivalentToBetweenPredicate() { 319 320 return iFirstWildCard > 0 321 && iFirstWildCard == wildCardType.length - 1 322 && cLike[iFirstWildCard] == '%'; 323 } 324 325 boolean isEquivalentToBetweenPredicateAugmentedWithLike() { 326 return iFirstWildCard > 0 && cLike[iFirstWildCard] == '%'; 327 } 328 329 String getRangeLow() { 330 return getStartsWith(); 331 } 332 333 String getRangeHigh() { 334 335 String s = getStartsWith(); 336 337 return s == null ? null 338 : s.concat("\uffff"); 339 } 340 341 public String describe(Session session) { 342 343 StringBuffer sb = new StringBuffer (); 344 345 sb.append(super.toString()).append("[\n"); 346 sb.append("escapeChar=").append(escapeChar).append('\n'); 347 sb.append("isNull=").append(isNull).append('\n'); 348 sb.append("optimised=").append(optimised).append('\n'); 349 sb.append("isIgnoreCase=").append(isIgnoreCase).append('\n'); 350 sb.append("iLen=").append(iLen).append('\n'); 351 sb.append("iFirstWildCard=").append(iFirstWildCard).append('\n'); 352 sb.append("cLike="); 353 sb.append(StringUtil.arrayToString(cLike)); 354 sb.append('\n'); 355 sb.append("wildCardType="); 356 sb.append(StringUtil.arrayToString(wildCardType)); 357 sb.append(']'); 358 359 return sb.toString(); 360 } 361 } 362 | Popular Tags |