PostgreSQL Source Code  git master
extern.h File Reference
#include "libpq-fe.h"
#include "sqlca.h"
#include "sqlda-native.h"
#include "sqlda-compat.h"
#include "ecpg_config.h"
#include <limits.h>
Include dependency graph for extern.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ECPGgeneric_varchar
 
struct  ECPGtype_information_cache
 
struct  statement
 
struct  prepared_statement
 
struct  connection
 
struct  descriptor
 
struct  descriptor_item
 
struct  variable
 
struct  var_list
 

Macros

#define INFORMIX_MODE(X)   ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)
 
#define ORACLE_MODE(X)   ((X) == ECPG_COMPAT_ORACLE)
 
#define ECPG_IS_ARRAY(X)   ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
 
#define ECPG_SQLSTATE_NO_DATA   "02000"
 
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS   "07001"
 
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS   "07002"
 
#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION   "07006"
 
#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX   "07009"
 
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION   "08001"
 
#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST   "08003"
 
#define ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN   "08007"
 
#define ECPG_SQLSTATE_CARDINALITY_VIOLATION   "21000"
 
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER   "22002"
 
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION   "25001"
 
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION   "25P01"
 
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME   "26000"
 
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME   "33000"
 
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME   "34000"
 
#define ECPG_SQLSTATE_SYNTAX_ERROR   "42601"
 
#define ECPG_SQLSTATE_DATATYPE_MISMATCH   "42804"
 
#define ECPG_SQLSTATE_DUPLICATE_CURSOR   "42P03"
 
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR   "YE000"
 
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY   "YE001"
 

Enumerations

enum  COMPAT_MODE {
  ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ECPG_COMPAT_ORACLE,
  ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ECPG_COMPAT_ORACLE
}
 
enum  ARRAY_TYPE {
  ECPG_ARRAY_ERROR, ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR,
  ECPG_ARRAY_NONE
}
 

Functions

bool ecpg_add_mem (void *ptr, int lineno)
 
bool ecpg_get_data (const PGresult *, int, int, int, enum ECPGttype type, enum ECPGttype, char *, char *, long, long, long, enum ARRAY_TYPE, enum COMPAT_MODE, bool)
 
struct connectionecpg_get_connection (const char *)
 
char * ecpg_alloc (long, int)
 
char * ecpg_auto_alloc (long, int)
 
char * ecpg_realloc (void *, long, int)
 
void ecpg_free (void *)
 
bool ecpg_init (const struct connection *, const char *, const int)
 
char * ecpg_strdup (const char *, int)
 
const char * ecpg_type_name (enum ECPGttype)
 
int ecpg_dynamic_type (Oid)
 
int sqlda_dynamic_type (Oid, enum COMPAT_MODE)
 
void ecpg_free_auto_mem (void)
 
void ecpg_clear_auto_mem (void)
 
struct descriptorecpggetdescp (int, char *)
 
struct descriptorecpg_find_desc (int line, const char *name)
 
struct prepared_statementecpg_find_prepared_statement (const char *, struct connection *, struct prepared_statement **)
 
bool ecpg_store_result (const PGresult *results, int act_field, const struct statement *stmt, struct variable *var)
 
bool ecpg_store_input (const int, const bool, const struct variable *, char **, bool)
 
void ecpg_free_params (struct statement *stmt, bool print)
 
bool ecpg_do_prologue (int, const int, const int, const char *, const bool, enum ECPG_statement_type, const char *, va_list, struct statement **)
 
bool ecpg_build_params (struct statement *)
 
bool ecpg_autostart_transaction (struct statement *stmt)
 
bool ecpg_execute (struct statement *stmt)
 
bool ecpg_process_output (struct statement *, bool)
 
void ecpg_do_epilogue (struct statement *)
 
bool ecpg_do (const int, const int, const int, const char *, const bool, const int, const char *, va_list)
 
bool ecpg_check_PQresult (PGresult *, int, PGconn *, enum COMPAT_MODE)
 
void ecpg_raise (int line, int code, const char *sqlstate, const char *str)
 
void ecpg_raise_backend (int line, PGresult *result, PGconn *conn, int compat)
 
char * ecpg_prepared (const char *, struct connection *)
 
bool ecpg_deallocate_all_conn (int lineno, enum COMPAT_MODE c, struct connection *conn)
 
void ecpg_log (const char *format,...) pg_attribute_printf(1
 
void bool ecpg_auto_prepare (int, const char *, const int, char **, const char *)
 
void ecpg_init_sqlca (struct sqlca_t *sqlca)
 
struct sqlda_compatecpg_build_compat_sqlda (int, PGresult *, int, enum COMPAT_MODE)
 
void ecpg_set_compat_sqlda (int, struct sqlda_compat **, const PGresult *, int, enum COMPAT_MODE)
 
struct sqlda_structecpg_build_native_sqlda (int, PGresult *, int, enum COMPAT_MODE)
 
void ecpg_set_native_sqlda (int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE)
 

Variables

bool ecpg_internal_regression_mode
 
struct var_listivlist
 

Macro Definition Documentation

◆ ECPG_IS_ARRAY

#define ECPG_IS_ARRAY (   X)    ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)

Definition at line 31 of file extern.h.

Referenced by ecpg_get_data(), ecpg_is_type_an_array(), and garbage_left().

◆ ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION

#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION   "25001"

Definition at line 211 of file extern.h.

Referenced by ECPGnoticeReceiver().

◆ ECPG_SQLSTATE_CARDINALITY_VIOLATION

#define ECPG_SQLSTATE_CARDINALITY_VIOLATION   "21000"

Definition at line 209 of file extern.h.

Referenced by ecpg_store_result(), and ECPGget_desc().

◆ ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST

#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST   "08003"

Definition at line 207 of file extern.h.

Referenced by ecpg_init(), and ECPGdescribe().

◆ ECPG_SQLSTATE_DATATYPE_MISMATCH

#define ECPG_SQLSTATE_DATATYPE_MISMATCH   "42804"

Definition at line 217 of file extern.h.

Referenced by ecpg_get_data(), ecpg_store_input(), and ecpg_store_result().

◆ ECPG_SQLSTATE_DUPLICATE_CURSOR

#define ECPG_SQLSTATE_DUPLICATE_CURSOR   "42P03"

Definition at line 218 of file extern.h.

Referenced by ECPGnoticeReceiver().

◆ ECPG_SQLSTATE_ECPG_INTERNAL_ERROR

#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR   "YE000"

◆ ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY

◆ ECPG_SQLSTATE_INVALID_CURSOR_NAME

#define ECPG_SQLSTATE_INVALID_CURSOR_NAME   "34000"

Definition at line 215 of file extern.h.

Referenced by ECPGnoticeReceiver().

◆ ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX

#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX   "07009"

Definition at line 205 of file extern.h.

Referenced by ECPGget_desc().

◆ ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME

#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME   "33000"

Definition at line 214 of file extern.h.

Referenced by ecpg_find_desc(), and ECPGdeallocate_desc().

◆ ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME

#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME   "26000"

Definition at line 213 of file extern.h.

Referenced by deallocate_one(), ecpg_do_prologue(), ECPGdeallocate(), and ECPGdescribe().

◆ ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION

#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION   "25P01"

Definition at line 212 of file extern.h.

Referenced by ECPGnoticeReceiver().

◆ ECPG_SQLSTATE_NO_DATA

#define ECPG_SQLSTATE_NO_DATA   "02000"

Definition at line 201 of file extern.h.

Referenced by ecpg_get_data(), and ecpg_process_output().

◆ ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER

#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER   "22002"

Definition at line 210 of file extern.h.

Referenced by ecpg_get_data().

◆ ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION

#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION   "07006"

Definition at line 204 of file extern.h.

Referenced by get_char_item(), get_int_item(), and set_int_item().

◆ ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION

#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION   "08001"

Definition at line 206 of file extern.h.

Referenced by ECPGconnect().

◆ ECPG_SQLSTATE_SYNTAX_ERROR

#define ECPG_SQLSTATE_SYNTAX_ERROR   "42601"

Definition at line 216 of file extern.h.

◆ ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN

#define ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN   "08007"

Definition at line 208 of file extern.h.

◆ ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS   "07001"

Definition at line 202 of file extern.h.

Referenced by ecpg_build_params().

◆ ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS   "07002"

Definition at line 203 of file extern.h.

Referenced by ecpg_process_output().

◆ INFORMIX_MODE

◆ ORACLE_MODE

#define ORACLE_MODE (   X)    ((X) == ECPG_COMPAT_ORACLE)

Definition at line 24 of file extern.h.

Referenced by ecpg_get_data().

Enumeration Type Documentation

◆ ARRAY_TYPE

enum ARRAY_TYPE
Enumerator
ECPG_ARRAY_ERROR 
ECPG_ARRAY_NOT_SET 
ECPG_ARRAY_ARRAY 
ECPG_ARRAY_VECTOR 
ECPG_ARRAY_NONE 

Definition at line 26 of file extern.h.

◆ COMPAT_MODE

Enumerator
ECPG_COMPAT_PGSQL 
ECPG_COMPAT_INFORMIX 
ECPG_COMPAT_INFORMIX_SE 
ECPG_COMPAT_ORACLE 
ECPG_COMPAT_PGSQL 
ECPG_COMPAT_INFORMIX 
ECPG_COMPAT_INFORMIX_SE 
ECPG_COMPAT_ORACLE 

Definition at line 16 of file extern.h.

Function Documentation

◆ ecpg_add_mem()

bool ecpg_add_mem ( void *  ptr,
int  lineno 
)

Definition at line 124 of file memory.c.

References ecpg_alloc(), get_auto_allocs, auto_mem::next, auto_mem::pointer, and set_auto_allocs.

Referenced by ecpg_auto_alloc().

125 {
126  struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);
127 
128  if (!am)
129  return false;
130 
131  am->pointer = ptr;
132  am->next = get_auto_allocs();
133  set_auto_allocs(am);
134  return true;
135 }
void * pointer
Definition: memory.c:67
#define get_auto_allocs()
Definition: memory.c:103
#define set_auto_allocs(am)
Definition: memory.c:104
char * ecpg_alloc(long size, int lineno)
Definition: memory.c:19
struct auto_mem * next
Definition: memory.c:68

◆ ecpg_alloc()

char* ecpg_alloc ( long  ,
int   
)

Definition at line 19 of file memory.c.

References calloc, ECPG_OUT_OF_MEMORY, ecpg_raise(), and ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY.

Referenced by deallocate_one(), ecpg_add_mem(), ecpg_auto_alloc(), ecpg_build_compat_sqlda(), ecpg_build_native_sqlda(), ecpg_build_params(), ecpg_do_prologue(), ecpg_get_data(), ecpg_is_type_an_array(), ecpg_store_input(), ecpg_type_infocache_push(), ECPGallocate_desc(), ECPGconnect(), ECPGset_desc(), insert_tobeinserted(), prepare_common(), quote_postgres(), and replace_variables().

20 {
21  char *new = (char *) calloc(1L, size);
22 
23  if (!new)
24  {
26  return NULL;
27  }
28 
29  return new;
30 }
#define calloc(a, b)
Definition: header.h:55
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13

◆ ecpg_auto_alloc()

char* ecpg_auto_alloc ( long  ,
int   
)

Definition at line 108 of file memory.c.

References ecpg_add_mem(), ecpg_alloc(), and ecpg_free().

Referenced by ecpg_store_result(), and ECPGget_desc().

109 {
110  void *ptr = (void *) ecpg_alloc(size, lineno);
111 
112  if (!ptr)
113  return NULL;
114 
115  if (!ecpg_add_mem(ptr, lineno))
116  {
117  ecpg_free(ptr);
118  return NULL;
119  }
120  return ptr;
121 }
char * ecpg_alloc(long size, int lineno)
Definition: memory.c:19
void ecpg_free(void *ptr)
Definition: memory.c:13
bool ecpg_add_mem(void *ptr, int lineno)
Definition: memory.c:124

◆ ecpg_auto_prepare()

void bool ecpg_auto_prepare ( int  ,
const char *  ,
const int  ,
char **  ,
const char *   
)

Definition at line 468 of file prepare.c.

References AddStmtToCache(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_log(), ecpg_strdup(), ECPGprepare(), stmtCacheEntry::execs, nextStmtID, prepare_common(), SearchStmtCache(), stmtCacheEntry::stmtID, and STMTID_SIZE.

Referenced by ecpg_do_prologue().

469 {
470  int entNo;
471 
472  /* search the statement cache for this statement */
473  entNo = SearchStmtCache(query);
474 
475  /* if not found - add the statement to the cache */
476  if (entNo)
477  {
478  char *stmtID;
479  struct connection *con;
480  struct prepared_statement *prep;
481 
482  ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
483 
484  stmtID = stmtCacheEntries[entNo].stmtID;
485 
486  con = ecpg_get_connection(connection_name);
487  prep = ecpg_find_prepared_statement(stmtID, con, NULL);
488  /* This prepared name doesn't exist on this connection. */
489  if (!prep && !prepare_common(lineno, con, stmtID, query))
490  return false;
491 
492  *name = ecpg_strdup(stmtID, lineno);
493  }
494  else
495  {
496  char stmtID[STMTID_SIZE];
497 
498  ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);
499 
500  /* generate a statement ID */
501  sprintf(stmtID, "ecpg%d", nextStmtID++);
502 
503  if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
504  return false;
505  if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
506  return false;
507 
508  *name = ecpg_strdup(stmtID, lineno);
509  }
510 
511  /* increase usage counter */
512  stmtCacheEntries[entNo].execs++;
513 
514  return true;
515 }
static int SearchStmtCache(const char *ecpgQuery)
Definition: prepare.c:351
Definition: type.h:102
bool ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
Definition: prepare.c:161
long execs
Definition: prepare.c:21
char stmtID[STMTID_SIZE]
Definition: prepare.c:19
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
static int AddStmtToCache(int lineno, const char *stmtID, const char *connection, int compat, const char *ecpgQuery)
Definition: prepare.c:418
void ecpg_log(const char *format,...) pg_attribute_printf(1
enum COMPAT_MODE compat
Definition: ecpg.c:25
static bool prepare_common(int lineno, struct connection *con, const char *name, const char *variable)
Definition: prepare.c:103
static int nextStmtID
Definition: prepare.c:25
static stmtCacheEntry stmtCacheEntries[16384]
Definition: prepare.c:28
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
#define STMTID_SIZE
Definition: prepare.c:14

◆ ecpg_autostart_transaction()

bool ecpg_autostart_transaction ( struct statement stmt)

Definition at line 1412 of file execute.c.

References connection::autocommit, statement::compat, statement::connection, connection::connection, ecpg_check_PQresult(), ecpg_free_params(), statement::lineno, PQclear(), PQexec(), PQTRANS_IDLE, PQtransactionStatus(), and statement::results.

Referenced by ecpg_do().

1413 {
1415  {
1416  stmt->results = PQexec(stmt->connection->connection, "begin transaction");
1417  if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
1418  {
1419  ecpg_free_params(stmt, false);
1420  return false;
1421  }
1422  PQclear(stmt->results);
1423  stmt->results = NULL;
1424  }
1425  return true;
1426 }
void ecpg_free_params(struct statement *stmt, bool print)
Definition: execute.c:1052
PGresult * results
Definition: extern.h:67
bool autocommit
Definition: extern.h:84
struct connection * connection
Definition: extern.h:57
enum COMPAT_MODE compat
Definition: extern.h:58
int lineno
Definition: extern.h:54
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6071
void PQclear(PGresult *res)
Definition: fe-exec.c:671
PGconn * connection
Definition: extern.h:83
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:283
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897

◆ ecpg_build_compat_sqlda()

struct sqlda_compat* ecpg_build_compat_sqlda ( int  ,
PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 203 of file sqlda.c.

References sqlda_compat::desc_occ, ecpg_alloc(), ecpg_log(), i, PQfname(), PQfsize(), PQftype(), PQnfields(), sqlda_compat::sqld, sqlda_compat_total_size(), sqlda_dynamic_type(), sqlvar_compat::sqlname, sqlvar_compat::sqltype, sqlvar_compat::sqltypelen, sqlda_compat::sqlvar, and sqlvar_compat::sqlxid.

Referenced by ecpg_process_output(), and ECPGdescribe().

204 {
205  struct sqlda_compat *sqlda;
206  struct sqlvar_compat *sqlvar;
207  char *fname;
208  long size;
209  int sqld;
210  int i;
211 
212  size = sqlda_compat_total_size(res, row, compat);
213  sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
214  if (!sqlda)
215  return NULL;
216 
217  memset(sqlda, 0, size);
218  sqlvar = (struct sqlvar_compat *) (sqlda + 1);
219  sqld = PQnfields(res);
220  fname = (char *) (sqlvar + sqld);
221 
222  sqlda->sqld = sqld;
223  ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
224  sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
225  sqlda->sqlvar = sqlvar;
226 
227  for (i = 0; i < sqlda->sqld; i++)
228  {
229  sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
230  strcpy(fname, PQfname(res, i));
231  sqlda->sqlvar[i].sqlname = fname;
232  fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
233 
234  /*
235  * this is reserved for future use, so we leave it empty for the time
236  * being
237  */
238  /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */
239  sqlda->sqlvar[i].sqlxid = PQftype(res, i);
240  sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
241  }
242 
243  return sqlda;
244 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
int PQfsize(const PGresult *res, int field_num)
Definition: fe-exec.c:2973
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2810
short sqltypelen
Definition: sqlda-compat.h:21
char * sqlname
Definition: sqlda-compat.h:14
short desc_occ
Definition: sqlda-compat.h:42
void ecpg_log(const char *format,...) pg_attribute_printf(1
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:2962
char * ecpg_alloc(long, int)
Definition: memory.c:19
enum COMPAT_MODE compat
Definition: ecpg.c:25
int i
static long sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
Definition: sqlda.c:155
int sqlda_dynamic_type(Oid, enum COMPAT_MODE)
Definition: typename.c:106
struct sqlvar_compat * sqlvar
Definition: sqlda-compat.h:40

◆ ecpg_build_native_sqlda()

struct sqlda_struct* ecpg_build_native_sqlda ( int  ,
PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 410 of file sqlda.c.

References sqlname::data, ecpg_alloc(), ecpg_log(), i, sqlname::length, PQfname(), PQftype(), PQnfields(), sqlda_struct::sqld, sqlda_dynamic_type(), sqlda_native_total_size(), sqlda_struct::sqldabc, sqlda_struct::sqldaid, sqlda_struct::sqln, sqlvar_struct::sqlname, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.

Referenced by ecpg_process_output(), and ECPGdescribe().

411 {
412  struct sqlda_struct *sqlda;
413  long size;
414  int i;
415 
416  size = sqlda_native_total_size(res, row, compat);
417  sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
418  if (!sqlda)
419  return NULL;
420 
421  memset(sqlda, 0, size);
422 
423  sprintf(sqlda->sqldaid, "SQLDA ");
424  sqlda->sqld = sqlda->sqln = PQnfields(res);
425  ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
426  sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
427 
428  for (i = 0; i < sqlda->sqld; i++)
429  {
430  char *fname;
431 
432  sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
433  fname = PQfname(res, i);
434  sqlda->sqlvar[i].sqlname.length = strlen(fname);
435  strcpy(sqlda->sqlvar[i].sqlname.data, fname);
436  }
437 
438  return sqlda;
439 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
static long sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
Definition: sqlda.c:184
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2810
short length
Definition: sqlda-native.h:20
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
void ecpg_log(const char *format,...) pg_attribute_printf(1
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:2962
char sqldaid[8]
Definition: sqlda-native.h:35
char * ecpg_alloc(long, int)
Definition: memory.c:19
enum COMPAT_MODE compat
Definition: ecpg.c:25
char data[NAMEDATALEN]
Definition: sqlda-native.h:21
int i
int sqlda_dynamic_type(Oid, enum COMPAT_MODE)
Definition: typename.c:106
struct sqlname sqlname
Definition: sqlda-native.h:30

◆ ecpg_build_params()

bool ecpg_build_params ( struct statement )

Definition at line 1107 of file execute.c.

References variable::arrsize, statement::command, statement::compat, statement::connection, connection::connection, descriptor::count, descriptor_item::data, ecpg_alloc(), ecpg_find_desc(), ecpg_free_params(), ecpg_raise(), ecpg_realloc(), ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, ecpg_store_input(), ECPG_TOO_FEW_ARGUMENTS, ECPG_TOO_MANY_ARGUMENTS, ECPGt_char, ECPGt_char_variable, ECPGt_descriptor, ECPGt_int, ECPGt_NO_INDICATOR, ECPGt_short, ECPGt_sqlda, ECPGt_varchar, statement::force_indicator, i, variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, descriptor_item::indicator, INFORMIX_MODE, statement::inlist, insert_tobeinserted(), descriptor::items, statement::lineno, descriptor_item::next, variable::next, next_insert(), statement::nparams, descriptor_item::num, variable::offset, statement::paramvalues, variable::pointer, PQparameterStatus(), statement::questionmarks, snprintf(), sqlda_compat::sqld, sqlvar_compat::sqldata, sqlvar_struct::sqldata, sqlvar_compat::sqlind, sqlvar_struct::sqlind, sqlda_struct::sqln, sqlvar_compat::sqltype, sqlvar_struct::sqltype, sqlda_struct::sqlvar, sqlda_compat::sqlvar, variable::type, variable::value, value, and variable::varcharsize.

Referenced by ecpg_do().

1108 {
1109  struct variable *var;
1110  int desc_counter = 0;
1111  int position = 0;
1112  const char *value;
1113  bool std_strings = false;
1114 
1115  /* Get standard_conforming_strings setting. */
1116  value = PQparameterStatus(stmt->connection->connection, "standard_conforming_strings");
1117  if (value && strcmp(value, "on") == 0)
1118  std_strings = true;
1119 
1120  /*
1121  * If the type is one of the fill in types then we take the argument and
1122  * enter it to our parameter array at the first position. Then if there
1123  * are any more fill in types we add more parameters.
1124  */
1125  var = stmt->inlist;
1126  while (var)
1127  {
1128  char *tobeinserted;
1129  int counter = 1;
1130 
1131  tobeinserted = NULL;
1132 
1133  /*
1134  * A descriptor is a special case since it contains many variables but
1135  * is listed only once.
1136  */
1137  if (var->type == ECPGt_descriptor)
1138  {
1139  /*
1140  * We create an additional variable list here, so the same logic
1141  * applies.
1142  */
1143  struct variable desc_inlist;
1144  struct descriptor *desc;
1145  struct descriptor_item *desc_item;
1146 
1147  desc = ecpg_find_desc(stmt->lineno, var->pointer);
1148  if (desc == NULL)
1149  return false;
1150 
1151  desc_counter++;
1152  for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
1153  {
1154  if (desc_item->num == desc_counter)
1155  {
1156  desc_inlist.type = ECPGt_char;
1157  desc_inlist.value = desc_item->data;
1158  desc_inlist.pointer = &(desc_item->data);
1159  desc_inlist.varcharsize = strlen(desc_item->data);
1160  desc_inlist.arrsize = 1;
1161  desc_inlist.offset = 0;
1162  if (!desc_item->indicator)
1163  {
1164  desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1165  desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1166  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1167  }
1168  else
1169  {
1170  desc_inlist.ind_type = ECPGt_int;
1171  desc_inlist.ind_value = &(desc_item->indicator);
1172  desc_inlist.ind_pointer = &(desc_inlist.ind_value);
1173  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
1174  desc_inlist.ind_offset = 0;
1175  }
1176  if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
1177  return false;
1178 
1179  break;
1180  }
1181  }
1182  if (desc->count == desc_counter)
1183  desc_counter = 0;
1184  }
1185  else if (var->type == ECPGt_sqlda)
1186  {
1187  if (INFORMIX_MODE(stmt->compat))
1188  {
1189  struct sqlda_compat *sqlda = *(struct sqlda_compat **) var->pointer;
1190  struct variable desc_inlist;
1191  int i;
1192 
1193  if (sqlda == NULL)
1194  return false;
1195 
1196  desc_counter++;
1197  for (i = 0; i < sqlda->sqld; i++)
1198  {
1199  if (i + 1 == desc_counter)
1200  {
1201  desc_inlist.type = sqlda->sqlvar[i].sqltype;
1202  desc_inlist.value = sqlda->sqlvar[i].sqldata;
1203  desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
1204  switch (desc_inlist.type)
1205  {
1206  case ECPGt_char:
1207  case ECPGt_varchar:
1208  desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
1209  break;
1210  default:
1211  desc_inlist.varcharsize = 0;
1212  break;
1213  }
1214  desc_inlist.arrsize = 1;
1215  desc_inlist.offset = 0;
1216  if (sqlda->sqlvar[i].sqlind)
1217  {
1218  desc_inlist.ind_type = ECPGt_short;
1219  /* ECPG expects indicator value < 0 */
1220  if (*(sqlda->sqlvar[i].sqlind))
1221  *(sqlda->sqlvar[i].sqlind) = -1;
1222  desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
1223  desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
1224  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
1225  desc_inlist.ind_offset = 0;
1226  }
1227  else
1228  {
1229  desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1230  desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1231  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1232  }
1233  if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
1234  return false;
1235 
1236  break;
1237  }
1238  }
1239  if (sqlda->sqld == desc_counter)
1240  desc_counter = 0;
1241  }
1242  else
1243  {
1244  struct sqlda_struct *sqlda = *(struct sqlda_struct **) var->pointer;
1245  struct variable desc_inlist;
1246  int i;
1247 
1248  if (sqlda == NULL)
1249  return false;
1250 
1251  desc_counter++;
1252  for (i = 0; i < sqlda->sqln; i++)
1253  {
1254  if (i + 1 == desc_counter)
1255  {
1256  desc_inlist.type = sqlda->sqlvar[i].sqltype;
1257  desc_inlist.value = sqlda->sqlvar[i].sqldata;
1258  desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
1259  switch (desc_inlist.type)
1260  {
1261  case ECPGt_char:
1262  case ECPGt_varchar:
1263  desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
1264  break;
1265  default:
1266  desc_inlist.varcharsize = 0;
1267  break;
1268  }
1269  desc_inlist.arrsize = 1;
1270  desc_inlist.offset = 0;
1271  if (sqlda->sqlvar[i].sqlind)
1272  {
1273  desc_inlist.ind_type = ECPGt_short;
1274  /* ECPG expects indicator value < 0 */
1275  if (*(sqlda->sqlvar[i].sqlind))
1276  *(sqlda->sqlvar[i].sqlind) = -1;
1277  desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
1278  desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
1279  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
1280  desc_inlist.ind_offset = 0;
1281  }
1282  else
1283  {
1284  desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1285  desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1286  desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1287  }
1288  if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
1289  return false;
1290 
1291  break;
1292  }
1293  }
1294  if (sqlda->sqln == desc_counter)
1295  desc_counter = 0;
1296  }
1297 
1298  }
1299  else
1300  {
1301  if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
1302  return false;
1303  }
1304 
1305  /*
1306  * now tobeinserted points to an area that contains the next
1307  * parameter; now find the position in the string where it belongs
1308  */
1309  if ((position = next_insert(stmt->command, position, stmt->questionmarks, std_strings) + 1) == 0)
1310  {
1311  /*
1312  * We have an argument but we dont have the matched up placeholder
1313  * in the string
1314  */
1315  ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS,
1317  NULL);
1318  ecpg_free_params(stmt, false);
1319  return false;
1320  }
1321 
1322  /*
1323  * if var->type=ECPGt_char_variable we have a dynamic cursor we have
1324  * to simulate a dynamic cursor because there is no backend
1325  * functionality for it
1326  */
1327  if (var->type == ECPGt_char_variable)
1328  {
1329  int ph_len = (stmt->command[position] == '?') ? strlen("?") : strlen("$1");
1330 
1331  if (!insert_tobeinserted(position, ph_len, stmt, tobeinserted))
1332  {
1333  ecpg_free_params(stmt, false);
1334  return false;
1335  }
1336  tobeinserted = NULL;
1337  }
1338 
1339  /*
1340  * if the placeholder is '$0' we have to replace it on the client side
1341  * this is for places we want to support variables at that are not
1342  * supported in the backend
1343  */
1344  else if (stmt->command[position] == '0')
1345  {
1346  if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
1347  {
1348  ecpg_free_params(stmt, false);
1349  return false;
1350  }
1351  tobeinserted = NULL;
1352  }
1353  else
1354  {
1355  char **paramvalues;
1356 
1357  if (!(paramvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno)))
1358  {
1359  ecpg_free_params(stmt, false);
1360  return false;
1361  }
1362 
1363  stmt->nparams++;
1364  stmt->paramvalues = paramvalues;
1365  stmt->paramvalues[stmt->nparams - 1] = tobeinserted;
1366 
1367  /* let's see if this was an old style placeholder */
1368  if (stmt->command[position] == '?')
1369  {
1370  /* yes, replace with new style */
1371  int buffersize = sizeof(int) * CHAR_BIT * 10 / 3; /* a rough guess of the
1372  * size we need */
1373 
1374  if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))
1375  {
1376  ecpg_free_params(stmt, false);
1377  return false;
1378  }
1379 
1380  snprintf(tobeinserted, buffersize, "$%d", counter++);
1381 
1382  if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
1383  {
1384  ecpg_free_params(stmt, false);
1385  return false;
1386  }
1387  tobeinserted = NULL;
1388  }
1389  }
1390 
1391  if (desc_counter == 0)
1392  var = var->next;
1393  }
1394 
1395  /* Check if there are unmatched things left. */
1396  if (next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)
1397  {
1398  ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
1400  ecpg_free_params(stmt, false);
1401  return false;
1402  }
1403 
1404  return true;
1405 }
static bool insert_tobeinserted(int position, int ph_len, struct statement *stmt, char *tobeinserted)
Definition: execute.c:1068
void ecpg_free_params(struct statement *stmt, bool print)
Definition: execute.c:1052
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6081
#define INFORMIX_MODE(X)
Definition: extern.h:23
char * data
Definition: extern.h:103
void * pointer
Definition: extern.h:116
enum ECPGttype type
Definition: extern.h:114
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
#define ECPG_TOO_MANY_ARGUMENTS
Definition: ecpgerrno.h:19
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
char * sqldata
Definition: sqlda-native.h:28
struct variable * next
Definition: extern.h:126
char * sqldata
Definition: sqlda-compat.h:12
static int next_insert(char *text, int pos, bool questionmarks, bool std_strings)
Definition: execute.c:111
struct descriptor * ecpg_find_desc(int line, const char *name)
Definition: descriptor.c:800
char * ecpg_alloc(long, int)
Definition: memory.c:19
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
int count
Definition: extern.h:96
static struct @131 value
#define ECPG_TOO_FEW_ARGUMENTS
Definition: ecpgerrno.h:20
struct descriptor_item * items
Definition: extern.h:97
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS
Definition: extern.h:202
short * sqlind
Definition: sqlda-native.h:29
struct descriptor_item * next
Definition: extern.h:109
int i
bool ecpg_store_input(const int lineno, const bool force_indicator, const struct variable *var, char **tobeinserted_p, bool quote)
Definition: execute.c:494
short * sqlind
Definition: sqlda-compat.h:13
struct sqlvar_compat * sqlvar
Definition: sqlda-compat.h:40
char * ecpg_realloc(void *, long, int)
Definition: memory.c:33

◆ ecpg_check_PQresult()

bool ecpg_check_PQresult ( PGresult ,
int  ,
PGconn ,
enum  COMPAT_MODE 
)

Definition at line 283 of file error.c.

References ECPG_EMPTY, ecpg_log(), ecpg_raise(), ecpg_raise_backend(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, PGRES_BAD_RESPONSE, PGRES_COMMAND_OK, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, PGRES_TUPLES_OK, PQclear(), PQendcopy(), PQerrorMessage(), PQresultErrorMessage(), and PQresultStatus().

Referenced by deallocate_one(), ecpg_autostart_transaction(), ecpg_execute(), ecpg_is_type_an_array(), ECPGdescribe(), ECPGsetcommit(), ECPGtrans(), and prepare_common().

284 {
285  if (results == NULL)
286  {
287  ecpg_log("ecpg_check_PQresult on line %d: no result - %s", lineno, PQerrorMessage(connection));
288  ecpg_raise_backend(lineno, NULL, connection, compat);
289  return false;
290  }
291 
292  switch (PQresultStatus(results))
293  {
294 
295  case PGRES_TUPLES_OK:
296  return true;
297  break;
298  case PGRES_EMPTY_QUERY:
299  /* do nothing */
301  PQclear(results);
302  return false;
303  break;
304  case PGRES_COMMAND_OK:
305  return true;
306  break;
308  case PGRES_FATAL_ERROR:
309  case PGRES_BAD_RESPONSE:
310  ecpg_log("ecpg_check_PQresult on line %d: bad response - %s", lineno, PQresultErrorMessage(results));
311  ecpg_raise_backend(lineno, results, connection, compat);
312  PQclear(results);
313  return false;
314  break;
315  case PGRES_COPY_OUT:
316  return true;
317  break;
318  case PGRES_COPY_IN:
319  ecpg_log("ecpg_check_PQresult on line %d: COPY IN data transfer in progress\n", lineno);
321  PQclear(results);
322  return false;
323  break;
324  default:
325  ecpg_log("ecpg_check_PQresult on line %d: unknown execution status type\n",
326  lineno);
327  ecpg_raise_backend(lineno, results, connection, compat);
328  PQclear(results);
329  return false;
330  break;
331  }
332 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6116
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
#define ECPG_EMPTY
Definition: ecpgerrno.h:30
void ecpg_log(const char *format,...) pg_attribute_printf(1
void ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)
Definition: error.c:219
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
enum COMPAT_MODE compat
Definition: ecpg.c:25
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int PQendcopy(PGconn *conn)
Definition: fe-exec.c:2573
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:2663

◆ ecpg_clear_auto_mem()

void ecpg_clear_auto_mem ( void  )

Definition at line 158 of file memory.c.

References ecpg_free(), get_auto_allocs, auto_mem::next, and set_auto_allocs.

Referenced by ecpg_do_prologue(), and ECPGconnect().

159 {
160  struct auto_mem *am = get_auto_allocs();
161 
162  /* only free our own structure */
163  if (am)
164  {
165  do
166  {
167  struct auto_mem *act = am;
168 
169  am = am->next;
170  ecpg_free(act);
171  } while (am);
172  set_auto_allocs(NULL);
173  }
174 }
#define get_auto_allocs()
Definition: memory.c:103
#define set_auto_allocs(am)
Definition: memory.c:104
void ecpg_free(void *ptr)
Definition: memory.c:13
struct auto_mem * next
Definition: memory.c:68

◆ ecpg_deallocate_all_conn()

bool ecpg_deallocate_all_conn ( int  lineno,
enum COMPAT_MODE  c,
struct connection conn 
)

Definition at line 276 of file prepare.c.

References deallocate_one(), and connection::prep_stmts.

Referenced by ecpg_finish(), and ECPGdeallocate_all().

277 {
278  /* deallocate all prepared statements */
279  while (con->prep_stmts)
280  {
281  if (!deallocate_one(lineno, c, con, NULL, con->prep_stmts))
282  return false;
283  }
284 
285  return true;
286 }
static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
Definition: prepare.c:201
char * c

◆ ecpg_do()

bool ecpg_do ( const int  ,
const int  ,
const int  ,
const char *  ,
const bool  ,
const int  ,
const char *  ,
va_list   
)

Definition at line 2003 of file execute.c.

References ecpg_autostart_transaction(), ecpg_build_params(), ecpg_do_epilogue(), ecpg_do_prologue(), ecpg_execute(), and ecpg_process_output().

Referenced by ECPGdo().

2004 {
2005  struct statement *stmt = NULL;
2006 
2007  if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name,
2009  query, args, &stmt))
2010  goto fail;
2011 
2012  if (!ecpg_build_params(stmt))
2013  goto fail;
2014 
2015  if (!ecpg_autostart_transaction(stmt))
2016  goto fail;
2017 
2018  if (!ecpg_execute(stmt))
2019  goto fail;
2020 
2021  if (!ecpg_process_output(stmt, true))
2022  goto fail;
2023 
2024  ecpg_do_epilogue(stmt);
2025  return true;
2026 
2027 fail:
2028  ecpg_do_epilogue(stmt);
2029  return false;
2030 }
bool ecpg_process_output(struct statement *stmt, bool clear_result)
Definition: execute.c:1481
bool ecpg_autostart_transaction(struct statement *stmt)
Definition: execute.c:1412
ECPG_statement_type
Definition: ecpgtype.h:94
bool ecpg_build_params(struct statement *stmt)
Definition: execute.c:1107
bool ecpg_execute(struct statement *stmt)
Definition: execute.c:1433
int lineno
Definition: extern.h:54
bool questionmarks
Definition: ecpg.c:19
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool ecpg_do_prologue(int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, enum ECPG_statement_type statement_type, const char *query, va_list args, struct statement **stmt_out)
Definition: execute.c:1754
void ecpg_do_epilogue(struct statement *stmt)
Definition: execute.c:1986
bool force_indicator
Definition: ecpg.c:18

◆ ecpg_do_epilogue()

void ecpg_do_epilogue ( struct statement )

Definition at line 1986 of file execute.c.

References free_statement(), statement::oldlocale, and setlocale.

Referenced by ecpg_do(), and ecpg_do_prologue().

1987 {
1988  if (stmt == NULL)
1989  return;
1990 
1991  if (stmt->oldlocale)
1992  setlocale(LC_NUMERIC, stmt->oldlocale);
1993 
1994  free_statement(stmt);
1995 }
#define setlocale(a, b)
Definition: win32_port.h:419
static void free_statement(struct statement *stmt)
Definition: execute.c:98

◆ ecpg_do_prologue()

bool ecpg_do_prologue ( int  ,
const int  ,
const int  ,
const char *  ,
const bool  ,
enum  ECPG_statement_type,
const char *  ,
va_list  ,
struct statement **   
)

Definition at line 1754 of file execute.c.

References variable::arrsize, statement::command, compat, statement::compat, statement::connection, connection::connection, ecpg_alloc(), ecpg_auto_prepare(), ecpg_clear_auto_mem(), ecpg_do_epilogue(), ECPG_EMPTY, ecpg_free(), ecpg_get_connection(), ecpg_gettext, ecpg_init(), ECPG_INVALID_STMT, ECPG_NOT_CONN, ecpg_prepared(), ecpg_raise(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, ecpg_strdup(), ECPGst_execute, ECPGst_prepnormal, ECPGt_char, ECPGt_EOIT, ECPGt_EORT, ECPGt_NO_INDICATOR, ECPGt_unsigned_char, force_indicator, statement::force_indicator, variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, statement::inlist, statement::lineno, sort-test::list, statement::name, connection::name, variable::next, variable::offset, statement::oldlocale, statement::outlist, variable::pointer, questionmarks, statement::questionmarks, setlocale, statement::statement_type, variable::type, generate_unaccent_rules::type, variable::value, and variable::varcharsize.

Referenced by ecpg_do().

1758 {
1759  struct statement *stmt;
1760  struct connection *con;
1761  enum ECPGttype type;
1762  struct variable **list;
1763  char *prepname;
1764 
1765  *stmt_out = NULL;
1766 
1767  if (!query)
1768  {
1770  return false;
1771  }
1772 
1773  stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
1774 
1775  if (stmt == NULL)
1776  return false;
1777 
1778  /*
1779  * Make sure we do NOT honor the locale for numeric input/output since the
1780  * database wants the standard decimal point
1781  */
1782  stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
1783  if (stmt->oldlocale == NULL)
1784  {
1785  ecpg_do_epilogue(stmt);
1786  return false;
1787  }
1788  setlocale(LC_NUMERIC, "C");
1789 
1790 #ifdef ENABLE_THREAD_SAFETY
1791  ecpg_pthreads_init();
1792 #endif
1793 
1794  con = ecpg_get_connection(connection_name);
1795 
1796  if (!ecpg_init(con, connection_name, lineno))
1797  {
1798  ecpg_do_epilogue(stmt);
1799  return false;
1800  }
1801 
1802  /*
1803  * If statement type is ECPGst_prepnormal we are supposed to prepare the
1804  * statement before executing them
1805  */
1807  {
1808  if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
1809  {
1810  ecpg_do_epilogue(stmt);
1811  return false;
1812  }
1813 
1814  /*
1815  * statement is now prepared, so instead of the query we have to
1816  * execute the name
1817  */
1818  stmt->command = prepname;
1820  }
1821  else
1822  stmt->command = ecpg_strdup(query, lineno);
1823 
1824  stmt->name = NULL;
1825 
1827  {
1828  /* if we have an EXECUTE command, only the name is send */
1829  char *command = ecpg_prepared(stmt->command, con);
1830 
1831  if (command)
1832  {
1833  stmt->name = stmt->command;
1834  stmt->command = ecpg_strdup(command, lineno);
1835  }
1836  else
1837  {
1839  ecpg_do_epilogue(stmt);
1840  return false;
1841  }
1842  }
1843 
1844  stmt->connection = con;
1845  stmt->lineno = lineno;
1846  stmt->compat = compat;
1848  stmt->questionmarks = questionmarks;
1850 
1851  /*------
1852  * create a list of variables
1853  *
1854  * The variables are listed with input variables preceding outputvariables
1855  * The end of each group is marked by an end marker. per variable we list:
1856  *
1857  * type - as defined in ecpgtype.h
1858  * value - where to store the data
1859  * varcharsize - length of string in case we have a stringvariable, else 0
1860  * arraysize - 0 for pointer (we don't know the size of the array), 1 for
1861  * simple variable, size for arrays
1862  * offset - offset between ith and (i+1)th entry in an array, normally
1863  * that means sizeof(type)
1864  * ind_type - type of indicator variable
1865  * ind_value - pointer to indicator variable
1866  * ind_varcharsize - empty
1867  * ind_arraysize - arraysize of indicator array
1868  * ind_offset - indicator offset
1869  *------
1870  */
1871 
1872  list = &(stmt->inlist);
1873 
1874  type = va_arg(args, enum ECPGttype);
1875 
1876  while (type != ECPGt_EORT)
1877  {
1878  if (type == ECPGt_EOIT)
1879  list = &(stmt->outlist);
1880  else
1881  {
1882  struct variable *var,
1883  *ptr;
1884 
1885  if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
1886  {
1887  ecpg_do_epilogue(stmt);
1888  return false;
1889  }
1890 
1891  var->type = type;
1892  var->pointer = va_arg(args, char *);
1893 
1894  var->varcharsize = va_arg(args, long);
1895  var->arrsize = va_arg(args, long);
1896  var->offset = va_arg(args, long);
1897 
1898  /*
1899  * Unknown array size means pointer to an array. Unknown
1900  * varcharsize usually also means pointer. But if the type is
1901  * character and the array size is known, it is an array of
1902  * pointers to char, so use var->pointer as it is.
1903  */
1904  if (var->arrsize == 0 ||
1905  (var->varcharsize == 0 && ((var->type != ECPGt_char && var->type != ECPGt_unsigned_char) || (var->arrsize <= 1))))
1906  var->value = *((char **) (var->pointer));
1907  else
1908  var->value = var->pointer;
1909 
1910  /*
1911  * negative values are used to indicate an array without given
1912  * bounds
1913  */
1914  /* reset to zero for us */
1915  if (var->arrsize < 0)
1916  var->arrsize = 0;
1917  if (var->varcharsize < 0)
1918  var->varcharsize = 0;
1919 
1920  var->next = NULL;
1921 
1922  var->ind_type = va_arg(args, enum ECPGttype);
1923  var->ind_pointer = va_arg(args, char *);
1924  var->ind_varcharsize = va_arg(args, long);
1925  var->ind_arrsize = va_arg(args, long);
1926  var->ind_offset = va_arg(args, long);
1927 
1928  if (var->ind_type != ECPGt_NO_INDICATOR
1929  && (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
1930  var->ind_value = *((char **) (var->ind_pointer));
1931  else
1932  var->ind_value = var->ind_pointer;
1933 
1934  /*
1935  * negative values are used to indicate an array without given
1936  * bounds
1937  */
1938  /* reset to zero for us */
1939  if (var->ind_arrsize < 0)
1940  var->ind_arrsize = 0;
1941  if (var->ind_varcharsize < 0)
1942  var->ind_varcharsize = 0;
1943 
1944  /* if variable is NULL, the statement hasn't been prepared */
1945  if (var->pointer == NULL)
1946  {
1948  ecpg_free(var);
1949  ecpg_do_epilogue(stmt);
1950  return false;
1951  }
1952 
1953  for (ptr = *list; ptr && ptr->next; ptr = ptr->next)
1954  ;
1955 
1956  if (ptr == NULL)
1957  *list = var;
1958  else
1959  ptr->next = var;
1960  }
1961 
1962  type = va_arg(args, enum ECPGttype);
1963  }
1964 
1965  /* are we connected? */
1966  if (con == NULL || con->connection == NULL)
1967  {
1968  ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
1969  ecpg_do_epilogue(stmt);
1970  return false;
1971  }
1972 
1973  /* initialize auto_mem struct */
1975 
1976  *stmt_out = stmt;
1977 
1978  return true;
1979 }
long ind_arrsize
Definition: extern.h:124
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:105
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
#define ECPG_NOT_CONN
Definition: ecpgerrno.h:37
void ecpg_free(void *)
Definition: memory.c:13
#define setlocale(a, b)
Definition: win32_port.h:419
#define ECPG_INVALID_STMT
Definition: ecpgerrno.h:39
char * name
Definition: extern.h:82
enum ECPG_statement_type statement_type
Definition: extern.h:60
void * pointer
Definition: extern.h:116
enum ECPGttype type
Definition: extern.h:114
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
struct variable * next
Definition: extern.h:126
#define ECPG_EMPTY
Definition: ecpgerrno.h:30
char * oldlocale
Definition: extern.h:64
struct connection * connection
Definition: extern.h:57
enum COMPAT_MODE compat
Definition: extern.h:58
int lineno
Definition: extern.h:54
void * value
Definition: extern.h:115
char * ecpg_alloc(long, int)
Definition: memory.c:19
void bool ecpg_auto_prepare(int, const char *, const int, char **, const char *)
Definition: prepare.c:468
void ecpg_clear_auto_mem(void)
Definition: memory.c:158
bool questionmarks
Definition: ecpg.c:19
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
enum COMPAT_MODE compat
Definition: ecpg.c:25
char * ecpg_prepared(const char *, struct connection *)
Definition: prepare.c:295
#define ecpg_gettext(x)
Definition: ecpglib.h:18
void * ind_pointer
Definition: extern.h:122
long offset
Definition: extern.h:119
char * command
Definition: extern.h:55
struct variable * inlist
Definition: extern.h:62
PGconn * connection
Definition: extern.h:83
long ind_varcharsize
Definition: extern.h:123
bool force_indicator
Definition: extern.h:59
enum ECPGttype ind_type
Definition: extern.h:120
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
Definition: extern.h:213
char * name
Definition: extern.h:56
void ecpg_do_epilogue(struct statement *stmt)
Definition: execute.c:1986
long ind_offset
Definition: extern.h:125
bool questionmarks
Definition: extern.h:61
long arrsize
Definition: extern.h:118
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
bool force_indicator
Definition: ecpg.c:18
void * ind_value
Definition: extern.h:121
long varcharsize
Definition: extern.h:117
struct variable * outlist
Definition: extern.h:63
ECPGttype
Definition: ecpgtype.h:41

◆ ecpg_dynamic_type()

int ecpg_dynamic_type ( Oid  )

Definition at line 72 of file typename.c.

References SQL3_BOOLEAN, SQL3_CHARACTER, SQL3_CHARACTER_VARYING, SQL3_DATE_TIME_TIMESTAMP, SQL3_DOUBLE_PRECISION, SQL3_INTEGER, SQL3_NUMERIC, SQL3_REAL, and SQL3_SMALLINT.

Referenced by ecpg_is_type_an_array(), and ECPGget_desc().

73 {
74  switch (type)
75  {
76  case BOOLOID:
77  return SQL3_BOOLEAN; /* bool */
78  case INT2OID:
79  return SQL3_SMALLINT; /* int2 */
80  case INT4OID:
81  return SQL3_INTEGER; /* int4 */
82  case TEXTOID:
83  return SQL3_CHARACTER; /* text */
84  case FLOAT4OID:
85  return SQL3_REAL; /* float4 */
86  case FLOAT8OID:
87  return SQL3_DOUBLE_PRECISION; /* float8 */
88  case BPCHAROID:
89  return SQL3_CHARACTER; /* bpchar */
90  case VARCHAROID:
91  return SQL3_CHARACTER_VARYING; /* varchar */
92  case DATEOID:
93  return SQL3_DATE_TIME_TIMESTAMP; /* date */
94  case TIMEOID:
95  return SQL3_DATE_TIME_TIMESTAMP; /* time */
96  case TIMESTAMPOID:
97  return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
98  case NUMERICOID:
99  return SQL3_NUMERIC; /* numeric */
100  default:
101  return 0;
102  }
103 }

◆ ecpg_execute()

bool ecpg_execute ( struct statement stmt)

Definition at line 1433 of file execute.c.

References statement::command, statement::compat, statement::connection, connection::connection, ecpg_check_PQresult(), ecpg_free_params(), ecpg_log(), ECPGst_execute, statement::lineno, statement::name, connection::name, statement::nparams, statement::paramvalues, PQexec(), PQexecParams(), PQexecPrepared(), statement::results, and statement::statement_type.

Referenced by ecpg_do().

1434 {
1435  ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
1436  if (stmt->statement_type == ECPGst_execute)
1437  {
1438  stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
1439  ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
1440  }
1441  else
1442  {
1443  if (stmt->nparams == 0)
1444  {
1445  stmt->results = PQexec(stmt->connection->connection, stmt->command);
1446  ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
1447  }
1448  else
1449  {
1450  stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0);
1451  ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
1452  }
1453  }
1454 
1455  ecpg_free_params(stmt, true);
1456 
1457  if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
1458  return false;
1459 
1460  return true;
1461 }
PGresult * PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
Definition: fe-exec.c:1958
void ecpg_free_params(struct statement *stmt, bool print)
Definition: execute.c:1052
char * name
Definition: extern.h:82
enum ECPG_statement_type statement_type
Definition: extern.h:60
PGresult * results
Definition: extern.h:67
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct connection * connection
Definition: extern.h:57
enum COMPAT_MODE compat
Definition: extern.h:58
int lineno
Definition: extern.h:54
char * command
Definition: extern.h:55
PGconn * connection
Definition: extern.h:83
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:283
char * name
Definition: extern.h:56
char ** paramvalues
Definition: extern.h:66
PGresult * PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
Definition: fe-exec.c:1911
int nparams
Definition: extern.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897

◆ ecpg_find_desc()

struct descriptor* ecpg_find_desc ( int  line,
const char *  name 
)

Definition at line 800 of file descriptor.c.

References ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, ECPG_UNKNOWN_DESCRIPTOR, get_descriptors, descriptor::name, and descriptor::next.

Referenced by ecpg_build_params(), ecpg_process_output(), ecpg_result_by_descriptor(), ECPGdescribe(), ECPGset_desc(), and ECPGset_desc_header().

801 {
802  struct descriptor *desc;
803 
804  for (desc = get_descriptors(); desc; desc = desc->next)
805  {
806  if (strcmp(name, desc->name) == 0)
807  return desc;
808  }
809 
811  return NULL; /* not found */
812 }
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME
Definition: extern.h:214
struct descriptor * next
Definition: extern.h:95
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define ECPG_UNKNOWN_DESCRIPTOR
Definition: ecpgerrno.h:42
const char * name
Definition: encode.c:521
char * name
Definition: extern.h:93
#define get_descriptors()
Definition: descriptor.c:56

◆ ecpg_find_prepared_statement()

struct prepared_statement* ecpg_find_prepared_statement ( const char *  ,
struct connection ,
struct prepared_statement **   
)

Definition at line 182 of file prepare.c.

References prepared_statement::next, and connection::prep_stmts.

Referenced by ecpg_auto_prepare(), ecpg_freeStmtCacheEntry(), ecpg_prepared(), ECPGdeallocate(), ECPGdescribe(), and ECPGprepare().

184 {
185  struct prepared_statement *this,
186  *prev;
187 
188  for (this = con->prep_stmts, prev = NULL; this != NULL; prev = this, this = this->next)
189  {
190  if (strcmp(this->name, name) == 0)
191  {
192  if (prev_)
193  *prev_ = prev;
194  return this;
195  }
196  }
197  return NULL;
198 }
struct prepared_statement * next
Definition: extern.h:76
const char * name
Definition: encode.c:521

◆ ecpg_free()

◆ ecpg_free_auto_mem()

void ecpg_free_auto_mem ( void  )

◆ ecpg_free_params()

void ecpg_free_params ( struct statement stmt,
bool  print 
)

Definition at line 1052 of file execute.c.

References ecpg_free(), ecpg_log(), statement::lineno, statement::nparams, and statement::paramvalues.

Referenced by ecpg_autostart_transaction(), ecpg_build_params(), and ecpg_execute().

1053 {
1054  int n;
1055 
1056  for (n = 0; n < stmt->nparams; n++)
1057  {
1058  if (print)
1059  ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", stmt->lineno, n + 1, stmt->paramvalues[n] ? stmt->paramvalues[n] : "null");
1060  ecpg_free(stmt->paramvalues[n]);
1061  }
1062  ecpg_free(stmt->paramvalues);
1063  stmt->paramvalues = NULL;
1064  stmt->nparams = 0;
1065 }
void print(const void *obj)
Definition: print.c:35
void ecpg_free(void *)
Definition: memory.c:13
void ecpg_log(const char *format,...) pg_attribute_printf(1
int lineno
Definition: extern.h:54
char ** paramvalues
Definition: extern.h:66
int nparams
Definition: extern.h:65

◆ ecpg_get_connection()

struct connection* ecpg_get_connection ( const char *  )

Definition at line 74 of file connect.c.

References actual_connection, ecpg_get_connection_nr(), pthread_getspecific(), pthread_mutex_lock(), and pthread_mutex_unlock().

Referenced by ecpg_auto_prepare(), ecpg_do_prologue(), ecpg_freeStmtCacheEntry(), ECPGconnect(), ECPGdeallocate(), ECPGdeallocate_all(), ECPGdescribe(), ECPGget_desc(), ECPGget_PGconn(), ECPGprepare(), ECPGprepared_statement(), ECPGsetcommit(), ECPGsetconn(), ECPGstatus(), ECPGtrans(), and ECPGtransactionStatus().

75 {
76  struct connection *ret = NULL;
77 
78  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
79  {
80 #ifdef ENABLE_THREAD_SAFETY
81  ret = pthread_getspecific(actual_connection_key);
82 
83  /*
84  * if no connection in TSD for this thread, get the global default
85  * connection and hope the user knows what they're doing (i.e. using
86  * their own mutex to protect that connection from concurrent accesses
87  */
88  /* if !ret then we got the connection from TSD */
89  if (NULL == ret)
90  /* no TSD connection here either, using global */
91  ret = actual_connection;
92 #else
93  ret = actual_connection;
94 #endif
95  }
96  else
97  {
98 #ifdef ENABLE_THREAD_SAFETY
99  pthread_mutex_lock(&connections_mutex);
100 #endif
101 
102  ret = ecpg_get_connection_nr(connection_name);
103 
104 #ifdef ENABLE_THREAD_SAFETY
105  pthread_mutex_unlock(&connections_mutex);
106 #endif
107  }
108 
109  return ret;
110 }
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
static struct connection * actual_connection
Definition: connect.c:18

◆ ecpg_get_data()

bool ecpg_get_data ( const PGresult ,
int  ,
int  ,
int  ,
enum ECPGttype  type,
enum  ECPGttype,
char *  ,
char *  ,
long  ,
long  ,
long  ,
enum  ARRAY_TYPE,
enum  COMPAT_MODE,
bool   
)

Definition at line 127 of file data.c.

References ECPGgeneric_varchar::arr, array_boundary(), array_delimiter(), check_special_value(), ecpg_alloc(), ECPG_ARRAY_ARRAY, ECPG_COMPAT_PGSQL, ECPG_CONVERT_BOOL, ECPG_DATA_NOT_ARRAY, ECPG_DATE_FORMAT, ECPG_FLOAT_FORMAT, ECPG_INT_FORMAT, ecpg_internal_regression_mode, ECPG_INTERVAL_FORMAT, ECPG_IS_ARRAY, ecpg_log(), ECPG_MISSING_INDICATOR, ECPG_NOT_FOUND, ECPG_NUMERIC_FORMAT, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_NO_DATA, ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER, ECPG_TIMESTAMP_FORMAT, ecpg_type_name(), ECPG_UINT_FORMAT, ECPG_UNSUPPORTED, ECPGget_sqlca(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGt_varchar, false, free, garbage_left(), INFORMIX_MODE, ECPGgeneric_varchar::len, ORACLE_MODE, PGTYPESdate_from_asc(), PGTYPESinterval_copy(), PGTYPESinterval_from_asc(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PGTYPESnumeric_new(), PGTYPESnumeric_to_decimal(), PGTYPEStimestamp_from_asc(), PQfformat(), PQgetisnull(), PQgetlength(), PQgetvalue(), sqlca, sqlca_t::sqlwarn, and generate_unaccent_rules::str.

Referenced by ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), and ecpg_store_result().

131 {
132  struct sqlca_t *sqlca = ECPGget_sqlca();
133  char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
134  int binary = PQfformat(results, act_field);
135  int size = PQgetlength(results, act_tuple, act_field);
136  int value_for_indicator = 0;
137  long log_offset;
138 
139  if (sqlca == NULL)
140  {
143  return false;
144  }
145 
146  /*
147  * If we are running in a regression test, do not log the offset variable,
148  * it depends on the machine's alignment.
149  */
151  log_offset = -1;
152  else
153  log_offset = offset;
154 
155  ecpg_log("ecpg_get_data on line %d: RESULT: %s offset: %ld; array: %s\n", lineno, pval ? (binary ? "BINARY" : pval) : "EMPTY", log_offset, ECPG_IS_ARRAY(isarray) ? "yes" : "no");
156 
157  /* pval is a pointer to the value */
158  if (!pval)
159  {
160  /*
161  * This should never happen because we already checked that we found
162  * at least one tuple, but let's play it safe.
163  */
165  return false;
166  }
167 
168  /* We will have to decode the value */
169 
170  /*
171  * check for null value and set indicator accordingly, i.e. -1 if NULL and
172  * 0 if not
173  */
174  if (PQgetisnull(results, act_tuple, act_field))
175  value_for_indicator = -1;
176 
177  switch (ind_type)
178  {
179  case ECPGt_short:
181  *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
182  break;
183  case ECPGt_int:
184  case ECPGt_unsigned_int:
185  *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
186  break;
187  case ECPGt_long:
188  case ECPGt_unsigned_long:
189  *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
190  break;
191 #ifdef HAVE_LONG_LONG_INT
192  case ECPGt_long_long:
194  *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
195  break;
196 #endif /* HAVE_LONG_LONG_INT */
197  case ECPGt_NO_INDICATOR:
198  if (value_for_indicator == -1)
199  {
200  if (force_indicator == false)
201  {
202  /*
203  * Informix has an additional way to specify NULLs note
204  * that this uses special values to denote NULL
205  */
206  ECPGset_noind_null(type, var + offset * act_tuple);
207  }
208  else
209  {
212  NULL);
213  return false;
214  }
215  }
216  break;
217  default:
220  ecpg_type_name(ind_type));
221  return false;
222  break;
223  }
224 
225  if (value_for_indicator == -1)
226  return true;
227 
228  /* let's check if it really is an array if it should be one */
229  if (isarray == ECPG_ARRAY_ARRAY)
230  {
231  if (*pval != '{')
232  {
235  return false;
236  }
237 
238  switch (type)
239  {
240  case ECPGt_char:
241  case ECPGt_unsigned_char:
242  case ECPGt_varchar:
243  case ECPGt_string:
244  break;
245 
246  default:
247  pval++;
248  break;
249  }
250  }
251 
252  do
253  {
254  if (binary)
255  {
256  if (varcharsize == 0 || varcharsize * offset >= size)
257  memcpy(var + offset * act_tuple, pval, size);
258  else
259  {
260  memcpy(var + offset * act_tuple, pval, varcharsize * offset);
261 
262  if (varcharsize * offset < size)
263  {
264  /* truncation */
265  switch (ind_type)
266  {
267  case ECPGt_short:
269  *((short *) (ind + ind_offset * act_tuple)) = size;
270  break;
271  case ECPGt_int:
272  case ECPGt_unsigned_int:
273  *((int *) (ind + ind_offset * act_tuple)) = size;
274  break;
275  case ECPGt_long:
276  case ECPGt_unsigned_long:
277  *((long *) (ind + ind_offset * act_tuple)) = size;
278  break;
279 #ifdef HAVE_LONG_LONG_INT
280  case ECPGt_long_long:
282  *((long long int *) (ind + ind_offset * act_tuple)) = size;
283  break;
284 #endif /* HAVE_LONG_LONG_INT */
285  default:
286  break;
287  }
288  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
289  }
290  }
291  pval += size;
292  }
293  else
294  {
295  switch (type)
296  {
297  long res;
298  unsigned long ures;
299  double dres;
300  char *scan_length;
301  numeric *nres;
302  date ddres;
303  timestamp tres;
304  interval *ires;
305  char *endptr,
306  endchar;
307 
308  case ECPGt_short:
309  case ECPGt_int:
310  case ECPGt_long:
311  res = strtol(pval, &scan_length, 10);
312  if (garbage_left(isarray, &scan_length, compat))
313  {
314  ecpg_raise(lineno, ECPG_INT_FORMAT,
316  return false;
317  }
318  pval = scan_length;
319 
320  switch (type)
321  {
322  case ECPGt_short:
323  *((short *) (var + offset * act_tuple)) = (short) res;
324  break;
325  case ECPGt_int:
326  *((int *) (var + offset * act_tuple)) = (int) res;
327  break;
328  case ECPGt_long:
329  *((long *) (var + offset * act_tuple)) = (long) res;
330  break;
331  default:
332  /* Cannot happen */
333  break;
334  }
335  break;
336 
338  case ECPGt_unsigned_int:
339  case ECPGt_unsigned_long:
340  ures = strtoul(pval, &scan_length, 10);
341  if (garbage_left(isarray, &scan_length, compat))
342  {
345  return false;
346  }
347  pval = scan_length;
348 
349  switch (type)
350  {
352  *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
353  break;
354  case ECPGt_unsigned_int:
355  *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
356  break;
357  case ECPGt_unsigned_long:
358  *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
359  break;
360  default:
361  /* Cannot happen */
362  break;
363  }
364  break;
365 
366 #ifdef HAVE_LONG_LONG_INT
367 #ifdef HAVE_STRTOLL
368  case ECPGt_long_long:
369  *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
370  if (garbage_left(isarray, &scan_length, compat))
371  {
373  return false;
374  }
375  pval = scan_length;
376 
377  break;
378 #endif /* HAVE_STRTOLL */
379 #ifdef HAVE_STRTOULL
381  *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
382  if (garbage_left(isarray, &scan_length, compat))
383  {
385  return false;
386  }
387  pval = scan_length;
388 
389  break;
390 #endif /* HAVE_STRTOULL */
391 #endif /* HAVE_LONG_LONG_INT */
392 
393  case ECPGt_float:
394  case ECPGt_double:
395  if (isarray && *pval == '"')
396  pval++;
397 
398  if (!check_special_value(pval, &dres, &scan_length))
399  dres = strtod(pval, &scan_length);
400 
401  if (isarray && *scan_length == '"')
402  scan_length++;
403 
404  /* no special INFORMIX treatment for floats */
405  if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
406  {
409  return false;
410  }
411  pval = scan_length;
412 
413  switch (type)
414  {
415  case ECPGt_float:
416  *((float *) (var + offset * act_tuple)) = dres;
417  break;
418  case ECPGt_double:
419  *((double *) (var + offset * act_tuple)) = dres;
420  break;
421  default:
422  /* Cannot happen */
423  break;
424  }
425  break;
426 
427  case ECPGt_bool:
428  if (pval[0] == 'f' && pval[1] == '\0')
429  {
430  *((bool *) (var + offset * act_tuple)) = false;
431  pval++;
432  break;
433  }
434  else if (pval[0] == 't' && pval[1] == '\0')
435  {
436  *((bool *) (var + offset * act_tuple)) = true;
437  pval++;
438  break;
439  }
440  else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
441  {
442  /* NULL is valid */
443  break;
444  }
445 
448  return false;
449  break;
450 
451  case ECPGt_char:
452  case ECPGt_unsigned_char:
453  case ECPGt_string:
454  {
455  char *str = (char *) (var + offset * act_tuple);
456 
457  /*
458  * If varcharsize is unknown and the offset is that of
459  * char *, then this variable represents the array of
460  * character pointers. So, use extra indirection.
461  */
462  if (varcharsize == 0 && offset == sizeof(char *))
463  str = *(char **) str;
464 
465  if (varcharsize == 0 || varcharsize > size)
466  {
467  /*
468  * compatibility mode, blank pad and null
469  * terminate char array
470  */
472  {
473  memset(str, ' ', varcharsize);
474  memcpy(str, pval, size);
475  str[varcharsize - 1] = '\0';
476 
477  /*
478  * compatibility mode empty string gets -1
479  * indicator but no warning
480  */
481  if (size == 0)
482  {
483  /* truncation */
484  switch (ind_type)
485  {
486  case ECPGt_short:
488  *((short *) (ind + ind_offset * act_tuple)) = -1;
489  break;
490  case ECPGt_int:
491  case ECPGt_unsigned_int:
492  *((int *) (ind + ind_offset * act_tuple)) = -1;
493  break;
494  case ECPGt_long:
495  case ECPGt_unsigned_long:
496  *((long *) (ind + ind_offset * act_tuple)) = -1;
497  break;
498 #ifdef HAVE_LONG_LONG_INT
499  case ECPGt_long_long:
501  *((long long int *) (ind + ind_offset * act_tuple)) = -1;
502  break;
503 #endif /* HAVE_LONG_LONG_INT */
504  default:
505  break;
506  }
507  }
508  }
509  else
510  {
511  strncpy(str, pval, size + 1);
512  }
513  /* do the rtrim() */
514  if (type == ECPGt_string)
515  {
516  char *last = str + size;
517 
518  while (last > str && (*last == ' ' || *last == '\0'))
519  {
520  *last = '\0';
521  last--;
522  }
523  }
524  }
525  else
526  {
527  strncpy(str, pval, varcharsize);
528 
529  /* compatibility mode, null terminate char array */
530  if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
531  {
533  str[varcharsize - 1] = '\0';
534  }
535 
536  if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
537  {
538  /* truncation */
539  switch (ind_type)
540  {
541  case ECPGt_short:
543  *((short *) (ind + ind_offset * act_tuple)) = size;
544  break;
545  case ECPGt_int:
546  case ECPGt_unsigned_int:
547  *((int *) (ind + ind_offset * act_tuple)) = size;
548  break;
549  case ECPGt_long:
550  case ECPGt_unsigned_long:
551  *((long *) (ind + ind_offset * act_tuple)) = size;
552  break;
553 #ifdef HAVE_LONG_LONG_INT
554  case ECPGt_long_long:
556  *((long long int *) (ind + ind_offset * act_tuple)) = size;
557  break;
558 #endif /* HAVE_LONG_LONG_INT */
559  default:
560  break;
561  }
562  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
563  }
564  }
565  pval += size;
566  }
567  break;
568 
569  case ECPGt_varchar:
570  {
571  struct ECPGgeneric_varchar *variable =
572  (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
573 
574  variable->len = size;
575  if (varcharsize == 0)
576  strncpy(variable->arr, pval, variable->len);
577  else
578  {
579  strncpy(variable->arr, pval, varcharsize);
580 
581  if (variable->len > varcharsize)
582  {
583  /* truncation */
584  switch (ind_type)
585  {
586  case ECPGt_short:
588  *((short *) (ind + ind_offset * act_tuple)) = variable->len;
589  break;
590  case ECPGt_int:
591  case ECPGt_unsigned_int:
592  *((int *) (ind + ind_offset * act_tuple)) = variable->len;
593  break;
594  case ECPGt_long:
595  case ECPGt_unsigned_long:
596  *((long *) (ind + ind_offset * act_tuple)) = variable->len;
597  break;
598 #ifdef HAVE_LONG_LONG_INT
599  case ECPGt_long_long:
601  *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
602  break;
603 #endif /* HAVE_LONG_LONG_INT */
604  default:
605  break;
606  }
607  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
608 
609  variable->len = varcharsize;
610  }
611  }
612  pval += size;
613  }
614  break;
615 
616  case ECPGt_decimal:
617  case ECPGt_numeric:
618  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
619  endchar = *endptr;
620  *endptr = '\0';
621  nres = PGTYPESnumeric_from_asc(pval, &scan_length);
622  *endptr = endchar;
623 
624  /* did we get an error? */
625  if (nres == NULL)
626  {
627  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
628  lineno, pval, errno);
629 
630  if (INFORMIX_MODE(compat))
631  {
632  /*
633  * Informix wants its own NULL value here instead
634  * of an error
635  */
636  nres = PGTYPESnumeric_new();
637  if (nres)
639  else
640  {
643  return false;
644  }
645  }
646  else
647  {
650  return false;
651  }
652  }
653  else
654  {
655  if (!isarray && garbage_left(isarray, &scan_length, compat))
656  {
657  free(nres);
660  return false;
661  }
662  }
663  pval = scan_length;
664 
665  if (type == ECPGt_numeric)
666  PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
667  else
668  PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
669 
670  PGTYPESnumeric_free(nres);
671  break;
672 
673  case ECPGt_interval:
674  if (*pval == '"')
675  pval++;
676 
677  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
678  endchar = *endptr;
679  *endptr = '\0';
680  ires = PGTYPESinterval_from_asc(pval, &scan_length);
681  *endptr = endchar;
682 
683  /* did we get an error? */
684  if (ires == NULL)
685  {
686  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
687  lineno, pval, errno);
688 
689  if (INFORMIX_MODE(compat))
690  {
691  /*
692  * Informix wants its own NULL value here instead
693  * of an error
694  */
695  ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
696  if (!ires)
697  return false;
698 
700  }
701  else
702  {
705  return false;
706  }
707  }
708  else
709  {
710  if (*scan_length == '"')
711  scan_length++;
712 
713  if (!isarray && garbage_left(isarray, &scan_length, compat))
714  {
715  free(ires);
718  return false;
719  }
720  }
721  pval = scan_length;
722 
723  PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
724  free(ires);
725  break;
726 
727  case ECPGt_date:
728  if (*pval == '"')
729  pval++;
730 
731  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
732  endchar = *endptr;
733  *endptr = '\0';
734  ddres = PGTYPESdate_from_asc(pval, &scan_length);
735  *endptr = endchar;
736 
737  /* did we get an error? */
738  if (errno != 0)
739  {
740  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
741  lineno, pval, errno);
742 
743  if (INFORMIX_MODE(compat))
744  {
745  /*
746  * Informix wants its own NULL value here instead
747  * of an error
748  */
750  }
751  else
752  {
755  return false;
756  }
757  }
758  else
759  {
760  if (*scan_length == '"')
761  scan_length++;
762 
763  if (!isarray && garbage_left(isarray, &scan_length, compat))
764  {
767  return false;
768  }
769  }
770 
771  *((date *) (var + offset * act_tuple)) = ddres;
772  pval = scan_length;
773  break;
774 
775  case ECPGt_timestamp:
776  if (*pval == '"')
777  pval++;
778 
779  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
780  endchar = *endptr;
781  *endptr = '\0';
782  tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
783  *endptr = endchar;
784 
785  /* did we get an error? */
786  if (errno != 0)
787  {
788  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
789  lineno, pval, errno);
790 
791  if (INFORMIX_MODE(compat))
792  {
793  /*
794  * Informix wants its own NULL value here instead
795  * of an error
796  */
798  }
799  else
800  {
803  return false;
804  }
805  }
806  else
807  {
808  if (*scan_length == '"')
809  scan_length++;
810 
811  if (!isarray && garbage_left(isarray, &scan_length, compat))
812  {
815  return false;
816  }
817  }
818 
819  *((timestamp *) (var + offset * act_tuple)) = tres;
820  pval = scan_length;
821  break;
822 
823  default:
827  return false;
828  break;
829  }
830  if (ECPG_IS_ARRAY(isarray))
831  {
832  bool string = false;
833 
834  /* set array to next entry */
835  ++act_tuple;
836 
837  /* set pval to the next entry */
838 
839  /*
840  * *pval != '\0' should not be needed, but is used as a safety
841  * guard
842  */
843  for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
844  if (*pval == '"')
845  string = string ? false : true;
846 
847  if (array_delimiter(isarray, *pval))
848  ++pval;
849  }
850  }
851  } while (*pval != '\0' && !array_boundary(isarray, *pval));
852 
853  return true;
854 }
#define ECPG_DATA_NOT_ARRAY
Definition: ecpgerrno.h:33
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3129
date PGTYPESdate_from_asc(char *, char **)
Definition: datetime.c:48
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
Definition: extern.h:217
#define ORACLE_MODE(X)
Definition: extern.h:24
int PGTYPESnumeric_copy(numeric *, numeric *)
Definition: numeric.c:1475
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
char arr[FLEXIBLE_ARRAY_MEMBER]
Definition: extern.h:37
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
#define INFORMIX_MODE(X)
Definition: extern.h:23
int PGTYPESinterval_copy(interval *, interval *)
Definition: interval.c:1086
#define ECPG_NUMERIC_FORMAT
Definition: ecpgerrno.h:25
#define sqlca
Definition: sqlca.h:59
int64 timestamp
#define ECPG_INTERVAL_FORMAT
Definition: ecpgerrno.h:26
char sqlwarn[8]
Definition: sqlca.h:39
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:21
#define ECPG_CONVERT_BOOL
Definition: ecpgerrno.h:29
int PGTYPESnumeric_to_decimal(numeric *, decimal *)
Definition: numeric.c:1629
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
Definition: data.c:34
long date
Definition: pgtypes_date.h:8
#define false
Definition: c.h:283
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
#define ECPG_UINT_FORMAT
Definition: ecpgerrno.h:23
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
Definition: extern.h:210
#define ECPG_SQLSTATE_NO_DATA
Definition: extern.h:201
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:127
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
#define ECPG_DATE_FORMAT
Definition: ecpgerrno.h:27
const char * ecpg_type_name(enum ECPGttype)
Definition: typename.c:18
Definition: sqlca.h:19
interval * PGTYPESinterval_from_asc(char *, char **)
Definition: interval.c:1007
char * ecpg_alloc(long, int)
Definition: memory.c:19
#define ECPG_FLOAT_FORMAT
Definition: ecpgerrno.h:24
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool ecpg_internal_regression_mode
Definition: misc.c:30
#define ECPG_MISSING_INDICATOR
Definition: ecpgerrno.h:31
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
#define ECPG_IS_ARRAY(X)
Definition: extern.h:31
static bool check_special_value(char *ptr, double *retval, char **endptr)
Definition: data.c:102
numeric * PGTYPESnumeric_from_asc(char *, char **)
Definition: numeric.c:406
#define free(a)
Definition: header.h:65
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:320
#define ECPG_TIMESTAMP_FORMAT
Definition: ecpgerrno.h:28
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
Definition: data.c:47
bool force_indicator
Definition: ecpg.c:18
#define ECPG_INT_FORMAT
Definition: ecpgerrno.h:22
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143
int PQfformat(const PGresult *res, int field_num)
Definition: fe-exec.c:2951
timestamp PGTYPEStimestamp_from_asc(char *, char **)
Definition: timestamp.c:207

◆ ecpg_init()

bool ecpg_init ( const struct connection ,
const char *  ,
const int   
)

Definition at line 105 of file misc.c.

References arg, ecpg_gettext, ecpg_init_sqlca(), ECPG_NO_CONN, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPGget_sqlca(), and free.

Referenced by ecpg_do_prologue(), ECPGdeallocate(), ECPGdisconnect(), ECPGprepare(), ECPGsetcommit(), ECPGsetconn(), ECPGstatus(), and ECPGtrans().

106 {
107  struct sqlca_t *sqlca = ECPGget_sqlca();
108 
109  if (sqlca == NULL)
110  {
112  NULL);
113  return false;
114  }
115 
116  ecpg_init_sqlca(sqlca);
117  if (con == NULL)
118  {
120  connection_name ? connection_name : ecpg_gettext("NULL"));
121  return false;
122  }
123 
124  return true;
125 }
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:99
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST
Definition: extern.h:207
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
Definition: sqlca.h:19
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define ecpg_gettext(x)
Definition: ecpglib.h:18
static struct sqlca_t sqlca
Definition: misc.c:63
#define ECPG_NO_CONN
Definition: ecpgerrno.h:36

◆ ecpg_init_sqlca()

void ecpg_init_sqlca ( struct sqlca_t sqlca)

Definition at line 99 of file misc.c.

Referenced by ecpg_init(), ECPGallocate_desc(), ECPGconnect(), ECPGdeallocate_desc(), ECPGdisconnect(), ECPGget_desc(), ECPGget_desc_header(), and ECPGget_sqlca().

100 {
101  memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
102 }
Definition: sqlca.h:19
static struct sqlca_t sqlca_init
Definition: misc.c:32

◆ ecpg_log()

◆ ecpg_prepared()

char* ecpg_prepared ( const char *  ,
struct connection  
)

Definition at line 295 of file prepare.c.

References statement::command, ecpg_find_prepared_statement(), and prepared_statement::stmt.

Referenced by ecpg_do_prologue(), and ECPGprepared_statement().

296 {
297  struct prepared_statement *this;
298 
299  this = ecpg_find_prepared_statement(name, con, NULL);
300  return this ? this->stmt->command : NULL;
301 }
struct statement * stmt
Definition: extern.h:75
char * command
Definition: extern.h:55
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521

◆ ecpg_process_output()

bool ecpg_process_output ( struct statement ,
bool   
)

Definition at line 1481 of file execute.c.

References pgNotify::be_pid, buffer, statement::compat, statement::connection, connection::connection, ecpg_build_compat_sqlda(), ecpg_build_native_sqlda(), ECPG_COMPAT_INFORMIX_SE, ecpg_find_desc(), ecpg_log(), ECPG_NOT_FOUND, ECPG_OUT_OF_MEMORY, ecpg_raise(), ecpg_raise_backend(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_NO_DATA, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, ecpg_store_result(), ECPG_TOO_FEW_ARGUMENTS, ECPG_TOO_MANY_ARGUMENTS, ECPGget_sqlca(), ECPGt_descriptor, ECPGt_sqlda, free, i, INFORMIX_MODE, statement::lineno, variable::next, statement::outlist, PGRES_COMMAND_OK, PGRES_COPY_OUT, PGRES_TUPLES_OK, variable::pointer, PQclear(), PQcmdStatus(), PQcmdTuples(), PQfreemem(), PQgetCopyData(), PQgetResult(), PQnfields(), PQnotifies(), PQntuples(), PQoidValue(), PQresultErrorMessage(), PQresultStatus(), pgNotify::relname, descriptor::result, statement::results, sqlca, sqlca_t::sqlerrd, status(), and variable::type.

Referenced by ecpg_do().

1482 {
1483  struct variable *var;
1484  bool status = false;
1485  char *cmdstat;
1486  PGnotify *notify;
1487  struct sqlca_t *sqlca = ECPGget_sqlca();
1488  int nfields,
1489  ntuples,
1490  act_field;
1491 
1492  if (sqlca == NULL)
1493  {
1494  ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY,
1496  return false;
1497  }
1498 
1499  var = stmt->outlist;
1500  switch (PQresultStatus(stmt->results))
1501  {
1502  case PGRES_TUPLES_OK:
1503  nfields = PQnfields(stmt->results);
1504  sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
1505 
1506  ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
1507  status = true;
1508 
1509  if (ntuples < 1)
1510  {
1511  if (ntuples)
1512  ecpg_log("ecpg_process_output on line %d: incorrect number of matches (%d)\n",
1513  stmt->lineno, ntuples);
1514  ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
1515  status = false;
1516  break;
1517  }
1518 
1519  if (var != NULL && var->type == ECPGt_descriptor)
1520  {
1521  struct descriptor *desc = ecpg_find_desc(stmt->lineno, var->pointer);
1522 
1523  if (desc == NULL)
1524  status = false;
1525  else
1526  {
1527  if (desc->result)
1528  PQclear(desc->result);
1529  desc->result = stmt->results;
1530  clear_result = false;
1531  ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
1532  stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
1533  }
1534  var = var->next;
1535  }
1536  else if (var != NULL && var->type == ECPGt_sqlda)
1537  {
1538  if (INFORMIX_MODE(stmt->compat))
1539  {
1540  struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
1541  struct sqlda_compat *sqlda = *_sqlda;
1542  struct sqlda_compat *sqlda_new;
1543  int i;
1544 
1545  /*
1546  * If we are passed in a previously existing sqlda (chain)
1547  * then free it.
1548  */
1549  while (sqlda)
1550  {
1551  sqlda_new = sqlda->desc_next;
1552  free(sqlda);
1553  sqlda = sqlda_new;
1554  }
1555  *_sqlda = sqlda = sqlda_new = NULL;
1556  for (i = ntuples - 1; i >= 0; i--)
1557  {
1558  /*
1559  * Build a new sqlda structure. Note that only
1560  * fetching 1 record is supported
1561  */
1562  sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
1563 
1564  if (!sqlda_new)
1565  {
1566  /* cleanup all SQLDAs we created up */
1567  while (sqlda)
1568  {
1569  sqlda_new = sqlda->desc_next;
1570  free(sqlda);
1571  sqlda = sqlda_new;
1572  }
1573  *_sqlda = NULL;
1574 
1575  ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
1576  status = false;
1577  break;
1578  }
1579  else
1580  {
1581  ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
1582 
1583  *_sqlda = sqlda_new;
1584 
1585  ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
1586  ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
1587  stmt->lineno, PQnfields(stmt->results));
1588 
1589  sqlda_new->desc_next = sqlda;
1590  sqlda = sqlda_new;
1591  }
1592  }
1593  }
1594  else
1595  {
1596  struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
1597  struct sqlda_struct *sqlda = *_sqlda;
1598  struct sqlda_struct *sqlda_new;
1599  int i;
1600 
1601  /*
1602  * If we are passed in a previously existing sqlda (chain)
1603  * then free it.
1604  */
1605  while (sqlda)
1606  {
1607  sqlda_new = sqlda->desc_next;
1608  free(sqlda);
1609  sqlda = sqlda_new;
1610  }
1611  *_sqlda = sqlda = sqlda_new = NULL;
1612  for (i = ntuples - 1; i >= 0; i--)
1613  {
1614  /*
1615  * Build a new sqlda structure. Note that only
1616  * fetching 1 record is supported
1617  */
1618  sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
1619 
1620  if (!sqlda_new)
1621  {
1622  /* cleanup all SQLDAs we created up */
1623  while (sqlda)
1624  {
1625  sqlda_new = sqlda->desc_next;
1626  free(sqlda);
1627  sqlda = sqlda_new;
1628  }
1629  *_sqlda = NULL;
1630 
1631  ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
1632  status = false;
1633  break;
1634  }
1635  else
1636  {
1637  ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
1638 
1639  *_sqlda = sqlda_new;
1640 
1641  ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
1642  ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
1643  stmt->lineno, PQnfields(stmt->results));
1644 
1645  sqlda_new->desc_next = sqlda;
1646  sqlda = sqlda_new;
1647  }
1648  }
1649  }
1650 
1651  var = var->next;
1652  }
1653  else
1654  for (act_field = 0; act_field < nfields && status; act_field++)
1655  {
1656  if (var != NULL)
1657  {
1658  status = ecpg_store_result(stmt->results, act_field, stmt, var);
1659  var = var->next;
1660  }
1661  else if (!INFORMIX_MODE(stmt->compat))
1662  {
1664  return false;
1665  }
1666  }
1667 
1668  if (status && var != NULL)
1669  {
1671  status = false;
1672  }
1673 
1674  break;
1675  case PGRES_COMMAND_OK:
1676  status = true;
1677  cmdstat = PQcmdStatus(stmt->results);
1678  sqlca->sqlerrd[1] = PQoidValue(stmt->results);
1679  sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
1680  ecpg_log("ecpg_process_output on line %d: OK: %s\n", stmt->lineno, cmdstat);
1681  if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
1682  !sqlca->sqlerrd[2] &&
1683  (strncmp(cmdstat, "UPDATE", 6) == 0
1684  || strncmp(cmdstat, "INSERT", 6) == 0
1685  || strncmp(cmdstat, "DELETE", 6) == 0))
1686  ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
1687  break;
1688  case PGRES_COPY_OUT:
1689  {
1690  char *buffer;
1691  int res;
1692 
1693  ecpg_log("ecpg_process_output on line %d: COPY OUT data transfer in progress\n", stmt->lineno);
1694  while ((res = PQgetCopyData(stmt->connection->connection,
1695  &buffer, 0)) > 0)
1696  {
1697  printf("%s", buffer);
1698  PQfreemem(buffer);
1699  }
1700  if (res == -1)
1701  {
1702  /* COPY done */
1703  PQclear(stmt->results);
1704  stmt->results = PQgetResult(stmt->connection->connection);
1705  if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
1706  ecpg_log("ecpg_process_output on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
1707  else
1708  ecpg_log("ecpg_process_output on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
1709  }
1710  break;
1711  }
1712  default:
1713 
1714  /*
1715  * execution should never reach this code because it is already
1716  * handled in ECPGcheck_PQresult()
1717  */
1718  ecpg_log("ecpg_process_output on line %d: unknown execution status type\n",
1719  stmt->lineno);
1720  ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
1721  status = false;
1722  break;
1723  }
1724 
1725  if (clear_result)
1726  {
1727  PQclear(stmt->results);
1728  stmt->results = NULL;
1729  }
1730 
1731  /* check for asynchronous returns */
1732  notify = PQnotifies(stmt->connection->connection);
1733  if (notify)
1734  {
1735  ecpg_log("ecpg_process_output on line %d: asynchronous notification of \"%s\" from backend PID %d received\n",
1736  stmt->lineno, notify->relname, notify->be_pid);
1737  PQfreemem(notify);
1738  }
1739 
1740  return status;
1741 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2732
bool ecpg_store_result(const PGresult *results, int act_field, const struct statement *stmt, struct variable *var)
Definition: execute.c:309
PGnotify * PQnotifies(PGconn *conn)
Definition: fe-exec.c:2244
#define INFORMIX_MODE(X)
Definition: extern.h:23
#define sqlca
Definition: sqlca.h:59
char * PQcmdTuples(PGresult *res)
Definition: fe-exec.c:3065
Oid PQoidValue(const PGresult *res)
Definition: fe-exec.c:3036
void * pointer
Definition: extern.h:116
enum ECPGttype type
Definition: extern.h:114
#define ECPG_TOO_MANY_ARGUMENTS
Definition: ecpgerrno.h:19
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
struct variable * next
Definition: extern.h:126
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2428
#define ECPG_SQLSTATE_NO_DATA
Definition: extern.h:201
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS
Definition: extern.h:203
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
void ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)
Definition: error.c:219
void ecpg_set_compat_sqlda(int, struct sqlda_compat **, const PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:253
int be_pid
Definition: libpq-fe.h:164
Definition: sqlca.h:19
struct descriptor * ecpg_find_desc(int line, const char *name)
Definition: descriptor.c:800
PGresult * result
Definition: extern.h:94
char * relname
Definition: libpq-fe.h:163
long sqlerrd[6]
Definition: sqlca.h:30
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
char * PQcmdStatus(PGresult *res)
Definition: fe-exec.c:2995
struct sqlda_compat * ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:203
struct sqlda_struct * ecpg_build_native_sqlda(int, PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:410
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
#define ECPG_TOO_FEW_ARGUMENTS
Definition: ecpgerrno.h:20
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:2663
int i
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
void ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:442
void PQfreemem(void *ptr)
Definition: fe-exec.c:3251
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1753

◆ ecpg_raise()

void ecpg_raise ( int  line,
int  code,
const char *  sqlstate,
const char *  str 
)

Definition at line 13 of file error.c.

References ECPG_ARRAY_INSERT, ECPG_CONNECT, ECPG_CONVERT_BOOL, ECPG_DATA_NOT_ARRAY, ECPG_EMPTY, ECPG_FLOAT_FORMAT, ecpg_gettext, ECPG_INT_FORMAT, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_INVALID_STMT, ecpg_log(), ECPG_MISSING_INDICATOR, ECPG_NO_ARRAY, ECPG_NO_CONN, ECPG_NOT_CONN, ECPG_NOT_FOUND, ECPG_OUT_OF_MEMORY, ECPG_TOO_FEW_ARGUMENTS, ECPG_TOO_MANY_ARGUMENTS, ECPG_TRANS, ECPG_UINT_FORMAT, ECPG_UNKNOWN_DESCRIPTOR, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_UNSUPPORTED, ECPG_VAR_NOT_CHAR, ECPG_VAR_NOT_NUMERIC, ECPGfree_auto_mem(), ECPGget_sqlca(), snprintf(), sqlca, sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, and sqlca_t::sqlstate.

Referenced by deallocate_one(), ecpg_alloc(), ecpg_build_params(), ecpg_check_PQresult(), ecpg_do_prologue(), ecpg_find_desc(), ecpg_get_data(), ecpg_init(), ecpg_process_output(), ecpg_realloc(), ecpg_store_input(), ecpg_store_result(), ecpg_strdup(), ECPGallocate_desc(), ECPGconnect(), ECPGdeallocate(), ECPGdeallocate_desc(), ECPGdescribe(), ECPGdisconnect(), ECPGget_desc(), ECPGget_desc_header(), ECPGset_desc(), ECPGset_var(), ECPGstatus(), get_char_item(), get_int_item(), and set_int_item().

14 {
15  struct sqlca_t *sqlca = ECPGget_sqlca();
16 
17  if (sqlca == NULL)
18  {
19  ecpg_log("out of memory");
21  return;
22  }
23 
24  sqlca->sqlcode = code;
25  strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
26 
27  switch (code)
28  {
29  case ECPG_NOT_FOUND:
30  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
31  /*------
32  translator: this string will be truncated at 149 characters expanded. */
33  ecpg_gettext("no data found on line %d"), line);
34  break;
35 
36  case ECPG_OUT_OF_MEMORY:
37  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
38  /*------
39  translator: this string will be truncated at 149 characters expanded. */
40  ecpg_gettext("out of memory on line %d"), line);
41  break;
42 
43  case ECPG_UNSUPPORTED:
44  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
45  /*------
46  translator: this string will be truncated at 149 characters expanded. */
47  ecpg_gettext("unsupported type \"%s\" on line %d"), str, line);
48  break;
49 
51  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
52  /*------
53  translator: this string will be truncated at 149 characters expanded. */
54  ecpg_gettext("too many arguments on line %d"), line);
55  break;
56 
58  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
59  /*------
60  translator: this string will be truncated at 149 characters expanded. */
61  ecpg_gettext("too few arguments on line %d"), line);
62  break;
63 
64  case ECPG_INT_FORMAT:
65  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
66  /*------
67  translator: this string will be truncated at 149 characters expanded. */
68  ecpg_gettext("invalid input syntax for type int: \"%s\", on line %d"), str, line);
69  break;
70 
71  case ECPG_UINT_FORMAT:
72  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
73  /*------
74  translator: this string will be truncated at 149 characters expanded. */
75  ecpg_gettext("invalid input syntax for type unsigned int: \"%s\", on line %d"), str, line);
76  break;
77 
78  case ECPG_FLOAT_FORMAT:
79  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
80  /*------
81  translator: this string will be truncated at 149 characters expanded. */
82  ecpg_gettext("invalid input syntax for floating-point type: \"%s\", on line %d"), str, line);
83  break;
84 
85  case ECPG_CONVERT_BOOL:
86  if (str)
87  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
88  /*------
89  translator: this string will be truncated at 149 characters expanded. */
90  ecpg_gettext("invalid syntax for type boolean: \"%s\", on line %d"), str, line);
91  else
92  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
93  /*------
94  translator: this string will be truncated at 149 characters expanded. */
95  ecpg_gettext("could not convert boolean value: size mismatch, on line %d"), line);
96  break;
97 
98  case ECPG_EMPTY:
99  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
100  /*------
101  translator: this string will be truncated at 149 characters expanded. */
102  ecpg_gettext("empty query on line %d"), line);
103  break;
104 
106  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
107  /*------
108  translator: this string will be truncated at 149 characters expanded. */
109  ecpg_gettext("null value without indicator on line %d"), line);
110  break;
111 
112  case ECPG_NO_ARRAY:
113  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
114  /*------
115  translator: this string will be truncated at 149 characters expanded. */
116  ecpg_gettext("variable does not have an array type on line %d"), line);
117  break;
118 
119  case ECPG_DATA_NOT_ARRAY:
120  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
121  /*------
122  translator: this string will be truncated at 149 characters expanded. */
123  ecpg_gettext("data read from server is not an array on line %d"), line);
124  break;
125 
126  case ECPG_ARRAY_INSERT:
127  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
128  /*------
129  translator: this string will be truncated at 149 characters expanded. */
130  ecpg_gettext("inserting an array of variables is not supported on line %d"), line);
131  break;
132 
133  case ECPG_NO_CONN:
134  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
135  /*------
136  translator: this string will be truncated at 149 characters expanded. */
137  ecpg_gettext("connection \"%s\" does not exist on line %d"), str, line);
138  break;
139 
140  case ECPG_NOT_CONN:
141  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
142  /*------
143  translator: this string will be truncated at 149 characters expanded. */
144  ecpg_gettext("not connected to connection \"%s\" on line %d"), str, line);
145  break;
146 
147  case ECPG_INVALID_STMT:
148  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
149  /*------
150  translator: this string will be truncated at 149 characters expanded. */
151  ecpg_gettext("invalid statement name \"%s\" on line %d"), str, line);
152  break;
153 
155  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
156  /*------
157  translator: this string will be truncated at 149 characters expanded. */
158  ecpg_gettext("descriptor \"%s\" not found on line %d"), str, line);
159  break;
160 
162  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
163  /*------
164  translator: this string will be truncated at 149 characters expanded. */
165  ecpg_gettext("descriptor index out of range on line %d"), line);
166  break;
167 
169  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
170  /*------
171  translator: this string will be truncated at 149 characters expanded. */
172  ecpg_gettext("unrecognized descriptor item \"%s\" on line %d"), str, line);
173  break;
174 
176  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
177  /*------
178  translator: this string will be truncated at 149 characters expanded. */
179  ecpg_gettext("variable does not have a numeric type on line %d"), line);
180  break;
181 
182  case ECPG_VAR_NOT_CHAR:
183  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
184  /*------
185  translator: this string will be truncated at 149 characters expanded. */
186  ecpg_gettext("variable does not have a character type on line %d"), line);
187  break;
188 
189  case ECPG_TRANS:
190  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
191  /*------
192  translator: this string will be truncated at 149 characters expanded. */
193  ecpg_gettext("error in transaction processing on line %d"), line);
194  break;
195 
196  case ECPG_CONNECT:
197  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
198  /*------
199  translator: this string will be truncated at 149 characters expanded. */
200  ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
201  break;
202 
203  default:
204  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
205  /*------
206  translator: this string will be truncated at 149 characters expanded. */
207  ecpg_gettext("SQL error %d on line %d"), code, line);
208  break;
209  }
210 
211  sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
212  ecpg_log("raising sqlcode %d on line %d: %s\n", code, line, sqlca->sqlerrm.sqlerrmc);
213 
214  /* free all memory we have allocated for the user */
216 }
#define ECPG_DATA_NOT_ARRAY
Definition: ecpgerrno.h:33
#define ECPG_CONNECT
Definition: ecpgerrno.h:51
#define ECPG_NOT_CONN
Definition: ecpgerrno.h:37
struct sqlca_t::@134 sqlerrm
void ECPGfree_auto_mem(void)
Definition: memory.c:138
#define sqlca
Definition: sqlca.h:59
#define ECPG_INVALID_STMT
Definition: ecpgerrno.h:39
#define ECPG_VAR_NOT_CHAR
Definition: ecpgerrno.h:46
#define ECPG_CONVERT_BOOL
Definition: ecpgerrno.h:29
#define ECPG_INVALID_DESCRIPTOR_INDEX
Definition: ecpgerrno.h:43
#define ECPG_UNKNOWN_DESCRIPTOR_ITEM
Definition: ecpgerrno.h:44
int sqlerrml
Definition: sqlca.h:26
#define ECPG_TOO_MANY_ARGUMENTS
Definition: ecpgerrno.h:19
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define ECPG_UINT_FORMAT
Definition: ecpgerrno.h:23
#define ECPG_EMPTY
Definition: ecpgerrno.h:30
#define ECPG_TRANS
Definition: ecpgerrno.h:50
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
#define ECPG_NO_ARRAY
Definition: ecpgerrno.h:32
Definition: sqlca.h:19
#define ECPG_FLOAT_FORMAT
Definition: ecpgerrno.h:24
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
char sqlstate[5]
Definition: sqlca.h:53
#define ECPG_ARRAY_INSERT
Definition: ecpgerrno.h:34
#define ECPG_MISSING_INDICATOR
Definition: ecpgerrno.h:31
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
long sqlcode
Definition: sqlca.h:23
#define ecpg_gettext(x)
Definition: ecpglib.h:18
#define ECPG_VAR_NOT_NUMERIC
Definition: ecpgerrno.h:45
#define ECPG_UNKNOWN_DESCRIPTOR
Definition: ecpgerrno.h:42
#define ECPG_TOO_FEW_ARGUMENTS
Definition: ecpgerrno.h:20
char sqlerrmc[SQLERRMC_LEN]
Definition: sqlca.h:27
#define ECPG_INT_FORMAT
Definition: ecpgerrno.h:22
#define ECPG_NO_CONN
Definition: ecpgerrno.h:36

◆ ecpg_raise_backend()

void ecpg_raise_backend ( int  line,
PGresult result,
PGconn conn,
int  compat 
)

Definition at line 219 of file error.c.

References CONNECTION_BAD, ECPG_DUPLICATE_KEY, ecpg_gettext, ECPG_INFORMIX_DUPLICATE_KEY, ECPG_INFORMIX_SUBSELECT_NOT_ONE, ecpg_log(), ECPG_PGSQL, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SUBSELECT_NOT_ONE, ECPGfree_auto_mem(), ECPGget_sqlca(), INFORMIX_MODE, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SQLSTATE, PQerrorMessage(), PQresultErrorField(), PQstatus(), snprintf(), sqlca, sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, and sqlca_t::sqlstate.

Referenced by ecpg_check_PQresult(), and ecpg_process_output().

220 {
221  struct sqlca_t *sqlca = ECPGget_sqlca();
222  char *sqlstate;
223  char *message;
224 
225  if (sqlca == NULL)
226  {
227  ecpg_log("out of memory");
229  return;
230  }
231 
232  if (result)
233  {
234  sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
235  if (sqlstate == NULL)
237  message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
238  }
239  else
240  {
242  message = PQerrorMessage(conn);
243  }
244 
245  if (strcmp(sqlstate, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR) == 0)
246  {
247  /*
248  * we might get here if the connection breaks down, so let's check for
249  * this instead of giving just the generic internal error
250  */
251  if (PQstatus(conn) == CONNECTION_BAD)
252  {
253  sqlstate = "57P02";
254  message = ecpg_gettext("the connection to the server was lost");
255  }
256  }
257 
258  /* copy error message */
259  snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "%s on line %d", message, line);
260  sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
261 
262  /* copy SQLSTATE */
263  strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
264 
265  /* assign SQLCODE for backward compatibility */
266  if (strncmp(sqlca->sqlstate, "23505", sizeof(sqlca->sqlstate)) == 0)
268  else if (strncmp(sqlca->sqlstate, "21000", sizeof(sqlca->sqlstate)) == 0)
270  else
271  sqlca->sqlcode = ECPG_PGSQL;
272 
273  /* %.*s is safe here as long as sqlstate is all-ASCII */
274  ecpg_log("raising sqlstate %.*s (sqlcode %ld): %s\n",
275  (int) sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, sqlca->sqlerrm.sqlerrmc);
276 
277  /* free all memory we have allocated for the user */
279 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6116
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
struct sqlca_t::@134 sqlerrm
void ECPGfree_auto_mem(void)
Definition: memory.c:138
#define INFORMIX_MODE(X)
Definition: extern.h:23
#define sqlca
Definition: sqlca.h:59
int sqlerrml
Definition: sqlca.h:26
#define ECPG_PGSQL
Definition: ecpgerrno.h:49
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
#define ECPG_SUBSELECT_NOT_ONE
Definition: ecpgerrno.h:53
Definition: sqlca.h:19
#define ECPG_INFORMIX_DUPLICATE_KEY
Definition: ecpgerrno.h:57
char sqlstate[5]
Definition: sqlca.h:53
enum COMPAT_MODE compat
Definition: ecpg.c:25
long sqlcode
Definition: sqlca.h:23
#define ecpg_gettext(x)
Definition: ecpglib.h:18
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2709
#define ECPG_DUPLICATE_KEY
Definition: ecpgerrno.h:52
#define ECPG_INFORMIX_SUBSELECT_NOT_ONE
Definition: ecpgerrno.h:58
char sqlerrmc[SQLERRMC_LEN]
Definition: sqlca.h:27
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6063

◆ ecpg_realloc()

char* ecpg_realloc ( void *  ,
long  ,
int   
)

Definition at line 33 of file memory.c.

References ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, and realloc.

Referenced by ecpg_build_params(), and ecpg_store_input().

34 {
35  char *new = (char *) realloc(ptr, size);
36 
37  if (!new)
38  {
40  return NULL;
41  }
42 
43  return new;
44 }
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define realloc(a, b)
Definition: header.h:60

◆ ecpg_set_compat_sqlda()

void ecpg_set_compat_sqlda ( int  ,
struct sqlda_compat **  ,
const PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 253 of file sqlda.c.

References numeric::buf, numeric::digits, ECPG_ARRAY_NONE, ecpg_get_data(), ecpg_log(), ecpg_sqlda_align_add_size(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, i, numeric::ndigits, numeric(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PQgetisnull(), PQgetvalue(), sqlda_compat::sqld, sqlda_compat_empty_size(), sqlvar_compat::sqldata, sqlvar_compat::sqlilen, sqlvar_compat::sqlilongdata, sqlvar_compat::sqlind, sqlvar_compat::sqlitype, sqlvar_compat::sqllen, sqlvar_compat::sqltype, sqlda_compat::sqlvar, val, value_is_not_null, and value_is_null.

Referenced by ecpg_process_output().

254 {
255  struct sqlda_compat *sqlda = (*_sqlda);
256  int i;
257  long offset,
258  next_offset;
259 
260  if (row < 0)
261  return;
262 
263  /* Offset for the first field value */
264  offset = sqlda_compat_empty_size(res);
265 
266  /*
267  * Set sqlvar[i]->sqldata pointers and convert values to correct format
268  */
269  for (i = 0; i < sqlda->sqld; i++)
270  {
271  int isnull;
272  int datalen;
273  bool set_data = true;
274 
275  switch (sqlda->sqlvar[i].sqltype)
276  {
277  case ECPGt_short:
279  ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
280  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
281  sqlda->sqlvar[i].sqllen = sizeof(short);
282  break;
283  case ECPGt_int:
284  case ECPGt_unsigned_int:
285  ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
286  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
287  sqlda->sqlvar[i].sqllen = sizeof(int);
288  break;
289  case ECPGt_long:
290  case ECPGt_unsigned_long:
291  ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
292  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
293  sqlda->sqlvar[i].sqllen = sizeof(long);
294  break;
295  case ECPGt_long_long:
297  ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
298  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
299  sqlda->sqlvar[i].sqllen = sizeof(long long);
300  break;
301  case ECPGt_bool:
302  ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
303  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
304  sqlda->sqlvar[i].sqllen = sizeof(bool);
305  break;
306  case ECPGt_float:
307  ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
308  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
309  sqlda->sqlvar[i].sqllen = sizeof(float);
310  break;
311  case ECPGt_double:
312  ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
313  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
314  sqlda->sqlvar[i].sqllen = sizeof(double);
315  break;
316  case ECPGt_decimal:
317  ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
318  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
319  sqlda->sqlvar[i].sqllen = sizeof(decimal);
320  break;
321  case ECPGt_numeric:
322  {
323  numeric *num;
324  char *val;
325 
326  set_data = false;
327 
328  ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
329  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
330  sqlda->sqlvar[i].sqllen = sizeof(numeric);
331 
332  if (PQgetisnull(res, row, i))
333  {
335  break;
336  }
337 
338  val = PQgetvalue(res, row, i);
339  num = PGTYPESnumeric_from_asc(val, NULL);
340  if (!num)
341  {
343  break;
344  }
345 
346  memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
347 
348  if (num->ndigits)
349  {
350  ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
351  memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
352 
353  ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
354  ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
355  }
356 
357  PGTYPESnumeric_free(num);
358 
359  break;
360  }
361  case ECPGt_date:
362  ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
363  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
364  sqlda->sqlvar[i].sqllen = sizeof(date);
365  break;
366  case ECPGt_timestamp:
367  ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
368  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
369  sqlda->sqlvar[i].sqllen = sizeof(timestamp);
370  break;
371  case ECPGt_interval:
372  ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
373  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
374  sqlda->sqlvar[i].sqllen = sizeof(interval);
375  break;
376  case ECPGt_char:
377  case ECPGt_unsigned_char:
378  case ECPGt_string:
379  default:
380  datalen = strlen(PQgetvalue(res, row, i)) + 1;
381  ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
382  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
383  sqlda->sqlvar[i].sqllen = datalen;
384  if (datalen > 32768)
385  sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
386  break;
387  }
388 
389  isnull = PQgetisnull(res, row, i);
390  ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
391  sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
392  sqlda->sqlvar[i].sqlitype = ECPGt_short;
393  sqlda->sqlvar[i].sqlilen = sizeof(short);
394  if (!isnull)
395  {
396  if (set_data)
397  ecpg_get_data(res, row, i, lineno,
398  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
399  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
400  ECPG_ARRAY_NONE, compat, false);
401  }
402  else
403  ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
404 
405  offset = next_offset;
406  }
407 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
int64 timestamp
NumericDigit * buf
static int16 value_is_not_null
Definition: sqlda.c:250
long date
Definition: pgtypes_date.h:8
char bool
Definition: c.h:275
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
void ecpg_log(const char *format,...) pg_attribute_printf(1
char * sqldata
Definition: sqlda-compat.h:12
static void ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
Definition: sqlda.c:34
NumericDigit * digits
Datum numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:944
int16 NumericDigit
Definition: numeric.c:100
static int16 value_is_null
Definition: sqlda.c:249
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, char *var, char *ind, long varcharsize, long offset, long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
Definition: data.c:127
numeric * PGTYPESnumeric_from_asc(char *, char **)
Definition: numeric.c:406
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:320
int i
static long sqlda_compat_empty_size(const PGresult *res)
Definition: sqlda.c:46
short * sqlind
Definition: sqlda-compat.h:13
char * sqlilongdata
Definition: sqlda-compat.h:32
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143
long val
Definition: informix.c:689
struct sqlvar_compat * sqlvar
Definition: sqlda-compat.h:40

◆ ecpg_set_native_sqlda()

void ecpg_set_native_sqlda ( int  ,
struct sqlda_struct **  ,
const PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 442 of file sqlda.c.

References numeric::buf, numeric::digits, ECPG_ARRAY_NONE, ecpg_get_data(), ecpg_log(), ecpg_sqlda_align_add_size(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, i, numeric::ndigits, numeric(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PQgetisnull(), PQgetvalue(), sqlda_struct::sqld, sqlda_native_empty_size(), sqlvar_struct::sqldata, sqlvar_struct::sqlind, sqlvar_struct::sqllen, sqlvar_struct::sqltype, sqlda_struct::sqlvar, val, value_is_not_null, and value_is_null.

Referenced by ecpg_process_output().

443 {
444  struct sqlda_struct *sqlda = (*_sqlda);
445  int i;
446  long offset,
447  next_offset;
448 
449  if (row < 0)
450  return;
451 
452  /* Offset for the first field value */
453  offset = sqlda_native_empty_size(res);
454 
455  /*
456  * Set sqlvar[i]->sqldata pointers and convert values to correct format
457  */
458  for (i = 0; i < sqlda->sqld; i++)
459  {
460  int isnull;
461  int datalen;
462  bool set_data = true;
463 
464  switch (sqlda->sqlvar[i].sqltype)
465  {
466  case ECPGt_short:
468  ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
469  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
470  sqlda->sqlvar[i].sqllen = sizeof(short);
471  break;
472  case ECPGt_int:
473  case ECPGt_unsigned_int:
474  ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
475  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
476  sqlda->sqlvar[i].sqllen = sizeof(int);
477  break;
478  case ECPGt_long:
479  case ECPGt_unsigned_long:
480  ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
481  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
482  sqlda->sqlvar[i].sqllen = sizeof(long);
483  break;
484  case ECPGt_long_long:
486  ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
487  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
488  sqlda->sqlvar[i].sqllen = sizeof(long long);
489  break;
490  case ECPGt_bool:
491  ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
492  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
493  sqlda->sqlvar[i].sqllen = sizeof(bool);
494  break;
495  case ECPGt_float:
496  ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
497  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
498  sqlda->sqlvar[i].sqllen = sizeof(float);
499  break;
500  case ECPGt_double:
501  ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
502  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
503  sqlda->sqlvar[i].sqllen = sizeof(double);
504  break;
505  case ECPGt_decimal:
506  ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
507  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
508  sqlda->sqlvar[i].sqllen = sizeof(decimal);
509  break;
510  case ECPGt_numeric:
511  {
512  numeric *num;
513  char *val;
514 
515  set_data = false;
516 
517  ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
518  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
519  sqlda->sqlvar[i].sqllen = sizeof(numeric);
520 
521  if (PQgetisnull(res, row, i))
522  {
524  break;
525  }
526 
527  val = PQgetvalue(res, row, i);
528  num = PGTYPESnumeric_from_asc(val, NULL);
529  if (!num)
530  {
532  break;
533  }
534 
535  memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
536 
537  if (num->ndigits)
538  {
539  ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
540  memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
541 
542  ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
543  ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
544  }
545 
546  PGTYPESnumeric_free(num);
547 
548  break;
549  }
550  case ECPGt_date:
551  ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
552  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
553  sqlda->sqlvar[i].sqllen = sizeof(date);
554  break;
555  case ECPGt_timestamp:
556  ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
557  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
558  sqlda->sqlvar[i].sqllen = sizeof(timestamp);
559  break;
560  case ECPGt_interval:
561  ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
562  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
563  sqlda->sqlvar[i].sqllen = sizeof(interval);
564  break;
565  case ECPGt_char:
566  case ECPGt_unsigned_char:
567  case ECPGt_string:
568  default:
569  datalen = strlen(PQgetvalue(res, row, i)) + 1;
570  ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
571  sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
572  sqlda->sqlvar[i].sqllen = datalen;
573  break;
574  }
575 
576  isnull = PQgetisnull(res, row, i);
577  ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
578  sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
579  if (!isnull)
580  {
581  if (set_data)
582  ecpg_get_data(res, row, i, lineno,
583  sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
584  sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
585  ECPG_ARRAY_NONE, compat, false);
586  }
587 
588  offset = next_offset;
589  }
590 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
int64 timestamp
struct sqlvar_struct sqlvar[1]
Definition: sqlda-native.h:40
NumericDigit * buf
static int16 value_is_not_null
Definition: sqlda.c:250
long date
Definition: pgtypes_date.h:8
char * sqldata
Definition: sqlda-native.h:28
char bool
Definition: c.h:275
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
void ecpg_log(const char *format,...) pg_attribute_printf(1
static void ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
Definition: sqlda.c:34
NumericDigit * digits
Datum numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:944
int16 NumericDigit
Definition: numeric.c:100
static int16 value_is_null
Definition: sqlda.c:249
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, char *var, char *ind, long varcharsize, long offset, long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
Definition: data.c:127
numeric * PGTYPESnumeric_from_asc(char *, char **)
Definition: numeric.c:406
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:320
short * sqlind
Definition: sqlda-native.h:29
int i
static long sqlda_native_empty_size(const PGresult *res)
Definition: sqlda.c:169
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3143
long val
Definition: informix.c:689

◆ ecpg_store_input()

bool ecpg_store_input ( const int  ,
const bool  ,
const struct variable ,
char **  ,
bool   
)

Definition at line 494 of file execute.c.

References ECPGgeneric_varchar::arr, variable::arrsize, numeric::dscale, ecpg_alloc(), ECPG_CONVERT_BOOL, ecpg_free(), ecpg_raise(), ecpg_realloc(), ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ecpg_strdup(), ecpg_type_name(), ECPG_UNSUPPORTED, ECPGis_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_char_variable, ECPGt_const, ECPGt_date, ECPGt_decimal, ECPGt_descriptor, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_sqlda, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGt_varchar, element(), variable::ind_type, variable::ind_value, ECPGgeneric_varchar::len, variable::offset, PGTYPESdate_to_asc(), PGTYPESinterval_to_asc(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_decimal(), PGTYPESnumeric_new(), PGTYPESnumeric_to_asc(), PGTYPEStimestamp_to_asc(), quote_postgres(), sprintf_double_value(), sprintf_float_value(), generate_unaccent_rules::str, variable::type, variable::value, and variable::varcharsize.

Referenced by ecpg_build_params(), and ECPGset_desc().

496 {
497  char *mallocedval = NULL;
498  char *newcopy = NULL;
499 
500  /*
501  * arrays are not possible unless the column is an array, too FIXME: we do
502  * not know if the column is an array here array input to singleton column
503  * will result in a runtime error
504  */
505 
506  /*
507  * Some special treatment is needed for records since we want their
508  * contents to arrive in a comma-separated list on insert (I think).
509  */
510 
511  *tobeinserted_p = "";
512 
513  /* check for null value and set input buffer accordingly */
514  switch (var->ind_type)
515  {
516  case ECPGt_short:
518  if (*(short *) var->ind_value < 0)
519  *tobeinserted_p = NULL;
520  break;
521  case ECPGt_int:
522  case ECPGt_unsigned_int:
523  if (*(int *) var->ind_value < 0)
524  *tobeinserted_p = NULL;
525  break;
526  case ECPGt_long:
527  case ECPGt_unsigned_long:
528  if (*(long *) var->ind_value < 0L)
529  *tobeinserted_p = NULL;
530  break;
531 #ifdef HAVE_LONG_LONG_INT
532  case ECPGt_long_long:
534  if (*(long long int *) var->ind_value < (long long) 0)
535  *tobeinserted_p = NULL;
536  break;
537 #endif /* HAVE_LONG_LONG_INT */
538  case ECPGt_NO_INDICATOR:
539  if (force_indicator == false)
540  {
541  if (ECPGis_noind_null(var->type, var->value))
542  *tobeinserted_p = NULL;
543  }
544  break;
545  default:
546  break;
547  }
548  if (*tobeinserted_p != NULL)
549  {
550  int asize = var->arrsize ? var->arrsize : 1;
551 
552  switch (var->type)
553  {
554  int element;
555 
556  case ECPGt_short:
557  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
558  return false;
559 
560  if (asize > 1)
561  {
562  strcpy(mallocedval, "{");
563 
564  for (element = 0; element < asize; element++)
565  sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
566 
567  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
568  }
569  else
570  sprintf(mallocedval, "%hd", *((short *) var->value));
571 
572  *tobeinserted_p = mallocedval;
573  break;
574 
575  case ECPGt_int:
576  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
577  return false;
578 
579  if (asize > 1)
580  {
581  strcpy(mallocedval, "{");
582 
583  for (element = 0; element < asize; element++)
584  sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);
585 
586  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
587  }
588  else
589  sprintf(mallocedval, "%d", *((int *) var->value));
590 
591  *tobeinserted_p = mallocedval;
592  break;
593 
595  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
596  return false;
597 
598  if (asize > 1)
599  {
600  strcpy(mallocedval, "{");
601 
602  for (element = 0; element < asize; element++)
603  sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
604 
605  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
606  }
607  else
608  sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
609 
610  *tobeinserted_p = mallocedval;
611  break;
612 
613  case ECPGt_unsigned_int:
614  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
615  return false;
616 
617  if (asize > 1)
618  {
619  strcpy(mallocedval, "{");
620 
621  for (element = 0; element < asize; element++)
622  sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
623 
624  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
625  }
626  else
627  sprintf(mallocedval, "%u", *((unsigned int *) var->value));
628 
629  *tobeinserted_p = mallocedval;
630  break;
631 
632  case ECPGt_long:
633  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
634  return false;
635 
636  if (asize > 1)
637  {
638  strcpy(mallocedval, "{");
639 
640  for (element = 0; element < asize; element++)
641  sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
642 
643  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
644  }
645  else
646  sprintf(mallocedval, "%ld", *((long *) var->value));
647 
648  *tobeinserted_p = mallocedval;
649  break;
650 
651  case ECPGt_unsigned_long:
652  if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
653  return false;
654 
655  if (asize > 1)
656  {
657  strcpy(mallocedval, "{");
658 
659  for (element = 0; element < asize; element++)
660  sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
661 
662  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
663  }
664  else
665  sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
666 
667  *tobeinserted_p = mallocedval;
668  break;
669 #ifdef HAVE_LONG_LONG_INT
670  case ECPGt_long_long:
671  if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
672  return false;
673 
674  if (asize > 1)
675  {
676  strcpy(mallocedval, "{");
677 
678  for (element = 0; element < asize; element++)
679  sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);
680 
681  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
682  }
683  else
684  sprintf(mallocedval, "%lld", *((long long int *) var->value));
685 
686  *tobeinserted_p = mallocedval;
687  break;
688 
690  if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
691  return false;
692 
693  if (asize > 1)
694  {
695  strcpy(mallocedval, "{");
696 
697  for (element = 0; element < asize; element++)
698  sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);
699 
700  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
701  }
702  else
703  sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value));
704 
705  *tobeinserted_p = mallocedval;
706  break;
707 #endif /* HAVE_LONG_LONG_INT */
708  case ECPGt_float:
709  if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
710  return false;
711 
712  if (asize > 1)
713  {
714  strcpy(mallocedval, "{");
715 
716  for (element = 0; element < asize; element++)
717  sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ",");
718 
719  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
720  }
721  else
722  sprintf_float_value(mallocedval, *((float *) var->value), "");
723 
724  *tobeinserted_p = mallocedval;
725  break;
726 
727  case ECPGt_double:
728  if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
729  return false;
730 
731  if (asize > 1)
732  {
733  strcpy(mallocedval, "{");
734 
735  for (element = 0; element < asize; element++)
736  sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ",");
737 
738  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
739  }
740  else
741  sprintf_double_value(mallocedval, *((double *) var->value), "");
742 
743  *tobeinserted_p = mallocedval;
744  break;
745 
746  case ECPGt_bool:
747  if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("{}"), lineno)))
748  return false;
749 
750  if (var->arrsize > 1)
751  {
752  strcpy(mallocedval, "{");
753 
754  for (element = 0; element < asize; element++)
755  sprintf(mallocedval + strlen(mallocedval), "%c,", (((bool *) var->value)[element]) ? 't' : 'f');
756 
757  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
758  }
759  else
760  {
761  if (var->offset == sizeof(char))
762  sprintf(mallocedval, "%c", (*((char *) var->value)) ? 't' : 'f');
763  else if (var->offset == sizeof(int))
764  sprintf(mallocedval, "%c", (*((int *) var->value)) ? 't' : 'f');
765  else
767  }
768 
769  *tobeinserted_p = mallocedval;
770  break;
771 
772  case ECPGt_char:
773  case ECPGt_unsigned_char:
774  case ECPGt_string:
775  {
776  /* set slen to string length if type is char * */
777  int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int) var->varcharsize;
778 
779  if (!(newcopy = ecpg_alloc(slen + 1, lineno)))
780  return false;
781 
782  strncpy(newcopy, (char *) var->value, slen);
783  newcopy[slen] = '\0';
784 
785  mallocedval = quote_postgres(newcopy, quote, lineno);
786  if (!mallocedval)
787  {
788  ecpg_free(newcopy);
789  return false;
790  }
791 
792  *tobeinserted_p = mallocedval;
793  }
794  break;
795  case ECPGt_const:
796  case ECPGt_char_variable:
797  {
798  int slen = strlen((char *) var->value);
799 
800  if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))
801  return false;
802 
803  strncpy(mallocedval, (char *) var->value, slen);
804  mallocedval[slen] = '\0';
805 
806  *tobeinserted_p = mallocedval;
807  }
808  break;
809  case ECPGt_varchar:
810  {
811  struct ECPGgeneric_varchar *variable =
812  (struct ECPGgeneric_varchar *) (var->value);
813 
814  if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, lineno)))
815  return false;
816 
817  strncpy(newcopy, variable->arr, variable->len);
818  newcopy[variable->len] = '\0';
819 
820  mallocedval = quote_postgres(newcopy, quote, lineno);
821  if (!mallocedval)
822  {
823  ecpg_free(newcopy);
824  return false;
825  }
826 
827  *tobeinserted_p = mallocedval;
828  }
829  break;
830 
831  case ECPGt_decimal:
832  case ECPGt_numeric:
833  {
834  char *str = NULL;
835  int slen;
836  numeric *nval;
837 
838  if (var->arrsize > 1)
839  mallocedval = ecpg_strdup("{", lineno);
840  else
841  mallocedval = ecpg_strdup("", lineno);
842 
843  if (!mallocedval)
844  return false;
845 
846  for (element = 0; element < asize; element++)
847  {
848  int result;
849 
850  nval = PGTYPESnumeric_new();
851  if (!nval)
852  {
853  ecpg_free(mallocedval);
854  return false;
855  }
856 
857  if (var->type == ECPGt_numeric)
858  result = PGTYPESnumeric_copy(&(((numeric *) (var->value))[element]), nval);
859  else
860  result = PGTYPESnumeric_from_decimal(&(((decimal *) (var->value))[element]), nval);
861 
862  if (result != 0)
863  {
864  PGTYPESnumeric_free(nval);
865  ecpg_free(mallocedval);
866  return false;
867  }
868 
869  str = PGTYPESnumeric_to_asc(nval, nval->dscale);
870  slen = strlen(str);
871  PGTYPESnumeric_free(nval);
872 
873  if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
874  {
875  ecpg_free(mallocedval);
876  ecpg_free(str);
877  return false;
878  }
879  mallocedval = newcopy;
880 
881  /* also copy trailing '\0' */
882  memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
883  if (var->arrsize > 1)
884  strcpy(mallocedval + strlen(mallocedval), ",");
885 
886  ecpg_free(str);
887  }
888 
889  if (var->arrsize > 1)
890  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
891 
892  *tobeinserted_p = mallocedval;
893  }
894  break;
895 
896  case ECPGt_interval:
897  {
898  char *str = NULL;
899  int slen;
900 
901  if (var->arrsize > 1)
902  mallocedval = ecpg_strdup("{", lineno);
903  else
904  mallocedval = ecpg_strdup("", lineno);
905 
906  if (!mallocedval)
907  return false;
908 
909  for (element = 0; element < asize; element++)
910  {
911  str = quote_postgres(PGTYPESinterval_to_asc(&(((interval *) (var->value))[element])), quote, lineno);
912  if (!str)
913  {
914  ecpg_free(mallocedval);
915  return false;
916  }
917 
918  slen = strlen(str);
919 
920  if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
921  {
922  ecpg_free(mallocedval);
923  ecpg_free(str);
924  return false;
925  }
926  mallocedval = newcopy;
927 
928  /* also copy trailing '\0' */
929  memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
930  if (var->arrsize > 1)
931  strcpy(mallocedval + strlen(mallocedval), ",");
932 
933  ecpg_free(str);
934  }
935 
936  if (var->arrsize > 1)
937  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
938 
939  *tobeinserted_p = mallocedval;
940  }
941  break;
942 
943  case ECPGt_date:
944  {
945  char *str = NULL;
946  int slen;
947 
948  if (var->arrsize > 1)
949  mallocedval = ecpg_strdup("{", lineno);
950  else
951  mallocedval = ecpg_strdup("", lineno);
952 
953  if (!mallocedval)
954  return false;
955 
956  for (element = 0; element < asize; element++)
957  {
958  str = quote_postgres(PGTYPESdate_to_asc(((date *) (var->value))[element]), quote, lineno);
959  if (!str)
960  {
961  ecpg_free(mallocedval);
962  return false;
963  }
964 
965  slen = strlen(str);
966 
967  if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
968  {
969  ecpg_free(mallocedval);
970  ecpg_free(str);
971  return false;
972  }
973  mallocedval = newcopy;
974 
975  /* also copy trailing '\0' */
976  memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
977  if (var->arrsize > 1)
978  strcpy(mallocedval + strlen(mallocedval), ",");
979 
980  ecpg_free(str);
981  }
982 
983  if (var->arrsize > 1)
984  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
985 
986  *tobeinserted_p = mallocedval;
987  }
988  break;
989 
990  case ECPGt_timestamp:
991  {
992  char *str = NULL;
993  int slen;
994 
995  if (var->arrsize > 1)
996  mallocedval = ecpg_strdup("{", lineno);
997  else
998  mallocedval = ecpg_strdup("", lineno);
999 
1000  if (!mallocedval)
1001  return false;
1002 
1003  for (element = 0; element < asize; element++)
1004  {
1005  str = quote_postgres(PGTYPEStimestamp_to_asc(((timestamp *) (var->value))[element]), quote, lineno);
1006  if (!str)
1007  {
1008  ecpg_free(mallocedval);
1009  return false;
1010  }
1011 
1012  slen = strlen(str);
1013 
1014  if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
1015  {
1016  ecpg_free(mallocedval);
1017  ecpg_free(str);
1018  return false;
1019  }
1020  mallocedval = newcopy;
1021 
1022  /* also copy trailing '\0' */
1023  memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
1024  if (var->arrsize > 1)
1025  strcpy(mallocedval + strlen(mallocedval), ",");
1026 
1027  ecpg_free(str);
1028  }
1029 
1030  if (var->arrsize > 1)
1031  strcpy(mallocedval + strlen(mallocedval) - 1, "}");
1032 
1033  *tobeinserted_p = mallocedval;
1034  }
1035  break;
1036 
1037  case ECPGt_descriptor:
1038  case ECPGt_sqlda:
1039  break;
1040 
1041  default:
1042  /* Not implemented yet */
1044  return false;
1045  break;
1046  }
1047  }
1048  return true;
1049 }
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
Definition: extern.h:217
static void sprintf_float_value(char *ptr, float value, const char *delim)
Definition: execute.c:478
int PGTYPESnumeric_copy(numeric *, numeric *)
Definition: numeric.c:1475
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
char arr[FLEXIBLE_ARRAY_MEMBER]
Definition: extern.h:37
void ecpg_free(void *)
Definition: memory.c:13
int64 timestamp
int PGTYPESnumeric_from_decimal(decimal *, numeric *)
Definition: numeric.c:1652
#define ECPG_CONVERT_BOOL
Definition: ecpgerrno.h:29
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
long date
Definition: pgtypes_date.h:8
char * PGTYPESdate_to_asc(date)
Definition: datetime.c:102
static char * quote_postgres(char *arg, bool quote, int lineno)
Definition: execute.c:42
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:127
const char * ecpg_type_name(enum ECPGttype)
Definition: typename.c:18
char * ecpg_alloc(long, int)
Definition: memory.c:19
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:380
char * PGTYPESnumeric_to_asc(numeric *, int)
Definition: numeric.c:428
char * PGTYPEStimestamp_to_asc(timestamp)
Definition: timestamp.c:277
char * PGTYPESinterval_to_asc(interval *)
Definition: interval.c:1066
bool ECPGis_noind_null(enum ECPGttype type, const void *ptr)
Definition: misc.c:388
static void sprintf_double_value(char *ptr, double value, const char *delim)
Definition: execute.c:462
bool force_indicator
Definition: ecpg.c:18
char * ecpg_realloc(void *, long, int)
Definition: memory.c:33

◆ ecpg_store_result()

bool ecpg_store_result ( const PGresult results,
int  act_field,
const struct statement stmt,
struct variable var 
)

Definition at line 309 of file execute.c.

References variable::arrsize, statement::compat, ECPG_ARRAY_ERROR, ECPG_ARRAY_NONE, ecpg_auto_alloc(), ecpg_get_data(), ECPG_INFORMIX_SUBSELECT_NOT_ONE, ecpg_is_type_an_array(), ecpg_log(), ECPG_NO_ARRAY, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_CARDINALITY_VIOLATION, ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_TOO_MANY_MATCHES, ECPGt_char, ECPGt_string, ECPGt_unsigned_char, ECPGt_varchar, statement::force_indicator, variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, INFORMIX_MODE, ECPGtype_information_cache::isarray, statement::lineno, variable::offset, variable::pointer, PQfformat(), PQftype(), PQgetlength(), PQgetvalue(), PQntuples(), status(), variable::type, variable::value, and variable::varcharsize.

Referenced by ecpg_process_output(), and ECPGget_desc().

311 {
312  enum ARRAY_TYPE isarray;
313  int act_tuple,
314  ntuples = PQntuples(results);
315  bool status = true;
316 
317  if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
318  {
320  return false;
321  }
322 
323  if (isarray == ECPG_ARRAY_NONE)
324  {
325  /*
326  * if we don't have enough space, we cannot read all tuples
327  */
328  if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
329  {
330  ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
331  stmt->lineno, ntuples, var->arrsize);
333  return false;
334  }
335  }
336  else
337  {
338  /*
339  * since we read an array, the variable has to be an array too
340  */
341  if (var->arrsize == 0)
342  {
344  return false;
345  }
346  }
347 
348  /*
349  * allocate memory for NULL pointers
350  */
351  if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
352  {
353  int len = 0;
354 
355  if (!PQfformat(results, act_field))
356  {
357  switch (var->type)
358  {
359  case ECPGt_char:
360  case ECPGt_unsigned_char:
361  case ECPGt_string:
362  if (!var->varcharsize && !var->arrsize)
363  {
364  /* special mode for handling char**foo=0 */
365  for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
366  len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
367  len *= var->offset; /* should be 1, but YMNK */
368  len += (ntuples + 1) * sizeof(char *);
369  }
370  else
371  {
372  var->varcharsize = 0;
373  /* check strlen for each tuple */
374  for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
375  {
376  int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
377 
378  if (len > var->varcharsize)
379  var->varcharsize = len;
380  }
381  var->offset *= var->varcharsize;
382  len = var->offset * ntuples;
383  }
384  break;
385  case ECPGt_varchar:
386  len = ntuples * (var->varcharsize + sizeof(int));
387  break;
388  default:
389  len = var->offset * ntuples;
390  break;
391  }
392  }
393  else
394  {
395  for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
396  len += PQgetlength(results, act_tuple, act_field);
397  }
398 
399  ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);
400  var->value = (char *) ecpg_auto_alloc(len, stmt->lineno);
401  if (!var->value)
402  return false;
403  *((char **) var->pointer) = var->value;
404  }
405 
406  /* allocate indicator variable if needed */
407  if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer != NULL)
408  {
409  int len = var->ind_offset * ntuples;
410 
411  var->ind_value = (char *) ecpg_auto_alloc(len, stmt->lineno);
412  if (!var->ind_value)
413  return false;
414  *((char **) var->ind_pointer) = var->ind_value;
415  }
416 
417  /* fill the variable with the tuple(s) */
418  if (!var->varcharsize && !var->arrsize &&
419  (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
420  {
421  /* special mode for handling char**foo=0 */
422 
423  /* filling the array of (char*)s */
424  char **current_string = (char **) var->value;
425 
426  /* storing the data (after the last array element) */
427  char *current_data_location = (char *) &current_string[ntuples + 1];
428 
429  for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
430  {
431  int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
432 
433  if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
434  var->type, var->ind_type, current_data_location,
435  var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
436  status = false;
437  else
438  {
439  *current_string = current_data_location;
440  current_data_location += len;
441  current_string++;
442  }
443  }
444 
445  /* terminate the list */
446  *current_string = NULL;
447  }
448  else
449  {
450  for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
451  {
452  if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
453  var->type, var->ind_type, var->value,
454  var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
455  status = false;