@@ -82,15 +82,16 @@ static bool printCrosstab(const PGresult *results,
8282int num_columns ,pivot_field * piv_columns ,int field_for_columns ,
8383int num_rows ,pivot_field * piv_rows ,int field_for_rows ,
8484int 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 ,
8687int 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 ,
9091pivot_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 intrankCompare(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{
108109char * opt_field_for_rows = pset .ctv_col_V ;
109110char * 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 ,
488496int * * col_numbers ,
489497int max_columns ,
490498char separator )
491499{
492- char * p = arg ;
500+ const char * p = arg ;
493501char 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 ;
499505while ((c = * p )!= '\0' )
500506{
507+ const char * field_start = p ;
501508bool quoted_field = false;
502509
503- field_start = p ;
504-
505510/* first char */
506511if (c == '"' )
507512{
@@ -533,20 +538,27 @@ parseColumnRefs(char *arg,
533538
534539if (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 );
540549gotoerrfail ;
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 );
545557if (col_num < 0 )
546558gotoerrfail ;
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}
551563else
552564{
@@ -557,7 +569,7 @@ parseColumnRefs(char *arg,
557569if (* p )
558570p += PQmblen (p ,pset .encoding );
559571}
560- return nb_cols ;
572+ return num_cols ;
561573
562574errfail :
563575pg_free (* col_numbers );
@@ -776,7 +788,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
776788char c ;
777789
778790if (* p ++ != '"' )
779- return ! pg_strcasecmp (arg ,fieldname );
791+ return ( pg_strcasecmp (arg ,fieldname ) == 0 );
780792
781793while ((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{
810822int idx ;
811823