Cope with the removal of pg_class.relhasoids in PG12 correctly when retrieving updata...
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sun, 5 Jan 2020 01:01:07 +0000 (10:01 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sun, 5 Jan 2020 01:01:07 +0000 (10:01 +0900)
connection.c
parse.c
statement.h

index 069f428ce0f5686aab179bd2227a267282ee6c17..ab77efc19349c0429f81e632527597b2a7e1781a 100644 (file)
@@ -2068,7 +2068,11 @@ MYLOG(DETAIL_LOG_LEVEL, "Discarded a RELEASE result\n");
                    {
                        QR_set_haskeyset(res->next);
                        if (stmt)
+                       {
+                           if (stmt->num_key_fields < 0) /* for safety */
+                               CheckPgClassInfo(stmt);
                            res->next->num_key_fields = stmt->num_key_fields;
+                       }
                    }
                    MYLOG(0, " 'T' no result_in: res = %p\n", res->next);
                    res = res->next;
@@ -2087,7 +2091,11 @@ MYLOG(DETAIL_LOG_LEVEL, "Discarded a RELEASE result\n");
                    {
                        QR_set_haskeyset(res);
                        if (stmt)
+                       {
+                           if (stmt->num_key_fields < 0) /* for safety */
+                               CheckPgClassInfo(stmt);
                            res->num_key_fields = stmt->num_key_fields;
+                       }
                        if (cursor && cursor[0])
                            QR_set_synchronize_keys(res);
                    }
diff --git a/parse.c b/parse.c
index 0ff76bcbabfe253f0d59926cc7e862122e0446a0..b0d751fc6b7de8d6960c250ecaaa1ed35231b42b 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -379,12 +379,22 @@ void lower_the_name(char *name, ConnectionClass *conn, BOOL dquote)
    }
 }
 
-static BOOL CheckHasOidsUsingSaved(StatementClass *stmt, TABLE_INFO *ti)
+/*
+ * Check relhasoids(before PG12), relhssubclass and get some relevant information.
+ */
+BOOL CheckPgClassInfo(StatementClass *stmt)
 {
    const COL_INFO *coli;
    int table_info;
+   TABLE_INFO  *ti;
    BOOL    hasoids = FALSE, hassubclass =FALSE, keyFound = FALSE;
 
+MYLOG(0, "Entering\n");
+   if (0 != SC_checked_hasoids(stmt))
+       return TRUE;
+   if (!stmt->ti || !stmt->ti[0])
+       return FALSE;
+   ti = stmt->ti[0];
    MYLOG(DETAIL_LOG_LEVEL, "ti->col_info=%p\n", ti->col_info);
    if (TI_checked_hasoids(ti))
        ;
@@ -465,95 +475,6 @@ static BOOL CheckHasOidsUsingSaved(StatementClass *stmt, TABLE_INFO *ti)
    return TRUE;
 }
 
-static BOOL CheckHasOids(StatementClass * stmt)
-{
-   QResultClass    *res;
-   BOOL        hasoids = TRUE, hassubclass =FALSE, foundKey = FALSE;
-   char        query[512];
-   ConnectionClass *conn = SC_get_conn(stmt);
-   TABLE_INFO  *ti;
-
-MYLOG(0, "Entering\n");
-    if (PG_VERSION_GE(conn, 12.0))
-      return FALSE;
-   if (0 != SC_checked_hasoids(stmt))
-       return TRUE;
-   if (!stmt->ti || !stmt->ti[0])
-       return FALSE;
-   ti = stmt->ti[0];
-   if (CheckHasOidsUsingSaved(stmt, ti))
-       return TRUE;
-   // no longer come here??
-   SPRINTF_FIXED(query,
-            "select relhasoids, c.oid, relhassubclass from pg_class c, pg_namespace n where relname = '%s' and nspname = '%s' and c.relnamespace = n.oid",
-            SAFE_NAME(ti->table_name), SAFE_NAME(ti->schema_name));
-   res = CC_send_query(conn, query, NULL, READ_ONLY_QUERY, NULL);
-   if (QR_command_maybe_successful(res))
-   {
-       stmt->num_key_fields = PG_NUM_NORMAL_KEYS;
-       if (1 == QR_get_num_total_tuples(res))
-       {
-           const char *value = QR_get_value_backend_text(res, 0, 0);
-           const char *value2 = QR_get_value_backend_text(res, 0, 2);
-           if (value && ('f' == *value || '0' == *value))
-           {
-               hasoids = FALSE;
-               TI_set_has_no_oids(ti);
-           }
-           else
-           {
-               TI_set_hasoids(ti);
-               foundKey = TRUE;
-               STR_TO_NAME(ti->bestitem, OID_NAME);
-               STRX_TO_NAME(ti->bestqual, "\"" OID_NAME "\" = %u");
-           }
-           if (value2 && ('f' == *value2 || '0' == *value2))
-           {
-               TI_set_has_no_subclass(ti);
-           }
-           else
-           {
-               hassubclass = TRUE;
-               TI_set_hassubclass(ti);
-               STR_TO_NAME(ti->bestitem, TABLEOID_NAME);
-               STRX_TO_NAME(ti->bestqual, "\"" TABLEOID_NAME "\" = %u");
-           }
-           TI_set_hasoids_checked(ti);
-           ti->table_oid = (OID) strtoul(QR_get_value_backend_text(res, 0, 1), NULL, 10);
-       }
-       QR_Destructor(res);
-       res = NULL;
-       if (!hasoids && !hassubclass)
-       {
-           SPRINTF_FIXED(query, "select a.attname, a.atttypid from pg_index i, pg_attribute a where indrelid=%u and indnatts=1 and indisunique and indexprs is null and indpred is null and i.indrelid = a.attrelid and a.attnum=i.indkey[0] and attnotnull and atttypid in (%d, %d)", ti->table_oid, PG_TYPE_INT4, PG_TYPE_OID);
-           res = CC_send_query(conn, query, NULL, READ_ONLY_QUERY, NULL);
-           if (QR_command_maybe_successful(res) && QR_get_num_total_tuples(res) > 0)
-           {
-               foundKey = TRUE;
-               STR_TO_NAME(ti->bestitem, QR_get_value_backend_text(res, 0, 0));
-               SPRINTF_FIXED(query, "\"%s\" = %%", SAFE_NAME(ti->bestitem));
-               if (PG_TYPE_INT4 == (OID) QR_get_value_backend_int(res, 0, 1, NULL))
-                   STRCAT_FIXED(query, "d");
-               else
-                   STRCAT_FIXED(query, "u");
-               STRX_TO_NAME(ti->bestqual, query);
-           }
-           else
-           {
-               /* stmt->updatable = FALSE; */
-               foundKey = TRUE;
-               stmt->num_key_fields--;
-           }
-       }
-   }
-   QR_Destructor(res);
-   SC_set_checked_hasoids(stmt, foundKey);
-
-   MYLOG(DETAIL_LOG_LEVEL, "subclass=%d oids=%d bestqual=%s foundKey=%d num_key_fields=%d\n", TI_has_subclass(ti), TI_has_oids(ti), PRINT_NAME(ti->bestqual), foundKey, stmt->num_key_fields);
-
-   return TRUE;
-}
-
 static BOOL increaseNtab(StatementClass *stmt, const char *func)
 {
    TABLE_INFO  **ti = stmt->ti, *wti;
@@ -1383,7 +1304,7 @@ parse_the_statement(StatementClass *stmt, BOOL check_hasoids, BOOL sqlsvr_check)
    if (SC_parsed_status(stmt) != STMT_PARSE_NONE)
    {
        if (check_hasoids)
-           CheckHasOids(stmt);
+           CheckPgClassInfo(stmt);
        return TRUE;
    }
    nfields = 0;
@@ -2261,7 +2182,7 @@ MYLOG(0, "blevel=%d btoken=%s in_dot=%d in_field=%d tbname=%s\n", blevel, btoken
    }
 
    if (check_hasoids && updatable)
-       CheckHasOids(stmt);
+       CheckPgClassInfo(stmt);
    SC_set_parse_status(stmt, parse ? STMT_PARSE_COMPLETE : STMT_PARSE_INCOMPLETE);
    for (i = 0; i < (int) irdflds->nfields; i++)
    {
index 1f1ef8c2d89ebe2b1ec6a4eea556700700e5b745..5abeca88c2f7087eb292ef182596a6579cbdf667 100644 (file)
@@ -542,6 +542,7 @@ RETCODE     SetStatementSvp(StatementClass *self, unsigned int option);
 RETCODE        DiscardStatementSvp(StatementClass *self, RETCODE, BOOL errorOnly);
 
 QResultClass *ParseAndDescribeWithLibpq(StatementClass *stmt, const char *plan_name, const char *query_p, Int2 num_params, const char *comment, QResultClass *res);
+BOOL   CheckPgClassInfo(StatementClass *);
 
 /*
  * Macros to convert global index <-> relative index in resultset/rowset