Comments (9)
The types of all parameters are set when I prepare the statement, and it's all checked before execution. How are you provoking this?
from skunk.
I have the following table:
CREATE TABLE orders (
uuid VARCHAR PRIMARY KEY,
user_id VARCHAR UNIQUE NOT NULL,
payment_id VARCHAR UNIQUE NOT NULL,
items VARCHAR NOT NULL,
total NUMERIC
);
And this command (o.total.value
is of type BigDecimal
):
val insertOrder: Command[UserId ~ Order] =
sql"""
INSERT INTO orders
VALUES ($varchar, $varchar, $varchar, $varchar, $numeric)
""".command.contramap {
case id ~ o =>
o.id.value.toString ~ id.value.toString ~ o.paymentId.value.toString ~ o.items.asJson.noSpaces ~ o.total.value
}
This is how the command is executed (not sure if relevant):
def create(
userId: UserId,
paymentId: PaymentId,
items: List[CartItem],
total: USD
): F[OrderId] =
sessionPool.use { session =>
session.prepare(insertOrder).use { cmd =>
GenUUID[F].make[OrderId].flatMap { id =>
val itMap = items.map(x => x.item.uuid -> x.quantity).toMap
val order = Order(id, paymentId, itMap, total)
cmd.execute(userId ~ order).as(id)
}
}
}
The USD
type simply wraps a BigDecimal
, which is the type of the total
column.
Here is the error being logged in the Postgres server:
2019-11-04 21:48:38.883 UTC [31] ERROR: column "total" is of type numeric but expression is of type character varying at character 61
2019-11-04 21:48:38.883 UTC [31] HINT: You will need to rewrite or cast the expression.
2019-11-04 21:48:38.883 UTC [31] STATEMENT:
INSERT INTO orders
VALUES ($1, $1, $1, $1, $1)
Anything I'm doing obviously wrong? 😄
from skunk.
I think the bug might have been introduced when inserting values in the following way was fixed:
INSERT INTO foo
VALUES ($codec)
If there's any other error this is what I see in the Postgres logs (before it was all $1
s):
INSERT INTO orders
VALUES ($1, $2, $3, $4, $5)
By using the syntax INSERT INTO foo VALUES ($codec)
I got it working.
from skunk.
Summarizing
This works:
val codec: Codec[UserId ~ Order] =
(varchar ~ varchar ~ varchar ~ varchar ~ numeric).imap {
case o ~ u ~ p ~ i ~ t =>
ju.UUID.fromString(u).coerce[UserId] ~
Order(
ju.UUID.fromString(o).coerce[OrderId],
ju.UUID.fromString(p).coerce[PaymentId],
decode[Map[ItemId, Quantity]](i).getOrElse(Map.empty),
t.coerce[USD]
)
} {
case id ~ o =>
o.id.value.toString ~ id.value.toString ~ o.paymentId.value.toString ~ o.items.asJson.noSpaces ~ o.total.value
}
val insertOrder: Command[UserId ~ Order] =
sql"""
INSERT INTO orders
VALUES ($codec)
""".command
This doesn't:
val insertItem: Command[ItemId ~ CreateItem] =
sql"""
INSERT INTO items
VALUES ($varchar, $varchar, $varchar, $numeric, $varchar, $varchar)
""".command.contramap {
case id ~ i =>
id.value.toString ~ i.name.value ~ i.description.value ~ i.price.value ~ i.brandId.value.toString ~ i.categoryId.value.toString
}
from skunk.
Yeah, the bug is that it's all $1
. I'll have a look.
from skunk.
Thanks!
from skunk.
I think adding the following command to CommandTest should reveal the issue:
val insertCity: Command[City] =
sql"""
INSERT INTO city
VALUES ($int4, $varchar, $bpchar(3), $varchar, $int4)
""".command.contramap {
case c => c.id ~ c.name ~ c.code ~ c.district ~ c.pop
}
from skunk.
This fix is available in 0.0.4+25-afe55d7f-SNAPSHOT
which is being built right now.
from skunk.
Wow, that was quick, thanks! 🚀
from skunk.
Related Issues (20)
- Type inference for type argument in `to[A]` no longer working HOT 1
- Deadlock while using session pool HOT 1
- Unhandled backend message HOT 1
- NumberFormatException when parsing OID values exceeding 32-bit signed integer range HOT 7
- e HOT 1
- Feature request: logical replication HOT 2
- Support dynamic passwords HOT 1
- Should AppliedFragment Monoid use spaces?
- postgis types are a bit too generic
- Skunk sends all arguments to tracing/logging HOT 6
- Fragment's stripMargin can change the query
- Exceptions in transactions are printed to stderr HOT 3
- Skunk can't find `enum` type in schema HOT 3
- Support query pipelineing in a single session HOT 1
- Relax reliance on `SocketGroup` HOT 1
- Feature reqest: migrations. HOT 1
- Extending the sql interpolator?
- Session pool examples [Question]
- decode joined rows
- Fragment interpolation breaks with nested fragments HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from skunk.