Ejemplo n.º 1
0
static awk_value_t *
process_result(PGconn *conn, PGresult *res, awk_value_t *resp)
{
  ExecStatusType rc;

  switch (rc = PQresultStatus(res)) {
  case PGRES_TUPLES_OK:
    {
      static unsigned long hnum = 0;
      char handle[64];
      size_t sl;

      snprintf(handle, sizeof(handle), "TUPLES %d pgres%lu",
	       PQntuples(res), hnum++);
      sl = strlen(handle);
      strhash_get(results, handle, sl, 1)->data = res;
      make_string_malloc(handle, sl, resp);
    }
    break;
  case PGRES_COMMAND_OK:
  case PGRES_EMPTY_QUERY:
    {
      char result[32];
      int cnt;

      if (sscanf(PQcmdTuples(res), "%d", &cnt) != 1)
        cnt = 0;
      snprintf(result, sizeof(result), "OK %d", cnt);
      PQclear(res);
      make_string_malloc(result, strlen(result), resp);
    }
    break;
  case PGRES_COPY_IN:
    {
      char buf[100];
      snprintf(buf, sizeof(buf), "COPY_IN %d %s",
	       PQnfields(res), (PQbinaryTuples(res) ? "BINARY" : "TEXT"));
      make_string_malloc(buf, strlen(buf), resp);
      PQclear(res);
    }
    break;
  case PGRES_COPY_OUT:
    {
      char buf[100];
      snprintf(buf, sizeof(buf), "COPY_OUT %d %s",
	       PQnfields(res), (PQbinaryTuples(res) ? "BINARY" : "TEXT"));
      make_string_malloc(buf, strlen(buf), resp);
      PQclear(res);
    }
    break;
  default: /* error */
    set_error(conn, rc, resp);
    set_ERRNO(PQresultErrorMessage(res));
    PQclear(res);
  }
  return resp;
}
Ejemplo n.º 2
0
   int CPgsqlResultHandler::extractValueAsInt(const int columnIndex)
   {
      char * valuePoint = PQgetvalue(m_res, m_currentResultIndex, columnIndex);
      int result = 0;
      if (PQbinaryTuples(m_res) == 1)
      {
         int nbBytes = PQfsize(m_res, columnIndex);

         switch (nbBytes)
         {
         case 8:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int64 *)valuePoint));
            break;
         default:
         case 4:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int32 *)valuePoint));
            break;
         case 2:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int16 *)valuePoint));
            break;
         }
      }
      else
      {
         result = atoi(valuePoint);
      }
      return result;
   }
Ejemplo n.º 3
0
Archivo: common.c Proyecto: GisKook/Gis
/*
 * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
 *
 * Note: Utility function for use by SendQuery() only.
 *
 * Returns true if the query executed successfully, false otherwise.
 */
static bool
ProcessCopyResult(PGresult *results)
{
	bool		success = false;

	if (!results)
		return false;

	switch (PQresultStatus(results))
	{
		case PGRES_TUPLES_OK:
		case PGRES_COMMAND_OK:
		case PGRES_EMPTY_QUERY:
			/* nothing to do here */
			success = true;
			break;

		case PGRES_COPY_OUT:
			SetCancelConn();
			success = handleCopyOut(pset.db, pset.queryFout);
			ResetCancelConn();
			break;

		case PGRES_COPY_IN:
			SetCancelConn();
			success = handleCopyIn(pset.db, pset.cur_cmd_source,
								   PQbinaryTuples(results));
			ResetCancelConn();
			break;

		default:
			break;
	}

	/* may need this to recover from conn loss during COPY */
	if (!CheckConnection())
		return false;

	return success;
}
Ejemplo n.º 4
0
Archivo: copy.c Proyecto: colinet/sqlix
/*
 * Execute a \copy command (frontend copy). We have to open a file, then
 * submit a COPY query to the backend and either feed it data from the
 * file or route its response into the file.
 */
bool
do_copy(const char *args)
{
	struct pqbuf query;
	FILE* copystream;
	struct copy_options *options;
	PGresult* result;
	bool success;
	struct stat st;

	/* parse options */
	options = parse_slash_copy(args);
	if (!options)
		return false;

	/* prepare to read or write the target file */
	if (options->file)
		canonicalize_path(options->file);

	if (options->from) {
		if (options->file)
			copystream = fopen(options->file, PG_BINARY_R);
		else if (!options->psql_inout)
			copystream = pset.cur_cmd_source;
		else
			copystream = stdin;
	} else {
		if (options->file)
			copystream = fopen(options->file, PG_BINARY_W);
		else if (!options->psql_inout)
			copystream = pset.queryFout;
		else
			copystream = stdout;
	}

	if (!copystream) {
		psql_error("%s: %s\n", options->file, strerror(errno));
		free_copy_options(options);
		return false;
	}

	/* make sure the specified file is not a directory */
	fstat(fileno(copystream), &st);
	if (S_ISDIR(st.st_mode)) {
		fclose(copystream);
		psql_error("%s: cannot copy from/to a directory\n", options->file);
		free_copy_options(options);
		return false;
	}

	/* build the command we will send to the backend */
	init_pqbuf(&query);
	print_pqbuf(&query, "COPY ");
	append_pqbuf_str(&query, options->before_tofrom);
	if (options->from)
		append_pqbuf(&query, " FROM STDIN ");
	else
		append_pqbuf(&query, " TO STDOUT ");

	if (options->after_tofrom)
		append_pqbuf_str(&query, options->after_tofrom);

	result = PSQLexec(query.data, true);
	term_pqbuf(&query);

	switch (PQresultStatus(result)) {
	case PGRES_COPY_OUT:
		SetCancelConn();
		success = handleCopyOut(pset.db, copystream);
		ResetCancelConn();
		break;
	case PGRES_COPY_IN:
		SetCancelConn();
		success = handleCopyIn(pset.db, copystream, PQbinaryTuples(result));
		ResetCancelConn();
		break;
	case PGRES_NONFATAL_ERROR:
	case PGRES_FATAL_ERROR:
	case PGRES_BAD_RESPONSE:
		success = false;
		psql_error("\\copy: %s", PQerrorMessage(pset.db));
		break;
	default:
		success = false;
		psql_error("\\copy: unexpected response (%d)\n", PQresultStatus(result));
		break;
	}

	PQclear(result);

	/*
	 * Make sure we have pumped libpq dry of results; else it may still be in
	 * ASYNC_BUSY state, leading to false readings in, eg, get_prompt().
	 */
	while ((result = PQgetResult(pset.db)) != NULL) {
		success = false;
		psql_error("\\copy: unexpected response (%d)\n", PQresultStatus(result));

		/* if still in COPY IN state, try to get out of it */
		if (PQresultStatus(result) == PGRES_COPY_IN)
			PQputCopyEnd(pset.db, _("trying to exit copy mode"));

		PQclear(result);
	}

	if (options->file != NULL) {
		if (fclose(copystream) != 0) {
			psql_error("%s: %s\n", options->file, strerror(errno));
			success = false;
		}
	}

	free_copy_options(options);
	return success;
}
Ejemplo n.º 5
0
/*
 * ProcessResult: utility function for use by SendQuery() only
 *
 * When our command string contained a COPY FROM STDIN or COPY TO STDOUT,
 * PQexec() has stopped at the PGresult associated with the first such
 * command.  In that event, we'll marshal data for the COPY and then cycle
 * through any subsequent PGresult objects.
 *
 * When the command string contained no such COPY command, this function
 * degenerates to an AcceptResult() call.
 *
 * Changes its argument to point to the last PGresult of the command string,
 * or NULL if that result was for a COPY TO STDOUT.  (Returning NULL prevents
 * the command status from being printed, which we want in that case so that
 * the status line doesn't get taken as part of the COPY data.)
 *
 * Returns true on complete success, false otherwise.  Possible failure modes
 * include purely client-side problems; check the transaction status for the
 * server-side opinion.
 */
static bool
ProcessResult(PGresult **results)
{
	bool		success = true;
	bool		first_cycle = true;

	for (;;)
	{
		ExecStatusType result_status;
		bool		is_copy;
		PGresult   *next_result;

		if (!AcceptResult(*results))
		{
			/*
			 * Failure at this point is always a server-side failure or a
			 * failure to submit the command string.  Either way, we're
			 * finished with this command string.
			 */
			success = false;
			break;
		}

		result_status = PQresultStatus(*results);
		switch (result_status)
		{
			case PGRES_EMPTY_QUERY:
			case PGRES_COMMAND_OK:
			case PGRES_TUPLES_OK:
				is_copy = false;
				break;

			case PGRES_COPY_OUT:
			case PGRES_COPY_IN:
				is_copy = true;
				break;

			default:
				/* AcceptResult() should have caught anything else. */
				is_copy = false;
				psql_error("unexpected PQresultStatus: %d\n", result_status);
				break;
		}

		if (is_copy)
		{
			/*
			 * Marshal the COPY data.  Either subroutine will get the
			 * connection out of its COPY state, then call PQresultStatus()
			 * once and report any error.
			 *
			 * If pset.copyStream is set, use that as data source/sink,
			 * otherwise use queryFout or cur_cmd_source as appropriate.
			 */
			FILE	   *copystream = pset.copyStream;
			PGresult   *copy_result;

			SetCancelConn();
			if (result_status == PGRES_COPY_OUT)
			{
				if (!copystream)
					copystream = pset.queryFout;
				success = handleCopyOut(pset.db,
										copystream,
										&copy_result) && success;

				/*
				 * Suppress status printing if the report would go to the same
				 * place as the COPY data just went.  Note this doesn't
				 * prevent error reporting, since handleCopyOut did that.
				 */
				if (copystream == pset.queryFout)
				{
					PQclear(copy_result);
					copy_result = NULL;
				}
			}
			else
			{
				if (!copystream)
					copystream = pset.cur_cmd_source;
				success = handleCopyIn(pset.db,
									   copystream,
									   PQbinaryTuples(*results),
									   &copy_result) && success;
			}
			ResetCancelConn();

			/*
			 * Replace the PGRES_COPY_OUT/IN result with COPY command's exit
			 * status, or with NULL if we want to suppress printing anything.
			 */
			PQclear(*results);
			*results = copy_result;
		}
		else if (first_cycle)
		{
			/* fast path: no COPY commands; PQexec visited all results */
			break;
		}

		/*
		 * Check PQgetResult() again.  In the typical case of a single-command
		 * string, it will return NULL.  Otherwise, we'll have other results
		 * to process that may include other COPYs.  We keep the last result.
		 */
		next_result = PQgetResult(pset.db);
		if (!next_result)
			break;

		PQclear(*results);
		*results = next_result;
		first_cycle = false;
	}

	/* may need this to recover from conn loss during COPY */
	if (!first_cycle && !CheckConnection())
		return false;

	return success;
}
Ejemplo n.º 6
0
/*
 * ProcessResult: utility function for use by SendQuery() only
 *
 * When our command string contained a COPY FROM STDIN or COPY TO STDOUT,
 * PQexec() has stopped at the PGresult associated with the first such
 * command.  In that event, we'll marshal data for the COPY and then cycle
 * through any subsequent PGresult objects.
 *
 * When the command string contained no affected COPY command, this function
 * degenerates to an AcceptResult() call.
 *
 * Changes its argument to point to the last PGresult of the command string,
 * or NULL if that result was for a COPY FROM STDIN or COPY TO STDOUT.
 *
 * Returns true on complete success, false otherwise.  Possible failure modes
 * include purely client-side problems; check the transaction status for the
 * server-side opinion.
 */
static bool
ProcessResult(PGresult **results)
{
	PGresult   *next_result;
	bool		success = true;
	bool		first_cycle = true;

	do
	{
		ExecStatusType result_status;
		bool		is_copy;

		if (!AcceptResult(*results))
		{
			/*
			 * Failure at this point is always a server-side failure or a
			 * failure to submit the command string.  Either way, we're
			 * finished with this command string.
			 */
			success = false;
			break;
		}

		result_status = PQresultStatus(*results);
		switch (result_status)
		{
			case PGRES_EMPTY_QUERY:
			case PGRES_COMMAND_OK:
			case PGRES_TUPLES_OK:
				is_copy = false;
				break;

			case PGRES_COPY_OUT:
			case PGRES_COPY_IN:
				is_copy = true;
				break;

			default:
				/* AcceptResult() should have caught anything else. */
				is_copy = false;
				psql_error("unexpected PQresultStatus: %d\n", result_status);
				break;
		}

		if (is_copy)
		{
			/*
			 * Marshal the COPY data.  Either subroutine will get the
			 * connection out of its COPY state, then call PQresultStatus()
			 * once and report any error.
			 */
			SetCancelConn();
			if (result_status == PGRES_COPY_OUT)
				success = handleCopyOut(pset.db, pset.queryFout) && success;
			else
				success = handleCopyIn(pset.db, pset.cur_cmd_source,
									   PQbinaryTuples(*results)) && success;
			ResetCancelConn();

			/*
			 * Call PQgetResult() once more.  In the typical case of a
			 * single-command string, it will return NULL.	Otherwise, we'll
			 * have other results to process that may include other COPYs.
			 */
			PQclear(*results);
			*results = next_result = PQgetResult(pset.db);
		}
		else if (first_cycle)
			/* fast path: no COPY commands; PQexec visited all results */
			break;
		else if ((next_result = PQgetResult(pset.db)))
		{
			/* non-COPY command(s) after a COPY: keep the last one */
			PQclear(*results);
			*results = next_result;
		}

		first_cycle = false;
	} while (next_result);

	/* may need this to recover from conn loss during COPY */
	if (!first_cycle && !CheckConnection())
		return false;

	return success;
}
Ejemplo n.º 7
0
/*
 * Execute a \copy command (frontend copy). We have to open a file, then
 * submit a COPY query to the backend and either feed it data from the
 * file or route its response into the file.
 */
bool
do_copy(const char *args)
{
	PQExpBufferData query;
	FILE	   *copystream;
	struct copy_options *options;
	PGresult   *result;
	bool		success;
	struct stat st;

	/* parse options */
	options = parse_slash_copy(args);

	if (!options)
		return false;

	initPQExpBuffer(&query);

	printfPQExpBuffer(&query, "COPY ");

	appendPQExpBuffer(&query, "%s ", options->table);

	if (options->column_list)
		appendPQExpBuffer(&query, "%s ", options->column_list);

	if (options->from)
		appendPQExpBuffer(&query, "FROM STDIN");
	else
		appendPQExpBuffer(&query, "TO STDOUT");


	if (options->binary)
		appendPQExpBuffer(&query, " BINARY ");

	if (options->oids)
		appendPQExpBuffer(&query, " OIDS ");

	if (options->delim)
		emit_copy_option(&query, " DELIMITER ", options->delim);

	if (options->null)
		emit_copy_option(&query, " NULL AS ", options->null);

	if (options->csv_mode)
		appendPQExpBuffer(&query, " CSV");

	if (options->header)
		appendPQExpBuffer(&query, " HEADER");

	if (options->quote)
		emit_copy_option(&query, " QUOTE AS ", options->quote);

	if (options->escape)
		emit_copy_option(&query, " ESCAPE AS ", options->escape);

	if (options->force_quote_list)
		appendPQExpBuffer(&query, " FORCE QUOTE %s", options->force_quote_list);

	if (options->force_notnull_list)
		appendPQExpBuffer(&query, " FORCE NOT NULL %s", options->force_notnull_list);

	if (options->file)
		canonicalize_path(options->file);

	if (options->from)
	{
		if (options->file)
			copystream = fopen(options->file, PG_BINARY_R);
		else if (!options->psql_inout)
			copystream = pset.cur_cmd_source;
		else
			copystream = stdin;
	}
	else
	{
		if (options->file)
			copystream = fopen(options->file,
							   options->binary ? PG_BINARY_W : "w");
		else if (!options->psql_inout)
			copystream = pset.queryFout;
		else
			copystream = stdout;
	}

	if (!copystream)
	{
		psql_error("%s: %s\n",
				   options->file, strerror(errno));
		free_copy_options(options);
		return false;
	}

	/* make sure the specified file is not a directory */
	fstat(fileno(copystream), &st);
	if (S_ISDIR(st.st_mode))
	{
		fclose(copystream);
		psql_error("%s: cannot copy from/to a directory\n",
				   options->file);
		free_copy_options(options);
		return false;
	}

	result = PSQLexec(query.data, true);
	termPQExpBuffer(&query);

	switch (PQresultStatus(result))
	{
		case PGRES_COPY_OUT:
			SetCancelConn();
			success = handleCopyOut(pset.db, copystream);
			ResetCancelConn();
			break;
		case PGRES_COPY_IN:
			SetCancelConn();
			success = handleCopyIn(pset.db, copystream,
								   PQbinaryTuples(result));
			ResetCancelConn();
			break;
		case PGRES_NONFATAL_ERROR:
		case PGRES_FATAL_ERROR:
		case PGRES_BAD_RESPONSE:
			success = false;
			psql_error("\\copy: %s", PQerrorMessage(pset.db));
			break;
		default:
			success = false;
			psql_error("\\copy: unexpected response (%d)\n",
					   PQresultStatus(result));
			break;
	}

	PQclear(result);

	/*
	 * Make sure we have pumped libpq dry of results; else it may still be
	 * in ASYNC_BUSY state, leading to false readings in, eg, get_prompt().
	 */
	while ((result = PQgetResult(pset.db)) != NULL)
	{
		success = false;
		psql_error("\\copy: unexpected response (%d)\n",
				   PQresultStatus(result));
		/* if still in COPY IN state, try to get out of it */
		if (PQresultStatus(result) == PGRES_COPY_IN)
			PQputCopyEnd(pset.db, _("trying to exit copy mode"));
		PQclear(result);
	}

	if (options->file != NULL)
	{
		if (fclose(copystream) != 0)
		{
			psql_error("%s: %s\n", options->file, strerror(errno));
			success = false;
		}
	}
	free_copy_options(options);
	return success;
}
Ejemplo n.º 8
0
int pg_createrowset(ClipMachine* mp,SQLROWSET* rs,ClipVar* ap,ClipVar* idname,const char* gen_idSQL){
	PG_ROWSET* rowset = (PG_ROWSET*)rs;
	PG_STMT* stmt = rowset->stmt;
	PG_CONN* conn = rowset->conn;
	int i,mod;

	pg_bindpars(stmt,ap);
	if(!stmt->sql){
		_clip_trap_err(mp,0,0,0,subsys,ER_NOSQL,er_nosql);
		return 1;
	}

	stmt->res = PQexec(conn->conn,stmt->sql);
	if(!stmt->res){
		_clip_trap_err(mp,0,0,0,subsys,ER_BADSTATEMENT,
			PQresultErrorMessage(stmt->res));
		return 1;
	}
	if(PQresultStatus(stmt->res)!=PGRES_TUPLES_OK){
		_clip_trap_err(mp,0,0,0,subsys,ER_BADSELECT,
			PQresultErrorMessage(stmt->res));
		return 1;
	}

	rowset->rowset_item =
		_clip_store_c_item(mp,rowset,_C_ITEM_TYPE_SQL,destroy_pg_rowset);

	rowset->binary = PQbinaryTuples(stmt->res);
	rowset->nfields = PQnfields(stmt->res);
	rowset->fields = calloc(1,rowset->nfields*sizeof(SQLFIELD));
	rowset->id = -1;
	for(i=0;i<rowset->nfields;i++){
		strncpy(rowset->fields[i].name,PQfname(stmt->res,i),
			MAXFIELDNAME);
		rowset->fields[i].name[MAXFIELDNAME] = 0;
		rowset->fields[i].type = PQftype(stmt->res,i);
		rowset->fields[i].ctype[0] = _pg_ctype(rowset->fields[i].type);
		rowset->fields[i].dec = 0;
		mod = PQfmod(stmt->res,i);
		switch(rowset->fields[i].type){
			case PGT_BPCHAR:
			case PGT_CHAR:
			case PGT_VARCHAR:
				rowset->fields[i].len = mod-4;
				break;
			case PGT_TEXT:
				rowset->fields[i].len = 10;
				break;
			case PGT_NUMERIC:
				rowset->fields[i].len = (mod >> 16);
				rowset->fields[i].dec = (mod & 0xffff)-4;
				break;
			case PGT_DATE:
				rowset->fields[i].len = 8;
				break;
			default:
				rowset->fields[i].len = PQfsize(stmt->res,i);
				break;
		}
		rowset->fields[i].ops = 0;
		if(idname && idname->t.type == CHARACTER_t && idname->s.str.buf){
			if(!strcasecmp(rowset->fields[i].name,idname->s.str.buf)){
				rowset->id = i;
			}
		} else if(rowset->fields[i].type == PGT_OID){
			rowset->id = i;
		}
	}

	rowset->lastrec = PQntuples(stmt->res);
	rowset->data = calloc(rowset->lastrec,sizeof(void*));
	return 0;
}