diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index b0dd575fb95e6a25238c60a9cdbf55c95942dc50..2b0d67a648d8ff000c5994b6f319b572dad8b18c 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -384,7 +384,7 @@ CC_begin(ConnectionClass *self) if (res != NULL) { - ret = QR_command_successful(res); + ret = QR_command_maybe_successful(res); QR_Destructor(res); } else @@ -408,7 +408,7 @@ CC_commit(ConnectionClass *self) mylog("CC_commit: sending COMMIT!\n"); if (res != NULL) { - ret = QR_command_successful(res); + ret = QR_command_maybe_successful(res); QR_Destructor(res); } else diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index e4232137fef7dd292c2cdee3ec182b7f92abe69b..a2e2ee8c778b78b9780eeda18bc34c05359d1e50 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -169,6 +169,7 @@ timestamp2stime(const char *str, SIMPLE_TIME *st, BOOL *bZone, int *zone) *bZone = FALSE; *zone = 0; st->fr = 0; + st->infinity = 0; if ((scnt = sscanf(str, "%4d-%2d-%2d %2d:%2d:%2d%s", &st->y, &st->m, &st->d, &st->hh, &st->mm, &st->ss, rest)) < 6) return FALSE; else if (scnt == 6) @@ -455,6 +456,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: st.fr = 0; st.infinity = 0; @@ -464,9 +466,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 st.m = 12; st.d = 31; st.y = 9999; - st.hh = 24; - st.mm = 0; - st.ss = 0; + st.hh = 23; + st.mm = 59; + st.ss = 59; } if (strnicmp(value, "-infinity", 9) == 0) { @@ -641,6 +643,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: len = 19; if (cbValueMax > len) @@ -1810,7 +1813,7 @@ copy_statement_with_parameters(StatementClass *stmt) st.ss = tss->second; st.fr = tss->fraction; - mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); + mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d,fr=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss, st.fr); break; diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index 14ed086e83a62694703a32d218b4098b2f79b2d5..f82a327f9958d62b32695550364f8b43ee6ec7b9 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -553,7 +553,7 @@ PGAPI_Transact( return SQL_ERROR; } - ok = QR_command_successful(res); + ok = QR_command_maybe_successful(res); QR_Destructor(res); if (!ok) diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c index 07f42372842a2e8b03b8b3e13d81ccdf2644b1c9..75deea4c7bd649bd2a628378bcad1b38c365ae1c 100644 --- a/src/interfaces/odbc/info.c +++ b/src/interfaces/odbc/info.c @@ -2966,6 +2966,7 @@ isMultibyte(const unsigned char *str) } return FALSE; } +#ifdef NOT_USED static char * getClientTableName(ConnectionClass *conn, const char *serverSchemaName, char *serverTableName, BOOL *nameAlloced) { @@ -3106,6 +3107,73 @@ getClientColumnName(ConnectionClass *conn, const char * serverSchemaName, const } return ret; } +#endif /* NOT_USED */ +static char * +getClientColumnName(ConnectionClass *conn, UInt4 relid, char *serverColumnName, BOOL *nameAlloced) +{ + char query[1024], saveattnum[16], + *ret = serverColumnName; + BOOL continueExec = TRUE, + bError = FALSE; + QResultClass *res; + + *nameAlloced = FALSE; + if (!conn->client_encoding || !isMultibyte(serverColumnName)) + return ret; + if (!conn->server_encoding) + { + if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL, CLEAR_RESULT_ON_ABORT), res) + { + if (QR_get_num_tuples(res) > 0) + conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0)); + QR_Destructor(res); + } + } + if (!conn->server_encoding) + return ret; + sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding); + bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); + if (!bError && continueExec) + { + sprintf(query, "select attnum from pg_attribute " + "where attrelid = %u and attname = '%s'", + relid, serverColumnName); + if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) + { + if (QR_get_num_tuples(res) > 0) + { + strcpy(saveattnum, QR_get_value_backend_row(res, 0, 0)); + } + else + continueExec = FALSE; + QR_Destructor(res); + } + else + bError = TRUE; + } + continueExec = (continueExec && !bError); + if (bError && CC_is_in_trans(conn)) + { + CC_abort(conn); + bError = FALSE; + } + /* restore the cleint encoding */ + sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding); + bError = (CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT) == NULL); + if (bError || !continueExec) + return ret; + sprintf(query, "select attname from pg_attribute where attrelid = %u and attnum = %s", relid, saveattnum); + if (res = CC_send_query(conn, query, NULL, CLEAR_RESULT_ON_ABORT), res) + { + if (QR_get_num_tuples(res) > 0) + { + ret = strdup(QR_get_value_backend_row(res, 0, 0)); + *nameAlloced = TRUE; + } + QR_Destructor(res); + } + return ret; +} #endif /* MULTIBYTE */ RETCODE SQL_API @@ -3140,23 +3208,20 @@ PGAPI_ForeignKeys( char upd_rule[MAX_TABLE_LEN], del_rule[MAX_TABLE_LEN]; char pk_table_needed[MAX_TABLE_LEN + 1]; +char fk_table_fetched[MAX_TABLE_LEN + 1]; char fk_table_needed[MAX_TABLE_LEN + 1]; - char schema_needed[MAX_TABLE_LEN + 1]; +char pk_table_fetched[MAX_TABLE_LEN + 1]; + char schema_needed[MAX_SCHEMA_LEN + 1]; +char schema_fetched[MAX_SCHEMA_LEN + 1]; char *pkey_ptr, *pkey_text, *fkey_ptr, - *fkey_text, - *pk_table, - *pkt_text, - *fk_table, - *fkt_text; + *fkey_text; ConnectionClass *conn; #ifdef MULTIBYTE BOOL pkey_alloced, - fkey_alloced, - pkt_alloced, - fkt_alloced; + fkey_alloced; #endif /* MULTIBYTE */ int i, j, @@ -3171,6 +3236,7 @@ PGAPI_ForeignKeys( #endif char pkey[MAX_INFO_STRING]; Int2 result_cols; + UInt4 relid1, relid2; mylog("%s: entering...stmt=%u\n", func, stmt); @@ -3251,14 +3317,15 @@ PGAPI_ForeignKeys( pk_table_needed[0] = '\0'; fk_table_needed[0] = '\0'; schema_needed[0] = '\0'; + schema_fetched[0] = '\0'; make_string(szPkTableName, cbPkTableName, pk_table_needed); make_string(szFkTableName, cbFkTableName, fk_table_needed); conn = SC_get_conn(stmt); #ifdef MULTIBYTE - pkey_text = fkey_text = pkt_text = fkt_text = NULL; - pkey_alloced = fkey_alloced = pkt_alloced = fkt_alloced = FALSE; + pkey_text = fkey_text = NULL; + pkey_alloced = fkey_alloced = FALSE; #endif /* MULTIBYTE */ /* @@ -3275,31 +3342,39 @@ PGAPI_ForeignKeys( " pt.tgnargs, " " pt.tgdeferrable, " " pt.tginitdeferred, " - " pg_proc.proname, " - " pg_proc_1.proname " + " pp1.proname, " + " pp2.proname, " + " pc.oid, " + " pc1.oid, " + " pc1.relname, " + " pn.nspname " "FROM pg_class pc, " - " pg_proc pg_proc, " - " pg_proc pg_proc_1, " - " pg_trigger pg_trigger, " - " pg_trigger pg_trigger_1, " + " pg_proc pp1, " + " pg_proc pp2, " + " pg_trigger pt1, " + " pg_trigger pt2, " " pg_proc pp, " - " pg_trigger pt " + " pg_trigger pt, " + " pg_class pc1, " + " pg_namespace pn " "WHERE pt.tgrelid = pc.oid " "AND pp.oid = pt.tgfoid " - "AND pg_trigger.tgconstrrelid = pc.oid " - "AND pg_proc.oid = pg_trigger.tgfoid " - "AND pg_trigger_1.tgfoid = pg_proc_1.oid " - "AND pg_trigger_1.tgconstrrelid = pc.oid " + "AND pt1.tgconstrrelid = pc.oid " + "AND pp1.oid = pt1.tgfoid " + "AND pt2.tgfoid = pp2.oid " + "AND pt2.tgconstrrelid = pc.oid " "AND ((pc.relname='%s') " "AND (pg_namespace.oid = pc.relnamespace) " "AND (pg_namespace.nspname = '%s') " "AND (pp.proname LIKE '%%ins') " - "AND (pg_proc.proname LIKE '%%upd') " - "AND (pg_proc_1.proname LIKE '%%del') " - "AND (pg_trigger.tgrelid=pt.tgconstrrelid) " - "AND (pg_trigger.tgconstrname=pt.tgconstrname) " - "AND (pg_trigger_1.tgrelid=pt.tgconstrrelid) " - "AND (pg_trigger_1.tgconstrname=pt.tgconstrname))", + "AND (pp1.proname LIKE '%%upd') " + "AND (pp2.proname LIKE '%%del') " + "AND (pt1.tgrelid=pt.tgconstrrelid) " + "AND (pt1.tgconstrname=pt.tgconstrname) " + "AND (pt2.tgrelid=pt.tgconstrrelid) " + "AND (pt2.tgconstrname=pt.tgconstrname) " + "AND (pt.tgconstrrelid=pc1.oid) " + "AND (pc1.relnamespace=pn.oid))", fk_table_needed, schema_needed); } else @@ -3307,29 +3382,34 @@ PGAPI_ForeignKeys( " pt.tgnargs, " " pt.tgdeferrable, " " pt.tginitdeferred, " - " pg_proc.proname, " - " pg_proc_1.proname " + " pp1.proname, " + " pp2.proname, " + " pc.oid, " + " pc1.oid, " + " pc1.relname " "FROM pg_class pc, " - " pg_proc pg_proc, " - " pg_proc pg_proc_1, " - " pg_trigger pg_trigger, " - " pg_trigger pg_trigger_1, " + " pg_proc pp1, " + " pg_proc pp2, " + " pg_trigger pt1, " + " pg_trigger pt2, " " pg_proc pp, " - " pg_trigger pt " + " pg_trigger pt, " + " pg_class pc1 " "WHERE pt.tgrelid = pc.oid " "AND pp.oid = pt.tgfoid " - "AND pg_trigger.tgconstrrelid = pc.oid " - "AND pg_proc.oid = pg_trigger.tgfoid " - "AND pg_trigger_1.tgfoid = pg_proc_1.oid " - "AND pg_trigger_1.tgconstrrelid = pc.oid " + "AND pt1.tgconstrrelid = pc.oid " + "AND pp1.oid = pt1.tgfoid " + "AND pt2.tgfoid = pp2.oid " + "AND pt2.tgconstrrelid = pc.oid " "AND ((pc.relname='%s') " "AND (pp.proname LIKE '%%ins') " - "AND (pg_proc.proname LIKE '%%upd') " - "AND (pg_proc_1.proname LIKE '%%del') " - "AND (pg_trigger.tgrelid=pt.tgconstrrelid) " - "AND (pg_trigger.tgconstrname=pt.tgconstrname) " - "AND (pg_trigger_1.tgrelid=pt.tgconstrrelid) " - "AND (pg_trigger_1.tgconstrname=pt.tgconstrname))", + "AND (pp1.proname LIKE '%%upd') " + "AND (pp2.proname LIKE '%%del') " + "AND (pt1.tgrelid=pt.tgconstrrelid) " + "AND (pt1.tgconstrname=pt.tgconstrname) " + "AND (pt2.tgrelid=pt.tgconstrrelid) " + "AND (pt2.tgconstrname=pt.tgconstrname) " + "AND (pt.tgconstrrelid=pc1.oid)) ", fk_table_needed); result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); @@ -3409,6 +3489,51 @@ PGAPI_ForeignKeys( return SQL_ERROR; } + result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, + &relid1, sizeof(relid1), NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, + &relid2, sizeof(relid2), NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + result = PGAPI_BindCol(htbl_stmt, 9, SQL_C_CHAR, + pk_table_fetched, MAX_TABLE_LEN, NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + +if (conn->schema_support) +{ + result = PGAPI_BindCol(htbl_stmt, 10, SQL_C_CHAR, + schema_fetched, MAX_SCHEMA_LEN, NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } +} + result = PGAPI_Fetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; @@ -3449,30 +3574,18 @@ PGAPI_ForeignKeys( mylog("Foreign Key Case#2: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys); - pk_table = trig_args; - - /* Get to the PK Table Name */ - for (k = 0; k < 2; k++) - pk_table += strlen(pk_table) + 1; - -#ifdef MULTIBYTE - fk_table = trig_args + strlen(trig_args) + 1; - pkt_text = getClientTableName(conn, schema_needed, pk_table, &pkt_alloced); -#else - pkt_text = pk_table; -#endif /* MULTIBYTE */ /* If there is a pk table specified, then check it. */ if (pk_table_needed[0] != '\0') { /* If it doesn't match, then continue */ - if (strcmp(pkt_text, pk_table_needed)) + if (strcmp(pk_table_fetched, pk_table_needed)) { result = PGAPI_Fetch(htbl_stmt); continue; } } - keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, schema_needed, SQL_NTS, pkt_text, SQL_NTS); + keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, schema_fetched, SQL_NTS, pk_table_fetched, SQL_NTS); if (keyresult != SQL_SUCCESS) { stmt->errornumber = STMT_NO_MEMORY_ERROR; @@ -3498,7 +3611,7 @@ PGAPI_ForeignKeys( break; } #ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, schema_needed, pk_table, pkey_ptr, &pkey_alloced); + pkey_text = getClientColumnName(conn, relid2, pkey_ptr, &pkey_alloced); #else pkey_text = pkey_ptr; #endif /* MULTIBYTE */ @@ -3566,16 +3679,16 @@ PGAPI_ForeignKeys( row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField)); #ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, schema_needed, pk_table, pkey_ptr, &pkey_alloced); - fkey_text = getClientColumnName(conn, schema_needed, fk_table, fkey_ptr, &fkey_alloced); + pkey_text = getClientColumnName(conn, relid2, pkey_ptr, &pkey_alloced); + fkey_text = getClientColumnName(conn, relid1, fkey_ptr, &fkey_alloced); #else pkey_text = pkey_ptr; fkey_text = fkey_ptr; #endif /* MULTIBYTE */ - mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pkt_text, pkey_text); + mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pk_table_fetched, pkey_text); set_tuplefield_null(&row->tuple[0]); - set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(schema_needed)); - set_tuplefield_string(&row->tuple[2], pkt_text); + set_tuplefield_string(&row->tuple[1], GET_SCHEMA_NAME(schema_fetched)); + set_tuplefield_string(&row->tuple[2], pk_table_fetched); set_tuplefield_string(&row->tuple[3], pkey_text); mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_text); @@ -3611,11 +3724,6 @@ PGAPI_ForeignKeys( pkey_ptr += strlen(pkey_ptr) + 1; } } -#ifdef MULTIBYTE - if (pkt_alloced) - free(pkt_text); - pkt_alloced = FALSE; -#endif /* MULTIBYTE */ result = PGAPI_Fetch(htbl_stmt); } @@ -3632,66 +3740,75 @@ PGAPI_ForeignKeys( if (conn->schema_support) { schema_strcat(schema_needed, "%.*s", szPkTableOwner, cbPkTableOwner, szPkTableName, cbPkTableName); - sprintf(tables_query, "SELECT pg_trigger.tgargs, " - " pg_trigger.tgnargs, " - " pg_trigger.tgdeferrable, " - " pg_trigger.tginitdeferred, " - " pg_proc.proname, " - " pg_proc_1.proname " - "FROM pg_class pg_class, " - " pg_class pg_class_1, " - " pg_class pg_class_2, " - " pg_proc pg_proc, " - " pg_proc pg_proc_1, " - " pg_trigger pg_trigger, " - " pg_trigger pg_trigger_1, " - " pg_trigger pg_trigger_2 " - "WHERE pg_trigger.tgconstrrelid = pg_class.oid " - " AND pg_trigger.tgrelid = pg_class_1.oid " - " AND pg_trigger_1.tgfoid = pg_proc_1.oid " - " AND pg_trigger_1.tgconstrrelid = pg_class_1.oid " - " AND pg_trigger_2.tgconstrrelid = pg_class_2.oid " - " AND pg_trigger_2.tgfoid = pg_proc.oid " - " AND pg_class_2.oid = pg_trigger.tgrelid " + sprintf(tables_query, "SELECT pt.tgargs, " + " pt.tgnargs, " + " pt.tgdeferrable, " + " pt.tginitdeferred, " + " pp.proname, " + " pp1.proname, " + " pc.oid, " + " pc1.oid, " + " pc1.relname, " + " pn.nspname " + "FROM pg_class pc, " + " pg_class pc1, " + " pg_class pc2, " + " pg_proc pp, " + " pg_proc pp1, " + " pg_trigger pt, " + " pg_trigger pt1, " + " pg_trigger pt2, " + " pg_namespace pn " + "WHERE pt.tgconstrrelid = pc.oid " + " AND pt.tgrelid = pc1.oid " + " AND pt1.tgfoid = pp1.oid " + " AND pt1.tgconstrrelid = pc1.oid " + " AND pt2.tgconstrrelid = pc2.oid " + " AND pt2.tgfoid = pp.oid " + " AND pc2.oid = pt.tgrelid " " AND (" - " (pg_class.relname='%s') " - " AND (pg_namespace.oid = pg_class.relnamespace) " + " (pc.relname='%s') " + " AND (pg_namespace.oid = pc.relnamespace) " " AND (pg_namespace.nspname = '%s') " - " AND (pg_proc.proname Like '%%upd') " - " AND (pg_proc_1.proname Like '%%del')" - " AND (pg_trigger_1.tgrelid = pg_trigger.tgconstrrelid) " - " AND (pg_trigger_2.tgrelid = pg_trigger.tgconstrrelid) " + " AND (pp.proname Like '%%upd') " + " AND (pp1.proname Like '%%del')" + " AND (pt1.tgrelid = pt.tgconstrrelid) " + " AND (pt2.tgrelid = pt.tgconstrrelid) " + " AND (pn.oid = pc1.relnamespace) " " )", pk_table_needed, schema_needed); } else - sprintf(tables_query, "SELECT pg_trigger.tgargs, " - " pg_trigger.tgnargs, " - " pg_trigger.tgdeferrable, " - " pg_trigger.tginitdeferred, " - " pg_proc.proname, " - " pg_proc_1.proname " - "FROM pg_class pg_class, " - " pg_class pg_class_1, " - " pg_class pg_class_2, " - " pg_proc pg_proc, " - " pg_proc pg_proc_1, " - " pg_trigger pg_trigger, " - " pg_trigger pg_trigger_1, " - " pg_trigger pg_trigger_2 " - "WHERE pg_trigger.tgconstrrelid = pg_class.oid " - " AND pg_trigger.tgrelid = pg_class_1.oid " - " AND pg_trigger_1.tgfoid = pg_proc_1.oid " - " AND pg_trigger_1.tgconstrrelid = pg_class_1.oid " - " AND pg_trigger_2.tgconstrrelid = pg_class_2.oid " - " AND pg_trigger_2.tgfoid = pg_proc.oid " - " AND pg_class_2.oid = pg_trigger.tgrelid " + sprintf(tables_query, "SELECT pt.tgargs, " + " pt.tgnargs, " + " pt.tgdeferrable, " + " pt.tginitdeferred, " + " pp.proname, " + " pp1.proname, " + " pc.oid, " + " pc1.oid, " + " pc1.relname " + "FROM pg_class pc, " + " pg_class pc1, " + " pg_class pc2, " + " pg_proc pp, " + " pg_proc pp1, " + " pg_trigger pt, " + " pg_trigger pt1, " + " pg_trigger pt2 " + "WHERE pt.tgconstrrelid = pc.oid " + " AND pt.tgrelid = pc1.oid " + " AND pt1.tgfoid = pp1.oid " + " AND pt1.tgconstrrelid = pc1.oid " + " AND pt2.tgconstrrelid = pc2.oid " + " AND pt2.tgfoid = pp.oid " + " AND pc2.oid = pt.tgrelid " " AND (" - " (pg_class.relname='%s') " - " AND (pg_proc.proname Like '%%upd') " - " AND (pg_proc_1.proname Like '%%del')" - " AND (pg_trigger_1.tgrelid = pg_trigger.tgconstrrelid) " - " AND (pg_trigger_2.tgrelid = pg_trigger.tgconstrrelid) " + " (pc.relname='%s') " + " AND (pp.proname Like '%%upd') " + " AND (pp1.proname Like '%%del')" + " AND (pt1.tgrelid = pt.tgconstrrelid) " + " AND (pt2.tgrelid = pt.tgconstrrelid) " " )", pk_table_needed); @@ -3771,6 +3888,51 @@ PGAPI_ForeignKeys( return SQL_ERROR; } + result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, + &relid1, sizeof(relid1), NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, + &relid2, sizeof(relid2), NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + result = PGAPI_BindCol(htbl_stmt, 9, SQL_C_CHAR, + fk_table_fetched, MAX_TABLE_LEN, NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } + +if (conn->schema_support) +{ + result = PGAPI_BindCol(htbl_stmt, 10, SQL_C_CHAR, + schema_fetched, MAX_SCHEMA_LEN, NULL); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { + stmt->errormsg = tbl_stmt->errormsg; + stmt->errornumber = tbl_stmt->errornumber; + SC_log_error(func, "", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + return SQL_ERROR; + } +} + result = PGAPI_Fetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; @@ -3829,16 +3991,6 @@ PGAPI_ForeignKeys( for (i = 0; i < 5; i++) pkey_ptr += strlen(pkey_ptr) + 1; - /* Get to first foreign table */ - fk_table = trig_args; - fk_table += strlen(fk_table) + 1; -#ifdef MULTIBYTE - pk_table = fk_table + strlen(fk_table) + 1; - fkt_text = getClientTableName(conn, schema_needed, fk_table, &fkt_alloced); -#else - fkt_text = fk_table; -#endif /* MULTIBYTE */ - /* Get to first foreign key */ fkey_ptr = trig_args; for (k = 0; k < 4; k++) @@ -3847,13 +3999,13 @@ PGAPI_ForeignKeys( for (k = 0; k < num_keys; k++) { #ifdef MULTIBYTE - pkey_text = getClientColumnName(conn, schema_needed, pk_table, pkey_ptr, &pkey_alloced); - fkey_text = getClientColumnName(conn, schema_needed, fk_table, fkey_ptr, &fkey_alloced); + pkey_text = getClientColumnName(conn, relid1, pkey_ptr, &pkey_alloced); + fkey_text = getClientColumnName(conn, relid2, fkey_ptr, &fkey_alloced); #else pkey_text = pkey_ptr; fkey_text = fkey_ptr; #endif /* MULTIBYTE */ - mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_text, fkt_text, fkey_text); + mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_text, fk_table_fetched, fkey_text); row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField)); @@ -3863,10 +4015,10 @@ PGAPI_ForeignKeys( set_tuplefield_string(&row->tuple[2], pk_table_needed); set_tuplefield_string(&row->tuple[3], pkey_text); - mylog("fk_table = '%s', fkey_ptr = '%s'\n", fkt_text, fkey_text); + mylog("fk_table = '%s', fkey_ptr = '%s'\n", fk_table_fetched, fkey_text); set_tuplefield_null(&row->tuple[4]); - set_tuplefield_string(&row->tuple[5], GET_SCHEMA_NAME(schema_needed)); - set_tuplefield_string(&row->tuple[6], fkt_text); + set_tuplefield_string(&row->tuple[5], GET_SCHEMA_NAME(schema_fetched)); + set_tuplefield_string(&row->tuple[6], fk_table_fetched); set_tuplefield_string(&row->tuple[7], fkey_text); set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1)); @@ -3902,11 +4054,6 @@ PGAPI_ForeignKeys( fkey_ptr += strlen(fkey_ptr) + 1; } } -#ifdef MULTIBYTE - if (fkt_alloced) - free(fkt_text); - fkt_alloced = FALSE; -#endif /* MULTIBYTE */ result = PGAPI_Fetch(htbl_stmt); } } @@ -3919,12 +4066,8 @@ PGAPI_ForeignKeys( return SQL_ERROR; } #ifdef MULTIBYTE - if (pkt_alloced) - free(pkt_text); if (pkey_alloced) free(pkey_text); - if (fkt_alloced) - free(fkt_text); if (fkey_alloced) free(fkey_text); #endif /* MULTIBYTE */ @@ -4002,15 +4145,15 @@ PGAPI_Procedures( " proname as " "PROCEDURE_NAME" ", '' as " "NUM_INPUT_PARAMS" "," " '' as " "NUM_OUTPUT_PARAMS" ", '' as " "NUM_RESULT_SETS" "," " '' as " "REMARKS" "," - " case when prorettype = 0 then 1::int2 else 2::int2 end as " "PROCEDURE_TYPE" " from pg_proc where"); + " case when prorettype = 0 then 1::int2 else 2::int2 end as " "PROCEDURE_TYPE" " from pg_proc"); if (conn->schema_support) { - strcat(proc_query, " pg_proc.namespace = pg_namespace.oid"); + strcat(proc_query, " where pg_proc.pronamespace = pg_namespace.oid"); schema_strcat(proc_query, " and nspname like '%.*s'", szProcOwner, cbProcOwner, szProcName, cbProcName); my_strcat(proc_query, " and proname like '%.*s'", szProcName, cbProcName); } else - my_strcat(proc_query, " proname like '%.*s'", szProcName, cbProcName); + my_strcat(proc_query, " where proname like '%.*s'", szProcName, cbProcName); if (res = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), !res) { diff --git a/src/interfaces/odbc/pgtypes.c b/src/interfaces/odbc/pgtypes.c index 3bc42a97a58c9f14c92f8d09c33229ad8d27345b..74df2a79e93f9c70f14ed9d358a9bd4bc03a52df 100644 --- a/src/interfaces/odbc/pgtypes.c +++ b/src/interfaces/odbc/pgtypes.c @@ -55,6 +55,7 @@ Int4 pgtypes_defined[] = { PG_TYPE_TIME_WITH_TMZONE, PG_TYPE_DATETIME, PG_TYPE_ABSTIME, + PG_TYPE_TIMESTAMP_NO_TMZONE, PG_TYPE_TIMESTAMP, PG_TYPE_TEXT, PG_TYPE_INT2, @@ -312,6 +313,7 @@ pgtype_to_concise_type(StatementClass *stmt, Int4 type) return SQL_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: #if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) @@ -416,6 +418,7 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type) return SQL_C_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: #if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) @@ -491,6 +494,8 @@ pgtype_to_name(StatementClass *stmt, Int4 type) return "abstime"; case PG_TYPE_DATETIME: return "datetime"; + case PG_TYPE_TIMESTAMP_NO_TMZONE: + return "timestamp_nozone"; case PG_TYPE_TIMESTAMP: return "timestamp"; case PG_TYPE_MONEY: @@ -817,6 +822,7 @@ pgtype_column_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_ case PG_TYPE_TIMESTAMP: return 22; case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: /* return 22; */ return getTimestampColumnSize(stmt, type, col); @@ -851,6 +857,7 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si case PG_TYPE_NUMERIC: return getNumericColumnSize(stmt, type, col); case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: return getTimestampDecimalDigits(stmt, type, col); } return -1; @@ -938,6 +945,7 @@ pgtype_buffer_length(StatementClass *stmt, Int4 type, int col, int handle_unknow case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: + case PG_TYPE_TIMESTAMP_NO_TMZONE: return 16; /* sizeof(TIMESTAMP_STRUCT) */ /* Character types use the default precision */ @@ -1001,6 +1009,7 @@ pgtype_desclength(StatementClass *stmt, Int4 type, int col, int handle_unknown_s case PG_TYPE_TIME: case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: case PG_TYPE_VARCHAR: case PG_TYPE_BPCHAR: @@ -1073,6 +1082,7 @@ pgtype_decimal_digits(StatementClass *stmt, Int4 type, int col) case PG_TYPE_TIMESTAMP: return 0; case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: /* return 0; */ return getTimestampDecimalDigits(stmt, type, col); @@ -1147,6 +1157,7 @@ pgtype_auto_increment(StatementClass *stmt, Int4 type) case PG_TYPE_TIME: case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: return FALSE; diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c index 5f78ba936adae694a0f4b58e32724cb8bcc0c673..937e275e058d082cbaa20545d9f28bff2fad773b 100644 --- a/src/interfaces/odbc/results.c +++ b/src/interfaces/odbc/results.c @@ -1964,7 +1964,7 @@ SC_pos_delete(StatementClass *stmt, mylog("dltstr=%s\n", dltstr); qres = CC_send_query(conn, dltstr, NULL, CLEAR_RESULT_ON_ABORT); ret = SQL_SUCCESS; - if (qres && QR_command_successful(qres)) + if (qres && QR_command_maybe_successful(qres)) { int dltcnt; const char *cmdstr = QR_get_command(qres); diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c index cf3db03ead30665b635b846d748f49ecd8ca676e..122fcbff9bb371b07d692edb09a1c64ab7c24b72 100644 --- a/src/interfaces/odbc/statement.c +++ b/src/interfaces/odbc/statement.c @@ -955,7 +955,7 @@ SC_execute(StatementClass *self) /* send the declare/select */ res = CC_send_query(conn, self->stmt_with_params, NULL, qflag); if (SC_is_fetchcursor(self) && res != NULL && - QR_command_successful(res)) + QR_command_maybe_successful(res)) { QR_Destructor(res); qflag &= (~ GO_INTO_TRANSACTION);