<div dir="ltr"><div><div><div>+1 for clarifiying the use of types in QGIS. It is very hard for non-developers users to understand the concepts behind, and the differences between real, double, float /  int, integer, int4, int8  / varchar, char, text, string / etc.<br>
</div><br></div>The hard part would be to let the drivers use specific types != showing only "simple types" as float / string / integer / boolean.<br></div><div>Why not store the driver type (for example bigint for postgres) but only show "simple" correspondance ( integer here). The power users will be able to see the real driver type in the metadata tab (or anywhere else more appropriate).<br>
<br></div><div>I would love to see only these types in the Field tab : string / float / integer / boolean<br><br></div><div>Michael<br></div><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/5 Radim Blazek <span dir="ltr"><<a href="mailto:radim.blazek@gmail.com" target="_blank">radim.blazek@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I would like to ask how vector attribute types conversion between<br>
providers is supposed to work. Currently:<br>
<br>
QgsMemoryProvider:<br>
* mNativeTypes: int(10), double(20,5), string(255)<br>
* addAttributes() silently skips the field if type is not Int, Double<br>
or String, does not test length and precision, always returns true.<br>
<br>
QgsOgrProvider:<br>
* mNativeTypes: int(10), double(20,15), string(255), date, datetime<br>
(the types should be taken from OGR because depend on OGR driver, but<br>
I don't see any function in OGR to get supported types)<br>
* addAttributes(): if type is not supported, the field is not added,<br>
error is set and returns false, supported fields are added however.<br>
* createEmptyLayer() is using QgsVectorFileWriter which has its own<br>
field types handling (different from QgsOgrProvider::addAttributes())<br>
and calls directly OGR_L_CreateField()<br>
* convertField(): doing the same as QgsVectorFileWriter (copy pasted<br>
code) but not used at all<br>
<br>
QgsPostgresProvider:<br>
* mNativeTypes: int(0), longlong(0), double (20,20), string(255), date<br>
(there are more types defined but these are those with max<br>
lengh/precision per QVariant type)<br>
* addAttributes(): is using field typeName() to add fields, but<br>
typeName is always provider specific so it may become problem if<br>
fields come from another provider. If single field fails, no fields<br>
are added (transaction) and false is returned<br>
* createEmptyLayer(): is using convertField() (that is why d'n'd does<br>
not fail) on all fields and then addAttributes()<br>
* convertField(): sets field typeName based on type<br>
<br>
The problems I see:<br>
* impossible to take simply fields from one provider and add them to<br>
another one, for example:<br>
    * ogr -> memory: numbers are often double(24,15) or date<br>
    * ogr -> postgres: ogr is using String as typeName which fails as<br>
type in postgres, postgres mNativeTypes are too short<br>
* postgres provider addAttribute() takes typeName (which may be<br>
whatever) as type for add column<br>
* no method to convert not supported field to a supported one + get<br>
message (for example, "string cut to 255 characters" or "date<br>
converted to string"<br>
<br>
I believe that, from user point of view, if data are being written to<br>
a provider which does not supported all data types, then:<br>
* user should be warned before the data are written, getting a list of<br>
necessary type conversions and length/precision cuts<br>
* if confirmed by user, all the data should be written converted to<br>
supported types<br>
but there is no support for that in API.<br>
<br>
My suggestion:<br>
* add<br>
     virtual QgsField QgsVectorDataProvider::supportedField(field, ok, message)<br>
  which would try to convert unsupported field to a supported field<br>
and set message about conversion, it should almost never fail<br>
* all methods adding fields (createEmptyLayer, QgsVectorFileWriter)<br>
should use the same provider addAttributes()<br>
* provider addAttributes() should first check if all fields are<br>
supported using supportedField() and add nothing if at least one is<br>
unsupported (if some fields are not added successive addFeature()<br>
fails because of different number of attributes)<br>
* add support for date and datetime to memory provider and set<br>
benevolent length/precision limits (however it is not correct to set<br>
size/precision > 15 for double, that is the only way to make possible<br>
to copy data from OGR)<br>
<br>
I am not sure how QgsPostgresProvide::addAttributes() should work,<br>
because using typeName() may fail for fields from different provider<br>
while using type() (i.e. convertField()) would disable the possibility<br>
to specify explicitly postgres type by typeName. This is maybe<br>
crucial. In general, what defines field type - "type" or "typeName"?<br>
We could say that if typeName is unknown to postgres, it should use a<br>
type based on "type" but the same typeName may have different meaning<br>
for different drivers.<br>
<br>
I am talking about 2.1.<br>
<br>
Radim<br>
_______________________________________________<br>
Qgis-developer mailing list<br>
<a href="mailto:Qgis-developer@lists.osgeo.org">Qgis-developer@lists.osgeo.org</a><br>
<a href="http://lists.osgeo.org/mailman/listinfo/qgis-developer" target="_blank">http://lists.osgeo.org/mailman/listinfo/qgis-developer</a><br>
</blockquote></div><br></div>