You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2021/05/12 09:27:42 UTC

[shardingsphere] branch master updated: Support PostgreSQL Close command (#10316)

This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 9e35377  Support PostgreSQL Close command (#10316)
9e35377 is described below

commit 9e35377cdd8aa2297cb1c92cdca010ef4fa85a71
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Wed May 12 17:27:04 2021 +0800

    Support PostgreSQL Close command (#10316)
---
 .../command/PostgreSQLCommandPacketFactory.java    |  3 +
 .../ConnectionScopeBinaryStatementRegistry.java    | 10 +++
 .../close/PostgreSQLCloseCompletePacket.java       | 38 +++++++++++
 .../binary/close/PostgreSQLComClosePacket.java     | 77 ++++++++++++++++++++++
 .../PostgreSQLCommandPacketFactoryTest.java        |  7 ++
 ...ConnectionScopeBinaryStatementRegistryTest.java | 12 ++--
 .../close/PostgreSQLCloseCompletePacketTest.java   | 34 ++++++++++
 .../binary/close/PostgreSQLComClosePacketTest.java | 67 +++++++++++++++++++
 .../command/PostgreSQLCommandExecutorFactory.java  |  4 ++
 .../binary/close/PostgreSQLComCloseExecutor.java   | 72 ++++++++++++++++++++
 .../PostgreSQLCommandExecutorFactoryTest.java      |  7 +-
 .../close/PostgreSQLComCloseExecutorTest.java      | 76 +++++++++++++++++++++
 12 files changed, 400 insertions(+), 7 deletions(-)

diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactory.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactory.java
index cd3d451..070bc37 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactory.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactory.java
@@ -21,6 +21,7 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.admin.PostgreSQLUnsupportedCommandPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.bind.PostgreSQLComBindPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.describe.PostgreSQLComDescribePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.execute.PostgreSQLComExecutePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.parse.PostgreSQLComParsePacket;
@@ -57,6 +58,8 @@ public final class PostgreSQLCommandPacketFactory {
                 return new PostgreSQLComExecutePacket(payload);
             case SYNC_COMMAND:
                 return new PostgreSQLComSyncPacket(payload);
+            case CLOSE_COMMAND:
+                return new PostgreSQLComClosePacket(payload);
             case TERMINATE:
                 return new PostgreSQLComTerminationPacket(payload);
             default:
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistry.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistry.java
index 670753d..651f036 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistry.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistry.java
@@ -49,4 +49,14 @@ public final class ConnectionScopeBinaryStatementRegistry {
     public PostgreSQLBinaryStatement getBinaryStatement(final String statementId) {
         return binaryStatements.get(statementId);
     }
+    
+    /**
+     * Close prepared statement.
+     *
+     * @param statementId statement ID
+     * @return closed binary prepared statement
+     */
+    public PostgreSQLBinaryStatement closeStatement(final String statementId) {
+        return binaryStatements.remove(statementId);
+    }
 }
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacket.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacket.java
new file mode 100644
index 0000000..30ab0ae
--- /dev/null
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacket.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close;
+
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
+import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
+
+/**
+ * Close complete packet for PostgreSQL.
+ */
+public final class PostgreSQLCloseCompletePacket implements PostgreSQLIdentifierPacket {
+    
+    @Override
+    public void write(final PostgreSQLPacketPayload payload) {
+    }
+    
+    @Override
+    public PostgreSQLIdentifierTag getIdentifier() {
+        return PostgreSQLMessagePacketType.CLOSE_COMPLETE;
+    }
+}
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacket.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacket.java
new file mode 100644
index 0000000..2120c18
--- /dev/null
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacket.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacketType;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
+import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
+
+/**
+ * Command close packet for PostgreSQL.
+ */
+@Getter
+public final class PostgreSQLComClosePacket extends PostgreSQLCommandPacket {
+    
+    private final Type type;
+    
+    private final String name;
+    
+    public PostgreSQLComClosePacket(final PostgreSQLPacketPayload payload) {
+        payload.readInt4();
+        type = Type.valueOf((char) payload.readInt1());
+        name = payload.readStringNul();
+    }
+    
+    @Override
+    public void write(final PostgreSQLPacketPayload payload) {
+    }
+    
+    @Override
+    public PostgreSQLIdentifierTag getIdentifier() {
+        return PostgreSQLCommandPacketType.CLOSE_COMMAND;
+    }
+    
+    @RequiredArgsConstructor
+    @Getter
+    public enum Type {
+        
+        PREPARED_STATEMENT('S'),
+        
+        PORTAL('P');
+        
+        private final char type;
+        
+        /**
+         * Value of type.
+         *
+         * @param type type
+         * @return type
+         */
+        public static Type valueOf(final char type) {
+            for (Type each : values()) {
+                if (type == each.type) {
+                    return each;
+                }
+            }
+            throw new IllegalArgumentException(String.format("Close type must be 'S' or 'P'. Got '%c'", type));
+        }
+    }
+}
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactoryTest.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactoryTest.java
index 1d97f95..830675e 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactoryTest.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/PostgreSQLCommandPacketFactoryTest.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.db.protocol.postgresql.packet.command;
 
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.PostgreSQLBinaryStatementRegistry;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.bind.PostgreSQLComBindPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.describe.PostgreSQLComDescribePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.execute.PostgreSQLComExecutePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.parse.PostgreSQLComParsePacket;
@@ -81,6 +82,12 @@ public final class PostgreSQLCommandPacketFactoryTest {
     }
     
     @Test
+    public void assertNewInstanceWithCloseComPacket() {
+        when(payload.readInt1()).thenReturn((int) PostgreSQLComClosePacket.Type.PREPARED_STATEMENT.getType());
+        assertThat(PostgreSQLCommandPacketFactory.newInstance(PostgreSQLCommandPacketType.CLOSE_COMMAND, payload, 1), instanceOf(PostgreSQLComClosePacket.class));
+    }
+    
+    @Test
     public void assertNewInstanceWithTerminationComPacket() {
         assertThat(PostgreSQLCommandPacketFactory.newInstance(PostgreSQLCommandPacketType.TERMINATE, payload, 1), instanceOf(PostgreSQLComTerminationPacket.class));
     }
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistryTest.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistryTest.java
index 3ab64ea..3212c19 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistryTest.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/ConnectionScopeBinaryStatementRegistryTest.java
@@ -45,10 +45,14 @@ public final class ConnectionScopeBinaryStatementRegistryTest {
     }
     
     @Test
-    public void assertGetBinaryStatement() {
+    public void assertGetAndCloseBinaryStatement() {
         ConnectionScopeBinaryStatementRegistry statementRegistry = new ConnectionScopeBinaryStatementRegistry();
-        statementRegistry.register("stat-id", "", 1, null);
-        PostgreSQLBinaryStatement binaryStatement = statementRegistry.getBinaryStatement("stat-id");
-        assertNotNull(binaryStatement);
+        String statementId = "stat-id";
+        statementRegistry.register(statementId, "", 1, null);
+        PostgreSQLBinaryStatement actual = statementRegistry.getBinaryStatement(statementId);
+        assertNotNull(actual);
+        PostgreSQLBinaryStatement actualClosed = statementRegistry.closeStatement(statementId);
+        assertThat(actualClosed, is(actual));
+        assertNull(statementRegistry.getBinaryStatement(statementId));
     }
 }
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacketTest.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacketTest.java
new file mode 100644
index 0000000..3f8a9a5
--- /dev/null
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLCloseCompletePacketTest.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close;
+
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public final class PostgreSQLCloseCompletePacketTest {
+    
+    @Test
+    public void assertIdentifier() {
+        PostgreSQLIdentifierTag actual = new PostgreSQLCloseCompletePacket().getIdentifier();
+        assertThat(actual, is(PostgreSQLMessagePacketType.CLOSE_COMPLETE));
+    }
+}
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacketTest.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacketTest.java
new file mode 100644
index 0000000..99fd233
--- /dev/null
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/test/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/binary/close/PostgreSQLComClosePacketTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close;
+
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacketType;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLIdentifierTag;
+import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class PostgreSQLComClosePacketTest {
+    
+    @Mock
+    private PostgreSQLPacketPayload payload;
+    
+    @Test
+    public void assertClosePreparedStatement() {
+        when(payload.readInt1()).thenReturn((int) 'S');
+        when(payload.readStringNul()).thenReturn("S_1");
+        PostgreSQLComClosePacket actual = new PostgreSQLComClosePacket(payload);
+        assertThat(actual.getType(), is(PostgreSQLComClosePacket.Type.PREPARED_STATEMENT));
+        assertThat(actual.getName(), is("S_1"));
+    }
+    
+    @Test
+    public void assertClosePortal() {
+        when(payload.readInt1()).thenReturn((int) 'P');
+        when(payload.readStringNul()).thenReturn("P_1");
+        PostgreSQLComClosePacket actual = new PostgreSQLComClosePacket(payload);
+        assertThat(actual.getType(), is(PostgreSQLComClosePacket.Type.PORTAL));
+        assertThat(actual.getName(), is("P_1"));
+    }
+    
+    @Test
+    public void assertIdentifier() {
+        when(payload.readInt1()).thenReturn((int) 'S');
+        PostgreSQLIdentifierTag actual = new PostgreSQLComClosePacket(payload).getIdentifier();
+        assertThat(actual, is(PostgreSQLCommandPacketType.CLOSE_COMMAND));
+    }
+    
+    @Test(expected = IllegalArgumentException.class)
+    public void assertInvalidType() {
+        new PostgreSQLComClosePacket(payload);
+    }
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
index c963ffa..6860547 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
@@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacketType;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.bind.PostgreSQLComBindPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.parse.PostgreSQLComParsePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.text.PostgreSQLComQueryPacket;
 import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
@@ -30,6 +31,7 @@ import org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.generic.PostgreSQLComTerminationExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.generic.PostgreSQLUnsupportedCommandExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.bind.PostgreSQLComBindExecutor;
+import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.close.PostgreSQLComCloseExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.describe.PostgreSQLComDescribeExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.execute.PostgreSQLComExecuteExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.parse.PostgreSQLComParseExecutor;
@@ -70,6 +72,8 @@ public final class PostgreSQLCommandExecutorFactory {
                 return new PostgreSQLComExecuteExecutor();
             case SYNC_COMMAND:
                 return new PostgreSQLComSyncExecutor(backendConnection);
+            case CLOSE_COMMAND:
+                return new PostgreSQLComCloseExecutor((PostgreSQLComClosePacket) commandPacket, backendConnection);
             case TERMINATE:
                 return new PostgreSQLComTerminationExecutor();
             default:
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutor.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutor.java
new file mode 100644
index 0000000..0599a68
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.close;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.db.protocol.packet.DatabasePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
+import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLMessageSeverityLevel;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.ConnectionScopeBinaryStatementRegistry;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.PostgreSQLBinaryStatementRegistry;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLCloseCompletePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
+import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
+import org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Command close executor for PostgreSQL.
+ */
+@RequiredArgsConstructor
+public final class PostgreSQLComCloseExecutor implements CommandExecutor {
+    
+    private final PostgreSQLComClosePacket packet;
+    
+    private final BackendConnection backendConnection;
+    
+    @Override
+    public Collection<DatabasePacket<?>> execute() throws SQLException {
+        switch (packet.getType()) {
+            case PREPARED_STATEMENT:
+                return closePreparedStatement();
+            case PORTAL:
+                return closePortal();
+            default:
+                throw new UnsupportedOperationException(packet.getType().name());
+        }
+    }
+    
+    private Collection<DatabasePacket<?>> closePreparedStatement() {
+        ConnectionScopeBinaryStatementRegistry binaryStatementRegistry = PostgreSQLBinaryStatementRegistry.getInstance().get(backendConnection.getConnectionId());
+        if (null != binaryStatementRegistry) {
+            binaryStatementRegistry.closeStatement(packet.getName());
+        }
+        return Collections.singletonList(new PostgreSQLCloseCompletePacket());
+    }
+    
+    private List<DatabasePacket<?>> closePortal() {
+        PostgreSQLErrorResponsePacket packet = PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.ERROR, PostgreSQLErrorCode.FEATURE_NOT_SUPPORTED,
+                "Not implemented: Close portal").build();
+        return Collections.singletonList(packet);
+    }
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
index d80d3a5..b7851c3 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactoryTest.java
@@ -22,13 +22,14 @@ import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.PostgreSQLCommandPacketType;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.bind.PostgreSQLComBindPacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.parse.PostgreSQLComParsePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.text.PostgreSQLComQueryPacket;
 import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.generic.PostgreSQLComTerminationExecutor;
-import org.apache.shardingsphere.proxy.frontend.postgresql.command.generic.PostgreSQLUnsupportedCommandExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.bind.PostgreSQLComBindExecutor;
+import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.close.PostgreSQLComCloseExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.describe.PostgreSQLComDescribeExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.execute.PostgreSQLComExecuteExecutor;
 import org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.parse.PostgreSQLComParseExecutor;
@@ -58,8 +59,8 @@ public final class PostgreSQLCommandExecutorFactoryTest {
             new InputOutput(PostgreSQLCommandPacketType.DESCRIBE_COMMAND, null, PostgreSQLComDescribeExecutor.class),
             new InputOutput(PostgreSQLCommandPacketType.EXECUTE_COMMAND, null, PostgreSQLComExecuteExecutor.class),
             new InputOutput(PostgreSQLCommandPacketType.SYNC_COMMAND, null, PostgreSQLComSyncExecutor.class),
-            new InputOutput(PostgreSQLCommandPacketType.TERMINATE, null, PostgreSQLComTerminationExecutor.class),
-            new InputOutput(PostgreSQLCommandPacketType.CLOSE_COMMAND, null, PostgreSQLUnsupportedCommandExecutor.class)
+            new InputOutput(PostgreSQLCommandPacketType.CLOSE_COMMAND, PostgreSQLComClosePacket.class, PostgreSQLComCloseExecutor.class),
+            new InputOutput(PostgreSQLCommandPacketType.TERMINATE, null, PostgreSQLComTerminationExecutor.class)
         );
         for (InputOutput inputOutput : inputOutputs) {
             Class<? extends PostgreSQLCommandPacket> commandPacketClass = inputOutput.getCommandPacketClass();
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutorTest.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutorTest.java
new file mode 100644
index 0000000..8e747db
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/binary/close/PostgreSQLComCloseExecutorTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.close;
+
+import org.apache.shardingsphere.db.protocol.packet.DatabasePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.PostgreSQLBinaryStatementRegistry;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLCloseCompletePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.close.PostgreSQLComClosePacket;
+import org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
+import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Random;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class PostgreSQLComCloseExecutorTest {
+    
+    private static final int CONNECTION_ID = new Random().nextInt() & Integer.MAX_VALUE;
+    
+    @Mock
+    private PostgreSQLComClosePacket packet;
+    
+    @Mock
+    private BackendConnection backendConnection;
+    
+    @Before
+    public void setUp() {
+        when(backendConnection.getConnectionId()).thenReturn(CONNECTION_ID);
+        PostgreSQLBinaryStatementRegistry.getInstance().register(CONNECTION_ID);
+    }
+    
+    @Test
+    public void assertExecuteClosePreparedStatement() throws SQLException {
+        when(packet.getType()).thenReturn(PostgreSQLComClosePacket.Type.PREPARED_STATEMENT);
+        when(packet.getName()).thenReturn("S_1");
+        PostgreSQLComCloseExecutor closeExecutor = new PostgreSQLComCloseExecutor(packet, backendConnection);
+        Collection<DatabasePacket<?>> actual = closeExecutor.execute();
+        assertThat(actual.size(), is(1));
+        assertThat(actual.iterator().next(), is(instanceOf(PostgreSQLCloseCompletePacket.class)));
+    }
+    
+    @Test
+    public void assertExecuteClosePortal() throws SQLException {
+        when(packet.getType()).thenReturn(PostgreSQLComClosePacket.Type.PORTAL);
+        PostgreSQLComCloseExecutor closeExecutor = new PostgreSQLComCloseExecutor(packet, backendConnection);
+        Collection<DatabasePacket<?>> actual = closeExecutor.execute();
+        assertThat(actual.size(), is(1));
+        assertThat(actual.iterator().next(), is(instanceOf(PostgreSQLErrorResponsePacket.class)));
+    }
+}