summaryrefslogtreecommitdiff
path: root/bind.h
blob: 00b60704308155b79aee32002dcd6bc80eb1b28b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* File:			bind.h
 *
 * Description:		See "bind.c"
 *
 * Comments:		See "readme.txt" for copyright and license information.
 *
 */

#ifndef __BIND_H__
#define __BIND_H__

#include "psqlodbc.h"
#include "descriptor.h"

/*
 * BindInfoClass -- stores information about a bound column
 */
struct BindInfoClass_
{
	SQLLEN	buflen;			/* size of buffer */
	char	*buffer;		/* pointer to the buffer */
	SQLLEN	*used;			/* used space in the buffer (for strings
					 * not counting the '\0') */
	SQLLEN	*indicator;		/* indicator == used in many cases ? */
	SQLSMALLINT	returntype;	/* kind of conversion to be applied when
					 * returning (SQL_C_DEFAULT,
					 * SQL_C_CHAR... etc) */
	SQLSMALLINT	precision;	/* the precision for numeric or timestamp type */
	SQLSMALLINT	scale;		/* the scale for numeric type */
	/* area for work variables */
	char	dummy_data;		/* currently not used */
};

/* struct for SQLGetData */
typedef struct
{
	/* for BLOBs which don't hold the data */
	struct GetBlobDataClass {
		Int8	data_left64;	/* amount of large object data
					   left to read before conversion */
	} blob;
	/* for non-BLOBs which hold the data in ttlbuf after conversion */
	char	*ttlbuf;		/* to save the large result */
	SQLLEN	ttlbuflen;		/* the buffer length */
	SQLLEN	ttlbufused;		/* used length of the buffer */
	SQLLEN	data_left;		/* amount of data left to read */
}	GetDataClass;
#define GETDATA_RESET(gdc) ((gdc).blob.data_left64 = (gdc).data_left = -1)

/*
 * ParameterInfoClass -- stores information about a bound parameter
 */
struct ParameterInfoClass_
{
	SQLLEN	buflen;
	char	*buffer;
	SQLLEN	*used;
	SQLLEN	*indicator;	/* indicator == used in many cases ? */
	SQLSMALLINT	CType;
	SQLSMALLINT	precision;	/* the precision for numeric or timestamp type */
	SQLSMALLINT	scale;		/* the scale for numeric type */
	/* area for work variables */
	char	data_at_exec;
};

typedef struct
{
	SQLLEN	*EXEC_used;	/* amount of data */
	char	*EXEC_buffer; 	/* the data */
	OID	lobj_oid;
}	PutDataClass;

/*
 * ParameterImplClass -- stores implementation information about a parameter
 */
struct ParameterImplClass_
{
	pgNAME		paramName;	/* this is unavailable even in 8.1 */
	SQLSMALLINT	paramType;
	SQLSMALLINT	SQLType;
	OID		PGType;
	SQLULEN		column_size;
	SQLSMALLINT	decimal_digits;
	SQLSMALLINT	precision;	/* the precision for numeric or timestamp type */
	SQLSMALLINT	scale;		/* the scale for numeric type */
};

typedef struct
{
	GetDataClass	fdata;
	SQLSMALLINT	allocated;
	GetDataClass	*gdata;
}	GetDataInfo;
typedef struct
{
	SQLSMALLINT	allocated;
	PutDataClass	*pdata;
}	PutDataInfo;

#define	PARSE_PARAM_CAST	FALSE
#define	EXEC_PARAM_CAST		TRUE
#define	SIMPLE_PARAM_CAST	TRUE

#define CALC_BOOKMARK_ADDR(book, offset, bind_size, index) \
	(book->buffer + offset + \
	(bind_size > 0 ? bind_size : (SQL_C_VARBOOKMARK == book->returntype ? book->buflen : sizeof(UInt4))) * index)

/* Macros to handle pgtype of parameters */
#define	PIC_get_pgtype(pari) ((pari).PGType)
#define	PIC_set_pgtype(pari, type) ((pari).PGType = (type))
#define	PIC_dsp_pgtype(conn, pari) ((pari).PGType ? (pari).PGType : sqltype_to_pgtype(conn, (pari).SQLType))

void	extend_column_bindings(ARDFields *opts, int num_columns);
void	reset_a_column_binding(ARDFields *opts, int icol);
void	extend_parameter_bindings(APDFields *opts, int num_params);
void	extend_iparameter_bindings(IPDFields *opts, int num_params);
void	reset_a_parameter_binding(APDFields *opts, int ipar);
void	reset_a_iparameter_binding(IPDFields *opts, int ipar);
int	CountParameters(const StatementClass *stmt, Int2 *inCount, Int2 *ioCount, Int2 *outputCount);
void	GetDataInfoInitialize(GetDataInfo *gdata);
void	extend_getdata_info(GetDataInfo *gdata, int num_columns, BOOL shrink);
void	reset_a_getdata_info(GetDataInfo *gdata, int icol);
void	GDATA_unbind_cols(GetDataInfo *gdata, BOOL freeall);
void	PutDataInfoInitialize(PutDataInfo *pdata);
void	extend_putdata_info(PutDataInfo *pdata, int num_params, BOOL shrink);
void	reset_a_putdata_info(PutDataInfo *pdata, int ipar);
void	PDATA_free_params(PutDataInfo *pdata, char option);
void	SC_param_next(const StatementClass*, int *param_number, ParameterInfoClass **, ParameterImplClass **);

RETCODE       prepareParameters(StatementClass *stmt, BOOL fake_params);
RETCODE       prepareParametersNoDesc(StatementClass *stmt, BOOL fake_params, BOOL param_cast);
int	decideHowToPrepare(StatementClass *stmt, BOOL force);

#endif