Project

General

Profile

7035-20230209.patch

Dănuț Filimon, 02/09/2023 06:55 AM

Download (35 KB)

View differences:

new/src/com/goldencode/p2j/jmx/FwdJMX.java 2023-02-09 11:37:06 +0000
25 25
**     AL2 20230104 Added OrmRedo.
26 26
**                  Added OrmNoUndoTrace.
27 27
**     OM  20230112 Added finer-granulation instrumentation for processing of dynamic queries. 
28
**     DDF 20230209 Added counters for psCache (prepared statement cache) hit/miss. (refs: #7035)
28 29
*/ 
29 30

  
30 31
/*
......
551 552
      /** Outgoing network traffic */
552 553
      NetworkWrites,
553 554
      /** Widget attributes flush count */
554
      WidgetAttrFlushes;
555
      WidgetAttrFlushes,
556
      /** psCache hit counter */
557
      PSCacheHits,
558
      /** psCache miss counter */
559
      PSCacheMisses;
555 560
      
556 561
      /** Counter instance */
557 562
      private final SimpleLongCounter counter = new SimpleLongCounter();
new/src/com/goldencode/p2j/persist/FQLBundle.java 2023-02-09 11:38:33 +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 20230209          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-09 11:38:58 +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 20230209          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-09 11:40:23 +0000
282 282
**                           are not the same), to be aware of the external buffers (i.e. added for CAN-FIND
283 283
**                           sub-select clauses).  The translate will be performed before the query is being
284 284
**                           executed.
285
**     DDF 20230209          Extracted query parameters from the where clause and refactored ParameterIndices
286
**                           into ParameterDiff to store a mapping of substitution parameter lambdas for all
287
**                           parameters (parameters given at query initialization and the ones extracted 
288
**                           from the AST). (refs: #7035)
285 289
*/
286 290

  
287 291
/*
......
467 471
 * substitution parameters in the proper order:
468 472
 * <ul>
469 473
 *   <li>{@link #getFQL()}
470
 *   <li>{@link #getParameterIndices()}
474
 *   <li>{@link #getParameterDiff()}
471 475
 *   <li>{@link #ansiJoins()}
472 476
 * </ul>
473 477
 * <p>
......
615 619
    */
616 620
   private boolean inlinedTernary = false;
617 621
   
618
   /** Mapping of index positions for substitution parameters after rewrite */
619
   private ParameterIndices paramIndices = null;
622
   /** Mapping of substitution parameters functions after rewrite */
623
   private ParameterDiff paramDiff = null;
620 624
   
621 625
   /** Map of properties used by this where clause, keyed by DMO entity */
622 626
   private Map<String, Set<String>> restrictionProperties = null;
......
1289 1293
   }
1290 1294
   
1291 1295
   /**
1292
    * Get the <code>ParameterIndices</code> object associated with this query.
1296
    * Get the <code>ParameterDiff</code> object associated with this query.
1293 1297
    * This object maintains an array of zero-based indices into the array of
1294
    * query substitution arguments for the where clause, as it exists
1298
    * query substitution parameter lambdas for the where clause, as it exists
1295 1299
    * <i>after</i> preprocessing is complete.  This additional level of
1296 1300
    * indirection is necessary because the query substitution placeholders may
1297 1301
    * have been reordered within the FQL where clause expression during the
......
1299 1303
    * inlined into the where clause.
1300 1304
    *
1301 1305
    * @return  An object which provides a mapping of indices into the query
1302
    *          substitution parameter list.
1306
    *          substitution parameter lambdas list.
1303 1307
    */
1304
   ParameterIndices getParameterIndices()
1308
   ParameterDiff getParameterDiff()
1305 1309
   {
1306
      return paramIndices;
1310
      return paramDiff;
1307 1311
   }
1308 1312
   
1309 1313
   /**
......
1554 1558
         
1555 1559
         this.findByRowid = checkFindByRowid(root);
1556 1560
         
1561
         // parameters need to be created before fql is emitted
1562
         this.paramDiff = createParameterDiffs(root, parameters);
1563
         
1557 1564
         // Emit the preprocessed FQL expression text.
1558 1565
         this.fql = emit(root, false);
1559 1566
         
......
1563 1570
            LOG.log(Level.FINEST,
1564 1571
                    "[" + database + "] Preprocessed FQL:  " + fql + sep + root.dumpTree());
1565 1572
         }
1566
         
1567
         this.paramIndices = createParameterIndices(root, parameters);
1568 1573
      }
1569 1574
   }
1570 1575
   
......
5849 5854
   }
5850 5855
   
5851 5856
   /**
5852
    * Create the mapping of substitution parameters to their corresponding
5857
    * Create the mapping of substitution parameters functions to their corresponding
5853 5858
    * substitution placeholders in the rewritten FQL where clause.  These
5854 5859
    * placeholders (<code>?</code>) may have been reordered or removed (due to
5855 5860
    * inlining) during the rewrite process.
5856 5861
    * <p>
5857 5862
    * During parsing of the FQL clause, an index annotation was added to each
5858 5863
    * AST of type <code>SUBST</code> (token type for the query substitution
5859
    * parameter placeholder), denoting that placeholder's position in the
5860
    * original where clause.  We now walk the rewritten AST, extracting this
5861
    * annotation and storing it in a new list.  The resulting array defines
5864
    * parameter placeholder), and each <code>NUM_LITERAL</code>, <code>DEC_LITERAL</code>,
5865
    * <code>STRING</code> which is substituted to <code>SUBST</code> 
5866
    * denoting that placeholder's lambda in the original where clause.  
5867
    * We now walk the rewritten AST, extracting this annotation
5868
    * and storing it in a new list.  The resulting array defines
5862 5869
    * the new order of the substitution parameters.  For parameters which
5863 5870
    * were dropped, due to inlining, a null placeholder will appear in the new
5864 5871
    * list.
......
5871 5878
    * @return  Object which maps new query substitution parameter positions to their positions in the original
5872 5879
    *          parameters array. These indices are zero-based.
5873 5880
    */
5874
   private ParameterIndices createParameterIndices(HQLAst root, Object[] parameters)
5881
   private ParameterDiff createParameterDiffs(HQLAst root, Object[] parameters)
5875 5882
   {
5876
      if (parameters == null)
5877
      {
5878
         return (new ParameterIndices(null));
5879
      }
5883
      int parameterCounter = parameters != null ? parameters.length : 0;
5884
      FqlType parameterType = null;
5880 5885
      
5881
      List<Integer> indices = new ArrayList<>(parameters.length);
5886
      List<Function<Object[], Object>> retrieveParameterFunctions = new ArrayList<>();
5882 5887
      
5883 5888
      // Extract the "index" annotation from each SUBST node, in order of
5884 5889
      // the tree walk, which will correspond to the order of the placeholders
5885 5890
      // in the final, infix expression.
5891
      
5892
      // There are two types of parameters, parameters that are substituted from the beginning,
5893
      // and those that are substituted in the mainWalk() method.
5894
      // In the case of the "extracted-value" annotation being present, create a function 
5895
      // that returns the value after being casted to a BaseDataType.
5896
      // For the substituted parameters that already existed, the function returns
5897
      // the index positioned value in the params given.
5886 5898
      Iterator<Aast> iter = root.iterator();
5887 5899
      while (iter.hasNext())
5888 5900
      {
5889
         Long index = null;
5890 5901
         HQLAst next = (HQLAst) iter.next();
5891 5902
         switch (next.getType())
5892
         {
5893
            case SUBST:
5894
               index = (Long) next.getAnnotation("index");
5895
               indices.add(index.intValue());
5896
               break;
5897
               
5903
         {            
5904
            // The BOOL_TRUE and BOOL_FALSE cases are not handled
5898 5905
            case NUM_LITERAL:
5906
               if (parameterType == null)
5907
               {
5908
                  parameterType = FqlType.INTEGER;
5909
               }
5899 5910
            case DEC_LITERAL:
5911
               if (parameterType == null)
5912
               {
5913
                  parameterType = FqlType.DECIMAL;
5914
               }
5900 5915
            case STRING:
5901
            case IS_NULL:
5902
            case NOT_NULL:
5903
            case BOOL_FALSE:
5916
               if (parameterType == null)
5917
               {
5918
                  parameterType = FqlType.TEXT;
5919
               }
5920
               
5904 5921
               if (inline && next.isAnnotation("inlined"))
5905 5922
               {
5906
                  // Allow null to remain at this position in the array.
5907
                  indices.add(null);
5908
               }
5923
                  break;
5924
               }
5925
               
5926
               // Add an index and datatype annotation to the current node.
5927
               // The extracted-value annotation stores the value of the node.
5928
               next.putAnnotation("index", (long) parameterCounter++);
5929
               next.putAnnotation("datatype", parameterType.toString());
5930
               next.putAnnotation("extracted-value", next.getText());
5931
               parameterType = null;
5932
               
5933
               // Change the node type and value
5934
               next.setType(SUBST);
5935
               next.setText("?");
5936
            case SUBST:
5937
               Function<Object[], Object> rp = null;
5938
               
5939
               if (next.isAnnotation("extracted-value"))
5940
               {
5941
                  rp = (Object[] params) -> 
5942
                  {
5943
                     String value = (String) next.getAnnotation("extracted-value");
5944
                     FqlType fqlType = Enum.valueOf(FqlType.class, (String) next.getAnnotation("datatype"));
5945
                     switch (fqlType)
5946
                     {
5947
                        case INTEGER:
5948
                           return new integer(value);
5949
                        case DECIMAL:
5950
                           return new decimal(value);
5951
                        case TEXT:
5952
                           assert (value.charAt(0) == '\'');
5953
                           assert (value.charAt(value.length() - 1) == '\'');
5954
                           value = value.substring(1, value.length() - 1);
5955
                           return new character(value);
5956
                        default:
5957
                           throw new IllegalStateException("No matching datatype for the extracted value.");
5958
                     }
5959
                  };
5960
               }
5961
               else 
5962
               {
5963
                  rp = (Object[] params) -> 
5964
                  {
5965
                     Long index = (Long) next.getAnnotation("index");
5966
                     return params[index.intValue()];
5967
                  };
5968
               }
5969
               
5970
               retrieveParameterFunctions.add(rp);
5909 5971
               break;
5910 5972
               
5911 5973
            default:
......
5913 5975
         }
5914 5976
      }
5915 5977
      
5916
      Integer[] idx = indices.toArray(new Integer[indices.size()]);
5917
      
5918
      return (new ParameterIndices(idx));
5978
      if (retrieveParameterFunctions.size() == 0)
5979
      {
5980
         return new ParameterDiff(null);
5981
      }
5982
      
5983
      @SuppressWarnings("unchecked")
5984
      Function<Object[], Object>[] rpf = retrieveParameterFunctions.toArray(new Function[] {});
5985
      
5986
      return new ParameterDiff(rpf);
5919 5987
   }
5920 5988
   
5921 5989
   /**
new/src/com/goldencode/p2j/persist/ParameterDiff.java 2023-02-07 13:27:23 +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
      if (substParamFunctions == null)
194
      {
195
         return null;
196
      }
197
      
198
      Object[] args = new Object[count];
199
      for (int position = 0; position < substParamFunctions.length; position++)
200
      {
201
         if (substParamFunctions[position] != null)
202
         {
203
            args[position] = substParamFunctions[position].apply(params);
204
         }
205
      }
206
      return args;
207
   }
208
}
new/src/com/goldencode/p2j/persist/QueryComponent.java 2023-02-09 11:40:53 +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 20230209 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)
598
      {
599
         return null;
600
      }
601
      
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;
599
      ParameterDiff pd = preproc.getParameterDiff();
600
      if (intermediate == null && pd == null)
601
      {
602
         return null;
603
      }
604
      
605
      if (pd == null)
606
      {
607
         return intermediate;
608
      }
609

  
610
      Object[] filteredArgs = pd.getSubstParameters(intermediate);
611
      
612
      if (filteredArgs == null)
613
      {
614
         return null;
615
      }
616
      
617
      for (int i = 0; i < filteredArgs.length; i++)
618
      {
619
         // Substitution parameters returned also need to be resolved.
620
         filteredArgs[i] = resolveArg(filteredArgs[i]);
620 621
      }
621 622
      
622 623
      return filteredArgs;
new/src/com/goldencode/p2j/persist/RandomAccessQuery.java 2023-02-09 11:41:19 +0000
347 347
**                           are not the same), to be aware of the external buffers (i.e. added for CAN-FIND
348 348
**                           sub-select clauses).  The translate will be performed before the query is being
349 349
**                           executed.
350
**     DDF 20230209          Refactoring ParameterIndices into ParameterDiff and added method for retrieving 
351
**                           parameter values. (refs: #7035)
350 352
*/
351 353

  
352 354
/*
......
4251 4253
      boolean debug = LOG.isLoggable(Level.FINE);
4252 4254
      
4253 4255
      DirtyShareContext dirtyContext = buffer.getDirtyContext();
4254
      ParameterIndices pi = activeBundle.getParameterIndices();
4256
      ParameterDiff pi = activeBundle.getParameterDiff();
4255 4257
      int origArgCount = (values == null ? 0 : values.length);
4256 4258
      int baseArgCount = (pi == null ? origArgCount : pi.getCount());
4257 4259
      
......
4338 4340
            // resolve these parameters.
4339 4341
            for (int j = 0, i = startIndex; i < baseArgCount; j++)
4340 4342
            {
4341
               int k = -1;
4342
               if (pi == null)
4343
               {
4344
                  k = j;
4345
               }
4346
               else
4347
               {
4348
                  Integer idx = pi.getIndex(j);
4349
                  if (idx == null)
4350
                  {
4351
                     // original substitution parameter was inlined into HQL by preprocessor;  skip it
4352
                     continue;
4353
                  }
4354
                  k = idx;
4355
               }
4356 4343
               
4357 4344
               // Substitution placeholders may have been reordered if this
4358 4345
               // statement was rewritten by the HQL preprocessor. Make sure
4359 4346
               // we access the correct substitution parameter.
4360
               Object next = values[k];
4347
               Function<Object[], Object> currentParameterFunction = pi.getIndex(j);
4348
               Object next = currentParameterFunction.apply(values);
4361 4349
               
4362 4350
               // store parameters in the base args array, resolving them first if necessary
4363 4351
               if (next instanceof Resolvable)
new/src/com/goldencode/p2j/persist/RecordBuffer.java 2023-02-09 11:41:45 +0000
1265 1265
**                           runtime.
1266 1266
**     CA  20230123          isPropertyIndexed must have protected access, because is accessed from static
1267 1267
**                           methods. 
1268
**     DDF 20230209          Refactoring ParameterIndices into ParameterDiff and added method for retrieving 
1269
**                           parameter values. (refs: #7035)
1268 1270
*/
1269 1271

  
1270 1272
/*
......
10743 10745
            
10744 10746
            if (args != null && args.length > 0)
10745 10747
            {
10746
               ParameterIndices pi = preproc.getParameterIndices();
10747
               int len = pi.getCount();
10748
               List<Object> argList = new ArrayList<>(len);
10749
               for (int i = 0, count = 0; count < len; i++)
10750
               {
10751
                  Integer nextIndex = pi.getIndex(i);
10752
                  if (nextIndex == null)
10753
                  {
10754
                     // original substitution parameter was inlined into HQL by preprocessor;
10755
                     // skip it.
10756
                     continue;
10757
                  }
10758
                  
10759
                  // substitution placeholders may have been reordered if this statement was
10760
                  // rewritten by the HQL preprocessor; make sure we access the correct
10761
                  // substitution parameter
10762
                  Object next = args[nextIndex];
10763
                  argList.add(next);
10764
                  
10765
                  count++;
10766
               }
10767
               args = argList.toArray();
10748
               ParameterDiff pd = preproc.getParameterDiff();
10749
               Object[] filteredArgs = pd.getSubstParameters(args);
10750
               args = filteredArgs;
10768 10751
            }
10769 10752
         }
10770 10753
         
new/src/com/goldencode/p2j/persist/TemporaryBuffer.java 2023-02-09 11:42:37 +0000
645 645
**                           runtime.
646 646
**     HC  20230118          Eliminated some of the uses of String.toUpperCase and/or
647 647
**                           String.toLowerCase for performance.
648
**     DDF 20230209          Refactoring ParameterIndices into ParameterDiff and added method for retrieving 
649
**                           parameter values. (refs: #7035)
648 650
*/
649 651

  
650 652
/*
......
7856 7858
         
7857 7859
         if (args != null && args.length > 0)
7858 7860
         {
7859
            ParameterIndices pi = preproc.getParameterIndices();
7860
            int len = pi.getCount();
7861
            List<Object> argList = new ArrayList<>(len);
7862
            for (int i = 0, count = 0; count < len; i++)
7863
            {
7864
               Integer nextIndex = pi.getIndex(i);
7865
               if (nextIndex == null)
7866
               {
7867
                  // original substitution parameter was inlined into HQL by preprocessor;
7868
                  // skip it.
7869
                  continue;
7870
               }
7871
               
7872
               // substitution placeholders may have been reordered if this statement was
7873
               // rewritten by the HQL preprocessor; make sure we access the correct
7874
               // substitution parameter
7875
               Object next = args[nextIndex];
7876
               argList.add(next);
7877
               
7878
               count++;
7879
            }
7880
            args = argList.toArray();
7861
            ParameterDiff pd = preproc.getParameterDiff();
7862
            Object[] filteredArgs = pd.getSubstParameters(args);
7863
            args = filteredArgs;
7881 7864
         }
7882 7865
      }
7883 7866
      String delStmt = query.toFinalExpression();
new/src/com/goldencode/p2j/persist/orm/TempTableDataSourceProvider.java 2023-02-09 11:24:29 +0000
79 79
import java.util.logging.*;
80 80
import javax.sql.DataSource;
81 81
import com.goldencode.cache.*;
82
import com.goldencode.p2j.jmx.*;
82 83
import com.goldencode.p2j.persist.*;
83 84
import com.goldencode.p2j.persist.dialect.*;
84 85
import com.goldencode.p2j.persist.orm.types.*;
......
120 121
      /** Logger */
121 122
      private static final Logger LOG = LogHelper.getLogger(DataSourceImpl.class.getName());
122 123
      
124
      private static final SimpleCounter PSCacheHits = SimpleCounter.getInstance(
125
               FwdJMX.Counter.PSCacheHits
126
      );
127
      
128
      private static final SimpleCounter PSCacheMisses = SimpleCounter.getInstance(
129
               FwdJMX.Counter.PSCacheMisses
130
      );
131
      
123 132
      /**
124 133
       * Attempts to establish a connection with the data source of the {@code _temp} database.
125 134
       * Uses the credentials from the {@code DatabaseManager} configuration.
......
231 240
                     PreparedStatement raw = ctx.physicalConn.prepareStatement(sql, resultSetType, resultSetConcurrency);
232 241
                     ps = new UnclosablePreparedStatement(raw, false);
233 242
                     ctx.psCache.put(key, ps);
243
                     PSCacheMisses.update(1L);
234 244
                  }
235 245
                  else if (ps.isCheckedOut())
236 246
                  {
......
243 253
                     {
244 254
                        LOG.log(Level.FINE, "Multiply-cached PreparedStatement: " + sql);
245 255
                     }
256
                     PSCacheMisses.update(1L);
257
                  }
258
                  else 
259
                  {
260
                     PSCacheHits.update(1L);
246 261
                  }
247 262
                  
248 263
                  ps.checkOut();