Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numeric value out of range: 1416 Cannot get geometry object from data you send to the GEOMETRY field #69

Closed
Synchro opened this issue Dec 6, 2022 · 4 comments

Comments

@Synchro
Copy link
Contributor

Synchro commented Dec 6, 2022

I'm getting a casting problem when running this update:

I have a Point value set from request properties like this:

$return_location = new Point((float)$request->latitude, (float)$request->longitude);

This is then used to update DB records:

            $count = Checkout::query()
                ->where('user_id', $user->id)
                ->limit(1)
                ->update(
                    [
                        'return_location'   => $return_location,
                    ]
                );

but even though the Point object is valid, and has a cast set correctly in its model, it fails like this:

SQLSTATE[22003]: Numeric value out of range: 1416 Cannot get geometry object from data you send to the GEOMETRY
field (SQL: update `checkouts` set `return_location` = POINT(-0.118092 51.509865), `checkouts`.`updated_at` = 
2022-12-06 11:03:38 where `user_id` = 4 limit 1)

In other contexts this field works fine.

Is there some limitation I'm running into here, or a bug?

@MatanYadaev
Copy link
Owner

Hi @Synchro, as I understand it, casts don't work when you use mass updates. You have to fetch the model before updating it.

@Synchro
Copy link
Contributor Author

Synchro commented Dec 6, 2022

Ah, ok, that explains it. I will have to take the long way around!

@Synchro Synchro closed this as completed Dec 6, 2022
@Synchro
Copy link
Contributor Author

Synchro commented Dec 7, 2022

One thought – while casts might not be applied automatically, what should I do to make use of the casting manually? For example:

$count = Checkout::query()
                ->where('user_id', $user->id)
                ->limit(1)
                ->update(
                    [
                        'return_location'   => DB::raw((string)$return_location),
                    ]
                );

My only concern here is that the default string representation might not be one that's compatible with what the DB is expecting. Is this the right way to do it, or do I need to call some toWkt() method or similar?

@MatanYadaev
Copy link
Owner

There is no clean way to do that today.

The logic happens here:

public function set($model, string $key, $value, array $attributes): Expression|null

This code should work, although I didn't test it:

$geometryCast = new GeometryCast(Point::class);
$model = new Checkout(); // just to get the DB connection out of it
$wkt = $geometryCast($model, '', $return_location, []);

If you want, you can submit a PR that makes it less dirty. It should be a function that receives a DB connection and a Geometry instance and returns a WKT that can be inserted into the DB.

Synchro added a commit to Synchro/laravel-eloquent-spatial that referenced this issue Dec 7, 2022
MatanYadaev added a commit that referenced this issue Dec 12, 2022
* Add a manual casting function, fixes #69

* Requested changes for #70

* Update .run/Test.run.xml

Co-authored-by: Matan Yadaev <[email protected]>

* Update API.md

Co-authored-by: Matan Yadaev <[email protected]>

* Update tests/Objects/GeometryTest.php

Co-authored-by: Matan Yadaev <[email protected]>

* Update tests/Objects/GeometryTest.php

Co-authored-by: Matan Yadaev <[email protected]>

* Use expression generator in cast and builder, see #70

Co-authored-by: Matan Yadaev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants