PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ ShpDumperOpenTable()

int ShpDumperOpenTable ( SHPDUMPERSTATE state)

Definition at line 1333 of file pgsql2shp-core.c.

1334{
1335 PGresult *res;
1336
1337 char buf[256];
1338 char *query;
1339 int gidfound = 0, i, j, ret, status;
1340
1341
1342 /* Open the column map if one was specified */
1343 if (state->config->column_map_filename)
1344 {
1346 &state->column_map, state->message, SHPDUMPERMSGLEN);
1347 if (!ret) return SHPDUMPERERR;
1348 }
1349
1350 /* If a user-defined query has been specified, create and point the state to our new table */
1351 if (state->config->usrquery)
1352 {
1353 state->table = malloc(20 + 20); /* string + max long precision */
1354 sprintf(state->table, "__pgsql2shp%lu_tmp_table", (long)getpid());
1355
1356 query = malloc(32 + strlen(state->table) + strlen(state->config->usrquery));
1357
1358 sprintf(query, "CREATE TEMP TABLE \"%s\" AS %s", state->table, state->config->usrquery);
1359 res = PQexec(state->conn, query);
1360 free(query);
1361
1362 /* Execute the code to create the table */
1363 if (PQresultStatus(res) != PGRES_COMMAND_OK)
1364 {
1365 snprintf(state->message, SHPDUMPERMSGLEN, _("Error executing user query: %s"), PQresultErrorMessage(res));
1366 PQclear(res);
1367 return SHPDUMPERERR;
1368 }
1369 }
1370 else
1371 {
1372 /* Simply point the state to copies of the supplied schema and table */
1373 state->table = strdup(state->config->table);
1374 if (state->config->schema)
1375 state->schema = strdup(state->config->schema);
1376 }
1377
1378
1379 /* Get the list of columns and their types for the selected table */
1380 if (state->schema)
1381 {
1382 query = malloc(250 + strlen(state->schema) + strlen(state->table));
1383
1384 sprintf(query, "SELECT a.attname, a.atttypid, "
1385 "a.atttypmod, a.attlen FROM "
1386 "pg_attribute a, pg_class c, pg_namespace n WHERE "
1387 "n.nspname = '%s' AND a.attrelid = c.oid AND "
1388 "n.oid = c.relnamespace AND "
1389 "a.atttypid != 0 AND "
1390 "a.attnum > 0 AND c.relname = '%s'", state->schema, state->table);
1391 }
1392 else
1393 {
1394 query = malloc(250 + strlen(state->table));
1395
1396 sprintf(query, "SELECT a.attname, a.atttypid, "
1397 "a.atttypmod, a.attlen FROM "
1398 "pg_attribute a, pg_class c WHERE "
1399 "a.attrelid = c.oid and a.attnum > 0 AND "
1400 "a.atttypid != 0 AND "
1401 "c.relname = '%s' AND "
1402 "pg_catalog.pg_table_is_visible(c.oid)", state->table);
1403 }
1404
1405 LWDEBUGF(3, "query is: %s\n", query);
1406
1407 res = PQexec(state->conn, query);
1408 free(query);
1409
1410 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1411 {
1412 snprintf(state->message, SHPDUMPERMSGLEN, _("Error querying for attributes: %s"), PQresultErrorMessage(res));
1413 PQclear(res);
1414 return SHPDUMPERERR;
1415 }
1416
1417 if (!PQntuples(res))
1418 {
1419 snprintf(state->message, SHPDUMPERMSGLEN, _("Table %s does not exist"), state->table);
1420 PQclear(res);
1421 return SHPDUMPERERR;
1422 }
1423
1424 /* If a shapefile name was specified, use it. Otherwise simply use the table name. */
1425 if (state->config->shp_file != NULL)
1426 state->shp_file = state->config->shp_file;
1427 else
1428 state->shp_file = state->table;
1429
1430 /* Create the dbf file: */
1431 /* If there's a user-specified encoding hanging around, try and use that. */
1432 /* Otherwise, just use UTF-8 encoding, since that's usually our client encoding. */
1433 if ( getenv("PGCLIENTENCODING") )
1434 {
1435 char *codepage = encoding2codepage(getenv("PGCLIENTENCODING"));
1436 state->dbf = DBFCreateEx(state->shp_file, codepage);
1437 }
1438 else
1439 {
1440 state->dbf = DBFCreateEx(state->shp_file, "UTF-8");
1441 }
1442
1443 if (!state->dbf)
1444 {
1445 snprintf(state->message, SHPDUMPERMSGLEN, _("Could not create dbf file %s"), state->shp_file);
1446 return SHPDUMPERERR;
1447 }
1448
1449 /*
1450 * Scan the result setting fields to be returned in mainscan
1451 * query, filling the type_ary, and creating .dbf and .shp files.
1452 */
1453 state->dbffieldnames = malloc(sizeof(char *) * PQntuples(res));
1454 state->dbffieldtypes = malloc(sizeof(int) * PQntuples(res));
1455 state->pgfieldnames = malloc(sizeof(char *) * PQntuples(res));
1456 state->pgfieldlens = malloc(sizeof(int) * PQntuples(res));
1457 state->pgfieldtypmods = malloc(sizeof(int) * PQntuples(res));
1458 state->fieldcount = 0;
1459 int tmpint = 1;
1460
1461 for (i = 0; i < PQntuples(res); i++)
1462 {
1463 char *ptr;
1464
1465 int pgfieldtype, pgtypmod, pgfieldlen;
1466 char *pgfieldname;
1467
1468 int dbffieldtype, dbffieldsize, dbffielddecs;
1469 char *dbffieldname;
1470
1471 pgfieldname = PQgetvalue(res, i, 0);
1472 pgfieldtype = atoi(PQgetvalue(res, i, 1));
1473 pgtypmod = atoi(PQgetvalue(res, i, 2));
1474 pgfieldlen = atoi(PQgetvalue(res, i, 3));
1475 dbffieldtype = -1;
1476 dbffieldsize = 0;
1477 dbffielddecs = 0;
1478
1479 /*
1480 * This is a geometry/geography column
1481 */
1482 if (pgfieldtype == state->geom_oid || pgfieldtype == state->geog_oid)
1483 {
1484 /* If no geometry/geography column has been found yet... */
1485 if (!state->geo_col_name)
1486 {
1487 /* If either no geo* column name was provided (in which case this is
1488 the first match) or we match the provided column name, we have
1489 found our geo* column */
1490 if (!state->config->geo_col_name || !strcmp(state->config->geo_col_name, pgfieldname))
1491 {
1492 dbffieldtype = 9;
1493
1494 state->geo_col_name = strdup(pgfieldname);
1495 }
1496 }
1497 }
1498
1499 /*
1500 * Everything else (non geometries) will be
1501 * a DBF attribute.
1502 */
1503
1504 /* Skip gid (if not asked to do otherwise */
1505 if (!strcmp(pgfieldname, "gid") )
1506 {
1507 gidfound = 1;
1508
1509 if (!state->config->includegid)
1510 continue;
1511 }
1512
1513 /* Unescape any reserved column names */
1514 ptr = pgfieldname;
1515 if (!state->config->unescapedattrs)
1516 {
1517 if (*ptr == '_')
1518 ptr += 2;
1519 }
1520
1521 /*
1522 * This needs special handling since both xmin and _xmin
1523 * becomes __xmin when escaped
1524 */
1525
1526 /* Limit dbf field name to 10-digits */
1527 dbffieldname = malloc(11);
1528 strncpy(dbffieldname, ptr, 10);
1529 dbffieldname[10] = '\0';
1530
1531 /* If a column map file has been passed in,
1532 * use this to create the dbf field name from
1533 * the PostgreSQL column name */
1534 {
1535 const char *mapped = colmap_dbf_by_pg(&state->column_map, dbffieldname);
1536 if (mapped)
1537 {
1538 strncpy(dbffieldname, mapped, 10);
1539 dbffieldname[10] = '\0';
1540 }
1541 }
1542
1543 /*
1544 * make sure the fields all have unique names,
1545 */
1546 tmpint = 1;
1547 for (j = 0; j < state->fieldcount; j++)
1548 {
1549 if (!strncasecmp(dbffieldname, state->dbffieldnames[j], 10))
1550 {
1551 sprintf(dbffieldname, "%.7s_%.2d", ptr, abs(tmpint) % 100);
1552 tmpint++;
1553 continue;
1554 }
1555 }
1556
1557 /* make UPPERCASE if keep_fieldname_case = 0 */
1558 if (!state->config->keep_fieldname_case)
1559 {
1560 size_t nameit;
1561 for (nameit = 0; nameit < strlen(dbffieldname); nameit++)
1562 dbffieldname[nameit] = toupper(dbffieldname[nameit]);
1563 }
1564
1565 /* Issue warning if column has been renamed */
1566 if (strcasecmp(dbffieldname, pgfieldname))
1567 {
1568 if ( snprintf(buf, 256, _("Warning, field %s renamed to %s\n"),
1569 pgfieldname, dbffieldname) >= 256 )
1570 {
1571 buf[255] = '\0';
1572 }
1573 /* Note: we concatenate all warnings from the main loop as this is useful information */
1574 strncat(state->message, buf, SHPDUMPERMSGLEN - strlen(state->message) - 1);
1575
1576 ret = SHPDUMPERWARN;
1577 }
1578
1579
1580 /*
1581 * Find appropriate type of dbf attributes
1582 */
1583
1584 /* int2 type */
1585 if (pgfieldtype == 21)
1586 {
1587 /*
1588 * Longest text representation for
1589 * an int2 type (16bit) is 6 bytes
1590 * (-32768)
1591 */
1592 dbffieldtype = FTInteger;
1593 dbffieldsize = 6;
1594 dbffielddecs = 0;
1595 }
1596
1597 /* int4 type */
1598 else if (pgfieldtype == 23)
1599 {
1600 /*
1601 * Longest text representation for
1602 * an int4 type (32bit) is 11 bytes
1603 * (-2147483648)
1604 */
1605 dbffieldtype = FTInteger;
1606 dbffieldsize = 11;
1607 dbffielddecs = 0;
1608 }
1609
1610 /* int8 type */
1611 else if (pgfieldtype == 20)
1612 {
1613 /*
1614 * Longest text representation for
1615 * an int8 type (64bit) is 20 bytes
1616 * (-9223372036854775808)
1617 */
1618 dbffieldtype = FTInteger;
1619 dbffieldsize = 19;
1620 dbffielddecs = 0;
1621 }
1622
1623 /*
1624 * double or numeric types:
1625 * 700: float4
1626 * 701: float8
1627 * 1700: numeric
1628 *
1629 *
1630 * TODO: stricter handling of sizes
1631 */
1632 else if (pgfieldtype == 700 || pgfieldtype == 701 || pgfieldtype == 1700)
1633 {
1634 dbffieldtype = FTDouble;
1635 dbffieldsize = 32;
1636 dbffielddecs = 10;
1637 }
1638
1639 /*
1640 * Boolean field, we use FTLogical
1641 */
1642 else if (pgfieldtype == 16)
1643 {
1644 dbffieldtype = FTLogical;
1645 dbffieldsize = 1;
1646 dbffielddecs = 0;
1647 }
1648
1649 /*
1650 * Date field
1651 */
1652 else if (pgfieldtype == 1082)
1653 {
1654 dbffieldtype = FTDate;
1655 dbffieldsize = 8;
1656 dbffielddecs = 0;
1657 }
1658
1659 /*
1660 * time, timetz, timestamp, or timestamptz field.
1661 */
1662 else if (pgfieldtype == 1083 || pgfieldtype == 1266 || pgfieldtype == 1114 || pgfieldtype == 1184)
1663 {
1664 int secondsize;
1665
1666 switch (pgtypmod)
1667 {
1668 case -1:
1669 secondsize = 6 + 1;
1670 break;
1671 case 0:
1672 secondsize = 0;
1673 break;
1674 default:
1675 secondsize = pgtypmod + 1;
1676 break;
1677 }
1678
1679 /* We assume the worst case scenario for all of these:
1680 * date = '5874897-12-31' = 13
1681 * date = '294276-11-20' = 12 (with --enable-interger-datetimes)
1682 * time = '00:00:00' = 8
1683 * zone = '+01:39:52' = 9 (see Europe/Helsinki around 1915)
1684 */
1685
1686 /* time */
1687 if (pgfieldtype == 1083)
1688 {
1689 dbffieldsize = 8 + secondsize;
1690 }
1691 /* timetz */
1692 else if (pgfieldtype == 1266)
1693 {
1694 dbffieldsize = 8 + secondsize + 9;
1695 }
1696 /* timestamp */
1697 else if (pgfieldtype == 1114)
1698 {
1699 dbffieldsize = 13 + 1 + 8 + secondsize;
1700 }
1701 /* timestamptz */
1702 else if (pgfieldtype == 1184)
1703 {
1704 dbffieldsize = 13 + 1 + 8 + secondsize + 9;
1705 }
1706
1707 dbffieldtype = FTString;
1708 dbffielddecs = 0;
1709 }
1710
1711 /*
1712 * uuid type 36 bytes (12345678-9012-3456-7890-123456789012)
1713 */
1714 else if (pgfieldtype == 2950)
1715 {
1716 dbffieldtype = FTString;
1717 dbffieldsize = 36;
1718 dbffielddecs = 0;
1719 }
1720
1721 /*
1722 * For variable-sized fields we know about, we use
1723 * the maximum allowed size.
1724 * 1042 is bpchar, 1043 is varchar
1725 */
1726 else if ((pgfieldtype == 1042 || pgfieldtype == 1043) && pgtypmod != -1)
1727 {
1728 /*
1729 * mod is maximum allowed size, including
1730 * header which contains *real* size.
1731 */
1732 dbffieldtype = FTString;
1733 dbffieldsize = pgtypmod - 4; /* 4 is header size */
1734 dbffielddecs = 0;
1735 }
1736
1737 /* For all other valid non-geometry/geography fields... */
1738 else if (dbffieldtype == -1)
1739 {
1740 /*
1741 * For types we don't know anything about, all
1742 * we can do is query the table for the maximum field
1743 * size.
1744 */
1745 dbffieldsize = getMaxFieldSize(state->conn, state->schema, state->table, pgfieldname);
1746 if (dbffieldsize == -1)
1747 {
1748 free(dbffieldname);
1749 return 0;
1750 }
1751
1752 if (!dbffieldsize)
1753 dbffieldsize = 32;
1754
1755 /* might 0 be a good size ? */
1756
1757 dbffieldtype = FTString;
1758 dbffielddecs = 0;
1759
1760 /* Check to make sure the final field size isn't too large */
1761 if (dbffieldsize > MAX_DBF_FIELD_SIZE)
1762 {
1763 /* Note: we concatenate all warnings from the main loop as this is useful information */
1764 snprintf(buf, 256, _("Warning: values of field '%s' exceeding maximum dbf field width (%d) "
1765 "will be truncated.\n"), dbffieldname, MAX_DBF_FIELD_SIZE);
1766 strncat(state->message, buf, SHPDUMPERMSGLEN - strlen(state->message));
1767 dbffieldsize = MAX_DBF_FIELD_SIZE;
1768
1769 ret = SHPDUMPERWARN;
1770 }
1771 }
1772
1773 LWDEBUGF(3, "DBF FIELD_NAME: %s, SIZE: %d\n", dbffieldname, dbffieldsize);
1774
1775 if (dbffieldtype != 9)
1776 {
1777 /* Add the field to the DBF file */
1778 if (DBFAddField(state->dbf, dbffieldname, dbffieldtype, dbffieldsize, dbffielddecs) == -1)
1779 {
1780 snprintf(state->message, SHPDUMPERMSGLEN, _("Error: field %s of type %d could not be created."), dbffieldname, dbffieldtype);
1781
1782 return SHPDUMPERERR;
1783 }
1784
1785 /* Add the field information to our field arrays */
1786 state->dbffieldnames[state->fieldcount] = dbffieldname;
1787 state->dbffieldtypes[state->fieldcount] = dbffieldtype;
1788 state->pgfieldnames[state->fieldcount] = pgfieldname;
1789 state->pgfieldlens[state->fieldcount] = pgfieldlen;
1790 state->pgfieldtypmods[state->fieldcount] = pgtypmod;
1791
1792 state->fieldcount++;
1793 }
1794 }
1795
1796 /* Now we have generated the field lists, grab some info about the table */
1797 status = getTableInfo(state);
1798 if (status == SHPDUMPERERR)
1799 return SHPDUMPERERR;
1800
1801 LWDEBUGF(3, "rows: %d\n", state->rowcount);
1802 LWDEBUGF(3, "shptype: %c\n", state->outtype);
1803 LWDEBUGF(3, "shpouttype: %d\n", state->outshptype);
1804
1805 /* If we didn't find a geometry/geography column... */
1806 if (!state->geo_col_name)
1807 {
1808 if (state->config->geo_col_name)
1809 {
1810 /* A geo* column was specified, but not found */
1811 snprintf(state->message, SHPDUMPERMSGLEN, _("%s: no such attribute in table %s"), state->config->geo_col_name, state->table);
1812
1813 return SHPDUMPERERR;
1814 }
1815 else
1816 {
1817 /* No geo* column specified so we can only create the DBF section -
1818 but let's issue a warning... */
1819 snprintf(buf, 256, _("No geometry column found.\nThe DBF file will be created but not the shx or shp files.\n"));
1820 strncat(state->message, buf, SHPDUMPERMSGLEN - strlen(state->message));
1821
1822 state->shp = NULL;
1823
1824 ret = SHPDUMPERWARN;
1825 }
1826 }
1827 else
1828 {
1829 /* Since we have found a geo* column, open the shapefile */
1830 state->shp = SHPCreate(state->shp_file, state->outshptype);
1831 if (!state->shp)
1832 {
1833 snprintf(state->message, SHPDUMPERMSGLEN, _("Could not open shapefile %s!"), state->shp_file);
1834
1835 return SHPDUMPERERR;
1836 }
1837 }
1838
1839
1840 /* Now we have the complete list of fieldnames, let's generate the SQL query. First let's make sure
1841 we reserve enough space for tables with lots of columns */
1842 j = 0;
1843 /*TODO: this really should be rewritten to use stringbuffer */
1844 for (i = 0; i < state->fieldcount; i++)
1845 j += strlen( state->pgfieldnames[i]) + 10; /*add extra space for the quotes to quote identify and any embedded quotes that may need escaping */
1846
1847 state->main_scan_query = malloc(1024 + j);
1848
1849 sprintf(state->main_scan_query, "DECLARE cur ");
1850 if (state->config->binary)
1851 strcat(state->main_scan_query, "BINARY ");
1852
1853 strcat(state->main_scan_query, "CURSOR FOR SELECT ");
1854
1855 for (i = 0; i < state->fieldcount; i++)
1856 {
1857 /* Comma-separated column names */
1858 if (i > 0)
1859 strcat(state->main_scan_query, ",");
1860
1861 if (state->config->binary)
1862 sprintf(buf, "%s::text", quote_identifier(state->pgfieldnames[i]) ) ;
1863 else
1864 sprintf(buf, "%s", quote_identifier(state->pgfieldnames[i]) );
1865
1866 strcat(state->main_scan_query, buf);
1867 }
1868
1869 /* If we found a valid geometry/geography column then use it */
1870 if (state->geo_col_name)
1871 {
1872 /* If this is the (only) column, no need for the initial comma */
1873 if (state->fieldcount > 0)
1874 strcat(state->main_scan_query, ",");
1875
1876#ifdef WORDS_BIGENDIAN
1877 if (state->pgis_major_version > 0)
1878 {
1879 sprintf(buf, "ST_asEWKB(ST_SetSRID(%s::geometry, 0), 'XDR') AS _geoX", quote_identifier(state->geo_col_name) );
1880 }
1881 else
1882 {
1883 sprintf(buf, "asbinary(%s::geometry, 'XDR') AS _geoX",
1885 }
1886#else
1887 if (state->pgis_major_version > 0)
1888 {
1889 sprintf(buf, "ST_AsEWKB(ST_SetSRID(%s::geometry, 0), 'NDR') AS _geoX", quote_identifier(state->geo_col_name) ) ;
1890 }
1891 else
1892 {
1893 sprintf(buf, "asbinary(%s::geometry, 'NDR') AS _geoX",
1895 }
1896#endif
1897
1898 strcat(state->main_scan_query, buf);
1899 }
1900
1901 if (state->schema)
1902 {
1903 sprintf(buf, " FROM \"%s\".\"%s\"", state->schema, state->table);
1904 }
1905 else
1906 {
1907 sprintf(buf, " FROM \"%s\"", state->table);
1908 }
1909
1910 strcat(state->main_scan_query, buf);
1911
1912 /* Order by 'gid' (if found) */
1913 if (gidfound)
1914 {
1915 sprintf(buf, " ORDER BY \"gid\"");
1916 strcat(state->main_scan_query, buf);
1917 }
1918
1919 /* Now we've finished with the result set, we can dispose of it */
1920 PQclear(res);
1921
1922 LWDEBUGF(3, "FINAL QUERY: %s\n", state->main_scan_query);
1923
1924 /*
1925 * Begin the transaction
1926 * (a cursor can only be defined inside a transaction block)
1927 */
1928 res = PQexec(state->conn, "BEGIN");
1929 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1930 {
1931 snprintf(state->message, SHPDUMPERMSGLEN, _("Error starting transaction: %s"), PQresultErrorMessage(res));
1932 PQclear(res);
1933 return SHPDUMPERERR;
1934 }
1935
1936 PQclear(res);
1937
1938 /* Execute the main scan query */
1939 res = PQexec(state->conn, state->main_scan_query);
1940 if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
1941 {
1942 snprintf(state->message, SHPDUMPERMSGLEN, _("Error executing main scan query: %s"), PQresultErrorMessage(res));
1943 PQclear(res);
1944 return SHPDUMPERERR;
1945 }
1946
1947 PQclear(res);
1948
1949 /* Setup initial scan state */
1950 state->currow = 0;
1951 state->curresrow = 0;
1952 state->currescount = 0;
1953 state->fetchres = NULL;
1954
1955 /* Generate the fetch query */
1956 state->fetch_query = malloc(256);
1957 sprintf(state->fetch_query, "FETCH %d FROM cur", state->config->fetchsize);
1958
1959 return SHPDUMPEROK;
1960}
int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
Definition dbfopen.c:757
DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename, const char *pszCodePage)
Definition dbfopen.c:628
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
void * malloc(YYSIZE_T)
void free(void *)
tuple res
Definition window.py:79
static int getMaxFieldSize(PGconn *conn, char *schema, char *table, char *fname)
char * quote_identifier(const char *s)
static int getTableInfo(SHPDUMPERSTATE *state)
#define MAX_DBF_FIELD_SIZE
#define SHPDUMPERMSGLEN
#define SHPDUMPEROK
#define SHPDUMPERERR
#define SHPDUMPERWARN
SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType)
Definition shpopen.c:828
char * encoding2codepage(const char *encoding)
Definition shpcommon.c:343
int colmap_read(const char *filename, colmap *map, char *errbuf, size_t errbuflen)
Read the content of filename into a symbol map.
Definition shpcommon.c:213
const char * colmap_dbf_by_pg(colmap *map, const char *pgname)
Definition shpcommon.c:185
#define _(String)
Definition shpcommon.h:24
SHPDUMPERCONFIG * config
char message[SHPDUMPERMSGLEN]

References _, shp_dumper_config::binary, colmap_dbf_by_pg(), colmap_read(), shp_dumper_state::column_map, shp_dumper_config::column_map_filename, shp_dumper_state::config, shp_dumper_state::conn, shp_dumper_state::currescount, shp_dumper_state::curresrow, shp_dumper_state::currow, shp_dumper_state::dbf, DBFAddField(), DBFCreateEx(), shp_dumper_state::dbffieldnames, shp_dumper_state::dbffieldtypes, encoding2codepage(), shp_dumper_state::fetch_query, shp_dumper_state::fetchres, shp_dumper_config::fetchsize, shp_dumper_state::fieldcount, free(), shp_dumper_config::geo_col_name, shp_dumper_state::geo_col_name, shp_dumper_state::geog_oid, shp_dumper_state::geom_oid, getMaxFieldSize(), getTableInfo(), shp_dumper_config::includegid, shp_dumper_config::keep_fieldname_case, LWDEBUGF, shp_dumper_state::main_scan_query, malloc(), MAX_DBF_FIELD_SIZE, shp_dumper_state::message, shp_dumper_state::outshptype, shp_dumper_state::outtype, shp_dumper_state::pgfieldlens, shp_dumper_state::pgfieldnames, shp_dumper_state::pgfieldtypmods, shp_dumper_state::pgis_major_version, quote_identifier(), shp_dumper_state::rowcount, shp_dumper_config::schema, shp_dumper_state::schema, shp_dumper_state::shp, shp_dumper_config::shp_file, shp_dumper_state::shp_file, SHPCreate(), SHPDUMPERERR, SHPDUMPERMSGLEN, SHPDUMPEROK, SHPDUMPERWARN, shp_dumper_config::table, shp_dumper_state::table, shp_dumper_config::unescapedattrs, and shp_dumper_config::usrquery.

Referenced by main(), and pgui_action_export().

Here is the call graph for this function:
Here is the caller graph for this function: