diff options
Diffstat (limited to 'src/interfaces/ecpg/lib')
-rw-r--r-- | src/interfaces/ecpg/lib/data.c | 50 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/descriptor.c | 25 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/ecpglib.c | 52 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/error.c | 10 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/typename.c | 25 |
5 files changed, 114 insertions, 48 deletions
diff --git a/src/interfaces/ecpg/lib/data.c b/src/interfaces/ecpg/lib/data.c index 5b30eb1ca4b..af3c78ce591 100644 --- a/src/interfaces/ecpg/lib/data.c +++ b/src/interfaces/ecpg/lib/data.c @@ -8,13 +8,26 @@ 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) + void *var, void *ind, long varcharsize, long offset, + bool isarray) { char *pval = (char *)PQgetvalue(results, act_tuple, act_field); ECPGlog("get_data line %d: RESULT: %s\n", lineno, pval ? pval : ""); /* Now the pval is a pointer to the value. */ + /* let's check is it really is an array if it should be */ + if (isarray) + { + 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); + } + else ++pval; + } + /* We will have to decode the value */ /* @@ -48,8 +61,10 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno, break; } - switch (type) - { + do + { + switch (type) + { long res; unsigned long ures; double dres; @@ -61,7 +76,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno, if (pval) { res = strtol(pval, &scan_length, 10); - if (*scan_length != '\0') /* Garbage left */ + if ((isarray && *scan_length != ',' && *scan_length != '}') + || (!isarray && *scan_length != '\0')) /* Garbage left */ { ECPGraise(lineno, ECPG_INT_FORMAT, pval); return (false); @@ -94,7 +110,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno, if (pval) { ures = strtoul(pval, &scan_length, 10); - if (*scan_length != '\0') /* Garbage left */ + if ((isarray && *scan_length != ',' && *scan_length != '}') + || (!isarray && *scan_length != '\0')) /* Garbage left */ { ECPGraise(lineno, ECPG_UINT_FORMAT, pval); return (false); @@ -127,7 +144,8 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno, if (pval) { dres = strtod(pval, &scan_length); - if (*scan_length != '\0') /* Garbage left */ + if ((isarray && *scan_length != ',' && *scan_length != '}') + || (!isarray && *scan_length != '\0')) /* Garbage left */ { ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval); return (false); @@ -246,7 +264,23 @@ get_data(PGresult *results, int act_tuple, int act_field, int lineno, 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); } diff --git a/src/interfaces/ecpg/lib/descriptor.c b/src/interfaces/ecpg/lib/descriptor.c index 1f0c5536f79..a27915ce5c1 100644 --- a/src/interfaces/ecpg/lib/descriptor.c +++ b/src/interfaces/ecpg/lib/descriptor.c @@ -26,28 +26,6 @@ static PGresult } static unsigned int -ECPGDynamicType(Oid 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; - } -} - -static unsigned int ECPGDynamicType_DDT(Oid type) { switch(type) @@ -61,7 +39,6 @@ ECPGDynamicType_DDT(Oid type) } } - bool ECPGget_desc_header(int lineno, char * desc_name, int *count) { @@ -266,7 +243,7 @@ ECPGget_desc(int lineno, char *desc_name, int index, ...) 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)) + if (!get_data(ECPGresult, 0, index, lineno, vartype, ECPGt_NO_INDICATOR, var, NULL, varcharsize, offset, false)) return (false); break; diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 2891eefe084..c3c262bea4c 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -24,6 +24,7 @@ #include <ecpgtype.h> #include <ecpglib.h> #include <sqlca.h> +#include <sql3types.h> /* variables visible to the programs */ static struct sqlca sqlca_init = @@ -689,23 +690,46 @@ ECPGexecute(struct statement * stmt) isarray = 0; if (PQresultStatus(query) == PGRES_TUPLES_OK) { isarray = atol((char *)PQgetvalue(query, 0, 0)); + if (ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER || + (PQftype(results, act_field)) == SQL3_CHARACTER_VARYING) + { + /* 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"); } PQclear(query); - /* - * 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)) + if (!isarray) { - ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", + /* + * 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); - ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL); - status = false; - break; + ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL); + status = false; + break; + } } - + else + { + /* + * since we read an array, the variable has to be + * an array too + */ + if (var->arrsize == 0) + { + ECPGlog("ECPGexecute line %d: variable is not an array\n"); + ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL); + status = false; + break; + } + } + /* * allocate memory for NULL pointers */ @@ -745,7 +769,7 @@ ECPGexecute(struct statement * stmt) { if (!get_data(results, act_tuple, act_field, stmt->lineno, var->type, var->ind_type, var->value, - var->ind_value, var->varcharsize, var->offset)) + var->ind_value, var->varcharsize, var->offset, isarray)) status = false; } var = var->next; @@ -1067,13 +1091,9 @@ ECPGlog(const char *format,...) * * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de> * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/ecpglib.c,v 1.60 2000/02/23 19:25:43 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/ecpglib.c,v 1.61 2000/03/01 12:49:42 meskes Exp $ */ -/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */ - -#include <sql3types.h> - PGconn *ECPG_internal_get_connection(char *name); extern struct descriptor diff --git a/src/interfaces/ecpg/lib/error.c b/src/interfaces/ecpg/lib/error.c index aa63fe94397..54e48a55271 100644 --- a/src/interfaces/ecpg/lib/error.c +++ b/src/interfaces/ecpg/lib/error.c @@ -67,6 +67,16 @@ ECPGraise(int line, int code, const char *str) 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), diff --git a/src/interfaces/ecpg/lib/typename.c b/src/interfaces/ecpg/lib/typename.c index af87b160aa9..1999ab82d75 100644 --- a/src/interfaces/ecpg/lib/typename.c +++ b/src/interfaces/ecpg/lib/typename.c @@ -1,5 +1,8 @@ #include <stdlib.h> #include <ecpgtype.h> +#include <ecpglib.h> +#include <sql3types.h> + /* * This function is used to generate the correct type names. */ @@ -39,3 +42,25 @@ ECPGtype_name(enum ECPGttype typ) } return NULL; } + +unsigned int +ECPGDynamicType(Oid 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; + } +} |