@@ -82,15 +82,16 @@ static bool printCrosstab(const PGresult *results,
82
82
int num_columns , pivot_field * piv_columns , int field_for_columns ,
83
83
int num_rows , pivot_field * piv_rows , int field_for_rows ,
84
84
int field_for_data );
85
- static int parseColumnRefs (char * arg , PGresult * res , int * * col_numbers ,
85
+ static int parseColumnRefs (const char * arg , const PGresult * res ,
86
+ int * * col_numbers ,
86
87
int max_columns , char separator );
87
88
static void avlInit (avl_tree * tree );
88
89
static void avlMergeValue (avl_tree * tree , char * name , char * sort_value );
89
90
static int avlCollectFields (avl_tree * tree , avl_node * node ,
90
91
pivot_field * fields , int idx );
91
92
static void avlFree (avl_tree * tree , avl_node * node );
92
93
static void rankSort (int num_columns , pivot_field * piv_columns );
93
- static int indexOfColumn (const char * arg , PGresult * res );
94
+ static int indexOfColumn (const char * arg , const PGresult * res );
94
95
static int pivotFieldCompare (const void * a , const void * b );
95
96
static int rankCompare (const void * a , const void * b );
96
97
@@ -103,7 +104,7 @@ static int rankCompare(const void *a, const void *b);
103
104
* then call printCrosstab() for the actual output.
104
105
*/
105
106
bool
106
- PrintResultsInCrosstab (PGresult * res )
107
+ PrintResultsInCrosstab (const PGresult * res )
107
108
{
108
109
char * opt_field_for_rows = pset .ctv_col_V ;
109
110
char * opt_field_for_columns = pset .ctv_col_H ;
@@ -475,33 +476,37 @@ printCrosstab(const PGresult *results,
475
476
}
476
477
477
478
/*
478
- * Parse col1[<sep>col2][<sep>col3]...
479
- * where colN can be:
479
+ * Parse "arg", which is a string of column IDs separated by "separator".
480
+ *
481
+ * Each column ID can be:
480
482
* - a number from 1 to PQnfields(res)
481
483
* - an unquoted column name matching (case insensitively) one of PQfname(res,...)
482
484
* - a quoted column name matching (case sensitively) one of PQfname(res,...)
483
- * max_columns: 0 if no maximum
485
+ *
486
+ * If max_columns > 0, it is the max number of column IDs allowed.
487
+ *
488
+ * On success, return number of column IDs found (possibly 0), and return a
489
+ * malloc'd array of the matching column numbers of "res" into *col_numbers.
490
+ *
491
+ * On failure, return -1 and set *col_numbers to NULL.
484
492
*/
485
493
static int
486
- parseColumnRefs (char * arg ,
487
- PGresult * res ,
494
+ parseColumnRefs (const char * arg ,
495
+ const PGresult * res ,
488
496
int * * col_numbers ,
489
497
int max_columns ,
490
498
char separator )
491
499
{
492
- char * p = arg ;
500
+ const char * p = arg ;
493
501
char c ;
494
- int col_num = -1 ;
495
- int nb_cols = 0 ;
496
- char * field_start = NULL ;
502
+ int num_cols = 0 ;
497
503
498
504
* col_numbers = NULL ;
499
505
while ((c = * p ) != '\0' )
500
506
{
507
+ const char * field_start = p ;
501
508
bool quoted_field = false;
502
509
503
- field_start = p ;
504
-
505
510
/* first char */
506
511
if (c == '"' )
507
512
{
@@ -533,20 +538,27 @@ parseColumnRefs(char *arg,
533
538
534
539
if (p != field_start )
535
540
{
536
- /* look up the column and add its index into *col_numbers */
537
- if (max_columns != 0 && nb_cols == max_columns )
541
+ char * col_name ;
542
+ int col_num ;
543
+
544
+ /* enforce max_columns limit */
545
+ if (max_columns > 0 && num_cols == max_columns )
538
546
{
539
- psql_error (_ ("No more than %d column references expected\n" ), max_columns );
547
+ psql_error (_ ("No more than %d column references expected\n" ),
548
+ max_columns );
540
549
goto errfail ;
541
550
}
542
- c = * p ;
543
- * p = '\0' ;
544
- col_num = indexOfColumn (field_start , res );
551
+ /* look up the column and add its index into *col_numbers */
552
+ col_name = pg_malloc (p - field_start + 1 );
553
+ memcpy (col_name , field_start , p - field_start );
554
+ col_name [p - field_start ] = '\0' ;
555
+ col_num = indexOfColumn (col_name , res );
556
+ pg_free (col_name );
545
557
if (col_num < 0 )
546
558
goto errfail ;
547
- * p = c ;
548
- * col_numbers = ( int * ) pg_realloc ( * col_numbers , ( 1 + nb_cols ) * sizeof (int ));
549
- (* col_numbers )[nb_cols ++ ] = col_num ;
559
+ * col_numbers = ( int * ) pg_realloc ( * col_numbers ,
560
+ ( num_cols + 1 ) * sizeof (int ));
561
+ (* col_numbers )[num_cols ++ ] = col_num ;
550
562
}
551
563
else
552
564
{
@@ -557,7 +569,7 @@ parseColumnRefs(char *arg,
557
569
if (* p )
558
570
p += PQmblen (p , pset .encoding );
559
571
}
560
- return nb_cols ;
572
+ return num_cols ;
561
573
562
574
errfail :
563
575
pg_free (* col_numbers );
@@ -776,7 +788,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
776
788
char c ;
777
789
778
790
if (* p ++ != '"' )
779
- return ! pg_strcasecmp (arg , fieldname );
791
+ return ( pg_strcasecmp (arg , fieldname ) == 0 );
780
792
781
793
while ((c = * p ++ ))
782
794
{
@@ -805,7 +817,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
805
817
* or if it's ambiguous (arg corresponding to several columns)
806
818
*/
807
819
static int
808
- indexOfColumn (const char * arg , PGresult * res )
820
+ indexOfColumn (const char * arg , const PGresult * res )
809
821
{
810
822
int idx ;
811
823
0 commit comments