PostgreSQL Source Code: src/bin/psql/command.c Source File (original) (raw)
1
2
3
4
5
6
7
9
10#include <ctype.h>
14#ifndef WIN32
15#include <sys/stat.h>
16#include <sys/time.h>
17#include <fcntl.h>
18#include <unistd.h>
19#else
20#include <win32.h>
21#include <io.h>
22#include <fcntl.h>
23#include <direct.h>
24#include <sys/stat.h>
25#endif
26
27#include "catalog/pg_class_d.h"
46
47
48
49
51{
55
56
65 const char *cmd);
69 const char *cmd);
71 const char *cmd);
77 const char *cmd);
79 const char *pattern,
80 bool show_verbose, bool show_system);
86 const char *cmd);
100 const char *cmd);
103 bool active_branch,
104 const char *cmd);
107 const char *cmd);
114 const char *cmd);
118 const char *cmd);
120 const char *cmd);
125 const char *cmd);
128 const char *cmd);
137 const char *cmd);
139 const char *cmd, bool is_func);
146 const char *cmd);
148 const char *cmd,
154 const char *cmd);
174 int lineno, bool discard_on_quit, bool *edited);
175static bool do_shell(const char *command);
176static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows);
178 Oid *obj_oid);
185
190
191#ifdef WIN32
192static void checkWin32Codepage(void);
193#endif
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
229{
231 char *cmd;
232 char *arg;
233
234 Assert(scan_state != NULL);
235 Assert(cstack != NULL);
236
237
239
240
241 status = exec_command(cmd, scan_state, cstack, query_buf, previous_buf);
242
244 {
249 }
250
252 {
253
254
255
256
257
259
263 {
264 if (active_branch)
267 }
269 }
270 else
271 {
272
276 }
277
278
280
282
283
285
286 return status;
287}
288
289
290
291
292
293
294
295
296
303{
306
307
308
309
310
311
312
313
316 {
317 pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
318 cmd);
319 }
320
321 if (strcmp(cmd, "a") == 0)
323 else if (strcmp(cmd, "bind") == 0)
325 else if (strcmp(cmd, "bind_named") == 0)
327 else if (strcmp(cmd, "C") == 0)
329 else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
331 else if (strcmp(cmd, "cd") == 0)
332 status = exec_command_cd(scan_state, active_branch, cmd);
333 else if (strcmp(cmd, "close") == 0)
335 else if (strcmp(cmd, "conninfo") == 0)
339 else if (strcmp(cmd, "copyright") == 0)
341 else if (strcmp(cmd, "crosstabview") == 0)
343 else if (cmd[0] == 'd')
344 status = exec_command_d(scan_state, active_branch, cmd);
345 else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
347 query_buf, previous_buf);
348 else if (strcmp(cmd, "ef") == 0)
349 status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
350 else if (strcmp(cmd, "ev") == 0)
351 status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
352 else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
353 strcmp(cmd, "warn") == 0)
355 else if (strcmp(cmd, "elif") == 0)
357 else if (strcmp(cmd, "else") == 0)
359 else if (strcmp(cmd, "endif") == 0)
361 else if (strcmp(cmd, "endpipeline") == 0)
363 else if (strcmp(cmd, "encoding") == 0)
365 else if (strcmp(cmd, "errverbose") == 0)
367 else if (strcmp(cmd, "f") == 0)
369 else if (strcmp(cmd, "flush") == 0)
371 else if (strcmp(cmd, "flushrequest") == 0)
373 else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
374 status = exec_command_g(scan_state, active_branch, cmd);
375 else if (strcmp(cmd, "gdesc") == 0)
377 else if (strcmp(cmd, "getenv") == 0)
379 else if (strcmp(cmd, "getresults") == 0)
381 else if (strcmp(cmd, "gexec") == 0)
383 else if (strcmp(cmd, "gset") == 0)
385 else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
387 else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
389 else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
390 strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
392 else if (strcmp(cmd, "if") == 0)
394 else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
395 strcmp(cmd, "lx") == 0 || strcmp(cmd, "listx") == 0 ||
396 strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0 ||
397 strcmp(cmd, "lx+") == 0 || strcmp(cmd, "listx+") == 0 ||
398 strcmp(cmd, "l+x") == 0 || strcmp(cmd, "list+x") == 0)
400 else if (strncmp(cmd, "lo_", 3) == 0)
401 status = exec_command_lo(scan_state, active_branch, cmd);
402 else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
404 else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
406 query_buf, previous_buf);
407 else if (strcmp(cmd, "parse") == 0)
409 else if (strcmp(cmd, "password") == 0)
411 else if (strcmp(cmd, "prompt") == 0)
413 else if (strcmp(cmd, "pset") == 0)
415 else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
417 else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
419 else if (strcmp(cmd, "s") == 0)
421 else if (strcmp(cmd, "sendpipeline") == 0)
423 else if (strcmp(cmd, "set") == 0)
425 else if (strcmp(cmd, "setenv") == 0)
427 else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
429 else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
431 else if (strcmp(cmd, "startpipeline") == 0)
433 else if (strcmp(cmd, "syncpipeline") == 0)
435 else if (strcmp(cmd, "t") == 0)
437 else if (strcmp(cmd, "T") == 0)
439 else if (strcmp(cmd, "timing") == 0)
441 else if (strcmp(cmd, "unset") == 0)
443 else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
445 query_buf, previous_buf);
446 else if (strcmp(cmd, "watch") == 0)
448 query_buf, previous_buf);
449 else if (strcmp(cmd, "x") == 0)
451 else if (strcmp(cmd, "z") == 0 ||
452 strcmp(cmd, "zS") == 0 || strcmp(cmd, "zx") == 0 ||
453 strcmp(cmd, "zSx") == 0 || strcmp(cmd, "zxS") == 0)
454 status = exec_command_z(scan_state, active_branch, cmd);
455 else if (strcmp(cmd, "!") == 0)
457 else if (strcmp(cmd, "?") == 0)
459 else
461
462
463
464
465
466
469
470 return status;
471}
472
473
474
475
476
477
478
481{
483
484 if (active_branch)
485 {
488 else
490 }
491
493}
494
495
496
497
500{
502
503 if (active_branch)
504 {
505 char *opt;
506 int nparams = 0;
507 int nalloc = 0;
508
510
512 {
513 nparams++;
514 if (nparams > nalloc)
515 {
516 nalloc = nalloc ? nalloc * 2 : 1;
518 }
520 }
521
524 }
525 else
527
528 return status;
529}
530
531
532
533
536 const char *cmd)
537{
539
540 if (active_branch)
541 {
542 char *opt;
543 int nparams = 0;
544 int nalloc = 0;
545
547
548
550 if (!opt)
551 {
552 pg_log_error("\\%s: missing required argument", cmd);
554 }
555 else
556 {
559
560
562 {
563 nparams++;
564 if (nparams > nalloc)
565 {
566 nalloc = nalloc ? nalloc * 2 : 1;
568 }
570 }
572 }
573 }
574 else
576
577 return status;
578}
579
580
581
582
585{
587
588 if (active_branch)
589 {
592
595 }
596 else
598
600}
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
618{
620
621 if (active_branch)
622 {
623 static const char prefix[] = "-reuse-previous=";
624 char *opt1,
625 *opt2,
626 *opt3,
627 *opt4;
629
631 if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
632 {
633 bool on_off;
634
636 "-reuse-previous",
637 &on_off);
639 {
643 }
644 }
645
646 if (success)
647 {
651
653
657 }
659 }
660 else
662
664}
665
666
667
668
671{
673
674 if (active_branch)
675 {
678 char *dir;
679
680 if (opt)
681 dir = opt;
682 else
683 {
684#ifndef WIN32
685
686 dir = getenv("HOME");
687 if (dir == NULL || dir[0] == '\0')
688 {
689 uid_t user_id = geteuid();
690 struct passwd *pw;
691
692 errno = 0;
693 pw = getpwuid(user_id);
694 if (pw)
695 dir = pw->pw_dir;
696 else
697 {
698 pg_log_error("could not get home directory for user ID %ld: %s",
699 (long) user_id,
700 errno ? strerror(errno) : _("user does not exist"));
702 }
703 }
704#else
705
706
707
708
709
710 dir = "/";
711#endif
712 }
713
715 chdir(dir) < 0)
716 {
717 pg_log_error("\\%s: could not change directory to \"%s\": %m",
718 cmd, dir);
720 }
721
723 }
724 else
726
728}
729
730
731
732
735{
737
738 if (active_branch)
739 {
742
744
745 if (!opt)
746 {
747 pg_log_error("\\%s: missing required argument", cmd);
749 }
750 else
751 {
755 }
756 }
757 else
759
760 return status;
761}
762
763
764
765
768{
770 int rows,
771 cols;
772 char *db;
773 char *host;
774 bool print_hostaddr;
775 char *hostaddr;
776 char *protocol_version,
777 *backend_pid;
778 int ssl_in_use,
779 password_used,
780 gssapi_used;
781 char *paramval;
782
783 if (!active_branch)
785
787 if (db == NULL)
788 {
789 printf(_("You are currently not connected to a database.\n"));
791 }
792
793
801
802
804 hostaddr && *hostaddr && strcmp(host, hostaddr) != 0);
805
806
807 rows = 12;
808 cols = 2;
809 if (ssl_in_use)
810 rows += 6;
811 if (print_hostaddr)
812 rows++;
813
814
818
819
822
823
826
827
829 {
830
831 if (hostaddr && *hostaddr)
832 {
835 }
836 else
837 {
840 }
841 }
842 else
843 {
846 if (print_hostaddr)
847 {
850 }
851 }
852
853
856
857
860
861
864
865
867 printTableAddCell(&cont, password_used ? _("true") : _("false"), false, false);
868
869
871 printTableAddCell(&cont, gssapi_used ? _("true") : _("false"), false, false);
872
873
876
877
879 printTableAddCell(&cont, ssl_in_use ? _("true") : _("false"), false, false);
880
881
882 if (ssl_in_use)
883 {
884 char *library,
885 *protocol,
886 *key_bits,
887 *cipher,
888 *compression,
889 *alpn;
890
897
899 printTableAddCell(&cont, library ? library : _("unknown"), false, false);
900
902 printTableAddCell(&cont, protocol ? protocol : _("unknown"), false, false);
903
905 printTableAddCell(&cont, key_bits ? key_bits : _("unknown"), false, false);
906
908 printTableAddCell(&cont, cipher ? cipher : _("unknown"), false, false);
909
911 printTableAddCell(&cont, (compression && strcmp(compression, "off") != 0) ?
912 _("true") : _("false"), false, false);
913
915 printTableAddCell(&cont, (alpn && alpn[0] != '\0') ? alpn : _("none"), false, false);
916 }
917
920 printTableAddCell(&cont, paramval ? paramval : _("unknown"), false, false);
921
924 printTableAddCell(&cont, paramval ? paramval : _("unknown"), false, false);
925
928
929 pfree(protocol_version);
930 pfree(backend_pid);
931
933}
934
935
936
937
940{
942
943 if (active_branch)
944 {
947
950 }
951 else
953
955}
956
957
958
959
962{
963 if (active_branch)
965
967}
968
969
970
971
974{
976
977 if (active_branch)
978 {
979 int i;
980
986 }
987 else
989
990 return status;
991}
992
993
994
995
998{
1001
1002 if (active_branch)
1003 {
1004 char *pattern;
1005 bool show_verbose,
1006 show_system;
1007 unsigned short int save_expanded;
1008
1009
1012
1013 show_verbose = strchr(cmd, '+') ? true : false;
1014 show_system = strchr(cmd, 'S') ? true : false;
1015
1016
1017
1018
1019
1020
1021
1023 if (cmd[1] != '\0' && strchr(&cmd[2], 'x'))
1025
1026 switch (cmd[1])
1027 {
1028 case '\0':
1029 case '+':
1030 case 'S':
1031 if (pattern)
1033 else
1034
1036 break;
1037 case 'A':
1038 {
1039 char *pattern2 = NULL;
1040
1041 if (pattern && cmd[2] != '\0' && cmd[2] != '+' && cmd[2] != 'x')
1043
1044 switch (cmd[2])
1045 {
1046 case '\0':
1047 case '+':
1048 case 'x':
1050 break;
1051 case 'c':
1053 break;
1054 case 'f':
1056 break;
1057 case 'o':
1059 break;
1060 case 'p':
1062 break;
1063 default:
1065 break;
1066 }
1067
1068 free(pattern2);
1069 }
1070 break;
1071 case 'a':
1073 break;
1074 case 'b':
1076 break;
1077 case 'c':
1078 if (strncmp(cmd, "dconfig", 7) == 0)
1080 show_verbose,
1081 show_system);
1082 else
1084 show_verbose,
1085 show_system);
1086 break;
1087 case 'C':
1089 break;
1090 case 'd':
1091 if (strncmp(cmd, "ddp", 3) == 0)
1093 else
1095 break;
1096 case 'D':
1098 break;
1099 case 'f':
1100 switch (cmd[2])
1101 {
1102 case '\0':
1103 case '+':
1104 case 'S':
1105 case 'a':
1106 case 'n':
1107 case 'p':
1108 case 't':
1109 case 'w':
1110 case 'x':
1112 show_verbose, show_system);
1113 break;
1114 default:
1116 break;
1117 }
1118 break;
1119 case 'g':
1120
1122 break;
1123 case 'l':
1125 break;
1126 case 'L':
1128 break;
1129 case 'n':
1131 break;
1132 case 'o':
1134 show_verbose, show_system);
1135 break;
1136 case 'O':
1138 break;
1139 case 'p':
1141 break;
1142 case 'P':
1143 {
1144 switch (cmd[2])
1145 {
1146 case '\0':
1147 case '+':
1148 case 't':
1149 case 'i':
1150 case 'n':
1151 case 'x':
1153 break;
1154 default:
1156 break;
1157 }
1158 }
1159 break;
1160 case 'T':
1162 break;
1163 case 't':
1164 case 'v':
1165 case 'm':
1166 case 'i':
1167 case 's':
1168 case 'E':
1169 success = listTables(&cmd[1], pattern, show_verbose, show_system);
1170 break;
1171 case 'r':
1172 if (cmd[2] == 'd' && cmd[3] == 's')
1173 {
1174 char *pattern2 = NULL;
1175
1176 if (pattern)
1180
1181 free(pattern2);
1182 }
1183 else if (cmd[2] == 'g')
1185 else
1187 break;
1188 case 'R':
1189 switch (cmd[2])
1190 {
1191 case 'p':
1192 if (show_verbose)
1194 else
1196 break;
1197 case 's':
1199 break;
1200 default:
1202 }
1203 break;
1204 case 'u':
1206 break;
1207 case 'F':
1208 switch (cmd[2])
1209 {
1210 case '\0':
1211 case '+':
1212 case 'x':
1214 break;
1215 case 'p':
1217 break;
1218 case 'd':
1220 break;
1221 case 't':
1223 break;
1224 default:
1226 break;
1227 }
1228 break;
1229 case 'e':
1230 switch (cmd[2])
1231 {
1232 case 's':
1234 break;
1235 case 'u':
1237 break;
1238 case 'w':
1240 break;
1241 case 't':
1243 break;
1244 default:
1246 break;
1247 }
1248 break;
1249 case 'x':
1250 if (show_verbose)
1252 else
1254 break;
1255 case 'X':
1257 break;
1258 case 'y':
1260 break;
1261 default:
1263 }
1264
1265
1267
1268 free(pattern);
1269 }
1270 else
1272
1275
1276 return status;
1277}
1278
1279
1280static bool
1282 const char *pattern,
1283 bool show_verbose, bool show_system)
1284{
1287 int num_arg_patterns = 0;
1288
1289
1290 if (pattern)
1291 {
1292 char *ap;
1293
1295 OT_NORMAL, NULL, true)) != NULL)
1296 {
1297 arg_patterns[num_arg_patterns++] = ap;
1299 break;
1300 }
1301 }
1302
1303 if (cmd[1] == 'f')
1305 arg_patterns, num_arg_patterns,
1306 show_verbose, show_system);
1307 else
1309 arg_patterns, num_arg_patterns,
1310 show_verbose, show_system);
1311
1312 while (--num_arg_patterns >= 0)
1313 free(arg_patterns[num_arg_patterns]);
1314
1316}
1317
1318
1319
1320
1321
1325{
1327
1328 if (active_branch)
1329 {
1330 if (!query_buf)
1331 {
1334 }
1335 else
1336 {
1337 char *fname;
1338 char *ln = NULL;
1339 int lineno = -1;
1340
1343 if (fname)
1344 {
1345
1348 if (ln == NULL)
1349 {
1350
1351 if (fname[0] &&
1352 strspn(fname, "0123456789") == strlen(fname))
1353 {
1354
1355 ln = fname;
1356 fname = NULL;
1357 }
1358 }
1359 }
1360 if (ln)
1361 {
1362 lineno = atoi(ln);
1363 if (lineno < 1)
1364 {
1365 pg_log_error("invalid line number: %s", ln);
1367 }
1368 }
1370 {
1371 bool discard_on_quit;
1372
1374 if (fname)
1375 {
1377
1378 discard_on_quit = true;
1379 }
1380 else
1381 {
1382
1383
1384
1385
1386
1388 previous_buf);
1389 }
1390
1391 if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL))
1393 else
1395 }
1396
1397
1398
1399
1400
1403
1404 free(fname);
1406 }
1407 }
1408 else
1410
1411 return status;
1412}
1413
1414
1415
1416
1417
1421{
1423
1424 if (active_branch)
1425 {
1428 NULL, true);
1429 int lineno = -1;
1430
1431 if (!query_buf)
1432 {
1435 }
1436 else
1437 {
1440
1442 if (lineno == 0)
1443 {
1444
1446 }
1447 else if (!obj_desc)
1448 {
1449
1451 if (is_func)
1453 "CREATE FUNCTION ( )\n"
1454 " RETURNS \n"
1455 " LANGUAGE \n"
1456 " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1457 "AS functionfunctionfunction\n"
1458 "\n$function$\n");
1459 else
1461 "CREATE VIEW AS\n"
1462 " SELECT \n"
1463 " -- something...\n");
1464 }
1466 {
1467
1469 }
1471 {
1472
1474 }
1475 else if (is_func && lineno > 0)
1476 {
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486 const char *lines = query_buf->data;
1487
1488 while (*lines != '\0')
1489 {
1490 if (strncmp(lines, "AS ", 3) == 0 ||
1491 strncmp(lines, "BEGIN ", 6) == 0 ||
1492 strncmp(lines, "RETURN ", 7) == 0)
1493 break;
1494 lineno++;
1495
1496 lines = strchr(lines, '\n');
1497 if (!lines)
1498 break;
1499 lines++;
1500 }
1501 }
1502 }
1503
1505 {
1506 bool edited = false;
1507
1508 if ((NULL, query_buf, lineno, true, &edited))
1510 else if (!edited)
1511 puts(_("No changes"));
1512 else
1514 }
1515
1516
1517
1518
1519
1522
1523 free(obj_desc);
1524 }
1525 else
1527
1528 return status;
1529}
1530
1531
1532
1533
1536{
1537 if (active_branch)
1538 {
1540 char quoted;
1541 bool no_newline = false;
1542 bool first = true;
1543 FILE *fout;
1544
1545 if (strcmp(cmd, "qecho") == 0)
1547 else if (strcmp(cmd, "warn") == 0)
1548 fout = stderr;
1549 else
1551
1554 {
1555 if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1556 no_newline = true;
1557 else
1558 {
1559 if (first)
1560 first = false;
1561 else
1562 fputc(' ', fout);
1563 fputs(value, fout);
1564 }
1566 }
1567 if (!no_newline)
1568 fputs("\n", fout);
1569 }
1570 else
1572
1574}
1575
1576
1577
1578
1581{
1582 if (active_branch)
1583 {
1586
1588 {
1589
1591 }
1592 else
1593 {
1594
1596 pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1597 else
1598 {
1599
1605 }
1607 }
1608 }
1609 else
1611
1613}
1614
1615
1616
1617
1620{
1621 if (active_branch)
1622 {
1624 {
1625 char *msg;
1626
1630 if (msg)
1631 {
1634 }
1635 else
1636 puts(_("out of memory"));
1637 }
1638 else
1639 puts(_("There is no previous error."));
1640 }
1641
1643}
1644
1645
1646
1647
1650{
1652
1653 if (active_branch)
1654 {
1657
1659 free(fname);
1660 }
1661 else
1663
1665}
1666
1667
1668
1669
1672{
1674
1675 if (active_branch)
1676 {
1679 }
1680 else
1682
1683 return status;
1684}
1685
1686
1687
1688
1691{
1693
1694 if (active_branch)
1695 {
1698 }
1699 else
1701
1702 return status;
1703}
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1716{
1718 char *fname;
1719
1720
1721
1722
1723
1726
1727 if (fname && fname[0] == '(')
1728 {
1729
1731 active_branch, cmd);
1732 free(fname);
1733
1736 }
1737
1739 {
1741 {
1742 pg_log_error("\\%s not allowed in pipeline mode", cmd);
1744 free(fname);
1746 }
1747
1748 if (!fname)
1750 else
1751 {
1754 }
1755 if (strcmp(cmd, "gx") == 0)
1756 {
1757
1761 }
1763 }
1764
1765 free(fname);
1766
1767 return status;
1768}
1769
1770
1771
1772
1773
1774
1777 bool active_branch, const char *cmd)
1778{
1780 bool found_r_paren = false;
1781
1782 do
1783 {
1785 size_t optlen;
1786
1787
1788 if (first_option)
1789 option = first_option;
1790 else
1791 {
1795 {
1796 if (active_branch)
1797 {
1798 pg_log_error("\\%s: missing right parenthesis", cmd);
1800 }
1801 break;
1802 }
1803 }
1804
1805
1806 optlen = strlen(option);
1807 if (optlen > 0 && option[optlen - 1] == ')')
1808 {
1809 option[--optlen] = '\0';
1810 found_r_paren = true;
1811 }
1812
1813
1814 if (optlen > 0)
1815 {
1816
1817 char *valptr = strchr(option, '=');
1818
1819 if (valptr)
1820 *valptr++ = '\0';
1821 if (active_branch)
1822 {
1823
1827 }
1828 }
1829
1830
1831 if (first_option)
1832 first_option = NULL;
1833 else
1835 } while (!found_r_paren);
1836
1837
1839 {
1842 }
1843
1845}
1846
1847
1848
1849
1852{
1854
1855 if (active_branch)
1856 {
1859 }
1860
1861 return status;
1862}
1863
1864
1865
1866
1869 const char *cmd)
1870{
1872
1873 if (active_branch)
1874 {
1879
1880 if (!myvar || !envvar)
1881 {
1882 pg_log_error("\\%s: missing required argument", cmd);
1884 }
1885 else
1886 {
1887 char *envval = getenv(envvar);
1888
1891 }
1892 free(myvar);
1893 free(envvar);
1894 }
1895 else
1897
1899}
1900
1901
1902
1903
1906{
1908
1909 if (active_branch)
1910 {
1911 char *opt;
1912 int num_results;
1913
1917
1919 if (opt != NULL)
1920 {
1921 num_results = atoi(opt);
1922 if (num_results < 0)
1923 {
1924 pg_log_error("\\getresults: invalid number of requested results");
1926 }
1928 }
1929 }
1930 else
1932
1933 return status;
1934}
1935
1936
1937
1938
1939
1942{
1944
1945 if (active_branch)
1946 {
1948 {
1949 pg_log_error("\\gexec not allowed in pipeline mode");
1952 }
1955 }
1956
1957 return status;
1958}
1959
1960
1961
1962
1965{
1967
1968 if (active_branch)
1969 {
1972
1974 {
1975 pg_log_error("\\gset not allowed in pipeline mode");
1978 }
1979
1980 if (prefix)
1982 else
1983 {
1984
1986 }
1987
1989 }
1990 else
1992
1993 return status;
1994}
1995
1996
1997
1998
2001{
2002 if (active_branch)
2003 {
2006
2009 }
2010 else
2012
2014}
2015
2016
2017
2018
2021{
2023
2024 if (active_branch)
2025 {
2028 else
2030 }
2031
2033}
2034
2035
2036
2037
2040{
2042
2043 if (active_branch)
2044 {
2047
2048 if (!fname)
2049 {
2050 pg_log_error("\\%s: missing required argument", cmd);
2052 }
2053 else
2054 {
2055 bool include_relative;
2056
2057 include_relative = (strcmp(cmd, "ir") == 0
2058 || strcmp(cmd, "include_relative") == 0);
2061 free(fname);
2062 }
2063 }
2064 else
2066
2068}
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2082{
2084 {
2085
2086
2087
2088
2089
2090
2092
2093
2095
2096
2097
2098
2101 }
2102 else
2103 {
2104
2105
2106
2107
2108
2110
2111
2113
2115 }
2116
2118}
2119
2120
2121
2122
2123
2124
2128{
2130
2132 {
2134
2135
2136
2137
2138
2139
2141
2142
2143
2144
2145
2146
2149 break;
2151
2152
2153
2154
2156
2157
2158
2159
2160
2161
2165 break;
2167
2168
2169
2170
2172
2173
2174
2175
2176
2178 break;
2181 pg_log_error("\\elif: cannot occur after \\else");
2183 break;
2185
2188 break;
2189 }
2190
2192}
2193
2194
2195
2196
2197
2198
2199
2200
2204{
2206
2208 {
2210
2211
2212
2213
2214
2215
2217
2218
2220 break;
2222
2223
2224
2225
2227
2228
2229
2230
2231
2233 break;
2235
2236
2237
2238
2240
2241
2242
2243
2244
2245
2247 break;
2250 pg_log_error("\\else: cannot occur after \\else");
2252 break;
2254
2257 break;
2258 }
2259
2261}
2262
2263
2264
2265
2269{
2271
2273 {
2276
2279 break;
2283
2284
2285
2286
2288
2289
2292 break;
2294
2297 break;
2298 }
2299
2301}
2302
2303
2304
2305
2308{
2310
2311 if (active_branch)
2312 {
2313 char *pattern;
2314 bool show_verbose;
2315 unsigned short int save_expanded;
2316
2319
2320 show_verbose = strchr(cmd, '+') ? true : false;
2321
2322
2324 if (strchr(cmd, 'x'))
2326
2328
2329
2331
2332 free(pattern);
2333 }
2334 else
2336
2338}
2339
2340
2341
2342
2345{
2348
2349 if (active_branch)
2350 {
2351 char *opt1,
2352 *opt2;
2353
2358
2359 if (strcmp(cmd + 3, "export") == 0)
2360 {
2361 if (!opt2)
2362 {
2363 pg_log_error("\\%s: missing required argument", cmd);
2365 }
2366 else
2367 {
2370 }
2371 }
2372
2373 else if (strcmp(cmd + 3, "import") == 0)
2374 {
2375 if (!opt1)
2376 {
2377 pg_log_error("\\%s: missing required argument", cmd);
2379 }
2380 else
2381 {
2384 }
2385 }
2386
2387 else if (strncmp(cmd + 3, "list", 4) == 0)
2388 {
2389 bool show_verbose;
2390 unsigned short int save_expanded;
2391
2392 show_verbose = strchr(cmd, '+') ? true : false;
2393
2394
2396 if (strchr(cmd, 'x'))
2398
2400
2401
2403 }
2404
2405 else if (strcmp(cmd + 3, "unlink") == 0)
2406 {
2407 if (!opt1)
2408 {
2409 pg_log_error("\\%s: missing required argument", cmd);
2411 }
2412 else
2414 }
2415
2416 else
2418
2421 }
2422 else
2424
2427
2428 return status;
2429}
2430
2431
2432
2433
2436{
2438
2439 if (active_branch)
2440 {
2443
2446 free(fname);
2447 }
2448 else
2450
2452}
2453
2454
2455
2456
2460{
2461 if (active_branch)
2462 {
2463
2464
2465
2466
2467
2468 if (query_buf && query_buf->len > 0)
2469 puts(query_buf->data);
2470 else if (previous_buf && previous_buf->len > 0)
2471 puts(previous_buf->data);
2473 puts(_("Query buffer is empty."));
2475 }
2476
2478}
2479
2480
2481
2482
2485 const char *cmd)
2486{
2488
2489 if (active_branch)
2490 {
2493
2495
2496 if (!opt)
2497 {
2498 pg_log_error("\\%s: missing required argument", cmd);
2500 }
2501 else
2502 {
2506 }
2507 }
2508 else
2510
2511 return status;
2512}
2513
2514
2515
2516
2519{
2521
2522 if (active_branch)
2523 {
2526 char *pw1 = NULL;
2527 char *pw2 = NULL;
2530
2531 if (user == NULL)
2532 {
2533
2535
2536 res = PSQLexec("SELECT CURRENT_USER");
2537 if (!res)
2539
2542 }
2543
2544
2547 prompt_ctx.canceled = false;
2548
2551
2555
2557 {
2558
2560 }
2561 else if (strcmp(pw1, pw2) != 0)
2562 {
2565 }
2566 else
2567 {
2569
2571 {
2574 }
2575
2577 }
2578
2583 }
2584 else
2586
2588}
2589
2590
2591
2592
2595 const char *cmd)
2596{
2598
2599 if (active_branch)
2600 {
2601 char *opt,
2602 *prompt_text = NULL;
2603 char *arg1,
2604 *arg2;
2605
2608
2609 if (!arg1)
2610 {
2611 pg_log_error("\\%s: missing required argument", cmd);
2613 }
2614 else
2615 {
2616 char *result;
2618
2619
2622 prompt_ctx.canceled = false;
2623
2624 if (arg2)
2625 {
2626 prompt_text = arg1;
2627 opt = arg2;
2628 }
2629 else
2630 opt = arg1;
2631
2633 {
2635 }
2636 else
2637 {
2638 if (prompt_text)
2639 {
2640 fputs(prompt_text, stdout);
2642 }
2644 if (!result)
2645 {
2646 pg_log_error("\\%s: could not read value for variable",
2647 cmd);
2649 }
2650 }
2651
2655
2656 free(result);
2657 free(prompt_text);
2659 }
2660 }
2661 else
2663
2665}
2666
2667
2668
2669
2672{
2674
2675 if (active_branch)
2676 {
2681
2682 if (!opt0)
2683 {
2684
2685
2686 int i;
2687 static const char *const my_list[] = {
2688 "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
2689 "fieldsep_zero", "footer", "format", "linestyle", "null",
2690 "numericlocale", "pager", "pager_min_lines",
2691 "recordsep", "recordsep_zero",
2692 "tableattr", "title", "tuples_only",
2693 "unicode_border_linestyle",
2694 "unicode_column_linestyle",
2695 "unicode_header_linestyle",
2696 "xheader_width",
2697 NULL
2698 };
2699
2700 for (i = 0; my_list[i] != NULL; i++)
2701 {
2703
2704 printf("%-24s %s\n", my_list[i], val);
2706 }
2707
2709 }
2710 else
2712
2715 }
2716 else
2718
2720}
2721
2722
2723
2724
2727{
2729
2730 if (active_branch)
2732
2733 return status;
2734}
2735
2736
2737
2738
2742{
2743 if (active_branch)
2744 {
2748 puts(_("Query buffer reset (cleared)."));
2749 }
2750
2752}
2753
2754
2755
2756
2759{
2761
2762 if (active_branch)
2763 {
2766
2770 printf(_("Wrote history to file \"%s\".\n"), fname);
2771 if (!fname)
2772 putchar('\n');
2773 free(fname);
2774 }
2775 else
2777
2779}
2780
2781
2782
2783
2786{
2788
2789 if (active_branch)
2790 {
2792 {
2795 {
2797 }
2798 else
2799 {
2800 pg_log_error("\\sendpipeline must be used after \\bind or \\bind_named");
2803 }
2804 }
2805 else
2806 {
2807 pg_log_error("\\sendpipeline not allowed outside of pipeline mode");
2810 }
2811 }
2812 else
2814
2815 return status;
2816}
2817
2818
2819
2820
2823{
2825
2826 if (active_branch)
2827 {
2830
2831 if (!opt0)
2832 {
2833
2836 }
2837 else
2838 {
2839
2840
2841
2843 char *opt;
2844
2849
2852 {
2854 strcat(newval, opt);
2856 }
2857
2860
2862 }
2864 }
2865 else
2867
2869}
2870
2871
2872
2873
2876 const char *cmd)
2877{
2879
2880 if (active_branch)
2881 {
2886
2887 if (!envvar)
2888 {
2889 pg_log_error("\\%s: missing required argument", cmd);
2891 }
2892 else if (strchr(envvar, '=') != NULL)
2893 {
2894 pg_log_error("\\%s: environment variable name must not contain \"=\"",
2895 cmd);
2897 }
2898 else if (!envval)
2899 {
2900
2903 }
2904 else
2905 {
2906
2907 setenv(envvar, envval, 1);
2909 }
2910 free(envvar);
2911 free(envval);
2912 }
2913 else
2915
2917}
2918
2919
2920
2921
2924 const char *cmd, bool is_func)
2925{
2927
2928 if (active_branch)
2929 {
2930 bool show_linenumbers = (strchr(cmd, '+') != NULL);
2932 char *obj_desc;
2935
2939 if (!obj_desc)
2940 {
2941 if (is_func)
2943 else
2946 }
2948 {
2949
2951 }
2953 {
2954
2956 }
2957 else
2958 {
2960 bool is_pager;
2961
2962
2964 {
2965
2967
2969 is_pager = true;
2970 }
2971 else
2972 {
2973
2975 is_pager = false;
2976 }
2977
2978 if (show_linenumbers)
2979 {
2980
2982 }
2983 else
2984 {
2985
2987 }
2988
2989 if (is_pager)
2991 }
2992
2993 free(obj_desc);
2995 }
2996 else
2998
2999 return status;
3000}
3001
3002
3003
3004
3007{
3009
3010 if (active_branch)
3011 {
3014 }
3015 else
3017
3018 return status;
3019}
3020
3021
3022
3023
3026{
3028
3029 if (active_branch)
3030 {
3033 }
3034 else
3036
3037 return status;
3038}
3039
3040
3041
3042
3045{
3047
3048 if (active_branch)
3049 {
3052 }
3053 else
3055
3056 return status;
3057}
3058
3059
3060
3061
3064{
3066
3067 if (active_branch)
3068 {
3071
3074 }
3075 else
3077
3079}
3080
3081
3082
3083
3086{
3088
3089 if (active_branch)
3090 {
3093
3096 }
3097 else
3099
3101}
3102
3103
3104
3105
3108{
3110
3111 if (active_branch)
3112 {
3115
3116 if (opt)
3118 else
3121 {
3123 puts(_("Timing is on."));
3124 else
3125 puts(_("Timing is off."));
3126 }
3128 }
3129 else
3131
3133}
3134
3135
3136
3137
3140 const char *cmd)
3141{
3143
3144 if (active_branch)
3145 {
3148
3149 if (!opt)
3150 {
3151 pg_log_error("\\%s: missing required argument", cmd);
3153 }
3156
3158 }
3159 else
3161
3163}
3164
3165
3166
3167
3170 const char *cmd,
3172{
3174
3175 if (active_branch)
3176 {
3179 FILE *fd = NULL;
3180 bool is_pipe = false;
3181
3182 if (!query_buf)
3183 {
3186 }
3187 else
3188 {
3189 if (!fname)
3190 {
3191 pg_log_error("\\%s: missing required argument", cmd);
3193 }
3194 else
3195 {
3197 if (fname[0] == '|')
3198 {
3199 is_pipe = true;
3200 fflush(NULL);
3202 fd = popen(&fname[1], "w");
3203 }
3204 else
3205 {
3207 fd = fopen(fname, "w");
3208 }
3209 if ()
3210 {
3213 }
3214 }
3215 }
3216
3217 if (fd)
3218 {
3219 int result;
3220
3221
3222
3223
3224
3225
3226
3227 if (query_buf && query_buf->len > 0)
3229 else if (previous_buf && previous_buf->len > 0)
3231
3232 if (is_pipe)
3233 {
3234 result = pclose(fd);
3235
3236 if (result != 0)
3237 {
3240 }
3242 }
3243 else
3244 {
3245 result = fclose(fd);
3246
3247 if (result == EOF)
3248 {
3251 }
3252 }
3253 }
3254
3255 if (is_pipe)
3257
3258 free(fname);
3259 }
3260 else
3262
3263 return status;
3264}
3265
3266
3267
3268
3269
3273{
3275
3276 if (active_branch)
3277 {
3278 bool have_sleep = false;
3279 bool have_iter = false;
3280 bool have_min_rows = false;
3282 int iter = 0;
3283 int min_rows = 0;
3284
3286 {
3287 pg_log_error("\\watch not allowed in pipeline mode");
3290 }
3291
3292
3293
3294
3295
3296
3297
3298
3300 {
3303 char *valptr;
3304 char *opt_end;
3305
3306 if (!opt)
3307 break;
3308
3309 valptr = strchr(opt, '=');
3310 if (valptr)
3311 {
3312
3313 valptr++;
3314 if (strncmp("i=", opt, strlen("i=")) == 0 ||
3315 strncmp("interval=", opt, strlen("interval=")) == 0)
3316 {
3317 if (have_sleep)
3318 {
3319 pg_log_error("\\watch: interval value is specified more than once");
3321 }
3322 else
3323 {
3324 have_sleep = true;
3325 errno = 0;
3326 sleep = strtod(valptr, &opt_end);
3327 if (sleep < 0 || *opt_end || errno == ERANGE)
3328 {
3329 pg_log_error("\\watch: incorrect interval value \"%s\"", valptr);
3331 }
3332 }
3333 }
3334 else if (strncmp("c=", opt, strlen("c=")) == 0 ||
3335 strncmp("count=", opt, strlen("count=")) == 0)
3336 {
3337 if (have_iter)
3338 {
3339 pg_log_error("\\watch: iteration count is specified more than once");
3341 }
3342 else
3343 {
3344 have_iter = true;
3345 errno = 0;
3346 iter = strtoint(valptr, &opt_end, 10);
3347 if (iter <= 0 || *opt_end || errno == ERANGE)
3348 {
3349 pg_log_error("\\watch: incorrect iteration count \"%s\"", valptr);
3351 }
3352 }
3353 }
3354 else if (strncmp("m=", opt, strlen("m=")) == 0 ||
3355 strncmp("min_rows=", opt, strlen("min_rows=")) == 0)
3356 {
3357 if (have_min_rows)
3358 {
3359 pg_log_error("\\watch: minimum row count specified more than once");
3361 }
3362 else
3363 {
3364 have_min_rows = true;
3365 errno = 0;
3366 min_rows = strtoint(valptr, &opt_end, 10);
3367 if (min_rows <= 0 || *opt_end || errno == ERANGE)
3368 {
3369 pg_log_error("\\watch: incorrect minimum row count \"%s\"", valptr);
3371 }
3372 }
3373 }
3374 else
3375 {
3376 pg_log_error("\\watch: unrecognized parameter \"%s\"", opt);
3378 }
3379 }
3380 else
3381 {
3382
3383 if (have_sleep)
3384 {
3385 pg_log_error("\\watch: interval value is specified more than once");
3387 }
3388 else
3389 {
3390 have_sleep = true;
3391 errno = 0;
3392 sleep = strtod(opt, &opt_end);
3393 if (sleep < 0 || *opt_end || errno == ERANGE)
3394 {
3395 pg_log_error("\\watch: incorrect interval value \"%s\"", opt);
3397 }
3398 }
3399 }
3400
3402 }
3403
3404
3406 {
3407
3409
3411 }
3412
3413
3416 }
3417 else
3419
3421}
3422
3423
3424
3425
3428{
3430
3431 if (active_branch)
3432 {
3435
3438 }
3439 else
3441
3443}
3444
3445
3446
3447
3450{
3452
3453 if (active_branch)
3454 {
3455 char *pattern;
3456 bool show_system;
3457 unsigned short int save_expanded;
3458
3461
3462 show_system = strchr(cmd, 'S') ? true : false;
3463
3464
3466 if (strchr(cmd, 'x'))
3468
3470
3471
3473
3474 free(pattern);
3475 }
3476 else
3478
3480}
3481
3482
3483
3484
3487{
3489
3490 if (active_branch)
3491 {
3494
3497 }
3498 else
3500
3502}
3503
3504
3505
3506
3509{
3510 if (active_branch)
3511 {
3514
3515 if (!opt0 || strcmp(opt0, "commands") == 0)
3517 else if (strcmp(opt0, "options") == 0)
3519 else if (strcmp(opt0, "variables") == 0)
3521 else
3523
3525 }
3526 else
3528
3530}
3531
3532
3533
3534
3535
3536
3537
3538static char *
3540{
3541 char *result;
3542 char quote;
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3554
3555 if (!result)
3556 return NULL;
3557
3558 if (quote)
3559 return result;
3560
3561 if (*result == '\0' || strcmp(result, "-") == 0)
3562 {
3563 free(result);
3564 return NULL;
3565 }
3566
3567 return result;
3568}
3569
3570
3571
3572
3573
3574
3575
3576
3577
3580{
3582 int num_options = 0;
3584
3585
3587 OT_NORMAL, NULL, false)) != NULL)
3588 {
3589
3590 if (num_options > 0)
3593 num_options++;
3595 }
3596
3597 return exp_buf;
3598}
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608static bool
3610{
3612 bool value = false;
3614
3617}
3618
3619
3620
3621
3622
3623
3624
3625static void
3627{
3629
3631}
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641static void
3643{
3644 char *arg;
3645
3647 OT_NORMAL, NULL, false)) != NULL)
3649}
3650
3651
3652
3653
3654
3655
3656
3657
3658static void
3660{
3663
3665}
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678static void
3680{
3683
3685}
3686
3687
3688
3689
3690static bool
3692{
3693 return (strcmp(cmd, "if") == 0 ||
3694 strcmp(cmd, "elif") == 0 ||
3695 strcmp(cmd, "else") == 0 ||
3696 strcmp(cmd, "endif") == 0);
3697}
3698
3699
3700
3701
3702
3703
3704
3705
3706static void
3709{
3710 if (query_buf)
3714}
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726static void
3729{
3730 if (query_buf)
3731 {
3733
3734 Assert(new_len >= 0 && new_len <= query_buf->len);
3735 query_buf->len = new_len;
3736 query_buf->data[new_len] = '\0';
3737 }
3740}
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752static bool
3754{
3755 if (query_buf && query_buf->len == 0)
3756 {
3758 return true;
3759 }
3760 return false;
3761}
3762
3763
3764
3765
3766
3767
3768
3769
3770static char *
3772{
3773 char *result;
3775
3776
3779 prompt_ctx.canceled = false;
3780
3783 else
3784 {
3785 char *prompt_text;
3786
3789 free(prompt_text);
3790 }
3791
3792 if (canceled)
3793 *canceled = prompt_ctx.canceled;
3794
3795 return result;
3796}
3797
3798static bool
3800{
3801 if (new_val == NULL)
3802 return false;
3803
3804 if (old_val == NULL || strcmp(old_val, new_val) != 0)
3805 return true;
3806
3807 return false;
3808}
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821static bool
3824{
3826 *n_conn = NULL;
3828 int nconnopts = 0;
3829 bool same_host = false;
3831 char *client_encoding;
3833 bool keep_password = true;
3834 bool has_connection_string;
3835 bool reuse_previous;
3836
3837 has_connection_string = dbname ?
3839
3840
3841 if (has_connection_string && (user || host || port))
3842 {
3843 pg_log_error("Do not give user, host, or port separately when using a connection string");
3844 return false;
3845 }
3846
3847 switch (reuse_previous_specification)
3848 {
3850 reuse_previous = true;
3851 break;
3853 reuse_previous = false;
3854 break;
3855 default:
3856 reuse_previous = !has_connection_string;
3857 break;
3858 }
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869 if (reuse_previous)
3870 {
3871 if (o_conn)
3875 else
3876 {
3877
3878 pg_log_error("No database connection exists to re-use parameters from");
3879 return false;
3880 }
3881 }
3882 else
3884
3885 if (cinfo)
3886 {
3887 if (has_connection_string)
3888 {
3889
3892
3894 if (replcinfo)
3895 {
3898 bool have_password = false;
3899
3900 for (ci = cinfo, replci = replcinfo;
3902 ci++, replci++)
3903 {
3905
3906 if (replci->val)
3907 {
3908
3909
3910
3911
3912
3913 char *swap = replci->val;
3914
3916 ci->val = swap;
3917
3918
3919
3920
3921
3922
3923
3924
3925 if (replci->val == NULL ||
3926 strcmp(ci->val, replci->val) != 0)
3927 {
3928 if (strcmp(replci->keyword, "user") == 0 ||
3929 strcmp(replci->keyword, "host") == 0 ||
3930 strcmp(replci->keyword, "hostaddr") == 0 ||
3931 strcmp(replci->keyword, "port") == 0)
3932 keep_password = false;
3933 }
3934
3935 if (strcmp(replci->keyword, "password") == 0)
3936 have_password = true;
3937 }
3938 else if (!reuse_previous)
3939 {
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3955 ci->val = NULL;
3956 }
3957 }
3959
3960
3961 nconnopts = ci - cinfo;
3962
3964
3965
3966
3967
3968
3969
3970 if (have_password)
3971 keep_password = true;
3972
3973
3975 }
3976 else
3977 {
3978
3980 {
3983 }
3984 else
3987 }
3988 }
3989 else
3990 {
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4005
4006 for (ci = cinfo; ci->keyword; ci++)
4007 {
4008 if (user && strcmp(ci->keyword, "user") == 0)
4009 {
4010 if (!(ci->val && strcmp(user, ci->val) == 0))
4011 keep_password = false;
4012 }
4013 else if (host && strcmp(ci->keyword, "host") == 0)
4014 {
4015 if (ci->val && strcmp(host, ci->val) == 0)
4016 same_host = true;
4017 else
4018 keep_password = false;
4019 }
4020 else if (port && strcmp(ci->keyword, "port") == 0)
4021 {
4022 if (!(ci->val && strcmp(port, ci->val) == 0))
4023 keep_password = false;
4024 }
4025 }
4026
4027
4028 nconnopts = ci - cinfo;
4029 }
4030 }
4031 else
4032 {
4033
4036 }
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4049 {
4050 bool canceled = false;
4051
4052
4053
4054
4055
4056
4057
4058
4060 &canceled);
4062 }
4063
4064
4065
4066
4067
4068
4069 if (pset.notty || getenv("PGCLIENTENCODING"))
4070 client_encoding = NULL;
4071 else
4072 client_encoding = "auto";
4073
4074
4076 {
4079 int paramnum = 0;
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091 for (ci = cinfo; ci->keyword; ci++)
4092 {
4094
4095 if (dbname && strcmp(ci->keyword, "dbname") == 0)
4097 else if (user && strcmp(ci->keyword, "user") == 0)
4099 else if (host && strcmp(ci->keyword, "host") == 0)
4100 values[paramnum++] = host;
4101 else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0)
4102 {
4103
4104 values[paramnum++] = NULL;
4105 }
4106 else if (port && strcmp(ci->keyword, "port") == 0)
4108
4109 else if ((password || !keep_password) &&
4110 strcmp(ci->keyword, "password") == 0)
4112 else if (strcmp(ci->keyword, "fallback_application_name") == 0)
4114 else if (client_encoding &&
4115 strcmp(ci->keyword, "client_encoding") == 0)
4116 values[paramnum++] = client_encoding;
4117 else if (ci->val)
4119
4120 }
4121
4123 values[paramnum] = NULL;
4124
4125
4127
4130
4133 break;
4134
4135
4136
4137
4138
4140 {
4141 bool canceled = false;
4142
4143
4144
4145
4146
4149 n_conn = NULL;
4151 continue;
4152 }
4153
4154
4155
4156
4157
4158 if (n_conn == NULL)
4160
4162 }
4163
4164
4167
4169 {
4170
4171
4172
4173
4174
4176 {
4177 if (n_conn)
4178 {
4181 }
4182
4183
4184 if (o_conn)
4185 pg_log_info("Previous connection kept");
4186 }
4187 else
4188 {
4189 if (n_conn)
4190 {
4193 }
4194
4195 if (o_conn)
4196 {
4197
4198
4199
4200
4201
4202
4203
4204
4205
4210 }
4211
4212
4214 {
4217 }
4218 }
4219
4220 return false;
4221 }
4222
4223
4224
4225
4226
4227
4232
4233
4235 {
4236 if (!o_conn ||
4239 {
4242
4244 {
4245
4246 if (hostaddr && *hostaddr)
4247 printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
4249 else
4250 printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
4252 }
4253 else
4254 {
4255 if (hostaddr && *hostaddr && strcmp(connhost, hostaddr) != 0)
4256 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
4258 else
4259 printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
4261 }
4262 }
4263 else
4264 printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
4266 }
4267
4268
4269 if (o_conn)
4272 {
4275 }
4276
4277 return true;
4278}
4279
4280
4281
4282
4283
4284
4285static void
4287{
4288 bool forRead = false;
4289
4290 while (true)
4291 {
4292 int rc;
4293 int sock;
4295
4296
4297
4298
4299
4301 break;
4302
4303
4304
4305
4306
4308 if (sock == -1)
4309 break;
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4327 if (rc == -1)
4328 return;
4329
4331 {
4334 return;
4336 forRead = true;
4337 continue;
4339 forRead = false;
4340 continue;
4343 }
4344 }
4345}
4346
4347void
4349{
4351 {
4352 int client_ver = PG_VERSION_NUM;
4353 char cverbuf[32];
4354 char sverbuf[32];
4355
4357 {
4359
4360
4362
4364 {
4366 sverbuf, sizeof(sverbuf));
4368 }
4369
4370 printf(_("%s (%s, server %s)\n"),
4372 }
4373
4374 else if (in_startup)
4376
4377
4378
4379
4380
4381 if (pset.sversion / 100 > client_ver / 100 ||
4383 printf(_("WARNING: %s major version %s, server major version %s.\n"
4384 " Some psql features might not work.\n"),
4387 cverbuf, sizeof(cverbuf)),
4389 sverbuf, sizeof(sverbuf)));
4390
4391#ifdef WIN32
4392 if (in_startup)
4393 checkWin32Codepage();
4394#endif
4397 }
4398}
4399
4400
4401
4402
4403
4404
4405
4406static void
4408{
4409 const char *protocol;
4410 const char *cipher;
4411 const char *compression;
4412 const char *alpn;
4413
4415 return;
4416
4421
4422 printf(_("SSL connection (protocol: %s, cipher: %s, compression: %s, ALPN: %s)\n"),
4423 protocol ? protocol : _("unknown"),
4424 cipher ? cipher : _("unknown"),
4425 (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"),
4426 (alpn && alpn[0] != '\0') ? alpn : _("none"));
4427}
4428
4429
4430
4431
4432
4433
4434static void
4436{
4438 return;
4439
4440 printf(_("GSSAPI-encrypted connection\n"));
4441}
4442
4443
4444
4445
4446
4447
4448
4449#ifdef WIN32
4450static void
4451checkWin32Codepage(void)
4452{
4453 unsigned int wincp,
4454 concp;
4455
4456 wincp = GetACP();
4457 concp = GetConsoleCP();
4458 if (wincp != concp)
4459 {
4460 printf(_("WARNING: Console code page (%u) differs from Windows code page (%u)\n"
4461 " 8-bit characters might not work correctly. See psql reference\n"
4462 " page \"Notes for Windows users\" for details.\n"),
4463 concp, wincp);
4464 }
4465}
4466#endif
4467
4468
4469
4470
4471
4472
4473
4474
4475void
4477{
4478 char vbuf[32];
4480
4481
4485
4487
4494
4495
4496
4498
4500 {
4503 }
4505
4508
4509
4512}
4513
4514
4515
4516
4517
4518
4519void
4521{
4530}
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540static bool
4542{
4543 const char *editorName;
4544 const char *editor_lineno_arg = NULL;
4545 char *sys;
4546 int result;
4547
4548 Assert(fname != NULL);
4549
4550
4551 editorName = getenv("PSQL_EDITOR");
4552 if (!editorName)
4553 editorName = getenv("EDITOR");
4554 if (!editorName)
4555 editorName = getenv("VISUAL");
4556 if (!editorName)
4558
4559
4560 if (lineno > 0)
4561 {
4562 editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
4563#ifdef DEFAULT_EDITOR_LINENUMBER_ARG
4564 if (!editor_lineno_arg)
4566#endif
4567 if (!editor_lineno_arg)
4568 {
4569 pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
4570 return false;
4571 }
4572 }
4573
4574
4575
4576
4577
4578
4579
4580
4581#ifndef WIN32
4582 if (lineno > 0)
4583 sys = psprintf("exec %s %s%d '%s'",
4584 editorName, editor_lineno_arg, lineno, fname);
4585 else
4586 sys = psprintf("exec %s '%s'",
4587 editorName, fname);
4588#else
4589 if (lineno > 0)
4590 sys = psprintf("\"%s\" %s%d \"%s\"",
4591 editorName, editor_lineno_arg, lineno, fname);
4592 else
4593 sys = psprintf("\"%s\" \"%s\"",
4594 editorName, fname);
4595#endif
4596 fflush(NULL);
4597 result = system(sys);
4598 if (result == -1)
4599 pg_log_error("could not start editor \"%s\"", editorName);
4600 else if (result == 127)
4603
4604 return result == 0;
4605}
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622static bool
4624 int lineno, bool discard_on_quit, bool *edited)
4625{
4627 FILE *stream = NULL;
4628 const char *fname;
4629 bool error = false;
4630 int fd;
4632 after;
4633
4634 if (filename_arg)
4635 fname = filename_arg;
4636 else
4637 {
4638
4639#ifndef WIN32
4640 const char *tmpdir = getenv("TMPDIR");
4641
4642 if (!tmpdir)
4643 tmpdir = "/tmp";
4644#else
4646 int ret;
4647
4648 ret = GetTempPath(MAXPGPATH, tmpdir);
4649 if (ret == 0 || ret > MAXPGPATH)
4650 {
4651 pg_log_error("could not locate temporary directory: %s",
4652 !ret ? strerror(errno) : "");
4653 return false;
4654 }
4655#endif
4656
4657
4658
4659
4660
4661
4662#ifndef WIN32
4663 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4664 "/", (int) getpid());
4665#else
4666 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4667 "" , (int) getpid());
4668#endif
4669
4670 fname = (const char *) fnametmp;
4671
4672 fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
4673 if (fd != -1)
4674 stream = fdopen(fd, "w");
4675
4676 if (fd == -1 || !stream)
4677 {
4678 pg_log_error("could not open temporary file \"%s\": %m", fname);
4680 }
4681 else
4682 {
4683 unsigned int ql = query_buf->len;
4684
4685
4686 if (ql > 0 && query_buf->data[ql - 1] != '\n')
4687 {
4689 ql++;
4690 }
4691
4692 if (fwrite(query_buf->data, 1, ql, stream) != ql)
4693 {
4695
4696 if (fclose(stream) != 0)
4698
4699 if (remove(fname) != 0)
4701
4703 }
4704 else if (fclose(stream) != 0)
4705 {
4707 if (remove(fname) != 0)
4710 }
4711 else
4712 {
4713 struct utimbuf ut;
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726 ut.modtime = ut.actime = time(NULL) - 2;
4727 (void) utime(fname, &ut);
4728 }
4729 }
4730 }
4731
4733 {
4736 }
4737
4738
4741
4742 if ( && stat(fname, &after) != 0)
4743 {
4746 }
4747
4748
4752 {
4754 if (!stream)
4755 {
4758 }
4759 else
4760 {
4761
4762 char line[1024];
4763
4765 while (fgets(line, sizeof(line), stream) != NULL)
4767
4768 if (ferror(stream))
4769 {
4773 }
4774 else if (edited)
4775 {
4776 *edited = true;
4777 }
4778
4779 fclose(stream);
4780 }
4781 }
4782 else
4783 {
4784
4785
4786
4787
4788 if (discard_on_quit)
4790 }
4791
4792
4793 if (!filename_arg)
4794 {
4795 if (remove(fname) == -1)
4796 {
4799 }
4800 }
4801
4803}
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817int
4819{
4820 FILE *fd;
4821 int result;
4822 char *oldfilename;
4824
4826 {
4827 fd = stdin;
4829 }
4830 else if (strcmp(filename, "-") != 0)
4831 {
4833
4834
4835
4836
4837
4838
4839
4842 {
4847
4849 }
4850
4852
4853 if ()
4854 {
4857 }
4858 }
4859 else
4860 {
4861 fd = stdin;
4862 filename = "";
4863 }
4864
4867
4869
4871
4872 if (fd != stdin)
4873 fclose(fd);
4874
4876
4878
4879 return result;
4880}
4881
4882
4883
4884static const char *
4886{
4887 switch (in)
4888 {
4890 return "nothing";
4891 break;
4893 return "aligned";
4894 break;
4896 return "asciidoc";
4897 break;
4899 return "csv";
4900 break;
4902 return "html";
4903 break;
4905 return "latex";
4906 break;
4908 return "latex-longtable";
4909 break;
4911 return "troff-ms";
4912 break;
4914 return "unaligned";
4915 break;
4917 return "wrapped";
4918 break;
4919 }
4920 return "unknown";
4921}
4922
4923
4924
4925
4926
4927static bool
4930{
4935 else
4936 return false;
4937 return true;
4938}
4939
4940static const char *
4942{
4943 switch (linestyle)
4944 {
4946 return "single";
4947 break;
4949 return "double";
4950 break;
4951 }
4952 return "unknown";
4953}
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970bool
4972{
4973 size_t vallen = 0;
4974
4975 Assert(param != NULL);
4976
4978 vallen = strlen(value);
4979
4980
4981 if (strcmp(param, "format") == 0)
4982 {
4983 static const struct fmt
4984 {
4985 const char *name;
4987 } formats[] =
4988 {
4989
4998 };
4999
5001 ;
5002 else
5003 {
5004 int match_pos = -1;
5005
5006 for (int i = 0; i < lengthof(formats); i++)
5007 {
5009 {
5010 if (match_pos < 0)
5011 match_pos = i;
5012 else
5013 {
5014 pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
5016 formats[match_pos].name, formats[i].name);
5017 return false;
5018 }
5019 }
5020 }
5021 if (match_pos >= 0)
5022 popt->topt.format = formats[match_pos].number;
5024 {
5025
5026
5027
5028
5029
5031 }
5032 else
5033 {
5034 pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
5035 return false;
5036 }
5037 }
5038 }
5039
5040
5041 else if (strcmp(param, "linestyle") == 0)
5042 {
5044 ;
5051 else
5052 {
5053 pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
5054 return false;
5055 }
5056 }
5057
5058
5059 else if (strcmp(param, "unicode_border_linestyle") == 0)
5060 {
5062 ;
5066 else
5067 {
5068 pg_log_error("\\pset: allowed Unicode border line styles are single, double");
5069 return false;
5070 }
5071 }
5072
5073
5074 else if (strcmp(param, "unicode_column_linestyle") == 0)
5075 {
5077 ;
5081 else
5082 {
5083 pg_log_error("\\pset: allowed Unicode column line styles are single, double");
5084 return false;
5085 }
5086 }
5087
5088
5089 else if (strcmp(param, "unicode_header_linestyle") == 0)
5090 {
5092 ;
5096 else
5097 {
5098 pg_log_error("\\pset: allowed Unicode header line styles are single, double");
5099 return false;
5100 }
5101 }
5102
5103
5104 else if (strcmp(param, "border") == 0)
5105 {
5108 }
5109
5110
5111 else if (strcmp(param, "x") == 0 ||
5112 strcmp(param, "expanded") == 0 ||
5113 strcmp(param, "vertical") == 0)
5114 {
5118 {
5119 bool on_off;
5120
5123 else
5124 {
5126 return false;
5127 }
5128 }
5129 else
5131 }
5132
5133
5134 else if (strcmp(param, "xheader_width") == 0)
5135 {
5137 ;
5144 else
5145 {
5146 int intval = atoi(value);
5147
5148 if (intval == 0)
5149 {
5150 pg_log_error("\\pset: allowed xheader_width values are \"%s\" (default), \"%s\", \"%s\", or a number specifying the exact width", "full", "column", "page");
5151 return false;
5152 }
5153
5156 }
5157 }
5158
5159
5160 else if (strcmp(param, "csv_fieldsep") == 0)
5161 {
5163 {
5164
5165 if (strlen(value) != 1)
5166 {
5167 pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
5168 return false;
5169 }
5170 if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
5171 {
5172 pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
5173 return false;
5174 }
5176 }
5177 }
5178
5179
5180 else if (strcmp(param, "numericlocale") == 0)
5181 {
5184 else
5186 }
5187
5188
5189 else if (strcmp(param, "null") == 0)
5190 {
5192 {
5195 }
5196 }
5197
5198
5199 else if (strcmp(param, "fieldsep") == 0)
5200 {
5202 {
5206 }
5207 }
5208
5209 else if (strcmp(param, "fieldsep_zero") == 0)
5210 {
5214 }
5215
5216
5217 else if (strcmp(param, "recordsep") == 0)
5218 {
5220 {
5224 }
5225 }
5226
5227 else if (strcmp(param, "recordsep_zero") == 0)
5228 {
5232 }
5233
5234
5235 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5236 {
5239 else
5241 }
5242
5243
5244 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5245 {
5248 popt->title = NULL;
5249 else
5251 }
5252
5253
5254 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5255 {
5259 else
5261 }
5262
5263
5264 else if (strcmp(param, "pager") == 0)
5265 {
5269 {
5270 bool on_off;
5271
5273 {
5275 return false;
5276 }
5277 popt->topt.pager = on_off ? 1 : 0;
5278 }
5281 else
5283 }
5284
5285
5286 else if (strcmp(param, "pager_min_lines") == 0)
5287 {
5290 return false;
5291 }
5292
5293
5294 else if (strcmp(param, "footer") == 0)
5295 {
5298 else
5300 }
5301
5302
5303 else if (strcmp(param, "columns") == 0)
5304 {
5307 }
5308 else
5309 {
5310 pg_log_error("\\pset: unknown option: %s", param);
5311 return false;
5312 }
5313
5314 if (!quiet)
5316
5317 return true;
5318}
5319
5320
5321
5322
5323static bool
5325{
5326 Assert(param != NULL);
5327
5328
5329 if (strcmp(param, "border") == 0)
5331
5332
5333 else if (strcmp(param, "columns") == 0)
5334 {
5336 printf(_("Target width is unset.\n"));
5337 else
5339 }
5340
5341
5342 else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
5343 {
5345 printf(_("Expanded display is on.\n"));
5347 printf(_("Expanded display is used automatically.\n"));
5348 else
5349 printf(_("Expanded display is off.\n"));
5350 }
5351
5352
5353 else if (strcmp(param, "xheader_width") == 0)
5354 {
5356 printf(_("Expanded header width is \"%s\".\n"), "full");
5358 printf(_("Expanded header width is \"%s\".\n"), "column");
5360 printf(_("Expanded header width is \"%s\".\n"), "page");
5363 }
5364
5365
5366 else if (strcmp(param, "csv_fieldsep") == 0)
5367 {
5368 printf(_("Field separator for CSV is \"%s\".\n"),
5370 }
5371
5372
5373 else if (strcmp(param, "fieldsep") == 0)
5374 {
5376 printf(_("Field separator is zero byte.\n"));
5377 else
5378 printf(_("Field separator is \"%s\".\n"),
5380 }
5381
5382 else if (strcmp(param, "fieldsep_zero") == 0)
5383 {
5384 printf(_("Field separator is zero byte.\n"));
5385 }
5386
5387
5388 else if (strcmp(param, "footer") == 0)
5389 {
5391 printf(_("Default footer is on.\n"));
5392 else
5393 printf(_("Default footer is off.\n"));
5394 }
5395
5396
5397 else if (strcmp(param, "format") == 0)
5398 {
5400 }
5401
5402
5403 else if (strcmp(param, "linestyle") == 0)
5404 {
5405 printf(_("Line style is %s.\n"),
5407 }
5408
5409
5410 else if (strcmp(param, "null") == 0)
5411 {
5412 printf(_("Null display is \"%s\".\n"),
5414 }
5415
5416
5417 else if (strcmp(param, "numericlocale") == 0)
5418 {
5420 printf(_("Locale-adjusted numeric output is on.\n"));
5421 else
5422 printf(_("Locale-adjusted numeric output is off.\n"));
5423 }
5424
5425
5426 else if (strcmp(param, "pager") == 0)
5427 {
5429 printf(_("Pager is used for long output.\n"));
5431 printf(_("Pager is always used.\n"));
5432 else
5433 printf(_("Pager usage is off.\n"));
5434 }
5435
5436
5437 else if (strcmp(param, "pager_min_lines") == 0)
5438 {
5439 printf(ngettext("Pager won't be used for less than %d line.\n",
5440 "Pager won't be used for less than %d lines.\n",
5443 }
5444
5445
5446 else if (strcmp(param, "recordsep") == 0)
5447 {
5449 printf(_("Record separator is zero byte.\n"));
5451 printf(_("Record separator is .\n"));
5452 else
5453 printf(_("Record separator is \"%s\".\n"),
5455 }
5456
5457 else if (strcmp(param, "recordsep_zero") == 0)
5458 {
5459 printf(_("Record separator is zero byte.\n"));
5460 }
5461
5462
5463 else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
5464 {
5466 printf(_("Table attributes are \"%s\".\n"),
5468 else
5469 printf(_("Table attributes unset.\n"));
5470 }
5471
5472
5473 else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
5474 {
5475 if (popt->title)
5476 printf(_("Title is \"%s\".\n"), popt->title);
5477 else
5478 printf(_("Title is unset.\n"));
5479 }
5480
5481
5482 else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
5483 {
5485 printf(_("Tuples only is on.\n"));
5486 else
5487 printf(_("Tuples only is off.\n"));
5488 }
5489
5490
5491 else if (strcmp(param, "unicode_border_linestyle") == 0)
5492 {
5493 printf(_("Unicode border line style is \"%s\".\n"),
5495 }
5496
5497 else if (strcmp(param, "unicode_column_linestyle") == 0)
5498 {
5499 printf(_("Unicode column line style is \"%s\".\n"),
5501 }
5502
5503 else if (strcmp(param, "unicode_header_linestyle") == 0)
5504 {
5505 printf(_("Unicode header line style is \"%s\".\n"),
5507 }
5508
5509 else
5510 {
5511 pg_log_error("\\pset: unknown option: %s", param);
5512 return false;
5513 }
5514
5515 return true;
5516}
5517
5518
5519
5520
5521
5522
5525{
5527
5529
5530
5532
5533
5542 if (popt->title)
5544
5545
5546
5547
5548
5551
5552 return save;
5553}
5554
5555
5556
5557
5558
5559void
5561{
5562
5563
5564
5570
5571
5572
5573
5574
5577
5578
5580
5581
5583}
5584
5585static const char *
5587{
5588 return val ? "on" : "off";
5589}
5590
5591
5592static char *
5594{
5596 char *r = ret;
5597
5598 *r++ = '\'';
5599
5601 {
5602 if (*str == '\n')
5603 {
5604 *r++ = '\\';
5605 *r++ = 'n';
5606 }
5607 else if (*str == '\'')
5608 {
5609 *r++ = '\\';
5610 *r++ = '\'';
5611 }
5612 else
5613 *r++ = *str;
5614 }
5615
5616 *r++ = '\'';
5617 *r = '\0';
5618
5619 return ret;
5620}
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630static char *
5632{
5633 Assert(param != NULL);
5634
5635 if (strcmp(param, "border") == 0)
5637 else if (strcmp(param, "columns") == 0)
5639 else if (strcmp(param, "csv_fieldsep") == 0)
5641 else if (strcmp(param, "expanded") == 0)
5643 ? "auto"
5645 else if (strcmp(param, "fieldsep") == 0)
5648 : "");
5649 else if (strcmp(param, "fieldsep_zero") == 0)
5651 else if (strcmp(param, "footer") == 0)
5653 else if (strcmp(param, "format") == 0)
5655 else if (strcmp(param, "linestyle") == 0)
5657 else if (strcmp(param, "null") == 0)
5660 : "");
5661 else if (strcmp(param, "numericlocale") == 0)
5663 else if (strcmp(param, "pager") == 0)
5665 else if (strcmp(param, "pager_min_lines") == 0)
5667 else if (strcmp(param, "recordsep") == 0)
5670 : "");
5671 else if (strcmp(param, "recordsep_zero") == 0)
5673 else if (strcmp(param, "tableattr") == 0)
5675 else if (strcmp(param, "title") == 0)
5677 else if (strcmp(param, "tuples_only") == 0)
5679 else if (strcmp(param, "unicode_border_linestyle") == 0)
5681 else if (strcmp(param, "unicode_column_linestyle") == 0)
5683 else if (strcmp(param, "unicode_header_linestyle") == 0)
5685 else if (strcmp(param, "xheader_width") == 0)
5686 {
5690 return pstrdup("column");
5693 else
5694 {
5695
5696 char wbuff[32];
5697
5698 snprintf(wbuff, sizeof(wbuff), "%d",
5701 }
5702 }
5703 else
5704 return pstrdup("ERROR");
5705}
5706
5707
5708
5709#ifndef WIN32
5710#define DEFAULT_SHELL "/bin/sh"
5711#else
5712
5713
5714
5715
5716#define DEFAULT_SHELL "cmd.exe"
5717#endif
5718
5719static bool
5721{
5722 int result;
5723
5724 fflush(NULL);
5725 if (!command)
5726 {
5727 char *sys;
5728 const char *shellName;
5729
5730 shellName = getenv("SHELL");
5731#ifdef WIN32
5732 if (shellName == NULL)
5733 shellName = getenv("COMSPEC");
5734#endif
5735 if (shellName == NULL)
5737
5738
5739#ifndef WIN32
5740 sys = psprintf("exec %s", shellName);
5741#else
5742 sys = psprintf("\"%s\"", shellName);
5743#endif
5744 result = system(sys);
5746 }
5747 else
5748 result = system(command);
5749
5751
5752 if (result == 127 || result == -1)
5753 {
5755 return false;
5756 }
5757 return true;
5758}
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770static bool
5772{
5773 long sleep_ms = (long) (sleep * 1000);
5775 const char *strftime_fmt;
5776 const char *user_title;
5777 char *title;
5778 const char *pagerprog = NULL;
5779 FILE *pagerpipe = NULL;
5780 int title_len;
5781 int res = 0;
5782 bool done = false;
5783#ifndef WIN32
5784 sigset_t sigalrm_sigchld_sigint;
5785 sigset_t sigalrm_sigchld;
5786 sigset_t sigint;
5788#endif
5789
5790 if (!query_buf || query_buf->len <= 0)
5791 {
5792 pg_log_error("\\watch cannot be used with an empty query");
5793 return false;
5794 }
5795
5796#ifndef WIN32
5797 sigemptyset(&sigalrm_sigchld_sigint);
5798 sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
5799 sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
5800 sigaddset(&sigalrm_sigchld_sigint, SIGINT);
5801
5802 sigemptyset(&sigalrm_sigchld);
5803 sigaddset(&sigalrm_sigchld, SIGCHLD);
5804 sigaddset(&sigalrm_sigchld, SIGALRM);
5805
5806 sigemptyset(&sigint);
5807 sigaddset(&sigint, SIGINT);
5808
5809
5810
5811
5812
5813 sigprocmask(SIG_BLOCK, &sigalrm_sigchld, NULL);
5814
5815
5816
5817
5818
5823 {
5825 done = true;
5826 }
5827#endif
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837#ifndef WIN32
5838 pagerprog = getenv("PSQL_WATCH_PAGER");
5839
5840 if (pagerprog && strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
5841 pagerprog = NULL;
5842#endif
5843 if (pagerprog && myopt.topt.pager &&
5844 isatty(fileno(stdin)) && isatty(fileno(stdout)))
5845 {
5846 fflush(NULL);
5848 pagerpipe = popen(pagerprog, "w");
5849
5850 if (!pagerpipe)
5851
5853 }
5854
5855
5856
5857
5858
5859
5860 strftime_fmt = "%c";
5861
5862
5863
5864
5865
5866 if (!pagerpipe)
5868
5869
5870
5871
5872
5873
5874 user_title = myopt.title;
5875 title_len = (user_title ? strlen(user_title) : 0) + 256;
5877
5878
5879 while (!done)
5880 {
5881 time_t timer;
5882 char timebuf[128];
5883
5884
5885
5886
5887
5888
5889 timer = time(NULL);
5890 strftime(timebuf, sizeof(timebuf), strftime_fmt, localtime(&timer));
5891
5892 if (user_title)
5893 snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
5894 user_title, timebuf, sleep_ms / 1000.0);
5895 else
5896 snprintf(title, title_len, _("%s (every %gs)\n"),
5897 timebuf, sleep_ms / 1000.0);
5898 myopt.title = title;
5899
5900
5901 res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe, min_rows);
5902
5903
5904
5905
5906
5907 if (res <= 0)
5908 break;
5909
5910
5911 if (iter && (--iter <= 0))
5912 break;
5913
5914
5915 if (pagerpipe && ferror(pagerpipe))
5916 break;
5917
5918
5920 continue;
5921
5922#ifdef WIN32
5923
5924
5925
5926
5927
5928
5930 {
5932
5935 {
5936 done = true;
5937 break;
5938 }
5939 i -= s;
5940 }
5941#else
5942
5943 sigprocmask(SIG_BLOCK, &sigint, NULL);
5945 done = true;
5946
5947
5948 while (!done)
5949 {
5950 int signal_received;
5951
5952 errno = sigwait(&sigalrm_sigchld_sigint, &signal_received);
5953 if (errno != 0)
5954 {
5955
5956 if (errno == EINTR)
5957 continue;
5958 else
5959 {
5960 pg_log_error("could not wait for signals: %m");
5961 done = true;
5962 break;
5963 }
5964 }
5965
5966 if (signal_received == SIGINT || signal_received == SIGCHLD)
5967 done = true;
5968
5969 break;
5970 }
5971
5972
5973 sigprocmask(SIG_UNBLOCK, &sigint, NULL);
5974#endif
5975 }
5976
5977 if (pagerpipe)
5978 {
5979 pclose(pagerpipe);
5981 }
5982 else
5983 {
5984
5985
5986
5987
5988
5989
5990
5993 }
5994
5995#ifndef WIN32
5996
5999
6000 sigprocmask(SIG_UNBLOCK, &sigalrm_sigchld_sigint, NULL);
6001#endif
6002
6004 return (res >= 0);
6005}
6006
6007
6008
6009
6010
6011static bool
6013{
6015 {
6016 printf(_("/******** QUERY *********/\n"
6017 "%s\n"
6018 "/************************/\n\n"), query);
6021 {
6023 _("/******** QUERY *********/\n"
6024 "%s\n"
6025 "/************************/\n\n"), query);
6027 }
6028
6030 return false;
6031 }
6032 return true;
6033}
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043static bool
6045 Oid *obj_oid)
6046{
6047 bool result = true;
6050
6051 switch (obj_type)
6052 {
6054
6055
6056
6057
6058
6059
6063 strchr(desc, '(') ? "regprocedure" : "regproc");
6064 break;
6065
6067
6068
6069
6070
6071
6072
6076 break;
6077 }
6078
6080 {
6082 return false;
6083 }
6087 else
6088 {
6090 result = false;
6091 }
6092
6095
6096 return result;
6097}
6098
6099
6100
6101
6102
6103static bool
6106{
6107 bool result = true;
6110
6111 switch (obj_type)
6112 {
6115 "SELECT pg_catalog.pg_get_functiondef(%u)",
6116 oid);
6117 break;
6118
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6134 {
6136 "SELECT nspname, relname, relkind, "
6137 "pg_catalog.pg_get_viewdef(c.oid, true), "
6138 "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
6139 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
6140 "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
6141 "FROM pg_catalog.pg_class c "
6142 "LEFT JOIN pg_catalog.pg_namespace n "
6143 "ON c.relnamespace = n.oid WHERE c.oid = %u",
6144 oid);
6145 }
6146 else
6147 {
6149 "SELECT nspname, relname, relkind, "
6150 "pg_catalog.pg_get_viewdef(c.oid, true), "
6151 "c.reloptions AS reloptions, "
6152 "NULL AS checkoption "
6153 "FROM pg_catalog.pg_class c "
6154 "LEFT JOIN pg_catalog.pg_namespace n "
6155 "ON c.relnamespace = n.oid WHERE c.oid = %u",
6156 oid);
6157 }
6158 break;
6159 }
6160
6162 {
6164 return false;
6165 }
6168 {
6170 switch (obj_type)
6171 {
6174 break;
6175
6177 {
6178 char *nspname = PQgetvalue(res, 0, 0);
6180 char *relkind = PQgetvalue(res, 0, 2);
6181 char *viewdef = PQgetvalue(res, 0, 3);
6182 char *reloptions = PQgetvalue(res, 0, 4);
6183 char *checkoption = PQgetvalue(res, 0, 5);
6184
6185
6186
6187
6188
6189
6190
6191 switch (relkind[0])
6192 {
6193#ifdef NOT_USED
6194 case RELKIND_MATVIEW:
6196 break;
6197#endif
6198 case RELKIND_VIEW:
6200 break;
6201 default:
6204 result = false;
6205 break;
6206 }
6209
6210
6211 if (reloptions != NULL && strlen(reloptions) > 2)
6212 {
6217 {
6218 pg_log_error("could not parse reloptions array");
6219 result = false;
6220 }
6222 }
6223
6224
6226
6227
6228 if (buf->len > 0 && buf->data[buf->len - 1] == ';')
6229 buf->data[--(buf->len)] = '\0';
6230
6231
6232 if (checkoption && checkoption[0] != '\0')
6234 checkoption);
6235 }
6236 break;
6237 }
6238
6239 if (buf->len > 0 && buf->data[buf->len - 1] != '\n')
6241 }
6242 else
6243 {
6245 result = false;
6246 }
6247
6250
6251 return result;
6252}
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263static int
6265{
6266 char *c;
6267 int lineno;
6268
6269 if (!obj || obj[0] == '\0')
6270 return -1;
6271
6272 c = obj + strlen(obj) - 1;
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285 while (c > obj && isascii((unsigned char) *c) && isspace((unsigned char) *c))
6286 c--;
6287
6288
6289 if (c == obj || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
6290 return -1;
6291
6292
6293 while (c > obj && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
6294 c--;
6295
6296
6297
6298 if (c == obj || !isascii((unsigned char) *c) ||
6299 !(isspace((unsigned char) *c) || *c == ')'))
6300 return -1;
6301
6302
6303 c++;
6304 lineno = atoi(c);
6305 if (lineno < 1)
6306 {
6308 return 0;
6309 }
6310
6311
6312 *c = '\0';
6313
6314 return lineno;
6315}
6316
6317
6318
6319
6320
6321static int
6323{
6324 int lineno = 0;
6325 const char *lines = buf->data;
6326
6327 while (*lines != '\0')
6328 {
6329 lineno++;
6330
6331 lines = strchr(lines, '\n');
6332 if (!lines)
6333 break;
6334 lines++;
6335 }
6336
6337 return lineno;
6338}
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351static void
6353{
6354 bool in_header = is_func;
6355 int lineno = 0;
6356
6357 while (*lines != '\0')
6358 {
6359 char *eol;
6360
6361 if (in_header &&
6362 (strncmp(lines, "AS ", 3) == 0 ||
6363 strncmp(lines, "BEGIN ", 6) == 0 ||
6364 strncmp(lines, "RETURN ", 7) == 0))
6365 in_header = false;
6366
6367
6368 if (!in_header)
6369 lineno++;
6370
6371
6372 eol = strchr(lines, '\n');
6373 if (eol != NULL)
6374 *eol = '\0';
6375
6376
6377 if (in_header)
6379 else
6381
6382
6383 if (eol == NULL)
6384 break;
6385 lines = ++eol;
6386 }
6387}
6388
6389
6390
6391
6392
6393static void
6395{
6397 const char *fld;
6398
6400
6402 if (fld)
6404 else
6407 if (fld)
6409 else
6412
6414
6416}
void expand_tilde(char **filename)
PGresult * PSQLexec(const char *query)
volatile sig_atomic_t sigint_interrupt_enabled
sigjmp_buf sigint_interrupt_jmp
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows)
void SetShellResultVariables(int wait_result)
void NoticeProcessor(void *arg, const char *message)
void clean_extended_state(void)
bool standard_strings(void)
bool setQFout(const char *fname)
bool recognized_connection_string(const char *connstr)
bool do_copy(const char *args)
static Datum values[MAXATTR]
#define ngettext(s, p, n)
void ResetCancelConn(void)
static backslashResult exec_command_startpipeline(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static backslashResult exec_command_getresults(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
int process_file(char *filename, bool use_relative_path)
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch)
static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf)
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
static char * pset_value_string(const char *param, printQueryOpt *popt)
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static bool set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
static void ignore_boolean_expression(PsqlScanState scan_state)
static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
static backslashResult exec_command_flushrequest(PsqlScanState scan_state, bool active_branch)
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
static backslashResult exec_command_bind(PsqlScanState scan_state, bool active_branch)
static const char * _unicode_linestyle2string(int linestyle)
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
static backslashResult exec_command_bind_named(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool discard_on_quit, bool *edited)
static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static char * pset_quoted_string(const char *str)
static backslashResult exec_command_close(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static bool param_is_newly_set(const char *old_val, const char *new_val)
static void ignore_slash_whole_line(PsqlScanState scan_state)
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static const char * pset_bool_string(bool val)
static int count_lines_in_buf(PQExpBuffer buf)
static bool echo_hidden_command(const char *query)
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
static void printSSLInfo(void)
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
static void ignore_slash_filepipe(PsqlScanState scan_state)
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
static bool printPsetInfo(const char *param, printQueryOpt *popt)
static const char * _align2string(enum printFormat in)
static char * read_connect_arg(PsqlScanState scan_state)
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
backslashResult HandleSlashCmds(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool editFile(const char *fname, int lineno)
static backslashResult exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
void UnsyncVariables(void)
static backslashResult exec_command_endpipeline(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
static void wait_until_connected(PGconn *conn)
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
static bool do_shell(const char *command)
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_parse(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
static void ignore_slash_options(PsqlScanState scan_state)
static backslashResult exec_command_flush(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command(const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
void connection_warnings(bool in_startup)
static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
static backslashResult exec_command_syncpipeline(PsqlScanState scan_state, bool active_branch)
static void minimal_error_message(PGresult *res)
static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
static bool is_branching_command(const char *cmd)
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
static void print_with_linenumbers(FILE *output, char *lines, bool is_func)
static int strip_lineno_from_objdesc(char *obj)
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch)
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
static void printGSSInfo(void)
static char * prompt_for_password(const char *username, bool *canceled)
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
enum _backslashResult backslashResult
void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
ifState conditional_stack_peek(ConditionalStack cstack)
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
bool conditional_stack_pop(ConditionalStack cstack)
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
int conditional_stack_get_query_len(ConditionalStack cstack)
bool conditional_active(ConditionalStack cstack)
int conditional_stack_get_paren_depth(ConditionalStack cstack)
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
#define fprintf(file, fmt, msg)
bool listUserMappings(const char *pattern, bool verbose)
bool listTSConfigs(const char *pattern, bool verbose)
bool describeRoles(const char *pattern, bool verbose, bool showSystem)
bool listOpFamilyFunctions(const char *access_method_pattern, const char *family_pattern, bool verbose)
bool listPublications(const char *pattern)
bool listTSParsers(const char *pattern, bool verbose)
bool listExtensionContents(const char *pattern)
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
bool listForeignDataWrappers(const char *pattern, bool verbose)
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
bool describeSubscriptions(const char *pattern, bool verbose)
bool describeRoleGrants(const char *pattern, bool showSystem)
bool listExtendedStats(const char *pattern)
bool describeTypes(const char *pattern, bool verbose, bool showSystem)
bool listOperatorFamilies(const char *access_method_pattern, const char *type_pattern, bool verbose)
bool listForeignServers(const char *pattern, bool verbose)
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
bool listDomains(const char *pattern, bool verbose, bool showSystem)
bool listTSDictionaries(const char *pattern, bool verbose)
bool listDbRoleSettings(const char *pattern, const char *pattern2)
bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
bool listCollations(const char *pattern, bool verbose, bool showSystem)
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
bool listExtensions(const char *pattern)
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
bool listTSTemplates(const char *pattern, bool verbose)
bool describeTablespaces(const char *pattern, bool verbose)
bool listCasts(const char *pattern, bool verbose)
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
bool listForeignTables(const char *pattern, bool verbose)
bool describeConfigurationParameters(const char *pattern, bool verbose, bool showSystem)
bool listEventTriggers(const char *pattern, bool verbose)
bool listDefaultACLs(const char *pattern)
bool listAllDbs(const char *pattern, bool verbose)
bool listConversions(const char *pattern, bool verbose, bool showSystem)
bool permissionsList(const char *pattern, bool showSystem)
bool describeAccessMethods(const char *pattern, bool verbose)
bool listLargeObjects(bool verbose)
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
bool describePublications(const char *pattern)
bool objectDescription(const char *pattern, bool showSystem)
int errmsg(const char *fmt,...)
PGresult * PQchangePassword(PGconn *conn, const char *user, const char *passwd)
int PQserverVersion(const PGconn *conn)
int PQprotocolVersion(const PGconn *conn)
char * PQoptions(const PGconn *conn)
char * PQdb(const PGconn *conn)
char * PQport(const PGconn *conn)
char * PQhost(const PGconn *conn)
char * PQservice(const PGconn *conn)
int PQconnectionUsedPassword(const PGconn *conn)
PQconninfoOption * PQconninfo(PGconn *conn)
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
void PQconninfoFree(PQconninfoOption *connOptions)
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
int PQconnectionNeedsPassword(const PGconn *conn)
int PQconnectionUsedGSSAPI(const PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
int PQclientEncoding(const PGconn *conn)
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
void PQfinish(PGconn *conn)
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
char * PQhostaddr(const PGconn *conn)
int PQbackendPID(const PGconn *conn)
PQconninfoOption * PQconndefaults(void)
char * PQuser(const PGconn *conn)
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
char * PQerrorMessage(const PGconn *conn)
int PQsocket(const PGconn *conn)
int PQsetClientEncoding(PGconn *conn, const char *encoding)
void PQfreemem(void *ptr)
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
ExecStatusType PQresultStatus(const PGresult *res)
void PQclear(PGresult *res)
int PQntuples(const PGresult *res)
char * PQresultErrorField(const PGresult *res, int fieldcode)
PGresult * PQexec(PGconn *conn, const char *query)
int PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time)
pg_usec_time_t PQgetCurrentTimeUSec(void)
int PQgssEncInUse(PGconn *conn)
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
int PQsslInUse(PGconn *conn)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
void * pg_realloc(void *ptr, size_t size)
#define pg_realloc_array(pointer, type, count)
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
void printTableCleanup(printTableContent *const content)
void restore_sigpipe_trap(void)
const printTextFormat * get_line_style(const printTableOpt *opt)
FILE * PageOutput(int lines, const printTableOpt *topt)
void refresh_utf8format(const printTableOpt *opt)
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
const printTextFormat pg_asciiformat
void ClosePager(FILE *pagerpipe)
const printTextFormat pg_asciiformat_old
void disable_sigpipe_trap(void)
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
printTextFormat pg_utf8format
volatile sig_atomic_t cancel_pressed
@ PRINT_XHEADER_EXACT_WIDTH
@ UNICODE_LINESTYLE_SINGLE
@ UNICODE_LINESTYLE_DOUBLE
Assert(PointerIsAligned(start, uint64))
void helpVariables(unsigned short int pager)
void helpSQL(const char *topic, unsigned short int pager)
void slashUsage(unsigned short int pager)
void print_copyright(void)
bool printHistory(const char *fname, unsigned short int pager)
char * gets_fromFile(FILE *source)
static const JsonPathKeyword keywords[]
bool do_lo_export(const char *loid_arg, const char *filename_arg)
bool do_lo_import(const char *filename_arg, const char *comment_arg)
bool do_lo_unlink(const char *loid_arg)
void pg_logging_config(int new_flags)
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define PG_LOG_FLAG_TERSE
int MainLoop(FILE *source)
char * pstrdup(const char *in)
void pfree(void *pointer)
static int server_version
#define pg_encoding_to_char
#define pg_log_warning(...)
void join_path_components(char *ret_path, const char *head, const char *tail)
#define is_absolute_path(filename)
int pg_strcasecmp(const char *s1, const char *s2)
void get_parent_directory(char *path)
void canonicalize_path_enc(char *path, int encoding)
bool has_drive_prefix(const char *path)
size_t strlcpy(char *dst, const char *src, size_t siz)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
#define PG_DIAG_MESSAGE_PRIMARY
static bool is_unixsock_path(const char *path)
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
void initPQExpBuffer(PQExpBuffer str)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)
void psql_scan_reset(PsqlScanState state)
void psql_scan_slash_command_end(PsqlScanState state)
void psql_scan_set_paren_depth(PsqlScanState state, int depth)
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
int psql_scan_get_paren_depth(PsqlScanState state)
char * psql_scan_slash_command(PsqlScanState state)
static int before(chr x, chr y)
#define relpath(rlocator, forknum)
#define DEFAULT_EDITOR_LINENUMBER_ARG
@ PSQL_ECHO_HIDDEN_NOEXEC
@ PSQL_SEND_PIPELINE_SYNC
@ PSQL_SEND_FLUSH_REQUEST
@ PSQL_SEND_START_PIPELINE_MODE
@ PSQL_SEND_EXTENDED_QUERY_PARAMS
@ PSQL_SEND_EXTENDED_PARSE
@ PSQL_SEND_END_PIPELINE_MODE
@ PSQL_SEND_EXTENDED_CLOSE
@ PSQL_SEND_EXTENDED_QUERY_PREPARED
void pg_usleep(long microsec)
char * simple_prompt_extended(const char *prompt, bool echo, PromptInterruptContext *prompt_ctx)
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
const char * fmtId(const char *rawid)
void setFmtEncoding(int encoding)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
volatile sig_atomic_t * enabled
PGresult * last_error_result
enum trivalue getPassword
PGContextVisibility show_context
PSQL_ECHO_HIDDEN echo_hidden
printQueryOpt * gsavepopt
const bool * translate_columns
unsigned short int expanded
unicode_linestyle unicode_border_linestyle
struct separator fieldSep
int expanded_header_exact_width
struct separator recordSep
printXheaderWidthType expanded_header_width_type
const printTextFormat * line_style
unsigned short int border
unicode_linestyle unicode_header_linestyle
unicode_linestyle unicode_column_linestyle
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
static void usage(const char *progname)
void PrintVariables(VariableSpace space)
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
bool ParseVariableBool(const char *value, const char *name, bool *result)
bool ParseVariableNum(const char *value, const char *name, int *result)
bool SetVariable(VariableSpace space, const char *name, const char *value)
char * wait_result_to_str(int exitstatus)