expr

package
v0.0.0-...-852522b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2025 License: MPL-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package expr provides a transpiler that converts Common Expression Language (CEL) expressions to Amazon DynamoDB expressions.

The transpiler is implemented as a visitor that walks the CEL Abstract Syntax Tree (AST) and builds a DynamoDB expression for use in database operations. This package is designed to be used with the official AWS Go SDK v2 DynamoDB expression package to bridge the use of CEL and Protocol Buffers with DynamoDB.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Condition

func Condition(ast *cel.Ast) (expression.ConditionBuilder, error)

ConditionExpression converts a CEL AST into a DynamoDB condition expression.

Example

Demonstrates converting a CEL AST to a DynamoDB Condition expression.

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
	"github.com/google/cel-go/cel"

	celtypes "github.com/google/cel-go/common/types"
	"github.com/picatz/dynabuf/expr"
)

func main() {
	env, err := expr.NewEnv(
		cel.Variable("name", celtypes.StringType),
		cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
	)
	if err != nil {
		panic(err)
	}

	ast, issues := env.Compile(`name == "bob" && "urgent" in tags`)
	if issues != nil && issues.Err() != nil {
		panic(issues.Err())
	}

	cond, err := expr.Condition(ast)
	if err != nil {
		panic(err)
	}

	dynamoExpr, err := expression.NewBuilder().WithCondition(cond).Build()
	if err != nil {
		panic(err)
	}

	fmt.Println(*dynamoExpr.Condition())
	fmt.Println(dynamoExpr.Names())
	fmt.Println(len(dynamoExpr.Values()))
	fmt.Println(dynamoExpr.Values()[":0"])
	fmt.Println(dynamoExpr.Values()[":1"])
}
Output:
(#0 = :0) AND (:1 IN (#1))
map[#0:name #1:tags]
2
&{bob {}}
&{urgent {}}

func Filter

func Filter(ast *cel.Ast) (expression.ConditionBuilder, error)

Filter converts a CEL AST into a DynamoDB filter expression.

Example

Demonstrates converting a CEL AST into a DynamoDB filter expression.

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/google/cel-go/cel"

	celtypes "github.com/google/cel-go/common/types"
	"github.com/picatz/dynabuf/expr"
)

func main() {
	env, err := expr.NewEnv(
		cel.Variable("severity", celtypes.StringType),
		cel.Variable("status", celtypes.StringType),
		cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
	)
	if err != nil {
		panic(err)
	}

	ast, issues := env.Compile(`severity == "critical" && status == "open"`)
	if issues != nil && issues.Err() != nil {
		panic(issues.Err())
	}

	cond, err := expr.Filter(ast)
	if err != nil {
		panic(err)
	}

	condExpr, err := expression.NewBuilder().WithFilter(cond).Build()
	if err != nil {
		panic(err)
	}

	_ = dynamodb.QueryInput{
		TableName:                 aws.String("example-table"),
		FilterExpression:          condExpr.Filter(),
		ExpressionAttributeNames:  condExpr.Names(),
		ExpressionAttributeValues: condExpr.Values(),
	}

	fmt.Println(*condExpr.Filter())
	fmt.Println(condExpr.Names())
	fmt.Println(len(condExpr.Values()))
	fmt.Println(condExpr.Values()[":0"])
	fmt.Println(condExpr.Values()[":1"])
}
Output:
(#0 = :0) AND (#1 = :1)
map[#0:severity #1:status]
2
&{critical {}}
&{open {}}

func KeyCondition

func KeyCondition(ast *cel.Ast) (expression.KeyConditionBuilder, error)

KeyCondition converts a CEL AST into a DynamoDB key condition expression.

Example

Demonstrates converting a CEL AST into a DynamoDB key condition expression.

package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
	"github.com/google/cel-go/cel"

	celtypes "github.com/google/cel-go/common/types"
	"github.com/picatz/dynabuf/expr"
)

func main() {
	env, err := expr.NewEnv(
		cel.Variable("user", celtypes.StringType),  // partition key
		cel.Variable("order", celtypes.StringType), // sort key
	)
	if err != nil {
		panic(err)
	}

	ast, issues := env.Compile(`user == "User#123" && begins_with(order, "Order#")`)
	if issues != nil && issues.Err() != nil {
		panic(issues.Err())
	}

	keyCond, err := expr.KeyCondition(ast)
	if err != nil {
		panic(err)
	}

	keyCondExpr, err := expression.NewBuilder().WithKeyCondition(keyCond).Build()
	if err != nil {
		panic(err)
	}

	fmt.Println(*keyCondExpr.KeyCondition())
	fmt.Println(keyCondExpr.Names())
	fmt.Println(len(keyCondExpr.Values()))
	fmt.Println(keyCondExpr.Values()[":0"])
}
Output:
(#0 = :0) AND (begins_with (#1, :1))
map[#0:user #1:order]
2
&{User#123 {}}

func MessageFieldVariables

func MessageFieldVariables(msg proto.Message) []cel.EnvOption

MessageFieldVariables creates environment options for each field in a proto message. Fields are exposed as variables using their JSON names, because that's how they are stored in DynamoDB when coverted using protojson.

func MessageVariable

func MessageVariable(name string, msg proto.Message) []cel.EnvOption

MessageVariable creates an environment option for using a whole proto message as a variable.

func NewEnv

func NewEnv(opts ...cel.EnvOption) (*cel.Env, error)

NewEnv returns a new CEL environment configured for DynamoDB expressions.

func Projection

func Projection(ast *cel.Ast) (expression.ProjectionBuilder, error)

Projection converts a CEL AST into a DynamoDB projection expression.

Example
package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/google/cel-go/cel"

	celtypes "github.com/google/cel-go/common/types"
	"github.com/picatz/dynabuf/expr"
)

func main() {
	env, err := expr.NewEnv(
		cel.Variable("name", celtypes.StringType),
		cel.Variable("age", celtypes.IntType),
		cel.Variable("email", celtypes.StringType),
	)
	if err != nil {
		panic(err)
	}

	ast, issues := env.Compile(`["name", "age", "email"]`)
	if issues != nil && issues.Err() != nil {
		panic(issues.Err())
	}

	proj, err := expr.Projection(ast)
	if err != nil {
		panic(err)
	}

	projExpr, err := expression.NewBuilder().WithProjection(proj).Build()
	if err != nil {
		panic(err)
	}

	_ = dynamodb.QueryInput{
		TableName:                aws.String("example-table"),
		ProjectionExpression:     projExpr.Projection(),
		ExpressionAttributeNames: projExpr.Names(),
	}

	fmt.Println(*projExpr.Projection())
	fmt.Println(projExpr.Names())
}
Output:
#0, #1, #2
map[#0:name #1:age #2:email]

func Update

func Update(ast *cel.Ast) (expression.UpdateBuilder, error)

Update converts a CEL AST into a DynamoDB update expression.

Example
package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/google/cel-go/cel"

	celtypes "github.com/google/cel-go/common/types"
	"github.com/picatz/dynabuf/expr"
)

func main() {
	env, err := expr.NewEnv(
		cel.Variable("views", celtypes.IntType),
		cel.Variable("likes", celtypes.IntType),
		cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
	)
	if err != nil {
		panic(err)
	}

	ast, issues := env.Compile(`add("views", 1)`)
	if issues != nil && issues.Err() != nil {
		panic(issues.Err())
	}

	update, err := expr.Update(ast)
	if err != nil {
		panic(err)
	}

	updateExpr, err := expression.NewBuilder().WithUpdate(update).Build()
	if err != nil {
		panic(err)
	}

	_ = dynamodb.UpdateItemInput{
		TableName:                 aws.String("example-table"),
		UpdateExpression:          updateExpr.Update(),
		ExpressionAttributeNames:  updateExpr.Names(),
		ExpressionAttributeValues: updateExpr.Values(),
	}

	fmt.Println(*updateExpr.Update())
	fmt.Println(updateExpr.Names())
	fmt.Println(len(updateExpr.Values()))
	fmt.Println(updateExpr.Values()[":0"])
}
Output:
ADD #0 :0

map[#0:views]
1
&{1 {}}

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL