7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.174 1999/03/30 05:00:42 ishii Exp $
10
+ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.175 1999/04/15 02:24:41 tgl Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -142,6 +142,17 @@ typedef struct _psqlSettings
142
142
* password */
143
143
} PsqlSettings ;
144
144
145
+ /*
146
+ * cur_cmd_source and cur_cmd_interactive are the top of a stack of
147
+ * source files (one stack level per recursive invocation of MainLoop).
148
+ * It's kinda grotty to make these global variables, but the alternative
149
+ * of passing them around through many function parameter lists seems
150
+ * worse.
151
+ */
152
+ static FILE * cur_cmd_source = stdin ; /* current source of command input */
153
+ static bool cur_cmd_interactive = false; /* is it an interactive source? */
154
+
155
+
145
156
#ifdef TIOCGWINSZ
146
157
struct winsize screen_size ;
147
158
@@ -172,10 +183,9 @@ static char *gets_noreadline(char *prompt, FILE *source);
172
183
static char * gets_readline (char * prompt , FILE * source );
173
184
static char * gets_fromFile (char * prompt , FILE * source );
174
185
static int listAllDbs (PsqlSettings * pset );
175
- static void SendQuery (bool * success_p , PsqlSettings * pset , const char * query ,
176
- const bool copy_in , const bool copy_out , FILE * copystream );
177
- static int
178
- HandleSlashCmds (PsqlSettings * pset , char * line , char * query );
186
+ static bool SendQuery (PsqlSettings * pset , const char * query ,
187
+ FILE * copy_in_stream , FILE * copy_out_stream );
188
+ static int HandleSlashCmds (PsqlSettings * pset , char * line , char * query );
179
189
static int MainLoop (PsqlSettings * pset , char * query , FILE * source );
180
190
static FILE * setFout (PsqlSettings * pset , char * fname );
181
191
@@ -1059,7 +1069,7 @@ objectDescription(PsqlSettings *pset, char *object)
1059
1069
1060
1070
PQclear (res );
1061
1071
1062
- SendQuery ( & success , pset , descbuf , false, false , NULL );
1072
+ success = SendQuery ( pset , descbuf , NULL , NULL );
1063
1073
1064
1074
return 0 ;
1065
1075
}
@@ -1132,14 +1142,18 @@ gets_fromFile(char *prompt, FILE *source)
1132
1142
}
1133
1143
1134
1144
/*
1135
- * SendQuery: send the query string to the backend return *success_p = 1 if
1136
- * the query executed successfully returns *success_p = 0 otherwise
1145
+ * SendQuery: send the query string to the backend.
1146
+ *
1147
+ * Return true if the query executed successfully, false otherwise.
1148
+ *
1149
+ * If not NULL, copy_in_stream and copy_out_stream are files to redirect
1150
+ * copy in/out data to.
1137
1151
*/
1138
- static void
1139
- SendQuery (bool * success_p , PsqlSettings * pset , const char * query ,
1140
- const bool copy_in , const bool copy_out , FILE * copystream )
1152
+ static bool
1153
+ SendQuery (PsqlSettings * pset , const char * query ,
1154
+ FILE * copy_in_stream , FILE * copy_out_stream )
1141
1155
{
1142
-
1156
+ bool success = false;
1143
1157
PGresult * results ;
1144
1158
PGnotify * notify ;
1145
1159
@@ -1164,7 +1178,7 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
1164
1178
if (results == NULL )
1165
1179
{
1166
1180
fprintf (stderr , "%s" , PQerrorMessage (pset -> db ));
1167
- * success_p = false;
1181
+ success = false;
1168
1182
}
1169
1183
else
1170
1184
{
@@ -1180,11 +1194,9 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
1180
1194
fp = setFout (& settings_copy , pset -> gfname );
1181
1195
if (!fp || fp == stdout )
1182
1196
{
1183
- * success_p = false;
1197
+ success = false;
1184
1198
break ;
1185
1199
}
1186
- else
1187
- * success_p = true;
1188
1200
PQprint (fp ,
1189
1201
results ,
1190
1202
& pset -> opt );
@@ -1194,48 +1206,49 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
1194
1206
fclose (fp );
1195
1207
free (pset -> gfname );
1196
1208
pset -> gfname = NULL ;
1209
+ success = true;
1197
1210
break ;
1198
1211
}
1199
1212
else
1200
1213
{
1201
- * success_p = true;
1214
+ success = true;
1202
1215
PQprint (pset -> queryFout ,
1203
1216
results ,
1204
1217
& (pset -> opt ));
1205
1218
fflush (pset -> queryFout );
1206
1219
}
1207
1220
break ;
1208
1221
case PGRES_EMPTY_QUERY :
1209
- * success_p = true;
1222
+ success = true;
1210
1223
break ;
1211
1224
case PGRES_COMMAND_OK :
1212
- * success_p = true;
1225
+ success = true;
1213
1226
if (!pset -> quiet )
1214
1227
printf ("%s\n" , PQcmdStatus (results ));
1215
1228
break ;
1216
1229
case PGRES_COPY_OUT :
1217
- if (copy_out )
1218
- * success_p = handleCopyOut (pset -> db , copystream );
1230
+ if (copy_out_stream )
1231
+ success = handleCopyOut (pset -> db , copy_out_stream );
1219
1232
else
1220
1233
{
1221
- if (!pset -> quiet )
1234
+ if (pset -> queryFout == stdout && !pset -> quiet )
1222
1235
printf ("Copy command returns...\n" );
1223
1236
1224
- * success_p = handleCopyOut (pset -> db , stdout );
1237
+ success = handleCopyOut (pset -> db , pset -> queryFout );
1225
1238
}
1226
1239
break ;
1227
1240
case PGRES_COPY_IN :
1228
- if (copy_in )
1229
- * success_p = handleCopyIn (pset -> db , false, copystream );
1241
+ if (copy_in_stream )
1242
+ success = handleCopyIn (pset -> db , false, copy_in_stream );
1230
1243
else
1231
- * success_p = handleCopyIn (pset -> db ,
1232
- ! pset -> quiet && !pset -> notty ,
1233
- stdin );
1244
+ success = handleCopyIn (pset -> db ,
1245
+ cur_cmd_interactive && !pset -> quiet ,
1246
+ cur_cmd_source );
1234
1247
break ;
1235
1248
case PGRES_NONFATAL_ERROR :
1236
1249
case PGRES_FATAL_ERROR :
1237
1250
case PGRES_BAD_RESPONSE :
1238
- * success_p = false;
1251
+ success = false;
1239
1252
fprintf (stderr , "%s" , PQerrorMessage (pset -> db ));
1240
1253
break ;
1241
1254
}
@@ -1259,6 +1272,7 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
1259
1272
if (results )
1260
1273
PQclear (results );
1261
1274
}
1275
+ return success ;
1262
1276
}
1263
1277
1264
1278
@@ -1495,7 +1509,9 @@ do_copy(const char *args, PsqlSettings *pset)
1495
1509
{
1496
1510
bool success ;/* The query succeeded at the backend */
1497
1511
1498
- SendQuery (& success , pset , query , from , !from , copystream );
1512
+ success = SendQuery (pset , query ,
1513
+ from ? copystream : (FILE * ) NULL ,
1514
+ !from ? copystream : (FILE * ) NULL );
1499
1515
fclose (copystream );
1500
1516
if (!pset -> quiet )
1501
1517
{
@@ -1999,7 +2015,7 @@ HandleSlashCmds(PsqlSettings *pset,
1999
2015
strcat (descbuf , "' " );
2000
2016
}
2001
2017
strcat (descbuf , "ORDER BY aggname, type;" );
2002
- SendQuery ( & success , pset , descbuf , false, false , NULL );
2018
+ success = SendQuery ( pset , descbuf , NULL , NULL );
2003
2019
}
2004
2020
else if (strncmp (cmd , "dd" , 2 ) == 0 )
2005
2021
/* descriptions */
@@ -2036,7 +2052,7 @@ HandleSlashCmds(PsqlSettings *pset,
2036
2052
strcat (descbuf , "' " );
2037
2053
}
2038
2054
strcat (descbuf , "ORDER BY result, function, arguments;" );
2039
- SendQuery ( & success , pset , descbuf , false, false , NULL );
2055
+ success = SendQuery ( pset , descbuf , NULL , NULL );
2040
2056
}
2041
2057
else if (strncmp (cmd , "di" , 2 ) == 0 )
2042
2058
/* only indices */
@@ -2110,7 +2126,7 @@ HandleSlashCmds(PsqlSettings *pset,
2110
2126
strcat (descbuf , "' " );
2111
2127
}
2112
2128
strcat (descbuf , "ORDER BY op, left_arg, right_arg, result;" );
2113
- SendQuery ( & success , pset , descbuf , false, false , NULL );
2129
+ success = SendQuery ( pset , descbuf , NULL , NULL );
2114
2130
}
2115
2131
else if (strncmp (cmd , "ds" , 2 ) == 0 )
2116
2132
/* only sequences */
@@ -2139,7 +2155,7 @@ HandleSlashCmds(PsqlSettings *pset,
2139
2155
strcat (descbuf , optarg2 );
2140
2156
strcat (descbuf , "' " );
2141
2157
}
2142
- SendQuery ( & success , pset , descbuf , false, false , NULL );
2158
+ success = SendQuery ( pset , descbuf , NULL , NULL );
2143
2159
}
2144
2160
else if (!optarg )
2145
2161
/* show tables, sequences and indices */
@@ -2413,7 +2429,6 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2413
2429
char * line ; /* line of input */
2414
2430
char * xcomment ; /* start of extended comment */
2415
2431
int len ; /* length of the line */
2416
- bool query_alloced = false;
2417
2432
int successResult = 1 ;
2418
2433
int slashCmdStatus = CMD_SEND ;
2419
2434
@@ -2431,31 +2446,25 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2431
2446
*/
2432
2447
2433
2448
bool querySent = false;
2434
- bool interactive ;
2435
2449
READ_ROUTINE GetNextLine ;
2436
- bool eof = 0 ;
2437
-
2438
- /* We've reached the end of our command input. */
2450
+ bool eof = false; /* end of our command input? */
2439
2451
bool success ;
2440
2452
char in_quote ; /* == 0 for no in_quote */
2441
2453
bool was_bslash ; /* backslash */
2442
2454
int paren_level ;
2443
2455
char * query_start ;
2456
+ /* Stack the prior command source */
2457
+ FILE * prev_cmd_source = cur_cmd_source ;
2458
+ bool prev_cmd_interactive = cur_cmd_interactive ;
2444
2459
2445
- if (query_alloced == false)
2446
- {
2447
- if ((query = malloc (MAX_QUERY_BUFFER )) == NULL )
2448
- {
2449
-
2450
- perror ("Memory Allocation Failed" );
2460
+ /* Establish new source */
2461
+ cur_cmd_source = source ;
2462
+ cur_cmd_interactive = ((source == stdin ) && !pset -> notty );
2451
2463
2452
- }
2453
- else
2454
- query_alloced = true;
2455
- }
2464
+ if ((query = malloc (MAX_QUERY_BUFFER )) == NULL )
2465
+ perror ("Memory Allocation Failed" );
2456
2466
2457
- interactive = ((source == stdin ) && !pset -> notty );
2458
- if (interactive )
2467
+ if (cur_cmd_interactive )
2459
2468
{
2460
2469
if (pset -> prompt )
2461
2470
free (pset -> prompt );
@@ -2504,7 +2513,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2504
2513
}
2505
2514
else
2506
2515
{
2507
- if (interactive && !pset -> quiet )
2516
+ if (cur_cmd_interactive && !pset -> quiet )
2508
2517
{
2509
2518
if (in_quote && in_quote == PROMPT_SINGLEQUOTE )
2510
2519
pset -> prompt [strlen (pset -> prompt ) - 3 ] = PROMPT_SINGLEQUOTE ;
@@ -2519,7 +2528,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2519
2528
}
2520
2529
line = GetNextLine (pset -> prompt , source );
2521
2530
#ifdef USE_HISTORY
2522
- if (interactive && pset -> useReadline && line != NULL )
2531
+ if (cur_cmd_interactive && pset -> useReadline && line != NULL )
2523
2532
add_history (line ); /* save non-empty lines in history */
2524
2533
#endif
2525
2534
}
@@ -2528,7 +2537,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2528
2537
* query - pointer to current command query_start - placeholder
2529
2538
* for next command
2530
2539
*/
2531
- if (line == NULL || (!interactive && * line == '\0' ))
2540
+ if (line == NULL || (!cur_cmd_interactive && * line == '\0' ))
2532
2541
{ /* No more input. Time to quit, or \i
2533
2542
* done */
2534
2543
if (!pset -> quiet )
@@ -2554,7 +2563,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2554
2563
line = rightTrim (line );
2555
2564
2556
2565
/* echo back if input is from file */
2557
- if (!interactive && !pset -> singleStep && !pset -> quiet )
2566
+ if (!cur_cmd_interactive && !pset -> singleStep && !pset -> quiet )
2558
2567
fprintf (stderr , "%s\n" , line );
2559
2568
2560
2569
slashCmdStatus = CMD_UNKNOWN ;
@@ -2569,7 +2578,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2569
2578
2570
2579
if (pset -> singleLineMode )
2571
2580
{
2572
- SendQuery ( & success , pset , line , false, false , NULL );
2581
+ success = SendQuery ( pset , line , NULL , NULL );
2573
2582
successResult &= success ;
2574
2583
querySent = true;
2575
2584
}
@@ -2697,7 +2706,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2697
2706
else
2698
2707
strcpy (query , query_start );
2699
2708
}
2700
- SendQuery ( & success , pset , query , false, false , NULL );
2709
+ success = SendQuery ( pset , query , NULL , NULL );
2701
2710
successResult &= success ;
2702
2711
line [i + 1 ] = hold_char ;
2703
2712
query_start = line + i + 1 ;
@@ -2793,17 +2802,21 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
2793
2802
/* had a backslash-g? force the query to be sent */
2794
2803
if (slashCmdStatus == CMD_SEND )
2795
2804
{
2796
- SendQuery ( & success , pset , query , false, false , NULL );
2805
+ success = SendQuery ( pset , query , NULL , NULL );
2797
2806
successResult &= success ;
2798
2807
xcomment = NULL ;
2799
2808
in_quote = false;
2800
2809
paren_level = 0 ;
2801
2810
querySent = true;
2802
2811
}
2803
2812
} /* while */
2804
- if (query_alloced )
2813
+
2814
+ if (query )
2805
2815
free (query );
2806
2816
2817
+ cur_cmd_source = prev_cmd_source ;
2818
+ cur_cmd_interactive = prev_cmd_interactive ;
2819
+
2807
2820
return successResult ;
2808
2821
} /* MainLoop() */
2809
2822
@@ -3038,12 +3051,7 @@ main(int argc, char **argv)
3038
3051
else
3039
3052
{
3040
3053
if (singleQuery )
3041
- {
3042
- bool success ;/* The query succeeded at the backend */
3043
-
3044
- SendQuery (& success , & settings , singleQuery , false, false, NULL );
3045
- successResult = success ;
3046
- }
3054
+ successResult = SendQuery (& settings , singleQuery , NULL , NULL );
3047
3055
else
3048
3056
successResult = MainLoop (& settings , NULL , stdin );
3049
3057
}
0 commit comments