/*
 * Copyright (c) 2003, PostgreSQL Global Development Group
 * See the LICENSE file in the project root for more information.
 */
// Copyright (c) 2004, Open Cloud Limited.

package org.postgresql.core;

Represents a query that is ready for execution by backend. The main difference from JDBC is ? are replaced with $1, $2, etc.
/** * Represents a query that is ready for execution by backend. The main difference from JDBC is ? are * replaced with $1, $2, etc. */
public class NativeQuery { private static final String[] BIND_NAMES = new String[128 * 10]; private static final int[] NO_BINDS = new int[0]; public final String nativeSql; public final int[] bindPositions; public final SqlCommand command; public final boolean multiStatement; static { for (int i = 1; i < BIND_NAMES.length; i++) { BIND_NAMES[i] = "$" + i; } } public NativeQuery(String nativeSql, SqlCommand dml) { this(nativeSql, NO_BINDS, true, dml); } public NativeQuery(String nativeSql, int[] bindPositions, boolean multiStatement, SqlCommand dml) { this.nativeSql = nativeSql; this.bindPositions = bindPositions == null || bindPositions.length == 0 ? NO_BINDS : bindPositions; this.multiStatement = multiStatement; this.command = dml; }
Stringize this query to a human-readable form, substituting particular parameter values for parameter placeholders.
Params:
  • parameters – a ParameterList returned by this Query's Query.createParameterList method, or null to leave the parameter placeholders unsubstituted.
Returns:a human-readable representation of this query
/** * Stringize this query to a human-readable form, substituting particular parameter values for * parameter placeholders. * * @param parameters a ParameterList returned by this Query's {@link Query#createParameterList} * method, or {@code null} to leave the parameter placeholders unsubstituted. * @return a human-readable representation of this query */
public String toString(ParameterList parameters) { if (bindPositions.length == 0) { return nativeSql; } int queryLength = nativeSql.length(); String[] params = new String[bindPositions.length]; for (int i = 1; i <= bindPositions.length; ++i) { String param = parameters == null ? "?" : parameters.toString(i, true); params[i - 1] = param; queryLength += param.length() - bindName(i).length(); } StringBuilder sbuf = new StringBuilder(queryLength); sbuf.append(nativeSql, 0, bindPositions[0]); for (int i = 1; i <= bindPositions.length; ++i) { sbuf.append(params[i - 1]); int nextBind = i < bindPositions.length ? bindPositions[i] : nativeSql.length(); sbuf.append(nativeSql, bindPositions[i - 1] + bindName(i).length(), nextBind); } return sbuf.toString(); }
Returns $1, $2, etc names of bind variables used by backend.
Params:
  • index – index of a bind variable
Returns:bind variable name
/** * Returns $1, $2, etc names of bind variables used by backend. * * @param index index of a bind variable * @return bind variable name */
public static String bindName(int index) { return index < BIND_NAMES.length ? BIND_NAMES[index] : "$" + index; } public static StringBuilder appendBindName(StringBuilder sb, int index) { if (index < BIND_NAMES.length) { return sb.append(bindName(index)); } sb.append('$'); sb.append(index); return sb; }
Calculate the text length required for the given number of bind variables including dollars. Do this to avoid repeated calls to AbstractStringBuilder.expandCapacity(...) and Arrays.copyOf
Params:
  • bindCount – total number of parameters in a query
Returns:int total character length for $xyz kind of binds
/** * Calculate the text length required for the given number of bind variables * including dollars. * Do this to avoid repeated calls to * AbstractStringBuilder.expandCapacity(...) and Arrays.copyOf * * @param bindCount total number of parameters in a query * @return int total character length for $xyz kind of binds */
public static int calculateBindLength(int bindCount) { int res = 0; int bindLen = 2; // $1 int maxBindsOfLen = 9; // $0 .. $9 while (bindCount > 0) { int numBinds = Math.min(maxBindsOfLen, bindCount); bindCount -= numBinds; res += bindLen * numBinds; bindLen++; maxBindsOfLen *= 10; // $0..$9 (9 items) -> $10..$99 (90 items) } return res; } public SqlCommand getCommand() { return command; } }