提交 9305fc74 编写于 作者: M Marc G. Fournier

Fixes:

Attached is a patch to allow libpq to determine if a field is null.

This is needed because text fields will return a PQgetlength() of 0
whether it is '' or NULL.  There is even a comment in the source noting
the fact.

I have changed the value of the 'len' field for NULL result fields.  If
the field is null, the len is set to -1 (NULL_LEN).  I have changed
PQgetlength() to return a 0 length for both '' and NULL.  A new function
PQgetisnull() returns true or false for NULL.

The only risk is to applications that do not use the suggested
PQgetlength() call, but read the result 'len' field directly.

As this is not recommended, I think we are safe here.

A separate documentation patch will be sent.


Submitted by: Bruce Momjian <maillist@candle.pha.pa.us>
上级 78d56d0b
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.14 1996/08/10 00:22:48 scrappy Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.15 1996/08/13 01:34:27 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -156,11 +156,9 @@ getTuple(PGconn *conn, PGresult* result, int binary) ...@@ -156,11 +156,9 @@ getTuple(PGconn *conn, PGresult* result, int binary)
for (i=0;i<nfields;i++) { for (i=0;i<nfields;i++) {
if (!(bmap & 0200)) { if (!(bmap & 0200)) {
/* if the field value is absent, make it '\0' */ /* if the field value is absent, make it '\0' */
/* XXX this makes it impossible to distinguish NULL
attributes from "". Is that OK? */
tup[i].value = (char*)malloc(1); tup[i].value = (char*)malloc(1);
tup[i].value[0] = '\0'; tup[i].value[0] = '\0';
tup[i].len = 0; tup[i].len = NULL_LEN;
} }
else { else {
/* get the value length (the first four bytes are for length) */ /* get the value length (the first four bytes are for length) */
...@@ -1469,6 +1467,35 @@ PQgetlength(PGresult *res, int tup_num, int field_num) ...@@ -1469,6 +1467,35 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
"PQgetlength: ERROR! field %d(of %d) of tuple %d(of %d) is not available", "PQgetlength: ERROR! field %d(of %d) of tuple %d(of %d) is not available",
field_num, res->numAttributes - 1, tup_num, res->ntups); field_num, res->numAttributes - 1, tup_num, res->ntups);
} }
return res->tuples[tup_num][field_num].len; if (res->tuples[tup_num][field_num].len != NULL_LEN)
return res->tuples[tup_num][field_num].len;
else
return 0;
} }
/* PQgetisnull:
returns the null status of a field value.
*/
int
PQgetisnull(PGresult *res, int tup_num, int field_num)
{
if (!res) {
fprintf(stderr, "PQgetisnull() -- pointer to PQresult is null");
return (int)NULL;
}
if (tup_num > (res->ntups - 1 )||
field_num > (res->numAttributes - 1)) {
fprintf(stderr,
"PQgetisnull: ERROR! field %d(of %d) of tuple %d(of %d) is not available",
field_num, res->numAttributes - 1, tup_num, res->ntups);
}
if (res->tuples[tup_num][field_num].len == NULL_LEN)
return 1;
else
return 0;
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq-fe.h,v 1.6 1996/08/06 16:16:50 scrappy Exp $ * $Id: libpq-fe.h,v 1.7 1996/08/13 01:34:29 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -83,6 +83,9 @@ typedef struct pgresAttDesc { ...@@ -83,6 +83,9 @@ typedef struct pgresAttDesc {
For binary tuples, the first four bytes of the value is the size, For binary tuples, the first four bytes of the value is the size,
and the bytes afterwards are the value. The binary value is and the bytes afterwards are the value. The binary value is
not guaranteed to be null-terminated. In fact, it can have embedded nulls*/ not guaranteed to be null-terminated. In fact, it can have embedded nulls*/
#define NULL_LEN (-1) /* pg_result len for NULL value */
typedef struct pgresAttValue { typedef struct pgresAttValue {
int len; /* length in bytes of the value */ int len; /* length in bytes of the value */
char *value; /* actual value */ char *value; /* actual value */
...@@ -178,6 +181,7 @@ extern char* PQcmdStatus(PGresult *res); ...@@ -178,6 +181,7 @@ extern char* PQcmdStatus(PGresult *res);
extern const char* PQoidStatus(PGresult *res); extern const char* PQoidStatus(PGresult *res);
extern char* PQgetvalue(PGresult *res, int tup_num, int field_num); extern char* PQgetvalue(PGresult *res, int tup_num, int field_num);
extern int PQgetlength(PGresult *res, int tup_num, int field_num); extern int PQgetlength(PGresult *res, int tup_num, int field_num);
extern int PQgetisnull(PGresult *res, int tup_num, int field_num);
extern void PQclear(PGresult* res); extern void PQclear(PGresult* res);
/* PQdisplayTuples() is a better version of PQprintTuples() */ /* PQdisplayTuples() is a better version of PQprintTuples() */
extern void PQdisplayTuples(PGresult *res, extern void PQdisplayTuples(PGresult *res,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册