Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f393fc

Browse files
author
Michael Meskes
committed
Fixed array handling in ecpg.
When ecpg was rewritten to the new protocol version not all variable types were corrected. This patch rewrites the code for these types to fix that. It also fixes the documentation to correctly tell the status of array handling.
1 parent 025c024 commit 1f393fc

File tree

10 files changed

+533
-453
lines changed

10 files changed

+533
-453
lines changed

doc/src/sgml/ecpg.sgml

+7-4
Original file line numberDiff line numberDiff line change
@@ -1377,10 +1377,13 @@ EXEC SQL END DECLARE SECTION;
13771377
<title>Arrays</title>
13781378

13791379
<para>
1380-
SQL-level arrays are not directly supported in ECPG. It is not
1381-
possible to simply map an SQL array into a C array host variable.
1382-
This will result in undefined behavior. Some workarounds exist,
1383-
however.
1380+
Multi-dimensional SQL-level arrays are not directly supported in ECPG.
1381+
One-dimensional SQL-level arrays can be mapped into C array host
1382+
variables and vice-versa. However, when creating a statement ecpg does
1383+
not know the types of the columns, so that it cannot check if a C array
1384+
is input into a corresponding SQL-level array. When processing the
1385+
output of a SQL statement, ecpg has the necessary information and thus
1386+
checks if both are arrays.
13841387
</para>
13851388

13861389
<para>

src/interfaces/ecpg/ecpglib/data.c

+37-26
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
291291
date ddres;
292292
timestamp tres;
293293
interval *ires;
294+
char *endptr, endchar;
294295

295296
case ECPGt_short:
296297
case ECPGt_int:
@@ -564,10 +565,11 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
564565

565566
case ECPGt_decimal:
566567
case ECPGt_numeric:
567-
if (isarray && *pval == '"')
568-
nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length);
569-
else
570-
nres = PGTYPESnumeric_from_asc(pval, &scan_length);
568+
for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
569+
endchar = *endptr;
570+
*endptr = '\0';
571+
nres = PGTYPESnumeric_from_asc(pval, &scan_length);
572+
*endptr = endchar;
571573

572574
/* did we get an error? */
573575
if (nres == NULL)
@@ -600,10 +602,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
600602
}
601603
else
602604
{
603-
if (isarray && *scan_length == '"')
604-
scan_length++;
605-
606-
if (garbage_left(isarray, scan_length, compat))
605+
if (!isarray && garbage_left(isarray, scan_length, compat))
607606
{
608607
free(nres);
609608
ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
@@ -622,10 +621,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
622621
break;
623622

624623
case ECPGt_interval:
625-
if (isarray && *pval == '"')
626-
ires = PGTYPESinterval_from_asc(pval + 1, &scan_length);
627-
else
628-
ires = PGTYPESinterval_from_asc(pval, &scan_length);
624+
if (*pval == '"')
625+
pval++;
626+
627+
for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
628+
endchar = *endptr;
629+
*endptr = '\0';
630+
ires = PGTYPESinterval_from_asc(pval, &scan_length);
631+
*endptr = endchar;
629632

630633
/* did we get an error? */
631634
if (ires == NULL)
@@ -654,10 +657,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
654657
}
655658
else
656659
{
657-
if (isarray && *scan_length == '"')
660+
if (*scan_length == '"')
658661
scan_length++;
659662

660-
if (garbage_left(isarray, scan_length, compat))
663+
if (!isarray && garbage_left(isarray, scan_length, compat))
661664
{
662665
free(ires);
663666
ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
@@ -672,10 +675,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
672675
break;
673676

674677
case ECPGt_date:
675-
if (isarray && *pval == '"')
676-
ddres = PGTYPESdate_from_asc(pval + 1, &scan_length);
677-
else
678-
ddres = PGTYPESdate_from_asc(pval, &scan_length);
678+
if (*pval == '"')
679+
pval++;
680+
681+
for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
682+
endchar = *endptr;
683+
*endptr = '\0';
684+
ddres = PGTYPESdate_from_asc(pval, &scan_length);
685+
*endptr = endchar;
679686

680687
/* did we get an error? */
681688
if (errno != 0)
@@ -700,10 +707,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
700707
}
701708
else
702709
{
703-
if (isarray && *scan_length == '"')
710+
if (*scan_length == '"')
704711
scan_length++;
705712

706-
if (garbage_left(isarray, scan_length, compat))
713+
if (!isarray && garbage_left(isarray, scan_length, compat))
707714
{
708715
ecpg_raise(lineno, ECPG_DATE_FORMAT,
709716
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -716,10 +723,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
716723
break;
717724

718725
case ECPGt_timestamp:
719-
if (isarray && *pval == '"')
720-
tres = PGTYPEStimestamp_from_asc(pval + 1, &scan_length);
721-
else
722-
tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
726+
if (*pval == '"')
727+
pval++;
728+
729+
for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
730+
endchar = *endptr;
731+
*endptr = '\0';
732+
tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
733+
*endptr = endchar;
723734

724735
/* did we get an error? */
725736
if (errno != 0)
@@ -744,10 +755,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
744755
}
745756
else
746757
{
747-
if (isarray && *scan_length == '"')
758+
if (*scan_length == '"')
748759
scan_length++;
749760

750-
if (garbage_left(isarray, scan_length, compat))
761+
if (!isarray && garbage_left(isarray, scan_length, compat))
751762
{
752763
ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
753764
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);

0 commit comments

Comments
 (0)