]> granicus.if.org Git - postgis/commitdiff
Backported stricter STRING and INTEGER attributes handling.
authorSandro Santilli <strk@keybit.net>
Mon, 24 Oct 2005 11:31:27 +0000 (11:31 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 24 Oct 2005 11:31:27 +0000 (11:31 +0000)
git-svn-id: http://svn.osgeo.org/postgis/branches/pgis_1_0@1988 b70326c6-7e19-0410-871a-916f4a2858ee

loader/pgsql2shp.c
loader/shp2pgsql.c

index 549199b71087e0b838a4f05222b6cc2b878fb769..2bfe256e50bc0d6d7f8be63452a97b7dd7fc35f0 100644 (file)
@@ -2414,7 +2414,8 @@ initialize(void)
 
        if ( schema )
        {
-               sprintf(query, "SELECT a.attname, a.atttypid, a.attlen FROM "
+               sprintf(query, "SELECT a.attname, a.atttypid, a.attlen, "
+                       "a.atttypmod FROM "
                        "pg_attribute a, pg_class c, pg_namespace n WHERE "
                        "n.nspname = '%s' AND a.attrelid = c.oid AND "
                        "n.oid = c.relnamespace AND "
@@ -2423,7 +2424,8 @@ initialize(void)
        }
        else
        {
-               sprintf(query, "SELECT a.attname, a.atttypid, a.attlen FROM "
+               sprintf(query, "SELECT a.attname, a.atttypid, a.attlen, "
+                       "a.atttypmod FROM "
                        "pg_attribute a, pg_class c WHERE "
                        "a.attrelid = c.oid and a.attnum > 0 AND "
                        "a.atttypid != 0 AND "
@@ -2471,7 +2473,7 @@ initialize(void)
        for (i=0; i<PQntuples(res); i++)
        {
                int j;
-               int type, size;
+               int type, size, mod;
                char *fname; // pgsql attribute name
                char *ptr;
                char field_name[32]; // dbf version of field name
@@ -2479,6 +2481,7 @@ initialize(void)
                fname = PQgetvalue(res, i, 0);
                type = atoi(PQgetvalue(res, i, 1));
                size = atoi(PQgetvalue(res, i, 2));
+               mod = atoi(PQgetvalue(res, i, 3));
 
 //printf( "A: %s, T: %d, S: %d\n", fname, type, size);
                /*
@@ -2575,10 +2578,56 @@ initialize(void)
                 * Find appropriate type of dbf attributes
                 */
 
-               /* integer type */
-               if(type == 20 || type == 21 || type == 23)
+               /* int2 type */
+               if ( type == 21 )
                {
-                       if(DBFAddField(dbf, field_name, FTInteger,16,0) == -1)
+                       /* 
+                        * Longest text representation for
+                        * an int2 type (16bit) is 6 bytes
+                        * (-32768)
+                        */
+                       if ( DBFAddField(dbf, field_name, FTInteger,
+                               6, 0) == -1 )
+                       {
+                               printf( "error - Field could not "
+                                       "be created.\n");
+                               return 0;
+                       }
+                       type_ary[mainscan_nflds]=1;
+                       mainscan_flds[mainscan_nflds++] = fname;
+                       continue;
+               }
+
+               /* int4 type */
+               if ( type == 23 )
+               {
+                       /* 
+                        * Longest text representation for
+                        * an int4 type (32bit) is 11 bytes
+                        * (-2147483648)
+                        */
+                       if ( DBFAddField(dbf, field_name, FTInteger,
+                               11, 0) == -1 )
+                       {
+                               printf( "error - Field could not "
+                                       "be created.\n");
+                               return 0;
+                       }
+                       type_ary[mainscan_nflds]=1;
+                       mainscan_flds[mainscan_nflds++] = fname;
+                       continue;
+               }
+
+               /* int8 type */
+               if ( type == 20 )
+               {
+                       /* 
+                        * Longest text representation for
+                        * an int8 type (64bit) is 20 bytes
+                        * (-9223372036854775808)
+                        */
+                       if ( DBFAddField(dbf, field_name, FTInteger,
+                               20, 0) == -1 )
                        {
                                printf( "error - Field could not "
                                        "be created.\n");
@@ -2589,7 +2638,15 @@ initialize(void)
                        continue;
                }
                
-               /* double type */
+               /*
+                * double or numeric types:
+                *    700: float4
+                *    701: float8
+                *   1700: numeric
+                *
+                *
+                * TODO: stricter handling of sizes
+                */
                if(type == 700 || type == 701 || type == 1700 )
                {
                        if(DBFAddField(dbf, field_name,FTDouble,32,10) == -1)
@@ -2622,14 +2679,29 @@ initialize(void)
                }
 
                /*
-                * For variable-sized fields we'll use max size in table
-                * as dbf field size
+                * For variable-sized fields we'll use either 
+                * maximum allowed size (atttypmod) or max actual
+                * attribute value in table.
                 */
                else if(size == -1)
                {
-                       size = getMaxFieldSize(conn, schema, table, fname);
-                       if ( size == -1 ) return 0;
-                       if ( ! size ) size = 32; // might 0 be a good size ?
+                       /*
+                        * 1042 is bpchar,  1043 is varchar
+                        * mod is maximum allowed size, including
+                        * header which contains *real* size.
+                        */
+                       if ( (type == 1042 || type == 1043) && mod != -1 )
+                       {
+                               size = mod-4; // 4 is header size
+                       }
+                       else
+                       {
+                               size = getMaxFieldSize(conn, schema,
+                                       table, fname);
+                               if ( size == -1 ) return 0;
+                               if ( ! size ) size = 32;
+                               // might 0 be a good size ?
+                       }
                }
 //printf( "FIELD_NAME: %s, SIZE: %d\n", field_name, size);
                
@@ -3122,6 +3194,14 @@ create_usrquerytable(void)
 
 /**********************************************************************
  * $Log$
+ * Revision 1.74.2.5  2005/10/24 11:31:27  strk
+ * Backported stricter STRING and INTEGER attributes handling.
+ *
+ * Revision 1.79  2005/10/03 18:08:55  strk
+ * Stricter string attributes lenght handling. DBF header will be used
+ * to set varchar maxlenght, (var)char typmod will be used to set DBF header
+ * len.
+ *
  * Revision 1.74.2.4  2005/07/22 19:20:49  strk
  * Fixed bug in {get,pop}{int,double} for 64bit archs
  *
index 0d0388e55e03f5eaaa8a195211d8bd3eef588734..a7f4233819fde1655b236d2b5570045e2250bc8f 100644 (file)
@@ -515,7 +515,7 @@ CreateTable(void)
                field_width = widths[j];
                field_precision = precisions[j];
 
-               printf(", \"%s\" ", field_names[j]);
+               printf(",\n\"%s\" ", field_names[j]);
 
                if(hDBFHandle->pachFieldType[j] == 'D' ) /* Date field */
                {
@@ -527,23 +527,32 @@ CreateTable(void)
 
                        if(type == FTString)
                        {
-                               printf ("varchar");
+                               // use DBF attribute size as maximum width
+                               printf ("varchar(%d)", field_width);
                        }
                        else if(type == FTInteger)
                        {
-                               if ( forceint4 || field_width <= 9 )
+                               if ( forceint4 )
                                {
                                        printf ("int4");
                                }
-                               else if( field_width > 18 )
+                               else if  ( field_width <= 6 )
                                {
-                                       printf("numeric(%d,0)",
-                                               field_width);
+                                       printf ("int2");
                                }
-                               else 
+                               else if  ( field_width <= 11 )
+                               {
+                                       printf ("int4");
+                               }
+                               else if  ( field_width <= 20 )
                                {
                                        printf ("int8");
                                }
+                               else 
+                               {
+                                       printf("numeric(%d,0)",
+                                               field_width);
+                               }
                        }
                        else if(type == FTDouble)
                        {
@@ -1661,6 +1670,14 @@ utf8 (const char *fromcode, char *inputbuf)
 
 /**********************************************************************
  * $Log$
+ * Revision 1.88.2.11  2005/10/24 11:31:27  strk
+ * Backported stricter STRING and INTEGER attributes handling.
+ *
+ * Revision 1.99  2005/10/03 18:08:55  strk
+ * Stricter string attributes lenght handling. DBF header will be used
+ * to set varchar maxlenght, (var)char typmod will be used to set DBF header
+ * len.
+ *
  * Revision 1.88.2.10  2005/10/21 11:34:25  strk
  * Applied patch by Lars Roessiger handling numerical values with a trailing decima
  * l dot