@@ -10,16 +10,17 @@ use serde_json::Value;
1010use crate :: OperationContext ;
1111use crate :: capacity_helpers;
1212use crate :: create_table:: storage_err_to_dynamo;
13- use crate :: expression_helpers:: build_expression_maps;
13+ use crate :: expression_helpers:: { build_expression_maps, parse_optional_condition } ;
1414use crate :: serialize_output;
1515use crate :: stream_capture;
1616use crate :: transact_write_helpers:: {
17- PreparedOp , compute_fingerprint, parse_optional_condition, validate_client_request_token,
18- validate_no_key_updates,
17+ PreparedOp , compute_fingerprint, validate_client_request_token, validate_no_key_updates,
1918} ;
2019use crate :: { DispatchMetrics , DispatchResult } ;
2120use extenddb_core:: error:: DynamoDbError ;
22- use extenddb_core:: expression:: parse_update;
21+ use extenddb_core:: expression:: {
22+ ExpressionKind , parse_update_from, tokenize_for, validate_no_reserved_words,
23+ } ;
2324use extenddb_core:: types:: { TransactWriteItem , TransactWriteItemsInput , TransactWriteItemsOutput } ;
2425use extenddb_core:: validation:: {
2526 validate_attribute_name_sizes, validate_attribute_values_nesting_depth,
@@ -218,7 +219,9 @@ async fn prepare_write_op(
218219 put. expression_attribute_values . as_ref ( ) ,
219220 ) ;
220221 let condition = parse_optional_condition ( put. condition_expression . as_deref ( ) , & ctx. limits ) ?;
221- {
222+ // Transactions accept names/values with no expression (unlike single-item
223+ // APIs); only check for unused refs when a condition is present.
224+ if condition. is_some ( ) {
222225 let exprs: Vec < & extenddb_core:: expression:: Expr > = condition. iter ( ) . collect ( ) ;
223226 extenddb_core:: expression:: validate_unused_attributes (
224227 & maps. names ,
@@ -256,7 +259,7 @@ async fn prepare_write_op(
256259 del. expression_attribute_values . as_ref ( ) ,
257260 ) ;
258261 let condition = parse_optional_condition ( del. condition_expression . as_deref ( ) , & ctx. limits ) ?;
259- {
262+ if condition . is_some ( ) {
260263 let exprs: Vec < & extenddb_core:: expression:: Expr > = condition. iter ( ) . collect ( ) ;
261264 extenddb_core:: expression:: validate_unused_attributes (
262265 & maps. names ,
@@ -293,9 +296,20 @@ async fn prepare_write_op(
293296 upd. expression_attribute_names . as_ref ( ) ,
294297 upd. expression_attribute_values . as_ref ( ) ,
295298 ) ;
296- let update_tokens =
297- crate :: expression_helpers:: tokenize_expression ( & upd. update_expression , & ctx. limits ) ?;
298- let actions = parse_update ( & update_tokens) ?;
299+ let actions = tokenize_for (
300+ & upd. update_expression ,
301+ ctx. limits . max_expression_tokens ,
302+ ExpressionKind :: Update ,
303+ )
304+ . and_then ( |update_tokens| {
305+ if ctx. limits . enforce_reserved_keywords {
306+ validate_no_reserved_words ( & update_tokens) ?;
307+ }
308+ parse_update_from ( & update_tokens, & upd. update_expression )
309+ } )
310+ . map_err ( |e| {
311+ crate :: expression_helpers:: prefix_expression_error ( e, ExpressionKind :: Update )
312+ } ) ?;
299313 validate_no_key_updates ( & actions, & key_info, & maps) ?;
300314
301315 // Validate nesting depth of EAV values that get stored via SET actions.
@@ -351,12 +365,17 @@ async fn prepare_write_op(
351365 cc. expression_attribute_names . as_ref ( ) ,
352366 cc. expression_attribute_values . as_ref ( ) ,
353367 ) ;
354- let tokens =
355- crate :: expression_helpers:: tokenize_expression ( & cc. condition_expression , & ctx. limits ) ?;
356- let condition = extenddb_core:: expression:: parse_condition_with_depth_limit (
357- & tokens,
358- ctx. limits . max_expression_depth ,
359- ) ?;
368+ let condition =
369+ crate :: expression_helpers:: tokenize_expression ( & cc. condition_expression , & ctx. limits )
370+ . and_then ( |tokens| {
371+ extenddb_core:: expression:: parse_condition_with_depth_limit (
372+ & tokens,
373+ ctx. limits . max_expression_depth ,
374+ )
375+ } )
376+ . map_err ( |e| {
377+ crate :: expression_helpers:: prefix_expression_error ( e, ExpressionKind :: Condition )
378+ } ) ?;
360379 {
361380 let exprs: Vec < & extenddb_core:: expression:: Expr > = vec ! [ & condition] ;
362381 extenddb_core:: expression:: validate_unused_attributes (
0 commit comments