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

Add UDT support for prepared statements #61

Merged

Conversation

vponomaryov
Copy link
Contributor

@vponomaryov vponomaryov commented Feb 19, 2024

Update the latte's to_scylla_value function (which is used by the execute_prepared one) to support CQL UserDefinedTypes.

If we create UDT like following:

  let KEYSPACE = "fooks"
  let UDT_NAME = "fooudt"
  context.execute(`CREATE TYPE IF NOT EXISTS ${KEYSPACE}.${UDT_NAME} (
    id bigint, textk1 text, textk2 text)`).await?;

And then use it in some table.
Then, with this change, we can use the rune::runtime::Object object defined like following:

  let udtexample = #{
    "_keyspace": KEYSPACE, "_type_name": UDT_NAME,
    "id": fooid, "textk1": textv1, "textk2": textv2
  };

in an execute_prepared function.

Note that _keyspace and _type_name are special and required fields which are used to satisfy the Scylla Rust driver's CqlValue::UserDefinedType object structure:

  pub enum CqlValue {
    ...
    UserDefinedType {
        keyspace: String,
        type_name: String,
        /// Order of `fields` vector must match the order of fields as defined in the UDT. The
        /// driver does not check it by itself, so incorrect data will be written if the order is
        /// wrong.
        fields: Vec<(String, Option<CqlValue>)>,
    },
    ...

Also, note that for proper workability of various sub-types of the UDT
such as bigint for the example id field mentioned above need to use
Scylla-rust driver 0.11 or newer.

Closes: #57

Update the latte's 'to_scylla_value' function (which is used by
the 'execute_prepared' one) to support CQL UserDefinedTypes.

If we create UDT like following:

  let KEYSPACE = "fooks"
  let UDT_NAME = "fooudt"
  context.execute(`CREATE TYPE IF NOT EXISTS ${KEYSPACE}.${UDT_NAME} (
    id bigint, textk1 text, textk2 text)`).await?;

And then use it in some table.
Then, with this change, we can use the 'rune::runtime::Object' object
defined like following:

  let udtexample = #{
    "_keyspace": KEYSPACE, "_type_name": UDT_NAME,
    "id": fooid, "textk1": textv1, "textk2": textv2
  };

in an 'execute_prepared' function.

Note that '_keyspace' and '_type_name' are special and required fields
which are used to satisfy the Scylla Rust driver's
"CqlValue::UserDefinedType" object structure:

  pub enum CqlValue {
    ...
    UserDefinedType {
        keyspace: String,
        type_name: String,
        /// Order of `fields` vector must match the order of fields as defined in the UDT. The
        /// driver does not check it by itself, so incorrect data will be written if the order is
        /// wrong.
        fields: Vec<(String, Option<CqlValue>)>,
    },
    ...

Also, note that for proper workability of various sub-types of the UDT
such as `bigint` for the example `id` field mentioned above need to use
Scylla-rust driver '0.11' or newer.
@vponomaryov
Copy link
Contributor Author

vponomaryov commented Feb 19, 2024

Valueable to consider it with the scylla-rust-driver latest version:

@pkolaczk pkolaczk merged commit 0c37536 into pkolaczk:main Feb 25, 2024
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

Successfully merging this pull request may close these issues.

Support for user defined functions
2 participants