Skip to content

BulkCopy does not work for Geometry Columns when they are first column in DataTable #1568

Open
@mxcolin

Description

@mxcolin

Software versions
MySqlConnector version: 2.40
Server type (MySQL, MariaDB, Aurora, etc.) and version: MySQL 8.0.31.0
.NET version: 9
(Optional) ORM NuGet packages and versions: 2.40

Describe the bug
When using MySqlBulkCopy, if the datatable that is sent contains a MySqlGeometry column as the first column it will throw an exception, all that's required to get around it is to add a dummy column in the datatable and increment the SourceColumn number in the mapping. However, this is a required work around or the below exception is thrown.

Exception
MySqlConnector.MySqlException: 'Cannot get geometry object from data you send to the GEOMETRY field'

at MySqlConnector.Core.ServerSession.d__117.MoveNext()
at System.Threading.Tasks.ValueTask1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at MySqlConnector.Core.ResultSet.d__2.MoveNext()
at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken)
at MySqlConnector.MySqlDataReader.d__111.MoveNext()
at MySqlConnector.Core.CommandExecutor.d__0.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.MySqlCommand.<ExecuteNonQueryAsync>d__78.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult()
at MySqlConnector.MySqlBulkLoader.d__73.MoveNext()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.MySqlBulkCopy.<WriteToServerAsync>d__31.MoveNext() at System.Runtime.CompilerServices.ValueTaskAwaiter1.GetResult()
at MySqlConnector.MySqlBulkCopy.WriteToServer(DataTable dataTable)
at Program.

$(String[] args) in C:\Users\colin\Projects\Velocity\src\Example\Program.cs:line 143

Code sample

/* A concise code sample to reproduce the bug */
var cs = "Server=hostname;Port=3306;User ID=userid;Password=password;Allow Load Local Infile=True;Allow User Variables=True";
var c = new MySqlConnection(cs);
c.Open();

var ct = "CREATE TABLE test_geog (geo_id BIGINT UNIQUE NOT NULL AUTO_INCREMENT, geo_data GEOMETRY SRID 4326 NOT NULL)";

var command = new MySqlCommand(ct, c);
command.ExecuteNonQuery();

var dt = new DataTable();

// Uncomment this line to add dummy column
//dt.Columns.Add("dummy", typeof(int));
dt.Columns.Add("geo_data", typeof(MySqlGeometry));

dt.Rows.Add([
    //1, 
    MySqlGeometry.FromWkb(4326, new Point(1, 1).ToBinary())
]);

var bc = new MySqlBulkCopy(c);
bc.DestinationTableName = "test_geog";

var mapping = new MySqlBulkCopyColumnMapping();

mapping.SourceOrdinal = 0;
// Will work if above lines uncommented and source ordinal increased, just can't be 0
// mapping.SourceOrdinal = 1;

mapping.DestinationColumn = "geo_data";
bc.ColumnMappings.Add(mapping);

bc.WriteToServer(dt);

Expected behavior
There shouldn't be a need to add a dummy column.

Additional context
I used NetTopologySuite for the Point class above so I could get WKB.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions