PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ ShpLoaderGetSQLHeader()

int ShpLoaderGetSQLHeader ( SHPLOADERSTATE state,
char **  strheader 
)

TODO: if the table has more then one geometry column the DROP TABLE call will leave spurious records in geometry_columns.

If the geometry column in the table being dropped does not match 'the_geom' or the name specified with -g an error is returned by DropGeometryColumn.

The table to be dropped might not exist.

If we are in dump mode and a transform was asked for need to create a temp table to store original data You may ask, why don't we go straight into the main table and then do an alter table alter column afterwards Main reason is so we don't incur the penalty of WAL logging when we change the typmod in final run.

create a temp table with same structure as main except for no restriction on geometry type

out input data is going to be in different srid from target, so need to remove type constraint

Definition at line 1279 of file shp2pgsql-core.c.

1280 {
1281  stringbuffer_t *sb;
1282  char *ret;
1283  int j;
1284 
1285  /* Create the stringbuffer containing the header; we use this API as it's easier
1286  for handling string resizing during append */
1287  sb = stringbuffer_create();
1288  stringbuffer_clear(sb);
1289 
1290  /* Set the client encoding if required */
1291  if (state->config->encoding)
1292  {
1293  stringbuffer_aprintf(sb, "SET CLIENT_ENCODING TO UTF8;\n");
1294  }
1295 
1296  /* Use SQL-standard string escaping rather than PostgreSQL standard */
1297  stringbuffer_aprintf(sb, "SET STANDARD_CONFORMING_STRINGS TO ON;\n");
1298 
1299  /* Drop table if requested */
1300  if (state->config->opt == 'd')
1301  {
1313  if (state->config->schema)
1314  {
1315  if (state->config->readshape == 1 && (! state->config->geography) )
1316  {
1317  stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('%s','%s','%s');\n",
1318  state->config->schema, state->config->table, state->geo_col);
1319  }
1320 
1321  stringbuffer_aprintf(sb, "DROP TABLE IF EXISTS \"%s\".\"%s\";\n", state->config->schema,
1322  state->config->table);
1323  }
1324  else
1325  {
1326  if (state->config->readshape == 1 && (! state->config->geography) )
1327  {
1328  stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('','%s','%s');\n",
1329  state->config->table, state->geo_col);
1330  }
1331 
1332  stringbuffer_aprintf(sb, "DROP TABLE IF EXISTS \"%s\";\n", state->config->table);
1333  }
1334  }
1335 
1336  /* Start of transaction if we are using one */
1337  if (state->config->usetransaction)
1338  {
1339  stringbuffer_aprintf(sb, "BEGIN;\n");
1340  }
1341 
1342  /* If not in 'append' mode create the spatial table */
1343  if (state->config->opt != 'a')
1344  {
1345  /*
1346  * Create a table for inserting the shapes into with appropriate
1347  * columns and types
1348  */
1349  if (state->config->schema)
1350  {
1351  stringbuffer_aprintf(sb, "CREATE TABLE \"%s\".\"%s\" (gid serial",
1352  state->config->schema, state->config->table);
1353  }
1354  else
1355  {
1356  stringbuffer_aprintf(sb, "CREATE TABLE \"%s\" (gid serial", state->config->table);
1357  }
1358 
1359  /* Generate the field types based upon the shapefile information */
1360  for (j = 0; j < state->num_fields; j++)
1361  {
1362  stringbuffer_aprintf(sb, ",\n\"%s\" ", state->field_names[j]);
1363 
1364  /* First output the raw field type string */
1365  stringbuffer_aprintf(sb, "%s", state->pgfieldtypes[j]);
1366 
1367  /* Some types do have typmods */
1368  /* Apply width typmod for varchar if there is positive width **/
1369  if (!strcmp("varchar", state->pgfieldtypes[j]) && state->widths[j] > 0)
1370  stringbuffer_aprintf(sb, "(%d)", state->widths[j]);
1371 
1372  if (!strcmp("numeric", state->pgfieldtypes[j]))
1373  {
1374  /* Doubles we just allow PostgreSQL to auto-detect the size */
1375  if (state->types[j] != FTDouble)
1376  stringbuffer_aprintf(sb, "(%d,0)", state->widths[j]);
1377  }
1378  }
1379 
1380  /* Add the geography column directly to the table definition, we don't
1381  need to do an AddGeometryColumn() call. */
1382  if (state->config->readshape == 1 && state->config->geography)
1383  {
1384  char *dimschar;
1385 
1386  if (state->pgdims == 4)
1387  dimschar = "ZM";
1388  else
1389  dimschar = "";
1390 
1391  if (state->to_srid == SRID_UNKNOWN ){
1392  state->to_srid = 4326;
1393  }
1394 
1395  stringbuffer_aprintf(sb, ",\n\"%s\" geography(%s%s,%d)", state->geo_col, state->pgtype, dimschar, state->to_srid);
1396  }
1397  stringbuffer_aprintf(sb, ")");
1398 
1399  /* Tablespace is optional. */
1400  if (state->config->tablespace != NULL)
1401  {
1402  stringbuffer_aprintf(sb, " TABLESPACE \"%s\"", state->config->tablespace);
1403  }
1404  stringbuffer_aprintf(sb, ";\n");
1405 
1406  /* Create the primary key. This is done separately because the index for the PK needs
1407  * to be in the correct tablespace. */
1408 
1409  /* TODO: Currently PostgreSQL does not allow specifying an index to use for a PK (so you get
1410  * a default one called table_pkey) and it does not provide a way to create a PK index
1411  * in a specific tablespace. So as a hacky solution we create the PK, then move the
1412  * index to the correct tablespace. Eventually this should be:
1413  * CREATE INDEX table_pkey on table(gid) TABLESPACE tblspc;
1414  * ALTER TABLE table ADD PRIMARY KEY (gid) USING INDEX table_pkey;
1415  * A patch has apparently been submitted to PostgreSQL to enable this syntax, see this thread:
1416  * http://archives.postgresql.org/pgsql-hackers/2011-01/msg01405.php */
1417  stringbuffer_aprintf(sb, "ALTER TABLE ");
1418 
1419  /* Schema is optional, include if present. */
1420  if (state->config->schema)
1421  {
1422  stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
1423  }
1424  stringbuffer_aprintf(sb, "\"%s\" ADD PRIMARY KEY (gid);\n", state->config->table);
1425 
1426  /* Tablespace is optional for the index. */
1427  if (state->config->idxtablespace != NULL)
1428  {
1429  stringbuffer_aprintf(sb, "ALTER INDEX ");
1430  if (state->config->schema)
1431  {
1432  stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
1433  }
1434 
1435  /* WARNING: We're assuming the default "table_pkey" name for the primary
1436  * key index. PostgreSQL may use "table_pkey1" or similar in the
1437  * case of a name conflict, so you may need to edit the produced
1438  * SQL in this rare case. */
1439  stringbuffer_aprintf(sb, "\"%s_pkey\" SET TABLESPACE \"%s\";\n",
1440  state->config->table, state->config->idxtablespace);
1441  }
1442 
1443  /* Create the geometry column with an addgeometry call */
1444  if (state->config->readshape == 1 && (!state->config->geography))
1445  {
1446  /* If they didn't specify a target SRID, see if they specified a source SRID. */
1447  int32_t srid = state->to_srid;
1448  if (state->config->schema)
1449  {
1450  stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('%s','%s','%s','%d',",
1451  state->config->schema, state->config->table, state->geo_col, srid);
1452  }
1453  else
1454  {
1455  stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('','%s','%s','%d',",
1456  state->config->table, state->geo_col, srid);
1457  }
1458 
1459  stringbuffer_aprintf(sb, "'%s',%d);\n", state->pgtype, state->pgdims);
1460  }
1461  }
1462 
1466  if (state->config->dump_format && state->to_srid != state->from_srid){
1468  stringbuffer_aprintf(sb, "CREATE TEMP TABLE \"pgis_tmp_%s\" AS SELECT * FROM ", state->config->table);
1469  /* Schema is optional, include if present. */
1470  if (state->config->schema)
1471  {
1472  stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
1473  }
1474  stringbuffer_aprintf(sb, "\"%s\" WHERE false;\n", state->config->table, state->geo_col);
1476  stringbuffer_aprintf(sb, "ALTER TABLE \"pgis_tmp_%s\" ALTER COLUMN \"%s\" TYPE geometry USING ( (\"%s\"::geometry) ); \n", state->config->table, state->geo_col, state->geo_col);
1477  }
1478 
1479  /* Copy the string buffer into a new string, destroying the string buffer */
1480  ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
1481  strcpy(ret, (char *)stringbuffer_getstring(sb));
1483 
1484  *strheader = ret;
1485 
1486  return SHPLOADEROK;
1487 }
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:229
void * malloc(YYSIZE_T)
#define SHPLOADEROK
void stringbuffer_clear(stringbuffer_t *s)
Reset the stringbuffer_t.
Definition: stringbuffer.c:88
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided.
Definition: stringbuffer.c:217
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
Definition: stringbuffer.c:33
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
Definition: stringbuffer.c:76
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
Definition: stringbuffer.c:113
DBFFieldType * types
SHPLOADERCONFIG * config

References shp_loader_state::config, shp_loader_config::dump_format, shp_loader_config::encoding, shp_loader_state::field_names, shp_loader_state::from_srid, shp_loader_state::geo_col, shp_loader_config::geography, shp_loader_config::idxtablespace, malloc(), shp_loader_state::num_fields, shp_loader_config::opt, shp_loader_state::pgdims, shp_loader_state::pgfieldtypes, shp_loader_state::pgtype, shp_loader_config::readshape, shp_loader_config::schema, SHPLOADEROK, SRID_UNKNOWN, stringbuffer_aprintf(), stringbuffer_clear(), stringbuffer_create(), stringbuffer_destroy(), stringbuffer_getstring(), shp_loader_config::table, shp_loader_config::tablespace, shp_loader_state::to_srid, shp_loader_state::types, shp_loader_config::usetransaction, and shp_loader_state::widths.

Referenced by pgui_action_import().

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