@@ -106,7 +106,9 @@ static TargetLayerInfo* SetupTargetLayer( GDALDataset *poSrcDS,
106
106
char **papszFieldMap,
107
107
const char * pszWHERE,
108
108
int bExactFieldNameMatch,
109
- int bQuiet );
109
+ int bQuiet,
110
+ int bForceNullable,
111
+ int bUnsetDefault);
110
112
111
113
static void FreeTargetLayerInfo (TargetLayerInfo* psInfo);
112
114
@@ -932,6 +934,8 @@ int main( int nArgc, char ** papszArgv )
932
934
int nCoordDim = -1 ;
933
935
char **papszOpenOptions = NULL ;
934
936
char **papszDestOpenOptions = NULL ;
937
+ int bForceNullable = FALSE ;
938
+ int bUnsetDefault = FALSE ;
935
939
936
940
int nGCPCount = 0 ;
937
941
GDAL_GCP *pasGCPs = NULL ;
@@ -1465,6 +1469,14 @@ int main( int nArgc, char ** papszArgv )
1465
1469
papszFieldMap = CSLTokenizeStringComplex (pszFieldMap, " ," ,
1466
1470
FALSE , FALSE );
1467
1471
}
1472
+ else if ( EQUAL (papszArgv[iArg]," -forceNullable" ) )
1473
+ {
1474
+ bForceNullable = TRUE ;
1475
+ }
1476
+ else if ( EQUAL (papszArgv[iArg]," -unsetDefault" ) )
1477
+ {
1478
+ bUnsetDefault = TRUE ;
1479
+ }
1468
1480
else if ( papszArgv[iArg][0 ] == ' -' )
1469
1481
{
1470
1482
Usage (CPLSPrintf (" Unknown option name '%s'" , papszArgv[iArg]));
@@ -1882,7 +1894,9 @@ int main( int nArgc, char ** papszArgv )
1882
1894
papszFieldMap,
1883
1895
pszWHERE,
1884
1896
bExactFieldNameMatch,
1885
- bQuiet);
1897
+ bQuiet,
1898
+ bForceNullable,
1899
+ bUnsetDefault);
1886
1900
1887
1901
poPassedLayer->ResetReading ();
1888
1902
@@ -2040,7 +2054,9 @@ int main( int nArgc, char ** papszArgv )
2040
2054
papszFieldMap,
2041
2055
pszWHERE,
2042
2056
bExactFieldNameMatch,
2043
- bQuiet);
2057
+ bQuiet,
2058
+ bForceNullable,
2059
+ bUnsetDefault);
2044
2060
2045
2061
if ( psInfo == NULL && !bSkipFailures )
2046
2062
exit (1 );
@@ -2318,7 +2334,9 @@ int main( int nArgc, char ** papszArgv )
2318
2334
papszFieldMap,
2319
2335
pszWHERE,
2320
2336
bExactFieldNameMatch,
2321
- bQuiet);
2337
+ bQuiet,
2338
+ bForceNullable,
2339
+ bUnsetDefault);
2322
2340
2323
2341
poPassedLayer->ResetReading ();
2324
2342
@@ -2444,7 +2462,7 @@ static void Usage(const char* pszAdditionalMsg, int bShort)
2444
2462
" [-wrapdateline][-datelineoffset val]\n "
2445
2463
" [[-simplify tolerance] | [-segmentize max_dist]]\n "
2446
2464
" [-addfields]\n "
2447
- " [-relaxedFieldNameMatch]\n "
2465
+ " [-relaxedFieldNameMatch] [-forceNullable] [-unsetDefault] \n "
2448
2466
" [-fieldTypeToString All|(type1[,type2]*)] [-unsetFieldWidth]\n "
2449
2467
" [-mapFieldType srctype|All=dsttype[,srctype2=dsttype2]*]\n "
2450
2468
" [-fieldmap identity | index1[,index2]*]\n "
@@ -2677,7 +2695,9 @@ void DoFieldTypeConversion(GDALDataset* poDstDS, OGRFieldDefn& oFieldDefn,
2677
2695
char ** papszFieldTypesToString,
2678
2696
char ** papszMapFieldType,
2679
2697
int bUnsetFieldWidth,
2680
- int bQuiet)
2698
+ int bQuiet,
2699
+ int bForceNullable,
2700
+ int bUnsetDefault)
2681
2701
{
2682
2702
if (papszFieldTypesToString != NULL &&
2683
2703
(CSLFindString (papszFieldTypesToString, " All" ) != -1 ||
@@ -2710,6 +2730,10 @@ void DoFieldTypeConversion(GDALDataset* poDstDS, OGRFieldDefn& oFieldDefn,
2710
2730
oFieldDefn.SetWidth (0 );
2711
2731
oFieldDefn.SetPrecision (0 );
2712
2732
}
2733
+ if ( bForceNullable )
2734
+ oFieldDefn.SetNullable (TRUE );
2735
+ if ( bUnsetDefault )
2736
+ oFieldDefn.SetDefault (NULL );
2713
2737
2714
2738
if ( poDstDS->GetDriver () != NULL &&
2715
2739
poDstDS->GetDriver ()->GetMetadataItem (GDAL_DMD_CREATIONFIELDDATATYPES) != NULL &&
@@ -2782,7 +2806,9 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
2782
2806
char **papszFieldMap,
2783
2807
const char * pszWHERE,
2784
2808
int bExactFieldNameMatch,
2785
- int bQuiet)
2809
+ int bQuiet,
2810
+ int bForceNullable,
2811
+ int bUnsetDefault)
2786
2812
{
2787
2813
OGRLayer *poDstLayer;
2788
2814
OGRFeatureDefn *poSrcFDefn;
@@ -2927,6 +2953,8 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
2927
2953
2928
2954
CPLErrorReset ();
2929
2955
2956
+ char ** papszLCOTemp = CSLDuplicate (papszLCO);
2957
+
2930
2958
int eGCreateLayerType = eGType;
2931
2959
if ( anRequestedGeomFields.size () == 0 &&
2932
2960
nSrcGeomFieldCount > 1 &&
@@ -2939,8 +2967,32 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
2939
2967
{
2940
2968
eGCreateLayerType = wkbNone;
2941
2969
}
2942
-
2943
- char ** papszLCOTemp = CSLDuplicate (papszLCO);
2970
+ // If the source feature has a single geometry column that is not nullable
2971
+ // and that ODsCCreateGeomFieldAfterCreateLayer is available, use it
2972
+ // so as to be able to set the not null constraint (if the driver supports it)
2973
+ else if ( anRequestedGeomFields.size () == 0 &&
2974
+ nSrcGeomFieldCount == 1 &&
2975
+ poDstDS->TestCapability (ODsCCreateGeomFieldAfterCreateLayer) &&
2976
+ !poSrcFDefn->GetGeomFieldDefn (0 )->IsNullable () &&
2977
+ !bForceNullable)
2978
+ {
2979
+ anRequestedGeomFields.push_back (0 );
2980
+ eGCreateLayerType = wkbNone;
2981
+ }
2982
+ // If the source feature first geometry column is not nullable
2983
+ // and that GEOMETRY_NULLABLE creation option is available, use it
2984
+ // so as to be able to set the not null constraint (if the driver supports it)
2985
+ else if ( anRequestedGeomFields.size () == 0 &&
2986
+ nSrcGeomFieldCount >= 1 &&
2987
+ !poSrcFDefn->GetGeomFieldDefn (0 )->IsNullable () &&
2988
+ poDstDS->GetDriver ()->GetMetadataItem (GDAL_DS_LAYER_CREATIONOPTIONLIST) != NULL &&
2989
+ strstr (poDstDS->GetDriver ()->GetMetadataItem (GDAL_DS_LAYER_CREATIONOPTIONLIST), " GEOMETRY_NULLABLE" ) != NULL &&
2990
+ CSLFetchNameValue (papszLCO, " GEOMETRY_NULLABLE" ) == NULL &&
2991
+ !bForceNullable )
2992
+ {
2993
+ papszLCOTemp = CSLSetNameValue (papszLCOTemp, " GEOMETRY_NULLABLE" , " NO" );
2994
+ }
2995
+
2944
2996
// Force FID column as 64 bit if the source feature has a 64 bit FID,
2945
2997
// the target driver supports 64 bit FID and the user didn't set it
2946
2998
// manually.
@@ -2991,6 +3043,8 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
2991
3043
eGType = ForceCoordDimension (eGType, nCoordDim);
2992
3044
oGFldDefn.SetType ((OGRwkbGeometryType) eGType);
2993
3045
}
3046
+ if ( bForceNullable )
3047
+ oGFldDefn.SetNullable (TRUE );
2994
3048
poDstLayer->CreateGeomField (&oGFldDefn);
2995
3049
}
2996
3050
}
@@ -3082,7 +3136,9 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
3082
3136
papszFieldTypesToString,
3083
3137
papszMapFieldType,
3084
3138
bUnsetFieldWidth,
3085
- bQuiet);
3139
+ bQuiet,
3140
+ bForceNullable,
3141
+ bUnsetDefault);
3086
3142
3087
3143
/* The field may have been already created at layer creation */
3088
3144
int iDstField = -1 ;
@@ -3196,7 +3252,9 @@ static TargetLayerInfo* SetupTargetLayer( CPL_UNUSED GDALDataset *poSrcDS,
3196
3252
papszFieldTypesToString,
3197
3253
papszMapFieldType,
3198
3254
bUnsetFieldWidth,
3199
- bQuiet);
3255
+ bQuiet,
3256
+ bForceNullable,
3257
+ bUnsetDefault);
3200
3258
3201
3259
/* The field may have been already created at layer creation */
3202
3260
std::map<CPLString, int >::iterator oIter =
0 commit comments