Hi All, While running test with bind varible getting segmentation fault. ( CVS Head 8.4)
For testcase, please find the crash.c (C test) and test.java ( JDBC test) attached with the mail. Had a quick look at the core dump and found the call stack for the segmentation fault. (gdb) bt #0 0x0813768d in analyze_requires_snapshot (parseTree=0x0) at analyze.c:270 #1 0x082e77a8 in exec_bind_message (input_message=0xbfd7d73c) at postgres.c:1698 #2 0x082ec524 in PostgresMain (argc=4, argv=0x916fc70, username=0x916fb7c "rushabh") at postgres.c:4882 #3 0x082ac10a in BackendRun (port=0x9191b18) at postmaster.c:3309 #4 0x082ab4d4 in BackendStartup (port=0x9191b18) at postmaster.c:2881 #5 0x082a8ae1 in ServerLoop () at postmaster.c:1291 Had a look at the previous version and found that because of following condition added with the new PG merge into exec_bind_message(); we end up with the segmentation fault. exec_bind_message{ ... /* * Set a snapshot if we have parameters to fetch (since the input * functions might need it) or the query isn't a utility command (and * hence could require redoing parse analysis and planning). */ if (numParams > 0 || analyze_requires_snapshot(psrc->raw_parse_tree)) { PushActiveSnapshot(GetTransactionSnapshot()); snapshot_set = true; } ... } Condition added with "Fix failure to ensure that a snapshot is available to datatype input functions" commit. ( http://git.postgresql.org/?p=postgresql.git;a=commitdiff;h=d5e7e5dd7c81440bb46f52872906633ee2b388c1 ) Not very much sure but for the quick check I just modifiled condition by added check for raw_parse_tree and test worked file. Modified condition: /* * Set a snapshot if we have parameters to fetch (since the input * functions might need it) or the query isn't a utility command (and * hence could require redoing parse analysis and planning). */ if (numParams > 0 || (psrc->raw_parse_tree && analyze_requires_snapshot(psrc->raw_parse_tree))) { PushActiveSnapshot(GetTransactionSnapshot()); snapshot_set = true; } Another fix would be to add check for parseTree into analyze_requires_snapshot(). Thanks , Rushabh Lathia www.EnterpriseDB.com
import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.*; public class Test { /** * @param args */ public static void main(String[] args) { try { Class.forName("org.postgresql.Driver"); Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres?loglevel=2","rushabh","edb"); PreparedStatement st; ResultSet rs; st = con.prepareStatement("SELECT ?;--SELECT ?"); st.setString(1, "a"); st.execute(); st.getMoreResults(); st.getMoreResults(); st.close(); } catch (Exception e) { e.printStackTrace(); } } }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include "libpq-fe.h" int main(int argc, char **argv) { const char *conninfo; PGconn *conn; PGresult *res; /* * If the user supplies a parameter on the command line, use it as the * conninfo string; otherwise default to setting dbname=postgres and using * environment variables or defaults for all other connection parameters. */ if (argc > 1) conninfo = argv[1]; else conninfo = "dbname = postgres"; /* Make a connection to the database */ conn = PQconnectdb(conninfo); /* Check to see that the backend connection was successfully made */ if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); return 1; } res = PQexecParams(conn, "/* nothing */", 0, /* no params */ NULL, /* let the backend deduce param type */ NULL, NULL, /* don't need param lengths since text */ NULL, /* default to all text params */ 0); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "query failed: %s", PQerrorMessage(conn)); } PQclear(res); /* close the connection to the database and cleanup */ PQfinish(conn); return 0; }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers