@@ -269,7 +269,9 @@ func (c *clientConn) handleQuery(body []byte) error {
269269 query := string (bytes .TrimRight (body , "\x00 " ))
270270 query = strings .TrimSpace (query )
271271
272- if query == "" {
272+ // Treat empty queries or queries with just semicolons as empty
273+ // PostgreSQL returns EmptyQueryResponse for queries like "" or ";" or ";;;"
274+ if query == "" || isEmptyQuery (query ) {
273275 writeEmptyQueryResponse (c .writer )
274276 writeReadyForQuery (c .writer , c .txStatus )
275277 c .writer .Flush ()
@@ -383,6 +385,17 @@ func (c *clientConn) handleQuery(body []byte) error {
383385 return nil
384386}
385387
388+ // isEmptyQuery checks if a query contains only semicolons and whitespace.
389+ // PostgreSQL returns EmptyQueryResponse for queries like ";" or ";;;" or "; ; ;"
390+ func isEmptyQuery (query string ) bool {
391+ for _ , r := range query {
392+ if r != ';' && r != ' ' && r != '\t' && r != '\n' && r != '\r' {
393+ return false
394+ }
395+ }
396+ return true
397+ }
398+
386399// stripLeadingComments removes leading SQL comments from a query.
387400// Handles both block comments /* ... */ and line comments -- ...
388401func stripLeadingComments (query string ) string {
@@ -458,11 +471,16 @@ func (c *clientConn) getCommandType(upperQuery string) string {
458471 return "UPDATE"
459472 case strings .HasPrefix (upperQuery , "DELETE" ):
460473 return "DELETE"
461- case strings .HasPrefix (upperQuery , "CREATE TABLE" ):
474+ case strings .HasPrefix (upperQuery , "CREATE TABLE" ),
475+ strings .HasPrefix (upperQuery , "CREATE TEMPORARY TABLE" ),
476+ strings .HasPrefix (upperQuery , "CREATE TEMP TABLE" ),
477+ strings .HasPrefix (upperQuery , "CREATE UNLOGGED TABLE" ):
462478 return "CREATE TABLE"
463- case strings .HasPrefix (upperQuery , "CREATE INDEX" ):
479+ case strings .HasPrefix (upperQuery , "CREATE INDEX" ),
480+ strings .HasPrefix (upperQuery , "CREATE UNIQUE INDEX" ):
464481 return "CREATE INDEX"
465- case strings .HasPrefix (upperQuery , "CREATE VIEW" ):
482+ case strings .HasPrefix (upperQuery , "CREATE VIEW" ),
483+ strings .HasPrefix (upperQuery , "CREATE OR REPLACE VIEW" ):
466484 return "CREATE VIEW"
467485 case strings .HasPrefix (upperQuery , "CREATE SCHEMA" ):
468486 return "CREATE SCHEMA"
@@ -1136,6 +1154,8 @@ func (c *clientConn) handleDescribe(body []byte) {
11361154 c .sendError ("ERROR" , "26000" , fmt .Sprintf ("prepared statement %q does not exist" , name ))
11371155 return
11381156 }
1157+ log .Printf ("[%s] Describe statement %q: %s" , c .username , name , ps .query )
1158+
11391159 // Send parameter description based on the number of $N placeholders we found
11401160 // If the client didn't send explicit types, create them
11411161 paramTypes := ps .paramTypes
@@ -1150,7 +1170,9 @@ func (c *clientConn) handleDescribe(body []byte) {
11501170
11511171 // For queries that return results, we need to send RowDescription
11521172 // For other queries, send NoData
1153- if ! queryReturnsResults (ps .query ) {
1173+ returnsResults := queryReturnsResults (ps .query )
1174+ log .Printf ("[%s] Describe statement %q: returnsResults=%v" , c .username , name , returnsResults )
1175+ if ! returnsResults {
11541176 writeNoData (c .writer )
11551177 return
11561178 }
@@ -1295,6 +1317,7 @@ func (c *clientConn) handleExecute(body []byte) {
12951317 // Non-result-returning query: use Exec with converted query
12961318 result , err := c .db .Exec (p .stmt .convertedQuery , args ... )
12971319 if err != nil {
1320+ log .Printf ("[%s] Execute error: %v" , c .username , err )
12981321 c .sendError ("ERROR" , "42000" , err .Error ())
12991322 c .setTxError ()
13001323 return
@@ -1308,6 +1331,7 @@ func (c *clientConn) handleExecute(body []byte) {
13081331 // Result-returning query: use Query with converted query
13091332 rows , err := c .db .Query (p .stmt .convertedQuery , args ... )
13101333 if err != nil {
1334+ log .Printf ("[%s] Query error: %v" , c .username , err )
13111335 c .sendError ("ERROR" , "42000" , err .Error ())
13121336 c .setTxError ()
13131337 return
@@ -1316,6 +1340,7 @@ func (c *clientConn) handleExecute(body []byte) {
13161340
13171341 cols , err := rows .Columns ()
13181342 if err != nil {
1343+ log .Printf ("[%s] Columns error: %v" , c .username , err )
13191344 c .sendError ("ERROR" , "42000" , err .Error ())
13201345 c .setTxError ()
13211346 return
0 commit comments