Compare commits

..

No commits in common. "v6.0.0" and "master" have entirely different histories.

54 changed files with 610 additions and 3425 deletions

View File

@ -612,17 +612,6 @@ public enum PGProperty {
B_CMPT_MODE("BCmptMode", "true", "Specify 'dolphin.b_compatibility_mode'"
+ " connection initialization parameter."),
/**
* Configure bit type format of b database, value include dec,bin,hex.
*/
BIT_OUTPUT("bitOutput", null, "Specify 'dolphin.bit_output' connection initialization parameter."),
/**
* Determine whether SAVEPOINTS used in AUTOSAVE will be released per query or not
*/
CLEANUP_SAVEPOINTS("cleanupSavepoints", "false", "Determine whether SAVEPOINTS "
+ "used in AUTOSAVE will be released per query or not", false, new String[]{"true", "false"})
;
private String _name;

View File

@ -10,7 +10,6 @@ import org.postgresql.jdbc.ClientLogic;
import org.postgresql.jdbc.FieldMetadata;
import org.postgresql.jdbc.PgStatement;
import org.postgresql.jdbc.TimestampUtils;
import org.postgresql.jdbc.PgDatabase;
import org.postgresql.log.Log;
import org.postgresql.util.LruCache;
import org.postgresql.xml.PGXmlFactoryFactory;
@ -247,6 +246,4 @@ public interface BaseConnection extends PGConnection, Connection {
public boolean IsBatchInsert();
public boolean isAdaptiveSetSQLType();
PgDatabase getPgDatabase();
}

View File

@ -13,7 +13,6 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import org.postgresql.log.Logger;
import org.postgresql.log.Log;
@ -28,7 +27,7 @@ public class Encoding {
private static Log LOGGER = Logger.getLogger(Encoding.class.getName());
private static final Encoding DEFAULT_ENCODING = new Encoding();
private static final Encoding UTF8_ENCODING = new Encoding(StandardCharsets.UTF_8, true);
private static final Encoding UTF8_ENCODING = new Encoding("UTF-8");
/*
* Preferred JVM encodings for backend encodings.
@ -80,42 +79,27 @@ public class Encoding {
encodings.put("LATIN10", new String[0]);
}
private final Charset encoding;
private final String encoding;
private final boolean fastASCIINumbers;
/**
* Uses the default charset of the JVM.
*/
private Encoding() {
this(Charset.defaultCharset());
this(Charset.defaultCharset().name());
}
/**
* Use the charset passed as parameter and tests at creation time whether
* the specified encoding is compatible with ASCII numbers.
* Use the charset passed as parameter.
*
* @param encoding charset name to use
*/
private Encoding(Charset encoding) {
this(encoding, testAsciiNumbers(encoding));
}
/**
* Subclasses may use this constructor if they know in advance of their
* ASCII number compatibility.
*
* @param encoding charset name to use
* @param isFastASCIINumbers whether this encoding is compatible with ASCII numbers.
*/
private Encoding(Charset encoding, boolean isFastASCIINumbers) {
protected Encoding(String encoding) {
if (encoding == null) {
throw new NullPointerException("Null encoding charset not supported");
}
this.encoding = encoding;
this.fastASCIINumbers = isFastASCIINumbers;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Creating new Encoding " + encoding + " with fastASCIINumbers " + isFastASCIINumbers);
}
fastASCIINumbers = testAsciiNumbers();
}
/**
@ -136,13 +120,11 @@ public class Encoding {
* default JVM encoding if the specified encoding is unavailable.
*/
public static Encoding getJVMEncoding(String jvmEncoding) {
if ("UTF-8".equals(jvmEncoding)) {
return UTF8_ENCODING;
}
if (Charset.isSupported(jvmEncoding)) {
return new Encoding(Charset.forName(jvmEncoding));
return new Encoding(jvmEncoding);
} else {
return DEFAULT_ENCODING;
}
return DEFAULT_ENCODING;
}
/**
@ -153,7 +135,7 @@ public class Encoding {
* default JVM encoding if the specified encoding is unavailable.
*/
public static Encoding getDatabaseEncoding(String databaseEncoding) {
if ("UTF8".equals(databaseEncoding) || "UNICODE".equals(databaseEncoding)) {
if ("UTF8".equals(databaseEncoding)) {
return UTF8_ENCODING;
}
// If the backend encoding is known and there is a suitable
@ -162,11 +144,9 @@ public class Encoding {
String[] candidates = encodings.get(databaseEncoding);
if (candidates != null) {
for (String candidate : candidates) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Search encoding candidate " + candidate);
}
LOGGER.trace("Search encoding candidate " + candidate);
if (Charset.isSupported(candidate)) {
return new Encoding(Charset.forName(candidate));
return new Encoding(candidate);
}
}
}
@ -174,13 +154,11 @@ public class Encoding {
// Try the encoding name directly -- maybe the charset has been
// provided by the user.
if (Charset.isSupported(databaseEncoding)) {
return new Encoding(Charset.forName(databaseEncoding));
return new Encoding(databaseEncoding);
}
// Fall back to default JVM encoding.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(databaseEncoding + " encoding not found, returning default encoding");
}
LOGGER.trace(databaseEncoding + " encoding not found, returning default encoding");
return DEFAULT_ENCODING;
}
@ -190,7 +168,7 @@ public class Encoding {
* @return the JVM encoding name used by this instance.
*/
public String name() {
return encoding.name();
return Charset.isSupported(encoding) ? Charset.forName(encoding).name() : encoding;
}
/**
@ -264,25 +242,30 @@ public class Encoding {
return DEFAULT_ENCODING;
}
@Override
public String toString() {
return encoding.name();
return encoding;
}
/**
* Checks weather this encoding is compatible with ASCII for the number characters '-' and
* '0'..'9'. Where compatible means that they are encoded with exactly same values.
*
* @param encoding current encoding
* @return If faster ASCII number parsing can be used with this encoding.
*/
private static boolean testAsciiNumbers(Charset encoding) {
private boolean testAsciiNumbers() {
// TODO: test all postgres supported encoding to see if there are
// any which do _not_ have ascii numbers in same location
// at least all the encoding listed in the encodings hashmap have
// working ascii numbers
String test = "-0123456789";
byte[] bytes = test.getBytes(encoding);
String res = new String(bytes, StandardCharsets.US_ASCII);
return test.equals(res);
try {
String test = "-0123456789";
byte[] bytes = encode(test);
String res = new String(bytes, "US-ASCII");
return test.equals(res);
} catch (java.io.UnsupportedEncodingException e) {
return false;
} catch (IOException e) {
return false;
}
}
}

View File

@ -228,19 +228,6 @@ public class PGStream implements Closeable, Flushable {
pg_output.write(_int4buf);
}
/**
* Sends a Long to the back end.
*
* @param val the long to be sent
* @throws IOException if an I/O error occurs
*/
public void sendLong(long val) throws IOException {
int high = (int)(val >> 32);
int low = (int)(val & 0xffffffff);
sendInteger4(high);
sendInteger4(low);
}
/**
* Sends a 2-byte integer (short) to the back end.
*
@ -340,18 +327,6 @@ public class PGStream implements Closeable, Flushable {
| _int4buf[3] & 0xFF;
}
/**
* Receives a Long from the backend.
*
* @return the 64bit integer received from the backend
* @throws IOException if an I/O error occurs
*/
public long receiveLong() throws IOException {
long high = receiveInteger4();
long low = receiveInteger4();
return (high << 32) | low;
}
/**
* Receives a two byte integer from the backend.
*

View File

@ -90,12 +90,8 @@ public abstract class QueryExecutorBase implements QueryExecutor {
});
}
protected abstract void sendSupportTrace() throws IOException;
protected abstract void sendCloseMessage() throws IOException;
protected abstract void sendTrace() throws IOException;
@Override
public void setNetworkTimeout(int milliseconds) throws IOException {
pgStream.setNetworkTimeout(milliseconds);
@ -150,7 +146,6 @@ public abstract class QueryExecutorBase implements QueryExecutor {
try {
LOGGER.trace(" FE=> Terminate");
sendTrace();
sendCloseMessage();
pgStream.flush();
pgStream.close();

View File

@ -42,6 +42,13 @@ public interface TypeInfo {
*/
void setPGTypes() throws SQLException;
/**
* cache db type, A/B/C/PG
* cache b_compatibility_mode, on or off
* @return
*/
void setDBType() throws SQLException;
/**
* Look up the oid for a given postgresql type name. This is the inverse of
* {@link #getPGType(int)}.

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2003, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package org.postgresql.core;
import org.postgresql.util.GT;
import java.io.IOException;
class UTF8Encoding extends Encoding {
private static final int MIN_2_BYTES = 0x80;
private static final int MIN_3_BYTES = 0x800;
private static final int MIN_4_BYTES = 0x10000;
private static final int MAX_CODE_POINT = 0x10ffff;
private char[] decoderArray = new char[1024];
UTF8Encoding(String jvmEncoding) {
super(jvmEncoding);
}
// helper for decode
private static void checkByte(int ch, int pos, int len) throws IOException {
if ((ch & 0xc0) != 0x80) {
throw new IOException(
GT.tr("Illegal UTF-8 sequence: byte {0} of {1} byte sequence is not 10xxxxxx: {2}",
pos, len, ch));
}
}
private static void checkMinimal(int ch, int minValue) throws IOException {
if (ch >= minValue) {
return;
}
int actualLen;
switch (minValue) {
case MIN_2_BYTES:
actualLen = 2;
break;
case MIN_3_BYTES:
actualLen = 3;
break;
case MIN_4_BYTES:
actualLen = 4;
break;
default:
throw new IllegalArgumentException(
"unexpected minValue passed to checkMinimal: " + minValue);
}
int expectedLen;
if (ch < MIN_2_BYTES) {
expectedLen = 1;
} else if (ch < MIN_3_BYTES) {
expectedLen = 2;
} else if (ch < MIN_4_BYTES) {
expectedLen = 3;
} else {
throw new IllegalArgumentException("unexpected ch passed to checkMinimal: " + ch);
}
throw new IOException(
GT.tr("Illegal UTF-8 sequence: {0} bytes used to encode a {1} byte value: {2}",
actualLen, expectedLen, ch));
}
/**
* Custom byte[] -> String conversion routine for UTF-8 only. This is about twice as fast as using
* the String(byte[],int,int,String) ctor, at least under JDK 1.4.2. The extra checks for illegal
* representations add about 10-15% overhead, but they seem worth it given the number of SQL_ASCII
* databases out there.
*
* @param data the array containing UTF8-encoded data
* @param offset the offset of the first byte in {@code data} to decode from
* @param length the number of bytes to decode
* @return a decoded string
* @throws IOException if something goes wrong
*/
@Override
public synchronized String decode(byte[] data, int offset, int length) throws IOException {
char[] cdata = decoderArray;
if (cdata.length < length) {
cdata = decoderArray = new char[length];
}
int in = offset;
int out = 0;
int end = length + offset;
try {
while (in < end) {
int ch = data[in++] & 0xff;
// Convert UTF-8 to 21-bit codepoint.
if (ch < 0x80) {
// 0xxxxxxx -- length 1.
} else if (ch < 0xc0) {
// 10xxxxxx -- illegal!
throw new IOException(GT.tr("Illegal UTF-8 sequence: initial byte is {0}: {1}",
"10xxxxxx", ch));
} else if (ch < 0xe0) {
// 110xxxxx 10xxxxxx
ch = ((ch & 0x1f) << 6);
checkByte(data[in], 2, 2);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_2_BYTES);
} else if (ch < 0xf0) {
// 1110xxxx 10xxxxxx 10xxxxxx
ch = ((ch & 0x0f) << 12);
checkByte(data[in], 2, 3);
ch = ch | ((data[in++] & 0x3f) << 6);
checkByte(data[in], 3, 3);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_3_BYTES);
} else if (ch < 0xf8) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
ch = ((ch & 0x07) << 18);
checkByte(data[in], 2, 4);
ch = ch | ((data[in++] & 0x3f) << 12);
checkByte(data[in], 3, 4);
ch = ch | ((data[in++] & 0x3f) << 6);
checkByte(data[in], 4, 4);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_4_BYTES);
} else {
throw new IOException(GT.tr("Illegal UTF-8 sequence: initial byte is {0}: {1}",
"11111xxx", ch));
}
if (ch > MAX_CODE_POINT) {
throw new IOException(
GT.tr("Illegal UTF-8 sequence: final value is out of range: {0}", ch));
}
// Convert 21-bit codepoint to Java chars:
// 0..ffff are represented directly as a single char
// 10000..10ffff are represented as a "surrogate pair" of two chars
// See: http://java.sun.com/developer/technicalArticles/Intl/Supplementary/
if (ch > 0xffff) {
// Use a surrogate pair to represent it.
ch -= 0x10000; // ch is now 0..fffff (20 bits)
cdata[out++] = (char) (0xd800 + (ch >> 10)); // top 10 bits
cdata[out++] = (char) (0xdc00 + (ch & 0x3ff)); // bottom 10 bits
} else if (ch >= 0xd800 && ch < 0xe000) {
// Not allowed to encode the surrogate range directly.
throw new IOException(
GT.tr("Illegal UTF-8 sequence: final value is a surrogate value: {0}", ch));
} else {
// Normal case.
cdata[out++] = (char) ch;
}
}
} catch (ArrayIndexOutOfBoundsException a) {
throw new IOException("Illegal UTF-8 sequence: multibyte sequence was truncated");
}
// Check if we ran past the end without seeing an exception.
if (in > end) {
throw new IOException("Illegal UTF-8 sequence: multibyte sequence was truncated");
}
return new String(cdata, 0, out);
}
}

View File

@ -126,16 +126,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
private String clientEncoding;
private long sendTime;
private long recvTime;
private long netTime;
private boolean enableTrace = false;
private boolean waitNexttime = false;
/**
* {@code CommandComplete(B)} messages are quite common, so we reuse instance to parse those
*/
@ -167,18 +157,11 @@ public class QueryExecutorImpl extends QueryExecutorBase {
private static final String OFF = "off";
private static final String GUC_SERVER_SUPPORT_TRACE = "enable_record_nettime";
private static final int PROTOCOL3_MSGLEN_OFFSET = 4;
private static final int TIME_NS_ONE_US = 1000;
public QueryExecutorImpl(PGStream pgStream, String user, String database,
int cancelSignalTimeout, Properties info) throws SQLException, IOException {
super(pgStream, user, database, cancelSignalTimeout, info);
this.allowEncodingChanges = PGProperty.ALLOW_ENCODING_CHANGES.getBoolean(info);
this.cleanupSavePoints = PGProperty.CLEANUP_SAVEPOINTS.getBoolean(info);
this.replicationProtocol = new V3ReplicationProtocol(this, pgStream);
this.socketAddress = pgStream.getConnectInfo();
this.secSocketAddress = pgStream.getSecConnectInfo();
@ -239,14 +222,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
return this.clientEncoding;
}
public boolean getWaitNexttime() {
return waitNexttime;
}
public void setWaitNexttime(boolean waitNexttime) {
this.waitNexttime = waitNexttime;
}
/**
* When database compatibility mode is A database and the parameter overload function
* is turned on, add out parameter description message.
@ -319,14 +294,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
}
}
private void recordSendTime() {
sendTime = System.nanoTime();
}
private void recordRecvTime() {
recvTime = System.nanoTime();
}
/**
* @param holder object assumed to hold the lock
* @return whether given object actually holds the lock
@ -396,10 +363,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
}
}
private boolean isSimpleQuery(int flags) {
return (flags & QueryExecutor.QUERY_EXECUTE_AS_SIMPLE) != 0;
}
public synchronized void execute(Query query, ParameterList parameters, ResultHandler handler,
int maxRows, int fetchSize, int flags) throws SQLException {
waitOnLock();
@ -425,7 +388,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
boolean autosave = false;
try {
try {
recordAndSendTrace(flags);
handler = sendQueryPreamble(handler, flags);
autosave = sendAutomaticSavepoint(query, flags);
sendQuery(query, (V3ParameterList) parameters, maxRows, fetchSize, flags,
@ -470,26 +432,11 @@ public class QueryExecutorImpl extends QueryExecutorBase {
try {
handler.handleCompletion();
if (cleanupSavePoints) {
releaseSavePoint(autosave, flags);
}
} catch (SQLException e) {
rollbackIfRequired(autosave, e);
}
}
private void releaseSavePoint(boolean autosave, int flags) throws SQLException {
if (autosave && getAutoSave() == AutoSave.ALWAYS
&& getTransactionState() == TransactionState.OPEN) {
try {
sendOneQuery(releaseAutoSave, SimpleQuery.NO_PARAMETERS, 1, 0,
QUERY_NO_RESULTS | QUERY_NO_METADATA | QUERY_EXECUTE_AS_SIMPLE);
} catch (IOException ex) {
throw new PSQLException(GT.tr("Error releasing savepoint"), PSQLState.IO_ERROR);
}
}
}
private boolean sendAutomaticSavepoint(Query query, int flags) throws IOException {
if (((flags & QueryExecutor.QUERY_SUPPRESS_BEGIN) == 0
|| getTransactionState() == TransactionState.OPEN)
@ -599,7 +546,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
boolean autosave = false;
ResultHandler handler = batchHandler;
try {
recordAndSendTrace(flags);
handler = sendQueryPreamble(batchHandler, flags);
autosave = sendAutomaticSavepoint(queries[0], flags);
estimatedReceiveBufferBytes = 0;
@ -638,9 +584,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
try {
handler.handleCompletion();
if (cleanupSavePoints) {
releaseSavePoint(autosave, flags);
}
} catch (SQLException e) {
rollbackIfRequired(autosave, e);
}
@ -676,8 +619,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
boolean autosave = false;
ResultHandler handler = batchHandler;
try {
// P->DS->S U->E->S
recordAndSendTrace(flags);
handler = sendQueryPreamble(batchHandler, flags);
autosave = sendAutomaticSavepoint(queries[0], flags);
estimatedReceiveBufferBytes = 0;
@ -707,9 +648,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
try {
handler.handleCompletion();
if (cleanupSavePoints) {
releaseSavePoint(autosave, flags);
}
} catch (SQLException e) {
rollbackIfRequired(autosave, e);
}
@ -810,7 +748,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
};
try {
recordAndSendTrace(QueryExecutor.QUERY_NO_METADATA);
sendOneQuery(beginTransactionQuery, SimpleQuery.NO_PARAMETERS, 0, 0,
QueryExecutor.QUERY_NO_METADATA);
sendSync();
@ -1627,32 +1564,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
}
}
//
// record sendTime and send K message.
//
private void recordAndSendTrace(int flags) throws IOException {
if (!isSimpleQuery(flags)) {
recordSendTime();
}
sendTrace();
}
//
// send netTime to database
//
protected void sendTrace() throws IOException {
if (!enableTrace) {
return;
}
pgStream.sendChar('K'); // Sync
pgStream.sendInteger4(8 + PROTOCOL3_MSGLEN_OFFSET); // Length
if (getWaitNexttime()) {
pgStream.sendLong(0L);
return;
}
pgStream.sendLong(netTime);
}
//
// Message sending
//
@ -2231,12 +2142,11 @@ public class QueryExecutorImpl extends QueryExecutorBase {
//
private void sendOneQuery(SimpleQuery query, SimpleParameterList params, int maxRows,
int fetchSize, int flags) throws IOException {
boolean asSimple = isSimpleQuery(flags);
boolean asSimple = (flags & QueryExecutor.QUERY_EXECUTE_AS_SIMPLE) != 0;
if (asSimple) {
assert (flags & QueryExecutor.QUERY_DESCRIBE_ONLY) == 0
: "Simple mode does not support describe requests. sql = " + query.getNativeSql()
+ ", flags = " + flags;
recordSendTime();
sendSimpleQuery(query, params);
return;
}
@ -2535,25 +2445,10 @@ public class QueryExecutorImpl extends QueryExecutorBase {
// from there.
boolean doneAfterRowDescNoData = false;
try {
boolean isRecvP = false;
while (!endQuery) {
c = pgStream.receiveChar();
recievedPacketType=c;
switch (c) {
case 'K': //receive dbTime
recordRecvTime();
int msgLen = pgStream.receiveInteger4();
// dbTime 8 bytes
assert (msgLen == 8 + PROTOCOL3_MSGLEN_OFFSET);
long dbTime = pgStream.receiveLong();
if (getWaitNexttime()) {
netTime += ((recvTime - sendTime) / TIME_NS_ONE_US) - dbTime;
} else {
netTime = ((recvTime - sendTime) / TIME_NS_ONE_US) - dbTime;
}
isRecvP = true;
break;
case 'A': // Asynchronous Notify
receiveAsyncNotify();
break;
@ -2698,8 +2593,8 @@ public class QueryExecutorImpl extends QueryExecutorBase {
// For simple 'Q' queries, executeQueue is cleared via ReadyForQuery message
}
if (currentQuery == autoSaveQuery || currentQuery == releaseAutoSave) {
// ignore "SAVEPOINT" or RELEASE SAVEPOINT status from autosave query
if (currentQuery == autoSaveQuery) {
// ignore "SAVEPOINT" status from autosave query
break;
}
@ -2941,7 +2836,7 @@ public class QueryExecutorImpl extends QueryExecutorBase {
throw new IOException("Unexpected packet type: " + c);
}
}
enableTrace = isRecvP;
} catch(IOException e) {
LOGGER.error("IO Exception.recieved packetType:" + recievedPacketType + "last PacketType:" + lastPacketType
+ "connection info:" + secSocketAddress + "buffer :\n" + pgStream.getInputBufferByHex());
@ -2982,7 +2877,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
processDeadParsedQueries();
processDeadPortals();
recordAndSendTrace(0);
sendExecute(portal.getQuery(), portal, fetchSize);
sendSync();
@ -3022,9 +2916,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
}
int typeLength = pgStream.receiveInteger2();
int typeModifier = pgStream.receiveInteger4();
if (typeOid == Oid.INT1 && typeModifier == 1) {
typeOid = Oid.BIT;
}
int formatType = pgStream.receiveInteger2();
fields[i] = new Field(columnLabel,
typeOid, typeLength, typeModifier, tableOid, positionInTable);
@ -3165,12 +3056,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
}
}
protected void sendSupportTrace() throws IOException {
pgStream.sendChar('V');
pgStream.sendInteger4(4);
pgStream.flush();
}
@Override
protected void sendCloseMessage() throws IOException {
pgStream.sendChar('X');
@ -3237,11 +3122,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
String name = pgStream.receiveString();
String value = pgStream.receiveString();
if (name.equals(GUC_SERVER_SUPPORT_TRACE)) {
// receive GUC_SERVER_SUPPORT_TRACE from server means server support trace
sendSupportTrace();
}
if (name.equals(CLIENT_ENCODING)) {
if (allowEncodingChanges) {
if (!value.equalsIgnoreCase("UTF8") && !value.equalsIgnoreCase("GBK")) {
@ -3411,7 +3291,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
private long nextUniqueID = 1;
private final boolean allowEncodingChanges;
private final boolean cleanupSavePoints;
private String output = "";
@ -3441,11 +3320,6 @@ public class QueryExecutorImpl extends QueryExecutorBase {
new NativeQuery("SAVEPOINT PGJDBC_AUTOSAVE", new int[0], false, SqlCommand.BLANK),
null, false);
private final SimpleQuery releaseAutoSave =
new SimpleQuery(
new NativeQuery("RELEASE SAVEPOINT PGJDBC_AUTOSAVE", new int[0], false, SqlCommand.BLANK),
null, false);
private final SimpleQuery restoreToAutoSave =
new SimpleQuery(
new NativeQuery("ROLLBACK TO SAVEPOINT PGJDBC_AUTOSAVE", new int[0], false, SqlCommand.BLANK),

View File

@ -229,142 +229,93 @@ class SimpleParameterList implements V3ParameterList {
bind(index, NULL_OBJECT, oid, binaryTransfer);
}
/**
* <p>Escapes a given text value as a literal, wraps it in single quotes, casts it to the
* to the given data type, and finally wraps the whole thing in parentheses.</p>
*
* <p>For example, "123" and "int4" becomes "('123'::int)"</p>
*
* <p>The additional parentheses is added to ensure that the surrounding text of where the
* parameter value is entered does modify the interpretation of the value.</p>
*
* <p>For example if our input SQL is: <code>SELECT ?b</code></p>
*
* <p>Using a parameter value of '{}' and type of json we'd get:</p>
*
* <pre>
* test=# SELECT ('{}'::json)b;
* b
* ----
* {}
* </pre>
*
* <p>But without the parentheses the result changes:</p>
*
* <pre>
* test=# SELECT '{}'::jsonb;
* jsonb
* -------
* {}
* </pre>
**/
private static String quoteAndCast(String text, String type, boolean standardConformingStrings) {
StringBuilder sb = new StringBuilder((text.length() + 10) / 10 * 11); // Add 10% for escaping.
sb.append("('");
try {
Utils.escapeLiteral(sb, text, standardConformingStrings);
} catch (SQLException e) {
// This should only happen if we have an embedded null
// and there's not much we can do if we do hit one.
//
// To force a server side failure, we deliberately include
// a zero byte character in the literal to force the server
// to reject the command.
sb.append('\u0000');
}
sb.append("'");
if (type != null) {
sb.append("::");
sb.append(type);
}
sb.append(")");
return sb.toString();
}
@Override
public String toString(int index, boolean standardConformingStrings) {
--index;
Object paramValue = paramValues[index];
if (paramValues[index] == null) {
return "?";
} else if (paramValues[index] == NULL_OBJECT) {
return "(NULL)";
return "NULL";
} else if ((flags[index] & BINARY) == BINARY) {
// handle some of the numeric types
switch (paramTypes[index]) {
case Oid.INT2:
short s = ByteConverter.int2((byte[]) paramValues[index], 0);
return quoteAndCast(Short.toString(s), "int2", standardConformingStrings);
return Short.toString(s);
case Oid.INT4:
int i = ByteConverter.int4((byte[]) paramValues[index], 0);
return quoteAndCast(Integer.toString(i), "int4", standardConformingStrings);
return Integer.toString(i);
case Oid.INT8:
long l = ByteConverter.int8((byte[]) paramValues[index], 0);
return quoteAndCast(Long.toString(l), "int8", standardConformingStrings);
return Long.toString(l);
case Oid.FLOAT4:
float f = ByteConverter.float4((byte[]) paramValues[index], 0);
if (Float.isNaN(f)) {
return "('NaN'::real)";
}
return quoteAndCast(Float.toString(f), "float", standardConformingStrings);
return Float.toString(f);
case Oid.FLOAT8:
double d = ByteConverter.float8((byte[]) paramValues[index], 0);
if (Double.isNaN(d)) {
return "('NaN'::double precision)";
}
return quoteAndCast(Double.toString(d), "double precision", standardConformingStrings);
case Oid.NUMERIC:
Number n = ByteConverter.numeric((byte[]) paramValue);
if (n instanceof Double) {
assert ((Double) n).isNaN();
return "('NaN'::numeric)";
}
return n.toString();
return Double.toString(d);
case Oid.UUID:
String uuid =
new UUIDArrayAssistant().buildElement((byte[]) paramValues[index], 0, 16).toString();
return quoteAndCast(uuid, "uuid", standardConformingStrings);
new UUIDArrayAssistant().buildElement((byte[]) paramValues[index], 0, 16).toString();
return "'" + uuid + "'::uuid";
case Oid.POINT:
PGpoint pgPoint = new PGpoint();
pgPoint.setByteValue((byte[]) paramValues[index], 0);
return quoteAndCast(pgPoint.toString(), "point", standardConformingStrings);
return "'" + pgPoint.toString() + "'::point";
case Oid.BOX:
PGbox pgBox = new PGbox();
pgBox.setByteValue((byte[]) paramValues[index], 0);
return quoteAndCast(pgBox.toString(), "box", standardConformingStrings);
return "'" + pgBox.toString() + "'::box";
}
return "?";
} else if (paramValues[index] instanceof Struct) {
Struct struct = (Struct) paramValues[index];
return struct.toString();
} else {
String param = paramValue.toString();
String param = paramValues[index].toString();
// add room for quotes + potential escaping.
StringBuilder p = new StringBuilder(3 + (param.length() + 10) / 10 * 11);
// No E'..' here since escapeLiteral escapes all things and it does not use \123 kind of
// escape codes
p.append('\'');
try {
p = Utils.escapeLiteral(p, param, standardConformingStrings);
} catch (SQLException sqle) {
// This should only happen if we have an embedded null
// and there's not much we can do if we do hit one.
//
// The goal of toString isn't to be sent to the server,
// so we aren't 100% accurate (see StreamWrapper), put
// the unescaped version of the data.
//
p.append(param);
}
p.append('\'');
int paramType = paramTypes[index];
if (paramType == Oid.TIMESTAMP) {
return quoteAndCast(param, "timestamp", standardConformingStrings);
p.append("::timestamp");
} else if (paramType == Oid.TIMESTAMPTZ) {
return quoteAndCast(param, "timestamp with time zone", standardConformingStrings);
p.append("::timestamp with time zone");
} else if (paramType == Oid.TIME) {
return quoteAndCast(param, "time", standardConformingStrings);
p.append("::time");
} else if (paramType == Oid.TIMETZ) {
return quoteAndCast(param, "time with time zone", standardConformingStrings);
p.append("::time with time zone");
} else if (paramType == Oid.DATE) {
return quoteAndCast(param, "date", standardConformingStrings);
p.append("::date");
} else if (paramType == Oid.INTERVAL) {
return quoteAndCast(param, "interval", standardConformingStrings);
} else if (paramType == Oid.NUMERIC) {
return quoteAndCast(param, "numeric", standardConformingStrings);
p.append("::interval");
}
return quoteAndCast(param, null, standardConformingStrings);
return p.toString();
}
}

View File

@ -1431,22 +1431,6 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable
PGProperty.AUTOSAVE.set(properties, autoSave.value());
}
/**
* see PGProperty#CLEANUP_SAVEPOINTS
* @return boolean indicating property set
*/
public boolean getCleanupSavepoints() {
return PGProperty.CLEANUP_SAVEPOINTS.getBoolean(properties);
}
/**
* see PGProperty#CLEANUP_SAVEPOINTS
* @param cleanupSavepoints will cleanup savepoints after a successful transaction
*/
public void setCleanupSavepoints(boolean cleanupSavepoints) {
PGProperty.CLEANUP_SAVEPOINTS.set(properties, cleanupSavepoints);
}
/**
* @see PGProperty#REWRITE_BATCHED_INSERTS
* @return boolean indicating property is enabled or not.
@ -1463,14 +1447,6 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable
PGProperty.REWRITE_BATCHED_INSERTS.set(properties, reWrite);
}
public boolean isCleanupSavePoints() {
return getCleanupSavepoints();
}
public void setCleanupSavePoints(final boolean cleanupSavepoints) {
setCleanupSavepoints(cleanupSavepoints);
}
public java.util.logging.Logger getParentLogger() {
if(org.postgresql.log.Logger.isUsingJDKLogger()){
return java.util.logging.Logger.getLogger("org.postgresql");

View File

@ -560,7 +560,7 @@ public class PgArray implements java.sql.Array {
final int type =
connection.getTypeInfo().getSQLType(connection.getTypeInfo().getPGArrayElement(oid));
if (type == Types.BIT || type == Types.BOOLEAN) {
if (type == Types.BIT) {
boolean[] pa = null; // primitive array
Object[] oa = null; // objects array
@ -656,7 +656,7 @@ public class PgArray implements java.sql.Array {
pa[length++] = o == null ? 0L : PgResultSet.toLong((String) o);
}
}
} else if (type == Types.NUMERIC || type == Types.DECIMAL) {
} else if (type == Types.NUMERIC) {
Object[] oa = null;
ret = oa =
(dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(BigDecimal.class, dimsLength)

View File

@ -181,7 +181,7 @@ class PgCallableStatement extends PgPreparedStatement implements CallableStateme
}
int columnType = rs.getMetaData().getColumnType(i + 1);
if (columnType == Types.NUMERIC || columnType == Types.DECIMAL) {
if (columnType == Types.NUMERIC) {
callResult[j] = rs.getBigDecimal(i + 1);
} else {
callResult[j] = rs.getObject(i + 1);
@ -251,8 +251,8 @@ class PgCallableStatement extends PgPreparedStatement implements CallableStateme
case Types.LONGVARCHAR:
sqlType = Types.VARCHAR;
break;
case Types.NUMERIC:
sqlType = Types.DECIMAL;
case Types.DECIMAL:
sqlType = Types.NUMERIC;
break;
case Types.FLOAT:
// float is the same as double
@ -598,7 +598,7 @@ class PgCallableStatement extends PgPreparedStatement implements CallableStateme
public java.math.BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
checkClosed();
checkIndex(parameterIndex, Types.DECIMAL, "BigDecimal");
checkIndex(parameterIndex, Types.NUMERIC, "BigDecimal");
try {
return ((BigDecimal) callResult[parameterIndex - 1]);
}catch(Exception e) {

View File

@ -198,9 +198,7 @@ public class PgConnection implements BaseConnection {
private String socketAddress;
private String secSocketAddress;
private boolean adaptiveSetSQLType = false;
private boolean isDolphinCmpt = false;
private PgDatabase pgDatabase;
private boolean isDolphinCmpt = false;
final CachedQuery borrowQuery(String sql) throws SQLException {
return queryExecutor.borrowQuery(sql);
}
@ -230,10 +228,6 @@ public class PgConnection implements BaseConnection {
LOGGER.debug(" setFlushCacheOnDeallocate = " + flushCacheOnDeallocate);
}
public PgDatabase getPgDatabase() {
return pgDatabase;
}
//
// Ctor.
//
@ -318,19 +312,6 @@ public class PgConnection implements BaseConnection {
bindStringAsVarchar = true;
}
/* set dolphin.b_compatibility_mode to the value of PGProperty.B_CMPT_MODE */
this.setDolphinCmpt(PGProperty.B_CMPT_MODE.getBoolean(info));
int unknownLength = PGProperty.UNKNOWN_LENGTH.getInt(info);
// Initialize object handling
_typeCache = createTypeInfo(this, unknownLength);
_typeCache.setPGTypes();
initObjectTypes(info);
pgDatabase = new PgDatabase(this);
pgDatabase.setDolphin(info);
// Initialize timestamp stuff
timestampUtils = new TimestampUtils(!queryExecutor.getIntegerDateTimes(), new Provider<TimeZone>() {
@Override
@ -339,7 +320,6 @@ public class PgConnection implements BaseConnection {
}
});
timestampUtils.setTimestampNanoFormat(PGProperty.TIMESTAMP_NANO_FORMAT.getInteger(info));
timestampUtils.setDolphin(pgDatabase.isDolphin());
// Initialize common queries.
// isParameterized==true so full parse is performed and the engine knows the query
@ -347,6 +327,14 @@ public class PgConnection implements BaseConnection {
commitQuery = createQuery("COMMIT", false, true).query;
rollbackQuery = createQuery("ROLLBACK", false, true).query;
int unknownLength = PGProperty.UNKNOWN_LENGTH.getInt(info);
// Initialize object handling
_typeCache = createTypeInfo(this, unknownLength);
_typeCache.setPGTypes();
_typeCache.setDBType();
initObjectTypes(info);
if (PGProperty.LOG_UNCLOSED_CONNECTIONS.getBoolean(info)) {
openStackTrace = new Throwable("Connection was created at this point:");
}
@ -357,11 +345,7 @@ public class PgConnection implements BaseConnection {
_typeCache.addCoreType("xml", Oid.XML, Types.SQLXML, "java.sql.SQLXML", Oid.XML_ARRAY);
}
_typeCache.addCoreType("clob", Oid.CLOB, Types.CLOB, "java.sql.CLOB", Oid.UNSPECIFIED);
int blobType = Types.BLOB;
if (pgDatabase.isDolphin()) {
blobType = Types.LONGVARBINARY;
}
_typeCache.addCoreType("blob", Oid.BLOB, blobType, "java.sql.BLOB", Oid.UNSPECIFIED);
_typeCache.addCoreType("blob", Oid.BLOB, Types.BLOB, "java.sql.BLOB", Oid.UNSPECIFIED);
this._clientInfo = new Properties();
if (haveMinimumServerVersion(ServerVersion.v9_0)) {
@ -481,8 +465,11 @@ public class PgConnection implements BaseConnection {
batchInsert = false;
}
adaptiveSetSQLType = PGProperty.ADAPTIVE_SET_SQL_TYPE.getBoolean(info);
/* set dolphin.b_compatibility_mode to the value of PGProperty.B_CMPT_MODE */
this.setDolphinCmpt(PGProperty.B_CMPT_MODE.getBoolean(info));
adaptiveSetSQLType = PGProperty.ADAPTIVE_SET_SQL_TYPE.getBoolean(info);
initClientLogic(info);
}

View File

@ -1,96 +0,0 @@
package org.postgresql.jdbc;
import org.postgresql.PGProperty;
import org.postgresql.core.BaseStatement;
import org.postgresql.core.QueryExecutor;
import org.postgresql.util.CompatibilityEnum;
import org.postgresql.util.GT;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.postgresql.util.BitOutputEnum;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Locale;
import java.util.Properties;
public class PgDatabase {
private PgConnection connection;
private boolean isDolphin;
private boolean isDec;
public PgDatabase(PgConnection connection) {
this.connection = connection;
}
public boolean isDolphin() {
return isDolphin;
}
public boolean isDec() {
return isDec;
}
/**
* cache dolphin
*
* @param info connection param
* @throws SQLException execute sql exception
*/
public void setDolphin(Properties info) throws SQLException {
String extensionDolphin = getDolphin("select count(1) from pg_extension where extname = 'dolphin';");
int dolphinNum = Integer.parseInt(extensionDolphin);
String compatibility = getDolphin("show dolphin.b_compatibility_mode;");
CompatibilityEnum compatibilityEnum = CompatibilityEnum.valueOf(compatibility.toUpperCase(Locale.ROOT));
if (dolphinNum > 0 && CompatibilityEnum.ON.equals(compatibilityEnum)) {
isDolphin = true;
String bitOutput = PGProperty.BIT_OUTPUT.get(info);
if (bitOutput == null) {
bitOutput = getDolphin("show dolphin.bit_output;");
} else {
updateBitOutput(bitOutput);
}
if (BitOutputEnum.DEC.equals(BitOutputEnum.valueOf(bitOutput.toUpperCase(Locale.ROOT)))) {
isDec = true;
}
} else {
isDolphin = false;
}
}
/**
* get dolphin
*
* @param sql execute sql
* @return dolphin of b database
* @throws SQLException execute sql exception
*/
public String getDolphin(String sql) throws SQLException {
try (PreparedStatement dbStatement = connection.prepareStatement(sql)) {
if (!((BaseStatement) dbStatement).executeWithFlags(QueryExecutor.QUERY_SUPPRESS_BEGIN)) {
throw new PSQLException(GT.tr("No results were returned by the query."), PSQLState.NO_DATA);
}
try (ResultSet rs = dbStatement.getResultSet()) {
if (rs.next()) {
return rs.getString(1);
}
return "";
}
}
}
private void updateBitOutput(String bitOutput) throws SQLException {
/* set parameter cannot use prepareStatement to set the value */
try (Statement stmt = connection.createStatement()) {
String sql = "set dolphin.bit_output to " + bitOutput;
stmt.execute(sql);
} catch (SQLException e) {
throw e;
}
}
}

View File

@ -30,8 +30,6 @@ import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import static org.postgresql.jdbc.TypeInfoCache.FLOATSCALE;
public class PgDatabaseMetaData implements DatabaseMetaData {
public PgDatabaseMetaData(PgConnection conn) {
@ -1603,7 +1601,7 @@ public class PgDatabaseMetaData implements DatabaseMetaData {
int decimalDigits = connection.getTypeInfo().getScale(typeOid, typeMod);
int columnSize = connection.getTypeInfo().getPrecision(typeOid, typeMod);
if (columnSize == 0 || decimalDigits == FLOATSCALE) {
if (columnSize == 0) {
columnSize = connection.getTypeInfo().getDisplaySize(typeOid, typeMod);
}
@ -2421,7 +2419,6 @@ public class PgDatabaseMetaData implements DatabaseMetaData {
sql += ") i";
}
sql += " where (i.keys).x >= 0";
sql += " ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION ";
return connection.createStatement().executeQuery(sql);

View File

@ -223,7 +223,7 @@ class PgPreparedStatement extends PgStatement implements PreparedStatement {
checkClosed();
int oid;
if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR || connection.getPgDatabase().isDolphin()) {
if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR) {
oid = connection.getStringVarcharFlag() ? Oid.VARCHAR : Oid.UNSPECIFIED;
} else if (sqlTypeToOid.containsKey(sqlType)) {
oid = sqlTypeToOid.get(sqlType);

View File

@ -256,122 +256,113 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
return getURL(findColumn(columnName));
}
protected Object internalGetObject(int columnIndex, Field field) throws SQLException {
switch (getSQLType(columnIndex)) {
case Types.BOOLEAN:
return getBoolean(columnIndex);
case Types.BIT:
return getBit(columnIndex);
case Types.SQLXML:
return getSQLXML(columnIndex);
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
if (field.getPGType().equals("uint4")) {
return getLong(columnIndex);
}
return getInt(columnIndex);
case Types.BIGINT:
if (field.getPGType().equals("uint8")) {
return getBigInteger(columnIndex);
}
return getLong(columnIndex);
case Types.NUMERIC:
case Types.DECIMAL:
int scale;
if (field.getMod() == -1) {
return getBigDecimal(columnIndex, -1);
} else {
scale = (short) ((field.getMod() - 4) & 0xffff);
return getBigDecimal(columnIndex, (Math.max(scale, -1)));
}
case Types.REAL:
return getFloat(columnIndex);
case Types.FLOAT:
case Types.DOUBLE:
return getDouble(columnIndex);
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
return getString(columnIndex);
case Types.DATE:
return getDate(columnIndex);
case Types.TIME:
return getTime(columnIndex);
case Types.TIMESTAMP:
return getTimestamp(columnIndex, null);
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
return getBytes(columnIndex);
case Types.ARRAY:
return getArray(columnIndex);
case Types.CLOB:
return getClob(columnIndex);
case Types.BLOB:
return getBlob(columnIndex);
case Types.STRUCT:
return getStruct(columnIndex);
protected Object internalGetObject(int columnIndex, Field field) throws SQLException {
switch (getSQLType(columnIndex)) {
case Types.BOOLEAN:
return getBoolean(columnIndex);
case Types.BIT:
return getBit(columnIndex);
case Types.SQLXML:
return getSQLXML(columnIndex);
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
return getInt(columnIndex);
case Types.BIGINT:
return getLong(columnIndex);
case TypeInfoCache.bIntegerType:
return getBigInteger(columnIndex);
case Types.NUMERIC:
case Types.DECIMAL:
return getBigDecimal(columnIndex,
(field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
case Types.REAL:
return getFloat(columnIndex);
case Types.FLOAT:
case Types.DOUBLE:
return getDouble(columnIndex);
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
return getString(columnIndex);
case Types.DATE:
return getDate(columnIndex);
case Types.TIME:
return getTime(columnIndex);
case Types.TIMESTAMP:
return getTimestamp(columnIndex, null);
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
return getBytes(columnIndex);
case Types.ARRAY:
return getArray(columnIndex);
case Types.CLOB:
return getClob(columnIndex);
case Types.BLOB:
return getBlob(columnIndex);
case Types.STRUCT:
return getStruct(columnIndex);
default:
String type = getPGType(columnIndex);
default:
String type = getPGType(columnIndex);
// if the backend doesn't know the type then coerce to String
if (type.equals("unknown")) {
return getString(columnIndex);
}
if (type.equals("uuid")) {
if (isBinary(columnIndex)) {
return getUUID(this_row[columnIndex - 1]);
}
return getUUID(getString(columnIndex));
}
// Specialized support for ref cursors is neater.
if (type.equals("refcursor")) {
// Fetch all results.
String cursorName = getString(columnIndex);
StringBuilder sb = new StringBuilder("FETCH ALL IN ");
Utils.escapeIdentifier(sb, cursorName);
// nb: no BEGIN triggered here. This is fine. If someone
// committed, and the cursor was not holdable (closing the
// cursor), we avoid starting a new xact and promptly causing
// it to fail. If the cursor *was* holdable, we don't want a
// new xact anyway since holdable cursor state isn't affected
// by xact boundaries. If our caller didn't commit at all, or
// autocommit was on, then we wouldn't issue a BEGIN anyway.
//
// We take the scrollability from the statement, but until
// we have updatable cursors it must be readonly.
ResultSet rs =
connection.execSQLQuery(sb.toString(), resultsettype, ResultSet.CONCUR_READ_ONLY);
//
// In long running transactions these backend cursors take up memory space
// we could close in rs.close(), but if the transaction is closed before the result set,
// then
// the cursor no longer exists
sb.setLength(0);
sb.append("CLOSE ");
Utils.escapeIdentifier(sb, cursorName);
connection.execSQLUpdate(sb.toString());
((PgResultSet) rs).setRefCursor(cursorName);
return rs;
}
if ("hstore".equals(type)) {
if (isBinary(columnIndex)) {
return HStoreConverter.fromBytes(this_row[columnIndex - 1], connection.getEncoding());
}
return HStoreConverter.fromString(getString(columnIndex));
}
// Caller determines what to do (JDBC3 overrides in this case)
return null;
// if the backend doesn't know the type then coerce to String
if (type.equals("unknown")) {
return getString(columnIndex);
}
if (type.equals("uuid")) {
if (isBinary(columnIndex)) {
return getUUID(this_row[columnIndex - 1]);
}
return getUUID(getString(columnIndex));
}
// Specialized support for ref cursors is neater.
if (type.equals("refcursor")) {
// Fetch all results.
String cursorName = getString(columnIndex);
StringBuilder sb = new StringBuilder("FETCH ALL IN ");
Utils.escapeIdentifier(sb, cursorName);
// nb: no BEGIN triggered here. This is fine. If someone
// committed, and the cursor was not holdable (closing the
// cursor), we avoid starting a new xact and promptly causing
// it to fail. If the cursor *was* holdable, we don't want a
// new xact anyway since holdable cursor state isn't affected
// by xact boundaries. If our caller didn't commit at all, or
// autocommit was on, then we wouldn't issue a BEGIN anyway.
//
// We take the scrollability from the statement, but until
// we have updatable cursors it must be readonly.
ResultSet rs =
connection.execSQLQuery(sb.toString(), resultsettype, ResultSet.CONCUR_READ_ONLY);
//
// In long running transactions these backend cursors take up memory space
// we could close in rs.close(), but if the transaction is closed before the result set,
// then
// the cursor no longer exists
sb.setLength(0);
sb.append("CLOSE ");
Utils.escapeIdentifier(sb, cursorName);
connection.execSQLUpdate(sb.toString());
((PgResultSet) rs).setRefCursor(cursorName);
return rs;
}
if ("hstore".equals(type)) {
if (isBinary(columnIndex)) {
return HStoreConverter.fromBytes(this_row[columnIndex - 1], connection.getEncoding());
}
return HStoreConverter.fromString(getString(columnIndex));
}
// Caller determines what to do (JDBC3 overrides in this case)
return null;
}
}
/**
* Get the PGStruct object based on parameter index
@ -658,7 +649,7 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
}
}
return connection.getTimestampUtils().toDate(cal, new String(this_row[i - 1]));
return connection.getTimestampUtils().toDate(cal, getString(i));
}
@ -2097,17 +2088,12 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
if (connection.unwrap(PgConnection.class).isDolphinCmpt()) {
return new String(toBytes(result));
}
} else if (blobSet.contains(typeName) || ("raw".equals(typeName)
&& connection.getPgDatabase().isDolphin())) {
} else if (blobSet.contains(typeName)) {
return new String(toBytes(result));
} else if ("time".equals(typeName)) {
char[] cs = result.toCharArray();
int start = TimestampUtils.firstDigit(cs, 0);
return result.substring(start);
} else if ("date".equals(typeName) && connection.getPgDatabase().isDolphin()) {
java.util.Calendar cal = getDefaultCalendar();
Date dt = connection.getTimestampUtils().toDate(cal, result);
return String.valueOf(dt);
result = result.substring(start);
}
return result;
} catch (IOException ioe) {
@ -2224,13 +2210,7 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
if (connection.getBitToString()) {
return val;
}
Field field = this.fields[columnIndex - 1];
if (field.getMod() == 1 || !connection.getPgDatabase().isDolphin()) {
return BooleanTypeUtil.castToBoolean(val);
}
return this.getBytes(columnIndex);
return BooleanTypeUtil.castToBoolean(val);
}
private static final BigInteger BYTEMAX = new BigInteger(Byte.toString(Byte.MAX_VALUE));
@ -2656,46 +2636,13 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
int oid = fields[columnIndex - 1].getOID();
if (oid == Oid.BYTEA) {
return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1]));
} else if (oid == Oid.BLOB || blobSet.contains(getPGType(columnIndex))) {
String result = new String(this_row[columnIndex - 1]);
return toBytes(result);
} else if (oid == Oid.BIT && connection.getPgDatabase().isDec()) {
return toDecBytes(fields[columnIndex - 1].getMod(), getString(columnIndex));
} else if (oid == Oid.BLOB) {
return toBytes(getString(columnIndex));
} else {
return trimBytes(columnIndex, this_row[columnIndex - 1]);
}
}
private byte[] toDecBytes(int mod, String str) {
if (mod <= 0) {
return new byte[0];
}
int lengthToSplit = 8;
long value = Long.parseLong(str);
String binary = Long.toBinaryString(value);
int formatMod = mod;
if (mod % lengthToSplit != 0) {
formatMod = (mod / lengthToSplit + 1) * lengthToSplit;
}
if (binary.length() < formatMod) {
StringBuilder formatBinary = new StringBuilder();
for (int i = 0; i < formatMod - binary.length(); i++) {
formatBinary.append("0");
}
binary = formatBinary.append(binary).toString();
}
int byteLength = formatMod / lengthToSplit;
byte[] bytes = new byte[byteLength];
for (int i = 0; i < byteLength; i++) {
String splitStr = binary.substring(i * lengthToSplit, (i + 1) * lengthToSplit);
bytes[i] = (byte) Integer.parseInt(splitStr, 2);
}
return bytes;
}
public java.sql.Date getDate(int columnIndex) throws SQLException {
connection.getLogger().trace("[" + connection.getSecSocketAddress() + "]" + " getDate columnIndex: " + columnIndex);
return getDate(columnIndex, null);
@ -2879,8 +2826,7 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
return null;
}
String pgType = getPGType(columnIndex);
if (blobSet.contains(pgType)) {
if(blobSet.contains(getPGType(columnIndex))){
return toBytes(getBlobSetString(columnIndex));
}
@ -2889,13 +2835,13 @@ public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultS
return result;
}
if (binarySet.contains(pgType)) {
if (binarySet.contains(getPGType(columnIndex))) {
return this_row[columnIndex - 1];
}
if (isBinary(columnIndex)) {
return connection.getObject(pgType, null, this_row[columnIndex - 1]);
return connection.getObject(getPGType(columnIndex), null, this_row[columnIndex - 1]);
}
return connection.getObject(pgType, getString(columnIndex), null);
return connection.getObject(getPGType(columnIndex), getString(columnIndex), null);
}
public Object getObject(String columnName) throws SQLException {

View File

@ -7,7 +7,6 @@ package org.postgresql.jdbc;
import org.postgresql.Driver;
import org.postgresql.core.*;
import org.postgresql.core.v3.QueryExecutorImpl;
import org.postgresql.quickautobalance.ConnectionManager;
import org.postgresql.quickautobalance.LoadBalanceHeartBeating;
import org.postgresql.util.GT;
@ -992,7 +991,6 @@ public class PgStatement implements Statement, BaseStatement {
BatchResultHandler handler;
handler = createBatchHandler(queries, parameterLists);
QueryExecutorImpl executer = (QueryExecutorImpl) connection.getQueryExecutor();
if ((preDescribe || forceBinaryTransfers)
&& (flags & QueryExecutor.QUERY_EXECUTE_AS_SIMPLE) == 0) {
// Do a client-server round trip, parsing and describing the query so we
@ -1002,9 +1000,6 @@ public class PgStatement implements Statement, BaseStatement {
StatementResultHandler handler2 = new StatementResultHandler();
try {
connection.getQueryExecutor().execute(queries[0], parameterLists[0], handler2, 0, 0, flags2);
if (connection.getQueryExecutor() instanceof QueryExecutorImpl) {
executer.setWaitNexttime(true);
}
} catch (SQLException e) {
// Unable to parse the first statement -> throw BatchUpdateException
handler.handleError(e);
@ -1051,7 +1046,6 @@ public class PgStatement implements Statement, BaseStatement {
}
}
}
executer.setWaitNexttime(false);
return handler;
}

View File

@ -61,12 +61,6 @@ public class TimestampUtils {
private TimeZone defaultTimeZoneCache;
private int timestampNanoFormat = 0;
private boolean isDolphin = false;
public void setDolphin(boolean isDolphin) {
this.isDolphin = isDolphin;
}
static {
// The expected maximum value is 60 (seconds), so 64 is used "just in case"
NUMBERS = new char[64][];
@ -408,7 +402,7 @@ public class TimestampUtils {
ParsedTimestamp ts = parseBackendTimestamp(s);
Calendar useCal = ts.tz != null ? ts.tz : setupCalendar(cal);
useCal.set(Calendar.ERA, ts.era);
useCal.set(Calendar.YEAR, getYear(ts.year, slen));
useCal.set(Calendar.YEAR, ts.year);
useCal.set(Calendar.MONTH, ts.month - 1);
useCal.set(Calendar.DAY_OF_MONTH, ts.day);
useCal.set(Calendar.HOUR_OF_DAY, ts.hour);
@ -421,17 +415,6 @@ public class TimestampUtils {
return result;
}
private int getYear(int tsYear, int slen) {
int year = tsYear;
if (slen == 2 || slen == 1) {
if (year <= 69) {
year += 100;
}
year += 1900;
}
return year;
}
/**
* Parse a string and return a LocalTime representing its value.
*
@ -657,9 +640,6 @@ public class TimestampUtils {
}
public synchronized String toString(Calendar cal, Timestamp x) {
if (isDolphin) {
return toString(cal, x, false);
}
return toString(cal, x, true);
}

View File

@ -68,55 +68,54 @@ public class TypeInfoCache implements TypeInfo {
private static ConcurrentHashMap<Integer, String> pgTypes = new ConcurrentHashMap<>();
// SELECT LENGTH(pow(10::numeric,131071)); 131071 = 2^17-1
public static final int NUMERIC_MAX_DISPLAYSIZE = 131089;
public static final int bIntegerType = 1324;
// when behavior_compat_options='float_as_numeric' is on,
// openGauss accepts float(p) as numeric Type and the scale is -32768(PG_INT16_MIN)
public static final int FLOATSCALE = -32768;
public static String sqlCompatibility = "A";
// basic pg types info:
// 0 - type name
// 1 - type oid
// 2 - sql type
// 3 - java class
// 4 - array type oid
private static final Object[][] types = {
{"int1", Oid.INT1, Types.TINYINT, "java.lang.Integer", Oid.INT1_ARRAY},
{"int2", Oid.INT2, Types.SMALLINT, "java.lang.Integer", Oid.INT2_ARRAY},
{"int4", Oid.INT4, Types.INTEGER, "java.lang.Integer", Oid.INT4_ARRAY},
{"oid", Oid.OID, Types.BIGINT, "java.lang.Long", Oid.OID_ARRAY},
{"int8", Oid.INT8, Types.BIGINT, "java.lang.Long", Oid.INT8_ARRAY},
{"uint1", Oid.UINT1, Types.TINYINT, "java.lang.Integer", Oid.UINT1_ARRAY},
{"uint2", Oid.UINT2, Types.SMALLINT, "java.lang.Integer", Oid.UINT2_ARRAY},
{"uint4", Oid.UINT4, Types.INTEGER, "java.lang.Integer", Oid.UINT4_ARRAY},
{"uint8", Oid.UINT8, Types.BIGINT, "java.lang.Long", Oid.UINT8_ARRAY},
{"money", Oid.MONEY, Types.DOUBLE, "java.lang.Double", Oid.MONEY_ARRAY},
{"numeric", Oid.NUMERIC, Types.DECIMAL, "java.math.BigDecimal", Oid.NUMERIC_ARRAY},
{"float4", Oid.FLOAT4, Types.REAL, "java.lang.Float", Oid.FLOAT4_ARRAY},
{"float8", Oid.FLOAT8, Types.DOUBLE, "java.lang.Double", Oid.FLOAT8_ARRAY},
{"char", Oid.CHAR, Types.CHAR, "java.lang.String", Oid.CHAR_ARRAY},
{"bpchar", Oid.BPCHAR, Types.CHAR, "java.lang.String", Oid.BPCHAR_ARRAY},
{"varchar", Oid.VARCHAR, Types.VARCHAR, "java.lang.String", Oid.VARCHAR_ARRAY},
{"text", Oid.TEXT, Types.VARCHAR, "java.lang.String", Oid.TEXT_ARRAY},
{"name", Oid.NAME, Types.VARCHAR, "java.lang.String", Oid.NAME_ARRAY},
{"bytea", Oid.BYTEA, Types.BINARY, "[B", Oid.BYTEA_ARRAY},
{"bool", Oid.BOOL, Types.BOOLEAN, "java.lang.Boolean", Oid.BOOL_ARRAY},
{"bit", Oid.BIT, Types.BIT, "java.lang.Boolean", Oid.BIT_ARRAY},
{"date", Oid.DATE, Types.DATE, "java.sql.Date", Oid.DATE_ARRAY},
{"time", Oid.TIME, Types.TIME, "java.sql.Time", Oid.TIME_ARRAY},
{"timetz", Oid.TIMETZ, Types.TIME, "java.sql.Time", Oid.TIMETZ_ARRAY},
{"timestamp", Oid.TIMESTAMP, Types.TIMESTAMP, "java.sql.Timestamp", Oid.TIMESTAMP_ARRAY},
{"smalldatetime", Oid.SMALLDATETIME, Types.TIMESTAMP, "java.lang.Timestamp", Oid.SMALLDATETIME_ARRAY},
{"timestamptz", Oid.TIMESTAMPTZ, Types.TIMESTAMP, "java.sql.Timestamp",
Oid.TIMESTAMPTZ_ARRAY},
{"json", Oid.JSON, Types.VARCHAR, "java.lang.String", Oid.JSON_ARRAY},
{"point", Oid.POINT, Types.OTHER, "org.postgresql.geometric.PGpoint", Oid.POINT_ARRAY},
{"blob", Oid.BLOB, Types.BLOB, "org.postgresql.util.PGobject", -1},
{"clob", Oid.CLOB, Types.CLOB, "org.postgresql.util.PGobject", -1},
{"nvarchar2", Oid.NVARCHAR2, Types.VARCHAR, "java.lang.String", Oid.NVARCHAR2_ARRAY},
{"refcursor", Oid.REF_CURSOR, Types.REF_CURSOR, "java.sql.ResultSet", Oid.REF_CURSOR_ARRAY}
};
public static String dolphinMode = "off";
// basic pg types info:
// 0 - type name
// 1 - type oid
// 2 - sql type
// 3 - java class
// 4 - array type oid
private static final Object[][] types = {
{"int1", Oid.INT1, Types.TINYINT, "java.lang.Integer", Oid.INT1_ARRAY},
{"int2", Oid.INT2, Types.SMALLINT, "java.lang.Integer", Oid.INT2_ARRAY},
{"int4", Oid.INT4, Types.INTEGER, "java.lang.Integer", Oid.INT4_ARRAY},
{"oid", Oid.OID, Types.BIGINT, "java.lang.Long", Oid.OID_ARRAY},
{"int8", Oid.INT8, Types.BIGINT, "java.lang.Long", Oid.INT8_ARRAY},
{"uint1", Oid.UINT1, Types.SMALLINT, "java.lang.Integer", Oid.UINT1_ARRAY},
{"uint2", Oid.UINT2, Types.INTEGER, "java.lang.Integer", Oid.UINT2_ARRAY},
{"uint4", Oid.UINT4, Types.BIGINT, "java.lang.Long", Oid.UINT4_ARRAY},
{"uint8", Oid.UINT8, bIntegerType, "java.math.BigInteger", Oid.UINT8_ARRAY},
{"money", Oid.MONEY, Types.DOUBLE, "java.lang.Double", Oid.MONEY_ARRAY},
{"numeric", Oid.NUMERIC, Types.NUMERIC, "java.math.BigDecimal", Oid.NUMERIC_ARRAY},
{"float4", Oid.FLOAT4, Types.REAL, "java.lang.Float", Oid.FLOAT4_ARRAY},
{"float8", Oid.FLOAT8, Types.DOUBLE, "java.lang.Double", Oid.FLOAT8_ARRAY},
{"char", Oid.CHAR, Types.CHAR, "java.lang.String", Oid.CHAR_ARRAY},
{"bpchar", Oid.BPCHAR, Types.CHAR, "java.lang.String", Oid.BPCHAR_ARRAY},
{"varchar", Oid.VARCHAR, Types.VARCHAR, "java.lang.String", Oid.VARCHAR_ARRAY},
{"text", Oid.TEXT, Types.VARCHAR, "java.lang.String", Oid.TEXT_ARRAY},
{"name", Oid.NAME, Types.VARCHAR, "java.lang.String", Oid.NAME_ARRAY},
{"bytea", Oid.BYTEA, Types.BINARY, "[B", Oid.BYTEA_ARRAY},
{"bool", Oid.BOOL, Types.BOOLEAN, "java.lang.Boolean", Oid.BOOL_ARRAY},
{"bit", Oid.BIT, Types.BIT, "java.lang.Boolean", Oid.BIT_ARRAY},
{"date", Oid.DATE, Types.DATE, "java.sql.Date", Oid.DATE_ARRAY},
{"time", Oid.TIME, Types.TIME, "java.sql.Time", Oid.TIME_ARRAY},
{"timetz", Oid.TIMETZ, Types.TIME, "java.sql.Time", Oid.TIMETZ_ARRAY},
{"timestamp", Oid.TIMESTAMP, Types.TIMESTAMP, "java.sql.Timestamp", Oid.TIMESTAMP_ARRAY},
{"smalldatetime", Oid.SMALLDATETIME, Types.TIMESTAMP, "java.lang.Timestamp", Oid.SMALLDATETIME_ARRAY},
{"timestamptz", Oid.TIMESTAMPTZ, Types.TIMESTAMP, "java.sql.Timestamp",
Oid.TIMESTAMPTZ_ARRAY},
{"json", Oid.JSON, Types.OTHER, "org.postgresql.util.PGobject", Oid.JSON_ARRAY},
{"point", Oid.POINT, Types.OTHER, "org.postgresql.geometric.PGpoint", Oid.POINT_ARRAY},
{"blob", Oid.BLOB, Types.BLOB, "org.postgresql.util.PGobject", -1},
{"clob", Oid.CLOB, Types.CLOB, "org.postgresql.util.PGobject", -1},
{"nvarchar2", Oid.NVARCHAR2, Types.VARCHAR, "java.lang.String", Oid.NVARCHAR2_ARRAY},
{"refcursor", Oid.REF_CURSOR, Types.REF_CURSOR, "java.sql.ResultSet", Oid.REF_CURSOR_ARRAY}
};
/**
* PG maps several alias to real type names. When we do queries against pg_catalog, we must use
@ -216,18 +215,6 @@ public class TypeInfoCache implements TypeInfo {
return i;
}
Integer type = null;
if ("binary".equals(pgTypeName)) {
type = Types.BINARY;
} else if ("varbinary".equals(pgTypeName)) {
type = Types.VARBINARY;
}
if (type != null) {
_pgNameToSQLType.put(pgTypeName, type);
return type;
}
if (_getTypeInfoStatement == null) {
// There's no great way of telling what's an array type.
// People can name their own types starting with _.
@ -253,6 +240,7 @@ public class TypeInfoCache implements TypeInfo {
ResultSet rs = _getTypeInfoStatement.getResultSet();
Integer type = null;
if (rs.next()) {
boolean isArray = rs.getBoolean(1);
String typtype = rs.getString(2);
@ -266,11 +254,7 @@ public class TypeInfoCache implements TypeInfo {
}
if (type == null) {
if (_conn.getPgDatabase().isDolphin()) {
type = Types.CHAR;
} else {
type = Types.OTHER;
}
type = Types.OTHER;
}
rs.close();
@ -450,6 +434,41 @@ public class TypeInfoCache implements TypeInfo {
return pgTypes;
}
public void setDBType() throws SQLException {
String compatibilitySql = "show sql_compatibility;";
String compatibility = getDBParam(compatibilitySql);
if (compatibility != null) {
sqlCompatibility = compatibility;
if ("B".equals(compatibility)) {
String dolphinSql = "show dolphin.b_compatibility_mode;";
String dolphin = getDBParam(dolphinSql);
if (dolphin != null) {
dolphinMode = dolphin;
}
}
}
}
private String getDBParam(String sql) throws SQLException {
PreparedStatement dbStatement = _conn.prepareStatement(sql);
if (!((BaseStatement) dbStatement).executeWithFlags(QueryExecutor.QUERY_SUPPRESS_BEGIN)) {
throw new PSQLException(GT.tr("No results were returned by the query."), PSQLState.NO_DATA);
}
ResultSet rs = dbStatement.getResultSet();
if (rs != null && rs.next()) {
return rs.getString(1);
}
return null;
}
public static String getDolphinMode(){
return dolphinMode;
}
public static String getSqlCompatibility(){
return sqlCompatibility;
}
public synchronized int getPGType(String pgTypeName) throws SQLException {
Integer oid = _pgNameToOid.get(pgTypeName);
if (oid != null) {
@ -802,7 +821,7 @@ public class TypeInfoCache implements TypeInfo {
if (typmod == -1) {
return 0;
}
return (short)((typmod - 4) & 0xFFFF);
return (typmod - 4) & 0xFFFF;
case Oid.TIME:
case Oid.TIMETZ:
case Oid.TIMESTAMP:
@ -938,15 +957,10 @@ public class TypeInfoCache implements TypeInfo {
return typmod - 4;
case Oid.NUMERIC:
if (typmod == -1) {
return NUMERIC_MAX_DISPLAYSIZE;
return 131089; // SELECT LENGTH(pow(10::numeric,131071)); 131071 = 2^17-1
}
int precision = (typmod - 4 >> 16) & 0xffff;
int scale = (short)((typmod - 4) & 0xffff);
if (scale == FLOATSCALE) {
return NUMERIC_MAX_DISPLAYSIZE;
} else if (scale < 0) {
return 1 + precision - scale;
}
int scale = (typmod - 4) & 0xffff;
// sign + digits + decimal point (only if we have nonzero scale)
return 1 + precision + (scale != 0 ? 1 : 0);
case Oid.BIT:

View File

@ -1,26 +0,0 @@
/*
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FITFOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.util;
/**
* This class is used b database and bit type.
*
* @author zhangting
* @date 2024/08/10 09:01
*/
public enum BitOutputEnum {
BIN, DEC, HEX
}

View File

@ -5,9 +5,6 @@
package org.postgresql.util;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* Helper methods to parse java base types from byte arrays.
*
@ -19,291 +16,6 @@ public class ByteConverter {
// prevent instantiation of static helper class
}
private static final int NUMERIC_DSCALE_MASK = 0x00003FFF;
private static final short NUMERIC_POS = 0x0000;
private static final short NUMERIC_NEG = 0x4000;
private static final short NUMERIC_NAN = (short) 0xC000;
private static final int SHORT_BYTES = 2;
private static final int[] INT_TEN_POWERS = new int[6];
private static final BigInteger[] BI_TEN_POWERS = new BigInteger[32];
private static final BigInteger BI_TEN_THOUSAND = BigInteger.valueOf(10000);
/**
* Convert a variable length array of bytes to an integer
* @param bytes array of bytes that can be decoded as an integer
* @return integer
*/
public static Number numeric(byte [] bytes) {
return numeric(bytes, 0, bytes.length);
}
/**
* Convert a variable length array of bytes to a {@link Number}. The result will
* always be a {@link BigDecimal} or {@link Double#NaN}.
*
* @param bytes array of bytes to be decoded from binary numeric representation.
* @param pos index of the start position of the bytes array for number
* @param numBytes number of bytes to use, length is already encoded
* in the binary format but this is used for double checking
* @return BigDecimal representation of numeric or {@link Double#NaN}.
*/
public static Number numeric(byte [] bytes, int pos, int numBytes) {
if (numBytes < 8) {
throw new IllegalArgumentException("number of bytes should be at-least 8");
}
//number of 2-byte shorts representing 4 decimal digits - should be treated as unsigned
int len = ByteConverter.int2(bytes, pos) & 0xFFFF;
//0 based number of 4 decimal digits (i.e. 2-byte shorts) before the decimal
//a value <= 0 indicates an absolute value < 1.
short weight = ByteConverter.int2(bytes, pos + 2);
//indicates positive, negative or NaN
short sign = ByteConverter.int2(bytes, pos + 4);
//number of digits after the decimal. This must be >= 0.
//a value of 0 indicates a whole number (integer).
short scale = ByteConverter.int2(bytes, pos + 6);
//An integer should be built from the len number of 2 byte shorts, treating each
//as 4 digits.
//The weight, if > 0, indicates how many of those 4 digit chunks should be to the
//"left" of the decimal. If the weight is 0, then all 4 digit chunks start immediately
//to the "right" of the decimal. If the weight is < 0, the absolute distance from 0
//indicates 4 leading "0" digits to the immediate "right" of the decimal, prior to the
//digits from "len".
//A weight which is positive, can be a number larger than what len defines. This means
//there are trailing 0s after the "len" integer and before the decimal.
//The scale indicates how many significant digits there are to the right of the decimal.
//A value of 0 indicates a whole number (integer).
//The combination of weight, len, and scale can result in either trimming digits provided
//by len (only to the right of the decimal) or adding significant 0 values to the right
//of len (on either side of the decimal).
if (numBytes != (len * SHORT_BYTES + 8)) {
throw new IllegalArgumentException("invalid length of bytes \"numeric\" value");
}
if (!(sign == NUMERIC_POS
|| sign == NUMERIC_NEG
|| sign == NUMERIC_NAN)) {
throw new IllegalArgumentException("invalid sign in \"numeric\" value");
}
if (sign == NUMERIC_NAN) {
return Double.NaN;
}
if ((scale & NUMERIC_DSCALE_MASK) != scale) {
throw new IllegalArgumentException("invalid scale in \"numeric\" value");
}
if (len == 0) {
return new BigDecimal(BigInteger.ZERO, scale);
}
int idx = pos + 8;
short d = ByteConverter.int2(bytes, idx);
//if the absolute value is (0, 1), then leading '0' values
//do not matter for the unscaledInt, but trailing 0s do
if (weight < 0) {
assert scale > 0;
int effectiveScale = scale;
//adjust weight to determine how many leading 0s after the decimal
//before the provided values/digits actually begin
++weight;
if (weight < 0) {
effectiveScale += 4 * weight;
}
int i = 1;
//typically there should not be leading 0 short values, as it is more
//efficient to represent that in the weight value
for (; i < len && d == 0; i++) {
//each leading 0 value removes 4 from the effective scale
effectiveScale -= 4;
idx += 2;
d = ByteConverter.int2(bytes, idx);
}
assert effectiveScale > 0;
if (effectiveScale >= 4) {
effectiveScale -= 4;
} else {
//an effective scale of less than four means that the value d
//has trailing 0s which are not significant
//so we divide by the appropriate power of 10 to reduce those
d = (short) (d / INT_TEN_POWERS[4 - effectiveScale]);
effectiveScale = 0;
}
//defer moving to BigInteger as long as possible
//operations on the long are much faster
BigInteger unscaledBI = null;
long unscaledInt = d;
for (; i < len; i++) {
if (i == 4 && effectiveScale > 2) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
idx += 2;
d = ByteConverter.int2(bytes, idx);
//if effective scale is at least 4, then all 4 digits should be used
//and the existing number needs to be shifted 4
if (effectiveScale >= 4) {
if (unscaledBI == null) {
unscaledInt *= 10000;
} else {
unscaledBI = unscaledBI.multiply(BI_TEN_THOUSAND);
}
effectiveScale -= 4;
} else {
//if effective scale is less than 4, then only shift left based on remaining scale
if (unscaledBI == null) {
unscaledInt *= INT_TEN_POWERS[effectiveScale];
} else {
unscaledBI = unscaledBI.multiply(tenPower(effectiveScale));
}
//and d needs to be shifted to the right to only get correct number of
//significant digits
d = (short) (d / INT_TEN_POWERS[4 - effectiveScale]);
effectiveScale = 0;
}
if (unscaledBI == null) {
unscaledInt += d;
} else {
if (d != 0) {
unscaledBI = unscaledBI.add(BigInteger.valueOf(d));
}
}
}
//now we need BigInteger to create BigDecimal
if (unscaledBI == null) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
//if there is remaining effective scale, apply it here
if (effectiveScale > 0) {
unscaledBI = unscaledBI.multiply(tenPower(effectiveScale));
}
if (sign == NUMERIC_NEG) {
unscaledBI = unscaledBI.negate();
}
return new BigDecimal(unscaledBI, scale);
}
//if there is no scale, then shorts are the unscaled int
if (scale == 0) {
//defer moving to BigInteger as long as possible
//operations on the long are much faster
BigInteger unscaledBI = null;
long unscaledInt = d;
//loop over all of the len shorts to process as the unscaled int
for (int i = 1; i < len; i++) {
if (i == 4) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
idx += 2;
d = ByteConverter.int2(bytes, idx);
if (unscaledBI == null) {
unscaledInt *= 10000;
unscaledInt += d;
} else {
unscaledBI = unscaledBI.multiply(BI_TEN_THOUSAND);
if (d != 0) {
unscaledBI = unscaledBI.add(BigInteger.valueOf(d));
}
}
}
//now we need BigInteger to create BigDecimal
if (unscaledBI == null) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
if (sign == NUMERIC_NEG) {
unscaledBI = unscaledBI.negate();
}
//the difference between len and weight (adjusted from 0 based) becomes the scale for BigDecimal
final int bigDecScale = (len - (weight + 1)) * 4;
//string representation always results in a BigDecimal with scale of 0
//the binary representation, where weight and len can infer trailing 0s, can result in a negative scale
//to produce a consistent BigDecimal, we return the equivalent object with scale set to 0
return bigDecScale == 0 ? new BigDecimal(unscaledBI) : new BigDecimal(unscaledBI, bigDecScale).setScale(0);
}
//defer moving to BigInteger as long as possible
//operations on the long are much faster
BigInteger unscaledBI = null;
long unscaledInt = d;
//weight and scale as defined by postgresql are a bit different than how BigDecimal treats scale
//maintain the effective values to massage as we process through values
int effectiveWeight = weight;
int effectiveScale = scale;
for (int i = 1; i < len; i++) {
if (i == 4) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
idx += 2;
d = ByteConverter.int2(bytes, idx);
//first process effective weight down to 0
if (effectiveWeight > 0) {
--effectiveWeight;
if (unscaledBI == null) {
unscaledInt *= 10000;
} else {
unscaledBI = unscaledBI.multiply(BI_TEN_THOUSAND);
}
} else if (effectiveScale >= 4) {
//if effective scale is at least 4, then all 4 digits should be used
//and the existing number needs to be shifted 4
effectiveScale -= 4;
if (unscaledBI == null) {
unscaledInt *= 10000;
} else {
unscaledBI = unscaledBI.multiply(BI_TEN_THOUSAND);
}
} else {
//if effective scale is less than 4, then only shift left based on remaining scale
if (unscaledBI == null) {
unscaledInt *= INT_TEN_POWERS[effectiveScale];
} else {
unscaledBI = unscaledBI.multiply(tenPower(effectiveScale));
}
//and d needs to be shifted to the right to only get correct number of
//significant digits
d = (short) (d / INT_TEN_POWERS[4 - effectiveScale]);
effectiveScale = 0;
}
if (unscaledBI == null) {
unscaledInt += d;
} else {
if (d != 0) {
unscaledBI = unscaledBI.add(BigInteger.valueOf(d));
}
}
}
//now we need BigInteger to create BigDecimal
if (unscaledBI == null) {
unscaledBI = BigInteger.valueOf(unscaledInt);
}
//if there is remaining weight, apply it here
if (effectiveWeight > 0) {
unscaledBI = unscaledBI.multiply(tenPower(effectiveWeight * 4));
}
//if there is remaining effective scale, apply it here
if (effectiveScale > 0) {
unscaledBI = unscaledBI.multiply(tenPower(effectiveScale));
}
if (sign == NUMERIC_NEG) {
unscaledBI = unscaledBI.negate();
}
return new BigDecimal(unscaledBI, scale);
}
private static BigInteger tenPower(int exponent) {
return BI_TEN_POWERS.length > exponent ? BI_TEN_POWERS[exponent] : BigInteger.TEN.pow(exponent);
}
/**
* Parses a long value from the byte array.
*

View File

@ -1,5 +0,0 @@
package org.postgresql.util;
public enum CompatibilityEnum {
ON, OFF
}

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.core;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* test utf8 encoding
*
* @author zhangting
* @since 2024-09-24
*/
@RunWith(Parameterized.class)
public class UTF8EncodingTest {
private static final int STEP = 8 * 1024;
/**
* character encoding
*/
@Parameterized.Parameter(0)
public Encoding encoding;
/**
* test data
*/
@Parameterized.Parameter(1)
public String str;
/**
* test data
*/
@Parameterized.Parameter(2)
public String shortStr;
/**
* Construct data
*
* @return data
*/
@Parameterized.Parameters(name = "string={2}, encoding={0}")
public static Iterable<Object[]> data() {
final StringBuilder reallyLongString = new StringBuilder(1024 * 1024);
for (int i = 0; i < 185000; ++i) {
reallyLongString.append(i);
}
final List<String> strs = new ArrayList<>(150);
strs.add("short simple");
strs.add("longer but still not really all that long");
strs.add(reallyLongString.toString());
// add multi-byte to end of a long string
strs.add(reallyLongString.append('\u03C0').toString());
strs.add(reallyLongString.delete((32 * 1024) + 5, reallyLongString.capacity() - 1).toString());
// add high order char to end of mid length string
strs.add(reallyLongString.append('\u00DC').toString());
strs.add(reallyLongString.delete((16 * 1024) + 5, reallyLongString.capacity() - 1).toString());
// add high order char to end of mid length string
strs.add(reallyLongString.append('\u00DD').toString());
strs.add("e\u00E4t \u03A3 \u03C0 \u798F, it is good");
for (int i = 1; i < 0xd800; i += STEP) {
int count = (i + STEP) > 0xd800 ? 0xd800 - i : STEP;
char[] testChars = new char[count];
for (int j = 0; j < count; ++j) {
testChars[j] = (char) (i + j);
}
strs.add(new String(testChars));
}
for (int i = 0xe000; i < 0x10000; i += STEP) {
int count = (i + STEP) > 0x10000 ? 0x10000 - i : STEP;
char[] testChars = new char[count];
for (int j = 0; j < count; ++j) {
testChars[j] = (char) (i + j);
}
strs.add(new String(testChars));
}
for (int i = 0x10000; i < 0x110000; i += STEP) {
int count = (i + STEP) > 0x110000 ? 0x110000 - i : STEP;
char[] testChars = new char[count * 2];
for (int j = 0; j < count; ++j) {
testChars[j * 2] = (char) (0xd800 + ((i + j - 0x10000) >> 10));
testChars[j * 2 + 1] = (char) (0xdc00 + ((i + j - 0x10000) & 0x3ff));
}
strs.add(new String(testChars));
}
final List<Object[]> data = new ArrayList<>(strs.size() * 2);
for (String str : strs) {
if (str != null && str.length() > 1000) {
str = str.substring(0, 100) + "...(" + str.length() + " chars)";
}
data.add(new Object[] {Encoding.getDatabaseEncoding("UNICODE"), str, str});
}
return data;
}
@Test
public void test() throws IOException {
final byte[] encoded = encoding.encode(str);
assertEquals(str, encoding.decode(encoded));
}
}

View File

@ -60,6 +60,6 @@ public class V3ParameterListTests {
s1SPL.appendAll(s2SPL);
assertEquals(
"Expected string representation of values does not match outcome.",
"<[('1'::int4) ,('2'::int4) ,('3'::int4) ,('4'::int4) ,('5'::int4) ,('6'::int4) ,('7'::int4) ,('8'::int4)]>", s1SPL.toString());
"<[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8]>", s1SPL.toString());
}
}

View File

@ -1,353 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.jdbc;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4PG;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import static org.junit.Assert.assertTrue;
/**
* test full trace.
*
* @author hwhbj
* @since 2024-08-20
*/
public class FullTraceTest extends BaseTest4PG {
private static final Integer WAIT_FLUSH_TIME = 1000;
private static final String QUERY_STMT_HISTORY = "select db_time, net_trans_time from statement_history "
+ "where query like '%s'";
private static final String RECORD_FULL_SQL = "set track_stmt_stat_level = 'L0,L0'";
private static final String ENABLE_TRACE_SQL = "set enable_record_nettime = on";
private static Connection createConnection() throws Exception {
return TestUtil.openDB();
}
private static Connection createConnection(Properties props) throws Exception {
return TestUtil.openDB(props);
}
private static Connection createConnection(String dbName) throws Exception {
return TestUtil.openDB(dbName);
}
private List<Integer> recordCount(String sql) throws Exception {
String querySql = String.format(QUERY_STMT_HISTORY, sql);
try (Connection conn = createConnection("postgres");
PreparedStatement pstmt = conn.prepareStatement(querySql);
ResultSet rs = pstmt.executeQuery()) {
int count1 = 0;
int count2 = 0;
int count3 = 0;
while (rs.next()) {
int dbTime = rs.getInt(1);
int netTransTime = rs.getInt(2);
if (dbTime == 0 && netTransTime == 0) {
count1++;
} else if (dbTime > 0 && netTransTime == 0) {
count2++;
} else if (dbTime > 0 && netTransTime > 0) {
count3++;
}
}
return Arrays.asList(count1, count2, count3);
}
}
private void setRecordFullSql(Connection conn) throws Exception {
try (PreparedStatement pstmt = conn.prepareStatement(ENABLE_TRACE_SQL + ";" + RECORD_FULL_SQL)) {
pstmt.execute();
}
}
private void sendPreTimeAndFlush(Connection conn) throws Exception {
/* send previous net_time */
try (PreparedStatement pstmt = conn.prepareStatement("select 1;")) {
pstmt.executeQuery();
Thread.sleep(WAIT_FLUSH_TIME);
}
}
@Test
public void testExecuteMultiSqlPBE() throws Exception {
String sql1 = "drop table if exists t1";
String sql2 = "create table t1(id int)";
List<Integer> beforeInfoSql1 = recordCount(sql1);
List<Integer> beforeInfoSql2 = recordCount(sql2);
/* PBEPBES */
try (Connection conn = createConnection();
PreparedStatement pstmt = conn.prepareStatement(sql1 + ";" + sql2)) {
setRecordFullSql(conn);
pstmt.execute();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql1 = recordCount(sql1);
List<Integer> afterInfoSql2 = recordCount(sql2);
assertTrue(beforeInfoSql1.get(0) + 1 == afterInfoSql1.get(0));
assertTrue(beforeInfoSql1.get(1) + 1 == afterInfoSql1.get(1));
assertTrue(beforeInfoSql1.get(2) == afterInfoSql1.get(2));
assertTrue(beforeInfoSql2.get(0) + 1 == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 1 == afterInfoSql2.get(2));
}
}
@Test
public void testExecuteBatchPBENoCache() throws Exception {
Properties props = new Properties();
props.setProperty("prepareThreshold", "0");
String sql1 = "drop table if exists t1; create table t1(id int);";
String sql2 = "insert into t1 values(?)";
String sql2Record = "insert into t1 values(%)";
List<Integer> beforeInfoSql2 = recordCount(sql2Record);
/* PUES / PUES */
try (Connection conn = createConnection(props);
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2)) {
stmt.execute(sql1);
setRecordFullSql(conn);
for (int i = 0; i < 5000; ++i) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
for (int i = 0; i < 5000; ++i) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql2 = recordCount(sql2Record);
assertTrue(beforeInfoSql2.get(0) + 2 == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 2 == afterInfoSql2.get(2));
}
}
@Test
public void testExecuteBatchPBEUseCache() throws Exception {
Properties props = new Properties();
props.setProperty("prepareThreshold", "1");
String sql1 = "drop table if exists t1; create table t1(id int);";
String sql2 = "insert into t1 values(?)";
String sql2Record = "insert into t1 values(%)";
List<Integer> beforeInfoSql2 = recordCount(sql2Record);
/* P/DS/S / UES / UES */
try (Connection conn = createConnection(props);
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2)) {
stmt.execute(sql1);
setRecordFullSql(conn);
for (int i = 0; i < 5000; ++i) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
for (int i = 0; i < 5000; ++i) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql2 = recordCount(sql2Record);
assertTrue(beforeInfoSql2.get(0) + 1 == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 2 == afterInfoSql2.get(2));
}
}
@Test
public void testExecutePBENoCache() throws Exception {
Properties props = new Properties();
props.setProperty("prepareThreshold", "0");
String sql1 = "drop table if exists t1; create table t1(id int, age int);";
String sql2 = "select ? from t1;";
String sql2Record = "select%from t1";
List<Integer> beforeInfoSql2 = recordCount(sql2Record);
/* PBES / PBES */
try (Connection conn = createConnection(props);
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2)) {
stmt.execute(sql1);
setRecordFullSql(conn);
pstmt.setString(1, "id");
pstmt.execute();
pstmt.setString(1, "age");
pstmt.execute();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql2 = recordCount(sql2Record);
assertTrue(beforeInfoSql2.get(0) + 2 == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 2 == afterInfoSql2.get(2));
}
}
@Test
public void testExecutePBEUseCache() throws Exception {
Properties props = new Properties();
props.setProperty("prepareThreshold", "1");
String sql1 = "drop table if exists t1; create table t1(id int, age int);";
String sql2 = "select ? from t1;";
String sql2Record = "select%from t1";
List<Integer> beforeInfoSql2 = recordCount(sql2Record);
/* PBES/BES */
try (Connection conn = createConnection(props);
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2)) {
stmt.execute(sql1);
setRecordFullSql(conn);
pstmt.setString(1, "id");
pstmt.execute();
pstmt.setString(1, "age");
pstmt.execute();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql2 = recordCount(sql2Record);
assertTrue(beforeInfoSql2.get(0) + 1 == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 2 == afterInfoSql2.get(2));
}
}
@Test
public void testExecuteFetchSize() throws Exception {
String sql1 = "drop table if exists t1; create table t1(id int)";
String sql2 = "insert into t1 values(?)";
String sql3 = "select * from t1";
List<Integer> beforeInfoSql3 = recordCount(sql3);
ResultSet rst = null;
try (Connection conn = createConnection();
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2);
PreparedStatement pstmt1 = conn.prepareStatement(sql3)) {
/* prepare data */
stmt.execute(sql1);
for (int i = 0; i < 5000; ++i) {
pstmt.setInt(1, i);
pstmt.addBatch();
}
pstmt.executeBatch();
conn.setAutoCommit(false);
setRecordFullSql(conn);
pstmt1.setFetchSize(1000);
/* PBDES/ES/ES/ES/ES/ES */
rst = pstmt1.executeQuery();
while (rst.next()) {
rst.getInt(1);
}
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql3 = recordCount(sql3);
assertTrue(beforeInfoSql3.get(0) + 1 == afterInfoSql3.get(0));
assertTrue(beforeInfoSql3.get(1) == afterInfoSql3.get(1));
assertTrue(beforeInfoSql3.get(2) + 6 == afterInfoSql3.get(2));
} finally {
if (rst != null) {
rst.close();
}
}
}
@Test
public void testExecuteMultiSqlQ() throws Exception {
Properties props = new Properties();
props.setProperty("preferQueryMode", "simple");
String sql1 = "drop table if exists t1";
String sql2 = "create table t1(id int)";
List<Integer> beforeInfoSql1 = recordCount(sql1);
List<Integer> beforeInfoSql2 = recordCount(sql2);
try (Connection conn = createConnection(props);
PreparedStatement pstmt = conn.prepareStatement(sql1 + ";" + sql2)) {
setRecordFullSql(conn);
/* Q -> Q */
pstmt.execute();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql1 = recordCount(sql1);
List<Integer> afterInfoSql2 = recordCount(sql2);
assertTrue(beforeInfoSql1.get(0) == afterInfoSql1.get(0));
assertTrue(beforeInfoSql1.get(1) + 1 == afterInfoSql1.get(1));
assertTrue(beforeInfoSql1.get(2) == afterInfoSql1.get(2));
assertTrue(beforeInfoSql2.get(0) == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 1 == afterInfoSql2.get(2));
}
}
@Test
public void testExecuteQ() throws Exception {
Properties props = new Properties();
props.setProperty("preferQueryMode", "simple");
String sql1 = "drop table if exists t1; create table t1(id int, age int)";
String sql2 = "select ? from t1";
String sql2Record = "select%from t1";
List<Integer> beforeInfoSql2 = recordCount(sql2Record);
try (Connection conn = createConnection(props);
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql2)) {
stmt.execute(sql1);
setRecordFullSql(conn);
/* Q / Q */
pstmt.setString(1, "id");
pstmt.execute();
pstmt.setString(1, "age");
pstmt.execute();
sendPreTimeAndFlush(conn);
List<Integer> afterInfoSql2 = recordCount(sql2Record);
assertTrue(beforeInfoSql2.get(0) == afterInfoSql2.get(0));
assertTrue(beforeInfoSql2.get(1) == afterInfoSql2.get(1));
assertTrue(beforeInfoSql2.get(2) + 2 == afterInfoSql2.get(2));
}
}
}

View File

@ -1,119 +0,0 @@
package org.postgresql.jdbc;
import org.junit.Test;
import org.postgresql.test.jdbc2.BaseTest4;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ParameterInjectionTest extends BaseTest4 {
private interface ParameterBinder {
void bind(PreparedStatement stmt) throws SQLException;
}
public void testParamInjection(ParameterBinder bindPositiveOne, ParameterBinder bindNegativeOne) throws SQLException {
PreparedStatement stmt = con.prepareStatement("SELECT -?");
bindPositiveOne.bind(stmt);
try (ResultSet rs = stmt.executeQuery()) {
assertTrue(rs.next());
assertEquals(-1, rs.getInt(1));
}
bindNegativeOne.bind(stmt);
try (ResultSet rs = stmt.executeQuery()) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
}
PreparedStatement stmt2 = con.prepareStatement("SELECT -?, ?");
bindPositiveOne.bind(stmt2);
stmt2.setString(2, "\nWHERE 0 > 1");
try (ResultSet rs = stmt2.executeQuery()) {
assertTrue(rs.next());
assertEquals(-1, rs.getInt(1));
}
bindNegativeOne.bind(stmt2);
stmt2.setString(2, "\nWHERE 0 > 1");
try (ResultSet rs = stmt2.executeQuery()) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
}
}
@Test
public void handleInt2() throws SQLException {
testParamInjection(
stmt -> {
stmt.setShort(1, (short) 1);
},
stmt -> {
stmt.setShort(1, (short) -1);
}
);
}
@Test
public void handleInt4() throws SQLException {
testParamInjection(
stmt -> {
stmt.setInt(1, 1);
},
stmt -> {
stmt.setInt(1, -1);
}
);
}
@Test
public void handleBigInt() throws SQLException {
testParamInjection(
stmt -> {
stmt.setLong(1, (long) 1);
},
stmt -> {
stmt.setLong(1, (long) -1);
}
);
}
@Test
public void handleNumeric() throws SQLException {
testParamInjection(
stmt -> {
stmt.setBigDecimal(1, new BigDecimal("1"));
},
stmt -> {
stmt.setBigDecimal(1, new BigDecimal("-1"));
}
);
}
@Test
public void handleFloat() throws SQLException {
testParamInjection(
stmt -> {
stmt.setFloat(1, 1);
},
stmt -> {
stmt.setFloat(1, -1);
}
);
}
@Test
public void handleDouble() throws SQLException {
testParamInjection(
stmt -> {
stmt.setDouble(1, 1);
},
stmt -> {
stmt.setDouble(1, -1);
}
);
}
}

View File

@ -41,7 +41,6 @@ public class TestUtil {
*/
public static final String SERVER_HOST_PORT_PROP = "_test_hostport";
public static final String DATABASE_PROP = "_test_database";
private static String applicationName = "Driver Tests";
/*
* Returns the Test database JDBC URL
@ -51,10 +50,10 @@ public class TestUtil {
}
public static String getURL(String server, int port) {
return getURL(server + ":" + port, getDatabase(), applicationName);
return getURL(server + ":" + port, getDatabase());
}
public static String getURL(String hostport, String database, String applicationName) {
public static String getURL(String hostport, String database) {
String logLevel = "";
if (getLogLevel() != null && !getLogLevel().equals("")) {
logLevel = "&loggerLevel=" + getLogLevel();
@ -100,11 +99,10 @@ public class TestUtil {
allowEncodingChanges = "&allowEncodingChanges=" + getAllowEncodingChanges();
}
String application = "?ApplicationName=" + applicationName;
return "jdbc:postgresql://"
+ hostport + "/"
+ database
+ application
+ "?ApplicationName=Driver Tests"
+ logLevel
+ logFile
+ protocolVersion
@ -365,10 +363,6 @@ public class TestUtil {
return openDB(props,getDatabase());
}
public static Connection openDB(String dbName) throws Exception {
return openDB(new Properties(), dbName);
}
public static Connection openDBPG(Properties props) throws Exception {
return openDB(props,getDatabasePG());
}
@ -418,10 +412,7 @@ public class TestUtil {
String hostport = props.getProperty(SERVER_HOST_PORT_PROP, getServer() + ":" + getPort());
String database = props.getProperty(DATABASE_PROP, dbName);
if (props.containsKey("ApplicationName")) {
return DriverManager.getConnection(getURL(hostport, database, props.get("ApplicationName").toString()), props);
}
return DriverManager.getConnection(getURL(hostport, database, applicationName), props);
return DriverManager.getConnection(getURL(hostport, database), props);
}
/*

View File

@ -1,129 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* test binary
*
* @author zhangting
* @since 2024-08-20
*/
public class BinaryTest extends BaseTest4B {
@Test
public void testBinary1() throws SQLException {
TestUtil.createTable(con, "test_binary_b", "id int, c1 binary(5)");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_binary_b VALUES (?,?)")) {
pstmt.setInt(1, 1);
try (InputStream data = new ByteArrayInputStream("abcde".getBytes(StandardCharsets.UTF_8))) {
pstmt.setBinaryStream(2, data);
pstmt.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
String sql = "INSERT INTO test_binary_b VALUES (2,'abcde'::binary)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.execute();
}
try (Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM test_binary_b")) {
while (rs.next()) {
assertEquals("\\x6162636465", new String(rs.getBytes(2),
StandardCharsets.UTF_8));
}
}
TestUtil.dropTable(con, "test_binary_b");
}
@Test
public void testBinary2() throws SQLException {
try (Statement stat = con.createStatement()) {
try (ResultSet rs = stat.executeQuery("SELECT '10101'::binary(5)")) {
while (rs.next()) {
assertEquals("\\x3130313031", new String(rs.getBytes(1),
StandardCharsets.UTF_8));
}
}
try (ResultSet rs = stat.executeQuery("SELECT cast('abc' as binary)")) {
while (rs.next()) {
assertEquals("\\x616263", rs.getString(1));
}
}
stat.execute("set bytea_output=escape;");
try (ResultSet rs = stat.executeQuery("SELECT '10101'::binary(5)")) {
while (rs.next()) {
assertEquals("10101", new String(rs.getBytes(1),
StandardCharsets.UTF_8));
}
}
try (ResultSet rs = stat.executeQuery("SELECT cast('abc' as binary)")) {
while (rs.next()) {
assertEquals("abc", rs.getString(1));
}
}
}
}
/*
* test binary type
*/
@Test
public void testBinaryType() throws Exception {
TestUtil.createTable(con, "test_binary", "c1 binary,c2 binary(5),"
+ "c3 varbinary,c4 varbinary(5)");
try (Statement stat = con.createStatement()) {
stat.execute("set bytea_output=escape;");
stat.executeUpdate("INSERT INTO test_binary VALUES ('a','abcde','a','abcde')");
}
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_binary")) {
assertTrue(rs.next());
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(4, rsmd.getColumnCount());
assertEquals(Types.BINARY, rsmd.getColumnType(1));
assertEquals(Types.BINARY, rsmd.getColumnType(2));
assertEquals(Types.VARBINARY, rsmd.getColumnType(3));
assertEquals(Types.VARBINARY, rsmd.getColumnType(4));
assertEquals("a", rs.getString(1));
assertEquals("abcde", rs.getString(2));
assertEquals("a", rs.getString(3));
assertEquals("abcde", rs.getString(4));
}
TestUtil.dropTable(con, "test_binary");
}
}

View File

@ -1,88 +0,0 @@
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
public class BitTest extends BaseTest4B {
@Override
protected void openDB(Properties props) throws Exception {
props.put("bitOutput", "dec");
props.put("ApplicationName", "PostgreSQL JDBC Driver");
super.openDB(props);
}
/*
* Tests bit type
*/
@Test
public void testBit() throws Exception {
TestUtil.createTable(con, "test_bit", "c1 bit(1),c2 bit(10),c3 bit(6)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_bit VALUES (1, 12.569, 8.753)");
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT c1,c2,c3 FROM test_bit");
assertTrue(rs.next());
Object o1 = rs.getObject(1);
assertNotNull(o1);
assertEquals(true, o1);
String o2 = rs.getObject(2).getClass().toString();
assertNotNull(o2);
assertEquals("class [B", o2);
String o3 = rs.getObject(3).getClass().toString();
assertNotNull(o3);
assertEquals("class [B", o3);
TestUtil.dropTable(con, "test_bit");
}
/*
* Tests bit by getBytes()
*/
@Test
public void testBitToBytes() throws Exception {
TestUtil.createTable(con, "test_bitToBytes", "c1 bit(10),c2 bit(18)");
String sql = "INSERT INTO test_bitToBytes VALUES (123.45, 18437.567)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.executeUpdate();
}
try (Statement ps = con.createStatement();
ResultSet rs = ps.executeQuery("SELECT c1,c2 FROM test_bitToBytes")) {
assertTrue(rs.next());
String r1 = rs.getString(1);
assertNotNull(r1);
assertEquals("123", r1);
byte[] bytes1 = rs.getBytes(1);
assertNotNull(bytes1);
assertEquals(0, bytes1[0]);
assertEquals(123, bytes1[1]);
String r2 = rs.getString(2);
assertNotNull(r2);
assertEquals("18438", r2);
byte[] bytes2 = rs.getBytes(2);
assertNotNull(bytes2);
assertEquals(0, bytes2[0]);
assertEquals(72, bytes2[1]);
assertEquals(6, bytes2[2]);
} finally {
TestUtil.dropTable(con, "test_bitToBytes");
}
}
}

View File

@ -5,6 +5,7 @@
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.core.ServerVersion;
import org.postgresql.core.types.PGBlob;
import org.postgresql.jdbc.PgConnection;
import org.postgresql.test.TestUtil;
@ -17,11 +18,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class BlobTest extends BaseTest4B {
@ -109,56 +107,4 @@ public class BlobTest extends BaseTest4B {
}
}
}
@Test
public void testStringToBlob() throws SQLException {
String sql = "INSERT INTO test_blob_b VALUES (2,'1234'::tinyblob,"
+ "'1234'::blob,'1234'::mediumblob,'1234'::longblob)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.execute();
}
try (Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM test_blob_b")) {
while (rs.next()) {
assertEquals("1234", new String(rs.getBlob(2).getBytes(1, 4),
StandardCharsets.UTF_8));
assertEquals("1234", new String(rs.getBlob(3).getBytes(1, 4),
StandardCharsets.UTF_8));
assertEquals("1234", new String(rs.getBlob(4).getBytes(1, 4),
StandardCharsets.UTF_8));
assertEquals("1234", new String(rs.getBlob(5).getBytes(1, 4),
StandardCharsets.UTF_8));
}
}
}
/**
* test blob by getBytes
*
* @throws SQLException sql exception
*/
@Test
public void testBlobToBytes() throws SQLException {
String sql = "INSERT INTO test_blob_b VALUES (1,'abcd'::tinyblob,"
+ "'abcd'::blob,'abcd'::mediumblob,'abcd'::longblob)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.execute();
}
try (Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM test_blob_b")) {
assertTrue(rs.next());
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(Types.LONGVARBINARY, rsmd.getColumnType(3));
assertEquals("abcd", new String(rs.getBytes(2),
StandardCharsets.UTF_8));
assertEquals("abcd", new String(rs.getBytes(3),
StandardCharsets.UTF_8));
assertEquals("abcd", new String(rs.getBytes(4),
StandardCharsets.UTF_8));
assertEquals("abcd", new String(rs.getBytes(5),
StandardCharsets.UTF_8));
}
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* test date
*
* @author zhangting
* @since 2024-08-30
*/
public class DateTest extends BaseTest4B {
/*
* test Date type
*/
@Test
public void testDate() throws Exception {
TestUtil.createTable(con, "test_date", "id date");
String sql = "INSERT INTO test_date VALUES (?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setString(1, "0000-01-01");
pstmt.executeUpdate();
pstmt.setString(1, "epoch");
pstmt.executeUpdate();
}
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_date")) {
assertTrue(rs.next());
assertEquals("0001-01-01", rs.getObject(1).toString());
assertTrue(rs.next());
assertEquals("1970-01-01", rs.getObject(1).toString());
}
TestUtil.dropTable(con, "test_date");
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* test default type
*
* @author zhangting
* @since 2024-09-04
*/
public class DefaultTypeTest extends BaseTest4B {
/*
* test Date type
*/
@Test
public void testDefaultType() throws Exception {
TestUtil.createTable(con, "test_default_type",
"c1 set('abc','ttp','mytest'),c2 enum('2012','2013','2014')");
String sql = "INSERT INTO test_default_type VALUES ('abc','2014')";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.executeUpdate();
}
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_default_type")) {
assertTrue(rs.next());
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(2, rsmd.getColumnCount());
assertEquals(Types.CHAR, rsmd.getColumnType(1));
assertEquals(Types.CHAR, rsmd.getColumnType(2));
assertEquals("abc", rs.getString(1));
assertEquals("2014", rs.getString(2));
}
TestUtil.dropTable(con, "test_default_type");
}
}

View File

@ -1,145 +0,0 @@
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class IntTest extends BaseTest4B {
/*
* Tests tinyint1 to boolean
*/
@Test
public void testTinyint1() throws Exception {
TestUtil.createTable(con, "test_tinyint", "id tinyint(1)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_tinyint VALUES (?)");
pstmt.setObject(1, 18, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, 106, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, -1, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, 0, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, -10, Types.INTEGER);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_tinyint");
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(true, r1);
assertTrue(rs.next());
Object r2 = rs.getObject(1);
assertNotNull(r2);
assertEquals(true, r2);
assertTrue(rs.next());
Object r3 = rs.getObject(1);
assertNotNull(r3);
assertEquals(true, r3);
assertTrue(rs.next());
Object r4 = rs.getObject(1);
assertNotNull(r4);
assertEquals(false, r4);
assertTrue(rs.next());
Object r5 = rs.getObject(1);
assertNotNull(r5);
assertEquals(false, r5);
TestUtil.dropTable(con, "test_tinyint");
}
/*
* Tests tinyint2
*/
@Test
public void testTinyint2() throws Exception {
TestUtil.createTable(con, "test_tinyint2", "id tinyint(2),id2 smallint(1)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_tinyint2 VALUES (?,?)");
pstmt.setObject(1, 25, Types.INTEGER);
pstmt.setObject(2, 36, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, -24, Types.INTEGER);
pstmt.setObject(2, -54, Types.INTEGER);
pstmt.executeUpdate();
pstmt.setObject(1, 0, Types.INTEGER);
pstmt.setObject(2, 0, Types.INTEGER);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id,id2 FROM test_tinyint2");
assertTrue(rs.next());
Object r11 = rs.getObject(1);
assertNotNull(r11);
assertEquals(25, r11);
Object r12 = rs.getObject(2);
assertNotNull(r12);
assertEquals(36, r12);
assertTrue(rs.next());
Object r21 = rs.getObject(1);
assertNotNull(r21);
assertEquals(-24, r21);
Object r22 = rs.getObject(2);
assertNotNull(r22);
assertEquals(-54, r22);
assertTrue(rs.next());
Object r31 = rs.getObject(1);
assertNotNull(r31);
assertEquals(0, r31);
Object r32 = rs.getObject(2);
assertNotNull(r32);
assertEquals(0, r32);
TestUtil.dropTable(con, "test_tinyint2");
}
/*
* Tests int type
*/
@Test
public void testIntType() throws Exception {
TestUtil.createTable(con, "test_int", "c1 int1,c2 int2,c3 int4,"
+ "c4 int8,uc1 uint1,uc2 uint2,uc3 uint4,uc4 uint8");
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_int")) {
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(8, rsmd.getColumnCount());
assertEquals(Types.TINYINT, rsmd.getColumnType(1));
assertEquals(Types.SMALLINT, rsmd.getColumnType(2));
assertEquals(Types.INTEGER, rsmd.getColumnType(3));
assertEquals(Types.BIGINT, rsmd.getColumnType(4));
assertEquals(Types.TINYINT, rsmd.getColumnType(5));
assertEquals(Types.SMALLINT, rsmd.getColumnType(6));
assertEquals(Types.INTEGER, rsmd.getColumnType(7));
assertEquals(Types.BIGINT, rsmd.getColumnType(8));
} finally {
TestUtil.dropTable(con, "test_int");
}
}
}

View File

@ -1,116 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
/**
* test null
*
* @author zhangting
* @since 2024-08-05
*/
public class NullTest extends BaseTest4B {
@Test
public void testStringNull() throws Exception {
TestUtil.createTable(con, "test_null", "id varchar, id2 varchar");
try (Statement statement = con.createStatement()) {
statement.execute("INSERT INTO test_null VALUES ('acc','uu'),('ptv','bb'),('mtt','gf')");
}
String sql = "select id,id2 from test_null where id in (?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setObject(1, "ptv");
pstmt.setNull(2, -3);
try (ResultSet rs = pstmt.executeQuery()) {
assertTrue(rs.next());
String s1 = rs.getString(1);
assertNotNull(s1);
assertEquals("ptv", s1);
String s2 = rs.getString(2);
assertNotNull(s2);
assertEquals("bb", s2);
}
}
TestUtil.dropTable(con, "test_null");
}
@Test
public void testIntNull() throws Exception {
TestUtil.createTable(con, "test_null", "id int, id2 int");
try (Statement statement = con.createStatement()) {
statement.execute("INSERT INTO test_null VALUES (51,34),(92,44),(67,88)");
}
String sql = "select id,id2 from test_null where id in (?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setInt(1, 92);
pstmt.setNull(2, 1111);
try (ResultSet rs = pstmt.executeQuery()) {
assertTrue(rs.next());
int r1 = rs.getInt(1);
assertNotNull(r1);
assertEquals(92, r1);
int r2 = rs.getInt(2);
assertNotNull(r2);
assertEquals(44, r2);
}
}
TestUtil.dropTable(con, "test_null");
}
@Test
public void testDateNull() throws Exception {
TestUtil.createTable(con, "test_null", "id date, id2 varchar");
try (Statement statement = con.createStatement()) {
statement.execute("INSERT INTO test_null VALUES ('2024-05-02','n1')");
statement.execute("INSERT INTO test_null VALUES ('2024-03-15','n2')");
statement.execute("INSERT INTO test_null VALUES ('2024-06-07','n3')");
}
String sql = "select id,id2 from test_null where id in (?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setObject(1, "2024-03-15");
pstmt.setNull(2, -2);
try (ResultSet rs = pstmt.executeQuery()) {
assertTrue(rs.next());
Date r1 = rs.getDate(1);
assertNotNull(r1);
Date d1 = new SimpleDateFormat("yyyy-MM-dd").parse("2024-03-15");
assertEquals(d1, r1);
String r2 = rs.getString(2);
assertNotNull(r2);
assertEquals("n2", r2);
}
}
TestUtil.dropTable(con, "test_null");
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
/**
* test numeric
*
* @author zhangting
* @since 2024-08-20
*/
public class NumericTest extends BaseTest4B {
/*
* test numeric type
*/
@Test
public void testNumeric() throws Exception {
TestUtil.createTable(con, "test_numeric", "c1 numeric,c2 numeric(8,4),c3 float,"
+ "c4 float(8,4),c5 double,c6 double(8,4),c7 real,c8 real(8,4),c9 decimal(8,4)");
String sql = "INSERT INTO test_numeric VALUES (?,?,?,?,?,?,?,?,?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
for (int i = 1; i <= 9; i++) {
pstmt.setDouble(i, 92.456739023);
}
pstmt.executeUpdate();
}
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_numeric")) {
assertTrue(rs.next());
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(9, rsmd.getColumnCount());
assertEquals(Types.DECIMAL, rsmd.getColumnType(1));
assertEquals(Types.DECIMAL, rsmd.getColumnType(2));
assertEquals(Types.REAL, rsmd.getColumnType(3));
assertEquals(Types.DECIMAL, rsmd.getColumnType(4));
assertEquals(Types.DOUBLE, rsmd.getColumnType(5));
assertEquals(Types.DECIMAL, rsmd.getColumnType(6));
assertEquals(Types.REAL, rsmd.getColumnType(7));
assertEquals(Types.DECIMAL, rsmd.getColumnType(8));
assertEquals(Types.DECIMAL, rsmd.getColumnType(9));
assertEquals(new BigDecimal(92), rs.getObject(1));
assertEquals(new String("92.4567"), rs.getString(2));
assertEquals(new String("92.4567"), rs.getString(4));
assertEquals(new String("92.4567"), rs.getString(6));
assertEquals(new String("92.4567"), rs.getString(8));
assertEquals(new String("92.4567"), rs.getString(9));
}
TestUtil.dropTable(con, "test_numeric");
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
/**
* test raw
*
* @author zhangting
* @since 2024-09-10
*/
public class RawTest extends BaseTest4B {
/*
* test raw type
*/
@Test
public void testRaw() throws Exception {
TestUtil.createTable(con, "test_raw", "c1 blob,c2 raw,c3 bytea");
try (Statement statement = con.createStatement()) {
statement.execute("set bytea_output=escape;");
statement.execute("INSERT INTO test_raw VALUES (empty_blob(),hextoraw('deadbeef'),e'\\\\xdeadbeef')");
statement.execute("INSERT INTO test_raw VALUES ('null','null','null')");
}
String sql = "select c1,c2,c3 from test_raw";
try (PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
assertTrue(rs.next());
assertEquals("", rs.getString(1));
assertEquals("deadbeef", rs.getString(2));
assertEquals("\\336\\255\\276\\357", rs.getString(3));
assertTrue(rs.next());
assertEquals("null", rs.getString(1));
assertEquals("null", rs.getString(2));
assertEquals("null", rs.getString(3));
}
TestUtil.dropTable(con, "test_raw");
}
}

View File

@ -7,9 +7,6 @@ import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@ -45,51 +42,4 @@ public class TimeTest extends BaseTest4B {
TestUtil.dropTable(con, "test_time");
}
@Test
public void testYearToDate() throws SQLException, ParseException {
TestUtil.createTable(con, "test_year", "c date,c2 year default '2024'");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_year(c) VALUES (?);");
pstmt.setObject(1, "2023-05-20", Types.DATE);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT c2 FROM test_year");
assertTrue(rs.next());
Object c21 = rs.getObject(1);
assertNotNull(c21);
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-01-01");
assertEquals(date, c21);
Date c22 = rs.getDate(1);
assertNotNull(c22);
assertEquals(date, c22);
TestUtil.dropTable(con, "test_year");
}
@Test
public void testAsTime() throws SQLException {
TestUtil.createTable(con, "test_as_time", "id int");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_as_time VALUES (?);");
pstmt.setObject(1, -11);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT cast(id as time) from test_as_time");
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals("00:00:11", r1.toString());
String r2 = rs.getString(1);
assertNotNull(r2);
assertEquals("00:00:11", r2);
Time r3 = rs.getTime(1);
assertNotNull(r3);
assertEquals("00:00:11", r3.toString());
TestUtil.dropTable(con, "test_as_time");
}
}

View File

@ -1,155 +0,0 @@
package org.postgresql.test.dolphintest;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
public class TimestampTest extends BaseTest4B {
@Test
public void testTimeZone() throws Exception {
TestUtil.createTable(con, "test_timestamp", "id int");
String createSql = "INSERT INTO test_timestamp VALUES (1)";
try (PreparedStatement pstmt = con.prepareStatement(createSql)) {
pstmt.execute();
}
String updateSql = "UPDATE test_timestamp SET id = timestampdiff(second,?,?)";
try (PreparedStatement pstmt2 = con.prepareStatement(updateSql)) {
java.util.Date start = new java.util.Date();
pstmt2.setTimestamp(1, new Timestamp(start.getTime()));
pstmt2.setTimestamp(2, new Timestamp(start.getTime() + 6000));
pstmt2.execute();
}
String selectSql = "SELECT id FROM test_timestamp";
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(selectSql)) {
assertTrue(rs.next());
int r1 = rs.getInt(1);
assertNotNull(r1);
assertEquals(6, r1);
}
TestUtil.dropTable(con, "test_timestamp");
}
@Test
public void testTimeZone2() throws Exception {
TestUtil.createTable(con, "test_timeZone", "id timestamp");
String sql = "INSERT INTO test_timeZone VALUES (?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
java.util.Date start = new java.util.Date();
pstmt.setTimestamp(1, new Timestamp(start.getTime()));
pstmt.execute();
}
TestUtil.dropTable(con, "test_timeZone");
}
@Test
public void testTimeRange() throws Exception {
TestUtil.createTable(con, "test_TimeRange", "id int, c2 timestamp");
String sql = "INSERT INTO test_TimeRange VALUES (?, ?)";
java.util.Date start = new java.util.Date();
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setInt(1, 1);
pstmt.setTimestamp(2, new Timestamp(start.getTime() - 100000));
pstmt.execute();
pstmt.setInt(1, 2);
pstmt.setTimestamp(2, new Timestamp(start.getTime()));
pstmt.execute();
pstmt.setInt(1, 3);
pstmt.setTimestamp(2, new Timestamp(start.getTime() + 500000));
pstmt.execute();
pstmt.setInt(1, 4);
pstmt.setTimestamp(2, new Timestamp(start.getTime() + 1000000000));
pstmt.execute();
}
String selectSql = "select id, c2 from test_TimeRange where c2 between ? and ?;";
try (PreparedStatement pstmt2 = con.prepareStatement(selectSql)) {
pstmt2.setTimestamp(1, new Timestamp(start.getTime()-5000));
pstmt2.setTimestamp(2, new Timestamp(start.getTime() + 800000));
try (ResultSet rs = pstmt2.executeQuery()) {
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
}
}
String selectSql2 = "select id, c2 from test_TimeRange where c2 >= ? and c2 <= ?;";
try (PreparedStatement pstmt2 = con.prepareStatement(selectSql2)) {
pstmt2.setTimestamp(1, new Timestamp(start.getTime()-5000));
pstmt2.setTimestamp(2, new Timestamp(start.getTime() + 800000));
try (ResultSet rs = pstmt2.executeQuery()) {
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
}
}
TestUtil.dropTable(con, "test_TimeRange");
}
@Test
public void testYear2() throws Exception {
TestUtil.createTable(con, "test_year2", "id year(2)");
try (Statement stat = con.createStatement()) {
stat.execute("INSERT INTO test_year2 VALUES (8),(69),(70),(82)");
}
String sql5 = "select id from test_year2";
try (PreparedStatement pstmt2 = con.prepareStatement(sql5);
ResultSet rs = pstmt2.executeQuery()) {
assertTrue(rs.next());
Date d1 = rs.getDate(1);
assertNotNull(d1);
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-01-01");
assertEquals(date, d1);
String s1 = rs.getString(1);
assertEquals("2008-01-01", s1);
assertTrue(rs.next());
Date d2 = rs.getDate(1);
assertNotNull(d2);
Date date2 = new SimpleDateFormat("yyyy-MM-dd").parse("2069-01-01");
assertEquals(date2, d2);
String s2 = rs.getString(1);
assertEquals("2069-01-01", s2);
assertTrue(rs.next());
Date d3 = rs.getDate(1);
assertNotNull(d3);
Date date3 = new SimpleDateFormat("yyyy-MM-dd").parse("1970-01-01");
assertEquals(date3, d3);
String s3 = rs.getString(1);
assertEquals("1970-01-01", s3);
assertTrue(rs.next());
Date d4 = rs.getDate(1);
assertNotNull(d4);
Date date4 = new SimpleDateFormat("yyyy-MM-dd").parse("1982-01-01");
assertEquals(date4, d4);
String s4 = rs.getString(1);
assertEquals("1982-01-01", s4);
}
TestUtil.dropTable(con, "test_year2");
}
}

View File

@ -2,21 +2,15 @@ package org.postgresql.test.dolphintest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4B;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Array;
import java.sql.*;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.*;
public class UnsignedTest extends BaseTest4B {
/**
@ -27,20 +21,19 @@ public class UnsignedTest extends BaseTest4B {
public void testUint1() throws SQLException {
TestUtil.createTable(con, "test_unit1", "id uint1");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit1 VALUES (?)")) {
pstmt.setObject(1, 234, Types.SMALLINT);
pstmt.executeUpdate();
}
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit1 VALUES (?)");
pstmt.setObject(1, 234, Types.SMALLINT);
pstmt.executeUpdate();
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit1");) {
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(234, r1);
} finally {
TestUtil.dropTable(con, "test_unit1");
}
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit1");
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(234, r1);
TestUtil.dropTable(con, "test_unit1");
}
/**
@ -51,20 +44,19 @@ public class UnsignedTest extends BaseTest4B {
public void testUint2() throws SQLException {
TestUtil.createTable(con, "test_unit2", "id uint2");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit2 VALUES (?)")) {
pstmt.setObject(1, 65518, Types.INTEGER);
pstmt.executeUpdate();
}
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit2 VALUES (?)");
pstmt.setObject(1, 65518, Types.INTEGER);
pstmt.executeUpdate();
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit2")) {
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(65518, r1);
} finally {
TestUtil.dropTable(con, "test_unit2");
}
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit2");
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(65518, r1);
TestUtil.dropTable(con, "test_unit2");
}
/**
@ -75,20 +67,20 @@ public class UnsignedTest extends BaseTest4B {
public void testUint4() throws SQLException {
TestUtil.createTable(con, "test_unit4", "id uint4");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit4 VALUES (?)")) {
pstmt.setObject(1, 4294967282L, Types.BIGINT);
pstmt.executeUpdate();
}
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit4 VALUES (?)");
long l = 4294967282L;
pstmt.setObject(1, l, Types.BIGINT);
pstmt.executeUpdate();
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit4")) {
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(4294967282L, r1);
} finally {
TestUtil.dropTable(con, "test_unit4");
}
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit4");
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(l, r1);
TestUtil.dropTable(con, "test_unit4");
}
/**
@ -98,113 +90,29 @@ public class UnsignedTest extends BaseTest4B {
@Test
public void testUint8() throws SQLException {
TestUtil.createTable(con, "test_unit8", "id uint8");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit8 VALUES (?)");
BigInteger b = new BigInteger("9223372036859999999");
pstmt.setObject(1, b, Types.NUMERIC);
pstmt.executeUpdate();
BigInteger b2 = new BigInteger("15223372036859999999");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_unit8 VALUES (?)")) {
pstmt.setObject(1, b, Types.NUMERIC);
pstmt.executeUpdate();
pstmt.setObject(1, b2, Types.NUMERIC);
pstmt.executeUpdate();
pstmt.setObject(1, b2, Types.NUMERIC);
pstmt.executeUpdate();
}
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit8");
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id FROM test_unit8")) {
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(b, r1);
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(b, r1);
assertTrue(rs.next());
Object r2 = rs.getObject(1);
assertNotNull(r2);
assertEquals(b2, r2);
} finally {
TestUtil.dropTable(con, "test_unit8");
}
}
assertTrue(rs.next());
Object r2 = rs.getObject(1);
assertNotNull(r2);
assertEquals(b2, r2);
@Test
public void testCreateArrayOfUint1() throws SQLException {
try (PreparedStatement pstmt = con.prepareStatement("SELECT ?::uint1[]")) {
Object[] in = new Object[3];
in[0] = 0;
in[1] = 88;
in[2] = 115;
pstmt.setArray(1, con.createArrayOf("uint1", in));
try (ResultSet rs = pstmt.executeQuery()) {
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Object[] out = (Object[]) arr.getArray();
Assert.assertEquals(3, out.length);
Assert.assertEquals(0, Integer.parseInt(out[0].toString()));
Assert.assertEquals(88, Integer.parseInt(out[1].toString()));
Assert.assertEquals(115, Integer.parseInt(out[2].toString()));
}
}
}
@Test
public void testCreateArrayOfUint2() throws SQLException {
try (PreparedStatement pstmt = con.prepareStatement("SELECT ?::uint2[]")) {
Short[] in = new Short[3];
in[0] = 0;
in[1] = 12654;
in[2] = 30035;
pstmt.setArray(1, con.createArrayOf("uint2", in));
try (ResultSet rs = pstmt.executeQuery()) {
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Short[] out = (Short[]) arr.getArray();
Assert.assertEquals(3, out.length);
Assert.assertEquals(0, out[0].shortValue());
Assert.assertEquals(12654, out[1].shortValue());
Assert.assertEquals(30035, out[2].shortValue());
}
}
}
@Test
public void testCreateArrayOfUint4() throws SQLException {
try (PreparedStatement pstmt = con.prepareStatement("SELECT ?::uint4[]")) {
Integer[] in = new Integer[2];
in[0] = 0;
in[1] = 1994967295;
pstmt.setArray(1, con.createArrayOf("uint4", in));
try (ResultSet rs = pstmt.executeQuery()) {
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Integer[] out = (Integer[]) arr.getArray();
Assert.assertEquals(2, out.length);
Assert.assertEquals(0, out[0].intValue());
Assert.assertEquals(1994967295, out[1].intValue());
}
}
}
@Test
public void testCreateArrayOfUint8() throws SQLException {
try (PreparedStatement pstmt = con.prepareStatement("SELECT ?::uint8[]")) {
Long[] in = new Long[2];
in[0] = 0L;
in[1] = 32458765334567556L;
pstmt.setArray(1, con.createArrayOf("uint8", in));
try (ResultSet rs = pstmt.executeQuery()) {
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Object[] out = (Object[]) arr.getArray();
Long[] outLong = new Long[out.length];
for (int i = 0; i < out.length; i++) {
outLong[i] = Long.valueOf(out[i].toString());
}
Assert.assertEquals(2, out.length);
Assert.assertEquals(0L, outLong[0].longValue());
Assert.assertEquals(32458765334567556L, outLong[1].longValue());
}
}
TestUtil.dropTable(con, "test_unit8");
}
}

View File

@ -109,7 +109,7 @@ public class ArrayTest extends BaseTest4 {
assertEquals(3, intarr[2].intValue());
arr = rs.getArray(2);
assertEquals(Types.DECIMAL, arr.getBaseType());
assertEquals(Types.NUMERIC, arr.getBaseType());
BigDecimal[] decarr = (BigDecimal[]) arr.getArray();
assertEquals(2, decarr.length);
assertEquals(new BigDecimal("3.1"), decarr[0]);
@ -151,7 +151,7 @@ public class ArrayTest extends BaseTest4 {
Assert.assertEquals(3, intarr[2].intValue());
arr = rs.getArray(2);
Assert.assertEquals(Types.DECIMAL, arr.getBaseType());
Assert.assertEquals(Types.NUMERIC, arr.getBaseType());
BigDecimal[] decarr = (BigDecimal[]) arr.getArray();
Assert.assertEquals(2, decarr.length);
Assert.assertEquals(new BigDecimal("3.1"), decarr[0]);
@ -223,7 +223,7 @@ public class ArrayTest extends BaseTest4 {
Assert.assertEquals(3, intarr[2].intValue());
arr = rs.getArray(2);
Assert.assertEquals(Types.DECIMAL, arr.getBaseType());
Assert.assertEquals(Types.NUMERIC, arr.getBaseType());
BigDecimal[] decarr = (BigDecimal[]) arr.getArray();
Assert.assertEquals(2, decarr.length);
Assert.assertEquals(new BigDecimal("3.1"), decarr[0]);
@ -271,7 +271,7 @@ public class ArrayTest extends BaseTest4 {
arrrs.close();
arr = rs.getArray(2);
Assert.assertEquals(Types.DECIMAL, arr.getBaseType());
Assert.assertEquals(Types.NUMERIC, arr.getBaseType());
arrrs = arr.getResultSet();
Assert.assertTrue(arrrs.next());
Assert.assertEquals(new BigDecimal("3.1"), arrrs.getBigDecimal(2));

View File

@ -171,7 +171,7 @@ public class CallableStmtTest extends BaseTest4 {
assumeCallableStatementsSupported();
CallableStatement call = con.prepareCall(func + pkgName + "getNumeric (?) }");
call.setBigDecimal(2, new java.math.BigDecimal(4));
call.registerOutParameter(1, Types.DECIMAL);
call.registerOutParameter(1, Types.NUMERIC);
call.execute();
assertEquals(new java.math.BigDecimal(42), call.getBigDecimal(1));
}
@ -180,7 +180,7 @@ public class CallableStmtTest extends BaseTest4 {
public void testGetNumericWithoutArg() throws Throwable {
assumeCallableStatementsSupported();
CallableStatement call = con.prepareCall(func + pkgName + "getNumericWithoutArg () }");
call.registerOutParameter(1, Types.DECIMAL);
call.registerOutParameter(1, Types.NUMERIC);
call.execute();
assertEquals(new java.math.BigDecimal(42), call.getBigDecimal(1));
}

View File

@ -1332,38 +1332,4 @@ public class DatabaseMetaDataTest {
}
}
@Test
public void testPrimaryKey() throws SQLException {
try (Statement stmt = con.createStatement()) {
stmt.execute("drop table if exists test_metadata");
stmt.execute("CREATE TABLE test_metadata (\n"
+ " col_pk numeric NOT NULL primary key,\n"
+ " partition_col character varying(30) NOT NULL\n"
+ ")\n"
+ "WITH (orientation=row, compression=no)\n"
+ "PARTITION BY LIST (partition_col)\n"
+ "(\n"
+ " PARTITION partition_col_id_0100 VALUES ('0100') ,\n"
+ " PARTITION partition_col_id_0110 VALUES ('0110') ,\n"
+ " PARTITION partition_col_id_other VALUES (DEFAULT)\n"
+ ");");
}
DatabaseMetaData metaData = con.getMetaData();
try (ResultSet rs = metaData.getPrimaryKeys("", "public", "test_metadata")) {
assertTrue(rs.next());
assertEquals("col_pk", rs.getString(4));
assertEquals(1, rs.getInt(5));
assertFalse(rs.next());
}
try (ResultSet rs1 = metaData.getIndexInfo("", "public",
"test_metadata", true, true)) {
assertTrue(rs1.next());
assertEquals("test_metadata_pkey", rs1.getString(6));
assertEquals("col_pk", rs1.getString(9));
assertFalse(rs1.next());
}
TestUtil.dropTable(con, "test_metadata");
}
}

View File

@ -15,7 +15,6 @@ import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Locale;
/**
@ -36,7 +35,6 @@ public class EncodingTest {
@Test
public void testTransformations() throws Exception {
Encoding encoding = Encoding.getDatabaseEncoding("UTF8");
assertTrue(encoding.hasAsciiNumbers());
assertEquals("ab", encoding.decode(new byte[]{97, 98}));
assertEquals(2, encoding.encode("ab").length);
@ -57,31 +55,4 @@ public class EncodingTest {
assertEquals(98, reader.read());
assertEquals(-1, reader.read());
}
@Test
public void testEncodingWithNull() {
try {
Encoding encoding = Encoding.getDatabaseEncoding(null);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Null charset name");
}
}
@Test
public void testGetJVMEncoding() {
Encoding encoding = Encoding.getJVMEncoding("UTF8");
assertEquals(encoding.name(), "UTF-8");
Encoding encodingGBK = Encoding.getJVMEncoding("GBK");
assertEquals(encodingGBK.name(), "GBK");
Encoding encodingWrong = Encoding.getJVMEncoding("encodingWrong");
assertEquals(encodingWrong.name(), Charset.defaultCharset().name());
}
@Test
public void testDefaultEncoding() {
Charset.defaultCharset();
assertEquals(Encoding.defaultEncoding().name(), Charset.defaultCharset().name());
}
}

View File

@ -129,8 +129,7 @@ import org.junit.runners.Suite;
CopyTest.class,
CopyLargeFileTest.class,
UpsertTest.class,
OuterJoinSyntaxTest.class,
NumericNegScaleTest.class
OuterJoinSyntaxTest.class
})
public class Jdbc2TestSuite {
}

View File

@ -1,122 +0,0 @@
package org.postgresql.test.jdbc2;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.postgresql.jdbc.TypeInfoCache.FLOATSCALE;
import static org.postgresql.jdbc.TypeInfoCache.NUMERIC_MAX_DISPLAYSIZE;
public class NumericNegScaleTest extends BaseTest4 {
@Test
public void testFloat() throws Exception {
TestUtil.execute("set behavior_compat_options='float_as_numeric'", con);
TestUtil.createTable(con, "test_float", "col1 float(1), col2 float(23), col3 float(126)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_float VALUES (?,?,?)");
BigDecimal n1 = new BigDecimal("1.8355454812");
pstmt.setObject(1, n1, Types.NUMERIC);
pstmt.setObject(2, n1, Types.NUMERIC);
pstmt.setObject(3, n1, Types.NUMERIC);
pstmt.executeUpdate();
n1 = BigDecimal.valueOf(1234567890);
pstmt.setObject(1, n1, Types.NUMERIC);
pstmt.setObject(2, n1, Types.NUMERIC);
pstmt.setObject(3, n1, Types.NUMERIC);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_float");
int[] precision_arr = {0, 1, 23, 126};
for (int i=1; i<4; i++)
{
assertEquals(rs.getMetaData().getPrecision(i), precision_arr[i]);
assertEquals(rs.getMetaData().getScale(i), FLOATSCALE);
assertEquals(rs.getMetaData().getColumnDisplaySize(i), NUMERIC_MAX_DISPLAYSIZE);
}
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(BigDecimal.valueOf(2), r1);
Object r2 = rs.getObject(2);
assertNotNull(r2);
assertEquals(BigDecimal.valueOf(1.835545), r2);
Object r3 = rs.getObject(3);
assertNotNull(r3);
assertEquals(BigDecimal.valueOf(1.8355454812), r3);
assertTrue(rs.next());
r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(BigDecimal.valueOf(1000000000), r1);
r2 = rs.getObject(2);
assertNotNull(r2);
assertEquals(BigDecimal.valueOf(1234568000), r2);
r3 = rs.getObject(3);
assertNotNull(r3);
assertEquals(BigDecimal.valueOf(1234567890), r3);
rs.close();
TestUtil.execute("set behavior_compat_options=''", con);
TestUtil.dropTable(con, "test_float");
}
@Test
public void testNegScale() throws Exception {
TestUtil.createTable(con, "test_neg_scale", "col1 numeric(4,-3), col2 numeric(3,-4)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_neg_scale VALUES (?,?)");
BigDecimal n1 = new BigDecimal("1.8355454812");
pstmt.setObject(1, n1, Types.NUMERIC);
pstmt.setObject(2, n1, Types.NUMERIC);
pstmt.executeUpdate();
n1 = BigDecimal.valueOf(1234567);
pstmt.setObject(1, n1, Types.NUMERIC);
pstmt.setObject(2, n1, Types.NUMERIC);
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_neg_scale");
int[][] typmod_arr = {{0}, {4, -3}, {3, -4}};
for (int i=1; i<3; i++)
{
assertEquals(rs.getMetaData().getPrecision(i), typmod_arr[i][0]);
assertEquals(rs.getMetaData().getScale(i), typmod_arr[i][1]);
assertEquals(rs.getMetaData().getColumnDisplaySize(i), 8);
}
assertTrue(rs.next());
Object r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(BigDecimal.valueOf(0), r1);
Object r2 = rs.getObject(2);
assertNotNull(r2);
assertEquals(BigDecimal.valueOf(0), r2);
assertTrue(rs.next());
r1 = rs.getObject(1);
assertNotNull(r1);
assertEquals(BigDecimal.valueOf(1235000), r1);
r2 = rs.getObject(2);
assertNotNull(r2);
assertEquals(BigDecimal.valueOf(1230000), r2);
rs.close();
TestUtil.dropTable(con, "test_neg_scale");
}
}

View File

@ -75,7 +75,7 @@ public class OptionTest extends BaseTest4 {
assertEquals(value, s);
// behavior_compat_options_name duplicate option
s = setOptionsAndGet(behaviorCompatOptionsName, "hide_tailing_zero,hide_tailing_zero");
assertEquals("hide_tailing_zero", s);
assertEquals("hide_tailing_zero,hide_tailing_zero", s);
// options applied failed
optionsBehaviorCompatOptionsFailed(behaviorCompatOptionsName, "''");
optionsBehaviorCompatOptionsFailed(behaviorCompatOptionsName, "hide_tailing_zero,,");

View File

@ -153,7 +153,6 @@ public class PGPropertyTest {
excluded.add("enableStatementLoadBalance");
excluded.add("writeDataSourceAddress");
excluded.add("BCmptMode");
excluded.add("bitOutput");
// index PropertyDescriptors by name
Map<String, PropertyDescriptor> propertyDescriptors =

View File

@ -328,8 +328,8 @@ public class PgCallableStatementTest extends BaseTest4 {
String queryStr = "{? = call fn_ty_in_ty_out3(?)}";
cmt = con.prepareCall(queryStr);
{
cmt.registerOutParameter(1, Types.DECIMAL);
cmt.registerOutParameter(2, Types.DECIMAL);
cmt.registerOutParameter(1, Types.NUMERIC);
cmt.registerOutParameter(2, Types.NUMERIC);
}
cmt.execute();
assertEquals(new BigDecimal(0), cmt.getObject(1));

View File

@ -35,6 +35,9 @@ import java.util.UUID;
@RunWith(Parameterized.class)
public class ArrayTest extends BaseTest4 {
private Connection _conn;
public ArrayTest(BinaryMode binaryMode) {
setBinaryMode(binaryMode);
}
@ -51,24 +54,26 @@ public class ArrayTest extends BaseTest4 {
@Override
public void setUp() throws Exception {
super.setUp();
TestUtil.createTable(con, "arrtest",
_conn = con;
TestUtil.createTable(_conn, "arrtest",
"intarr int[], decarr decimal(2,1)[], strarr text[]"
+ (TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_3) ? ", uuidarr uuid[]" : "")
+ (TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3) ? ", uuidarr uuid[]" : "")
+ ", floatarr float8[]"
+ ", intarr2 int4[][]");
TestUtil.createTable(con, "arrcompprnttest", "id serial, name character(10)");
TestUtil.createTable(con, "arrcompchldttest",
TestUtil.createTable(_conn, "arrcompprnttest", "id serial, name character(10)");
TestUtil.createTable(_conn, "arrcompchldttest",
"id serial, name character(10), description character varying, parent integer");
TestUtil.createTable(con, "\"correctcasing\"", "id serial");
TestUtil.createTable(con, "\"evil.table\"", "id serial");
TestUtil.createTable(_conn, "\"correctcasing\"", "id serial");
TestUtil.createTable(_conn, "\"evil.table\"", "id serial");
}
@Override
public void tearDown() throws SQLException {
TestUtil.dropTable(con, "arrtest");
TestUtil.dropTable(con, "arrcompprnttest");
TestUtil.dropTable(con, "arrcompchldttest");
TestUtil.dropTable(con, "\"CorrectCasing\"");
TestUtil.dropTable(_conn, "arrtest");
TestUtil.dropTable(_conn, "arrcompprnttest");
TestUtil.dropTable(_conn, "arrcompchldttest");
TestUtil.dropTable(_conn, "\"CorrectCasing\"");
super.tearDown();
}
@ -76,8 +81,8 @@ public class ArrayTest extends BaseTest4 {
@Ignore
// TODO PG修复了这个
public void testCreateArrayOfBool() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("SELECT ?::bool[]");
Array list= con.createArrayOf("boolean", new Object[]{ true, true, false });
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::bool[]");
Array list= _conn.createArrayOf("boolean", new Object[]{ true, true, false });
pstmt.setArray(1, list);
ResultSet rs = pstmt.executeQuery();
@ -93,12 +98,12 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCreateArrayOfInt() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("SELECT ?::int[]");
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::int[]");
Integer[] in = new Integer[3];
in[0] = 0;
in[1] = -1;
in[2] = 2;
pstmt.setArray(1, con.createArrayOf("int4", in));
pstmt.setArray(1, _conn.createArrayOf("int4", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
@ -113,12 +118,12 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCreateArrayOfSmallInt() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("SELECT ?::smallint[]");
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::smallint[]");
Short[] in = new Short[3];
in[0] = 0;
in[1] = -1;
in[2] = 2;
pstmt.setArray(1, con.createArrayOf("int2", in));
pstmt.setArray(1, _conn.createArrayOf("int2", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
@ -133,13 +138,13 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCreateArrayOfMultiString() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("SELECT ?::text[]");
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::text[]");
String[][] in = new String[2][2];
in[0][0] = "a";
in[0][1] = "";
in[1][0] = "\\";
in[1][1] = "\"\\'z";
pstmt.setArray(1, con.createArrayOf("text", in));
pstmt.setArray(1, _conn.createArrayOf("text", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
@ -156,22 +161,29 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCreateArrayOfMultiJson() throws SQLException {
if (!TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_2)) {
if (!TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v9_2)) {
return;
}
PreparedStatement pstmt = con.prepareStatement("SELECT ?::json[]");
String[] in = new String[]{"{\"x\": 10}", "{\"x\": 20}"};
pstmt.setArray(1, con.createArrayOf("json", in));
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::json[]");
PGobject p1 = new PGobject();
p1.setType("json");
p1.setValue("{\"x\": 10}");
PGobject p2 = new PGobject();
p2.setType("json");
p2.setValue("{\"x\": 20}");
PGobject[] in = new PGobject[] { p1, p2 };
pstmt.setArray(1, _conn.createArrayOf("json", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
ResultSet arrRs = arr.getResultSet();
Assert.assertTrue(arrRs.next());
Assert.assertEquals(in[0], arrRs.getString(2));
Assert.assertEquals(in[0], arrRs.getObject(2));
Assert.assertTrue(arrRs.next());
Assert.assertEquals(in[1], arrRs.getString(2));
Assert.assertEquals(in[1], arrRs.getObject(2));
}
@Test
@ -180,8 +192,8 @@ public class ArrayTest extends BaseTest4 {
in[0] = new PGbox(1, 2, 3, 4);
in[1] = new PGbox(5, 6, 7, 8);
PreparedStatement pstmt = con.prepareStatement("SELECT ?::box[]");
pstmt.setArray(1, con.createArrayOf("box", in));
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::box[]");
pstmt.setArray(1, _conn.createArrayOf("box", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
@ -201,11 +213,11 @@ public class ArrayTest extends BaseTest4 {
sql = "SELECT ?::int8[]";
}
PreparedStatement pstmt = con.prepareStatement(sql);
PreparedStatement pstmt = _conn.prepareStatement(sql);
String[] in = new String[2];
in[0] = null;
in[1] = null;
pstmt.setArray(1, con.createArrayOf("int8", in));
pstmt.setArray(1, _conn.createArrayOf("int8", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
@ -219,9 +231,9 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCreateEmptyArrayOfIntViaAlias() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("SELECT ?::int[]");
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::int[]");
Integer[] in = new Integer[0];
pstmt.setArray(1, con.createArrayOf("integer", in));
pstmt.setArray(1, _conn.createArrayOf("integer", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
@ -242,7 +254,7 @@ public class ArrayTest extends BaseTest4 {
in[1][0] = "\\";
in[1][1] = "\"\\'z";
Array arr = con.createArrayOf("varchar", in);
Array arr = _conn.createArrayOf("varchar", in);
String[][] out = (String[][]) arr.getArray();
Assert.assertEquals(2, out.length);
@ -261,7 +273,7 @@ public class ArrayTest extends BaseTest4 {
in[1][0] = 10.0 / 3;
in[1][1] = 77;
Array arr = con.createArrayOf("float8", in);
Array arr = _conn.createArrayOf("float8", in);
Double[][] out = (Double[][]) arr.getArray();
Assert.assertEquals(2, out.length);
@ -277,19 +289,19 @@ public class ArrayTest extends BaseTest4 {
Assume.assumeTrue("UUID is not supported in PreferQueryMode.SIMPLE",
preferQueryMode != PreferQueryMode.SIMPLE);
Assume.assumeTrue("UUID requires PostgreSQL 8.3+",
TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_3));
TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3));
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.randomUUID();
UUID uuid3 = UUID.randomUUID();
// insert a uuid array, and check
PreparedStatement pstmt1 = con.prepareStatement("INSERT INTO arrtest(uuidarr) VALUES (?)");
pstmt1.setArray(1, con.createArrayOf("uuid", new UUID[]{uuid1, uuid2, uuid3}));
PreparedStatement pstmt1 = _conn.prepareStatement("INSERT INTO arrtest(uuidarr) VALUES (?)");
pstmt1.setArray(1, _conn.createArrayOf("uuid", new UUID[]{uuid1, uuid2, uuid3}));
pstmt1.executeUpdate();
PreparedStatement pstmt2 =
con.prepareStatement("SELECT uuidarr FROM arrtest WHERE uuidarr @> ?");
pstmt2.setObject(1, con.createArrayOf("uuid", new UUID[]{uuid1}), Types.OTHER);
_conn.prepareStatement("SELECT uuidarr FROM arrtest WHERE uuidarr @> ?");
pstmt2.setObject(1, _conn.createArrayOf("uuid", new UUID[]{uuid1}), Types.OTHER);
ResultSet rs = pstmt2.executeQuery();
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
@ -303,13 +315,13 @@ public class ArrayTest extends BaseTest4 {
// concatenate a uuid, and check
UUID uuid4 = UUID.randomUUID();
PreparedStatement pstmt3 =
con.prepareStatement("UPDATE arrtest SET uuidarr = uuidarr || ? WHERE uuidarr @> ?");
_conn.prepareStatement("UPDATE arrtest SET uuidarr = uuidarr || ? WHERE uuidarr @> ?");
pstmt3.setObject(1, uuid4, Types.OTHER);
pstmt3.setArray(2, con.createArrayOf("uuid", new UUID[]{uuid1}));
pstmt3.setArray(2, _conn.createArrayOf("uuid", new UUID[]{uuid1}));
pstmt3.executeUpdate();
// --
pstmt2.setObject(1, con.createArrayOf("uuid", new UUID[]{uuid4}), Types.OTHER);
pstmt2.setObject(1, _conn.createArrayOf("uuid", new UUID[]{uuid4}), Types.OTHER);
rs = pstmt2.executeQuery();
Assert.assertTrue(rs.next());
arr = rs.getArray(1);
@ -327,7 +339,7 @@ public class ArrayTest extends BaseTest4 {
String[] strArray = new String[]{"a", "b", "c"};
Object[] objCopy = Arrays.copyOf(strArray, strArray.length, Object[].class);
PreparedStatement pstmt = con.prepareStatement("INSERT INTO arrtest(strarr) VALUES (?)");
PreparedStatement pstmt = _conn.prepareStatement("INSERT INTO arrtest(strarr) VALUES (?)");
//cannot handle generic Object[]
try {
@ -354,7 +366,7 @@ public class ArrayTest extends BaseTest4 {
// Correct way, though the use of "text" as a type is non-portable.
// Only supported for JDK 1.6 and JDBC4
Array sqlArray = con.createArrayOf("text", strArray);
Array sqlArray = _conn.createArrayOf("text", strArray);
pstmt.setArray(1, sqlArray);
pstmt.executeUpdate();
@ -364,10 +376,10 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testGetArrayOfComposites() throws SQLException {
Assume.assumeTrue("array_agg(expression) requires PostgreSQL 8.4+",
TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_4));
TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_4));
PreparedStatement insert_parent_pstmt =
con.prepareStatement("INSERT INTO arrcompprnttest (name) "
_conn.prepareStatement("INSERT INTO arrcompprnttest (name) "
+ "VALUES ('aParent');");
insert_parent_pstmt.execute();
@ -378,7 +390,7 @@ public class ArrayTest extends BaseTest4 {
"5\",3\""};
PreparedStatement insert_children_pstmt =
con.prepareStatement("INSERT INTO arrcompchldttest (name,description,parent) "
_conn.prepareStatement("INSERT INTO arrcompchldttest (name,description,parent) "
+ "VALUES ('child1',?,1),"
+ "('child2',?,1),"
+ "('child3',?,1),"
@ -391,7 +403,7 @@ public class ArrayTest extends BaseTest4 {
insert_children_pstmt.execute();
PreparedStatement pstmt = con.prepareStatement(
PreparedStatement pstmt = _conn.prepareStatement(
"SELECT arrcompprnttest.name, "
+ "array_agg("
+ "DISTINCT(arrcompchldttest.id, "
@ -432,7 +444,7 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCasingComposite() throws SQLException {
Assume.assumeTrue("Arrays of composite types requires PostgreSQL 8.3+",
TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_3));
TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3));
PGobject cc = new PGobject();
cc.setType("correctcasing");
@ -440,8 +452,8 @@ public class ArrayTest extends BaseTest4 {
Object[] in = new Object[1];
in[0] = cc;
Array arr = con.createArrayOf("correctcasing", in);
PreparedStatement pstmt = con.prepareStatement("SELECT ?::correctcasing[]");
Array arr = _conn.createArrayOf("correctcasing", in);
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::correctcasing[]");
pstmt.setArray(1, arr);
ResultSet rs = pstmt.executeQuery();
@ -455,8 +467,8 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCasingBuiltinAlias() throws SQLException {
Array arr = con.createArrayOf("INT", new Integer[]{1, 2, 3});
PreparedStatement pstmt = con.prepareStatement("SELECT ?::INT[]");
Array arr = _conn.createArrayOf("INT", new Integer[]{1, 2, 3});
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::INT[]");
pstmt.setArray(1, arr);
ResultSet rs = pstmt.executeQuery();
@ -468,8 +480,8 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testCasingBuiltinNonAlias() throws SQLException {
Array arr = con.createArrayOf("int4", new Integer[]{1, 2, 3});
PreparedStatement pstmt = con.prepareStatement("SELECT ?::int4[]");
Array arr = _conn.createArrayOf("int4", new Integer[]{1, 2, 3});
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::int4[]");
pstmt.setArray(1, arr);
ResultSet rs = pstmt.executeQuery();
@ -482,7 +494,7 @@ public class ArrayTest extends BaseTest4 {
@Test
public void testEvilCasing() throws SQLException {
Assume.assumeTrue("Arrays of composite types requires PostgreSQL 8.3+",
TestUtil.haveMinimumServerVersion(con, ServerVersion.v8_3));
TestUtil.haveMinimumServerVersion(_conn, ServerVersion.v8_3));
PGobject cc = new PGobject();
cc.setType("\"evil.table\"");
@ -490,8 +502,8 @@ public class ArrayTest extends BaseTest4 {
Object[] in = new Object[1];
in[0] = cc;
Array arr = con.createArrayOf("\"evil.table\"", in);
PreparedStatement pstmt = con.prepareStatement("SELECT ?::\"evil.table\"[]");
Array arr = _conn.createArrayOf("\"evil.table\"", in);
PreparedStatement pstmt = _conn.prepareStatement("SELECT ?::\"evil.table\"[]");
pstmt.setArray(1, arr);
ResultSet rs = pstmt.executeQuery();
@ -587,41 +599,4 @@ public class ArrayTest extends BaseTest4 {
TestUtil.closeQuietly(rs);
TestUtil.closeQuietly(ps);
}
@Test
public void testBooleanArray() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("select array_replace(?,'true','f');");
Boolean[][] in = new Boolean[][]{{false,false,false}, {true,true,true}};
pstmt.setArray(1, con.createArrayOf("boolean", in));
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Boolean[][] out = (Boolean[][]) arr.getArray();
Assert.assertEquals(2, out.length);
Assert.assertEquals(3, out[0].length);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Assert.assertFalse(out[i][j]);
}
}
}
@Test
public void testBooleanArray2() throws SQLException {
PreparedStatement pstmt = con.prepareStatement("select array_replace(array[[false,FALSE,false],[false,TRUE,false]],'false','t');");
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
Array arr = rs.getArray(1);
Boolean[][] out = (Boolean[][]) arr.getArray();
Assert.assertEquals(2, out.length);
Assert.assertEquals(3, out[0].length);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Assert.assertTrue(out[i][j]);
}
}
}
}

View File

@ -1,69 +0,0 @@
package org.postgresql.test.jdbc4;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
public class BitTest extends BaseTest4 {
/*
* Tests bit type
*/
@Test
public void testBit() throws Exception {
TestUtil.createTable(con, "test_bit", "c1 bit(1),c2 bit(10),c3 bit(6)");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_bit VALUES (0::bit(1), 1234::bit(10), 88::bit(6))");
pstmt.executeUpdate();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT c1,c2,c3 FROM test_bit");
assertTrue(rs.next());
Object o1 = rs.getObject(1);
assertNotNull(o1);
assertEquals(false, o1);
Object o2 = rs.getObject(2);
assertNotNull(o2);
assertEquals(true, o2);
Object o3 = rs.getObject(3);
assertNotNull(o3);
assertEquals(true, o3);
TestUtil.dropTable(con, "test_bit");
}
/*
* Tests bit by getBytes()
*/
@Test
public void testBitToBytes() throws Exception {
TestUtil.createTable(con, "test_bitToBytes", "c1 bit(10),c2 bit(18)");
String sql = "INSERT INTO test_bitToBytes VALUES (123::bit(10), 18437::bit(18))";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.executeUpdate();
}
try (Statement ps = con.createStatement();
ResultSet rs = ps.executeQuery("SELECT c1,c2 FROM test_bitToBytes")) {
assertTrue(rs.next());
String r1 = rs.getString(1);
assertNotNull(r1);
assertEquals("0001111011", r1);
String r2 = rs.getString(2);
assertNotNull(r2);
assertEquals("000100100000000101", r2);
} finally {
TestUtil.dropTable(con, "test_bitToBytes");
}
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.jdbc4;
import org.junit.Test;
import org.postgresql.core.types.PGBlob;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
/**
* test blob
*
* @author zhangting
* @since 2024-08-23
*/
public class BlobTest extends BaseTest4 {
@Test
public void testStringToBlob() throws SQLException {
TestUtil.createTable(con, "test_blob_a", "id int, c1 blob");
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO test_blob_a VALUES (?,?)")) {
pstmt.setInt(1, 1);
PGBlob blob = new PGBlob();
blob.setBytes(1, "1234".getBytes(StandardCharsets.UTF_8));
pstmt.setBlob(2, blob);
pstmt.execute();
}
String sql = "INSERT INTO test_blob_a VALUES (2,'31323334'::blob)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.execute();
}
try (Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM test_blob_a")) {
while (rs.next()) {
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(Types.BLOB, rsmd.getColumnType(2));
assertEquals("1234", new String(rs.getBlob(2).getBytes(1, 4),
StandardCharsets.UTF_8));
assertEquals("1234", new String(rs.getBytes(2), StandardCharsets.UTF_8));
}
}
TestUtil.dropTable(con, "test_blob_a");
}
}

View File

@ -1,120 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.jdbc4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
/**
* Test case for cleanupSavepoints property
*
* @author zhangting
* @since 2024-09-10
*/
public class CleanUpSavePointsPropertyTest extends BaseTest4 {
@Before
public void setUp() throws Exception {
Properties props = new Properties();
props.put("autosave", "always");
props.put("cleanupSavepoints", "true");
con = TestUtil.openDB(props);
TestUtil.createTable(con, "savepoint_table", "id int primary key, name varchar(16)");
con.setAutoCommit(false);
}
@After
public void tearDown() throws SQLException {
con.setAutoCommit(true);
TestUtil.dropTable(con, "savepoint_table");
super.tearDown();
}
@Test
public void test() throws SQLException {
// add record
IntStream.range(1, 6).forEach(i -> {
try {
addRecord(i, "xw" + i);
} catch (SQLException ex) {
ex.printStackTrace();
}
});
// update record
IntStream.range(1, 3).forEach(i -> {
try {
updateRecord(i, "name" + i + "-" + i);
} catch (SQLException e) {
e.printStackTrace();
}
});
// delete record
IntStream.range(4, 6).forEach(i -> {
try {
deleteRecord(i);
} catch (SQLException e) {
e.printStackTrace();
}
});
// count record
assertEquals(3, countRecord());
}
private void addRecord(int id, String name) throws SQLException {
String sql = "INSERT INTO savepoint_table(id, name) VALUES (?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.setString(2, name);
pstmt.executeUpdate();
}
}
private void updateRecord(int id, String name) throws SQLException {
String sql = "update savepoint_table set name= ? where id= ?";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setInt(2, id);
pstmt.executeUpdate();
}
}
private void deleteRecord(int id) throws SQLException {
String sql = "delete from savepoint_table where id= ?";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
}
}
private int countRecord() throws SQLException {
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM savepoint_table")) {
rs.next();
return rs.getInt(1);
}
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.postgresql.test.jdbc4;
import org.junit.Test;
import org.postgresql.test.TestUtil;
import org.postgresql.test.jdbc2.BaseTest4;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* test json
*
* @author zhangting
* @since 2024-08-20
*/
public class JsonTest extends BaseTest4 {
/*
* test json to string
*/
@Test
public void testJsonToString() throws Exception {
TestUtil.createTable(con, "test_json", "id json");
String sql = "INSERT INTO test_json VALUES ('{\"k1\":\"v1\",\"k2\":\"v2\"}')";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.executeUpdate();
}
try (Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM test_json")) {
assertTrue(rs.next());
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals(1, rsmd.getColumnCount());
assertEquals(Types.VARCHAR, rsmd.getColumnType(1));
assertEquals("{\"k1\":\"v1\",\"k2\":\"v2\"}", rs.getString(1));
}
TestUtil.dropTable(con, "test_json");
}
}