@@ -82,15 +82,16 @@ static bool printCrosstab(const PGresult *results,
8282 int num_columns , pivot_field * piv_columns , int field_for_columns ,
8383 int num_rows , pivot_field * piv_rows , int field_for_rows ,
8484 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 ,
8687 int max_columns , char separator );
8788static void avlInit (avl_tree * tree );
8889static void avlMergeValue (avl_tree * tree , char * name , char * sort_value );
8990static int avlCollectFields (avl_tree * tree , avl_node * node ,
9091 pivot_field * fields , int idx );
9192static void avlFree (avl_tree * tree , avl_node * node );
9293static 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 );
9495static int pivotFieldCompare (const void * a , const void * b );
9596static int rankCompare (const void * a , const void * b );
9697
@@ -103,7 +104,7 @@ static int rankCompare(const void *a, const void *b);
103104 * then call printCrosstab() for the actual output.
104105 */
105106bool
106- PrintResultsInCrosstab (PGresult * res )
107+ PrintResultsInCrosstab (const PGresult * res )
107108{
108109 char * opt_field_for_rows = pset .ctv_col_V ;
109110 char * opt_field_for_columns = pset .ctv_col_H ;
@@ -475,33 +476,37 @@ printCrosstab(const PGresult *results,
475476}
476477
477478/*
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:
480482 * - a number from 1 to PQnfields(res)
481483 * - an unquoted column name matching (case insensitively) one of PQfname(res,...)
482484 * - 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.
484492 */
485493static int
486- parseColumnRefs (char * arg ,
487- PGresult * res ,
494+ parseColumnRefs (const char * arg ,
495+ const PGresult * res ,
488496 int * * col_numbers ,
489497 int max_columns ,
490498 char separator )
491499{
492- char * p = arg ;
500+ const char * p = arg ;
493501 char c ;
494- int col_num = -1 ;
495- int nb_cols = 0 ;
496- char * field_start = NULL ;
502+ int num_cols = 0 ;
497503
498504 * col_numbers = NULL ;
499505 while ((c = * p ) != '\0' )
500506 {
507+ const char * field_start = p ;
501508 bool quoted_field = false;
502509
503- field_start = p ;
504-
505510 /* first char */
506511 if (c == '"' )
507512 {
@@ -533,20 +538,27 @@ parseColumnRefs(char *arg,
533538
534539 if (p != field_start )
535540 {
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 )
538546 {
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 );
540549 goto errfail ;
541550 }
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 );
545557 if (col_num < 0 )
546558 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 ;
550562 }
551563 else
552564 {
@@ -557,7 +569,7 @@ parseColumnRefs(char *arg,
557569 if (* p )
558570 p += PQmblen (p , pset .encoding );
559571 }
560- return nb_cols ;
572+ return num_cols ;
561573
562574errfail :
563575 pg_free (* col_numbers );
@@ -776,7 +788,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
776788 char c ;
777789
778790 if (* p ++ != '"' )
779- return ! pg_strcasecmp (arg , fieldname );
791+ return ( pg_strcasecmp (arg , fieldname ) == 0 );
780792
781793 while ((c = * p ++ ))
782794 {
@@ -805,7 +817,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
805817 * or if it's ambiguous (arg corresponding to several columns)
806818 */
807819static int
808- indexOfColumn (const char * arg , PGresult * res )
820+ indexOfColumn (const char * arg , const PGresult * res )
809821{
810822 int idx ;
811823
0 commit comments