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 (do\_edit(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 (fd)

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

3915 replci->val = ci->val;

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

3954 replci->val = ci->val;

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 (error && 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 (fd)

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 {

5931 long s = Min(i, 1000L);

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)