Compare commits
No commits in common. "v6.0.0" and "master" have entirely different histories.
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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();
|
||||
|
@ -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)}.
|
||||
|
168
pgjdbc/src/main/java/org/postgresql/core/UTF8Encoding.java
Normal file
168
pgjdbc/src/main/java/org/postgresql/core/UTF8Encoding.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
@ -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.
|
||||
*
|
||||
|
@ -1,5 +0,0 @@
|
||||
package org.postgresql.util;
|
||||
|
||||
public enum CompatibilityEnum {
|
||||
ON, OFF
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +129,7 @@ import org.junit.runners.Suite;
|
||||
CopyTest.class,
|
||||
CopyLargeFileTest.class,
|
||||
UpsertTest.class,
|
||||
OuterJoinSyntaxTest.class,
|
||||
NumericNegScaleTest.class
|
||||
OuterJoinSyntaxTest.class
|
||||
})
|
||||
public class Jdbc2TestSuite {
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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,,");
|
||||
|
@ -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 =
|
||||
|
@ -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));
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user