Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 87 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,97 @@
THIS_FILE := $(lastword $(MAKEFILE_LIST))

GO_CMD?=go
CGO_ENABLED?=0
# Go configuration
GO_CMD ?= go
CGO_ENABLED ?= 0

MAIN_PACKAGES=$$($(GO_CMD) list ./...)
# Main packages to test/build
MAIN_PACKAGES := $(shell $(GO_CMD) list ./...)

default: format test
all: generate format test
# Default target
default: help
all: generate format tidy test

generate:
@$(GO_CMD) generate ./...
# Build targets
build:
@echo "Building all packages..."
@$(GO_CMD) build ./...

# Dependency management
deps:
@echo "Downloading dependencies..."
@$(GO_CMD) mod download

tidy:
@echo "Tidying go modules..."
@$(GO_CMD) mod tidy

# Code quality
lint:
@echo "Running linter..."
@$(GO_CMD) vet ./...

format:
@echo "Formatting code..."
@find ./ -name '*.go' -print0 | xargs -P 12 -0 -I '{}' goimports -w '{}'

# Test targets
test:
@for pkg in $(MAIN_PACKAGES) ; do \
$(GO_CMD) test -cover $$pkg -parallel=20 ; \
done
@echo "Running tests..."
@$(GO_CMD) test -race -cover -count=1 -parallel=10 $(MAIN_PACKAGES)

test_neo4j:
@echo "Running Neo4j integration tests..."
@$(GO_CMD) test -tags neo4j_integration -race -cover -count=1 -parallel=1 $(MAIN_PACKAGES)

test_pg:
@echo "Running PostgreSQL integration tests..."
@$(GO_CMD) test -tags pg_integration -race -cover -count=1 -parallel=1 $(MAIN_PACKAGES)

test_update:
@echo "Updating test cases..."
@CYSQL_UPDATE_CASES=true $(GO_CMD) test -parallel=10 $(MAIN_PACKAGES)

@cp -fv cypher/analyzer/updated_cases/* cypher/test/cases
@rm -rf cypher/analyzer/updated_cases/
@cp -fv cypher/models/pgsql/test/updated_cases/* cypher/models/pgsql/test/translation_cases
@rm -rf cypher/models/pgsql/test/updated_cases

# Utility targets
generate:
@echo "Running code generation..."
@$(GO_CMD) generate ./...

clean:
@echo "Cleaning build artifacts..."
@$(GO_CMD) clean ./...

@rm -rf cypher/analyzer/updated_cases/
@rm -rf cypher/models/pgsql/test/updated_cases

help:
@echo "Available targets:"
@echo " default - Show this help message"
@echo " all - Runs all prep steps for prepare a changeset for review"
@echo ""
@echo "Build:"
@echo " build - Build all packages"
@echo ""
@echo "Dependencies:"
@echo " deps - Download dependencies"
@echo " tidy - Tidy go modules"
@echo ""
@echo "Code Quality:"
@echo " lint - Run go vet"
@echo " format - Format all Go files"
@echo " generate - Run code generation"
@echo ""
@echo "Testing:"
@echo " test - Run all unit tests with coverage"
@echo " test_bench - Run benchmark test"
@echo " test_neo4j - Run Neo4j integration tests"
@echo " test_pg - Run PostgreSQL integration tests"
@echo " test_update - Update test cases"
@echo ""
@echo "Utility:"
@echo " clean - Clean build artifacts"
@echo " help - Show this help message"
9 changes: 9 additions & 0 deletions cypher/models/pgsql/test/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ import (
"github.com/specterops/dawgs/cypher/models/pgsql"
"github.com/specterops/dawgs/cypher/models/pgsql/translate"
"github.com/specterops/dawgs/cypher/models/walk"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/query"
)

var (
// Node and edge kinds to keep queries consistent
NodeKind1 = graph.StringKind("NodeKind1")
NodeKind2 = graph.StringKind("NodeKind2")
EdgeKind1 = graph.StringKind("EdgeKind1")
EdgeKind2 = graph.StringKind("EdgeKind2")
)

func TestQuery_KindGeneratesInclusiveKindMatcher(t *testing.T) {
mapper := newKindMapper()

Expand Down
12 changes: 8 additions & 4 deletions cypher/models/pgsql/test/translation_cases/multipart.sql

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cypher/models/pgsql/test/translation_cases/nodes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,4 @@ with s0 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from

-- case: match (n:NodeKind1) optional match (m:NodeKind2) where m.distinguishedname = n.unknown + m.unknown optional match (o:NodeKind2) where o.distinguishedname <> n.otherunknown return n, m, o
with s0 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from node n0 where n0.kind_ids operator (pg_catalog.@>) array [1]::int2[]), s1 as (select s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, node n1 where ((n1.properties ->> 'distinguishedname') = ((s0.n0).properties -> 'unknown') + (n1.properties -> 'unknown')) and n1.kind_ids operator (pg_catalog.@>) array [2]::int2[]), s2 as (select s0.n0 as n0, s1.n1 as n1 from s0 left outer join s1 on (s0.n0 = s1.n0)), s3 as (select s2.n0 as n0, s2.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s2, node n2 where ((n2.properties -> 'distinguishedname') <> ((s2.n0).properties -> 'otherunknown')) and n2.kind_ids operator (pg_catalog.@>) array [2]::int2[]), s4 as (select s2.n0 as n0, s2.n1 as n1, s3.n2 as n2 from s2 left outer join s3 on (s2.n1 = s3.n1) and (s2.n0 = s3.n0)) select s4.n0 as n, s4.n1 as m, s4.n2 as o from s4;

Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::e
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on ((n0.properties ->> 'name') = 'value') and n0.id = e0.start_id join node n1 on n1.id = e0.end_id), s1 as (select s0.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.n0 as n0, s0.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0 join edge e1 on (s0.n1).id = e1.end_id join node n2 on (((n2.properties ->> 'is_target'))::bool) and n2.id = e1.start_id) select edges_to_path(variadic array [(s1.e0).id, (s1.e1).id]::int8[])::pathcomposite as p from s1;

-- case: match p = ()-[*..]->() return p limit 1
with s0 as (with recursive s1(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.start_id, e0.end_id, 1, false, e0.start_id = e0.end_id, array [e0.id] from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id union select s1.root_id, e0.end_id, s1.depth + 1, false, e0.id = any (s1.path), s1.path || e0.id from s1 join edge e0 on e0.start_id = s1.next_id join node n1 on n1.id = e0.end_id where s1.depth < 15 and not s1.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s1.path)) as e0, s1.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s1 join node n0 on n0.id = s1.root_id join node n1 on n1.id = s1.next_id) select edges_to_path(variadic ep0)::pathcomposite as p from s0 limit 1;
with s0 as (with recursive s1(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.start_id, e0.end_id, 1, false, e0.start_id = e0.end_id, array [e0.id] from edge e0 union select s1.root_id, e0.end_id, s1.depth + 1, false, e0.id = any (s1.path), s1.path || e0.id from s1 join edge e0 on e0.start_id = s1.next_id where s1.depth < 15 and not s1.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s1.path)) as e0, s1.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s1 join node n0 on n0.id = s1.root_id join node n1 on n1.id = s1.next_id) select edges_to_path(variadic ep0)::pathcomposite as p from s0 limit 1;

-- case: match p = (s)-[*..]->(i)-[]->() where id(s) = 1 and i.name = 'n3' return p limit 1
with s0 as (with recursive s1(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.start_id, e0.end_id, 1, ((n1.properties ->> 'name') = 'n3'), e0.start_id = e0.end_id, array [e0.id] from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where (n0.id = 1) union select s1.root_id, e0.end_id, s1.depth + 1, ((n1.properties ->> 'name') = 'n3'), e0.id = any (s1.path), s1.path || e0.id from s1 join edge e0 on e0.start_id = s1.next_id join node n1 on n1.id = e0.end_id where s1.depth < 15 and not s1.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s1.path)) as e0, s1.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s1 join node n0 on n0.id = s1.root_id join node n1 on n1.id = s1.next_id where s1.satisfied), s2 as (select s0.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.ep0 as ep0, s0.n0 as n0, s0.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0 join edge e1 on (s0.n1).id = e1.start_id join node n2 on n2.id = e1.end_id) select edges_to_path(variadic s2.ep0 || array [(s2.e1).id]::int8[])::pathcomposite as p from s2 limit 1;

-- case: match p = ()-[e:EdgeKind1]->()-[:EdgeKind1*..]->() return e, p
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[])), s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e1.start_id, e1.end_id, 1, false, e1.start_id = e1.end_id, array [e1.id] from s0 join edge e1 on (s0.n1).id = e1.start_id join node n2 on n2.id = e1.end_id where e1.kind_id = any (array [3]::int2[]) union select s2.root_id, e1.end_id, s2.depth + 1, false, e1.id = any (s2.path), s2.path || e1.id from s2 join edge e1 on e1.start_id = s2.next_id join node n2 on n2.id = e1.end_id where e1.kind_id = any (array [3]::int2[]) and s2.depth < 15 and not s2.is_cycle) select s0.e0 as e0, (select array_agg((e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite) from edge e1 where e1.id = any (s2.path)) as e1, s2.path as ep0, s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0, s2 join node n1 on n1.id = s2.root_id join node n2 on n2.id = s2.next_id where (s0.n1).id = s2.root_id) select s1.e0 as e, edges_to_path(variadic array [(s1.e0).id]::int8[] || s1.ep0)::pathcomposite as p from s1;
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[])), s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e1.start_id, e1.end_id, 1, false, e1.start_id = e1.end_id, array [e1.id] from s0 join edge e1 on (s0.n1).id = e1.start_id join node n2 on n2.id = e1.end_id where e1.kind_id = any (array [3]::int2[]) union select s2.root_id, e1.end_id, s2.depth + 1, false, e1.id = any (s2.path), s2.path || e1.id from s2 join edge e1 on e1.start_id = s2.next_id where e1.kind_id = any (array [3]::int2[]) and s2.depth < 15 and not s2.is_cycle) select s0.e0 as e0, (select array_agg((e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite) from edge e1 where e1.id = any (s2.path)) as e1, s2.path as ep0, s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0, s2 join node n1 on n1.id = s2.root_id join node n2 on n2.id = s2.next_id where (s0.n1).id = s2.root_id) select s1.e0 as e, edges_to_path(variadic array [(s1.e0).id]::int8[] || s1.ep0)::pathcomposite as p from s1;

-- case: match p = (m:NodeKind1)-[:EdgeKind1]->(c:NodeKind2) where m.objectid ends with "-513" and not toUpper(c.operatingsystem) contains "SERVER" return p limit 1000
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on ((n0.properties ->> 'objectid') like '%-513') and n0.kind_ids operator (pg_catalog.@>) array [1]::int2[] and n0.id = e0.start_id join node n1 on (not upper((n1.properties ->> 'operatingsystem'))::text like '%SERVER%') and n1.kind_ids operator (pg_catalog.@>) array [2]::int2[] and n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[])) select edges_to_path(variadic array [(s0.e0).id]::int8[])::pathcomposite as p from s0 limit 1000;
Expand Down Expand Up @@ -76,3 +76,4 @@ with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::e

-- case: match (m:NodeKind1)-[*1..]->(g:NodeKind2)-[]->(c3:NodeKind1) where not g.name in ["foo"] with collect(g.name) as bar match p=(m:NodeKind1)-[*1..]->(g:NodeKind2) where g.name in bar return p
with s0 as (with s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.start_id, e0.end_id, 1, (not (n1.properties ->> 'name') = any (array ['foo']::text[])) and n1.kind_ids operator (pg_catalog.@>) array [2]::int2[], e0.start_id = e0.end_id, array [e0.id] from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where n0.kind_ids operator (pg_catalog.@>) array [1]::int2[] union select s2.root_id, e0.end_id, s2.depth + 1, (not (n1.properties ->> 'name') = any (array ['foo']::text[])) and n1.kind_ids operator (pg_catalog.@>) array [2]::int2[], e0.id = any (s2.path), s2.path || e0.id from s2 join edge e0 on e0.start_id = s2.next_id join node n1 on n1.id = e0.end_id where s2.depth < 15 and not s2.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s2.path)) as e0, s2.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s2 join node n0 on n0.id = s2.root_id join node n1 on n1.id = s2.next_id where s2.satisfied), s3 as (select s1.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s1.ep0 as ep0, s1.n0 as n0, s1.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s1 join edge e1 on (s1.n1).id = e1.start_id join node n2 on n2.kind_ids operator (pg_catalog.@>) array [1]::int2[] and n2.id = e1.end_id) select array_remove(coalesce(array_agg(((s3.n1).properties ->> 'name'))::anyarray, array []::text[])::anyarray, null)::anyarray as i0 from s3), s4 as (with recursive s5(root_id, next_id, depth, satisfied, is_cycle, path) as (select e2.end_id, e2.start_id, 1, n3.kind_ids operator (pg_catalog.@>) array [1]::int2[], e2.end_id = e2.start_id, array [e2.id] from s0, edge e2 join node n4 on n4.id = e2.end_id join node n3 on n3.id = e2.start_id where n4.kind_ids operator (pg_catalog.@>) array [2]::int2[] and ((n4.properties ->> 'name') = any (s0.i0)) union select s5.root_id, e2.start_id, s5.depth + 1, n3.kind_ids operator (pg_catalog.@>) array [1]::int2[], e2.id = any (s5.path), s5.path || e2.id from s5 join edge e2 on e2.end_id = s5.next_id join node n3 on n3.id = e2.start_id where s5.depth < 15 and not s5.is_cycle) select (select array_agg((e2.id, e2.start_id, e2.end_id, e2.kind_id, e2.properties)::edgecomposite) from edge e2 where e2.id = any (s5.path)) as e2, s5.path as ep1, s0.i0 as i0, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3, (n4.id, n4.kind_ids, n4.properties)::nodecomposite as n4 from s0, s5 join node n4 on n4.id = s5.root_id join node n3 on n3.id = s5.next_id where s5.satisfied) select edges_to_path(variadic ep1)::pathcomposite as p from s4;

Loading
Loading