Hi,
Tom Lane írta:
> Boszormenyi Zoltan <[email protected]> writes:
>
>> in a continued effort for better Informix ESQL/C compatibility,
>> we added the "string" pseudo-type handling to ECPG.
>> ...
>> - "string" has become a type name, reserved word in ECPG.
>>
>
> This seems like a sufficient reason to reject the patch. Who knows
> what that will break? (I observe that it already broke a few of the
> ecpg regression tests, suggesting that using "string" as a variable
> name is hardly uncommon.)
>
> regards, tom lane
>
OK, let me retry. This version treats "string" as a non-reserved word,
and also discovers whether the PGC contains this construct below,
as in ecpg/tests/preproc/type.pgc:
exec sql type string is char[11];
typedef char string[11];
Now all regression tests pass unchanged and ECPG also accepts
string *string;
and
string string[N];
without typedef, replacing "string" with "char".
I think it's acceptable.
Thanks in advance,
Zoltán Böszörményi
--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
http://www.postgresql.at/
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/data.c postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/data.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/data.c 2009-01-15 12:52:55.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/data.c 2009-07-04 12:27:57.000000000 +0200
*************** ecpg_get_data(const PGresult *results, i
*** 138,143 ****
--- 138,144 ----
case ECPGt_char:
case ECPGt_unsigned_char:
case ECPGt_varchar:
+ case ECPGt_string:
break;
default:
*************** ecpg_get_data(const PGresult *results, i
*** 389,394 ****
--- 390,396 ----
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
if (pval)
{
if (varcharsize == 0 || varcharsize > size)
*************** ecpg_get_data(const PGresult *results, i
*** 426,431 ****
--- 428,454 ----
sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
}
}
+ /* Do the rtrim() */
+ if (type == ECPGt_string)
+ {
+ char *str = (char *) ((long) var + offset * act_tuple);
+ char *last;
+ int len = strlen(str);
+
+ last = str + len;
+ while (last > str)
+ {
+ if (*last == '\0')
+ last--;
+ else if (*last == ' ')
+ {
+ *last = '\0';
+ last--;
+ }
+ else
+ break;
+ }
+ }
pval += size;
}
break;
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/descriptor.c postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/descriptor.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/descriptor.c 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/descriptor.c 2009-07-04 12:12:02.000000000 +0200
*************** get_char_item(int lineno, void *var, enu
*** 201,206 ****
--- 201,207 ----
{
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
strncpy((char *) var, value, varcharsize);
break;
case ECPGt_varchar:
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/execute.c postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/execute.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/execute.c 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/execute.c 2009-07-04 12:12:02.000000000 +0200
*************** ecpg_store_result(const PGresult *result
*** 360,365 ****
--- 360,366 ----
{
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
if (!var->varcharsize && !var->arrsize)
{
/* special mode for handling char**foo=0 */
*************** ecpg_store_result(const PGresult *result
*** 419,425 ****
/* fill the variable with the tuple(s) */
if (!var->varcharsize && !var->arrsize &&
! (var->type == ECPGt_char || var->type == ECPGt_unsigned_char))
{
/* special mode for handling char**foo=0 */
--- 420,426 ----
/* fill the variable with the tuple(s) */
if (!var->varcharsize && !var->arrsize &&
! (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
{
/* special mode for handling char**foo=0 */
*************** ecpg_store_input(const int lineno, const
*** 758,763 ****
--- 759,765 ----
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
{
/* set slen to string length if type is char * */
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int) var->varcharsize;
*************** ecpg_execute(struct statement * stmt)
*** 1196,1201 ****
--- 1198,1204 ----
{
case ECPGt_char:
case ECPGt_varchar:
+ case ECPGt_string:
desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
break;
default:
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/misc.c postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/misc.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/misc.c 2009-06-11 16:49:13.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/misc.c 2009-07-04 12:12:02.000000000 +0200
*************** ECPGset_noind_null(enum ECPGttype type,
*** 295,300 ****
--- 295,301 ----
{
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
*((char *) ptr) = '\0';
break;
case ECPGt_short:
*************** ECPGis_noind_null(enum ECPGttype type, v
*** 361,366 ****
--- 362,368 ----
{
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
if (*((char *) ptr) == '\0')
return true;
break;
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/typename.c postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/typename.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/typename.c 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/typename.c 2009-07-04 12:12:02.000000000 +0200
*************** ecpg_type_name(enum ECPGttype typ)
*** 20,25 ****
--- 20,26 ----
switch (typ)
{
case ECPGt_char:
+ case ECPGt_string:
return "char";
case ECPGt_unsigned_char:
return "unsigned char";
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/include/ecpgtype.h postgresql-8.4.0-string/src/interfaces/ecpg/include/ecpgtype.h
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/include/ecpgtype.h 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/include/ecpgtype.h 2009-07-04 12:06:05.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
ECPGt_EOIT, /* End of insert types. */
ECPGt_EORT, /* End of result types. */
ECPGt_NO_INDICATOR, /* no indicator */
! ECPGt_sqlda /* INFORMIX-compatible sqlda_t descriptor */
};
/* descriptor items */
--- 62,69 ----
ECPGt_EOIT, /* End of insert types. */
ECPGt_EORT, /* End of result types. */
ECPGt_NO_INDICATOR, /* no indicator */
! ECPGt_sqlda, /* INFORMIX-compatible sqlda_t descriptor */
! ECPGt_string /* trimmed (char *) type */
};
/* descriptor items */
*************** enum ECPGdtype
*** 87,93 ****
ECPGd_cardinality
};
! #define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_interval)
/* we also have to handle different statement types */
enum ECPG_statement_type
--- 88,94 ----
ECPGd_cardinality
};
! #define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string))
/* we also have to handle different statement types */
enum ECPG_statement_type
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.addons postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.addons
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.addons 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.addons 2009-07-04 16:49:28.000000000 +0200
*************** ECPG: ColIdcol_name_keyword rule
*** 331,336 ****
--- 331,344 ----
| ECPGKeywords { $$ = $1; }
| ECPGCKeywords { $$ = $1; }
| CHAR_P { $$ = make_str("char"); }
+ | STRING_P
+ {
+ struct typedefs *this = get_typedef("string");
+ if (this)
+ $$ = make_str("string");
+ else
+ $$ = make_str("char");
+ }
| VALUES { $$ = make_str("values"); }
ECPG: type_function_nametype_func_name_keyword rule
| ECPGKeywords { $$ = $1; }
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.header postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.header
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.header 2009-06-11 01:11:52.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.header 2009-07-04 11:49:50.000000000 +0200
*************** adjust_informix(struct arguments *list)
*** 256,267 ****
original_var = ptr->variable->name;
sprintf(temp, "%d))", ecpg_informix_var);
! if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
{
ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
sprintf(temp, "%d, (", ecpg_informix_var++);
}
! else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
{
ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
sprintf(temp, "%d, (", ecpg_informix_var++);
--- 256,267 ----
original_var = ptr->variable->name;
sprintf(temp, "%d))", ecpg_informix_var);
! if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1)
{
ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
sprintf(temp, "%d, (", ecpg_informix_var++);
}
! else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char || ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1)
{
ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
sprintf(temp, "%d, (", ecpg_informix_var++);
*************** add_typedef(char *name, char * dimension
*** 371,376 ****
--- 371,377 ----
if (type_enum != ECPGt_varchar &&
type_enum != ECPGt_char &&
type_enum != ECPGt_unsigned_char &&
+ type_enum != ECPGt_string &&
atoi(this->type->type_index) >= 0)
mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.tokens postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.tokens
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.tokens 2008-11-14 11:03:33.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.tokens 2009-07-04 10:59:43.000000000 +0200
***************
*** 25,28 ****
%token TYPECAST
%token CSTRING CVARIABLE CPP_LINE IP
%token DOLCONST ECONST NCONST UCONST UIDENT
!
--- 25,28 ----
%token TYPECAST
%token CSTRING CVARIABLE CPP_LINE IP
%token DOLCONST ECONST NCONST UCONST UIDENT
! %token STRING_P
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.trailer postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.trailer
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.trailer 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.trailer 2009-07-04 17:02:20.000000000 +0200
*************** char_variable: cvariable
*** 213,218 ****
--- 213,219 ----
{
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
$$ = $1;
break;
case ECPGt_varchar:
*************** var_type: simple_type
*** 529,534 ****
--- 530,560 ----
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
}
+ else if (strcmp($1, "string") == 0)
+ {
+ struct typedefs *this = get_typedef($1);
+ if (this == NULL)
+ {
+ $$.type_enum = ECPGt_string;
+ $$.type_str = make_str("char");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else
+ {
+ $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
+ $$.type_enum = this->type->type_enum;
+ $$.type_dimension = this->type->type_dimension;
+ $$.type_index = this->type->type_index;
+ if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
+ $$.type_sizeof = this->type->type_sizeof;
+ else
+ $$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
+
+ struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+ }
+ }
else if (strcmp($1, "float") == 0)
{
$$.type_enum = ECPGt_float;
*************** signed_type: SQL_SHORT { $$ = ECPGt_s
*** 795,800 ****
--- 821,827 ----
}
| SQL_BOOL { $$ = ECPGt_bool; }
| CHAR_P { $$ = ECPGt_char; }
+ | STRING_P { $$ = ECPGt_string; }
| DOUBLE_P { $$ = ECPGt_double; }
;
*************** variable: opt_pointer ECPGColLabel opt_a
*** 855,860 ****
--- 882,888 ----
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
if (atoi(dimension) == -1)
{
int i = strlen($5);
*************** ECPGVar: SQL_VAR
*** 1331,1336 ****
--- 1359,1365 ----
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
if (atoi(dimension) == -1)
type = ECPGmake_simple_type($5.type_enum, length, 0);
else
*************** c_anything: ecpg_ident { $$ = $1; }
*** 2017,2022 ****
--- 2046,2052 ----
| SQL_UNSIGNED { $$ = make_str("unsigned"); }
| YEAR_P { $$ = make_str("year"); }
| CHAR_P { $$ = make_str("char"); }
+ | STRING_P { $$ = make_str("string"); }
| FLOAT_P { $$ = make_str("float"); }
| TO { $$ = make_str("to"); }
| UNION { $$ = make_str("union"); }
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/type.c postgresql-8.4.0-string/src/interfaces/ecpg/preproc/type.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/type.c 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/type.c 2009-07-04 14:12:07.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 200,205 ****
--- 200,208 ----
case ECPGt_timestamp:
return ("ECPGt_timestamp");
break;
+ case ECPGt_string:
+ return ("ECPGt_string");
+ break;
default:
mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type);
}
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 368,373 ****
--- 371,377 ----
case ECPGt_char:
case ECPGt_unsigned_char:
case ECPGt_char_variable:
+ case ECPGt_string:
/*
* we have to use the pointer except for arrays with given
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/variable.c postgresql-8.4.0-string/src/interfaces/ecpg/preproc/variable.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/variable.c 2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/variable.c 2009-07-04 11:45:25.000000000 +0200
*************** adjust_array(enum ECPGttype type_enum, c
*** 524,530 ****
"multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
pointer_len);
! if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char)
mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");
if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
--- 524,530 ----
"multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
pointer_len);
! if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");
if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
*************** adjust_array(enum ECPGttype type_enum, c
*** 563,568 ****
--- 563,569 ----
break;
case ECPGt_char:
case ECPGt_unsigned_char:
+ case ECPGt_string:
/* char ** */
if (pointer_len == 2)
{
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers