77 *
88 *
99 * 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 $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -142,6 +142,17 @@ typedef struct _psqlSettings
142142 * password */
143143}PsqlSettings ;
144144
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+
145156#ifdef TIOCGWINSZ
146157struct winsize screen_size ;
147158
@@ -172,10 +183,9 @@ static char *gets_noreadline(char *prompt, FILE *source);
172183static char * gets_readline (char * prompt ,FILE * source );
173184static char * gets_fromFile (char * prompt ,FILE * source );
174185static 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 );
179189static int MainLoop (PsqlSettings * pset ,char * query ,FILE * source );
180190static FILE * setFout (PsqlSettings * pset ,char * fname );
181191
@@ -1059,7 +1069,7 @@ objectDescription(PsqlSettings *pset, char *object)
10591069
10601070PQclear (res );
10611071
1062- SendQuery ( & success , pset ,descbuf ,false, false ,NULL );
1072+ success = SendQuery ( pset ,descbuf ,NULL ,NULL );
10631073
10641074return 0 ;
10651075}
@@ -1132,14 +1142,18 @@ gets_fromFile(char *prompt, FILE *source)
11321142}
11331143
11341144/*
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.
11371151 */
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 )
11411155{
1142-
1156+ bool success = false;
11431157PGresult * results ;
11441158PGnotify * notify ;
11451159
@@ -1164,7 +1178,7 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
11641178if (results == NULL )
11651179{
11661180fprintf (stderr ,"%s" ,PQerrorMessage (pset -> db ));
1167- * success_p = false;
1181+ success = false;
11681182}
11691183else
11701184{
@@ -1180,11 +1194,9 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
11801194fp = setFout (& settings_copy ,pset -> gfname );
11811195if (!fp || fp == stdout )
11821196{
1183- * success_p = false;
1197+ success = false;
11841198break ;
11851199}
1186- else
1187- * success_p = true;
11881200PQprint (fp ,
11891201results ,
11901202& pset -> opt );
@@ -1194,48 +1206,49 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
11941206fclose (fp );
11951207free (pset -> gfname );
11961208pset -> gfname = NULL ;
1209+ success = true;
11971210break ;
11981211}
11991212else
12001213{
1201- * success_p = true;
1214+ success = true;
12021215PQprint (pset -> queryFout ,
12031216results ,
12041217& (pset -> opt ));
12051218fflush (pset -> queryFout );
12061219}
12071220break ;
12081221case PGRES_EMPTY_QUERY :
1209- * success_p = true;
1222+ success = true;
12101223break ;
12111224case PGRES_COMMAND_OK :
1212- * success_p = true;
1225+ success = true;
12131226if (!pset -> quiet )
12141227printf ("%s\n" ,PQcmdStatus (results ));
12151228break ;
12161229case 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 );
12191232else
12201233{
1221- if (!pset -> quiet )
1234+ if (pset -> queryFout == stdout && !pset -> quiet )
12221235printf ("Copy command returns...\n" );
12231236
1224- * success_p = handleCopyOut (pset -> db ,stdout );
1237+ success = handleCopyOut (pset -> db ,pset -> queryFout );
12251238}
12261239break ;
12271240case 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 );
12301243else
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 );
12341247break ;
12351248case PGRES_NONFATAL_ERROR :
12361249case PGRES_FATAL_ERROR :
12371250case PGRES_BAD_RESPONSE :
1238- * success_p = false;
1251+ success = false;
12391252fprintf (stderr ,"%s" ,PQerrorMessage (pset -> db ));
12401253break ;
12411254}
@@ -1259,6 +1272,7 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
12591272if (results )
12601273PQclear (results );
12611274}
1275+ return success ;
12621276}
12631277
12641278
@@ -1495,7 +1509,9 @@ do_copy(const char *args, PsqlSettings *pset)
14951509{
14961510bool success ;/* The query succeeded at the backend */
14971511
1498- SendQuery (& success ,pset ,query ,from , !from ,copystream );
1512+ success = SendQuery (pset ,query ,
1513+ from ?copystream : (FILE * )NULL ,
1514+ !from ?copystream : (FILE * )NULL );
14991515fclose (copystream );
15001516if (!pset -> quiet )
15011517{
@@ -1999,7 +2015,7 @@ HandleSlashCmds(PsqlSettings *pset,
19992015strcat (descbuf ,"' " );
20002016}
20012017strcat (descbuf ,"ORDER BY aggname, type;" );
2002- SendQuery ( & success , pset ,descbuf ,false, false ,NULL );
2018+ success = SendQuery ( pset ,descbuf ,NULL ,NULL );
20032019}
20042020else if (strncmp (cmd ,"dd" ,2 )== 0 )
20052021/* descriptions */
@@ -2036,7 +2052,7 @@ HandleSlashCmds(PsqlSettings *pset,
20362052strcat (descbuf ,"' " );
20372053}
20382054strcat (descbuf ,"ORDER BY result, function, arguments;" );
2039- SendQuery ( & success , pset ,descbuf ,false, false ,NULL );
2055+ success = SendQuery ( pset ,descbuf ,NULL ,NULL );
20402056}
20412057else if (strncmp (cmd ,"di" ,2 )== 0 )
20422058/* only indices */
@@ -2110,7 +2126,7 @@ HandleSlashCmds(PsqlSettings *pset,
21102126strcat (descbuf ,"' " );
21112127}
21122128strcat (descbuf ,"ORDER BY op, left_arg, right_arg, result;" );
2113- SendQuery ( & success , pset ,descbuf ,false, false ,NULL );
2129+ success = SendQuery ( pset ,descbuf ,NULL ,NULL );
21142130}
21152131else if (strncmp (cmd ,"ds" ,2 )== 0 )
21162132/* only sequences */
@@ -2139,7 +2155,7 @@ HandleSlashCmds(PsqlSettings *pset,
21392155strcat (descbuf ,optarg2 );
21402156strcat (descbuf ,"' " );
21412157}
2142- SendQuery ( & success , pset ,descbuf ,false, false ,NULL );
2158+ success = SendQuery ( pset ,descbuf ,NULL ,NULL );
21432159}
21442160else if (!optarg )
21452161/* show tables, sequences and indices */
@@ -2413,7 +2429,6 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
24132429char * line ;/* line of input */
24142430char * xcomment ;/* start of extended comment */
24152431int len ;/* length of the line */
2416- bool query_alloced = false;
24172432int successResult = 1 ;
24182433int slashCmdStatus = CMD_SEND ;
24192434
@@ -2431,31 +2446,25 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
24312446 */
24322447
24332448bool querySent = false;
2434- bool interactive ;
24352449READ_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? */
24392451bool success ;
24402452char in_quote ;/* == 0 for no in_quote */
24412453bool was_bslash ;/* backslash */
24422454int paren_level ;
24432455char * query_start ;
2456+ /* Stack the prior command source */
2457+ FILE * prev_cmd_source = cur_cmd_source ;
2458+ bool prev_cmd_interactive = cur_cmd_interactive ;
24442459
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 );
24512463
2452- }
2453- else
2454- query_alloced = true;
2455- }
2464+ if ((query = malloc (MAX_QUERY_BUFFER ))== NULL )
2465+ perror ("Memory Allocation Failed" );
24562466
2457- interactive = ((source == stdin )&& !pset -> notty );
2458- if (interactive )
2467+ if (cur_cmd_interactive )
24592468{
24602469if (pset -> prompt )
24612470free (pset -> prompt );
@@ -2504,7 +2513,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
25042513}
25052514else
25062515{
2507- if (interactive && !pset -> quiet )
2516+ if (cur_cmd_interactive && !pset -> quiet )
25082517{
25092518if (in_quote && in_quote == PROMPT_SINGLEQUOTE )
25102519pset -> prompt [strlen (pset -> prompt )- 3 ]= PROMPT_SINGLEQUOTE ;
@@ -2519,7 +2528,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
25192528}
25202529line = GetNextLine (pset -> prompt ,source );
25212530#ifdef USE_HISTORY
2522- if (interactive && pset -> useReadline && line != NULL )
2531+ if (cur_cmd_interactive && pset -> useReadline && line != NULL )
25232532add_history (line );/* save non-empty lines in history */
25242533#endif
25252534}
@@ -2528,7 +2537,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
25282537 * query - pointer to current command query_start - placeholder
25292538 * for next command
25302539 */
2531- if (line == NULL || (!interactive && * line == '\0' ))
2540+ if (line == NULL || (!cur_cmd_interactive && * line == '\0' ))
25322541{/* No more input. Time to quit, or \i
25332542 * done */
25342543if (!pset -> quiet )
@@ -2554,7 +2563,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
25542563line = rightTrim (line );
25552564
25562565/* echo back if input is from file */
2557- if (!interactive && !pset -> singleStep && !pset -> quiet )
2566+ if (!cur_cmd_interactive && !pset -> singleStep && !pset -> quiet )
25582567fprintf (stderr ,"%s\n" ,line );
25592568
25602569slashCmdStatus = CMD_UNKNOWN ;
@@ -2569,7 +2578,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
25692578
25702579if (pset -> singleLineMode )
25712580{
2572- SendQuery ( & success , pset ,line ,false, false ,NULL );
2581+ success = SendQuery ( pset ,line ,NULL ,NULL );
25732582successResult &=success ;
25742583querySent = true;
25752584}
@@ -2697,7 +2706,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
26972706else
26982707strcpy (query ,query_start );
26992708}
2700- SendQuery ( & success , pset ,query ,false, false ,NULL );
2709+ success = SendQuery ( pset ,query ,NULL ,NULL );
27012710successResult &=success ;
27022711line [i + 1 ]= hold_char ;
27032712query_start = line + i + 1 ;
@@ -2793,17 +2802,21 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
27932802/* had a backslash-g? force the query to be sent */
27942803if (slashCmdStatus == CMD_SEND )
27952804{
2796- SendQuery ( & success , pset ,query ,false, false ,NULL );
2805+ success = SendQuery ( pset ,query ,NULL ,NULL );
27972806successResult &=success ;
27982807xcomment = NULL ;
27992808in_quote = false;
28002809paren_level = 0 ;
28012810querySent = true;
28022811}
28032812}/* while */
2804- if (query_alloced )
2813+
2814+ if (query )
28052815free (query );
28062816
2817+ cur_cmd_source = prev_cmd_source ;
2818+ cur_cmd_interactive = prev_cmd_interactive ;
2819+
28072820return successResult ;
28082821}/* MainLoop() */
28092822
@@ -3038,12 +3051,7 @@ main(int argc, char **argv)
30383051else
30393052{
30403053if (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 );
30473055else
30483056successResult = MainLoop (& settings ,NULL ,stdin );
30493057}