mirror of
https://github.com/postgres/postgres.git
synced 2025-07-18 17:42:25 +03:00
Ye-old pgindent run. Same 4-space tabs.
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* B.1 Create table, insert, select
|
||||
* B.1 Create table, insert, select
|
||||
*
|
||||
* This example function creates a table, inserts data into the table,
|
||||
* and selects the inserted data.
|
||||
@ -37,135 +37,137 @@
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
|
||||
int example1(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen)
|
||||
int
|
||||
example1(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen)
|
||||
{
|
||||
SQLHENV henv;
|
||||
SQLHDBC hdbc;
|
||||
SQLHDESC hdesc;
|
||||
SQLHDESC hdesc1;
|
||||
SQLHDESC hdesc2;
|
||||
SQLHSTMT hstmt;
|
||||
SQLINTEGER id;
|
||||
SQLSMALLINT idind;
|
||||
SQLCHAR name[51];
|
||||
SQLINTEGER namelen;
|
||||
SQLSMALLINT nameind;
|
||||
SQLHENV henv;
|
||||
SQLHDBC hdbc;
|
||||
SQLHDESC hdesc;
|
||||
SQLHDESC hdesc1;
|
||||
SQLHDESC hdesc2;
|
||||
SQLHSTMT hstmt;
|
||||
SQLINTEGER id;
|
||||
SQLSMALLINT idind;
|
||||
SQLCHAR name[51];
|
||||
SQLINTEGER namelen;
|
||||
SQLSMALLINT nameind;
|
||||
|
||||
/* EXEC SQL CONNECT TO :server USER :uid; */
|
||||
/* EXEC SQL CONNECT TO :server USER :uid; */
|
||||
|
||||
/* allocate an environment handle */
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
/* allocate a connection handle */
|
||||
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
/* allocate an environment handle */
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
/* allocate a connection handle */
|
||||
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
|
||||
/* connect to database */
|
||||
if (SQLConnect(hdbc, server, SQL_NTS, uid, SQL_NTS,
|
||||
authen, SQL_NTS)
|
||||
!= SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_DBC, hdbc));
|
||||
/* connect to database */
|
||||
if (SQLConnect(hdbc, server, SQL_NTS, uid, SQL_NTS,
|
||||
authen, SQL_NTS)
|
||||
!= SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_DBC, hdbc));
|
||||
|
||||
/* allocate a statement handle */
|
||||
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
/* allocate a statement handle */
|
||||
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
|
||||
/* EXEC SQL CREATE TABLE NAMEID (ID integer, NAME varchar(50)); */
|
||||
{
|
||||
SQLCHAR create[] ="CREATE TABLE NAMEID (ID integer,"
|
||||
" NAME varchar(50))";
|
||||
/* EXEC SQL CREATE TABLE NAMEID (ID integer, NAME varchar(50)); */
|
||||
{
|
||||
SQLCHAR create[] = "CREATE TABLE NAMEID (ID integer,"
|
||||
" NAME varchar(50))";
|
||||
|
||||
/* execute the CREATE TABLE statement */
|
||||
if (SQLExecDirect(hstmt, create, SQL_NTS) != SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
/* execute the CREATE TABLE statement */
|
||||
if (SQLExecDirect(hstmt, create, SQL_NTS) != SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
/* commit CREATE TABLE */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
/* EXEC SQL INSERT INTO NAMEID VALUES ( :id, :name ); */
|
||||
{
|
||||
SQLCHAR insert[]= "INSERT INTO NAMEID VALUES (?, ?)";
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
/* commit CREATE TABLE */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
/* EXEC SQL INSERT INTO NAMEID VALUES ( :id, :name ); */
|
||||
{
|
||||
SQLCHAR insert[] = "INSERT INTO NAMEID VALUES (?, ?)";
|
||||
|
||||
/* show the use of SQLPrepare/SQLExecute method */
|
||||
/* prepare the INSERT */
|
||||
if (SQLPrepare(hstmt, insert, SQL_NTS) != SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_STMT, hstmt));
|
||||
/* application parameter descriptor */
|
||||
SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_
|
||||
DESC, &hdesc1, 0L,
|
||||
(SQLINTEGER *)NULL);
|
||||
SQLSetDescRec(hdesc1, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER)&id, (SQLINTEGER *)NULL, (SQLSMALLINT *)NULL);
|
||||
SQLSetDescRec(hdesc1, 2, SQL_CHAR, 0, 0L, 0, 0,
|
||||
(SQLPOINTER)name, (SQLINTEGER *)NULL,
|
||||
(SQLSMALLINT *)NULL);
|
||||
/* implementation parameter descriptor */
|
||||
SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_
|
||||
DESC, &hdesc2, 0L,
|
||||
(SQLINTEGER *)NULL);
|
||||
SQLSetDescRec(hdesc2, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER)NULL, (SQLINTEGER *)NULL,
|
||||
(SQLSMALLINT *)NULL);
|
||||
SQLSetDescRec(hdesc2, 2, SQL_VARCHAR, 0, 50L, 0, 0,
|
||||
(SQLPOINTER)NULL, (SQLINTEGER *)NULL,
|
||||
(SQLSMALLINT *)NULL);
|
||||
/* show the use of SQLPrepare/SQLExecute method */
|
||||
/* prepare the INSERT */
|
||||
if (SQLPrepare(hstmt, insert, SQL_NTS) != SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_STMT, hstmt));
|
||||
/* application parameter descriptor */
|
||||
SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_
|
||||
DESC, &hdesc1, 0L,
|
||||
(SQLINTEGER *) NULL);
|
||||
SQLSetDescRec(hdesc1, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER) & id, (SQLINTEGER *) NULL, (SQLSMALLINT *) NULL);
|
||||
SQLSetDescRec(hdesc1, 2, SQL_CHAR, 0, 0L, 0, 0,
|
||||
(SQLPOINTER) name, (SQLINTEGER *) NULL,
|
||||
(SQLSMALLINT *) NULL);
|
||||
/* implementation parameter descriptor */
|
||||
SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_
|
||||
DESC, &hdesc2, 0L,
|
||||
(SQLINTEGER *) NULL);
|
||||
SQLSetDescRec(hdesc2, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER) NULL, (SQLINTEGER *) NULL,
|
||||
(SQLSMALLINT *) NULL);
|
||||
SQLSetDescRec(hdesc2, 2, SQL_VARCHAR, 0, 50L, 0, 0,
|
||||
(SQLPOINTER) NULL, (SQLINTEGER *) NULL,
|
||||
(SQLSMALLINT *) NULL);
|
||||
|
||||
/* assign parameter values and execute the INSERT */
|
||||
id=500;
|
||||
(void)strcpy(name, "Babbage");
|
||||
if (SQLExecute(hstmt) != SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
/* commit inserts */
|
||||
/* assign parameter values and execute the INSERT */
|
||||
id = 500;
|
||||
(void) strcpy(name, "Babbage");
|
||||
if (SQLExecute(hstmt) != SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
/* commit inserts */
|
||||
|
||||
/* EXEC SQL DECLARE c1 CURSOR FOR SELECT ID, NAME FROM NAMEID; */
|
||||
/* EXEC SQL OPEN c1; */
|
||||
/* The application doesn't specify "declare c1 cursor for" */
|
||||
{
|
||||
SQLCHAR select[]= "select ID, NAME from NAMEID";
|
||||
if (SQLExecDirect(hstmt, select, SQL_NTS) != SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
/* EXEC SQL DECLARE c1 CURSOR FOR SELECT ID, NAME FROM NAMEID; */
|
||||
/* EXEC SQL OPEN c1; */
|
||||
/* The application doesn't specify "declare c1 cursor for" */
|
||||
{
|
||||
SQLCHAR select[] = "select ID, NAME from NAMEID";
|
||||
|
||||
/* EXEC SQL FETCH c1 INTO :id, :name; */
|
||||
/* this time, explicitly allocate an application row descriptor */
|
||||
SQLAllocHandle(SQL_HANDLE_DESC, hdbc, &hdesc);
|
||||
SQLSetDescRec(hdesc, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER)&id, (SQLINTEGER *)NULL, (SQLSMALLINT *)&idind);
|
||||
if (SQLExecDirect(hstmt, select, SQL_NTS) != SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_STMT, hstmt));
|
||||
}
|
||||
|
||||
SQLSetDescRec(hdesc, 2, SQL_
|
||||
CHAR, 0, (SQLINTEGER)sizeof(name),
|
||||
0, 0, (SQLPOINTER)&name, (SQLINTEGER *)&namelen,
|
||||
(SQLSMALLINT *)&nameind);
|
||||
/* associate descriptor with statement handle */
|
||||
SQLSetStmtAttr(hstmt, SQL_ATTR_APP_ROW_DESC, &hdesc, 0);
|
||||
/* execute the fetch */
|
||||
SQLFetch(hstmt);
|
||||
/* EXEC SQL FETCH c1 INTO :id, :name; */
|
||||
/* this time, explicitly allocate an application row descriptor */
|
||||
SQLAllocHandle(SQL_HANDLE_DESC, hdbc, &hdesc);
|
||||
SQLSetDescRec(hdesc, 1, SQL_INTEGER, 0, 0L, 0, 0,
|
||||
(SQLPOINTER) & id, (SQLINTEGER *) NULL, (SQLSMALLINT *) & idind);
|
||||
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
/* commit the transaction */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
SQLSetDescRec(hdesc, 2, SQL_
|
||||
CHAR, 0, (SQLINTEGER) sizeof(name),
|
||||
0, 0, (SQLPOINTER) & name, (SQLINTEGER *) & namelen,
|
||||
(SQLSMALLINT *) & nameind);
|
||||
/* associate descriptor with statement handle */
|
||||
SQLSetStmtAttr(hstmt, SQL_ATTR_APP_ROW_DESC, &hdesc, 0);
|
||||
/* execute the fetch */
|
||||
SQLFetch(hstmt);
|
||||
|
||||
/* EXEC SQL CLOSE c1; */
|
||||
SQLClose(hstmt);
|
||||
/* free the statement handle */
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
/* EXEC SQL COMMIT WORK; */
|
||||
/* commit the transaction */
|
||||
SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT);
|
||||
|
||||
/* EXEC SQL DISCONNECT; */
|
||||
/* disconnect from the database */
|
||||
SQLDisconnect(hdbc);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc1);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc2);
|
||||
/* free connection handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
/* free environment handle */
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
/* EXEC SQL CLOSE c1; */
|
||||
SQLClose(hstmt);
|
||||
/* free the statement handle */
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
|
||||
return(0);
|
||||
/* EXEC SQL DISCONNECT; */
|
||||
/* disconnect from the database */
|
||||
SQLDisconnect(hdbc);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc1);
|
||||
/* free descriptor handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DESC, hdesc2);
|
||||
/* free connection handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
/* free environment handle */
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* B.2 Interactive Query
|
||||
* B.2 Interactive Query
|
||||
*
|
||||
* This sample function uses the concise CLI functions to
|
||||
* interactively execute a SQL statement supplied as an argument.
|
||||
@ -38,158 +38,163 @@
|
||||
|
||||
#define max(a,b) (a>b?a:b)
|
||||
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
int build_indicator_message(SQLCHAR *errmsg,
|
||||
SQLPOINTER *data,
|
||||
SQLINTEGER collen,
|
||||
SQLINTEGER *outlen,
|
||||
SQLSMALLINT colnum);
|
||||
int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
|
||||
int build_indicator_message(SQLCHAR * errmsg,
|
||||
SQLPOINTER * data,
|
||||
SQLINTEGER collen,
|
||||
SQLINTEGER * outlen,
|
||||
SQLSMALLINT colnum);
|
||||
|
||||
SQLINTEGER display_length(SQLSMALLINT coltype,
|
||||
SQLINTEGER collen,
|
||||
SQLCHAR *colname);
|
||||
SQLINTEGER collen,
|
||||
SQLCHAR * colname);
|
||||
|
||||
example2(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen, SQLCHAR *sqlstr)
|
||||
example2(SQLCHAR * server, SQLCHAR * uid, SQLCHAR * authen, SQLCHAR * sqlstr)
|
||||
{
|
||||
int i;
|
||||
SQLHENV henv;
|
||||
SQLHDBC hdbc;
|
||||
SQLHSTMT hstmt;
|
||||
SQLCHAR errmsg[256];
|
||||
SQLCHAR colname[32];
|
||||
SQLSMALLINT coltype;
|
||||
SQLSMALLINT colnamelen;
|
||||
SQLSMALLINT nullable;
|
||||
SQLINTEGER collen[MAXCOLS];
|
||||
SQLSMALLINT scale;
|
||||
SQLINTEGER outlen[MAXCOLS];
|
||||
SQLCHAR *data[MAXCOLS];
|
||||
SQLSMALLINT nresultcols;
|
||||
SQLINTEGER rowcount;
|
||||
SQLINTEGER stmttype;
|
||||
SQLRETURN rc;
|
||||
int i;
|
||||
SQLHENV henv;
|
||||
SQLHDBC hdbc;
|
||||
SQLHSTMT hstmt;
|
||||
SQLCHAR errmsg[256];
|
||||
SQLCHAR colname[32];
|
||||
SQLSMALLINT coltype;
|
||||
SQLSMALLINT colnamelen;
|
||||
SQLSMALLINT nullable;
|
||||
SQLINTEGER collen[MAXCOLS];
|
||||
SQLSMALLINT scale;
|
||||
SQLINTEGER outlen[MAXCOLS];
|
||||
SQLCHAR *data[MAXCOLS];
|
||||
SQLSMALLINT nresultcols;
|
||||
SQLINTEGER rowcount;
|
||||
SQLINTEGER stmttype;
|
||||
SQLRETURN rc;
|
||||
|
||||
/* allocate an environment handle */
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
/* allocate an environment handle */
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
|
||||
/* allocate a connection handle */
|
||||
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
/* allocate a connection handle */
|
||||
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
|
||||
/* connect to database */
|
||||
if (SQLConnect(hdbc, server, SQL_NTS, uid, SQL_NTS, authen, SQL_NTS)
|
||||
!= SQL_SUCCESS )
|
||||
return(print_err(SQL_HANDLE_DBC, hdbc));
|
||||
/* connect to database */
|
||||
if (SQLConnect(hdbc, server, SQL_NTS, uid, SQL_NTS, authen, SQL_NTS)
|
||||
!= SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_DBC, hdbc));
|
||||
|
||||
/* allocate a statement handle */
|
||||
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
/* allocate a statement handle */
|
||||
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
|
||||
/* execute the SQL statement */
|
||||
if (SQLExecDirect(hstmt, sqlstr, SQL_NTS) != SQL_SUCCESS)
|
||||
return(print_err(SQL_HANDLE_STMT, hstmt));
|
||||
/* execute the SQL statement */
|
||||
if (SQLExecDirect(hstmt, sqlstr, SQL_NTS) != SQL_SUCCESS)
|
||||
return (print_err(SQL_HANDLE_STMT, hstmt));
|
||||
|
||||
/* see what kind of statement it was */
|
||||
SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
|
||||
SQL_DIAG_DYNAMIC_FUNCTION_CODE,
|
||||
(SQLPOINTER)&stmttype, 0, (SQLSMALLINT *)NULL);
|
||||
/* see what kind of statement it was */
|
||||
SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
|
||||
SQL_DIAG_DYNAMIC_FUNCTION_CODE,
|
||||
(SQLPOINTER) & stmttype, 0, (SQLSMALLINT *) NULL);
|
||||
|
||||
switch (stmttype) {
|
||||
/* SELECT statement */
|
||||
case SQL_SELECT_CURSOR:
|
||||
/* determine number of result columns */
|
||||
SQLNumResultCols(hstmt, &nresultcols);
|
||||
/* display column names */
|
||||
for (i=0; i<nresultcols; i++) {
|
||||
SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
|
||||
&colnamelen, &coltype, &collen[i], &scale, &nullable);
|
||||
switch (stmttype)
|
||||
{
|
||||
/* SELECT statement */
|
||||
case SQL_SELECT_CURSOR:
|
||||
/* determine number of result columns */
|
||||
SQLNumResultCols(hstmt, &nresultcols);
|
||||
/* display column names */
|
||||
for (i = 0; i < nresultcols; i++)
|
||||
{
|
||||
SQLDescribeCol(hstmt, i + 1, colname, sizeof(colname),
|
||||
&colnamelen, &coltype, &collen[i], &scale, &nullable);
|
||||
|
||||
/* assume there is a display_length function which
|
||||
computes correct length given the data type */
|
||||
collen[i] = display_length(coltype, collen[i], colname);
|
||||
(void)printf("%*.*s", collen[i], collen[i], colname);
|
||||
/* allocate memory to bind column */
|
||||
data[i] = (SQLCHAR *) malloc(collen[i]);
|
||||
/*
|
||||
* assume there is a display_length function which
|
||||
* computes correct length given the data type
|
||||
*/
|
||||
collen[i] = display_length(coltype, collen[i], colname);
|
||||
(void) printf("%*.*s", collen[i], collen[i], colname);
|
||||
/* allocate memory to bind column */
|
||||
data[i] = (SQLCHAR *) malloc(collen[i]);
|
||||
|
||||
/* bind columns to program vars, converting all types to CHAR */
|
||||
SQLBindCol(hstmt, i+1, SQL_CHAR, data[i], collen[i],
|
||||
&outlen[i]);
|
||||
}
|
||||
/* display result rows */
|
||||
while ((rc=SQLFetch(hstmt))!=SQL_ERROR) {
|
||||
errmsg[0] = '\0';
|
||||
if (rc == SQL_SUCCESS_WITH_INFO) {
|
||||
for (i=0; i<nresultcols; i++) {
|
||||
if (outlen[i] == SQL_NULL_DATA || outlen[i] >= collen[i])
|
||||
build_indicator_message(errmsg,
|
||||
(SQLPOINTER *)&data[i], collen[i],
|
||||
&outlen[i], i);
|
||||
(void)printf("%*.*s ", outlen[i], outlen[i],
|
||||
data[i]);
|
||||
} /* for all columns in this row */
|
||||
/* print any truncation messages */
|
||||
(void)printf("\n%s", errmsg);
|
||||
}
|
||||
} /* while rows to fetch */
|
||||
SQLClose(hstmt);
|
||||
break;
|
||||
/*
|
||||
* bind columns to program vars, converting all types to
|
||||
* CHAR
|
||||
*/
|
||||
SQLBindCol(hstmt, i + 1, SQL_CHAR, data[i], collen[i],
|
||||
&outlen[i]);
|
||||
}
|
||||
/* display result rows */
|
||||
while ((rc = SQLFetch(hstmt)) != SQL_ERROR)
|
||||
{
|
||||
errmsg[0] = '\0';
|
||||
if (rc == SQL_SUCCESS_WITH_INFO)
|
||||
{
|
||||
for (i = 0; i < nresultcols; i++)
|
||||
{
|
||||
if (outlen[i] == SQL_NULL_DATA || outlen[i] >= collen[i])
|
||||
build_indicator_message(errmsg,
|
||||
(SQLPOINTER *) & data[i], collen[i],
|
||||
&outlen[i], i);
|
||||
(void) printf("%*.*s ", outlen[i], outlen[i],
|
||||
data[i]);
|
||||
} /* for all columns in this row */
|
||||
/* print any truncation messages */
|
||||
(void) printf("\n%s", errmsg);
|
||||
}
|
||||
} /* while rows to fetch */
|
||||
SQLClose(hstmt);
|
||||
break;
|
||||
|
||||
/* searched DELETE, INSERT or searched UPDATE statement */
|
||||
case SQL_DELETE_WHERE:
|
||||
case SQL_INSERT:
|
||||
case SQL_UPDATE_WHERE:
|
||||
/* check rowcount */
|
||||
SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
|
||||
SQL_DIAG_ROW_COUNT, (SQLPOINTER)&rowcount, 0,
|
||||
(SQLSMALLINT *)NULL);
|
||||
if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
|
||||
== SQL_SUCCESS) {
|
||||
(void) printf("Operation successful\n");
|
||||
}
|
||||
else {
|
||||
(void) printf("Operation failed\n");
|
||||
}
|
||||
(void)printf("%ld rows affected\n", rowcount);
|
||||
break;
|
||||
/* searched DELETE, INSERT or searched UPDATE statement */
|
||||
case SQL_DELETE_WHERE:
|
||||
case SQL_INSERT:
|
||||
case SQL_UPDATE_WHERE:
|
||||
/* check rowcount */
|
||||
SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
|
||||
SQL_DIAG_ROW_COUNT, (SQLPOINTER) & rowcount, 0,
|
||||
(SQLSMALLINT *) NULL);
|
||||
if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
|
||||
== SQL_SUCCESS)
|
||||
(void) printf("Operation successful\n");
|
||||
else
|
||||
(void) printf("Operation failed\n");
|
||||
(void) printf("%ld rows affected\n", rowcount);
|
||||
break;
|
||||
|
||||
/* other statements */
|
||||
case SQL_ALTER_TABLE:
|
||||
case SQL_CREATE_TABLE:
|
||||
case SQL_CREATE_VIEW:
|
||||
case SQL_DROP_TABLE:
|
||||
case SQL_DROP_VIEW:
|
||||
case SQL_DYNAMIC_DELETE_CURSOR:
|
||||
case SQL_DYNAMIC_UPDATE_CURSOR:
|
||||
case SQL_GRANT:
|
||||
case SQL_REVOKE:
|
||||
if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
|
||||
== SQL_SUCCESS) {
|
||||
(void) printf("Operation successful\n");
|
||||
}
|
||||
else {
|
||||
(void) printf("Operation failed\n");
|
||||
}
|
||||
break;
|
||||
/* other statements */
|
||||
case SQL_ALTER_TABLE:
|
||||
case SQL_CREATE_TABLE:
|
||||
case SQL_CREATE_VIEW:
|
||||
case SQL_DROP_TABLE:
|
||||
case SQL_DROP_VIEW:
|
||||
case SQL_DYNAMIC_DELETE_CURSOR:
|
||||
case SQL_DYNAMIC_UPDATE_CURSOR:
|
||||
case SQL_GRANT:
|
||||
case SQL_REVOKE:
|
||||
if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
|
||||
== SQL_SUCCESS)
|
||||
(void) printf("Operation successful\n");
|
||||
else
|
||||
(void) printf("Operation failed\n");
|
||||
break;
|
||||
|
||||
/* implementation-defined statement */
|
||||
default:
|
||||
(void)printf("Statement type=%ld\n", stmttype);
|
||||
break;
|
||||
}
|
||||
/* implementation-defined statement */
|
||||
default:
|
||||
(void) printf("Statement type=%ld\n", stmttype);
|
||||
break;
|
||||
}
|
||||
|
||||
/* free data buffers */
|
||||
for (i=0; i<nresultcols; i++) {
|
||||
(void)free(data[i]);
|
||||
}
|
||||
/* free data buffers */
|
||||
for (i = 0; i < nresultcols; i++)
|
||||
(void) free(data[i]);
|
||||
|
||||
/* free statement handle */
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
/* disconnect from database */
|
||||
SQLDisconnect(hdbc);
|
||||
/* free connection handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
/* free environment handle */
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
/* free statement handle */
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
/* disconnect from database */
|
||||
SQLDisconnect(hdbc);
|
||||
/* free connection handle */
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
/* free environment handle */
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
@ -202,59 +207,64 @@ example2(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen, SQLCHAR *sqlstr)
|
||||
/*#define max length of char string representation of no. as:
|
||||
|
||||
= max(precision) + leading sign + E + exp sign + max exp length
|
||||
= 15 + 1 + 1 + 1 + 2
|
||||
= 15 + 1 + 1 + 1 + 2
|
||||
= 15 + 5
|
||||
*/
|
||||
#define MAX_NUM_STRING_SIZE (MAX_NUM_PRECISION + 5)
|
||||
|
||||
SQLINTEGER display_length(SQLSMALLINT coltype, SQLINTEGER collen,
|
||||
SQLCHAR *colname)
|
||||
SQLINTEGER
|
||||
display_length(SQLSMALLINT coltype, SQLINTEGER collen,
|
||||
SQLCHAR * colname)
|
||||
{
|
||||
switch (coltype) {
|
||||
switch (coltype)
|
||||
{
|
||||
|
||||
case SQL_VARCHAR:
|
||||
case SQL_CHAR:
|
||||
return(max(collen,strlen((char *)colname)));
|
||||
break;
|
||||
case SQL_VARCHAR:
|
||||
case SQL_CHAR:
|
||||
return (max(collen, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
case SQL_FLOAT:
|
||||
case SQL_DOUBLE:
|
||||
case SQL_NUMERIC:
|
||||
case SQL_REAL:
|
||||
case SQL_DECIMAL:
|
||||
return(max(MAX_NUM_STRING_SIZE,strlen((char *)colname)));
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
case SQL_DOUBLE:
|
||||
case SQL_NUMERIC:
|
||||
case SQL_REAL:
|
||||
case SQL_DECIMAL:
|
||||
return (max(MAX_NUM_STRING_SIZE, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
case SQL_DATETIME:
|
||||
return(max(SQL_TIMESTAMP_LEN,strlen((char *)colname)));
|
||||
break;
|
||||
case SQL_DATETIME:
|
||||
return (max(SQL_TIMESTAMP_LEN, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
case SQL_INTEGER:
|
||||
return(max(10,strlen((char *)colname)));
|
||||
break;
|
||||
case SQL_INTEGER:
|
||||
return (max(10, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
case SQL_SMALLINT:
|
||||
return(max(5,strlen((char *)colname)));
|
||||
break;
|
||||
case SQL_SMALLINT:
|
||||
return (max(5, strlen((char *) colname)));
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)printf("Unknown datatype, %d\n", coltype);
|
||||
return(0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
(void) printf("Unknown datatype, %d\n", coltype);
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int build_indicator_message(SQLCHAR *errmsg, SQLPOINTER *data,
|
||||
SQLINTEGER collen, SQLINTEGER *outlen, SQLSMALLINT colnum)
|
||||
int
|
||||
build_indicator_message(SQLCHAR * errmsg, SQLPOINTER * data,
|
||||
SQLINTEGER collen, SQLINTEGER * outlen, SQLSMALLINT colnum)
|
||||
{
|
||||
if (*outlen == SQL_NULL_DATA) {
|
||||
(void)strcpy((char *)data, "NULL");
|
||||
*outlen=4;
|
||||
}
|
||||
else {
|
||||
sprintf((char *)errmsg+strlen((char *)errmsg),
|
||||
"%d chars truncated, col %d\n", *outlen-collen+1,
|
||||
colnum);
|
||||
*outlen=255;
|
||||
}
|
||||
if (*outlen == SQL_NULL_DATA)
|
||||
{
|
||||
(void) strcpy((char *) data, "NULL");
|
||||
*outlen = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf((char *) errmsg + strlen((char *) errmsg),
|
||||
"%d chars truncated, col %d\n", *outlen - collen + 1,
|
||||
colnum);
|
||||
*outlen = 255;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
|
||||
/* first we have a set of ecpg messages, they start at 200 */
|
||||
#define ECPG_UNSUPPORTED -200
|
||||
#define ECPG_TOO_MANY_ARGUMENTS -201
|
||||
#define ECPG_TOO_MANY_ARGUMENTS -201
|
||||
#define ECPG_TOO_FEW_ARGUMENTS -202
|
||||
#define ECPG_TOO_MANY_MATCHES -203
|
||||
#define ECPG_INT_FORMAT -204
|
||||
|
@ -17,27 +17,27 @@ extern "C"
|
||||
bool ECPGprepare(int, char *, char *);
|
||||
bool ECPGdeallocate(int, char *);
|
||||
bool ECPGdeallocate_all(int);
|
||||
char *ECPGprepared_statement(char *);
|
||||
|
||||
char *ECPGprepared_statement(char *);
|
||||
|
||||
void ECPGlog(const char *format,...);
|
||||
|
||||
|
||||
/* print an error message */
|
||||
void sqlprint(void);
|
||||
|
||||
|
||||
/* define this for simplicity as well as compatibility */
|
||||
|
||||
#define SQLCODE sqlca.sqlcode
|
||||
|
||||
/* dynamic SQL */
|
||||
|
||||
bool ECPGdo_descriptor(int line,const char *connection,
|
||||
const char *descriptor,const char *query);
|
||||
bool ECPGdeallocate_desc(int line,const char *name);
|
||||
bool ECPGallocate_desc(int line,const char *name);
|
||||
bool ECPGdo_descriptor(int line, const char *connection,
|
||||
const char *descriptor, const char *query);
|
||||
bool ECPGdeallocate_desc(int line, const char *name);
|
||||
bool ECPGallocate_desc(int line, const char *name);
|
||||
void ECPGraise(int line, int code, char *str);
|
||||
bool ECPGget_desc_header(int, char *, int *);
|
||||
bool ECPGget_desc(int, char *, int, ...);
|
||||
|
||||
bool ECPGget_desc(int, char *, int,...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ extern "C"
|
||||
ECPGt_NO_INDICATOR /* no indicator */
|
||||
};
|
||||
|
||||
/* descriptor items */
|
||||
/* descriptor items */
|
||||
enum ECPGdtype
|
||||
{
|
||||
ECPGd_count,
|
||||
|
@ -2,12 +2,14 @@
|
||||
*
|
||||
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.3 2000/03/17 23:26:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/include/sql3types.h,v 1.4 2000/04/12 17:17:01 momjian Exp $
|
||||
*/
|
||||
|
||||
/* chapter 13.1 table 2: Codes used for SQL data types in Dynamic SQL */
|
||||
|
||||
enum { SQL3_CHARACTER=1,
|
||||
enum
|
||||
{
|
||||
SQL3_CHARACTER = 1,
|
||||
SQL3_NUMERIC,
|
||||
SQL3_DECIMAL,
|
||||
SQL3_INTEGER,
|
||||
@ -16,23 +18,26 @@ enum { SQL3_CHARACTER=1,
|
||||
SQL3_REAL,
|
||||
SQL3_DOUBLE_PRECISION,
|
||||
SQL3_DATE_TIME_TIMESTAMP,
|
||||
SQL3_INTERVAL, /* 10 */
|
||||
SQL3_CHARACTER_VARYING=12,
|
||||
SQL3_INTERVAL, /* 10 */
|
||||
SQL3_CHARACTER_VARYING = 12,
|
||||
SQL3_ENUMERATED,
|
||||
SQL3_BIT,
|
||||
SQL3_BIT_VARYING,
|
||||
SQL3_BOOLEAN,
|
||||
SQL3_abstract
|
||||
/* the rest is xLOB stuff */
|
||||
};
|
||||
};
|
||||
|
||||
/* chapter 13.1 table 3: Codes associated with datetime data types in Dynamic SQL */
|
||||
|
||||
enum { SQL3_DDT_DATE=1,
|
||||
enum
|
||||
{
|
||||
SQL3_DDT_DATE = 1,
|
||||
SQL3_DDT_TIME,
|
||||
SQL3_DDT_TIMESTAMP,
|
||||
SQL3_DDT_TIME_WITH_TIME_ZONE,
|
||||
SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE,
|
||||
|
||||
SQL3_DDT_ILLEGAL /* not a datetime data type (not part of standard) */
|
||||
};
|
||||
|
||||
SQL3_DDT_ILLEGAL /* not a datetime data type (not part of
|
||||
* standard) */
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ extern "C"
|
||||
char sqlerrp[8];
|
||||
long sqlerrd[6];
|
||||
/* Element 0: empty */
|
||||
/* 1: OID of processed tuple if applicable */
|
||||
/* 1: OID of processed tuple if applicable */
|
||||
/* 2: number of rows processed */
|
||||
/* after an INSERT, UPDATE or */
|
||||
/* DELETE statement */
|
||||
@ -48,6 +48,7 @@ extern "C"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include "extern.h"
|
||||
#include <sqlca.h>
|
||||
|
||||
static struct connection *all_connections = NULL, *actual_connection = NULL;
|
||||
static struct connection *all_connections = NULL,
|
||||
*actual_connection = NULL;
|
||||
|
||||
struct connection *
|
||||
get_connection(const char *connection_name)
|
||||
@ -58,10 +59,10 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
|
||||
PGresult *results;
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
return(false);
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGsetcommit line %d action = %s connection = %s\n", lineno, mode, con->name);
|
||||
|
||||
|
||||
if (con->autocommit == true && strncmp(mode, "off", strlen("off")) == 0)
|
||||
{
|
||||
if (con->committed)
|
||||
@ -100,7 +101,7 @@ ECPGsetconn(int lineno, const char *connection_name)
|
||||
struct connection *con = get_connection(connection_name);
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
return(false);
|
||||
return (false);
|
||||
|
||||
actual_connection = con;
|
||||
return true;
|
||||
@ -112,7 +113,7 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
|
||||
struct connection *this;
|
||||
|
||||
init_sqlca();
|
||||
|
||||
|
||||
if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
|
||||
return false;
|
||||
|
||||
@ -171,7 +172,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
|
||||
con = get_connection(connection_name);
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
return(false);
|
||||
return (false);
|
||||
else
|
||||
ecpg_finish(con);
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
|
||||
bool
|
||||
get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
enum ECPGttype type, enum ECPGttype ind_type,
|
||||
void *var, void *ind, long varcharsize, long offset,
|
||||
bool isarray)
|
||||
enum ECPGttype type, enum ECPGttype ind_type,
|
||||
void *var, void *ind, long varcharsize, long offset,
|
||||
bool isarray)
|
||||
{
|
||||
char *pval = (char *)PQgetvalue(results, act_tuple, act_field);
|
||||
char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
|
||||
|
||||
ECPGlog("get_data line %d: RESULT: %s\n", lineno, pval ? pval : "");
|
||||
|
||||
@ -20,20 +20,20 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
/* let's check is it really is an array if it should be */
|
||||
if (isarray)
|
||||
{
|
||||
if (*pval != '{')
|
||||
if (*pval != '{')
|
||||
{
|
||||
ECPGlog("get_data data entry does not look like an array in line %d\n", lineno);
|
||||
ECPGraise(lineno, ECPG_DATA_NOT_ARRAY, NULL);
|
||||
return(false);
|
||||
return (false);
|
||||
}
|
||||
else ++pval;
|
||||
else
|
||||
++pval;
|
||||
}
|
||||
|
||||
/* We will have to decode the value */
|
||||
|
||||
/*
|
||||
* check for null value and set indicator
|
||||
* accordingly
|
||||
* check for null value and set indicator accordingly
|
||||
*/
|
||||
switch (ind_type)
|
||||
{
|
||||
@ -61,226 +61,226 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno,
|
||||
return (false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
long res;
|
||||
unsigned long ures;
|
||||
double dres;
|
||||
char *scan_length;
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
long res;
|
||||
unsigned long ures;
|
||||
double dres;
|
||||
char *scan_length;
|
||||
|
||||
case ECPGt_short:
|
||||
case ECPGt_int:
|
||||
case ECPGt_long:
|
||||
if (pval)
|
||||
{
|
||||
res = strtol(pval, &scan_length, 10);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
case ECPGt_short:
|
||||
case ECPGt_int:
|
||||
case ECPGt_long:
|
||||
if (pval)
|
||||
{
|
||||
ECPGraise(lineno, ECPG_INT_FORMAT, pval);
|
||||
return (false);
|
||||
res = 0L;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = 0L;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_short:
|
||||
((short *) var)[act_tuple] = (short) res;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
((int *) var)[act_tuple] = (int) res;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
((long *) var)[act_tuple] = res;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ECPGt_unsigned_short:
|
||||
case ECPGt_unsigned_int:
|
||||
case ECPGt_unsigned_long:
|
||||
if (pval)
|
||||
{
|
||||
ures = strtoul(pval, &scan_length, 10);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
|
||||
return (false);
|
||||
ures = 0L;
|
||||
}
|
||||
}
|
||||
else
|
||||
ures = 0L;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_unsigned_short:
|
||||
((unsigned short *) var)[act_tuple] = (unsigned short) ures;
|
||||
break;
|
||||
case ECPGt_unsigned_int:
|
||||
((unsigned int *) var)[act_tuple] = (unsigned int) ures;
|
||||
break;
|
||||
case ECPGt_unsigned_long:
|
||||
((unsigned long *) var)[act_tuple] = ures;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ECPGt_float:
|
||||
case ECPGt_double:
|
||||
if (pval)
|
||||
{
|
||||
dres = strtod(pval, &scan_length);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval);
|
||||
return (false);
|
||||
dres = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
dres = 0.0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_float:
|
||||
((float *) var)[act_tuple] = dres;
|
||||
break;
|
||||
case ECPGt_double:
|
||||
((double *) var)[act_tuple] = dres;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ECPGt_bool:
|
||||
if (pval)
|
||||
{
|
||||
if (pval[0] == 'f' && pval[1] == '\0')
|
||||
{
|
||||
((char *) var)[act_tuple] = false;
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == 't' && pval[1] == '\0')
|
||||
{
|
||||
((char *) var)[act_tuple] = true;
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
|
||||
{
|
||||
/* NULL is valid */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ECPGraise(lineno, ECPG_CONVERT_BOOL, pval);
|
||||
return (false);
|
||||
break;
|
||||
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
{
|
||||
strncpy((char *) ((long) var + offset * act_tuple), pval, varcharsize);
|
||||
if (varcharsize && varcharsize < strlen(pval))
|
||||
{
|
||||
/* truncation */
|
||||
switch (ind_type)
|
||||
res = strtol(pval, &scan_length, 10);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_unsigned_short:
|
||||
((short *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
case ECPGt_unsigned_int:
|
||||
((int *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
case ECPGt_unsigned_long:
|
||||
((long *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
ECPGraise(lineno, ECPG_INT_FORMAT, pval);
|
||||
return (false);
|
||||
res = 0L;
|
||||
}
|
||||
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ECPGt_varchar:
|
||||
{
|
||||
struct ECPGgeneric_varchar *variable =
|
||||
(struct ECPGgeneric_varchar *) ((long) var + offset * act_tuple);
|
||||
|
||||
if (varcharsize == 0)
|
||||
strncpy(variable->arr, pval, strlen(pval));
|
||||
else
|
||||
strncpy(variable->arr, pval, varcharsize);
|
||||
res = 0L;
|
||||
|
||||
variable->len = strlen(pval);
|
||||
if (varcharsize > 0 && variable->len > varcharsize)
|
||||
switch (type)
|
||||
{
|
||||
/* truncation */
|
||||
switch (ind_type)
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_unsigned_short:
|
||||
((short *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
case ECPGt_unsigned_int:
|
||||
((int *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
case ECPGt_unsigned_long:
|
||||
((long *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
||||
|
||||
variable->len = varcharsize;
|
||||
case ECPGt_short:
|
||||
((short *) var)[act_tuple] = (short) res;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
((int *) var)[act_tuple] = (int) res;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
((long *) var)[act_tuple] = res;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(type));
|
||||
return (false);
|
||||
break;
|
||||
}
|
||||
if (isarray)
|
||||
{
|
||||
bool string = false;
|
||||
|
||||
/* set array to next entry */
|
||||
++act_tuple;
|
||||
|
||||
/* set pval to the next entry */
|
||||
for (; string || (*pval != ',' && *pval != '}'); ++pval)
|
||||
if (*pval == '"')
|
||||
string = string ? false : true;
|
||||
|
||||
if (*pval == ',')
|
||||
++pval;
|
||||
}
|
||||
case ECPGt_unsigned_short:
|
||||
case ECPGt_unsigned_int:
|
||||
case ECPGt_unsigned_long:
|
||||
if (pval)
|
||||
{
|
||||
ures = strtoul(pval, &scan_length, 10);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
|
||||
return (false);
|
||||
ures = 0L;
|
||||
}
|
||||
}
|
||||
else
|
||||
ures = 0L;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_unsigned_short:
|
||||
((unsigned short *) var)[act_tuple] = (unsigned short) ures;
|
||||
break;
|
||||
case ECPGt_unsigned_int:
|
||||
((unsigned int *) var)[act_tuple] = (unsigned int) ures;
|
||||
break;
|
||||
case ECPGt_unsigned_long:
|
||||
((unsigned long *) var)[act_tuple] = ures;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ECPGt_float:
|
||||
case ECPGt_double:
|
||||
if (pval)
|
||||
{
|
||||
dres = strtod(pval, &scan_length);
|
||||
if ((isarray && *scan_length != ',' && *scan_length != '}')
|
||||
|| (!isarray && *scan_length != '\0')) /* Garbage left */
|
||||
{
|
||||
ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval);
|
||||
return (false);
|
||||
dres = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
dres = 0.0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECPGt_float:
|
||||
((float *) var)[act_tuple] = dres;
|
||||
break;
|
||||
case ECPGt_double:
|
||||
((double *) var)[act_tuple] = dres;
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ECPGt_bool:
|
||||
if (pval)
|
||||
{
|
||||
if (pval[0] == 'f' && pval[1] == '\0')
|
||||
{
|
||||
((char *) var)[act_tuple] = false;
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == 't' && pval[1] == '\0')
|
||||
{
|
||||
((char *) var)[act_tuple] = true;
|
||||
break;
|
||||
}
|
||||
else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
|
||||
{
|
||||
/* NULL is valid */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ECPGraise(lineno, ECPG_CONVERT_BOOL, pval);
|
||||
return (false);
|
||||
break;
|
||||
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
{
|
||||
strncpy((char *) ((long) var + offset * act_tuple), pval, varcharsize);
|
||||
if (varcharsize && varcharsize < strlen(pval))
|
||||
{
|
||||
/* truncation */
|
||||
switch (ind_type)
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_unsigned_short:
|
||||
((short *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
case ECPGt_unsigned_int:
|
||||
((int *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
case ECPGt_unsigned_long:
|
||||
((long *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ECPGt_varchar:
|
||||
{
|
||||
struct ECPGgeneric_varchar *variable =
|
||||
(struct ECPGgeneric_varchar *) ((long) var + offset * act_tuple);
|
||||
|
||||
if (varcharsize == 0)
|
||||
strncpy(variable->arr, pval, strlen(pval));
|
||||
else
|
||||
strncpy(variable->arr, pval, varcharsize);
|
||||
|
||||
variable->len = strlen(pval);
|
||||
if (varcharsize > 0 && variable->len > varcharsize)
|
||||
{
|
||||
/* truncation */
|
||||
switch (ind_type)
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_unsigned_short:
|
||||
((short *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
case ECPGt_unsigned_int:
|
||||
((int *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
case ECPGt_unsigned_long:
|
||||
((long *) ind)[act_tuple] = varcharsize;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W';
|
||||
|
||||
variable->len = varcharsize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(type));
|
||||
return (false);
|
||||
break;
|
||||
}
|
||||
if (isarray)
|
||||
{
|
||||
bool string = false;
|
||||
|
||||
/* set array to next entry */
|
||||
++act_tuple;
|
||||
|
||||
/* set pval to the next entry */
|
||||
for (; string || (*pval != ',' && *pval != '}'); ++pval)
|
||||
if (*pval == '"')
|
||||
string = string ? false : true;
|
||||
|
||||
if (*pval == ',')
|
||||
++pval;
|
||||
}
|
||||
} while (isarray && *pval != '}');
|
||||
|
||||
return (true);
|
||||
|
@ -6,265 +6,270 @@
|
||||
|
||||
struct descriptor
|
||||
{
|
||||
char *name;
|
||||
PGresult *result;
|
||||
struct descriptor *next;
|
||||
} *all_descriptors = NULL;
|
||||
|
||||
char *name;
|
||||
PGresult *result;
|
||||
struct descriptor *next;
|
||||
} *all_descriptors = NULL;
|
||||
|
||||
static PGresult
|
||||
*ECPGresultByDescriptor(int line,const char *name)
|
||||
*
|
||||
ECPGresultByDescriptor(int line, const char *name)
|
||||
{
|
||||
struct descriptor *i;
|
||||
|
||||
|
||||
for (i = all_descriptors; i != NULL; i = i->next)
|
||||
{
|
||||
if (!strcmp(name, i->name)) return i->result;
|
||||
if (!strcmp(name, i->name))
|
||||
return i->result;
|
||||
}
|
||||
|
||||
|
||||
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ECPGDynamicType_DDT(Oid type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 1082: return SQL3_DDT_DATE; /* date */
|
||||
case 1083: return SQL3_DDT_TIME; /* time */
|
||||
case 1184: return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* datetime */
|
||||
case 1296: return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* timestamp */
|
||||
switch (type)
|
||||
{
|
||||
case 1082:return SQL3_DDT_DATE; /* date */
|
||||
case 1083:
|
||||
return SQL3_DDT_TIME; /* time */
|
||||
case 1184:
|
||||
return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* datetime */
|
||||
case 1296:
|
||||
return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* timestamp */
|
||||
default:
|
||||
return SQL3_DDT_ILLEGAL;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ECPGget_desc_header(int lineno, char * desc_name, int *count)
|
||||
ECPGget_desc_header(int lineno, char *desc_name, int *count)
|
||||
{
|
||||
PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
|
||||
|
||||
PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
|
||||
|
||||
if (!ECPGresult)
|
||||
return false;
|
||||
|
||||
*count = PQnfields(ECPGresult);
|
||||
ECPGlog("ECPGget_desc_header: found %d attributes.\n", *count);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
get_int_item(int lineno, void *var, enum ECPGdtype vartype, int value)
|
||||
{
|
||||
switch (vartype)
|
||||
{
|
||||
case ECPGt_short:
|
||||
*(short *)var = value;
|
||||
break;
|
||||
{
|
||||
case ECPGt_short:
|
||||
*(short *) var = value;
|
||||
break;
|
||||
case ECPGt_int:
|
||||
*(int *)var = value;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
*(long *)var = value;
|
||||
break;
|
||||
case ECPGt_unsigned_short:
|
||||
*(unsigned short *)var = value;
|
||||
break;
|
||||
*(int *) var = value;
|
||||
break;
|
||||
case ECPGt_long:
|
||||
*(long *) var = value;
|
||||
break;
|
||||
case ECPGt_unsigned_short:
|
||||
*(unsigned short *) var = value;
|
||||
break;
|
||||
case ECPGt_unsigned_int:
|
||||
*(unsigned int *)var = value;
|
||||
break;
|
||||
case ECPGt_unsigned_long:
|
||||
*(unsigned long *)var = value;
|
||||
break;
|
||||
case ECPGt_float:
|
||||
*(float *)var = value;
|
||||
break;
|
||||
case ECPGt_double:
|
||||
*(double *)var = value;
|
||||
break;
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, NULL);
|
||||
return (false);
|
||||
*(unsigned int *) var = value;
|
||||
break;
|
||||
case ECPGt_unsigned_long:
|
||||
*(unsigned long *) var = value;
|
||||
break;
|
||||
case ECPGt_float:
|
||||
*(float *) var = value;
|
||||
break;
|
||||
case ECPGt_double:
|
||||
*(double *) var = value;
|
||||
break;
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static bool
|
||||
get_char_item(int lineno, void *var, enum ECPGdtype vartype, char *value, int varcharsize)
|
||||
{
|
||||
switch (vartype)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
strncpy((char *) var, value, varcharsize);
|
||||
break;
|
||||
case ECPGt_varchar:
|
||||
{
|
||||
struct ECPGgeneric_varchar *variable =
|
||||
(struct ECPGgeneric_varchar *) var;
|
||||
|
||||
if (varcharsize == 0)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
strncpy((char *) var, value, varcharsize);
|
||||
break;
|
||||
case ECPGt_varchar:
|
||||
{
|
||||
struct ECPGgeneric_varchar *variable =
|
||||
(struct ECPGgeneric_varchar *) var;
|
||||
|
||||
if (varcharsize == 0)
|
||||
strncpy(variable->arr, value, strlen(value));
|
||||
else
|
||||
strncpy(variable->arr, value, varcharsize);
|
||||
|
||||
variable->len = strlen(value);
|
||||
if (varcharsize > 0 && variable->len > varcharsize)
|
||||
variable->len = varcharsize;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_VAR_NOT_CHAR, NULL);
|
||||
return (false);
|
||||
else
|
||||
strncpy(variable->arr, value, varcharsize);
|
||||
|
||||
variable->len = strlen(value);
|
||||
if (varcharsize > 0 && variable->len > varcharsize)
|
||||
variable->len = varcharsize;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ECPGraise(lineno, ECPG_VAR_NOT_CHAR, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
ECPGget_desc(int lineno, char *desc_name, int index, ...)
|
||||
ECPGget_desc(int lineno, char *desc_name, int index,...)
|
||||
{
|
||||
va_list args;
|
||||
PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
|
||||
enum ECPGdtype type;
|
||||
va_list args;
|
||||
PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
|
||||
enum ECPGdtype type;
|
||||
bool DataButNoIndicator = false;
|
||||
|
||||
va_start(args, index);
|
||||
if (!ECPGresult)
|
||||
return (false);
|
||||
|
||||
if (PQntuples(ECPGresult) < 1)
|
||||
{
|
||||
ECPGraise(lineno, ECPG_NOT_FOUND, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (index < 1 || index >PQnfields(ECPGresult))
|
||||
{
|
||||
ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, NULL);
|
||||
return (false);
|
||||
}
|
||||
va_start(args, index);
|
||||
if (!ECPGresult)
|
||||
return (false);
|
||||
|
||||
if (PQntuples(ECPGresult) < 1)
|
||||
{
|
||||
ECPGraise(lineno, ECPG_NOT_FOUND, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (index < 1 || index > PQnfields(ECPGresult))
|
||||
{
|
||||
ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
ECPGlog("ECPGget_desc: reading items for tuple %d\n", index);
|
||||
--index;
|
||||
|
||||
type = va_arg(args, enum ECPGdtype);
|
||||
|
||||
while (type != ECPGd_EODT)
|
||||
{
|
||||
char type_str[20];
|
||||
long varcharsize;
|
||||
long offset;
|
||||
long arrsize;
|
||||
enum ECPGttype vartype;
|
||||
void *var;
|
||||
|
||||
vartype = va_arg(args, enum ECPGttype);
|
||||
var = va_arg(args, void *);
|
||||
varcharsize = va_arg(args, long);
|
||||
arrsize = va_arg(args, long);
|
||||
offset = va_arg(args, long);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (ECPGd_indicator):
|
||||
if (!get_int_item(lineno, var, vartype, -PQgetisnull(ECPGresult, 0, index)))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: INDICATOR = %d\n", -PQgetisnull(ECPGresult, 0, index));
|
||||
break;
|
||||
--index;
|
||||
|
||||
case ECPGd_name:
|
||||
if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
|
||||
return(false);
|
||||
|
||||
ECPGlog("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
|
||||
break;
|
||||
|
||||
case ECPGd_nullable:
|
||||
if (!get_int_item(lineno, var, vartype, 1))
|
||||
return (false);
|
||||
|
||||
break;
|
||||
|
||||
case ECPGd_key_member:
|
||||
if (!get_int_item(lineno, var, vartype, 0))
|
||||
return (false);
|
||||
|
||||
break;
|
||||
|
||||
case ECPGd_scale:
|
||||
if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
|
||||
break;
|
||||
|
||||
case ECPGd_precision:
|
||||
if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
|
||||
break;
|
||||
|
||||
case ECPGd_ret_length:
|
||||
type = va_arg(args, enum ECPGdtype);
|
||||
|
||||
while (type != ECPGd_EODT)
|
||||
{
|
||||
char type_str[20];
|
||||
long varcharsize;
|
||||
long offset;
|
||||
long arrsize;
|
||||
enum ECPGttype vartype;
|
||||
void *var;
|
||||
|
||||
vartype = va_arg(args, enum ECPGttype);
|
||||
var = va_arg(args, void *);
|
||||
varcharsize = va_arg(args, long);
|
||||
arrsize = va_arg(args, long);
|
||||
offset = va_arg(args, long);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (ECPGd_indicator):
|
||||
if (!get_int_item(lineno, var, vartype, -PQgetisnull(ECPGresult, 0, index)))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: INDICATOR = %d\n", -PQgetisnull(ECPGresult, 0, index));
|
||||
break;
|
||||
|
||||
case ECPGd_name:
|
||||
if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
|
||||
break;
|
||||
|
||||
case ECPGd_nullable:
|
||||
if (!get_int_item(lineno, var, vartype, 1))
|
||||
return (false);
|
||||
|
||||
break;
|
||||
|
||||
case ECPGd_key_member:
|
||||
if (!get_int_item(lineno, var, vartype, 0))
|
||||
return (false);
|
||||
|
||||
break;
|
||||
|
||||
case ECPGd_scale:
|
||||
if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
|
||||
break;
|
||||
|
||||
case ECPGd_precision:
|
||||
if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
|
||||
break;
|
||||
|
||||
case ECPGd_ret_length:
|
||||
case ECPGd_ret_octet:
|
||||
if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, 0, index)))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: RETURNED = %d\n", PQgetlength(ECPGresult, 0, index));
|
||||
break;
|
||||
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: RETURNED = %d\n", PQgetlength(ECPGresult, 0, index));
|
||||
break;
|
||||
|
||||
case ECPGd_octet:
|
||||
if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
|
||||
break;
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
|
||||
break;
|
||||
|
||||
case ECPGd_length:
|
||||
if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
|
||||
break;
|
||||
|
||||
case ECPGd_type:
|
||||
if (!get_int_item(lineno, var, vartype, ECPGDynamicType(PQftype(ECPGresult, index))))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType(PQftype(ECPGresult, index)));
|
||||
break;
|
||||
return (false);
|
||||
|
||||
case ECPGd_di_code:
|
||||
if (!get_int_item(lineno, var, vartype, ECPGDynamicType_DDT(PQftype(ECPGresult, index))))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType_DDT(PQftype(ECPGresult, index)));
|
||||
break;
|
||||
ECPGlog("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
|
||||
break;
|
||||
|
||||
case ECPGd_type:
|
||||
if (!get_int_item(lineno, var, vartype, ECPGDynamicType(PQftype(ECPGresult, index))))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType(PQftype(ECPGresult, index)));
|
||||
break;
|
||||
|
||||
case ECPGd_di_code:
|
||||
if (!get_int_item(lineno, var, vartype, ECPGDynamicType_DDT(PQftype(ECPGresult, index))))
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType_DDT(PQftype(ECPGresult, index)));
|
||||
break;
|
||||
case ECPGd_data:
|
||||
if (!get_data(ECPGresult, 0, index, lineno, vartype, ECPGt_NO_INDICATOR, var, NULL, varcharsize, offset, false))
|
||||
return (false);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(type_str, sizeof(type_str), "%d", type);
|
||||
ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str);
|
||||
return(false);
|
||||
}
|
||||
|
||||
type = va_arg(args, enum ECPGdtype);
|
||||
}
|
||||
|
||||
if (DataButNoIndicator && PQgetisnull(ECPGresult, 0, index))
|
||||
{
|
||||
ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL);
|
||||
return (false);
|
||||
}
|
||||
return (false);
|
||||
|
||||
return (true);
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(type_str, sizeof(type_str), "%d", type);
|
||||
ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str);
|
||||
return (false);
|
||||
}
|
||||
|
||||
type = va_arg(args, enum ECPGdtype);
|
||||
}
|
||||
|
||||
if (DataButNoIndicator && PQgetisnull(ECPGresult, 0, index))
|
||||
{
|
||||
ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -272,7 +277,7 @@ ECPGdeallocate_desc(int line, const char *name)
|
||||
{
|
||||
struct descriptor *i;
|
||||
struct descriptor **lastptr = &all_descriptors;
|
||||
|
||||
|
||||
for (i = all_descriptors; i; lastptr = &i->next, i = i->next)
|
||||
{
|
||||
if (!strcmp(name, i->name))
|
||||
@ -286,15 +291,15 @@ ECPGdeallocate_desc(int line, const char *name)
|
||||
}
|
||||
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ECPGallocate_desc(int line,const char *name)
|
||||
ECPGallocate_desc(int line, const char *name)
|
||||
{
|
||||
struct descriptor *new = (struct descriptor *)malloc(sizeof(struct descriptor));
|
||||
|
||||
struct descriptor *new = (struct descriptor *) malloc(sizeof(struct descriptor));
|
||||
|
||||
new->next = all_descriptors;
|
||||
new->name = malloc(strlen(name)+1);
|
||||
new->name = malloc(strlen(name) + 1);
|
||||
new->result = PQmakeEmptyPGresult(NULL, 0);
|
||||
strcpy(new->name, name);
|
||||
all_descriptors = new;
|
||||
|
@ -10,143 +10,143 @@ void
|
||||
ECPGraise(int line, int code, char *str)
|
||||
{
|
||||
sqlca.sqlcode = code;
|
||||
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case ECPG_NOT_FOUND:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"No data found in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_OUT_OF_MEMORY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Out of memory in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_UNSUPPORTED:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unsupported type %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_TOO_MANY_ARGUMENTS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Too many arguments in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_TOO_FEW_ARGUMENTS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Too few arguments in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_INT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted int type: %s line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_UINT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted unsigned type: %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_FLOAT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted floating point type: %s in line %d.", str, line);
|
||||
{
|
||||
case ECPG_NOT_FOUND:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"No data found in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_CONVERT_BOOL:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unable to convert %s to bool on line %d.", str, line);
|
||||
case ECPG_OUT_OF_MEMORY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Out of memory in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_EMPTY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Empty query in line %d.", line);
|
||||
case ECPG_UNSUPPORTED:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unsupported type %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_MISSING_INDICATOR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"NULL value without indicator in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_NO_ARRAY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"variable is not an array in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_DATA_NOT_ARRAY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"data read from backend is not an array in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_NO_CONN:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"No such connection %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_NOT_CONN:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not connected in line %d.", line);
|
||||
case ECPG_TOO_MANY_ARGUMENTS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Too many arguments in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_INVALID_STMT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Invalid statement name in line %d.", line);
|
||||
case ECPG_TOO_FEW_ARGUMENTS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Too few arguments in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_UNKNOWN_DESCRIPTOR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Sescriptor %s not found in line %d.", str, line);
|
||||
|
||||
case ECPG_INT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted int type: %s line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_INVALID_DESCRIPTOR_INDEX:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Sescriptor index out of range in line %d.", line);
|
||||
|
||||
case ECPG_UINT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted unsigned type: %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_UNKNOWN_DESCRIPTOR_ITEM:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unknown descriptor item %s in line %d.", str, line);
|
||||
|
||||
case ECPG_FLOAT_FORMAT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not correctly formatted floating point type: %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_VAR_NOT_NUMERIC:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Variable is not a numeric type in line %d.", line);
|
||||
|
||||
case ECPG_CONVERT_BOOL:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unable to convert %s to bool on line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_VAR_NOT_CHAR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Variable is not a character type in line %d.", line);
|
||||
|
||||
case ECPG_EMPTY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Empty query in line %d.", line);
|
||||
break;
|
||||
|
||||
|
||||
case ECPG_MISSING_INDICATOR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"NULL value without indicator in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_NO_ARRAY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"variable is not an array in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_DATA_NOT_ARRAY:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"data read from backend is not an array in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_NO_CONN:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"No such connection %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_NOT_CONN:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Not connected in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_INVALID_STMT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Invalid statement name in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_UNKNOWN_DESCRIPTOR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Sescriptor %s not found in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_INVALID_DESCRIPTOR_INDEX:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Sescriptor index out of range in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_UNKNOWN_DESCRIPTOR_ITEM:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Unknown descriptor item %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_VAR_NOT_NUMERIC:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Variable is not a numeric type in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_VAR_NOT_CHAR:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Variable is not a character type in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_PGSQL:
|
||||
/* strip trailing newline */
|
||||
if (str[strlen(str)-1] == '\n')
|
||||
str[strlen(str)-1] = '\0';
|
||||
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"'%s' in line %d.", str, line);
|
||||
if (str[strlen(str) - 1] == '\n')
|
||||
str[strlen(str) - 1] = '\0';
|
||||
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"'%s' in line %d.", str, line);
|
||||
break;
|
||||
|
||||
case ECPG_TRANS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Error in transaction processing in line %d.", line);
|
||||
|
||||
case ECPG_TRANS:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Error in transaction processing in line %d.", line);
|
||||
break;
|
||||
|
||||
case ECPG_CONNECT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Could not connect to database %s in line %d.", str, line);
|
||||
|
||||
case ECPG_CONNECT:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"Could not connect to database %s in line %d.", str, line);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"SQL error #%d in line %d.", code, line);
|
||||
snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc),
|
||||
"SQL error #%d in line %d.", code, line);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
|
||||
|
||||
/* free all memory we have allocated for the user */
|
||||
free_auto_mem();
|
||||
/* free all memory we have allocated for the user */
|
||||
free_auto_mem();
|
||||
}
|
||||
|
||||
/* print out an error message */
|
||||
|
@ -54,9 +54,9 @@ struct variable
|
||||
/* keep a list of memory we allocated for the user */
|
||||
static struct auto_mem
|
||||
{
|
||||
void *pointer;
|
||||
struct auto_mem *next;
|
||||
} *auto_allocs = NULL;
|
||||
void *pointer;
|
||||
struct auto_mem *next;
|
||||
} *auto_allocs = NULL;
|
||||
|
||||
static void
|
||||
add_mem(void *ptr, int lineno)
|
||||
@ -67,20 +67,21 @@ add_mem(void *ptr, int lineno)
|
||||
auto_allocs = am;
|
||||
}
|
||||
|
||||
void free_auto_mem(void)
|
||||
void
|
||||
free_auto_mem(void)
|
||||
{
|
||||
struct auto_mem *am;
|
||||
|
||||
/* free all memory we have allocated for the user */
|
||||
for (am = auto_allocs; am;)
|
||||
{
|
||||
struct auto_mem *act = am;
|
||||
|
||||
am = am->next;
|
||||
free(act->pointer);
|
||||
free(act);
|
||||
|
||||
/* free all memory we have allocated for the user */
|
||||
for (am = auto_allocs; am;)
|
||||
{
|
||||
struct auto_mem *act = am;
|
||||
|
||||
am = am->next;
|
||||
free(act->pointer);
|
||||
free(act);
|
||||
}
|
||||
|
||||
|
||||
auto_allocs = NULL;
|
||||
}
|
||||
|
||||
@ -245,7 +246,7 @@ next_insert(char *text)
|
||||
bool string = false;
|
||||
|
||||
for (; *ptr != '\0' && (*ptr != '?' || string); ptr++)
|
||||
if (*ptr == '\'' && *(ptr-1) != '\\')
|
||||
if (*ptr == '\'' && *(ptr - 1) != '\\')
|
||||
string = string ? false : true;
|
||||
|
||||
return (*ptr == '\0') ? NULL : ptr;
|
||||
@ -256,7 +257,8 @@ ECPGexecute(struct statement * stmt)
|
||||
{
|
||||
bool status = false;
|
||||
char *copiedquery;
|
||||
PGresult *results, *query;
|
||||
PGresult *results,
|
||||
*query;
|
||||
PGnotify *notify;
|
||||
struct variable *var;
|
||||
|
||||
@ -275,7 +277,7 @@ ECPGexecute(struct statement * stmt)
|
||||
char *mallocedval = NULL;
|
||||
char *tobeinserted = NULL;
|
||||
char *p;
|
||||
char buff[20];
|
||||
char buff[20];
|
||||
|
||||
/*
|
||||
* Some special treatment is needed for records since we want
|
||||
@ -311,20 +313,20 @@ ECPGexecute(struct statement * stmt)
|
||||
{
|
||||
switch (var->type)
|
||||
{
|
||||
int element;
|
||||
|
||||
int element;
|
||||
|
||||
case ECPGt_short:
|
||||
if (!(mallocedval = ecpg_alloc(var->arrsize * 20, stmt->lineno)))
|
||||
return false;
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%hd", *((short *) var->value));
|
||||
@ -338,12 +340,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%d", *((int *) var->value));
|
||||
@ -357,12 +359,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
|
||||
@ -376,12 +378,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%u", *((unsigned int *) var->value));
|
||||
@ -392,15 +394,15 @@ ECPGexecute(struct statement * stmt)
|
||||
case ECPGt_long:
|
||||
if (!(mallocedval = ecpg_alloc(var->arrsize * 20, stmt->lineno)))
|
||||
return false;
|
||||
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%ld", *((long *) var->value));
|
||||
@ -414,12 +416,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
|
||||
@ -433,12 +435,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%.14g,", ((float *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%.14g", *((float *) var->value));
|
||||
@ -452,12 +454,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%.14g,", ((double *) var->value)[element]);
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "%.14g", *((double *) var->value));
|
||||
@ -471,12 +473,12 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (var->arrsize > 1)
|
||||
{
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
strncpy(mallocedval, "'{", sizeof("'{"));
|
||||
|
||||
for (element = 0; element < var->arrsize; element++)
|
||||
sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
|
||||
strncpy(mallocedval + strlen(mallocedval) - 1, "}'", sizeof("}'"));
|
||||
}
|
||||
else
|
||||
sprintf(mallocedval, "'%c'", (*((char *) var->value)) ? 't' : 'f');
|
||||
@ -541,7 +543,7 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
default:
|
||||
/* Not implemented yet */
|
||||
ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, (char *)ECPGtype_name(var->type));
|
||||
ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, (char *) ECPGtype_name(var->type));
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@ -656,7 +658,7 @@ ECPGexecute(struct statement * stmt)
|
||||
for (act_field = 0; act_field < nfields && status; act_field++)
|
||||
{
|
||||
char *array_query;
|
||||
|
||||
|
||||
if (var == NULL)
|
||||
{
|
||||
ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
|
||||
@ -664,16 +666,21 @@ ECPGexecute(struct statement * stmt)
|
||||
return (false);
|
||||
}
|
||||
|
||||
array_query = (char *)ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt -> lineno);
|
||||
array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
|
||||
sprintf(array_query, "select typelem from pg_type where oid=%d", PQftype(results, act_field));
|
||||
query = PQexec(stmt->connection->connection, array_query);
|
||||
isarray = 0;
|
||||
if (PQresultStatus(query) == PGRES_TUPLES_OK) {
|
||||
isarray = atol((char *)PQgetvalue(query, 0, 0));
|
||||
if (PQresultStatus(query) == PGRES_TUPLES_OK)
|
||||
{
|
||||
isarray = atol((char *) PQgetvalue(query, 0, 0));
|
||||
if (ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER ||
|
||||
ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER_VARYING)
|
||||
ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER_VARYING)
|
||||
{
|
||||
/* arrays of character strings are not yet implemented */
|
||||
|
||||
/*
|
||||
* arrays of character strings are not yet
|
||||
* implemented
|
||||
*/
|
||||
isarray = false;
|
||||
}
|
||||
ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, PQftype(results, act_field), var->type, isarray ? "yes" : "no");
|
||||
@ -682,14 +689,15 @@ ECPGexecute(struct statement * stmt)
|
||||
|
||||
if (!isarray)
|
||||
{
|
||||
|
||||
/*
|
||||
* if we don't have enough space, we cannot read all
|
||||
* tuples
|
||||
* if we don't have enough space, we cannot read
|
||||
* all tuples
|
||||
*/
|
||||
if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
|
||||
{
|
||||
ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
|
||||
stmt->lineno, ntuples, var->arrsize);
|
||||
stmt->lineno, ntuples, var->arrsize);
|
||||
ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
|
||||
status = false;
|
||||
break;
|
||||
@ -697,6 +705,7 @@ ECPGexecute(struct statement * stmt)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* since we read an array, the variable has to be
|
||||
* an array too
|
||||
@ -707,9 +716,9 @@ ECPGexecute(struct statement * stmt)
|
||||
ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* allocate memory for NULL pointers
|
||||
*/
|
||||
@ -744,13 +753,13 @@ ECPGexecute(struct statement * stmt)
|
||||
*((void **) var->pointer) = var->value;
|
||||
add_mem(var->value, stmt->lineno);
|
||||
}
|
||||
|
||||
|
||||
for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
|
||||
{
|
||||
if (!get_data(results, act_tuple, act_field, stmt->lineno,
|
||||
var->type, var->ind_type, var->value,
|
||||
var->ind_value, var->varcharsize, var->offset, isarray))
|
||||
status = false;
|
||||
var->type, var->ind_type, var->value,
|
||||
var->ind_value, var->varcharsize, var->offset, isarray))
|
||||
status = false;
|
||||
}
|
||||
var = var->next;
|
||||
}
|
||||
@ -811,13 +820,13 @@ ECPGexecute(struct statement * stmt)
|
||||
}
|
||||
|
||||
bool
|
||||
ECPGdo(int lineno, const char *connection_name, char *query, ...)
|
||||
ECPGdo(int lineno, const char *connection_name, char *query,...)
|
||||
{
|
||||
va_list args;
|
||||
struct statement *stmt;
|
||||
struct connection *con = get_connection(connection_name);
|
||||
bool status=true;
|
||||
char *locale = setlocale(LC_NUMERIC, NULL);
|
||||
va_list args;
|
||||
struct statement *stmt;
|
||||
struct connection *con = get_connection(connection_name);
|
||||
bool status = true;
|
||||
char *locale = setlocale(LC_NUMERIC, NULL);
|
||||
|
||||
/* Make sure we do NOT honor the locale for numeric input/output */
|
||||
/* since the database wants teh standard decimal point */
|
||||
@ -826,7 +835,7 @@ ECPGdo(int lineno, const char *connection_name, char *query, ...)
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
{
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
return(false);
|
||||
return (false);
|
||||
}
|
||||
|
||||
va_start(args, query);
|
||||
@ -859,26 +868,27 @@ ECPGdo(int lineno, const char *connection_name, char *query, ...)
|
||||
*
|
||||
* Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.5 2000/04/05 15:51:25 meskes Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.6 2000/04/12 17:17:03 momjian Exp $
|
||||
*/
|
||||
|
||||
PGconn *ECPG_internal_get_connection(char *name);
|
||||
PGconn *ECPG_internal_get_connection(char *name);
|
||||
|
||||
extern struct descriptor
|
||||
{
|
||||
char *name;
|
||||
PGresult *result;
|
||||
struct descriptor *next;
|
||||
} *all_descriptors;
|
||||
char *name;
|
||||
PGresult *result;
|
||||
struct descriptor *next;
|
||||
} *all_descriptors;
|
||||
|
||||
/* like ECPGexecute */
|
||||
static bool execute_descriptor(int lineno,const char *query
|
||||
,struct connection *con,PGresult **resultptr)
|
||||
static bool
|
||||
execute_descriptor(int lineno, const char *query
|
||||
,struct connection * con, PGresult **resultptr)
|
||||
{
|
||||
bool status = false;
|
||||
bool status = false;
|
||||
PGresult *results;
|
||||
PGnotify *notify;
|
||||
|
||||
|
||||
/* Now the request is built. */
|
||||
|
||||
if (con->committed && !con->autocommit)
|
||||
@ -902,9 +912,12 @@ static bool execute_descriptor(int lineno,const char *query
|
||||
ECPGraise(lineno, ECPG_PGSQL, PQerrorMessage(con->connection));
|
||||
}
|
||||
else
|
||||
{ *resultptr=results;
|
||||
{
|
||||
*resultptr = results;
|
||||
switch (PQresultStatus(results))
|
||||
{ int ntuples;
|
||||
{
|
||||
int ntuples;
|
||||
|
||||
case PGRES_TUPLES_OK:
|
||||
status = true;
|
||||
sqlca.sqlerrd[2] = ntuples = PQntuples(results);
|
||||
@ -917,7 +930,7 @@ static bool execute_descriptor(int lineno,const char *query
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if 1 /* strictly these are not needed (yet) */
|
||||
#if 1 /* strictly these are not needed (yet) */
|
||||
case PGRES_EMPTY_QUERY:
|
||||
/* do nothing */
|
||||
ECPGraise(lineno, ECPG_EMPTY, NULL);
|
||||
@ -972,20 +985,22 @@ static bool execute_descriptor(int lineno,const char *query
|
||||
}
|
||||
|
||||
/* like ECPGdo */
|
||||
static bool do_descriptor2(int lineno,const char *connection_name,
|
||||
PGresult **resultptr, const char *query)
|
||||
static bool
|
||||
do_descriptor2(int lineno, const char *connection_name,
|
||||
PGresult **resultptr, const char *query)
|
||||
{
|
||||
struct connection *con = get_connection(connection_name);
|
||||
bool status=true;
|
||||
char *locale = setlocale(LC_NUMERIC, NULL);
|
||||
bool status = true;
|
||||
char *locale = setlocale(LC_NUMERIC, NULL);
|
||||
|
||||
/* Make sure we do NOT honor the locale for numeric input/output */
|
||||
/* since the database wants teh standard decimal point */
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
{ setlocale(LC_NUMERIC, locale);
|
||||
return(false);
|
||||
{
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
return (false);
|
||||
}
|
||||
|
||||
/* are we connected? */
|
||||
@ -997,33 +1012,38 @@ static bool do_descriptor2(int lineno,const char *connection_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
status = execute_descriptor(lineno,query,con,resultptr);
|
||||
status = execute_descriptor(lineno, query, con, resultptr);
|
||||
|
||||
/* and reset locale value so our application is not affected */
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
return (status);
|
||||
}
|
||||
|
||||
bool ECPGdo_descriptor(int line,const char *connection,
|
||||
const char *descriptor,const char *query)
|
||||
bool
|
||||
ECPGdo_descriptor(int line, const char *connection,
|
||||
const char *descriptor, const char *query)
|
||||
{
|
||||
struct descriptor *i;
|
||||
for (i=all_descriptors;i!=NULL;i=i->next)
|
||||
{ if (!strcmp(descriptor,i->name))
|
||||
{
|
||||
bool status;
|
||||
|
||||
for (i = all_descriptors; i != NULL; i = i->next)
|
||||
{
|
||||
if (!strcmp(descriptor, i->name))
|
||||
{
|
||||
bool status;
|
||||
|
||||
/* free previous result */
|
||||
if (i->result) PQclear(i->result);
|
||||
i->result=NULL;
|
||||
|
||||
status=do_descriptor2(line,connection,&i->result,query);
|
||||
|
||||
if (!i->result) PQmakeEmptyPGresult(NULL, 0);
|
||||
if (i->result)
|
||||
PQclear(i->result);
|
||||
i->result = NULL;
|
||||
|
||||
status = do_descriptor2(line, connection, &i->result, query);
|
||||
|
||||
if (!i->result)
|
||||
PQmakeEmptyPGresult(NULL, 0);
|
||||
return (status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor);
|
||||
return false;
|
||||
}
|
||||
|
@ -3,14 +3,14 @@
|
||||
|
||||
/* Here are some methods used by the lib. */
|
||||
/* Returns a pointer to a string containing a simple type name. */
|
||||
void free_auto_mem(void);
|
||||
void free_auto_mem(void);
|
||||
bool get_data(PGresult *, int, int, int, enum ECPGttype type,
|
||||
enum ECPGttype, void *, void *, long, long, bool);
|
||||
enum ECPGttype, void *, void *, long, long, bool);
|
||||
struct connection *get_connection(const char *);
|
||||
void init_sqlca(void);
|
||||
char *ecpg_alloc(long, int);
|
||||
bool ecpg_init(const struct connection *, const char *, const int);
|
||||
char *ecpg_strdup(const char *, int);
|
||||
void init_sqlca(void);
|
||||
char *ecpg_alloc(long, int);
|
||||
bool ecpg_init(const struct connection *, const char *, const int);
|
||||
char *ecpg_strdup(const char *, int);
|
||||
const char *ECPGtype_name(enum ECPGttype);
|
||||
unsigned int ECPGDynamicType(Oid);
|
||||
|
||||
@ -24,20 +24,19 @@ struct ECPGgeneric_varchar
|
||||
/* structure to store one statement */
|
||||
struct statement
|
||||
{
|
||||
int lineno;
|
||||
char *command;
|
||||
struct connection *connection;
|
||||
struct variable *inlist;
|
||||
struct variable *outlist;
|
||||
int lineno;
|
||||
char *command;
|
||||
struct connection *connection;
|
||||
struct variable *inlist;
|
||||
struct variable *outlist;
|
||||
};
|
||||
|
||||
/* structure to store connections */
|
||||
struct connection
|
||||
{
|
||||
char *name;
|
||||
PGconn *connection;
|
||||
bool committed;
|
||||
int autocommit;
|
||||
struct connection *next;
|
||||
char *name;
|
||||
PGconn *connection;
|
||||
bool committed;
|
||||
int autocommit;
|
||||
struct connection *next;
|
||||
};
|
||||
|
||||
|
@ -27,7 +27,7 @@ init_sqlca(void)
|
||||
}
|
||||
|
||||
bool
|
||||
ecpg_init(const struct connection *con, const char * connection_name, const int lineno)
|
||||
ecpg_init(const struct connection * con, const char *connection_name, const int lineno)
|
||||
{
|
||||
init_sqlca();
|
||||
if (con == NULL)
|
||||
@ -35,7 +35,7 @@ ecpg_init(const struct connection *con, const char * connection_name, const int
|
||||
ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL");
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ ECPGstatus(int lineno, const char *connection_name)
|
||||
struct connection *con = get_connection(connection_name);
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
return(false);
|
||||
return (false);
|
||||
|
||||
/* are we connected? */
|
||||
if (con->connection == NULL)
|
||||
@ -65,7 +65,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
|
||||
struct connection *con = get_connection(connection_name);
|
||||
|
||||
if (!ecpg_init(con, connection_name, lineno))
|
||||
return(false);
|
||||
return (false);
|
||||
|
||||
ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
|
||||
|
||||
@ -79,14 +79,14 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
|
||||
{
|
||||
con->committed = true;
|
||||
|
||||
/* deallocate all prepared statements */
|
||||
if (!ECPGdeallocate_all(lineno))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
static struct prepared_statement
|
||||
{
|
||||
char *name;
|
||||
struct statement *stmt;
|
||||
struct prepared_statement *next;
|
||||
} *prep_stmts = NULL;
|
||||
char *name;
|
||||
struct statement *stmt;
|
||||
struct prepared_statement *next;
|
||||
} *prep_stmts = NULL;
|
||||
|
||||
static bool
|
||||
isvarchar(unsigned char c)
|
||||
@ -47,7 +47,7 @@ replace_variables(char *text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* handle the EXEC SQL PREPARE statement */
|
||||
bool
|
||||
ECPGprepare(int lineno, char *name, char *variable)
|
||||
@ -117,7 +117,7 @@ ECPGdeallocate(int lineno, char *name)
|
||||
prev->next = this->next;
|
||||
else
|
||||
prep_stmts = this->next;
|
||||
|
||||
|
||||
free(this);
|
||||
return true;
|
||||
}
|
||||
@ -130,15 +130,15 @@ bool
|
||||
ECPGdeallocate_all(int lineno)
|
||||
{
|
||||
/* deallocate all prepared statements */
|
||||
while(prep_stmts != NULL)
|
||||
{
|
||||
bool b = ECPGdeallocate(lineno, prep_stmts->name);
|
||||
|
||||
if (!b)
|
||||
while (prep_stmts != NULL)
|
||||
{
|
||||
bool b = ECPGdeallocate(lineno, prep_stmts->name);
|
||||
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* return the prepared statement */
|
||||
|
@ -12,7 +12,7 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
{
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_char:
|
||||
return "char";
|
||||
case ECPGt_unsigned_char:
|
||||
return "unsigned char";
|
||||
@ -47,21 +47,34 @@ ECPGtype_name(enum ECPGttype typ)
|
||||
unsigned int
|
||||
ECPGDynamicType(Oid type)
|
||||
{
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case 16: return SQL3_BOOLEAN; /* bool */
|
||||
case 21: return SQL3_SMALLINT; /* int2 */
|
||||
case 23: return SQL3_INTEGER; /* int4 */
|
||||
case 25: return SQL3_CHARACTER; /* text */
|
||||
case 700: return SQL3_REAL; /* float4 */
|
||||
case 701: return SQL3_DOUBLE_PRECISION; /* float8 */
|
||||
case 1042: return SQL3_CHARACTER; /* bpchar */
|
||||
case 1043: return SQL3_CHARACTER_VARYING; /* varchar */
|
||||
case 1082: return SQL3_DATE_TIME_TIMESTAMP; /* date */
|
||||
case 1083: return SQL3_DATE_TIME_TIMESTAMP; /* time */
|
||||
case 1184: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
|
||||
case 1296: return SQL3_DATE_TIME_TIMESTAMP; /* timestamp */
|
||||
case 1700: return SQL3_NUMERIC; /* numeric */
|
||||
default: return -type;
|
||||
case 16:return SQL3_BOOLEAN; /* bool */
|
||||
case 21:
|
||||
return SQL3_SMALLINT; /* int2 */
|
||||
case 23:
|
||||
return SQL3_INTEGER;/* int4 */
|
||||
case 25:
|
||||
return SQL3_CHARACTER; /* text */
|
||||
case 700:
|
||||
return SQL3_REAL; /* float4 */
|
||||
case 701:
|
||||
return SQL3_DOUBLE_PRECISION; /* float8 */
|
||||
case 1042:
|
||||
return SQL3_CHARACTER; /* bpchar */
|
||||
case 1043:
|
||||
return SQL3_CHARACTER_VARYING; /* varchar */
|
||||
case 1082:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* date */
|
||||
case 1083:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* time */
|
||||
case 1184:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
|
||||
case 1296:
|
||||
return SQL3_DATE_TIME_TIMESTAMP; /* timestamp */
|
||||
case 1700:
|
||||
return SQL3_NUMERIC;/* numeric */
|
||||
default:
|
||||
return -type;
|
||||
}
|
||||
}
|
||||
|
@ -3,18 +3,19 @@
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
#include "extern.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* assignment handling function (descriptor)
|
||||
*/
|
||||
|
||||
|
||||
struct assignment *assignments;
|
||||
|
||||
void push_assignment(char *var, enum ECPGdtype value)
|
||||
void
|
||||
push_assignment(char *var, enum ECPGdtype value)
|
||||
{
|
||||
struct assignment *new = (struct assignment *)mm_alloc(sizeof(struct assignment));
|
||||
|
||||
struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
|
||||
|
||||
new->next = assignments;
|
||||
new->variable = mm_alloc(strlen(var) + 1);
|
||||
strcpy(new->variable, var);
|
||||
@ -35,91 +36,94 @@ drop_assignments(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void ECPGnumeric_lvalue(FILE *f,char *name)
|
||||
static void
|
||||
ECPGnumeric_lvalue(FILE *f, char *name)
|
||||
{
|
||||
const struct variable *v=find_variable(name);
|
||||
const struct variable *v = find_variable(name);
|
||||
|
||||
switch(v->type->typ)
|
||||
switch (v->type->typ)
|
||||
{
|
||||
case ECPGt_short:
|
||||
case ECPGt_int:
|
||||
case ECPGt_int:
|
||||
case ECPGt_long:
|
||||
case ECPGt_unsigned_short:
|
||||
case ECPGt_unsigned_int:
|
||||
case ECPGt_unsigned_long:
|
||||
fputs(name,yyout);
|
||||
fputs(name, yyout);
|
||||
break;
|
||||
default:
|
||||
snprintf(errortext,sizeof errortext,"variable %s: numeric type needed"
|
||||
,name);
|
||||
mmerror(ET_ERROR,errortext);
|
||||
snprintf(errortext, sizeof errortext, "variable %s: numeric type needed"
|
||||
,name);
|
||||
mmerror(ET_ERROR, errortext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* descriptor name lookup
|
||||
*/
|
||||
|
||||
|
||||
static struct descriptor *descriptors;
|
||||
|
||||
void add_descriptor(char *name,char *connection)
|
||||
void
|
||||
add_descriptor(char *name, char *connection)
|
||||
{
|
||||
struct descriptor *new = (struct descriptor *)mm_alloc(sizeof(struct descriptor));
|
||||
|
||||
struct descriptor *new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
|
||||
|
||||
new->next = descriptors;
|
||||
new->name = mm_alloc(strlen(name) + 1);
|
||||
strcpy(new->name,name);
|
||||
if (connection)
|
||||
strcpy(new->name, name);
|
||||
if (connection)
|
||||
{
|
||||
new->connection = mm_alloc(strlen(connection) + 1);
|
||||
strcpy(new->connection, connection);
|
||||
}
|
||||
else new->connection = connection;
|
||||
else
|
||||
new->connection = connection;
|
||||
descriptors = new;
|
||||
}
|
||||
|
||||
void
|
||||
drop_descriptor(char *name,char *connection)
|
||||
drop_descriptor(char *name, char *connection)
|
||||
{
|
||||
struct descriptor *i;
|
||||
struct descriptor **lastptr=&descriptors;
|
||||
|
||||
for (i=descriptors;i;lastptr=&i->next,i=i->next)
|
||||
struct descriptor **lastptr = &descriptors;
|
||||
|
||||
for (i = descriptors; i; lastptr = &i->next, i = i->next)
|
||||
{
|
||||
if (!strcmp(name,i->name))
|
||||
if (!strcmp(name, i->name))
|
||||
{
|
||||
if ((!connection && !i->connection)
|
||||
|| (connection && i->connection
|
||||
&& !strcmp(connection,i->connection)))
|
||||
if ((!connection && !i->connection)
|
||||
|| (connection && i->connection
|
||||
&& !strcmp(connection, i->connection)))
|
||||
{
|
||||
*lastptr=i->next;
|
||||
if (i->connection) free(i->connection);
|
||||
*lastptr = i->next;
|
||||
if (i->connection)
|
||||
free(i->connection);
|
||||
free(i->name);
|
||||
free(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf(errortext,sizeof errortext,"unknown descriptor %s",name);
|
||||
mmerror(ET_WARN,errortext);
|
||||
snprintf(errortext, sizeof errortext, "unknown descriptor %s", name);
|
||||
mmerror(ET_WARN, errortext);
|
||||
}
|
||||
|
||||
struct descriptor
|
||||
*lookup_descriptor(char *name, char *connection)
|
||||
*
|
||||
lookup_descriptor(char *name, char *connection)
|
||||
{
|
||||
struct descriptor *i;
|
||||
|
||||
|
||||
for (i = descriptors; i; i = i->next)
|
||||
{
|
||||
if (!strcmp(name, i->name))
|
||||
{
|
||||
if ((!connection && !i->connection)
|
||||
|| (connection && i->connection
|
||||
&& !strcmp(connection,i->connection)))
|
||||
{
|
||||
if ((!connection && !i->connection)
|
||||
|| (connection && i->connection
|
||||
&& !strcmp(connection, i->connection)))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf(errortext, sizeof errortext, "unknown descriptor %s", name);
|
||||
@ -136,14 +140,14 @@ output_get_descr_header(char *desc_name)
|
||||
for (results = assignments; results != NULL; results = results->next)
|
||||
{
|
||||
if (results->value == ECPGd_count)
|
||||
ECPGnumeric_lvalue(yyout,results->variable);
|
||||
ECPGnumeric_lvalue(yyout, results->variable);
|
||||
else
|
||||
{
|
||||
snprintf(errortext, sizeof errortext, "unknown descriptor header item '%d'", results->value);
|
||||
mmerror(ET_WARN, errortext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drop_assignments();
|
||||
fprintf(yyout, "));\n");
|
||||
whenever_action(3);
|
||||
@ -154,27 +158,27 @@ output_get_descr(char *desc_name, char *index)
|
||||
{
|
||||
struct assignment *results;
|
||||
|
||||
fprintf(yyout, "{ ECPGget_desc(%d,\"%s\",%s,", yylineno, desc_name, index);
|
||||
fprintf(yyout, "{ ECPGget_desc(%d,\"%s\",%s,", yylineno, desc_name, index);
|
||||
for (results = assignments; results != NULL; results = results->next)
|
||||
{
|
||||
const struct variable *v = find_variable(results->variable);
|
||||
|
||||
|
||||
switch (results->value)
|
||||
{
|
||||
case ECPGd_nullable:
|
||||
mmerror(ET_WARN,"nullable is always 1");
|
||||
mmerror(ET_WARN, "nullable is always 1");
|
||||
break;
|
||||
case ECPGd_key_member:
|
||||
mmerror(ET_WARN,"key_member is always 0");
|
||||
mmerror(ET_WARN, "key_member is always 0");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
fprintf(yyout, "%s,", get_dtype(results->value));
|
||||
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
drop_assignments();
|
||||
fputs("ECPGd_EODT);\n",yyout);
|
||||
|
||||
whenever_action(2|1);
|
||||
fputs("ECPGd_EODT);\n", yyout);
|
||||
|
||||
whenever_action(2 | 1);
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
int ret_value = OK, autocommit = 0;
|
||||
int ret_value = OK,
|
||||
autocommit = 0;
|
||||
struct _include_path *include_paths = NULL;
|
||||
struct cursor *cur = NULL;
|
||||
struct typedefs *types = NULL;
|
||||
@ -85,8 +86,8 @@ main(int argc, char *const argv[])
|
||||
verbose = true;
|
||||
break;
|
||||
case 'D':
|
||||
add_preprocessor_define(optarg);
|
||||
break;
|
||||
add_preprocessor_define(optarg);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return ILLEGAL_OPTION;
|
||||
@ -102,7 +103,7 @@ main(int argc, char *const argv[])
|
||||
fprintf(stderr, "End of search list.\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
if (optind >= argc) /* no files specified */
|
||||
{
|
||||
usage(argv[0]);
|
||||
@ -123,7 +124,7 @@ main(int argc, char *const argv[])
|
||||
/* take care of relative paths */
|
||||
ptr2ext = strrchr(input_filename, '/');
|
||||
ptr2ext = (ptr2ext ? strrchr(ptr2ext, '.') : strrchr(input_filename, '.'));
|
||||
|
||||
|
||||
/* no extension? */
|
||||
if (ptr2ext == NULL)
|
||||
{
|
||||
@ -137,7 +138,7 @@ main(int argc, char *const argv[])
|
||||
ptr2ext[4] = '\0';
|
||||
}
|
||||
|
||||
if (out_option == 0) /* calculate the output name */
|
||||
if (out_option == 0)/* calculate the output name */
|
||||
{
|
||||
output_filename = strdup(input_filename);
|
||||
|
||||
@ -177,7 +178,8 @@ main(int argc, char *const argv[])
|
||||
for (ptr = cur; ptr != NULL;)
|
||||
{
|
||||
struct cursor *this = ptr;
|
||||
struct arguments *l1, *l2;
|
||||
struct arguments *l1,
|
||||
*l2;
|
||||
|
||||
free(ptr->command);
|
||||
free(ptr->connection);
|
||||
@ -198,26 +200,28 @@ main(int argc, char *const argv[])
|
||||
cur = NULL;
|
||||
|
||||
/* remove non-pertinent old defines as well */
|
||||
while ( defines && !defines->pertinent ) {
|
||||
defptr = defines;
|
||||
defines = defines->next;
|
||||
while (defines && !defines->pertinent)
|
||||
{
|
||||
defptr = defines;
|
||||
defines = defines->next;
|
||||
|
||||
free(defptr->new);
|
||||
free(defptr->old);
|
||||
free(defptr);
|
||||
free(defptr->new);
|
||||
free(defptr->old);
|
||||
free(defptr);
|
||||
}
|
||||
|
||||
for (defptr = defines; defptr != NULL; defptr = defptr->next )
|
||||
for (defptr = defines; defptr != NULL; defptr = defptr->next)
|
||||
{
|
||||
struct _defines *this = defptr->next;
|
||||
|
||||
if ( this && !this->pertinent ) {
|
||||
defptr->next = this->next;
|
||||
struct _defines *this = defptr->next;
|
||||
|
||||
free(this->new);
|
||||
free(this->old);
|
||||
free(this);
|
||||
}
|
||||
if (this && !this->pertinent)
|
||||
{
|
||||
defptr->next = this->next;
|
||||
|
||||
free(this->new);
|
||||
free(this->old);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
/* and old typedefs */
|
||||
@ -232,18 +236,18 @@ main(int argc, char *const argv[])
|
||||
free(this);
|
||||
}
|
||||
types = NULL;
|
||||
|
||||
|
||||
/* initialize whenever structures */
|
||||
memset(&when_error, 0, sizeof(struct when));
|
||||
memset(&when_nf, 0, sizeof(struct when));
|
||||
memset(&when_warn, 0, sizeof(struct when));
|
||||
|
||||
|
||||
/* and structure member lists */
|
||||
memset(struct_member_list, 0, sizeof(struct_member_list));
|
||||
|
||||
|
||||
/* finally the actual connection */
|
||||
connection = NULL;
|
||||
|
||||
|
||||
/* initialize lex */
|
||||
lex_init();
|
||||
|
||||
|
@ -61,7 +61,8 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"section", SQL_SECTION},
|
||||
{"short", SQL_SHORT},
|
||||
{"signed", SQL_SIGNED},
|
||||
{"sql",SQL_SQL}, /* strange thing, used for into sql descriptor MYDESC; */
|
||||
{"sql", SQL_SQL}, /* strange thing, used for into sql
|
||||
* descriptor MYDESC; */
|
||||
{"sqlerror", SQL_SQLERROR},
|
||||
{"sqlprint", SQL_SQLPRINT},
|
||||
{"sqlwarning", SQL_SQLWARNING},
|
||||
|
@ -10,16 +10,19 @@
|
||||
/* variables */
|
||||
|
||||
extern int braces_open,
|
||||
autocommit,
|
||||
ret_value,
|
||||
struct_level;
|
||||
autocommit,
|
||||
ret_value,
|
||||
struct_level;
|
||||
extern char *descriptor_index;
|
||||
extern char *descriptor_name;
|
||||
extern char *connection;
|
||||
extern char *input_filename;
|
||||
extern char *yytext, errortext[128];
|
||||
extern int yylineno, yyleng;
|
||||
extern FILE *yyin, *yyout;
|
||||
extern char *input_filename;
|
||||
extern char *yytext,
|
||||
errortext[128];
|
||||
extern int yylineno,
|
||||
yyleng;
|
||||
extern FILE *yyin,
|
||||
*yyout;
|
||||
|
||||
extern struct _include_path *include_paths;
|
||||
extern struct cursor *cur;
|
||||
@ -29,7 +32,9 @@ extern struct ECPGtype ecpg_no_indicator;
|
||||
extern struct variable no_indicator;
|
||||
extern struct arguments *argsinsert;
|
||||
extern struct arguments *argsresult;
|
||||
extern struct when when_error, when_nf, when_warn;
|
||||
extern struct when when_error,
|
||||
when_nf,
|
||||
when_warn;
|
||||
extern struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH];
|
||||
extern struct descriptor *descriptors;
|
||||
|
||||
@ -47,19 +52,19 @@ extern int yylex(void);
|
||||
extern void yyerror(char *);
|
||||
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
|
||||
extern char *mm_strdup(const char *);
|
||||
extern void mmerror(enum errortype, char * );
|
||||
extern void mmerror(enum errortype, char *);
|
||||
extern ScanKeyword *ScanECPGKeywordLookup(char *);
|
||||
extern ScanKeyword *ScanCKeywordLookup(char *);
|
||||
extern void output_get_descr_header(char *);
|
||||
extern void output_get_descr(char *, char *);
|
||||
extern void push_assignment(char *, enum ECPGdtype);
|
||||
extern struct variable * find_variable(char *);
|
||||
extern struct variable *find_variable(char *);
|
||||
extern void whenever_action(int);
|
||||
extern void add_descriptor(char *,char *);
|
||||
extern void drop_descriptor(char *,char *);
|
||||
extern struct descriptor *lookup_descriptor(char *,char *);
|
||||
extern void add_variable(struct arguments ** , struct variable * , struct variable *);
|
||||
extern void append_variable(struct arguments ** , struct variable * , struct variable *);
|
||||
extern void add_descriptor(char *, char *);
|
||||
extern void drop_descriptor(char *, char *);
|
||||
extern struct descriptor *lookup_descriptor(char *, char *);
|
||||
extern void add_variable(struct arguments **, struct variable *, struct variable *);
|
||||
extern void append_variable(struct arguments **, struct variable *, struct variable *);
|
||||
extern void dump_variables(struct arguments *, int);
|
||||
extern struct typedefs *get_typedef(char *);
|
||||
extern void adjust_array(enum ECPGttype, int *, int *, int, int, bool);
|
||||
@ -67,13 +72,13 @@ extern void reset_variables(void);
|
||||
extern void check_indicator(struct ECPGtype *);
|
||||
extern void remove_variables(int);
|
||||
extern struct variable *new_variable(const char *, struct ECPGtype *);
|
||||
|
||||
|
||||
/* return codes */
|
||||
|
||||
#define OK 0
|
||||
#define PARSE_ERROR -1
|
||||
#define ILLEGAL_OPTION -2
|
||||
#define INDICATOR_NOT_ARRAY -3
|
||||
#define INDICATOR_NOT_ARRAY -3
|
||||
|
||||
#define NO_INCLUDE_FILE ENOENT
|
||||
#define OUT_OF_MEMORY ENOMEM
|
||||
|
@ -6,74 +6,83 @@
|
||||
void
|
||||
output_line_number()
|
||||
{
|
||||
if (input_filename)
|
||||
fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
|
||||
if (input_filename)
|
||||
fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
|
||||
}
|
||||
|
||||
void
|
||||
output_simple_statement(char *cmd)
|
||||
{
|
||||
int i, j = strlen(cmd);;
|
||||
|
||||
int i,
|
||||
j = strlen(cmd);;
|
||||
|
||||
/* do this char by char as we have to filter '\"' */
|
||||
for (i = 0; i < j; i++) {
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (cmd[i] != '"')
|
||||
fputc(cmd[i], yyout);
|
||||
else
|
||||
fputs("\\\"", yyout);
|
||||
}
|
||||
output_line_number();
|
||||
free(cmd);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* store the whenever action here
|
||||
*/
|
||||
struct when when_error, when_nf, when_warn;
|
||||
struct when when_error,
|
||||
when_nf,
|
||||
when_warn;
|
||||
|
||||
static void
|
||||
print_action(struct when *w)
|
||||
print_action(struct when * w)
|
||||
{
|
||||
switch (w->code)
|
||||
{
|
||||
case W_SQLPRINT: fprintf(yyout, "sqlprint();");
|
||||
break;
|
||||
case W_GOTO: fprintf(yyout, "goto %s;", w->command);
|
||||
break;
|
||||
case W_DO: fprintf(yyout, "%s;", w->command);
|
||||
break;
|
||||
case W_STOP: fprintf(yyout, "exit (1);");
|
||||
break;
|
||||
case W_BREAK: fprintf(yyout, "break;");
|
||||
break;
|
||||
default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
|
||||
break;
|
||||
case W_SQLPRINT:fprintf(yyout, "sqlprint();");
|
||||
break;
|
||||
case W_GOTO:
|
||||
fprintf(yyout, "goto %s;", w->command);
|
||||
break;
|
||||
case W_DO:
|
||||
fprintf(yyout, "%s;", w->command);
|
||||
break;
|
||||
case W_STOP:
|
||||
fprintf(yyout, "exit (1);");
|
||||
break;
|
||||
case W_BREAK:
|
||||
fprintf(yyout, "break;");
|
||||
break;
|
||||
default:
|
||||
fprintf(yyout, "{/* %d not implemented yet */}", w->code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
whenever_action(int mode)
|
||||
{
|
||||
if ((mode&1) == 1 && when_nf.code != W_NOTHING)
|
||||
if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
|
||||
{
|
||||
output_line_number();
|
||||
fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
|
||||
print_action(&when_nf);
|
||||
}
|
||||
if (when_warn.code != W_NOTHING)
|
||||
{
|
||||
{
|
||||
output_line_number();
|
||||
fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
|
||||
fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
|
||||
print_action(&when_warn);
|
||||
}
|
||||
}
|
||||
if (when_error.code != W_NOTHING)
|
||||
{
|
||||
{
|
||||
output_line_number();
|
||||
fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
|
||||
fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
|
||||
print_action(&when_error);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode&2) == 2)
|
||||
if ((mode & 2) == 2)
|
||||
fputc('}', yyout);
|
||||
|
||||
output_line_number();
|
||||
@ -82,30 +91,33 @@ whenever_action(int mode)
|
||||
char *
|
||||
hashline_number(void)
|
||||
{
|
||||
if (input_filename)
|
||||
{
|
||||
char* line = mm_alloc(strlen("\n#line %d \"%s\"\n") + 21 + strlen(input_filename));
|
||||
sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename);
|
||||
if (input_filename)
|
||||
{
|
||||
char *line = mm_alloc(strlen("\n#line %d \"%s\"\n") + 21 + strlen(input_filename));
|
||||
|
||||
return line;
|
||||
}
|
||||
sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename);
|
||||
|
||||
return EMPTY;
|
||||
return line;
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
void
|
||||
output_statement(char * stmt, int mode, char *descriptor, char *con)
|
||||
output_statement(char *stmt, int mode, char *descriptor, char *con)
|
||||
{
|
||||
int i, j = strlen(stmt);
|
||||
int i,
|
||||
j = strlen(stmt);
|
||||
|
||||
if (descriptor == NULL)
|
||||
fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", con ? con : "NULL");
|
||||
else
|
||||
fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, \"%s\", \"",
|
||||
con ? con : "NULL", descriptor);
|
||||
fprintf(yyout, "{ ECPGdo_descriptor(__LINE__, %s, \"%s\", \"",
|
||||
con ? con : "NULL", descriptor);
|
||||
|
||||
/* do this char by char as we have to filter '\"' */
|
||||
for (i = 0; i < j; i++) {
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (stmt[i] != '"')
|
||||
fputc(stmt[i], yyout);
|
||||
else
|
||||
@ -115,7 +127,7 @@ output_statement(char * stmt, int mode, char *descriptor, char *con)
|
||||
if (descriptor == NULL)
|
||||
{
|
||||
fputs("\", ", yyout);
|
||||
|
||||
|
||||
/* dump variables to C file */
|
||||
dump_variables(argsinsert, 1);
|
||||
fputs("ECPGt_EOIT, ", yyout);
|
||||
@ -125,7 +137,7 @@ output_statement(char * stmt, int mode, char *descriptor, char *con)
|
||||
}
|
||||
else
|
||||
fputs("\");", yyout);
|
||||
|
||||
|
||||
mode |= 2;
|
||||
whenever_action(mode);
|
||||
free(stmt);
|
||||
@ -134,4 +146,3 @@ output_statement(char * stmt, int mode, char *descriptor, char *con)
|
||||
if (connection != NULL)
|
||||
free(connection);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ get_type(enum ECPGttype typ)
|
||||
{
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGt_char:
|
||||
case ECPGt_char:
|
||||
return ("ECPGt_char");
|
||||
break;
|
||||
case ECPGt_unsigned_char:
|
||||
@ -163,7 +163,7 @@ get_type(enum ECPGttype typ)
|
||||
return ("ECPGt_NO_INDICATOR");
|
||||
break;
|
||||
case ECPGt_char_variable: /* string that should not be
|
||||
* quoted */
|
||||
* quoted */
|
||||
return ("ECPGt_char_variable");
|
||||
break;
|
||||
default:
|
||||
@ -200,10 +200,10 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in
|
||||
{
|
||||
switch (typ->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
case ECPGt_array:
|
||||
switch (typ->u.element->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
case ECPGt_array:
|
||||
yyerror("No nested arrays allowed (except strings)"); /* array of array */
|
||||
break;
|
||||
case ECPGt_struct:
|
||||
@ -269,7 +269,11 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGt_varchar:
|
||||
/* we have to use the pointer except for arrays with given bounds */
|
||||
|
||||
/*
|
||||
* we have to use the pointer except for arrays with given
|
||||
* bounds
|
||||
*/
|
||||
if (arrsize > 0)
|
||||
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
||||
else
|
||||
@ -280,7 +284,11 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
case ECPGt_char_variable:
|
||||
/* we have to use the pointer except for arrays with given bounds */
|
||||
|
||||
/*
|
||||
* we have to use the pointer except for arrays with given
|
||||
* bounds
|
||||
*/
|
||||
if (varcharsize > 1 || arrsize > 0)
|
||||
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
||||
else
|
||||
@ -289,7 +297,11 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype typ,
|
||||
sprintf(offset, "%ld*sizeof(char)", varcharsize == 0 ? 1 : varcharsize);
|
||||
break;
|
||||
default:
|
||||
/* we have to use the pointer except for arrays with given bounds */
|
||||
|
||||
/*
|
||||
* we have to use the pointer except for arrays with given
|
||||
* bounds
|
||||
*/
|
||||
if (arrsize > 0)
|
||||
sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
|
||||
else
|
||||
@ -375,10 +387,10 @@ ECPGfree_type(struct ECPGtype * typ)
|
||||
{
|
||||
switch (typ->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
case ECPGt_array:
|
||||
switch (typ->u.element->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
case ECPGt_array:
|
||||
yyerror("internal error, found multi-dimensional array\n");
|
||||
break;
|
||||
case ECPGt_struct:
|
||||
@ -412,7 +424,7 @@ get_dtype(enum ECPGdtype typ)
|
||||
{
|
||||
switch (typ)
|
||||
{
|
||||
case ECPGd_count:
|
||||
case ECPGd_count:
|
||||
return ("ECPGd_countr");
|
||||
break;
|
||||
case ECPGd_data:
|
||||
@ -450,10 +462,10 @@ get_dtype(enum ECPGdtype typ)
|
||||
case ECPGd_ret_octet:
|
||||
return ("ECPGd_ret_octet");
|
||||
break;
|
||||
case ECPGd_scale:
|
||||
case ECPGd_scale:
|
||||
return ("ECPGd_scale");
|
||||
break;
|
||||
case ECPGd_type:
|
||||
case ECPGd_type:
|
||||
return ("ECPGd_type");
|
||||
break;
|
||||
default:
|
||||
|
@ -119,7 +119,7 @@ struct _defines
|
||||
{
|
||||
char *old;
|
||||
char *new;
|
||||
int pertinent;
|
||||
int pertinent;
|
||||
struct _defines *next;
|
||||
};
|
||||
|
||||
@ -141,22 +141,25 @@ struct arguments
|
||||
|
||||
struct descriptor
|
||||
{
|
||||
char *name;
|
||||
char *connection;
|
||||
char *name;
|
||||
char *connection;
|
||||
struct descriptor *next;
|
||||
};
|
||||
|
||||
struct assignment
|
||||
{
|
||||
char *variable;
|
||||
enum ECPGdtype value;
|
||||
struct assignment *next;
|
||||
{
|
||||
char *variable;
|
||||
enum ECPGdtype value;
|
||||
struct assignment *next;
|
||||
};
|
||||
|
||||
enum errortype {ET_WARN, ET_ERROR, ET_FATAL};
|
||||
enum errortype
|
||||
{
|
||||
ET_WARN, ET_ERROR, ET_FATAL
|
||||
};
|
||||
|
||||
struct fetch_desc
|
||||
{
|
||||
char *str;
|
||||
char *name;
|
||||
char *str;
|
||||
char *name;
|
||||
};
|
||||
|
@ -2,174 +2,177 @@
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
struct variable * allvariables = NULL;
|
||||
struct variable *allvariables = NULL;
|
||||
|
||||
struct variable *
|
||||
new_variable(const char * name, struct ECPGtype * type)
|
||||
new_variable(const char *name, struct ECPGtype * type)
|
||||
{
|
||||
struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
|
||||
struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
|
||||
|
||||
p->name = mm_strdup(name);
|
||||
p->type = type;
|
||||
p->brace_level = braces_open;
|
||||
p->name = mm_strdup(name);
|
||||
p->type = type;
|
||||
p->brace_level = braces_open;
|
||||
|
||||
p->next = allvariables;
|
||||
allvariables = p;
|
||||
p->next = allvariables;
|
||||
allvariables = p;
|
||||
|
||||
return(p);
|
||||
return (p);
|
||||
}
|
||||
|
||||
static struct variable *
|
||||
find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
|
||||
find_struct_member(char *name, char *str, struct ECPGstruct_member * members)
|
||||
{
|
||||
char *next = strchr(++str, '.'), c = '\0';
|
||||
char *next = strchr(++str, '.'),
|
||||
c = '\0';
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
c = *next;
|
||||
if (next != NULL)
|
||||
{
|
||||
c = *next;
|
||||
*next = '\0';
|
||||
}
|
||||
|
||||
for (; members; members = members->next)
|
||||
{
|
||||
if (strcmp(members->name, str) == 0)
|
||||
{
|
||||
if (c == '\0')
|
||||
{
|
||||
/* found the end */
|
||||
switch (members->typ->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
return (new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
|
||||
case ECPGt_struct:
|
||||
case ECPGt_union:
|
||||
return (new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
|
||||
default:
|
||||
return (new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*next = c;
|
||||
if (c == '-')
|
||||
{
|
||||
next++;
|
||||
return (find_struct_member(name, next, members->typ->u.element->u.members));
|
||||
}
|
||||
else
|
||||
return (find_struct_member(name, next, members->typ->u.members));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct variable *
|
||||
find_struct(char *name, char *next)
|
||||
{
|
||||
struct variable *p;
|
||||
char c = *next;
|
||||
|
||||
/* first get the mother structure entry */
|
||||
*next = '\0';
|
||||
}
|
||||
p = find_variable(name);
|
||||
|
||||
for (; members; members = members->next)
|
||||
{
|
||||
if (strcmp(members->name, str) == 0)
|
||||
if (c == '-')
|
||||
{
|
||||
if (c == '\0')
|
||||
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||
{
|
||||
/* found the end */
|
||||
switch (members->typ->typ)
|
||||
{
|
||||
case ECPGt_array:
|
||||
return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
|
||||
case ECPGt_struct:
|
||||
case ECPGt_union:
|
||||
return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
|
||||
default:
|
||||
return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
|
||||
}
|
||||
sprintf(errortext, "variable %s is not a pointer", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
else
|
||||
{
|
||||
*next = c;
|
||||
if (c == '-')
|
||||
{
|
||||
next++;
|
||||
return(find_struct_member(name, next, members->typ->u.element->u.members));
|
||||
}
|
||||
else return(find_struct_member(name, next, members->typ->u.members));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
|
||||
{
|
||||
sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
/* restore the name, we will need it later on */
|
||||
*next = c;
|
||||
next++;
|
||||
|
||||
return find_struct_member(name, next, p->type->u.element->u.members);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||
{
|
||||
sprintf(errortext, "variable %s is neither a structure nor a union", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
/* restore the name, we will need it later on */
|
||||
*next = c;
|
||||
|
||||
return find_struct_member(name, next, p->type->u.members);
|
||||
}
|
||||
}
|
||||
|
||||
static struct variable *
|
||||
find_struct(char * name, char *next)
|
||||
find_simple(char *name)
|
||||
{
|
||||
struct variable * p;
|
||||
char c = *next;
|
||||
struct variable *p;
|
||||
|
||||
/* first get the mother structure entry */
|
||||
*next = '\0';
|
||||
p = find_variable(name);
|
||||
|
||||
if (c == '-')
|
||||
{
|
||||
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||
{
|
||||
sprintf(errortext, "variable %s is not a pointer", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
|
||||
{
|
||||
sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
/* restore the name, we will need it later on */
|
||||
*next = c;
|
||||
next++;
|
||||
|
||||
return find_struct_member(name, next, p->type->u.element->u.members);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
|
||||
for (p = allvariables; p; p = p->next)
|
||||
{
|
||||
sprintf(errortext, "variable %s is neither a structure nor a union", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
if (strcmp(p->name, name) == 0)
|
||||
return p;
|
||||
}
|
||||
|
||||
/* restore the name, we will need it later on */
|
||||
*next = c;
|
||||
|
||||
return find_struct_member(name, next, p->type->u.members);
|
||||
}
|
||||
}
|
||||
|
||||
static struct variable *
|
||||
find_simple(char * name)
|
||||
{
|
||||
struct variable * p;
|
||||
|
||||
for (p = allvariables; p; p = p->next)
|
||||
{
|
||||
if (strcmp(p->name, name) == 0)
|
||||
return p;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Note that this function will end the program in case of an unknown */
|
||||
/* variable */
|
||||
struct variable *
|
||||
find_variable(char * name)
|
||||
find_variable(char *name)
|
||||
{
|
||||
char * next;
|
||||
struct variable * p;
|
||||
char *next;
|
||||
struct variable *p;
|
||||
|
||||
if ((next = strchr(name, '.')) != NULL)
|
||||
p = find_struct(name, next);
|
||||
else if ((next = strstr(name, "->")) != NULL)
|
||||
p = find_struct(name, next);
|
||||
else
|
||||
p = find_simple(name);
|
||||
if ((next = strchr(name, '.')) != NULL)
|
||||
p = find_struct(name, next);
|
||||
else if ((next = strstr(name, "->")) != NULL)
|
||||
p = find_struct(name, next);
|
||||
else
|
||||
p = find_simple(name);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
sprintf(errortext, "The variable %s is not declared", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
if (p == NULL)
|
||||
{
|
||||
sprintf(errortext, "The variable %s is not declared", name);
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
return(p);
|
||||
return (p);
|
||||
}
|
||||
|
||||
void
|
||||
remove_variables(int brace_level)
|
||||
{
|
||||
struct variable * p, *prev;
|
||||
struct variable *p,
|
||||
*prev;
|
||||
|
||||
for (p = prev = allvariables; p; p = p ? p->next : NULL)
|
||||
{
|
||||
if (p->brace_level >= brace_level)
|
||||
for (p = prev = allvariables; p; p = p ? p->next : NULL)
|
||||
{
|
||||
/* remove it */
|
||||
if (p == allvariables)
|
||||
prev = allvariables = p->next;
|
||||
else
|
||||
prev->next = p->next;
|
||||
if (p->brace_level >= brace_level)
|
||||
{
|
||||
/* remove it */
|
||||
if (p == allvariables)
|
||||
prev = allvariables = p->next;
|
||||
else
|
||||
prev->next = p->next;
|
||||
|
||||
ECPGfree_type(p->type);
|
||||
free(p->name);
|
||||
free(p);
|
||||
p = prev;
|
||||
ECPGfree_type(p->type);
|
||||
free(p->name);
|
||||
free(p);
|
||||
p = prev;
|
||||
}
|
||||
else
|
||||
prev = p;
|
||||
}
|
||||
else
|
||||
prev = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -179,44 +182,45 @@ remove_variables(int brace_level)
|
||||
* I will make two lists for them.
|
||||
*/
|
||||
|
||||
struct arguments * argsinsert = NULL;
|
||||
struct arguments * argsresult = NULL;
|
||||
struct arguments *argsinsert = NULL;
|
||||
struct arguments *argsresult = NULL;
|
||||
|
||||
void
|
||||
reset_variables(void)
|
||||
{
|
||||
argsinsert = NULL;
|
||||
argsresult = NULL;
|
||||
argsinsert = NULL;
|
||||
argsresult = NULL;
|
||||
}
|
||||
|
||||
/* Insert a new variable into our request list. */
|
||||
void
|
||||
add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
|
||||
{
|
||||
struct arguments *p = (struct arguments *)mm_alloc(sizeof(struct arguments));
|
||||
|
||||
p->variable = var;
|
||||
p->indicator = ind;
|
||||
p->next = *list;
|
||||
*list = p;
|
||||
struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
||||
|
||||
p->variable = var;
|
||||
p->indicator = ind;
|
||||
p->next = *list;
|
||||
*list = p;
|
||||
}
|
||||
|
||||
/* Append a new variable to our request list. */
|
||||
void
|
||||
append_variable(struct arguments ** list, struct variable * var, struct variable * ind)
|
||||
{
|
||||
struct arguments *p, *new = (struct arguments *)mm_alloc(sizeof(struct arguments));
|
||||
struct arguments *p,
|
||||
*new = (struct arguments *) mm_alloc(sizeof(struct arguments));
|
||||
|
||||
for (p = *list; p && p->next; p = p->next);
|
||||
|
||||
new->variable = var;
|
||||
new->indicator = ind;
|
||||
new->next = NULL;
|
||||
|
||||
if (p)
|
||||
p->next = new;
|
||||
else
|
||||
*list = new;
|
||||
for (p = *list; p && p->next; p = p->next);
|
||||
|
||||
new->variable = var;
|
||||
new->indicator = ind;
|
||||
new->next = NULL;
|
||||
|
||||
if (p)
|
||||
p->next = new;
|
||||
else
|
||||
*list = new;
|
||||
}
|
||||
|
||||
/* Dump out a list of all the variable on this list.
|
||||
@ -226,33 +230,32 @@ append_variable(struct arguments ** list, struct variable * var, struct variable
|
||||
void
|
||||
dump_variables(struct arguments * list, int mode)
|
||||
{
|
||||
if (list == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (list == NULL)
|
||||
return;
|
||||
|
||||
/* The list is build up from the beginning so lets first dump the
|
||||
end of the list:
|
||||
*/
|
||||
/*
|
||||
* The list is build up from the beginning so lets first dump the end
|
||||
* of the list:
|
||||
*/
|
||||
|
||||
dump_variables(list->next, mode);
|
||||
dump_variables(list->next, mode);
|
||||
|
||||
/* Then the current element and its indicator */
|
||||
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
|
||||
list->indicator->name, list->indicator->type, NULL, NULL);
|
||||
/* Then the current element and its indicator */
|
||||
ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
|
||||
list->indicator->name, list->indicator->type, NULL, NULL);
|
||||
|
||||
/* Then release the list element. */
|
||||
if (mode != 0)
|
||||
free(list);
|
||||
/* Then release the list element. */
|
||||
if (mode != 0)
|
||||
free(list);
|
||||
}
|
||||
|
||||
void
|
||||
check_indicator(struct ECPGtype *var)
|
||||
check_indicator(struct ECPGtype * var)
|
||||
{
|
||||
/* make sure this is a valid indicator variable */
|
||||
switch (var->typ)
|
||||
{
|
||||
struct ECPGstruct_member *p;
|
||||
struct ECPGstruct_member *p;
|
||||
|
||||
case ECPGt_short:
|
||||
case ECPGt_int:
|
||||
@ -271,7 +274,7 @@ check_indicator(struct ECPGtype *var)
|
||||
case ECPGt_array:
|
||||
check_indicator(var->u.element);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
mmerror(ET_ERROR, "indicator variable must be integer type");
|
||||
break;
|
||||
}
|
||||
@ -289,20 +292,20 @@ get_typedef(char *name)
|
||||
mmerror(ET_FATAL, errortext);
|
||||
}
|
||||
|
||||
return(this);
|
||||
return (this);
|
||||
}
|
||||
|
||||
void
|
||||
adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dimension, int type_index, bool pointer)
|
||||
{
|
||||
if (type_index >= 0)
|
||||
if (type_index >= 0)
|
||||
{
|
||||
if (*length >= 0)
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support");
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support");
|
||||
|
||||
*length = type_index;
|
||||
}
|
||||
|
||||
|
||||
if (type_dimension >= 0)
|
||||
{
|
||||
if (*dimension >= 0 && *length >= 0)
|
||||
@ -319,56 +322,57 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
|
||||
|
||||
switch (type_enum)
|
||||
{
|
||||
case ECPGt_struct:
|
||||
case ECPGt_union:
|
||||
/* pointer has to get dimension 0 */
|
||||
if (pointer)
|
||||
{
|
||||
*length = *dimension;
|
||||
*dimension = 0;
|
||||
}
|
||||
case ECPGt_struct:
|
||||
case ECPGt_union:
|
||||
/* pointer has to get dimension 0 */
|
||||
if (pointer)
|
||||
{
|
||||
*length = *dimension;
|
||||
*dimension = 0;
|
||||
}
|
||||
|
||||
if (*length >= 0)
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support for structures");
|
||||
if (*length >= 0)
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support for structures");
|
||||
|
||||
break;
|
||||
case ECPGt_varchar:
|
||||
/* pointer has to get dimension 0 */
|
||||
if (pointer)
|
||||
*dimension = 0;
|
||||
break;
|
||||
case ECPGt_varchar:
|
||||
/* pointer has to get dimension 0 */
|
||||
if (pointer)
|
||||
*dimension = 0;
|
||||
|
||||
/* one index is the string length */
|
||||
if (*length < 0)
|
||||
{
|
||||
*length = *dimension;
|
||||
*dimension = -1;
|
||||
}
|
||||
/* one index is the string length */
|
||||
if (*length < 0)
|
||||
{
|
||||
*length = *dimension;
|
||||
*dimension = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
/* pointer has to get length 0 */
|
||||
if (pointer)
|
||||
*length=0;
|
||||
break;
|
||||
case ECPGt_char:
|
||||
case ECPGt_unsigned_char:
|
||||
/* pointer has to get length 0 */
|
||||
if (pointer)
|
||||
*length = 0;
|
||||
|
||||
/* one index is the string length */
|
||||
if (*length < 0)
|
||||
{
|
||||
*length = (*dimension < 0) ? 1 : *dimension;
|
||||
*dimension = -1;
|
||||
}
|
||||
/* one index is the string length */
|
||||
if (*length < 0)
|
||||
{
|
||||
*length = (*dimension < 0) ? 1 : *dimension;
|
||||
*dimension = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/* a pointer has dimension = 0 */
|
||||
if (pointer) {
|
||||
*length = *dimension;
|
||||
*dimension = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* a pointer has dimension = 0 */
|
||||
if (pointer)
|
||||
{
|
||||
*length = *dimension;
|
||||
*dimension = 0;
|
||||
}
|
||||
|
||||
if (*length >= 0)
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support for simple data types");
|
||||
if (*length >= 0)
|
||||
mmerror(ET_FATAL, "No multi-dimensional array support for simple data types");
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,32 @@
|
||||
exec sql include sqlca;
|
||||
|
||||
void Finish(msg)
|
||||
void
|
||||
Finish(msg)
|
||||
{
|
||||
fprintf(stderr, "Error in statement '%s':\n", msg);
|
||||
sqlprint();
|
||||
|
||||
|
||||
/* finish transaction */
|
||||
exec sql rollback;
|
||||
|
||||
exec sql rollback;
|
||||
|
||||
/* and remove test table */
|
||||
exec sql drop table meskes;
|
||||
exec sql commit;
|
||||
exec sql commit;
|
||||
|
||||
exec sql disconnect;
|
||||
|
||||
exec sql disconnect;
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void warn(void)
|
||||
void
|
||||
warn(void)
|
||||
{
|
||||
fprintf(stderr, "Warning: At least one column was truncated\n");
|
||||
}
|
||||
|
||||
exec sql whenever sqlerror do Finish(msg);
|
||||
exec sql whenever sqlwarning do warn();
|
||||
exec sql whenever sqlerror
|
||||
do
|
||||
Finish(msg);
|
||||
exec sql whenever sqlwarning
|
||||
do
|
||||
warn();
|
||||
|
@ -20,7 +20,7 @@
|
||||
**------------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
halt(char *format, ...)
|
||||
halt(char *format,...)
|
||||
{
|
||||
va_list arg_ptr;
|
||||
char *pstr;
|
||||
|
@ -4,11 +4,11 @@
|
||||
*/
|
||||
|
||||
PGresult *doquery(char *query);
|
||||
PGconn *connectdb(char *dbName,
|
||||
char *pghost,
|
||||
char *pgport,
|
||||
char *pgoptions,
|
||||
char *pgtty);
|
||||
PGconn *connectdb(char *dbName,
|
||||
char *pghost,
|
||||
char *pgport,
|
||||
char *pgoptions,
|
||||
char *pgtty);
|
||||
void disconnectdb(void);
|
||||
int fetch(void *param,...);
|
||||
int fetchwithnulls(void *param,...);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.48 2000/03/11 03:08:35 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.49 2000/04/12 17:17:11 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1381,7 +1381,7 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
|
||||
*/
|
||||
|
||||
static int
|
||||
Pg_have_listener(Pg_ConnectionId *connid, const char *relname)
|
||||
Pg_have_listener(Pg_ConnectionId * connid, const char *relname)
|
||||
{
|
||||
Pg_TclNotifies *notifies;
|
||||
Tcl_HashEntry *entry;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pgtclCmds.h,v 1.16 2000/01/26 05:58:43 momjian Exp $
|
||||
* $Id: pgtclCmds.h,v 1.17 2000/04/12 17:17:11 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,7 +39,7 @@ typedef struct Pg_TclNotifies_s
|
||||
* got round to deleting the Pg_TclNotifies structure.
|
||||
*/
|
||||
Tcl_HashTable notify_hash; /* Active pg_listen requests */
|
||||
} Pg_TclNotifies;
|
||||
} Pg_TclNotifies;
|
||||
|
||||
typedef struct Pg_ConnectionId_s
|
||||
{
|
||||
@ -56,7 +56,7 @@ typedef struct Pg_ConnectionId_s
|
||||
Pg_TclNotifies *notify_list;/* head of list of notify info */
|
||||
int notifier_running; /* notify event source is live */
|
||||
int notifier_socket;/* PQsocket on which notifier is listening */
|
||||
} Pg_ConnectionId;
|
||||
} Pg_ConnectionId;
|
||||
|
||||
/* Values of res_copyStatus */
|
||||
#define RES_COPY_NONE 0
|
||||
|
@ -13,7 +13,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.22 2000/01/26 05:58:43 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.23 2000/04/12 17:17:11 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
static int
|
||||
PgEndCopy(Pg_ConnectionId *connid, int *errorCodePtr)
|
||||
PgEndCopy(Pg_ConnectionId * connid, int *errorCodePtr)
|
||||
{
|
||||
connid->res_copyStatus = RES_COPY_NONE;
|
||||
if (PQendcopy(connid->conn))
|
||||
@ -197,7 +197,7 @@ PgSetConnectionId(Tcl_Interp *interp, PGconn *conn)
|
||||
* Get back the connection from the Id
|
||||
*/
|
||||
PGconn *
|
||||
PgGetConnectionId(Tcl_Interp *interp, char *id, Pg_ConnectionId **connid_p)
|
||||
PgGetConnectionId(Tcl_Interp *interp, char *id, Pg_ConnectionId ** connid_p)
|
||||
{
|
||||
Tcl_Channel conn_chan;
|
||||
Pg_ConnectionId *connid;
|
||||
@ -333,7 +333,7 @@ PgSetResultId(Tcl_Interp *interp, char *connid_c, PGresult *res)
|
||||
}
|
||||
|
||||
static int
|
||||
getresid(Tcl_Interp *interp, char *id, Pg_ConnectionId **connid_p)
|
||||
getresid(Tcl_Interp *interp, char *id, Pg_ConnectionId ** connid_p)
|
||||
{
|
||||
Tcl_Channel conn_chan;
|
||||
char *mark;
|
||||
@ -477,7 +477,7 @@ typedef struct
|
||||
Tcl_Event header; /* Standard Tcl event info */
|
||||
PGnotify info; /* Notify name from SQL server */
|
||||
Pg_ConnectionId *connid; /* Connection for server */
|
||||
} NotifyEvent;
|
||||
} NotifyEvent;
|
||||
|
||||
/* Dispatch a NotifyEvent that has reached the front of the event queue */
|
||||
|
||||
@ -569,7 +569,7 @@ Pg_Notify_EventProc(Tcl_Event *evPtr, int flags)
|
||||
*/
|
||||
|
||||
void
|
||||
PgNotifyTransferEvents(Pg_ConnectionId *connid)
|
||||
PgNotifyTransferEvents(Pg_ConnectionId * connid)
|
||||
{
|
||||
PGnotify *notify;
|
||||
|
||||
@ -678,7 +678,7 @@ Pg_Notify_FileHandler(ClientData clientData, int mask)
|
||||
*/
|
||||
|
||||
void
|
||||
PgStartNotifyEventSource(Pg_ConnectionId *connid)
|
||||
PgStartNotifyEventSource(Pg_ConnectionId * connid)
|
||||
{
|
||||
/* Start the notify event source if it isn't already running */
|
||||
if (!connid->notifier_running)
|
||||
@ -705,7 +705,7 @@ PgStartNotifyEventSource(Pg_ConnectionId *connid)
|
||||
}
|
||||
|
||||
void
|
||||
PgStopNotifyEventSource(Pg_ConnectionId *connid)
|
||||
PgStopNotifyEventSource(Pg_ConnectionId * connid)
|
||||
{
|
||||
/* Remove the event source */
|
||||
if (connid->notifier_running)
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pgtclId.h,v 1.14 2000/01/26 05:58:43 momjian Exp $
|
||||
* $Id: pgtclId.h,v 1.15 2000/04/12 17:17:12 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -43,9 +43,9 @@ extern int PgSetResultId(Tcl_Interp *interp, char *connid, PGresult *res);
|
||||
extern PGresult *PgGetResultId(Tcl_Interp *interp, char *id);
|
||||
extern void PgDelResultId(Tcl_Interp *interp, char *id);
|
||||
extern int PgGetConnByResultId(Tcl_Interp *interp, char *resid);
|
||||
extern void PgStartNotifyEventSource(Pg_ConnectionId *connid);
|
||||
extern void PgStopNotifyEventSource(Pg_ConnectionId *connid);
|
||||
extern void PgNotifyTransferEvents(Pg_ConnectionId *connid);
|
||||
extern void PgStartNotifyEventSource(Pg_ConnectionId * connid);
|
||||
extern void PgStopNotifyEventSource(Pg_ConnectionId * connid);
|
||||
extern void PgNotifyTransferEvents(Pg_ConnectionId * connid);
|
||||
extern void PgNotifyInterpDelete(ClientData clientData, Tcl_Interp *interp);
|
||||
|
||||
/* GetFileProc is needed in Tcl 7.6 *only* ... it went away again in 8.0 */
|
||||
|
@ -10,7 +10,7 @@
|
||||
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.38 2000/03/11 03:08:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.39 2000/04/12 17:17:13 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -94,7 +94,7 @@ static const struct authsvc authsvcs[] = {
|
||||
{"password", STARTUP_PASSWORD_MSG, 0}
|
||||
};
|
||||
|
||||
static const int n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
||||
static const int n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
|
||||
|
||||
#ifdef KRB4
|
||||
/*----------------------------------------------------------------
|
||||
@ -475,12 +475,12 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
|
||||
const char *password, char *PQerrormsg)
|
||||
{
|
||||
#if !defined(KRB4) && !defined(KRB5)
|
||||
(void)hostname; /*not used*/
|
||||
(void) hostname; /* not used */
|
||||
#endif
|
||||
|
||||
switch (areq)
|
||||
{
|
||||
case AUTH_REQ_OK:
|
||||
case AUTH_REQ_OK:
|
||||
break;
|
||||
|
||||
case AUTH_REQ_KRB4:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.93 2000/03/14 23:59:23 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.94 2000/04/12 17:17:14 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
/* keep this in same order as ExecStatusType in libpq-fe.h */
|
||||
char * const pgresStatus[] = {
|
||||
char *const pgresStatus[] = {
|
||||
"PGRES_EMPTY_QUERY",
|
||||
"PGRES_COMMAND_OK",
|
||||
"PGRES_TUPLES_OK",
|
||||
@ -47,7 +47,7 @@ char * const pgresStatus[] = {
|
||||
static void pqCatenateResultError(PGresult *res, const char *msg);
|
||||
static void saveErrorResult(PGconn *conn);
|
||||
static PGresult *prepareAsyncResult(PGconn *conn);
|
||||
static int addTuple(PGresult *res, PGresAttValue *tup);
|
||||
static int addTuple(PGresult *res, PGresAttValue * tup);
|
||||
static void parseInput(PGconn *conn);
|
||||
static void handleSendFailure(PGconn *conn);
|
||||
static int getRowDescriptions(PGconn *conn);
|
||||
@ -178,7 +178,7 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
|
||||
/* defaults... */
|
||||
result->noticeHook = NULL;
|
||||
result->noticeArg = NULL;
|
||||
result->client_encoding = 0; /* should be SQL_ASCII */
|
||||
result->client_encoding = 0; /* should be SQL_ASCII */
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -324,7 +324,7 @@ pqSetResultError(PGresult *res, const char *msg)
|
||||
static void
|
||||
pqCatenateResultError(PGresult *res, const char *msg)
|
||||
{
|
||||
PQExpBufferData errorBuf;
|
||||
PQExpBufferData errorBuf;
|
||||
|
||||
if (!res || !msg)
|
||||
return;
|
||||
@ -391,7 +391,9 @@ pqClearAsyncResult(PGconn *conn)
|
||||
static void
|
||||
saveErrorResult(PGconn *conn)
|
||||
{
|
||||
/* If no old async result, just let PQmakeEmptyPGresult make one.
|
||||
|
||||
/*
|
||||
* If no old async result, just let PQmakeEmptyPGresult make one.
|
||||
* Likewise if old result is not an error message.
|
||||
*/
|
||||
if (conn->result == NULL ||
|
||||
@ -421,9 +423,9 @@ prepareAsyncResult(PGconn *conn)
|
||||
PGresult *res;
|
||||
|
||||
/*
|
||||
* conn->result is the PGresult to return. If it is NULL
|
||||
* (which probably shouldn't happen) we assume there is an
|
||||
* appropriate error message in conn->errorMessage.
|
||||
* conn->result is the PGresult to return. If it is NULL (which
|
||||
* probably shouldn't happen) we assume there is an appropriate error
|
||||
* message in conn->errorMessage.
|
||||
*/
|
||||
res = conn->result;
|
||||
conn->result = NULL; /* handing over ownership to caller */
|
||||
@ -432,9 +434,10 @@ prepareAsyncResult(PGconn *conn)
|
||||
res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* Make sure PQerrorMessage agrees with result; it could
|
||||
* be different if we have concatenated messages.
|
||||
* Make sure PQerrorMessage agrees with result; it could be
|
||||
* different if we have concatenated messages.
|
||||
*/
|
||||
resetPQExpBuffer(&conn->errorMessage);
|
||||
appendPQExpBufferStr(&conn->errorMessage,
|
||||
@ -449,7 +452,7 @@ prepareAsyncResult(PGconn *conn)
|
||||
* Returns TRUE if OK, FALSE if not enough memory to add the row
|
||||
*/
|
||||
static int
|
||||
addTuple(PGresult *res, PGresAttValue *tup)
|
||||
addTuple(PGresult *res, PGresAttValue * tup)
|
||||
{
|
||||
if (res->ntups >= res->tupArrSize)
|
||||
{
|
||||
@ -521,7 +524,7 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
if (conn->asyncStatus != PGASYNC_IDLE)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"PQsendQuery() -- another query already in progress.\n");
|
||||
"PQsendQuery() -- another query already in progress.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -532,21 +535,21 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
/* send the query to the backend; */
|
||||
|
||||
/*
|
||||
* in order to guarantee that we don't send a partial query
|
||||
* where we would become out of sync with the backend and/or
|
||||
* block during a non-blocking connection we must first flush
|
||||
* the send buffer before sending more data
|
||||
* in order to guarantee that we don't send a partial query where we
|
||||
* would become out of sync with the backend and/or block during a
|
||||
* non-blocking connection we must first flush the send buffer before
|
||||
* sending more data
|
||||
*
|
||||
* an alternative is to implement 'queue reservations' where
|
||||
* we are able to roll up a transaction
|
||||
* (the 'Q' along with our query) and make sure we have
|
||||
* enough space for it all in the send buffer.
|
||||
* an alternative is to implement 'queue reservations' where we are able
|
||||
* to roll up a transaction (the 'Q' along with our query) and make
|
||||
* sure we have enough space for it all in the send buffer.
|
||||
*/
|
||||
if (pqIsnonblocking(conn))
|
||||
{
|
||||
|
||||
/*
|
||||
* the buffer must have emptied completely before we allow
|
||||
* a new query to be buffered
|
||||
* the buffer must have emptied completely before we allow a new
|
||||
* query to be buffered
|
||||
*/
|
||||
if (pqFlush(conn))
|
||||
return 0;
|
||||
@ -555,20 +558,21 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
if (pqPutnchar("Q", 1, conn) ||
|
||||
pqPuts(query, conn))
|
||||
{
|
||||
handleSendFailure(conn);
|
||||
handleSendFailure(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* give the data a push, ignore the return value as
|
||||
* ConsumeInput() will do any aditional flushing if needed
|
||||
* give the data a push, ignore the return value as ConsumeInput()
|
||||
* will do any aditional flushing if needed
|
||||
*/
|
||||
(void) pqFlush(conn);
|
||||
(void) pqFlush(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* the frontend-backend protocol uses 'Q' to
|
||||
* designate queries
|
||||
|
||||
/*
|
||||
* the frontend-backend protocol uses 'Q' to designate queries
|
||||
*/
|
||||
if (pqPutnchar("Q", 1, conn) ||
|
||||
pqPuts(query, conn) ||
|
||||
@ -596,16 +600,17 @@ PQsendQuery(PGconn *conn, const char *query)
|
||||
static void
|
||||
handleSendFailure(PGconn *conn)
|
||||
{
|
||||
|
||||
/*
|
||||
* Accept any available input data, ignoring errors. Note that if
|
||||
* pqReadData decides the backend has closed the channel, it will
|
||||
* close our side of the socket --- that's just what we want here.
|
||||
*/
|
||||
while (pqReadData(conn) > 0)
|
||||
/* loop until no more data readable */ ;
|
||||
/* loop until no more data readable */ ;
|
||||
|
||||
/*
|
||||
* Parse any available input messages. Since we are in PGASYNC_IDLE
|
||||
* Parse any available input messages. Since we are in PGASYNC_IDLE
|
||||
* state, only NOTICE and NOTIFY messages will be eaten.
|
||||
*/
|
||||
parseInput(conn);
|
||||
@ -631,11 +636,11 @@ PQconsumeInput(PGconn *conn)
|
||||
*/
|
||||
if (pqReadData(conn) < 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* for non-blocking connections
|
||||
* try to flush the send-queue otherwise we may never get a
|
||||
* responce for something that may not have already been sent
|
||||
* because it's in our write buffer!
|
||||
* for non-blocking connections try to flush the send-queue
|
||||
* otherwise we may never get a responce for something that may
|
||||
* not have already been sent because it's in our write buffer!
|
||||
*/
|
||||
if (pqIsnonblocking(conn))
|
||||
(void) pqFlush(conn);
|
||||
@ -686,11 +691,11 @@ parseInput(PGconn *conn)
|
||||
* OUT; always process them right away.
|
||||
*
|
||||
* Most other messages should only be processed while in BUSY state.
|
||||
* (In particular, in READY state we hold off further parsing until
|
||||
* the application collects the current PGresult.)
|
||||
* (In particular, in READY state we hold off further parsing
|
||||
* until the application collects the current PGresult.)
|
||||
*
|
||||
* However, if the state is IDLE then we got trouble; we need to
|
||||
* deal with the unexpected message somehow.
|
||||
* However, if the state is IDLE then we got trouble; we need to deal
|
||||
* with the unexpected message somehow.
|
||||
*/
|
||||
if (id == 'A')
|
||||
{
|
||||
@ -707,6 +712,7 @@ parseInput(PGconn *conn)
|
||||
/* If not IDLE state, just wait ... */
|
||||
if (conn->asyncStatus != PGASYNC_IDLE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Unexpected message in IDLE state; need to recover somehow.
|
||||
* ERROR messages are displayed using the notice processor;
|
||||
@ -723,7 +729,7 @@ parseInput(PGconn *conn)
|
||||
else
|
||||
{
|
||||
sprintf(noticeWorkspace,
|
||||
"Backend message type 0x%02x arrived while idle\n",
|
||||
"Backend message type 0x%02x arrived while idle\n",
|
||||
id);
|
||||
DONOTICE(conn, noticeWorkspace);
|
||||
/* Discard the unexpected message; good idea?? */
|
||||
@ -733,6 +739,7 @@ parseInput(PGconn *conn)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* In BUSY state, we can process everything.
|
||||
*/
|
||||
@ -743,13 +750,13 @@ parseInput(PGconn *conn)
|
||||
return;
|
||||
if (conn->result == NULL)
|
||||
conn->result = PQmakeEmptyPGresult(conn,
|
||||
PGRES_COMMAND_OK);
|
||||
PGRES_COMMAND_OK);
|
||||
strncpy(conn->result->cmdStatus, conn->workBuffer.data,
|
||||
CMDSTATUS_LEN);
|
||||
conn->asyncStatus = PGASYNC_READY;
|
||||
break;
|
||||
case 'E': /* error return */
|
||||
if (pqGets(& conn->errorMessage, conn))
|
||||
if (pqGets(&conn->errorMessage, conn))
|
||||
return;
|
||||
/* build an error result holding the error message */
|
||||
saveErrorResult(conn);
|
||||
@ -823,7 +830,7 @@ parseInput(PGconn *conn)
|
||||
else
|
||||
{
|
||||
sprintf(noticeWorkspace,
|
||||
"Backend sent D message without prior T\n");
|
||||
"Backend sent D message without prior T\n");
|
||||
DONOTICE(conn, noticeWorkspace);
|
||||
/* Discard the unexpected message; good idea?? */
|
||||
conn->inStart = conn->inEnd;
|
||||
@ -840,7 +847,7 @@ parseInput(PGconn *conn)
|
||||
else
|
||||
{
|
||||
sprintf(noticeWorkspace,
|
||||
"Backend sent B message without prior T\n");
|
||||
"Backend sent B message without prior T\n");
|
||||
DONOTICE(conn, noticeWorkspace);
|
||||
/* Discard the unexpected message; good idea?? */
|
||||
conn->inStart = conn->inEnd;
|
||||
@ -855,10 +862,10 @@ parseInput(PGconn *conn)
|
||||
break;
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"Unknown protocol character '%c' read from backend. "
|
||||
"(The protocol character is the first character the "
|
||||
"backend sends in response to a query it receives).\n",
|
||||
id);
|
||||
"Unknown protocol character '%c' read from backend. "
|
||||
"(The protocol character is the first character the "
|
||||
"backend sends in response to a query it receives).\n",
|
||||
id);
|
||||
/* build an error result holding the error message */
|
||||
saveErrorResult(conn);
|
||||
/* Discard the unexpected message; good idea?? */
|
||||
@ -963,6 +970,7 @@ getAnotherTuple(PGconn *conn, int binary)
|
||||
PGresult *result = conn->result;
|
||||
int nfields = result->numAttributes;
|
||||
PGresAttValue *tup;
|
||||
|
||||
/* the backend sends us a bitmap of which attributes are null */
|
||||
char std_bitmap[64]; /* used unless it doesn't fit */
|
||||
char *bitmap = std_bitmap;
|
||||
@ -1055,7 +1063,9 @@ getAnotherTuple(PGconn *conn, int binary)
|
||||
|
||||
outOfMemory:
|
||||
/* Replace partially constructed result with an error result */
|
||||
/* we do NOT use saveErrorResult() here, because of the likelihood
|
||||
|
||||
/*
|
||||
* we do NOT use saveErrorResult() here, because of the likelihood
|
||||
* that there's not enough memory to concatenate messages...
|
||||
*/
|
||||
pqClearAsyncResult(conn);
|
||||
@ -1116,8 +1126,10 @@ PQgetResult(PGconn *conn)
|
||||
if (pqWait(TRUE, FALSE, conn) ||
|
||||
pqReadData(conn) < 0)
|
||||
{
|
||||
/* conn->errorMessage has been set by pqWait or pqReadData.
|
||||
* We want to append it to any already-received error message.
|
||||
|
||||
/*
|
||||
* conn->errorMessage has been set by pqWait or pqReadData. We
|
||||
* want to append it to any already-received error message.
|
||||
*/
|
||||
saveErrorResult(conn);
|
||||
conn->asyncStatus = PGASYNC_IDLE;
|
||||
@ -1173,12 +1185,12 @@ PQexec(PGconn *conn, const char *query)
|
||||
{
|
||||
PGresult *result;
|
||||
PGresult *lastResult;
|
||||
bool savedblocking;
|
||||
bool savedblocking;
|
||||
|
||||
/*
|
||||
* we assume anyone calling PQexec wants blocking behaviour,
|
||||
* we force the blocking status of the connection to blocking
|
||||
* for the duration of this function and restore it on return
|
||||
* we assume anyone calling PQexec wants blocking behaviour, we force
|
||||
* the blocking status of the connection to blocking for the duration
|
||||
* of this function and restore it on return
|
||||
*/
|
||||
savedblocking = pqIsnonblocking(conn);
|
||||
if (PQsetnonblocking(conn, FALSE) == -1)
|
||||
@ -1205,15 +1217,15 @@ PQexec(PGconn *conn, const char *query)
|
||||
|
||||
/* OK to send the message */
|
||||
if (!PQsendQuery(conn, query))
|
||||
goto errout; /* restore blocking status */
|
||||
goto errout; /* restore blocking status */
|
||||
|
||||
/*
|
||||
* For backwards compatibility, return the last result if there are
|
||||
* more than one --- but merge error messages if we get more than one
|
||||
* error result.
|
||||
*
|
||||
* We have to stop if we see copy in/out, however.
|
||||
* We will resume parsing when application calls PQendcopy.
|
||||
* We have to stop if we see copy in/out, however. We will resume parsing
|
||||
* when application calls PQendcopy.
|
||||
*/
|
||||
lastResult = NULL;
|
||||
while ((result = PQgetResult(conn)) != NULL)
|
||||
@ -1260,11 +1272,13 @@ errout:
|
||||
static int
|
||||
getNotice(PGconn *conn)
|
||||
{
|
||||
/* Since the Notice might be pretty long, we create a temporary
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is
|
||||
|
||||
/*
|
||||
* Since the Notice might be pretty long, we create a temporary
|
||||
* PQExpBuffer rather than using conn->workBuffer. workBuffer is
|
||||
* intended for stuff that is expected to be short.
|
||||
*/
|
||||
PQExpBufferData noticeBuf;
|
||||
PQExpBufferData noticeBuf;
|
||||
|
||||
initPQExpBuffer(¬iceBuf);
|
||||
if (pqGets(¬iceBuf, conn))
|
||||
@ -1532,13 +1546,13 @@ PQendcopy(PGconn *conn)
|
||||
conn->asyncStatus != PGASYNC_COPY_OUT)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"PQendcopy() -- I don't think there's a copy in progress.\n");
|
||||
"PQendcopy() -- I don't think there's a copy in progress.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure no data is waiting to be sent,
|
||||
* abort if we are non-blocking and the flush fails
|
||||
* make sure no data is waiting to be sent, abort if we are
|
||||
* non-blocking and the flush fails
|
||||
*/
|
||||
if (pqFlush(conn) && pqIsnonblocking(conn))
|
||||
return (1);
|
||||
@ -1632,7 +1646,7 @@ PQfn(PGconn *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pqPuts("F ", conn) || /* function */
|
||||
if (pqPuts("F ", conn) || /* function */
|
||||
pqPutInt(fnid, 4, conn) || /* function id */
|
||||
pqPutInt(nargs, 4, conn)) /* # of args */
|
||||
{
|
||||
@ -1730,7 +1744,7 @@ PQfn(PGconn *conn,
|
||||
{
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"FATAL: PQfn: protocol error: id=0x%x\n",
|
||||
"FATAL: PQfn: protocol error: id=0x%x\n",
|
||||
id);
|
||||
saveErrorResult(conn);
|
||||
conn->inStart = conn->inCursor;
|
||||
@ -1764,7 +1778,7 @@ PQfn(PGconn *conn,
|
||||
default:
|
||||
/* The backend violates the protocol. */
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"FATAL: PQfn: protocol error: id=0x%x\n",
|
||||
"FATAL: PQfn: protocol error: id=0x%x\n",
|
||||
id);
|
||||
saveErrorResult(conn);
|
||||
conn->inStart = conn->inCursor;
|
||||
@ -1775,9 +1789,10 @@ PQfn(PGconn *conn,
|
||||
needInput = false;
|
||||
}
|
||||
|
||||
/* We fall out of the loop only upon failing to read data.
|
||||
* conn->errorMessage has been set by pqWait or pqReadData.
|
||||
* We want to append it to any already-received error message.
|
||||
/*
|
||||
* We fall out of the loop only upon failing to read data.
|
||||
* conn->errorMessage has been set by pqWait or pqReadData. We want to
|
||||
* append it to any already-received error message.
|
||||
*/
|
||||
saveErrorResult(conn);
|
||||
return prepareAsyncResult(conn);
|
||||
@ -1842,7 +1857,7 @@ PQbinaryTuples(const PGresult *res)
|
||||
static int
|
||||
check_field_number(const char *routineName, const PGresult *res, int field_num)
|
||||
{
|
||||
char noticeBuf[128];
|
||||
char noticeBuf[128];
|
||||
|
||||
if (!res)
|
||||
return FALSE; /* no way to display error message... */
|
||||
@ -1864,7 +1879,7 @@ static int
|
||||
check_tuple_field_number(const char *routineName, const PGresult *res,
|
||||
int tup_num, int field_num)
|
||||
{
|
||||
char noticeBuf[128];
|
||||
char noticeBuf[128];
|
||||
|
||||
if (!res)
|
||||
return FALSE; /* no way to display error message... */
|
||||
@ -1997,13 +2012,14 @@ PQcmdStatus(PGresult *res)
|
||||
char *
|
||||
PQoidStatus(const PGresult *res)
|
||||
{
|
||||
/*
|
||||
* This must be enough to hold the result. Don't laugh, this is
|
||||
* better than what this function used to do.
|
||||
|
||||
/*
|
||||
* This must be enough to hold the result. Don't laugh, this is better
|
||||
* than what this function used to do.
|
||||
*/
|
||||
static char buf[24];
|
||||
|
||||
size_t len;
|
||||
size_t len;
|
||||
|
||||
if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
|
||||
return "";
|
||||
@ -2019,25 +2035,25 @@ PQoidStatus(const PGresult *res)
|
||||
|
||||
/*
|
||||
PQoidValue -
|
||||
a perhaps preferable form of the above which just returns
|
||||
a perhaps preferable form of the above which just returns
|
||||
an Oid type
|
||||
*/
|
||||
Oid
|
||||
PQoidValue(const PGresult *res)
|
||||
{
|
||||
char * endptr = NULL;
|
||||
long int result;
|
||||
char *endptr = NULL;
|
||||
long int result;
|
||||
|
||||
if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
|
||||
return InvalidOid;
|
||||
if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
|
||||
return InvalidOid;
|
||||
|
||||
errno = 0;
|
||||
result = strtoul(res->cmdStatus + 7, &endptr, 10);
|
||||
errno = 0;
|
||||
result = strtoul(res->cmdStatus + 7, &endptr, 10);
|
||||
|
||||
if (!endptr || (*endptr != ' ' && *endptr != '\0') || errno == ERANGE)
|
||||
return InvalidOid;
|
||||
else
|
||||
return (Oid)result;
|
||||
if (!endptr || (*endptr != ' ' && *endptr != '\0') || errno == ERANGE)
|
||||
return InvalidOid;
|
||||
else
|
||||
return (Oid) result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2048,7 +2064,7 @@ PQoidValue(const PGresult *res)
|
||||
char *
|
||||
PQcmdTuples(PGresult *res)
|
||||
{
|
||||
char noticeBuf[128];
|
||||
char noticeBuf[128];
|
||||
|
||||
if (!res)
|
||||
return "";
|
||||
@ -2160,9 +2176,9 @@ PQsetnonblocking(PGconn *conn, int arg)
|
||||
/*
|
||||
* to guarantee constancy for flushing/query/result-polling behavior
|
||||
* we need to flush the send queue at this point in order to guarantee
|
||||
* proper behavior.
|
||||
* this is ok because either they are making a transition
|
||||
* _from_ or _to_ blocking mode, either way we can block them.
|
||||
* proper behavior. this is ok because either they are making a
|
||||
* transition _from_ or _to_ blocking mode, either way we can block
|
||||
* them.
|
||||
*/
|
||||
/* if we are going from blocking to non-blocking flush here */
|
||||
if (pqFlush(conn))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.28 2000/02/07 23:10:11 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.29 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -523,7 +523,7 @@ lo_initialize(PGconn *conn)
|
||||
PGresult *res;
|
||||
PGlobjfuncs *lobjfuncs;
|
||||
int n;
|
||||
const char *fname;
|
||||
const char *fname;
|
||||
Oid foid;
|
||||
|
||||
/* ----------------
|
||||
@ -563,7 +563,7 @@ lo_initialize(PGconn *conn)
|
||||
free(lobjfuncs);
|
||||
PQclear(res);
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: SELECT didn't return data in lo_initialize()\n");
|
||||
"ERROR: SELECT didn't return data in lo_initialize()\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -603,56 +603,56 @@ lo_initialize(PGconn *conn)
|
||||
if (lobjfuncs->fn_lo_open == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_open\n");
|
||||
"ERROR: Cannot determine OID for function lo_open\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_close == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_close\n");
|
||||
"ERROR: Cannot determine OID for function lo_close\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_creat == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_creat\n");
|
||||
"ERROR: Cannot determine OID for function lo_creat\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_unlink == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_unlink\n");
|
||||
"ERROR: Cannot determine OID for function lo_unlink\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_lseek == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_lseek\n");
|
||||
"ERROR: Cannot determine OID for function lo_lseek\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_tell == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lo_tell\n");
|
||||
"ERROR: Cannot determine OID for function lo_tell\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_read == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function loread\n");
|
||||
"ERROR: Cannot determine OID for function loread\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
if (lobjfuncs->fn_lo_write == 0)
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"ERROR: Cannot determine OID for function lowrite\n");
|
||||
"ERROR: Cannot determine OID for function lowrite\n");
|
||||
free(lobjfuncs);
|
||||
return -1;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.40 2000/04/11 19:00:31 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.41 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -91,40 +91,41 @@ pqGetc(char *result, PGconn *conn)
|
||||
static int
|
||||
pqPutBytes(const char *s, size_t nbytes, PGconn *conn)
|
||||
{
|
||||
size_t avail = Max(conn->outBufSize - conn->outCount, 0);
|
||||
size_t avail = Max(conn->outBufSize - conn->outCount, 0);
|
||||
|
||||
/*
|
||||
* if we are non-blocking and the send queue is too full to buffer this
|
||||
* request then try to flush some and return an error
|
||||
* if we are non-blocking and the send queue is too full to buffer
|
||||
* this request then try to flush some and return an error
|
||||
*/
|
||||
if (pqIsnonblocking(conn) && nbytes > avail && pqFlush(conn))
|
||||
{
|
||||
/*
|
||||
* even if the flush failed we may still have written some
|
||||
* data, recalculate the size of the send-queue relative
|
||||
* to the amount we have to send, we may be able to queue it
|
||||
* afterall even though it's not sent to the database it's
|
||||
* ok, any routines that check the data coming from the
|
||||
* database better call pqFlush() anyway.
|
||||
|
||||
/*
|
||||
* even if the flush failed we may still have written some data,
|
||||
* recalculate the size of the send-queue relative to the amount
|
||||
* we have to send, we may be able to queue it afterall even
|
||||
* though it's not sent to the database it's ok, any routines that
|
||||
* check the data coming from the database better call pqFlush()
|
||||
* anyway.
|
||||
*/
|
||||
if (nbytes > Max(conn->outBufSize - conn->outCount, 0))
|
||||
{
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqPutBytes -- pqFlush couldn't flush enough"
|
||||
" data: space available: %d, space needed %d\n",
|
||||
Max(conn->outBufSize - conn->outCount, 0), nbytes);
|
||||
"pqPutBytes -- pqFlush couldn't flush enough"
|
||||
" data: space available: %d, space needed %d\n",
|
||||
Max(conn->outBufSize - conn->outCount, 0), nbytes);
|
||||
return EOF;
|
||||
}
|
||||
/* fixup avail for while loop */
|
||||
avail = Max(conn->outBufSize - conn->outCount, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* is the amount of data to be sent is larger than the size of the
|
||||
* output buffer then we must flush it to make more room.
|
||||
*
|
||||
* the code above will make sure the loop conditional is never
|
||||
* true for non-blocking connections
|
||||
* the code above will make sure the loop conditional is never true for
|
||||
* non-blocking connections
|
||||
*/
|
||||
while (nbytes > avail)
|
||||
{
|
||||
@ -208,7 +209,7 @@ pqGetnchar(char *s, size_t len, PGconn *conn)
|
||||
conn->inCursor += len;
|
||||
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "From backend (%d)> %.*s\n", len, (int)len, s);
|
||||
fprintf(conn->Pfdebug, "From backend (%d)> %.*s\n", len, (int) len, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -224,7 +225,7 @@ pqPutnchar(const char *s, size_t len, PGconn *conn)
|
||||
return EOF;
|
||||
|
||||
if (conn->Pfdebug)
|
||||
fprintf(conn->Pfdebug, "To backend> %.*s\n", (int)len, s);
|
||||
fprintf(conn->Pfdebug, "To backend> %.*s\n", (int) len, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -324,7 +325,7 @@ pqReadReady(PGconn *conn)
|
||||
FD_SET(conn->sock, &input_mask);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
retry:
|
||||
retry:
|
||||
if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
|
||||
&timeout) < 0)
|
||||
{
|
||||
@ -333,7 +334,7 @@ pqReadReady(PGconn *conn)
|
||||
goto retry;
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqReadReady() -- select() failed: errno=%d\n%s\n",
|
||||
"pqReadReady() -- select() failed: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -358,7 +359,7 @@ pqWriteReady(PGconn *conn)
|
||||
FD_SET(conn->sock, &input_mask);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
retry:
|
||||
retry:
|
||||
if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
|
||||
&timeout) < 0)
|
||||
{
|
||||
@ -367,7 +368,7 @@ pqWriteReady(PGconn *conn)
|
||||
goto retry;
|
||||
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqWriteReady() -- select() failed: errno=%d\n%s\n",
|
||||
"pqWriteReady() -- select() failed: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -415,7 +416,7 @@ pqReadData(PGconn *conn)
|
||||
* buffer size. We enlarge before filling the buffer entirely so as
|
||||
* to avoid asking the kernel for a partial packet. The magic constant
|
||||
* here should be large enough for a TCP packet or Unix pipe
|
||||
* bufferload. 8K is the usual pipe buffer size, so...
|
||||
* bufferload. 8K is the usual pipe buffer size, so...
|
||||
*/
|
||||
if (conn->inBufSize - conn->inEnd < 8192)
|
||||
{
|
||||
@ -432,13 +433,13 @@ pqReadData(PGconn *conn)
|
||||
/* OK, try to read some data */
|
||||
tryAgain:
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
else
|
||||
#endif
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
if (nread < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
@ -458,24 +459,26 @@ tryAgain:
|
||||
goto definitelyFailed;
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqReadData() -- read() failed: errno=%d\n%s\n",
|
||||
"pqReadData() -- read() failed: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (nread > 0)
|
||||
{
|
||||
conn->inEnd += nread;
|
||||
|
||||
/*
|
||||
* Hack to deal with the fact that some kernels will only give us
|
||||
* back 1 packet per recv() call, even if we asked for more and there
|
||||
* is more available. If it looks like we are reading a long message,
|
||||
* loop back to recv() again immediately, until we run out of data
|
||||
* or buffer space. Without this, the block-and-restart behavior of
|
||||
* libpq's higher levels leads to O(N^2) performance on long messages.
|
||||
* back 1 packet per recv() call, even if we asked for more and
|
||||
* there is more available. If it looks like we are reading a
|
||||
* long message, loop back to recv() again immediately, until we
|
||||
* run out of data or buffer space. Without this, the
|
||||
* block-and-restart behavior of libpq's higher levels leads to
|
||||
* O(N^2) performance on long messages.
|
||||
*
|
||||
* Since we left-justified the data above, conn->inEnd gives the
|
||||
* amount of data already read in the current message. We consider
|
||||
* the message "long" once we have acquired 32k ...
|
||||
* amount of data already read in the current message. We
|
||||
* consider the message "long" once we have acquired 32k ...
|
||||
*/
|
||||
if (conn->inEnd > 32768 &&
|
||||
(conn->inBufSize - conn->inEnd) >= 8192)
|
||||
@ -516,13 +519,13 @@ tryAgain:
|
||||
*/
|
||||
tryAgain2:
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
if (conn->ssl)
|
||||
nread = SSL_read(conn->ssl, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd);
|
||||
else
|
||||
#endif
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
nread = recv(conn->sock, conn->inBuffer + conn->inEnd,
|
||||
conn->inBufSize - conn->inEnd, 0);
|
||||
if (nread < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
@ -542,7 +545,7 @@ tryAgain2:
|
||||
goto definitelyFailed;
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqReadData() -- read() failed: errno=%d\n%s\n",
|
||||
"pqReadData() -- read() failed: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -558,9 +561,9 @@ tryAgain2:
|
||||
*/
|
||||
definitelyFailed:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqReadData() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n");
|
||||
"pqReadData() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally\n"
|
||||
"\tbefore or while processing the request.\n");
|
||||
conn->status = CONNECTION_BAD; /* No more connection to backend */
|
||||
#ifdef WIN32
|
||||
closesocket(conn->sock);
|
||||
@ -588,9 +591,9 @@ pqFlush(PGconn *conn)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/*
|
||||
* don't try to send zero data, allows us to use this function
|
||||
* without too much worry about overhead
|
||||
/*
|
||||
* don't try to send zero data, allows us to use this function without
|
||||
* too much worry about overhead
|
||||
*/
|
||||
if (len == 0)
|
||||
return (0);
|
||||
@ -601,16 +604,17 @@ pqFlush(PGconn *conn)
|
||||
/* Prevent being SIGPIPEd if backend has closed the connection. */
|
||||
#ifndef WIN32
|
||||
pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
|
||||
|
||||
#endif
|
||||
|
||||
int sent;
|
||||
int sent;
|
||||
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
sent = SSL_write(conn->ssl, ptr, len);
|
||||
if (conn->ssl)
|
||||
sent = SSL_write(conn->ssl, ptr, len);
|
||||
else
|
||||
#endif
|
||||
sent = send(conn->sock, ptr, len, 0);
|
||||
sent = send(conn->sock, ptr, len, 0);
|
||||
|
||||
#ifndef WIN32
|
||||
pqsignal(SIGPIPE, oldsighandler);
|
||||
@ -642,22 +646,24 @@ pqFlush(PGconn *conn)
|
||||
case ECONNRESET:
|
||||
#endif
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqFlush() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally"
|
||||
" before or while processing the request.\n");
|
||||
"pqFlush() -- backend closed the channel unexpectedly.\n"
|
||||
"\tThis probably means the backend terminated abnormally"
|
||||
" before or while processing the request.\n");
|
||||
|
||||
/*
|
||||
* We used to close the socket here, but that's a bad
|
||||
* idea since there might be unread data waiting
|
||||
* (typically, a NOTICE message from the backend telling
|
||||
* us it's committing hara-kiri...). Leave the socket
|
||||
* open until pqReadData finds no more data can be read.
|
||||
* (typically, a NOTICE message from the backend
|
||||
* telling us it's committing hara-kiri...). Leave
|
||||
* the socket open until pqReadData finds no more data
|
||||
* can be read.
|
||||
*/
|
||||
return EOF;
|
||||
|
||||
default:
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqFlush() -- couldn't send data: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
"pqFlush() -- couldn't send data: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
/* We don't assume it's a fatal error... */
|
||||
return EOF;
|
||||
}
|
||||
@ -672,9 +678,9 @@ pqFlush(PGconn *conn)
|
||||
{
|
||||
/* We didn't send it all, wait till we can send more */
|
||||
|
||||
/*
|
||||
* if the socket is in non-blocking mode we may need
|
||||
* to abort here
|
||||
/*
|
||||
* if the socket is in non-blocking mode we may need to abort
|
||||
* here
|
||||
*/
|
||||
#ifdef USE_SSL
|
||||
/* can't do anything for our SSL users yet */
|
||||
@ -723,7 +729,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
|
||||
|
||||
if (forRead || forWrite)
|
||||
{
|
||||
retry:
|
||||
retry:
|
||||
FD_ZERO(&input_mask);
|
||||
FD_ZERO(&output_mask);
|
||||
if (forRead)
|
||||
@ -736,7 +742,7 @@ pqWait(int forRead, int forWrite, PGconn *conn)
|
||||
if (errno == EINTR)
|
||||
goto retry;
|
||||
printfPQExpBuffer(&conn->errorMessage,
|
||||
"pqWait() -- select() failed: errno=%d\n%s\n",
|
||||
"pqWait() -- select() failed: errno=%d\n%s\n",
|
||||
errno, strerror(errno));
|
||||
return EOF;
|
||||
}
|
||||
@ -775,7 +781,7 @@ PQenv2encoding(void)
|
||||
str = getenv("PGCLIENTENCODING");
|
||||
if (str && *str != '\0')
|
||||
encoding = pg_char_to_encoding(str);
|
||||
return(encoding);
|
||||
return (encoding);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -784,8 +790,8 @@ PQenv2encoding(void)
|
||||
int
|
||||
PQmblen(const unsigned char *s, int encoding)
|
||||
{
|
||||
(void)s;
|
||||
(void)encoding;
|
||||
(void) s;
|
||||
(void) encoding;
|
||||
return 1;
|
||||
}
|
||||
int
|
||||
|
@ -10,7 +10,7 @@
|
||||
* didn't really belong there.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.36 2000/03/14 23:59:23 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.37 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -38,12 +38,14 @@
|
||||
|
||||
#ifdef TIOCGWINSZ
|
||||
static struct winsize screen_size;
|
||||
|
||||
#else
|
||||
static struct winsize
|
||||
{
|
||||
int ws_row;
|
||||
int ws_col;
|
||||
} screen_size;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -54,7 +56,7 @@ static void do_field(const PQprintOpt *po, const PGresult *res,
|
||||
unsigned char *fieldNotNum, int *fieldMax,
|
||||
const int fieldMaxLen, FILE *fout);
|
||||
static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
|
||||
int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
|
||||
int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
|
||||
const int fs_len, const PGresult *res);
|
||||
static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
|
||||
unsigned char *fieldNotNum, int *fieldMax, char *border,
|
||||
@ -77,8 +79,8 @@ static void fill(int length, int max, char filler, FILE *fp);
|
||||
|
||||
void
|
||||
PQprint(FILE *fout,
|
||||
const PGresult *res,
|
||||
const PQprintOpt *po)
|
||||
const PGresult *res,
|
||||
const PQprintOpt *po)
|
||||
{
|
||||
int nFields;
|
||||
|
||||
@ -93,7 +95,7 @@ PQprint(FILE *fout,
|
||||
unsigned char *fieldNotNum = NULL;
|
||||
char *border = NULL;
|
||||
char **fields = NULL;
|
||||
const char **fieldNames;
|
||||
const char **fieldNames;
|
||||
int fieldMaxLen = 0;
|
||||
int numFieldName;
|
||||
int fs_len = strlen(po->fieldSep);
|
||||
@ -125,7 +127,7 @@ PQprint(FILE *fout,
|
||||
for (j = 0; j < nFields; j++)
|
||||
{
|
||||
int len;
|
||||
const char *s = (j < numFieldName && po->fieldName[j][0]) ?
|
||||
const char *s = (j < numFieldName && po->fieldName[j][0]) ?
|
||||
po->fieldName[j] : PQfname(res, j);
|
||||
|
||||
fieldNames[j] = s;
|
||||
@ -216,7 +218,7 @@ PQprint(FILE *fout,
|
||||
|
||||
for (j = 0; j < nFields; j++)
|
||||
{
|
||||
const char *s = fieldNames[j];
|
||||
const char *s = fieldNames[j];
|
||||
|
||||
fputs(s, fout);
|
||||
len += strlen(s) + fs_len;
|
||||
@ -313,12 +315,12 @@ static void
|
||||
do_field(const PQprintOpt *po, const PGresult *res,
|
||||
const int i, const int j, const int fs_len,
|
||||
char **fields,
|
||||
const int nFields, char const **fieldNames,
|
||||
const int nFields, char const ** fieldNames,
|
||||
unsigned char *fieldNotNum, int *fieldMax,
|
||||
const int fieldMaxLen, FILE *fout)
|
||||
{
|
||||
|
||||
const char *pval,
|
||||
const char *pval,
|
||||
*p;
|
||||
int plen;
|
||||
bool skipit;
|
||||
@ -341,7 +343,7 @@ do_field(const PQprintOpt *po, const PGresult *res,
|
||||
|
||||
if (!skipit)
|
||||
{
|
||||
if (po->align && ! fieldNotNum[j])
|
||||
if (po->align && !fieldNotNum[j])
|
||||
{
|
||||
/* Detect whether field contains non-numeric data */
|
||||
char ch = '0';
|
||||
@ -353,21 +355,22 @@ do_field(const PQprintOpt *po, const PGresult *res,
|
||||
#endif
|
||||
{
|
||||
ch = *p;
|
||||
if (! ((ch >= '0' && ch <= '9') ||
|
||||
ch == '.' ||
|
||||
ch == 'E' ||
|
||||
ch == 'e' ||
|
||||
ch == ' ' ||
|
||||
ch == '-'))
|
||||
if (!((ch >= '0' && ch <= '9') ||
|
||||
ch == '.' ||
|
||||
ch == 'E' ||
|
||||
ch == 'e' ||
|
||||
ch == ' ' ||
|
||||
ch == '-'))
|
||||
{
|
||||
fieldNotNum[j] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Above loop will believe E in first column is numeric; also, we
|
||||
* insist on a digit in the last column for a numeric. This test
|
||||
* is still not bulletproof but it handles most cases.
|
||||
* Above loop will believe E in first column is numeric; also,
|
||||
* we insist on a digit in the last column for a numeric. This
|
||||
* test is still not bulletproof but it handles most cases.
|
||||
*/
|
||||
if (*pval == 'E' || *pval == 'e' ||
|
||||
!(ch >= '0' && ch <= '9'))
|
||||
@ -483,7 +486,7 @@ do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
|
||||
fputs(po->fieldSep, fout);
|
||||
for (j = 0; j < nFields; j++)
|
||||
{
|
||||
const char *s = PQfname(res, j);
|
||||
const char *s = PQfname(res, j);
|
||||
|
||||
if (po->html3)
|
||||
{
|
||||
@ -562,11 +565,11 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
|
||||
|
||||
void
|
||||
PQdisplayTuples(const PGresult *res,
|
||||
FILE *fp, /* where to send the output */
|
||||
int fillAlign, /* pad the fields with spaces */
|
||||
const char *fieldSep, /* field separator */
|
||||
int printHeader,/* display headers? */
|
||||
int quiet
|
||||
FILE *fp, /* where to send the output */
|
||||
int fillAlign, /* pad the fields with spaces */
|
||||
const char *fieldSep, /* field separator */
|
||||
int printHeader,/* display headers? */
|
||||
int quiet
|
||||
)
|
||||
{
|
||||
#define DEFAULT_FIELD_SEP " "
|
||||
@ -597,7 +600,8 @@ PQdisplayTuples(const PGresult *res,
|
||||
fLength[j] = strlen(PQfname(res, j));
|
||||
for (i = 0; i < nTuples; i++)
|
||||
{
|
||||
int flen = PQgetlength(res, i, j);
|
||||
int flen = PQgetlength(res, i, j);
|
||||
|
||||
if (flen > fLength[j])
|
||||
fLength[j] = flen;
|
||||
}
|
||||
@ -653,11 +657,11 @@ PQdisplayTuples(const PGresult *res,
|
||||
|
||||
void
|
||||
PQprintTuples(const PGresult *res,
|
||||
FILE *fout, /* output stream */
|
||||
int PrintAttNames,/* print attribute names or not */
|
||||
int TerseOutput, /* delimiter bars or not? */
|
||||
int colWidth /* width of column, if 0, use variable
|
||||
* width */
|
||||
FILE *fout, /* output stream */
|
||||
int PrintAttNames,/* print attribute names or not */
|
||||
int TerseOutput, /* delimiter bars or not? */
|
||||
int colWidth /* width of column, if 0, use variable
|
||||
* width */
|
||||
)
|
||||
{
|
||||
int nFields;
|
||||
@ -713,7 +717,7 @@ PQprintTuples(const PGresult *res,
|
||||
{
|
||||
for (j = 0; j < nFields; j++)
|
||||
{
|
||||
const char *pval = PQgetvalue(res, i, j);
|
||||
const char *pval = PQgetvalue(res, i, j);
|
||||
|
||||
fprintf(fout, formatString,
|
||||
TerseOutput ? "" : "|",
|
||||
@ -730,13 +734,13 @@ PQprintTuples(const PGresult *res,
|
||||
|
||||
|
||||
/* simply send out max-length number of filler characters to fp */
|
||||
|
||||
|
||||
static void
|
||||
fill(int length, int max, char filler, FILE *fp)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = max - length;
|
||||
while (count-- >= 0)
|
||||
putc(filler, fp);
|
||||
int count;
|
||||
|
||||
count = max - length;
|
||||
while (count-- >= 0)
|
||||
putc(filler, fp);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: libpq-fe.h,v 1.64 2000/03/30 02:59:14 tgl Exp $
|
||||
* $Id: libpq-fe.h,v 1.65 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -30,31 +30,37 @@ extern "C"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Although you may decide to change this list in some way,
|
||||
values which become unused should never be removed, nor
|
||||
should constants be redefined - that would break
|
||||
compatibility with existing code. */
|
||||
|
||||
/*
|
||||
* Although you may decide to change this list in some way, values
|
||||
* which become unused should never be removed, nor should
|
||||
* constants be redefined - that would break compatibility with
|
||||
* existing code.
|
||||
*/
|
||||
CONNECTION_OK,
|
||||
CONNECTION_BAD,
|
||||
/* Non-blocking mode only below here */
|
||||
/* The existence of these should never be relied upon - they
|
||||
should only be used for user feedback or similar purposes. */
|
||||
CONNECTION_STARTED, /* Waiting for connection to be made. */
|
||||
CONNECTION_MADE, /* Connection OK; waiting to send. */
|
||||
CONNECTION_AWAITING_RESPONSE, /* Waiting for a response
|
||||
from the postmaster. */
|
||||
CONNECTION_AUTH_OK, /* Received authentication;
|
||||
waiting for backend startup. */
|
||||
CONNECTION_SETENV /* Negotiating environment. */
|
||||
|
||||
/*
|
||||
* The existence of these should never be relied upon - they
|
||||
* should only be used for user feedback or similar purposes.
|
||||
*/
|
||||
CONNECTION_STARTED, /* Waiting for connection to be made. */
|
||||
CONNECTION_MADE, /* Connection OK; waiting to send. */
|
||||
CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the
|
||||
* postmaster. */
|
||||
CONNECTION_AUTH_OK, /* Received authentication; waiting for
|
||||
* backend startup. */
|
||||
CONNECTION_SETENV /* Negotiating environment. */
|
||||
} ConnStatusType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PGRES_POLLING_FAILED = 0,
|
||||
PGRES_POLLING_READING, /* These two indicate that one may */
|
||||
PGRES_POLLING_WRITING, /* use select before polling again. */
|
||||
PGRES_POLLING_READING, /* These two indicate that one may */
|
||||
PGRES_POLLING_WRITING, /* use select before polling again. */
|
||||
PGRES_POLLING_OK,
|
||||
PGRES_POLLING_ACTIVE /* Can call poll function immediately.*/
|
||||
PGRES_POLLING_ACTIVE /* Can call poll function immediately. */
|
||||
} PostgresPollingStatusType;
|
||||
|
||||
typedef enum
|
||||
@ -104,17 +110,17 @@ extern "C"
|
||||
typedef void (*PQnoticeProcessor) (void *arg, const char *message);
|
||||
|
||||
/* Print options for PQprint() */
|
||||
typedef char pqbool;
|
||||
typedef char pqbool;
|
||||
|
||||
typedef struct _PQprintOpt
|
||||
{
|
||||
pqbool header; /* print output field headings and row
|
||||
pqbool header; /* print output field headings and row
|
||||
* count */
|
||||
pqbool align; /* fill align the fields */
|
||||
pqbool standard; /* old brain dead format */
|
||||
pqbool html3; /* output html tables */
|
||||
pqbool expanded; /* expand tables */
|
||||
pqbool pager; /* use pager for output if needed */
|
||||
pqbool align; /* fill align the fields */
|
||||
pqbool standard; /* old brain dead format */
|
||||
pqbool html3; /* output html tables */
|
||||
pqbool expanded; /* expand tables */
|
||||
pqbool pager; /* use pager for output if needed */
|
||||
char *fieldSep; /* field separator */
|
||||
char *tableOpt; /* insert to HTML <table ...> */
|
||||
char *caption; /* HTML <caption> */
|
||||
@ -135,14 +141,13 @@ extern "C"
|
||||
char *keyword; /* The keyword of the option */
|
||||
char *envvar; /* Fallback environment variable name */
|
||||
char *compiled; /* Fallback compiled in default value */
|
||||
char *val; /* Option's current value, or NULL */
|
||||
char *val; /* Option's current value, or NULL */
|
||||
char *label; /* Label for field in connect dialog */
|
||||
char *dispchar; /* Character to display for this field
|
||||
* in a connect dialog. Values are:
|
||||
* "" Display entered value as is
|
||||
* "*" Password field - hide value
|
||||
* "D" Debug option - don't show by default
|
||||
*/
|
||||
char *dispchar; /* Character to display for this field in
|
||||
* a connect dialog. Values are: ""
|
||||
* Display entered value as is "*"
|
||||
* Password field - hide value "D" Debug
|
||||
* option - don't show by default */
|
||||
int dispsize; /* Field size in characters for dialog */
|
||||
} PQconninfoOption;
|
||||
|
||||
@ -176,8 +181,8 @@ extern "C"
|
||||
extern PGconn *PQconnectdb(const char *conninfo);
|
||||
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
|
||||
const char *pgoptions, const char *pgtty,
|
||||
const char *dbName,
|
||||
const char *login, const char *pwd);
|
||||
const char *dbName,
|
||||
const char *login, const char *pwd);
|
||||
#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \
|
||||
PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
|
||||
|
||||
@ -195,7 +200,7 @@ extern "C"
|
||||
* parameters
|
||||
*/
|
||||
/* Asynchronous (non-blocking) */
|
||||
extern int PQresetStart(PGconn *conn);
|
||||
extern int PQresetStart(PGconn *conn);
|
||||
extern PostgresPollingStatusType PQresetPoll(PGconn *conn);
|
||||
/* Synchronous (blocking) */
|
||||
extern void PQreset(PGconn *conn);
|
||||
@ -258,12 +263,12 @@ extern "C"
|
||||
* use
|
||||
*/
|
||||
extern PGresult *PQfn(PGconn *conn,
|
||||
int fnid,
|
||||
int *result_buf,
|
||||
int *result_len,
|
||||
int result_is_int,
|
||||
const PQArgBlock *args,
|
||||
int nargs);
|
||||
int fnid,
|
||||
int *result_buf,
|
||||
int *result_len,
|
||||
int result_is_int,
|
||||
const PQArgBlock *args,
|
||||
int nargs);
|
||||
|
||||
/* Accessor functions for PGresult objects */
|
||||
extern ExecStatusType PQresultStatus(const PGresult *res);
|
||||
@ -278,8 +283,8 @@ extern "C"
|
||||
extern int PQfsize(const PGresult *res, int field_num);
|
||||
extern int PQfmod(const PGresult *res, int field_num);
|
||||
extern char *PQcmdStatus(PGresult *res);
|
||||
extern char *PQoidStatus(const PGresult *res); /* old and ugly */
|
||||
extern Oid PQoidValue(const PGresult *res); /* new and improved */
|
||||
extern char *PQoidStatus(const PGresult *res); /* old and ugly */
|
||||
extern Oid PQoidValue(const PGresult *res); /* new and improved */
|
||||
extern char *PQcmdTuples(PGresult *res);
|
||||
extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num);
|
||||
extern int PQgetlength(const PGresult *res, int tup_num, int field_num);
|
||||
@ -298,25 +303,27 @@ extern "C"
|
||||
/* === in fe-print.c === */
|
||||
|
||||
extern void PQprint(FILE *fout, /* output stream */
|
||||
const PGresult *res,
|
||||
const PQprintOpt *ps); /* option structure */
|
||||
const PGresult *res,
|
||||
const PQprintOpt *ps); /* option structure */
|
||||
|
||||
/*
|
||||
* really old printing routines
|
||||
*/
|
||||
extern void PQdisplayTuples(const PGresult *res,
|
||||
FILE *fp, /* where to send the output */
|
||||
int fillAlign, /* pad the fields with spaces */
|
||||
const char *fieldSep, /* field separator */
|
||||
int printHeader, /* display headers? */
|
||||
int quiet);
|
||||
|
||||
extern void PQprintTuples(const PGresult *res,
|
||||
FILE *fout, /* output stream */
|
||||
int printAttName, /* print attribute names */
|
||||
int terseOutput, /* delimiter bars */
|
||||
int width); /* width of column, if
|
||||
* 0, use variable width */
|
||||
/*
|
||||
* really old printing routines
|
||||
*/
|
||||
extern void PQdisplayTuples(const PGresult *res,
|
||||
FILE *fp, /* where to send the
|
||||
* output */
|
||||
int fillAlign, /* pad the fields with
|
||||
* spaces */
|
||||
const char *fieldSep, /* field separator */
|
||||
int printHeader, /* display headers? */
|
||||
int quiet);
|
||||
|
||||
extern void PQprintTuples(const PGresult *res,
|
||||
FILE *fout, /* output stream */
|
||||
int printAttName, /* print attribute names */
|
||||
int terseOutput, /* delimiter bars */
|
||||
int width); /* width of column, if
|
||||
* 0, use variable width */
|
||||
|
||||
|
||||
/* === in fe-lobj.c === */
|
||||
@ -339,10 +346,11 @@ extern "C"
|
||||
extern int PQmblen(const unsigned char *s, int encoding);
|
||||
|
||||
/* Get encoding id from environment variable PGCLIENTENCODING */
|
||||
extern int PQenv2encoding(void);
|
||||
extern int PQenv2encoding(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LIBPQ_FE_H */
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: libpq-int.h,v 1.22 2000/03/24 01:39:55 tgl Exp $
|
||||
* $Id: libpq-int.h,v 1.23 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -81,7 +81,7 @@ typedef struct pgresAttDesc
|
||||
Oid typid; /* type id */
|
||||
int typlen; /* type size */
|
||||
int atttypmod; /* type-specific modifier info */
|
||||
} PGresAttDesc;
|
||||
} PGresAttDesc;
|
||||
|
||||
/* Data for a single attribute of a single tuple */
|
||||
|
||||
@ -106,7 +106,7 @@ typedef struct pgresAttValue
|
||||
int len; /* length in bytes of the value */
|
||||
char *value; /* actual value, plus terminating zero
|
||||
* byte */
|
||||
} PGresAttValue;
|
||||
} PGresAttValue;
|
||||
|
||||
struct pg_result
|
||||
{
|
||||
@ -121,12 +121,13 @@ struct pg_result
|
||||
* last query */
|
||||
int binary; /* binary tuple values if binary == 1,
|
||||
* otherwise ASCII */
|
||||
|
||||
/*
|
||||
* The conn link in PGresult is no longer used by any libpq code.
|
||||
* It should be removed entirely, because it could be a dangling link
|
||||
* (the application could keep the PGresult around longer than it keeps
|
||||
* the PGconn!) But there may be apps out there that depend on it,
|
||||
* so we will leave it here at least for a release or so.
|
||||
* The conn link in PGresult is no longer used by any libpq code. It
|
||||
* should be removed entirely, because it could be a dangling link
|
||||
* (the application could keep the PGresult around longer than it
|
||||
* keeps the PGconn!) But there may be apps out there that depend on
|
||||
* it, so we will leave it here at least for a release or so.
|
||||
*/
|
||||
PGconn *xconn; /* connection we did the query on, if any */
|
||||
|
||||
@ -134,9 +135,9 @@ struct pg_result
|
||||
* These fields are copied from the originating PGconn, so that
|
||||
* operations on the PGresult don't have to reference the PGconn.
|
||||
*/
|
||||
PQnoticeProcessor noticeHook; /* notice/error message processor */
|
||||
PQnoticeProcessor noticeHook; /* notice/error message processor */
|
||||
void *noticeArg;
|
||||
int client_encoding; /* encoding id */
|
||||
int client_encoding;/* encoding id */
|
||||
|
||||
|
||||
char *errMsg; /* error message, or NULL if no error */
|
||||
@ -162,7 +163,7 @@ typedef enum
|
||||
PGASYNC_READY, /* result ready for PQgetResult */
|
||||
PGASYNC_COPY_IN, /* Copy In data transfer in progress */
|
||||
PGASYNC_COPY_OUT /* Copy Out data transfer in progress */
|
||||
} PGAsyncStatusType;
|
||||
} PGAsyncStatusType;
|
||||
|
||||
/* PGSetenvStatusType defines the state of the PQSetenv state machine */
|
||||
typedef enum
|
||||
@ -170,10 +171,10 @@ typedef enum
|
||||
SETENV_STATE_OPTION_SEND, /* About to send an Environment Option */
|
||||
SETENV_STATE_OPTION_WAIT, /* Waiting for above send to complete */
|
||||
/* these next two are only used in MULTIBYTE mode */
|
||||
SETENV_STATE_ENCODINGS_SEND, /* About to send an "encodings" query */
|
||||
SETENV_STATE_ENCODINGS_WAIT, /* Waiting for query to complete */
|
||||
SETENV_STATE_ENCODINGS_SEND,/* About to send an "encodings" query */
|
||||
SETENV_STATE_ENCODINGS_WAIT,/* Waiting for query to complete */
|
||||
SETENV_STATE_IDLE
|
||||
} PGSetenvStatusType;
|
||||
} PGSetenvStatusType;
|
||||
|
||||
/* large-object-access data ... allocated only if large-object code is used. */
|
||||
typedef struct pgLobjfuncs
|
||||
@ -186,7 +187,7 @@ typedef struct pgLobjfuncs
|
||||
Oid fn_lo_tell; /* OID of backend function lo_tell */
|
||||
Oid fn_lo_read; /* OID of backend function LOread */
|
||||
Oid fn_lo_write; /* OID of backend function LOwrite */
|
||||
} PGlobjfuncs;
|
||||
} PGlobjfuncs;
|
||||
|
||||
/* PGconn stores all the state data associated with a single connection
|
||||
* to a backend.
|
||||
@ -197,8 +198,8 @@ struct pg_conn
|
||||
char *pghost; /* the machine on which the server is
|
||||
* running */
|
||||
char *pghostaddr; /* the IPv4 address of the machine on
|
||||
* which the server is running, in
|
||||
* IPv4 numbers-and-dots notation. Takes
|
||||
* which the server is running, in IPv4
|
||||
* numbers-and-dots notation. Takes
|
||||
* precedence over above. */
|
||||
char *pgport; /* the server's communication port */
|
||||
char *pgtty; /* tty on which the backend messages is
|
||||
@ -243,8 +244,8 @@ struct pg_conn
|
||||
int inEnd; /* offset to first position after avail
|
||||
* data */
|
||||
|
||||
int nonblocking; /* whether this connection is using a blocking
|
||||
* socket to the backend or not */
|
||||
int nonblocking; /* whether this connection is using a
|
||||
* blocking socket to the backend or not */
|
||||
|
||||
/* Buffer for data not yet sent to backend */
|
||||
char *outBuffer; /* currently allocated buffer */
|
||||
@ -256,21 +257,21 @@ struct pg_conn
|
||||
PGresAttValue *curTuple; /* tuple currently being read */
|
||||
|
||||
/* Status for sending environment info. Used during PQSetenv only. */
|
||||
PGSetenvStatusType setenv_state;
|
||||
PGSetenvStatusType setenv_state;
|
||||
const struct EnvironmentOptions *next_eo;
|
||||
|
||||
#ifdef USE_SSL
|
||||
bool allow_ssl_try; /* Allowed to try SSL negotiation */
|
||||
SSL *ssl; /* SSL status, if have SSL connection */
|
||||
bool allow_ssl_try; /* Allowed to try SSL negotiation */
|
||||
SSL *ssl; /* SSL status, if have SSL connection */
|
||||
#endif
|
||||
|
||||
/* Buffer for current error message */
|
||||
PQExpBufferData errorMessage; /* expansible string */
|
||||
PQExpBufferData errorMessage; /* expansible string */
|
||||
|
||||
/* Buffer for receiving various parts of messages */
|
||||
PQExpBufferData workBuffer; /* expansible string */
|
||||
PQExpBufferData workBuffer; /* expansible string */
|
||||
|
||||
int client_encoding; /* encoding id */
|
||||
int client_encoding;/* encoding id */
|
||||
};
|
||||
|
||||
/* String descriptions of the ExecStatusTypes.
|
||||
@ -338,7 +339,7 @@ extern char *sys_errlist[];
|
||||
#endif /* sunos4 */
|
||||
#endif /* !strerror */
|
||||
|
||||
/*
|
||||
/*
|
||||
* this is so that we can check is a connection is non-blocking internally
|
||||
* without the overhead of a function call
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.5 2000/02/07 23:10:11 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/pqexpbuffer.c,v 1.6 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -39,7 +39,7 @@
|
||||
PQExpBuffer
|
||||
createPQExpBuffer(void)
|
||||
{
|
||||
PQExpBuffer res;
|
||||
PQExpBuffer res;
|
||||
|
||||
res = (PQExpBuffer) malloc(sizeof(PQExpBufferData));
|
||||
if (res != NULL)
|
||||
@ -156,7 +156,7 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed)
|
||||
/*------------------------
|
||||
* printfPQExpBuffer
|
||||
* Format text data under the control of fmt (an sprintf-like format string)
|
||||
* and insert it into str. More space is allocated to str if necessary.
|
||||
* and insert it into str. More space is allocated to str if necessary.
|
||||
* This is a convenience routine that does the same thing as
|
||||
* resetPQExpBuffer() followed by appendPQExpBuffer().
|
||||
*/
|
||||
@ -165,7 +165,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
size_t avail;
|
||||
int nprinted;
|
||||
int nprinted;
|
||||
|
||||
resetPQExpBuffer(str);
|
||||
|
||||
@ -184,12 +184,13 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
nprinted = vsnprintf(str->data + str->len, avail,
|
||||
fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/*
|
||||
* Note: some versions of vsnprintf return the number of chars
|
||||
* actually stored, but at least one returns -1 on failure.
|
||||
* Be conservative about believing whether the print worked.
|
||||
* actually stored, but at least one returns -1 on failure. Be
|
||||
* conservative about believing whether the print worked.
|
||||
*/
|
||||
if (nprinted >= 0 && nprinted < avail-1)
|
||||
if (nprinted >= 0 && nprinted < avail - 1)
|
||||
{
|
||||
/* Success. Note nprinted does not include trailing null. */
|
||||
str->len += nprinted;
|
||||
@ -197,7 +198,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
}
|
||||
}
|
||||
/* Double the buffer size and try again. */
|
||||
if (! enlargePQExpBuffer(str, str->maxlen))
|
||||
if (!enlargePQExpBuffer(str, str->maxlen))
|
||||
return; /* oops, out of memory */
|
||||
}
|
||||
}
|
||||
@ -215,7 +216,7 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
size_t avail;
|
||||
int nprinted;
|
||||
int nprinted;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -232,12 +233,13 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
nprinted = vsnprintf(str->data + str->len, avail,
|
||||
fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/*
|
||||
* Note: some versions of vsnprintf return the number of chars
|
||||
* actually stored, but at least one returns -1 on failure.
|
||||
* Be conservative about believing whether the print worked.
|
||||
* actually stored, but at least one returns -1 on failure. Be
|
||||
* conservative about believing whether the print worked.
|
||||
*/
|
||||
if (nprinted >= 0 && nprinted < avail-1)
|
||||
if (nprinted >= 0 && nprinted < avail - 1)
|
||||
{
|
||||
/* Success. Note nprinted does not include trailing null. */
|
||||
str->len += nprinted;
|
||||
@ -245,7 +247,7 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
|
||||
}
|
||||
}
|
||||
/* Double the buffer size and try again. */
|
||||
if (! enlargePQExpBuffer(str, str->maxlen))
|
||||
if (!enlargePQExpBuffer(str, str->maxlen))
|
||||
return; /* oops, out of memory */
|
||||
}
|
||||
}
|
||||
@ -270,7 +272,7 @@ void
|
||||
appendPQExpBufferChar(PQExpBuffer str, char ch)
|
||||
{
|
||||
/* Make more room if needed */
|
||||
if (! enlargePQExpBuffer(str, 1))
|
||||
if (!enlargePQExpBuffer(str, 1))
|
||||
return;
|
||||
|
||||
/* OK, append the character */
|
||||
@ -289,7 +291,7 @@ void
|
||||
appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
|
||||
{
|
||||
/* Make more room if needed */
|
||||
if (! enlargePQExpBuffer(str, datalen))
|
||||
if (!enlargePQExpBuffer(str, datalen))
|
||||
return;
|
||||
|
||||
/* OK, append the data */
|
||||
|
@ -18,7 +18,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pqexpbuffer.h,v 1.4 2000/02/07 23:10:11 petere Exp $
|
||||
* $Id: pqexpbuffer.h,v 1.5 2000/04/12 17:17:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -52,7 +52,7 @@ typedef PQExpBufferData *PQExpBuffer;
|
||||
* be returned by PQrequestCancel() or any routine in fe-auth.c.
|
||||
*------------------------
|
||||
*/
|
||||
#define INITIAL_EXPBUFFER_SIZE 256
|
||||
#define INITIAL_EXPBUFFER_SIZE 256
|
||||
|
||||
/*------------------------
|
||||
* There are two ways to create a PQExpBuffer object initially:
|
||||
@ -113,12 +113,12 @@ extern void resetPQExpBuffer(PQExpBuffer str);
|
||||
*
|
||||
* Returns 1 if OK, 0 if failed to enlarge buffer.
|
||||
*/
|
||||
extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed);
|
||||
extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed);
|
||||
|
||||
/*------------------------
|
||||
* printfPQExpBuffer
|
||||
* Format text data under the control of fmt (an sprintf-like format string)
|
||||
* and insert it into str. More space is allocated to str if necessary.
|
||||
* and insert it into str. More space is allocated to str if necessary.
|
||||
* This is a convenience routine that does the same thing as
|
||||
* resetPQExpBuffer() followed by appendPQExpBuffer().
|
||||
*/
|
||||
@ -153,6 +153,6 @@ extern void appendPQExpBufferChar(PQExpBuffer str, char ch);
|
||||
* if necessary.
|
||||
*/
|
||||
extern void appendBinaryPQExpBuffer(PQExpBuffer str,
|
||||
const char *data, size_t datalen);
|
||||
const char *data, size_t datalen);
|
||||
|
||||
#endif /* PQEXPBUFFER_H */
|
||||
|
@ -32,4 +32,3 @@
|
||||
|
||||
#define DEF_PGPORT "5432"
|
||||
#define MAXIMUM_ALIGNOF 4
|
||||
|
||||
|
Reference in New Issue
Block a user