Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions doc/pgjdbc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,39 @@ openssl pkcs8 -topk8 -in client.key -out client.pk8 -outform DER -v1 PBE-SHA1-3D
</listitem>
</varlistentry>

<varlistentry>
<term><varname>preparedStatementCacheQueries</varname> = <type>int</type></term>
<listitem>
<para>
Determine the number of queries that are cached in each connection.
The default is 256, meaning if you use more than 256 different queries
in <function>prepareStatement()</function> calls, the least recently used ones
will be discarded. The cache allows application to benefit from <xref linkend="server-prepare" />
(see <varname>prepareThreshold</varname>) even if the prepared statement is
closed after each execution. The value of 0 disables the cache.
<note>
<para>
Each connection has its own statement cache.
</para>
</note>
</para>
</listitem>
</varlistentry>

<varlistentry>
<term><varname>preparedStatementCacheSizeMiB</varname> = <type>int</type></term>
<listitem>
<para>
Determine the maximum size (in mebibytes) of the prepared queries cache
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean mega bytes ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure he does mean mebibytes. It explicitly means 2^20 vs 10^6.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to use this ? Seems a bit esoteric ?

Dave Cramer

On 28 June 2015 at 11:20, Sehrope Sarkuni [email protected] wrote:

In doc/pgjdbc.xml
#319 (comment):

  •     (see <varname>prepareThreshold</varname>) even if the prepared statement is
    
  •     closed after each execution. The value of 0 disables the cache.
    
  •     <note>
    
  •      <para>
    
  •       Each connection has its own statement cache.
    
  •      </para>
    
  •     </note>
    
  •    </para>
    
  •   </listitem>
    
  •  </varlistentry>
    
  •  <varlistentry>
    
  •   <term><varname>preparedStatementCacheSizeMiB</varname> = <type>int</type></term>
    
  •   <listitem>
    
  •    <para>
    
  •     Determine the maximum size (in mebibytes) of the prepared queries cache
    

Pretty sure he does mean mebibytes. It explicitly means 2^20 vs 10^6.


Reply to this email directly or view it on GitHub
https://github.com/pgjdbc/pgjdbc/pull/319/files#r33423738.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well technically it's the correct term for it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dave Cramer

On 28 June 2015 at 12:02, Sehrope Sarkuni [email protected] wrote:

In doc/pgjdbc.xml
#319 (comment):

  •     (see <varname>prepareThreshold</varname>) even if the prepared statement is
    
  •     closed after each execution. The value of 0 disables the cache.
    
  •     <note>
    
  •      <para>
    
  •       Each connection has its own statement cache.
    
  •      </para>
    
  •     </note>
    
  •    </para>
    
  •   </listitem>
    
  •  </varlistentry>
    
  •  <varlistentry>
    
  •   <term><varname>preparedStatementCacheSizeMiB</varname> = <type>int</type></term>
    
  •   <listitem>
    
  •    <para>
    
  •     Determine the maximum size (in mebibytes) of the prepared queries cache
    

Well technically it's the correct term for it.

Yes, but not very well known.


Reply to this email directly or view it on GitHub
https://github.com/pgjdbc/pgjdbc/pull/319/files#r33424088.

(see <varname>preparedStatementCacheQueries</varname>).
The default is 5, meaning if you happen to cache more than 5 MiB of queries
the least recently used ones will be discarded.
The main aim of this setting is to prevent <classname>OutOfMemoryError</classname>.
The value of 0 disables the cache.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term><varname>defaultRowFetchSize</varname> = <type>int</type></term>
<listitem>
Expand Down
10 changes: 10 additions & 0 deletions org/postgresql/PGProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ public enum PGProperty
*/
PREPARE_THRESHOLD("prepareThreshold", "5", "Statement prepare threshold. A value of {@code -1} stands for forceBinary"),

/**
* Specifies the maximum number of entries in cache of prepared statements. A value of {@code 0} disables the cache.
*/
PREPARED_STATEMENT_CACHE_QUERIES("preparedStatementCacheQueries", "256", "Specifies the maximum number of entries in per-connection cache of prepared statements. A value of {@code 0} disables the cache."),

/**
* Specifies the maximum size (in megabytes) of the prepared statement cache. A value of {@code 0} disables the cache.
*/
PREPARED_STATEMENT_CACHE_SIZE_MIB("preparedStatementCacheSizeMiB", "5", "Specifies the maximum size (in megabytes) of a per-connection prepared statement cache. A value of {@code 0} disables the cache."),

/**
* Default parameter for {@link java.sql.Statement#getFetchSize()}. A value of {@code 0} means that need fetch all rows at once
*/
Expand Down
60 changes: 60 additions & 0 deletions org/postgresql/core/CachedQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*-------------------------------------------------------------------------
*
* Copyright (c) 2015, PostgreSQL Global Development Group
*
*
*-------------------------------------------------------------------------
*/
package org.postgresql.core;

import org.postgresql.util.CanEstimateSize;

/**
* Stores information on the parsed JDBC query.
* It is used to cut parsing overhead when executing the same query through {@link java.sql.Connection#prepareStatement(String)}.
*/
public class CachedQuery implements CanEstimateSize {
/**
* Cache key. {@link String} or {@link org.postgresql.jdbc2.CallableQueryKey}
*/
public final Object key;
public final Query query;
public final boolean isFunction;
public final boolean outParmBeforeFunc;

private int executeCount;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is shared between threads. This should probably be an AtomicInteger?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CachedQuery is not yet shared between threads. Remember: queries are cached per-connection. No global cache yet exists.
Even if the sharing existed, we do not need precise counter here, so it is fine to have just int here.


public CachedQuery(Object key, Query query, boolean isFunction, boolean outParmBeforeFunc)
{
this.key = key;
this.query = query;
this.isFunction = isFunction;
this.outParmBeforeFunc = outParmBeforeFunc;
}

public void increaseExecuteCount() {
if (executeCount < Integer.MAX_VALUE)
executeCount++;
}

public void increaseExecuteCount(int inc) {
int newValue = executeCount + inc;
if (newValue > 0) // if overflows, just ignore the update
executeCount = newValue;
}

/**
* Number of times this statement has been used
* @return number of times this statement has been used
*/
public int getExecuteCount() {
return executeCount;
}

@Override
public long getSize()
{
int queryLength = String.valueOf(key).length() * 2 /* 2 bytes per char */;
return queryLength * 2 /* original query and native sql */ + 100 /* entry in hash map, CachedQuery wrapper, etc */;
}
}
77 changes: 77 additions & 0 deletions org/postgresql/core/NativeQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*-------------------------------------------------------------------------
*
* Copyright (c) 2003-2014, PostgreSQL Global Development Group
* 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.
*/
public class NativeQuery {
private final static String[] BIND_NAMES = new String[128];
private final static int[] NO_BINDS = new int[0];

public final String nativeSql;
public final int[] bindPositions;

static
{
for (int i = 1; i < BIND_NAMES.length; i++)
{
BIND_NAMES[i] = "$" + i;
}
}

public NativeQuery(String nativeSql)
{
this(nativeSql, NO_BINDS);
}

public NativeQuery(String nativeSql, int[] bindPositions)
{
this.nativeSql = nativeSql;
this.bindPositions = bindPositions == null || bindPositions.length == 0 ? NO_BINDS : bindPositions;
}

/**
* 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</code> 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;

StringBuilder sbuf = new StringBuilder(nativeSql.length());
sbuf.append(nativeSql, 0, bindPositions[0]);
for (int i = 1; i <= bindPositions.length; ++i)
{
if (parameters == null)
sbuf.append('?');
else
sbuf.append(parameters.toString(i));
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.
* @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;
}
}
Loading