7035-20230201.patch
new/src/com/goldencode/p2j/persist/FQLBundle.java 2023-02-01 08:34:40 +0000 | ||
---|---|---|
19 | 19 |
** 008 EVL 20160223 Javadoc fixes to make compatible with Oracle Java 8 for Solaris 10. |
20 | 20 |
** 009 ECF 20200906 New ORM implementation. |
21 | 21 |
** 010 OM 20221103 Renamed class to FQLBundle. |
22 |
** 011 DDF 20230201 Refactored ParameterIndices into ParameterDiff. (refs: #7035) |
|
22 | 23 |
*/ |
23 | 24 | |
24 | 25 |
/* |
... | ... | |
153 | 154 |
/** Parallel set of FQL statements for dirty database use */ |
154 | 155 |
private List<String> dirtyStatements = null; |
155 | 156 |
|
156 |
/** Mapping of indices in the array of query substitution parameters */
|
|
157 |
private ParameterIndices paramIndices = null;
|
|
157 |
/** Mapping of substitution parameters functions */
|
|
158 |
private ParameterDiff paramDiff = null;
|
|
158 | 159 |
|
159 | 160 |
/** |
160 | 161 |
* Default constructor. |
... | ... | |
347 | 348 |
} |
348 | 349 |
|
349 | 350 |
/** |
350 |
* Get the <code>ParameterIndices</code> object associated with this
|
|
351 |
* Get the <code>ParameterDiff</code> object associated with this
|
|
351 | 352 |
* bundle. This object maintains an array of zero-based indices into the |
352 |
* array of query substitution arguments for the base (i.e., unaugmented)
|
|
353 |
* array of query substitution parameters lambdas for the base (i.e., unaugmented)
|
|
353 | 354 |
* where clause, as it exists <i>after</i> preprocessing is complete. This |
354 | 355 |
* additional level of indirection is necessary because the query |
355 | 356 |
* substitution placeholders may have been reordered within the FQL where |
356 | 357 |
* clause expression during the FQL preprocessing rewrite step, and some |
357 | 358 |
* parameters may have been inlined into the where clause. |
358 | 359 |
* |
359 |
* @return An object which provides a mapping of indices into the query
|
|
360 |
* substitution parameter list.
|
|
360 |
* @return An object which provides a mapping of query substitution parameter
|
|
361 |
* functions.
|
|
361 | 362 |
*/ |
362 |
ParameterIndices getParameterIndices()
|
|
363 |
ParameterDiff getParameterDiff()
|
|
363 | 364 |
{ |
364 |
return paramIndices;
|
|
365 |
return paramDiff;
|
|
365 | 366 |
} |
366 | 367 |
|
367 | 368 |
/** |
368 |
* Set the <code>ParameterIndices</code> object associated with this
|
|
369 |
* Set the <code>ParameterDiff</code> object associated with this
|
|
369 | 370 |
* bundle. This object maintains an array of zero-based indices into the |
370 |
* array of query substitution arguments for the base (i.e., unaugmented)
|
|
371 |
* array of query substitution parameters lambdas for the base (i.e., unaugmented)
|
|
371 | 372 |
* where clause, as it exists <i>after</i> preprocessing is complete. This |
372 | 373 |
* additional level of indirection is necessary because the query |
373 | 374 |
* substitution placeholders may have been reordered within the FQL where |
... | ... | |
375 | 376 |
* parameters may have been inlined into the where clause. |
376 | 377 |
* |
377 | 378 |
* @param paramIndices |
378 |
* An object which provides a mapping of indices into the query
|
|
379 |
* substitution parameter list.
|
|
379 |
* An object which provides a mapping of query substitution parameter
|
|
380 |
* functions.
|
|
380 | 381 |
*/ |
381 |
void setParameterIndices(ParameterIndices paramIndices)
|
|
382 |
void setParameterDiff(ParameterDiff paramDiff)
|
|
382 | 383 |
{ |
383 |
this.paramIndices = paramIndices;
|
|
384 |
this.paramDiff = paramDiff;
|
|
384 | 385 |
} |
385 | 386 |
|
386 | 387 |
/** |
new/src/com/goldencode/p2j/persist/FQLHelper.java 2023-02-01 08:34:55 +0000 | ||
---|---|---|
130 | 130 |
** prevent NPE in proxy case. |
131 | 131 |
** CA 20221006 Added JMX instrumentation for FQL prepare (in 'obtain'). Refs #6814 |
132 | 132 |
** OM 20221103 Class renamed to FQLHelper. |
133 |
** DDF 20230201 Method call changed due to method refactoring of FQLBundle and |
|
134 |
** FQLPreprocessor. (refs: #7035) |
|
133 | 135 |
*/ |
134 | 136 | |
135 | 137 |
/* |
... | ... | |
971 | 973 |
} |
972 | 974 |
} |
973 | 975 |
|
974 |
// Store query substitution parameter indices.
|
|
976 |
// Store query substitution parameter lambdas.
|
|
975 | 977 |
// TODO: currently, these are shared, and not dialect specific, but |
976 | 978 |
// only because we do not inline parameters from this class. Were this |
977 |
// to change, we would need to maintain separate ParameterIndices
|
|
979 |
// to change, we would need to maintain separate ParameterDiff
|
|
978 | 980 |
// objects for the primary and dirty database statements. |
979 | 981 |
if (primary) |
980 | 982 |
{ |
981 |
bundle.setParameterIndices(fqlPreprocessor.getParameterIndices());
|
|
983 |
bundle.setParameterDiff(fqlPreprocessor.getParameterDiff());
|
|
982 | 984 |
} |
983 | 985 |
} |
984 | 986 |
|
new/src/com/goldencode/p2j/persist/FQLPreprocessor.java 2023-02-01 08:35:16 +0000 | ||
---|---|---|
281 | 281 |
** are not the same), to be aware of the external buffers (i.e. added for CAN-FIND |
282 | 282 |
** sub-select clauses). The translate will be performed before the query is being |
283 | 283 |
** executed. |
284 |
** DDF 20230201 Extracted query parameters from the where clause and refactored ParameterIndices |
|
285 |
** into ParameterDiff to store a mapping of substitution parameter lambdas for all |
|
286 |
** parameters (parameters given at query initialization and the ones extracted |
|
287 |
** from the AST). (refs: #7035) |
|
284 | 288 |
*/ |
285 | 289 | |
286 | 290 |
/* |
... | ... | |
466 | 470 |
* substitution parameters in the proper order: |
467 | 471 |
* <ul> |
468 | 472 |
* <li>{@link #getFQL()} |
469 |
* <li>{@link #getParameterIndices()}
|
|
473 |
* <li>{@link #getParameterDiff()}
|
|
470 | 474 |
* <li>{@link #ansiJoins()} |
471 | 475 |
* </ul> |
472 | 476 |
* <p> |
... | ... | |
614 | 618 |
*/ |
615 | 619 |
private boolean inlinedTernary = false; |
616 | 620 |
|
617 |
/** Mapping of index positions for substitution parameters after rewrite */
|
|
618 |
private ParameterIndices paramIndices = null;
|
|
621 |
/** Mapping of substitution parameters functions after rewrite */
|
|
622 |
private ParameterDiff paramDiff = null;
|
|
619 | 623 |
|
620 | 624 |
/** Map of properties used by this where clause, keyed by DMO entity */ |
621 | 625 |
private Map<String, Set<String>> restrictionProperties = null; |
... | ... | |
653 | 657 |
/** Flag indicating that the query depends on mutable SESSION attribute(s). */ |
654 | 658 |
private boolean dependsOnSessionAttribute = false; |
655 | 659 |
|
660 |
/** List of extracted parameters from the where clause */ |
|
661 |
private List<Object> parametersDiff = null; |
|
662 |
|
|
656 | 663 |
/** |
657 | 664 |
* Factory method which accepts an unprocessed where clause, the database |
658 | 665 |
* instance and the database dialect associated with the enclosing query, |
... | ... | |
1288 | 1295 |
} |
1289 | 1296 |
|
1290 | 1297 |
/** |
1291 |
* Get the <code>ParameterIndices</code> object associated with this query.
|
|
1298 |
* Get the <code>ParameterDiff</code> object associated with this query.
|
|
1292 | 1299 |
* This object maintains an array of zero-based indices into the array of |
1293 |
* query substitution arguments for the where clause, as it exists
|
|
1300 |
* query substitution parameter lambdas for the where clause, as it exists
|
|
1294 | 1301 |
* <i>after</i> preprocessing is complete. This additional level of |
1295 | 1302 |
* indirection is necessary because the query substitution placeholders may |
1296 | 1303 |
* have been reordered within the FQL where clause expression during the |
... | ... | |
1298 | 1305 |
* inlined into the where clause. |
1299 | 1306 |
* |
1300 | 1307 |
* @return An object which provides a mapping of indices into the query |
1301 |
* substitution parameter list. |
|
1308 |
* substitution parameter lambdas list.
|
|
1302 | 1309 |
*/ |
1303 |
ParameterIndices getParameterIndices()
|
|
1310 |
ParameterDiff getParameterDiff()
|
|
1304 | 1311 |
{ |
1305 |
return paramIndices;
|
|
1312 |
return paramDiff;
|
|
1306 | 1313 |
} |
1307 | 1314 |
|
1308 | 1315 |
/** |
... | ... | |
1563 | 1570 |
"[" + database + "] Preprocessed FQL: " + fql + sep + root.dumpTree()); |
1564 | 1571 |
} |
1565 | 1572 |
|
1566 |
this.paramIndices = createParameterIndices(root, parameters);
|
|
1573 |
this.paramDiff = createParameterDiffs(root, parameters);
|
|
1567 | 1574 |
} |
1568 | 1575 |
} |
1569 | 1576 |
|
... | ... | |
2609 | 2616 |
Set<HQLAst> nullsInInSet = null; |
2610 | 2617 |
Set<HQLAst> droppedTrims = null; |
2611 | 2618 |
|
2619 |
int parameterCounter = parameters != null ? parameters.length : 0; |
|
2620 |
FqlType parameterType = null; |
|
2621 |
|
|
2612 | 2622 |
boolean doInline = inline; |
2613 | 2623 |
inline = false; |
2614 | 2624 |
HQLAst parent; |
... | ... | |
2938 | 2948 |
|
2939 | 2949 |
break; |
2940 | 2950 |
|
2951 |
// The BOOL_TRUE and BOOL_FALSE cases are not handled because are duplicates |
|
2952 |
// Change node type to SUBST for future prepared statement processing |
|
2953 |
case NUM_LITERAL: |
|
2954 |
if (parameterType == null) |
|
2955 |
{ |
|
2956 |
parameterType = FqlType.INTEGER; |
|
2957 |
} |
|
2958 |
case DEC_LITERAL: |
|
2959 |
if (parameterType == null) |
|
2960 |
{ |
|
2961 |
parameterType = FqlType.DECIMAL; |
|
2962 |
} |
|
2963 |
case STRING: |
|
2964 |
if (parameterType == null) |
|
2965 |
{ |
|
2966 |
parameterType = FqlType.TEXT; |
|
2967 |
} |
|
2968 |
|
|
2969 |
// Add an index and datatype annotation to the current node. |
|
2970 |
// The extracted-value annotation stores the value of the node. |
|
2971 |
next.putAnnotation("index", (long) parameterCounter++); |
|
2972 |
next.putAnnotation("datatype", parameterType.toString()); |
|
2973 |
next.putAnnotation("extracted-value", next.getText()); |
|
2974 |
|
|
2975 |
if (parametersDiff == null) |
|
2976 |
{ |
|
2977 |
parametersDiff = new ArrayList<>(); |
|
2978 |
} |
|
2979 |
|
|
2980 |
parametersDiff.add(next.getText()); |
|
2981 |
parameterType = null; |
|
2982 |
|
|
2983 |
// Change the node type and value |
|
2984 |
next.setType(SUBST); |
|
2985 |
next.setText("?"); |
|
2986 |
|
|
2987 |
// Stop the inline of the extracted parameters. |
|
2988 |
break; |
|
2941 | 2989 |
// Possibly inline certain query substitution parameters. |
2942 | 2990 |
case SUBST: |
2943 | 2991 |
parent = (HQLAst) next.getParent(); |
... | ... | |
5848 | 5896 |
} |
5849 | 5897 |
|
5850 | 5898 |
/** |
5851 |
* Create the mapping of substitution parameters to their corresponding |
|
5899 |
* Create the mapping of substitution parameters functions to their corresponding
|
|
5852 | 5900 |
* substitution placeholders in the rewritten FQL where clause. These |
5853 | 5901 |
* placeholders (<code>?</code>) may have been reordered or removed (due to |
5854 | 5902 |
* inlining) during the rewrite process. |
5855 | 5903 |
* <p> |
5856 | 5904 |
* During parsing of the FQL clause, an index annotation was added to each |
5857 | 5905 |
* AST of type <code>SUBST</code> (token type for the query substitution |
5858 |
* parameter placeholder), denoting that placeholder's position in the |
|
5859 |
* original where clause. We now walk the rewritten AST, extracting this |
|
5860 |
* annotation and storing it in a new list. The resulting array defines |
|
5906 |
* parameter placeholder), and each <code>NUM_LITERAL</code>, <code>DEC_LITERAL</code>, |
|
5907 |
* <code>STRING</code> which is substituted to <code>SUBST</code> |
|
5908 |
* denoting that placeholder's lambda in the original where clause. |
|
5909 |
* We now walk the rewritten AST, extracting this annotation |
|
5910 |
* and storing it in a new list. The resulting array defines |
|
5861 | 5911 |
* the new order of the substitution parameters. For parameters which |
5862 | 5912 |
* were dropped, due to inlining, a null placeholder will appear in the new |
5863 | 5913 |
* list. |
... | ... | |
5870 | 5920 |
* @return Object which maps new query substitution parameter positions to their positions in the original |
5871 | 5921 |
* parameters array. These indices are zero-based. |
5872 | 5922 |
*/ |
5873 |
private ParameterIndices createParameterIndices(HQLAst root, Object[] parameters)
|
|
5923 |
private ParameterDiff createParameterDiffs(HQLAst root, Object[] parameters)
|
|
5874 | 5924 |
{ |
5875 |
if (parameters == null) |
|
5925 |
// If there are no arguments or substituted parameters |
|
5926 |
if (parameters == null && parametersDiff == null) |
|
5876 | 5927 |
{ |
5877 |
return (new ParameterIndices(null));
|
|
5928 |
return (new ParameterDiff(null));
|
|
5878 | 5929 |
} |
5879 | 5930 |
|
5880 |
List<Integer> indices = new ArrayList<>(parameters.length); |
|
5881 |
|
|
5931 |
int paramCounter = parameters != null ? parameters.length : 0; |
|
5932 |
paramCounter += parametersDiff != null ? parametersDiff.size() : 0; |
|
5933 |
@SuppressWarnings("unchecked") |
|
5934 |
Function<Object[], Object>[] retrieveParameters = new Function[paramCounter]; |
|
5935 | ||
5882 | 5936 |
// Extract the "index" annotation from each SUBST node, in order of |
5883 | 5937 |
// the tree walk, which will correspond to the order of the placeholders |
5884 | 5938 |
// in the final, infix expression. |
5939 |
|
|
5940 |
// There are two types of parameters, parameters that are substituted from the beginning, |
|
5941 |
// and those that are substituted in the mainWalk() method. |
|
5942 |
// In the case of the "extracted-value" annotation being present, create a function |
|
5943 |
// that returns the value after being casted to a BaseDataType. |
|
5944 |
// For the substituted parameters that already existed, the function returns |
|
5945 |
// the index positioned value in the params given. |
|
5946 |
int functionCounter = 0; |
|
5885 | 5947 |
Iterator<Aast> iter = root.iterator(); |
5886 | 5948 |
while (iter.hasNext()) |
5887 | 5949 |
{ |
5888 |
Long index = null; |
|
5889 | 5950 |
HQLAst next = (HQLAst) iter.next(); |
5890 | 5951 |
switch (next.getType()) |
5891 | 5952 |
{ |
5892 | 5953 |
case SUBST: |
5893 |
index = (Long) next.getAnnotation("index"); |
|
5894 |
indices.add(index.intValue()); |
|
5895 |
break; |
|
5896 |
|
|
5897 |
case NUM_LITERAL: |
|
5898 |
case DEC_LITERAL: |
|
5899 |
case STRING: |
|
5900 |
case IS_NULL: |
|
5901 |
case NOT_NULL: |
|
5902 |
case BOOL_FALSE: |
|
5903 | 5954 |
if (inline && next.isAnnotation("inlined")) |
5904 | 5955 |
{ |
5905 |
// Allow null to remain at this position in the array. |
|
5906 |
indices.add(null); |
|
5907 |
} |
|
5956 |
break; |
|
5957 |
} |
|
5958 |
|
|
5959 |
Function<Object[], Object> rp = null; |
|
5960 |
|
|
5961 |
if (next.isAnnotation("extracted-value")) |
|
5962 |
{ |
|
5963 |
rp = (Object[] params) -> |
|
5964 |
{ |
|
5965 |
String value = (String) next.getAnnotation("extracted-value"); |
|
5966 |
FqlType fqlType = Enum.valueOf(FqlType.class, (String) next.getAnnotation("datatype")); |
|
5967 |
switch (fqlType) |
|
5968 |
{ |
|
5969 |
case INTEGER: |
|
5970 |
return new integer(value); |
|
5971 |
case DECIMAL: |
|
5972 |
return new decimal(value); |
|
5973 |
case TEXT: |
|
5974 |
assert (value.charAt(0) == '\''); |
|
5975 |
assert (value.charAt(value.length() - 1) == '\''); |
|
5976 |
value = value.substring(1, value.length() - 1); |
|
5977 |
return new character(value); |
|
5978 |
default: |
|
5979 |
throw new IllegalStateException("No matching datatype for the extracted value."); |
|
5980 |
} |
|
5981 |
}; |
|
5982 |
} |
|
5983 |
else |
|
5984 |
{ |
|
5985 |
rp = (Object[] params) -> |
|
5986 |
{ |
|
5987 |
Long index = (Long) next.getAnnotation("index"); |
|
5988 |
return params[index.intValue()]; |
|
5989 |
}; |
|
5990 |
} |
|
5991 |
|
|
5992 |
retrieveParameters[functionCounter++] = rp; |
|
5993 |
|
|
5908 | 5994 |
break; |
5995 |
// case NUM_LITERAL: |
|
5996 |
// case DEC_LITERAL: |
|
5997 |
// case STRING: |
|
5998 |
// case IS_NULL: |
|
5999 |
// case NOT_NULL: |
|
6000 |
// case BOOL_FALSE: |
|
6001 |
// if (inline && next.isAnnotation("inlined")) |
|
6002 |
// { |
|
6003 |
// // Allow null to remain at this position in the array. |
|
6004 |
// indices.add(null); |
|
6005 |
// } |
|
6006 |
// break; |
|
5909 | 6007 |
|
5910 | 6008 |
default: |
5911 | 6009 |
break; |
5912 | 6010 |
} |
5913 | 6011 |
} |
5914 | 6012 |
|
5915 |
Integer[] idx = indices.toArray(new Integer[indices.size()]); |
|
5916 |
|
|
5917 |
return (new ParameterIndices(idx)); |
|
6013 |
return (new ParameterDiff(retrieveParameters)); |
|
5918 | 6014 |
} |
5919 | 6015 |
|
5920 | 6016 |
/** |
new/src/com/goldencode/p2j/persist/ParameterDiff.java 2023-02-01 08:34:22 +0000 | ||
---|---|---|
1 |
/* |
|
2 |
** Module : ParameterDiff.java |
|
3 |
** Abstract : Mapping of query substitution parameters functions in an array, after where clause preprocessing. |
|
4 |
** |
|
5 |
** Copyright (c) 2008-2023, Golden Code Development Corporation. |
|
6 |
** |
|
7 |
** -#- -I- --Date-- -JPRM- ------------------------------------Description------------------------------------ |
|
8 |
** 001 ECF 20081009 @40080 Created initial version. A mapping of query substitution parameters in an array, |
|
9 |
** after where clause preprocessing. |
|
10 |
** 002 OM 20221103 New class names for FQLPreprocessor, FQLExpression, FQLBundle, and FQLCache. |
|
11 |
** 003 DDF 20230201 Refactored ParameterIndices into ParameterDiff by replacing the Integer indices |
|
12 |
** array with an array of lambdas. Instead of storing the index of the parameters |
|
13 |
** from the AST node, we store a lambda that takes an array of arguments and returns |
|
14 |
** either an extracted value from the AST, or an existing value from the given array. |
|
15 |
*/ |
|
16 | ||
17 |
/* |
|
18 |
** This program is free software: you can redistribute it and/or modify |
|
19 |
** it under the terms of the GNU Affero General Public License as |
|
20 |
** published by the Free Software Foundation, either version 3 of the |
|
21 |
** License, or (at your option) any later version. |
|
22 |
** |
|
23 |
** This program is distributed in the hope that it will be useful, |
|
24 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
25 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
26 |
** GNU Affero General Public License for more details. |
|
27 |
** |
|
28 |
** You may find a copy of the GNU Affero GPL version 3 at the following |
|
29 |
** location: https://www.gnu.org/licenses/agpl-3.0.en.html |
|
30 |
** |
|
31 |
** Additional terms under GNU Affero GPL version 3 section 7: |
|
32 |
** |
|
33 |
** Under Section 7 of the GNU Affero GPL version 3, the following additional |
|
34 |
** terms apply to the works covered under the License. These additional terms |
|
35 |
** are non-permissive additional terms allowed under Section 7 of the GNU |
|
36 |
** Affero GPL version 3 and may not be removed by you. |
|
37 |
** |
|
38 |
** 0. Attribution Requirement. |
|
39 |
** |
|
40 |
** You must preserve all legal notices or author attributions in the covered |
|
41 |
** work or Appropriate Legal Notices displayed by works containing the covered |
|
42 |
** work. You may not remove from the covered work any author or developer |
|
43 |
** credit already included within the covered work. |
|
44 |
** |
|
45 |
** 1. No License To Use Trademarks. |
|
46 |
** |
|
47 |
** This license does not grant any license or rights to use the trademarks |
|
48 |
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks |
|
49 |
** of Golden Code Development Corporation. You are not authorized to use the |
|
50 |
** name Golden Code, FWD, or the names of any author or contributor, for |
|
51 |
** publicity purposes without written authorization. |
|
52 |
** |
|
53 |
** 2. No Misrepresentation of Affiliation. |
|
54 |
** |
|
55 |
** You may not represent yourself as Golden Code Development Corporation or FWD. |
|
56 |
** |
|
57 |
** You may not represent yourself for publicity purposes as associated with |
|
58 |
** Golden Code Development Corporation, FWD, or any author or contributor to |
|
59 |
** the covered work, without written authorization. |
|
60 |
** |
|
61 |
** 3. No Misrepresentation of Source or Origin. |
|
62 |
** |
|
63 |
** You may not represent the covered work as solely your work. All modified |
|
64 |
** versions of the covered work must be marked in a reasonable way to make it |
|
65 |
** clear that the modified work is not originating from Golden Code Development |
|
66 |
** Corporation or FWD. All modified versions must contain the notices of |
|
67 |
** attribution required in this license. |
|
68 |
*/ |
|
69 | ||
70 |
package com.goldencode.p2j.persist; |
|
71 | ||
72 |
import java.util.function.Function; |
|
73 | ||
74 |
/** |
|
75 |
* A mapping of the active indices in an array of query substitution |
|
76 |
* parameters, after an HQL where clause has been preprocessed. The HQL |
|
77 |
* preprocessor may inline or re-order query substitution parameters. Thus, |
|
78 |
* given an array of query substitution parameters, it is necessary to provide |
|
79 |
* a means for a query object to organize the remaining parameters when |
|
80 |
* submitting a query for execution. |
|
81 |
* <p> |
|
82 |
* A query object will have the original array of parameters provided by |
|
83 |
* business logic, as well as an instance of {@link FQLPreprocessor}. That |
|
84 |
* instance will provide an instance of this class via its {@link |
|
85 |
* FQLPreprocessor#getParameterDiff()} method. To obtain the correct list |
|
86 |
* of parameters which corresponds with the preprocessed where clause, the |
|
87 |
* query iterates its original array of parameters. For each index in that |
|
88 |
* array, it calls {@link #getIndex(int)} to obtain the remapped position of |
|
89 |
* the parameter originally at the current index. If <code>null</code> is |
|
90 |
* returned, it means the parameter originally at the current index has been |
|
91 |
* inlined into the where clause. A non-<code>null</code> value represents |
|
92 |
* the zero-based index at which the parameter can be found in the original |
|
93 |
* array. |
|
94 |
*/ |
|
95 |
final class ParameterDiff |
|
96 |
{ |
|
97 |
/** Count of substitution parameters functions in use */ |
|
98 |
private final int count; |
|
99 |
|
|
100 |
/** Array of functions for substitution parameters */ |
|
101 |
private final Function<Object[], Object>[] substParamFunctions; |
|
102 |
|
|
103 |
/** |
|
104 |
* Constructor which sets the array of substitution parameters |
|
105 |
* functions of query for the associated where clause. |
|
106 |
* |
|
107 |
* @param substFunctions |
|
108 |
* Array of substitution parameter functions. If |
|
109 |
* <code>null</code>, the associated query string has no query |
|
110 |
* substitution parameters. |
|
111 |
*/ |
|
112 |
ParameterDiff(Function<Object[], Object>[] substFunctions) |
|
113 |
{ |
|
114 |
this.substParamFunctions = substFunctions; |
|
115 |
int counter = 0; |
|
116 |
if (substParamFunctions != null) |
|
117 |
{ |
|
118 |
for (int i = 0; i < substParamFunctions.length; i++) |
|
119 |
{ |
|
120 |
if (substParamFunctions[i] == null) |
|
121 |
{ |
|
122 |
continue; |
|
123 |
} |
|
124 |
counter++; |
|
125 |
} |
|
126 |
} |
|
127 |
this.count = counter; |
|
128 |
} |
|
129 |
|
|
130 |
/** |
|
131 |
* Get the count of query substitution parameters functions which were created for |
|
132 |
* the where clause preprocessing step. This is the count of the passed |
|
133 |
* lambda array items to this object's constructor. |
|
134 |
* |
|
135 |
* @return Count of query substitution parameters functions. |
|
136 |
*/ |
|
137 |
int getCount() |
|
138 |
{ |
|
139 |
return count; |
|
140 |
} |
|
141 |
|
|
142 |
/** |
|
143 |
* Given a position of a query substitution parameter function in the original |
|
144 |
* array of lambdas (before the where clause preprocessing step), get the |
|
145 |
* lambda of that parameter in the original array. Note that the |
|
146 |
* original array is not changed, only the mapping of lambdas may have |
|
147 |
* changed. If the index returned matches the <code>position</code> |
|
148 |
* supplied, this indicates the parameter's placeholder (<code>?</code>) is |
|
149 |
* located at the same relative position in the where clause as before |
|
150 |
* preprocessing. |
|
151 |
* |
|
152 |
* @param position |
|
153 |
* Zero-based index of the target substitution parameter function |
|
154 |
* in the original array. |
|
155 |
* |
|
156 |
* @return New, zero-based index of the target substitution parameter function |
|
157 |
* in the original array, or <code>null</code> if the parameter was |
|
158 |
* inlined during preprocessing of the where clause. |
|
159 |
*/ |
|
160 |
Function<Object[], Object> getIndex(int position) |
|
161 |
{ |
|
162 |
return (substParamFunctions == null ? null : substParamFunctions[position]); |
|
163 |
} |
|
164 |
|
|
165 |
/** |
|
166 |
* Method for retrieving the substitution parameter functions. |
|
167 |
* |
|
168 |
* @return The substitution parameter functions, or null if |
|
169 |
* no functions were assigned. |
|
170 |
*/ |
|
171 |
Function<Object[], Object>[] getSubstParamFunctions() |
|
172 |
{ |
|
173 |
return substParamFunctions; |
|
174 |
} |
|
175 |
|
|
176 |
/** |
|
177 |
* Apply the substitution parameters lambdas based on the params given. The params |
|
178 |
* value is used just for already substituded parameters from the where clause, |
|
179 |
* while the value of the subtituted parameters from the preprocessing are replaced |
|
180 |
* by the value of the node annotation <code>extracted-value</code>. |
|
181 |
* |
|
182 |
* @param params |
|
183 |
* Parameter array for lambda which selects the parameter value |
|
184 |
* for substituted parameters that were not created during |
|
185 |
* the preprocessing phase. |
|
186 |
* The parameter array is still required for the other lambdas, |
|
187 |
* but not used. |
|
188 |
* |
|
189 |
* @return Object representing the value of the argument. |
|
190 |
*/ |
|
191 |
Object[] getSubstParameters(Object[] params) |
|
192 |
{ |
|
193 |
Object[] args = new Object[count]; |
|
194 |
for (int position = 0; position < substParamFunctions.length; position++) |
|
195 |
{ |
|
196 |
if (substParamFunctions[position] != null) |
|
197 |
{ |
|
198 |
args[position] = substParamFunctions[position].apply(params); |
|
199 |
} |
|
200 |
} |
|
201 |
return args; |
|
202 |
} |
|
203 |
} |
new/src/com/goldencode/p2j/persist/ParameterIndices.java 1970-01-01 00:00:00 +0000 | ||
---|---|---|
1 |
/* |
|
2 |
** Module : ParameterIndices.java |
|
3 |
** Abstract : Mapping of query substitution parameters in an array, after where clause preprocessing. |
|
4 |
** |
|
5 |
** Copyright (c) 2008-2022, Golden Code Development Corporation. |
|
6 |
** |
|
7 |
** -#- -I- --Date-- -JPRM- ------------------------------------Description------------------------------------ |
|
8 |
** 001 ECF 20081009 @40080 Created initial version. A mapping of query substitution parameters in an array, |
|
9 |
** after where clause preprocessing. |
|
10 |
** 002 OM 20221103 New class names for FQLPreprocessor, FQLExpression, FQLBundle, and FQLCache. |
|
11 |
*/ |
|
12 | ||
13 |
/* |
|
14 |
** This program is free software: you can redistribute it and/or modify |
|
15 |
** it under the terms of the GNU Affero General Public License as |
|
16 |
** published by the Free Software Foundation, either version 3 of the |
|
17 |
** License, or (at your option) any later version. |
|
18 |
** |
|
19 |
** This program is distributed in the hope that it will be useful, |
|
20 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
21 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
22 |
** GNU Affero General Public License for more details. |
|
23 |
** |
|
24 |
** You may find a copy of the GNU Affero GPL version 3 at the following |
|
25 |
** location: https://www.gnu.org/licenses/agpl-3.0.en.html |
|
26 |
** |
|
27 |
** Additional terms under GNU Affero GPL version 3 section 7: |
|
28 |
** |
|
29 |
** Under Section 7 of the GNU Affero GPL version 3, the following additional |
|
30 |
** terms apply to the works covered under the License. These additional terms |
|
31 |
** are non-permissive additional terms allowed under Section 7 of the GNU |
|
32 |
** Affero GPL version 3 and may not be removed by you. |
|
33 |
** |
|
34 |
** 0. Attribution Requirement. |
|
35 |
** |
|
36 |
** You must preserve all legal notices or author attributions in the covered |
|
37 |
** work or Appropriate Legal Notices displayed by works containing the covered |
|
38 |
** work. You may not remove from the covered work any author or developer |
|
39 |
** credit already included within the covered work. |
|
40 |
** |
|
41 |
** 1. No License To Use Trademarks. |
|
42 |
** |
|
43 |
** This license does not grant any license or rights to use the trademarks |
|
44 |
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks |
|
45 |
** of Golden Code Development Corporation. You are not authorized to use the |
|
46 |
** name Golden Code, FWD, or the names of any author or contributor, for |
|
47 |
** publicity purposes without written authorization. |
|
48 |
** |
|
49 |
** 2. No Misrepresentation of Affiliation. |
|
50 |
** |
|
51 |
** You may not represent yourself as Golden Code Development Corporation or FWD. |
|
52 |
** |
|
53 |
** You may not represent yourself for publicity purposes as associated with |
|
54 |
** Golden Code Development Corporation, FWD, or any author or contributor to |
|
55 |
** the covered work, without written authorization. |
|
56 |
** |
|
57 |
** 3. No Misrepresentation of Source or Origin. |
|
58 |
** |
|
59 |
** You may not represent the covered work as solely your work. All modified |
|
60 |
** versions of the covered work must be marked in a reasonable way to make it |
|
61 |
** clear that the modified work is not originating from Golden Code Development |
|
62 |
** Corporation or FWD. All modified versions must contain the notices of |
|
63 |
** attribution required in this license. |
|
64 |
*/ |
|
65 | ||
66 |
package com.goldencode.p2j.persist; |
|
67 | ||
68 |
/** |
|
69 |
* A mapping of the active indices in an array of query substitution |
|
70 |
* parameters, after an HQL where clause has been preprocessed. The HQL |
|
71 |
* preprocessor may inline or re-order query substitution parameters. Thus, |
|
72 |
* given an array of query substitution parameters, it is necessary to provide |
|
73 |
* a means for a query object to organize the remaining parameters when |
|
74 |
* submitting a query for execution. |
|
75 |
* <p> |
|
76 |
* A query object will have the original array of parameters provided by |
|
77 |
* business logic, as well as an instance of {@link FQLPreprocessor}. That |
|
78 |
* instance will provide an instance of this class via its {@link |
|
79 |
* FQLPreprocessor#getParameterIndices()} method. To obtain the correct list |
|
80 |
* of parameters which corresponds with the preprocessed where clause, the |
|
81 |
* query iterates its original array of parameters. For each index in that |
|
82 |
* array, it calls {@link #getIndex(int)} to obtain the remapped position of |
|
83 |
* the parameter originally at the current index. If <code>null</code> is |
|
84 |
* returned, it means the parameter originally at the current index has been |
|
85 |
* inlined into the where clause. A non-<code>null</code> value represents |
|
86 |
* the zero-based index at which the parameter can be found in the original |
|
87 |
* array. |
|
88 |
*/ |
|
89 |
final class ParameterIndices |
|
90 |
{ |
|
91 |
/** Count of substitution parameters in use */ |
|
92 |
private final int count; |
|
93 |
|
|
94 |
/** Mapping of indices of parameters in original array */ |
|
95 |
private final Integer[] indices; |
|
96 |
|
|
97 |
/** |
|
98 |
* Constructor which sets the array of new index positions of query |
|
99 |
* substitution parameters for the associated where clause. |
|
100 |
* |
|
101 |
* @param indices |
|
102 |
* Array of zero-based index positions of query substitution |
|
103 |
* parameters in the original array of parameters. If |
|
104 |
* <code>null</code>, the associated query string has no query |
|
105 |
* substitution parameters. |
|
106 |
*/ |
|
107 |
ParameterIndices(Integer[] indices) |
|
108 |
{ |
|
109 |
int i = 0; |
|
110 |
|
|
111 |
if (indices != null) |
|
112 |
{ |
|
113 |
for (Integer next : indices) |
|
114 |
{ |
|
115 |
if (next != null) |
|
116 |
{ |
|
117 |
i++; |
|
118 |
} |
|
119 |
} |
|
120 |
} |
|
121 |
|
|
122 |
this.indices = indices; |
|
123 |
this.count = i; |
|
124 |
} |
|
125 |
|
|
126 |
/** |
|
127 |
* Get the count of query substitution parameters which survived the where |
|
128 |
* clause preprocessing step. This is the count of non-<code>null</code> |
|
129 |
* index positions in the array of indices passed to this object's |
|
130 |
* constructor. |
|
131 |
* |
|
132 |
* @return Count of query substitution parameters. |
|
133 |
*/ |
|
134 |
int getCount() |
|
135 |
{ |
|
136 |
return count; |
|
137 |
} |
|
138 |
|
|
139 |
/** |
|
140 |
* Given a position of a query substitution parameter in the original array |
|
141 |
* of parameters (before the where clause preprocessing step), get the new, |
|
142 |
* zero-based index of that parameter in the original array. Note that the |
|
143 |
* original array is not changed, only the mapping of indices may have |
|
144 |
* changed. If the index returned matches the <code>position</code> |
|
145 |
* supplied, this indicates the parameter's placeholder (<code>?</code>) is |
|
146 |
* located at the same relative position in the where clause as before |
|
147 |
* preprocessing. |
|
148 |
* |
|
149 |
* @param position |
|
150 |
* Zero-based index of the target substitution parameter in the |
|
151 |
* original array. |
|
152 |
* |
|
153 |
* @return New, zero-based index of the target substitution parameter in |
|
154 |
* the original array, or <code>null</code> if the parameter was |
|
155 |
* inlined during preprocessing of the where clause. |
|
156 |
*/ |
|
157 |
Integer getIndex(int position) |
|
158 |
{ |
|
159 |
return (indices == null ? null : indices[position]); |
|
160 |
} |
|
161 |
} |
new/src/com/goldencode/p2j/persist/QueryComponent.java 2023-02-01 08:35:30 +0000 | ||
---|---|---|
32 | 32 |
** CA 20221130 Refactored the WHERE clause translation (when the bound and definition buffers are not the |
33 | 33 |
** same), to be aware of the external buffers (i.e. added for CAN-FIND sub-select clauses). |
34 | 34 |
** The translate will be performed before the query is being executed. |
35 |
** DDF 20230201 Refactored ParameterIndices into ParameterDiff. Extracted arguments also need to be |
|
36 |
** resolved. (refs: #7035) |
|
35 | 37 |
*/ |
36 | 38 | |
37 | 39 |
/* |
... | ... | |
490 | 492 |
protected Object[] getArgs() |
491 | 493 |
throws PersistenceException |
492 | 494 |
{ |
493 |
if (dfArgs != null && currentArgs == null)
|
|
495 |
if (currentArgs == null) |
|
494 | 496 |
{ |
495 | 497 |
currentArgs = filterArgs(getHQLPreprocessor()); |
496 | 498 |
} |
... | ... | |
594 | 596 |
// in this case the processDynamicFilters() is not required to be called before calling |
595 | 597 |
// resolveArgs() because it was called before constructing the preprocessor |
596 | 598 |
Object[] intermediate = resolveArgs(); |
597 |
if (intermediate == null) |
|
599 |
ParameterDiff pd = preproc.getParameterDiff(); |
|
600 |
if (intermediate == null && pd == null) |
|
598 | 601 |
{ |
599 | 602 |
return null; |
600 | 603 |
} |
601 | 604 |
|
602 |
ParameterIndices pi = preproc.getParameterIndices(); |
|
603 |
int len = pi.getCount(); |
|
604 |
Object[] filteredArgs = new Object[len]; |
|
605 |
for (int i = 0, count = 0; count < len; i++) |
|
606 |
{ |
|
607 |
Integer nextIndex = pi.getIndex(i); |
|
608 |
if (nextIndex == null) |
|
609 |
{ |
|
610 |
// original substitution parameter was inlined into HQL by preprocessor; skip it |
|
611 |
continue; |
|
612 |
} |
|
613 |
|
|
614 |
// Substitution placeholders may have been reordered if this |
|
615 |
// statement was rewritten by the HQL preprocessor. Make sure |
|
616 |
// we access the correct substitution parameter. |
|
617 |
Object next = intermediate[nextIndex]; |
|
618 |
|
|
619 |
filteredArgs[count++] = next; |
|
620 |
} |
|
605 |
if (pd == null) |
|
606 |
{ |
|
607 |
return intermediate; |
|
608 |
} |
|
609 | ||
610 |
Object[] filteredArgs = pd.getSubstParameters(intermediate); |
|
611 |
for (int i = 0; i < filteredArgs.length; i++) |
|
612 |
{ |
|
613 |
// Substitution parameters returned also need to be resolved. |
|
614 |
filteredArgs[i] = resolveArg(filteredArgs[i]); |
|
615 |
} |
|
616 |
|
|
617 |
// ParameterIndices pi = preproc.getParameterIndices(); |
|
618 |
// int len = pi.getCount(); |
|
619 |
// Object[] filteredArgs = new Object[len]; |
|
620 |
// for (int i = 0, count = 0; count < len; i++) |
|
621 |
// { |
|
622 |
// Integer nextIndex = pi.getIndex(i); |
|
623 |
// if (nextIndex == null) |
|
624 |
// { |
|
625 |
// // original substitution parameter was inlined into HQL by preprocessor; skip it |
|
626 |
// continue; |
|
627 |
// } |
|
628 |
// |
|
629 |
// // Substitution placeholders may have been reordered if this |
|
630 |
// // statement was rewritten by the HQL preprocessor. Make sure |
|
631 |
// // we access the correct substitution parameter. |
|
632 |
// Object next = intermediate[nextIndex]; |
|
633 |
// |
|
634 |
// filteredArgs[count++] = next; |
|
635 |
// } |
|
621 | 636 |
|
622 | 637 |
return filteredArgs; |
623 | 638 |
} |
new/src/com/goldencode/p2j/persist/RandomAccessQuery.java 2023-02-01 08:35:47 +0000 | ||
---|---|---|
346 | 346 |
** are not the same), to be aware of the external buffers (i.e. added for CAN-FIND |
347 | 347 |
** sub-select clauses). The translate will be performed before the query is being |
348 | 348 |
** executed. |
349 |
** DDF 20230201 Refactoring ParameterIndices into ParameterDiff and added method for retrieving |
|
350 |
** parameter values. (refs: #7035) |
|
349 | 351 |
*/ |
350 | 352 | |
351 | 353 |
/* |
... | ... | |
4239 | 4241 |
boolean debug = LOG.isLoggable(Level.FINE); |
4240 | 4242 |
|
4241 | 4243 |
DirtyShareContext dirtyContext = buffer.getDirtyContext(); |
4242 |
ParameterIndices pi = activeBundle.getParameterIndices();
|
|
4244 |
ParameterDiff pi = activeBundle.getParameterDiff();
|
|
4243 | 4245 |
int origArgCount = (values == null ? 0 : values.length); |
4244 | 4246 |
int baseArgCount = (pi == null ? origArgCount : pi.getCount()); |
4245 | 4247 |
|
... | ... | |
4326 | 4328 |
// resolve these parameters. |
4327 | 4329 |
for (int j = 0, i = startIndex; i < baseArgCount; j++) |
4328 | 4330 |
{ |
4329 |
int k = -1; |
|
4330 |
if (pi == null) |
|
4331 |
{ |
|
4332 |
k = j; |
|
4333 |
} |
|
4334 |
else |
|
4335 |
{ |
|
4336 |
Integer idx = pi.getIndex(j); |
|
4337 |
if (idx == null) |
|
4338 |
{ |
|
4339 |
// original substitution parameter was inlined into HQL by preprocessor; skip it |
|
4340 |
continue; |
|
4341 |
} |
|
4342 |
k = idx; |
|
4343 |
} |
|
4331 |
// int k = -1;
|
|
4332 |
// if (pi == null)
|
|
4333 |
// {
|
|
4334 |
// k = j;
|
|
4335 |
// }
|
|
4336 |
// else
|
|
4337 |
// {
|
|
4338 |
// Integer idx = pi.getIndex(j);
|
|
4339 |
// if (idx == null)
|
|
4340 |
// {
|
|
4341 |
// // original substitution parameter was inlined into HQL by preprocessor; skip it
|
|
4342 |
// continue;
|
|
4343 |
// }
|
|
4344 |
// k = idx;
|
|
4345 |
// }
|
|
4344 | 4346 |
|
4345 | 4347 |
// Substitution placeholders may have been reordered if this |
4346 | 4348 |
// statement was rewritten by the HQL preprocessor. Make sure |
4347 | 4349 |
// we access the correct substitution parameter. |
4348 |
Object next = values[k]; |
|
4350 |
Function<Object[], Object> currentParameterFunction = pi.getIndex(j); |
|
4351 |
Object next = currentParameterFunction.apply(values); |
|
4349 | 4352 |
|
4350 | 4353 |
// store parameters in the base args array, resolving them first if necessary |
4351 | 4354 |
if (next instanceof Resolvable) |
new/src/com/goldencode/p2j/persist/RecordBuffer.java 2023-02-01 08:36:16 +0000 | ||
---|---|---|
1260 | 1260 |
** runtime. |
1261 | 1261 |
** CA 20230123 isPropertyIndexed must have protected access, because is accessed from static |
1262 | 1262 |
** methods. |
1263 |
** DDF 20230201 Refactoring ParameterIndices into ParameterDiff and added method for retrieving |
|
1264 |
** parameter values. (refs: #7035) |
|
1263 | 1265 |
*/ |
1264 | 1266 | |
1265 | 1267 |
/* |
... | ... | |
10707 | 10709 |
|
10708 | 10710 |
if (args != null && args.length > 0) |
10709 | 10711 |
{ |
10710 |
ParameterIndices pi = preproc.getParameterIndices(); |
|
10711 |
int len = pi.getCount(); |
|
10712 |
List<Object> argList = new ArrayList<>(len); |
|
10713 |
for (int i = 0, count = 0; count < len; i++) |
|
10714 |
{ |
|
10715 |
Integer nextIndex = pi.getIndex(i); |
|
10716 |
if (nextIndex == null) |
|
10717 |
{ |
|
10718 |
// original substitution parameter was inlined into HQL by preprocessor; |
|
10719 |
// skip it. |
|
10720 |
continue; |
|
10721 |
} |
|
10722 |
|
|
10723 |
// substitution placeholders may have been reordered if this statement was |
|
10724 |
// rewritten by the HQL preprocessor; make sure we access the correct |
|
10725 |
// substitution parameter |
|
10726 |
Object next = args[nextIndex]; |
|
10727 |
argList.add(next); |
|
10728 |
|
|
10729 |
count++; |
|
10730 |
} |
|
10731 |
args = argList.toArray(); |
|
10712 |
ParameterDiff pd = preproc.getParameterDiff(); |
|
10713 |
Object[] filteredArgs = pd.getSubstParameters(args); |
|
10714 |
args = filteredArgs; |
|
10715 |
|
|
10716 |
// ParameterDiff pi = preproc.getParameterDiff(); |
|
10717 |
// int len = pi.getCount(); |
|
10718 |
// List<Object> argList = new ArrayList<>(len); |
|
10719 |
// for (int i = 0, count = 0; count < len; i++) |
|
10720 |
// { |
|
10721 |
// Integer nextIndex = pi.getIndex(i); |
|
10722 |
// if (nextIndex == null) |
|
10723 |
// { |
|
10724 |
// // original substitution parameter was inlined into HQL by preprocessor; |
|
10725 |
// // skip it. |
|
10726 |
// continue; |
|
10727 |
// } |
|
10728 |
// |
|
10729 |
// // substitution placeholders may have been reordered if this statement was |
|
10730 |
// // rewritten by the HQL preprocessor; make sure we access the correct |
|
10731 |
// // substitution parameter |
|
10732 |
// Object next = args[nextIndex]; |
|
10733 |
// argList.add(next); |
|
10734 |
// |
|
10735 |
// count++; |
|
10736 |
// } |
|
10737 |
// args = argList.toArray(); |
|
10732 | 10738 |
} |
10733 | 10739 |
} |
10734 | 10740 |
|
new/src/com/goldencode/p2j/persist/TemporaryBuffer.java 2023-02-01 08:36:49 +0000 | ||
---|---|---|
640 | 640 |
** runtime. |
641 | 641 |
** HC 20230118 Eliminated some of the uses of String.toUpperCase and/or |
642 | 642 |
** String.toLowerCase for performance. |
643 |
** DDF 20230201 Refactoring ParameterIndices into ParameterDiff and added method for retrieving |
|
644 |
** parameter values. (refs: #7035) |
|
643 | 645 |
*/ |
644 | 646 | |
645 | 647 |
/* |
... | ... | |
7709 | 7711 |
|
7710 | 7712 |
if (args != null && args.length > 0) |
7711 | 7713 |
{ |
7712 |
ParameterIndices pi = preproc.getParameterIndices(); |
|
7713 |
int len = pi.getCount(); |
|
7714 |
List<Object> argList = new ArrayList<>(len); |
|
7715 |
for (int i = 0, count = 0; count < len; i++) |
|
7716 |
{ |
|
7717 |
Integer nextIndex = pi.getIndex(i); |
|
7718 |
if (nextIndex == null) |
|
7719 |
{ |
|
7720 |
// original substitution parameter was inlined into HQL by preprocessor; |
|
7721 |
// skip it. |
|
7722 |
continue; |
|
7723 |
} |
|
7724 |
|
|
7725 |
// substitution placeholders may have been reordered if this statement was |
|
7726 |
// rewritten by the HQL preprocessor; make sure we access the correct |
|
7727 |
// substitution parameter |
|
7728 |
Object next = args[nextIndex]; |
|
7729 |
argList.add(next); |
|
7730 |
|
|
7731 |
count++; |
|
7732 |
} |
|
7733 |
args = argList.toArray(); |
|
7714 |
ParameterDiff pd = preproc.getParameterDiff(); |
|
7715 |
Object[] filteredArgs = pd.getSubstParameters(args); |
|
7716 |
args = filteredArgs; |
|
7717 |
// ParameterDiff pi = preproc.getParameterDiff(); |
|
7718 |
// int len = pi.getCount(); |
|
7719 |
// List<Object> argList = new ArrayList<>(len); |
|
7720 |
// for (int i = 0, count = 0; count < len; i++) |
|
7721 |
// { |
|
7722 |
// Integer nextIndex = pi.getIndex(i); |
|
7723 |
// if (nextIndex == null) |
|
7724 |
// { |
|
7725 |
// // original substitution parameter was inlined into HQL by preprocessor; |
|
7726 |
// // skip it. |
|
7727 |
// continue; |
|
7728 |
// } |
|
7729 |
// |
|
7730 |
// // substitution placeholders may have been reordered if this statement was |
|
7731 |
// // rewritten by the HQL preprocessor; make sure we access the correct |
|
7732 |
// // substitution parameter |
|
7733 |
// Object next = args[nextIndex]; |
|
7734 |
// argList.add(next); |
|
7735 |
// |
|
7736 |
// count++; |
|
7737 |
// } |
|
7738 |
// args = argList.toArray(); |
|
7734 | 7739 |
} |
7735 | 7740 |
} |
7736 | 7741 |
String delStmt = query.toFinalExpression(); |