static int get_types(db_cmd_t* cmd) { struct pg_cmd* pcmd; struct pg_con* pcon; pcmd = DB_GET_PAYLOAD(cmd); /* FIXME */ pcon = DB_GET_PAYLOAD(cmd->ctx->con[db_payload_idx]); pcmd->types = PQdescribePrepared(pcon->con, pcmd->name); if (PQresultStatus(pcmd->types) != PGRES_COMMAND_OK) { ERR("postgres: Error while obtaining description of prepared statement\n"); return -1; } return 0; }
CAMLprim value PQdescribePrepared_stub(value v_conn, value v_query) { CAMLparam1(v_conn); PGconn *conn = get_conn(v_conn); np_callback *np_cb = get_conn_cb(v_conn); PGresult *res; size_t len = caml_string_length(v_query) + 1; char *query = caml_stat_alloc(len); memcpy(query, String_val(v_query), len); caml_enter_blocking_section(); res = PQdescribePrepared(conn, query); free(query); caml_leave_blocking_section(); CAMLreturn(alloc_result(res, np_cb)); #else CAMLprim value PQdescribePrepared_stub(value __unused v_conn, value __unused v_query) { caml_failwith("Postgresql.describe_prepared: not supported"); return Val_unit; #endif }
static int get_types(db_cmd_t* cmd) { struct pg_cmd* pcmd; struct pg_con* pcon; int i, n; pg_type_t *types; pcmd = DB_GET_PAYLOAD(cmd); /* FIXME */ pcon = DB_GET_PAYLOAD(cmd->ctx->con[db_payload_idx]); types = pcon->oid; pcmd->types = PQdescribePrepared(pcon->con, pcmd->name); if (PQresultStatus(pcmd->types) != PGRES_COMMAND_OK) { ERR("postgres: Error while obtaining description of prepared statement\n"); return -1; } /* adapted from check_result() in db_mysql */ n = PQnfields(pcmd->types); if (cmd->result == NULL) { /* The result set parameter of db_cmd function was empty, that * means the command is select * and we have to create the array * of result fields in the cmd structure manually. */ cmd->result = db_fld(n + 1); cmd->result_count = n; for(i = 0; i < cmd->result_count; i++) { struct pg_fld *f; if (pg_fld(cmd->result + i, cmd->table.s) < 0) goto error; f = DB_GET_PAYLOAD(cmd->result + i); f->name = pkg_malloc(strlen(PQfname(pcmd->types, i))+1); if (f->name == NULL) { ERR("postgres: Out of private memory\n"); goto error; } strcpy(f->name, PQfname(pcmd->types, i)); cmd->result[i].name = f->name; } } else { if (cmd->result_count != n) { BUG("postgres: Number of fields in PQresult does not match number of parameters in DB API\n"); goto error; } } /* Now iterate through all the columns in the result set and replace * any occurrence of DB_UNKNOWN type with the type of the column * retrieved from the database and if no column name was provided then * update it from the database as well. */ for(i = 0; i < cmd->result_count; i++) { Oid type = PQftype(pcmd->types, i); if (cmd->result[i].type != DB_NONE) continue; if ((type == types[PG_INT2].oid) || (type == types[PG_INT4].oid) || (type == types[PG_INT8].oid)) cmd->result[i].type = DB_INT; else if (type == types[PG_FLOAT4].oid) cmd->result[i].type = DB_FLOAT; else if (type == types[PG_FLOAT8].oid) cmd->result[i].type = DB_DOUBLE; else if ((type == types[PG_TIMESTAMP].oid) || (type == types[PG_TIMESTAMPTZ].oid)) cmd->result[i].type = DB_DATETIME; else if ((type == types[PG_VARCHAR].oid) || (type == types[PG_CHAR].oid) || (type == types[PG_TEXT].oid)) cmd->result[i].type = DB_STR; else if ((type == types[PG_BIT].oid) || (type == types[PG_VARBIT].oid)) cmd->result[i].type = DB_BITMAP; else if (type == types[PG_BYTE].oid) cmd->result[i].type = DB_BLOB; else { ERR("postgres: Unsupported PostgreSQL column type: %d, table: %s, column: %s\n", type, cmd->table.s, PQfname(pcmd->types, i)); goto error; } } return 0; error: return -1; }