97 |
97 |
** OM 20210704 Added specialized copy constructor.
|
98 |
98 |
** AL2 20220706 Added isCompatible to filter out the sort clauses not belonging to the buffer.
|
99 |
99 |
** OM 20220727 FieldId and PropertyId are different for denormalized extent fields.
|
|
100 |
** RAA 20221213 Added a cache for storing the result of toSortExpression() method.
|
100 |
101 |
*/
|
101 |
102 |
|
102 |
103 |
/*
|
... | ... | |
225 |
226 |
/** Lock for cache */
|
226 |
227 |
private static final Object cacheLock = new Object();
|
227 |
228 |
|
|
229 |
/** Cache for storing the result of {@code toSortExpression} method. */
|
|
230 |
private final Vector<String> toStringCache;
|
|
231 |
|
228 |
232 |
/** <code>true</code> if sort is ascending, else it is descending */
|
229 |
233 |
private final boolean ascending;
|
230 |
234 |
|
... | ... | |
253 |
257 |
private final String originalName;
|
254 |
258 |
|
255 |
259 |
/** Sort property name, usually qualified */
|
256 |
|
private String name;
|
|
260 |
private final String name;
|
257 |
261 |
|
258 |
262 |
/** Subscript value, if any */
|
259 |
|
private int subscript = -1;
|
|
263 |
private final int subscript;
|
260 |
264 |
|
261 |
265 |
/** SQL dialect which used this sort criterion; used for rtrim calls on character properties */
|
262 |
|
private Dialect dialect = null;
|
|
266 |
private final Dialect dialect;
|
263 |
267 |
|
264 |
268 |
/**
|
265 |
269 |
* Constructor which parses original sort component text, deriving the property name, sort
|
... | ... | |
347 |
351 |
// parse the test and extract alias, property and optional extent
|
348 |
352 |
int spacePos = text.indexOf(' ');
|
349 |
353 |
String rawName = ((spacePos != -1) ? text.substring(0, spacePos) : text).trim();
|
350 |
|
name = rawName;
|
|
354 |
String actualName = rawName;
|
351 |
355 |
originalName = internStrings ? rawName.intern() : rawName;
|
352 |
356 |
int bracketPos = rawName.indexOf("[");
|
353 |
357 |
int endPos = -1;
|
|
358 |
int actualSubscript = -1;
|
354 |
359 |
if (bracketPos >= 0)
|
355 |
360 |
{
|
356 |
361 |
endPos = rawName.indexOf("]");
|
... | ... | |
360 |
365 |
}
|
361 |
366 |
|
362 |
367 |
// extract base name
|
363 |
|
name = rawName.substring(0, bracketPos);
|
|
368 |
actualName = rawName.substring(0, bracketPos);
|
364 |
369 |
}
|
365 |
370 |
|
366 |
|
int dotPos = name.lastIndexOf(".");
|
|
371 |
int dotPos = actualName.lastIndexOf(".");
|
367 |
372 |
if (dotPos < 0)
|
368 |
373 |
{
|
369 |
374 |
throw new PersistenceException("Sort property may not be unqualified: " + rawName);
|
370 |
375 |
}
|
371 |
376 |
|
372 |
|
String propName = name.substring(dotPos + 1);
|
373 |
|
String alias = name.substring(0, dotPos);
|
|
377 |
String propName = actualName.substring(dotPos + 1);
|
|
378 |
String alias = actualName.substring(0, dotPos);
|
374 |
379 |
DmoMeta dmoMeta = DmoMetadataManager.getDmoInfo(dmoClass);
|
375 |
380 |
Property propMeta = dmoMeta.getFieldInfo(propName);
|
376 |
381 |
this.propertyName = propMeta.name; // already interned, anyway
|
... | ... | |
385 |
390 |
String sub = rawName.substring(bracketPos + 1, endPos);
|
386 |
391 |
try
|
387 |
392 |
{
|
388 |
|
subscript = Integer.parseInt(sub);
|
|
393 |
actualSubscript = Integer.parseInt(sub);
|
389 |
394 |
}
|
390 |
395 |
catch (NumberFormatException exc)
|
391 |
396 |
{
|
392 |
397 |
throw new PersistenceException("Unsupported subscript: " + sub);
|
393 |
398 |
}
|
394 |
399 |
|
395 |
|
name = alias + "." + propertyName;
|
|
400 |
actualName = alias + "." + propertyName;
|
396 |
401 |
}
|
397 |
402 |
}
|
398 |
403 |
|
399 |
404 |
if (internStrings)
|
400 |
405 |
{
|
401 |
|
name = name.intern();
|
|
406 |
actualName = actualName.intern();
|
402 |
407 |
}
|
403 |
408 |
|
404 |
409 |
// determine sort direction
|
... | ... | |
448 |
453 |
ignoreCase = isCharacter && !caseSens;
|
449 |
454 |
computedColumnPrefix = ccPrefix;
|
450 |
455 |
}
|
|
456 |
|
|
457 |
name = actualName;
|
|
458 |
subscript = actualSubscript;
|
|
459 |
toStringCache = new Vector<>(16);
|
|
460 |
toStringCache.setSize(16);
|
451 |
461 |
}
|
452 |
462 |
|
453 |
463 |
/**
|
... | ... | |
475 |
485 |
this.originalName = other.originalName;
|
476 |
486 |
this.name = alias + "." + propertyName +
|
477 |
487 |
(subscript < 0 ? "" : "[" + subscript + "]") + (ascending ? " asc" : " desc");
|
|
488 |
toStringCache = new Vector<>(16);
|
|
489 |
toStringCache.setSize(16);
|
478 |
490 |
}
|
479 |
491 |
|
480 |
492 |
/**
|
... | ... | |
930 |
942 |
// ASC: ASC + NULLS LAST (CASE WHEN [Order] IS NULL THEN 1 ELSE 0 END), [Order] ASC
|
931 |
943 |
// DESC: DESC + NULLS FIRST (CASE WHEN [Order] IS NULL THEN 0 ELSE 1 END), [Order] DESC
|
932 |
944 |
|
|
945 |
int cacheKey = 0;
|
|
946 |
cacheKey += (invert ? 1 << 3 : 0);
|
|
947 |
cacheKey += (useTableAlias ? 1 << 2 : 0);
|
|
948 |
cacheKey += (uniqueAlias ? 1 << 1 : 0);
|
|
949 |
cacheKey += (doSpecificProcessing ? 1 : 0);
|
|
950 |
String cacheResult = null;
|
|
951 |
cacheResult = toStringCache.get(cacheKey);
|
|
952 |
|
|
953 |
if (cacheResult != null)
|
|
954 |
{
|
|
955 |
return cacheResult;
|
|
956 |
}
|
|
957 |
|
933 |
958 |
boolean mssqlFix = dialect instanceof P2JSQLServer2008Dialect;
|
934 |
959 |
StringBuilder buf = new StringBuilder();
|
935 |
960 |
StringBuilder sortExpr = mssqlFix ? new StringBuilder() : null;
|
... | ... | |
983 |
1008 |
buf.append(ascending ? "asc" : "desc");
|
984 |
1009 |
}
|
985 |
1010 |
|
986 |
|
return buf.toString();
|
|
1011 |
String result = buf.toString();
|
|
1012 |
toStringCache.setElementAt(result, cacheKey);
|
|
1013 |
return result;
|
987 |
1014 |
}
|
988 |
1015 |
|
989 |
1016 |
/**
|