<commit_before>/*--------
 * Module:			options.c
 *
 * Description:		This module contains routines for getting/setting
 *					connection and statement options.
 *
 * Classes:			n/a
 *
 * API functions:	SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
 *					SQLGetStmtOption
 *
 * Comments:		See "notice.txt" for copyright and license information.
 *--------
 */

#include "psqlodbc.h"
#include <string.h>

#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "qresult.h"
#include "pgapifunc.h"



RETCODE set_statement_option(ConnectionClass *conn,
					 StatementClass *stmt,
					 UWORD fOption,
					 UDWORD vParam);


RETCODE
set_statement_option(ConnectionClass *conn,
					 StatementClass *stmt,
					 UWORD fOption,
					 UDWORD vParam)
{
	CSTR func = "set_statement_option";
	char		changed = FALSE;
	ConnInfo   *ci = NULL;
	UDWORD		setval;

	if (conn)
		ci = &(conn->connInfo);
	else if (stmt)
		ci = &(SC_get_conn(stmt)->connInfo);
	switch (fOption)
	{
		case SQL_ASYNC_ENABLE:	/* ignored */
			break;

		case SQL_BIND_TYPE:
			/* now support multi-column and multi-row binding */
			if (conn)
				conn->ardOptions.bind_size = vParam;
			if (stmt)
				SC_get_ARDF(stmt)->bind_size = vParam;
			break;

		case SQL_CONCURRENCY:

			/*
			 * positioned update isn't supported so cursor concurrency is
			 * read-only
			 */
			mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);
			setval = SQL_CONCUR_READ_ONLY;
			if (SQL_CONCUR_READ_ONLY == vParam)
				;
			else if (ci->drivers.lie)
				setval = vParam;
			else if (ci->updatable_cursors)
				setval = SQL_CONCUR_ROWVER;
			if (conn)
				conn->stmtOptions.scroll_concurrency = setval;
			else if (stmt)
			{
				if (SC_get_Result(stmt))
				{
					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
					SC_log_error(func, "", stmt);
					return SQL_ERROR;
				}
				stmt->options.scroll_concurrency =
				stmt->options_orig.scroll_concurrency = setval;
			}
			if (setval != vParam)
				changed = TRUE;
			mylog("-> %d\n", setval);
			break;

		case SQL_CURSOR_TYPE:

			/*
			 * if declare/fetch, then type can only be forward. otherwise,
			 * it can only be forward or static.
			 */
			mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);
			setval = SQL_CURSOR_FORWARD_ONLY;
			if (ci->drivers.lie)
				setval = vParam;
#ifdef	DECLAREFETCH_FORWARDONLY
			else if (ci->drivers.use_declarefetch)
				;
#endif /* DECLAREFETCH_FORWARDONLY */
			else if (SQL_CURSOR_STATIC == vParam)
				setval = vParam;
			else if (SQL_CURSOR_KEYSET_DRIVEN == vParam)
			{
				if (ci->updatable_cursors)
					setval = vParam;
				else
					setval = SQL_CURSOR_STATIC; /* at least scrollable */
			}
			if (conn)
				conn->stmtOptions.cursor_type = setval;
			else if (stmt)
			{
				if (SC_get_Result(stmt))
				{
					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
					SC_log_error(func, "", stmt);
					return SQL_ERROR;
				}
				stmt->options_orig.cursor_type =
				stmt->options.cursor_type = setval;
			}
			if (setval != vParam)
				changed = TRUE;
			mylog("-> %d\n", setval);
			break;

		case SQL_KEYSET_SIZE:	/* ignored, but saved and returned	*/
			mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);

			if (conn)
				conn->stmtOptions.keyset_size = vParam;
			if (stmt)
			{
				stmt->options_orig.keyset_size = vParam;<commit_msg>According to MSDN docs for SQLSetStmtAttr, if you try to request a cursor type which isn't supported, the driver should fall back to a supported type, set an appropriate SQLState and return SQL_SUCCESS_WITH_INFO.<commit_after>/*--------
 * Module:			options.c
 *
 * Description:		This module contains routines for getting/setting
 *					connection and statement options.
 *
 * Classes:			n/a
 *
 * API functions:	SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
 *					SQLGetStmtOption
 *
 * Comments:		See "notice.txt" for copyright and license information.
 *--------
 */

#include "psqlodbc.h"
#include <string.h>

#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "qresult.h"
#include "pgapifunc.h"



RETCODE set_statement_option(ConnectionClass *conn,
					 StatementClass *stmt,
					 UWORD fOption,
					 UDWORD vParam);


RETCODE
set_statement_option(ConnectionClass *conn,
					 StatementClass *stmt,
					 UWORD fOption,
					 UDWORD vParam)
{
	CSTR func = "set_statement_option";
	char		changed = FALSE;
	ConnInfo   *ci = NULL;
	UDWORD		setval;

	if (conn)
		ci = &(conn->connInfo);
	else if (stmt)
		ci = &(SC_get_conn(stmt)->connInfo);
	switch (fOption)
	{
		case SQL_ASYNC_ENABLE:	/* ignored */
			break;

		case SQL_BIND_TYPE:
			/* now support multi-column and multi-row binding */
			if (conn)
				conn->ardOptions.bind_size = vParam;
			if (stmt)
				SC_get_ARDF(stmt)->bind_size = vParam;
			break;

		case SQL_CONCURRENCY:

			/*
			 * positioned update isn't supported so cursor concurrency is
			 * read-only
			 */
			mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);
			setval = SQL_CONCUR_READ_ONLY;
			if (SQL_CONCUR_READ_ONLY == vParam)
				;
			else if (ci->drivers.lie)
				setval = vParam;
			else if (ci->updatable_cursors)
				setval = SQL_CONCUR_ROWVER;
			if (conn)
				conn->stmtOptions.scroll_concurrency = setval;
			else if (stmt)
			{
				if (SC_get_Result(stmt))
				{
					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
					SC_log_error(func, "", stmt);
					return SQL_ERROR;
				}
				stmt->options.scroll_concurrency =
				stmt->options_orig.scroll_concurrency = setval;
			}
			if (setval != vParam)
				changed = TRUE;
			mylog("-> %d\n", setval);
			break;

		case SQL_CURSOR_TYPE:

			/*
			 * if declare/fetch, then type can only be forward. otherwise,
			 * it can only be forward or static.
			 */
			mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);
			setval = SQL_CURSOR_FORWARD_ONLY;
			if (ci->drivers.lie)
				setval = vParam;
#ifdef	DECLAREFETCH_FORWARDONLY
			else if (ci->drivers.use_declarefetch)
				;
#endif /* DECLAREFETCH_FORWARDONLY */
			else if (SQL_CURSOR_STATIC == vParam)
				setval = vParam;
			else if (SQL_CURSOR_KEYSET_DRIVEN == vParam)
			{
				if (ci->updatable_cursors)
					setval = vParam;
				else
				{
					changed = TRUE;
					setval = SQL_CURSOR_STATIC; /* at least scrollable */
				}
			}
			else if (SQL_CURSOR_DYNAMIC == vParam)
			{
				changed = TRUE;
				if (ci->updatable_cursors)
					setval = SQL_CURSOR_KEYSET_DRIVEN;
				else
					setval = SQL_CURSOR_STATIC;
			}
			if (conn)
				conn->stmtOptions.cursor_type = setval;
			else if (stmt)
			{
				if (SC_get_Result(stmt))
				{
					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
					SC_log_error(func, "", stmt);
					return SQL_ERROR;
				}
				stmt->options_orig.cursor_type =
				stmt->options.cursor_type = setval;
			}
			if (setval != vParam)
				changed = TRUE;
			mylog("-> %d\n", setval);
			break;

		case SQL_KEYSET_SIZE:	/* ignored, but saved and returned	*/
			mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);

			if (conn)
				conn->stmtOptions.keyset_size = vParam;
			if (stmt)
			{
				stmt->options_orig.keyset_size = vParam;
{'fraction_non_alphanumeric': 0.11720765992122777, 'fraction_numerical': 0.0, 'mean_word_length': 3.1347557551937113, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1000915', 'n_tokens_mistral': 3192, 'n_tokens_neox': 2626, 'n_words': 614}