Why SQL in Vadalog?

Prometheux supports native SQL queries embedded directly within Vadalog rules. This powerful feature allows you to:
  • Leverage existing SQL skills – write familiar SQL SELECT statements alongside Vadalog rules
  • Use SQL’s expressive power – complex JOINs, aggregations, window functions, and CTEs
  • Query across data sources – seamlessly combine PostgreSQL, MariaDB, Neo4j, COBOL mainframe files, CSV, and in-memory facts in a single SQL query
  • Scale to large datasets – benefit from distributed query execution for large-scale data processing
  • Simplify data transformation – use SQL for data manipulation while keeping Vadalog for logical reasoning
Prometheux automatically parallelizes and optimizes SQL queries across distributed compute resources while maintaining the declarative semantics of your program.

Two Ways to Use SQL

1. SQL in Rule Bodies

When a rule body starts with a SELECT or WITH keyword, it is interpreted as a SQL query:
Syntax:
  • The SQL query starts with SELECT (or WITH for CTEs) and ends with . (the rule terminator)
  • No arguments needed in the head – the output schema is defined by the SELECT clause
Simple Example:
Output:
CSV Example:

2. SQL in Functions (Advanced)

You can pass SQL queries as string arguments to graph analytics functions. This is useful when you want to filter or transform data before applying graph algorithms. Syntax:
  • Wrap the SQL query in double quotes: "SELECT ..."
  • The SQL query replaces the predicate atom normally passed to the function
  • Head arguments ARE required – they receive the function’s output
  • All function options still work (e.g., "visited=true", "max_depth=5")
Example:
Head Arguments
  • SQL in rule bodies: Head arguments are optional (empty parentheses () work)
  • SQL in functions: Head arguments are required (e.g., (X, Y)) to capture function output
The difference is that functions like #TC compute results (transitive closure) and assign them to variables, while SQL bodies directly define the output.

Column Naming Conventions

Vadalog uses specific column naming conventions depending on the data source and query type.
Column Naming Rules When all tables in a SQL query are from the same database, you can use actual column names. For queries across different data sources, use predicateName_columnIndex notation.

For In-Memory Facts

Facts use the pattern predicateName_columnIndex (zero-based):

For CSV/Parquet with Headers

Single-table queries can use actual column names:
Multi-table queries across different sources must use predicateName_columnIndex:

For Database Tables (PostgreSQL, MariaDB, etc.)

Single-table queries can use actual database column names:
Multi-table queries from the same database can use actual column names:
Multi-table queries across different databases must use predicateName_columnIndex:
Column Naming Rules
  • Single table → Use actual column names (CSV headers or DB column names)
  • Multiple tables from same database → Use actual column names
  • Multiple tables from different sources → Use predicateName_columnIndex notation

Case-Sensitive Identifiers

Some databases (e.g., PostgreSQL, Oracle) are case-sensitive and require quoted identifiers for mixed-case column or table names. Vadalog supports universal backtick notation that automatically converts to database-specific quotes.

Using Backticks for Case-Sensitive Identifiers

Database-Specific Conversion

Vadalog automatically converts backticks to the appropriate quote character for each database:
Universal Backtick Notation Always use backticks (`) for case-sensitive identifiers in your Vadalog code. The system will automatically convert them to the correct syntax for your target database. This ensures your code is portable across different database systems.

Example: Case-Sensitive JOIN


Examples

Example 1: Basic SQL Body with Facts

Output:

Example 2: SQL Body with CSV Files

Example 3: Same-Database JOIN

Example 4: Cross-Source JOIN with CSVs

Example 5: Mixing Facts and CSV

Example 6: SQL Aggregation with Same-Database Tables

Example 7: SQL with UNION

Example 8: Cross-Database Queries (PostgreSQL + MariaDB)

Example 9: Hybrid Queries (PostgreSQL + CSV + Facts)

Example 10: SQL over Neo4j (Graph Database)

SQL queries work seamlessly with Neo4j graph data. Prometheux automatically translates the SQL into optimized Cypher and pushes it down to the Neo4j server — no data is loaded into memory.
SQL also works on Neo4j relationship patterns:
Neo4j Pushdown SELECT * with LIMIT/OFFSET is translated to Cypher WITH ... SKIP n LIMIT n RETURN ... and executed server-side. Aggregations like COUNT(*) become Cypher count() queries. No data is loaded into memory for filtering or pagination.

SQL in Graph Functions

All graph analytics functions (#TC, #ASP, #PATHS, #CC, etc.) can accept SQL queries instead of predicate atoms.

Example 11: Transitive Closure with SQL

Result:
All reachable pairs including transitive paths (1→2, 2→3, 3→4, 1→3, 2→4, 1→4)

Example 12: All-Shortest Paths with SQL

Example 13: PATHS Function with SQL and Options

Example 14: Connected Components with SQL

Example 15: SQL Function with Filtering and JOIN

Example 16: SQL Function from CSV


Advanced Features

Mixing SQL Rules and Vadalog Rules

You can freely mix SQL-based rules with traditional Vadalog rules:

SQL with Subqueries

SQL with Window Functions

Common Table Expressions (CTEs)


Best Practices

1. Choose the Right Approach

Use SQL bodies when:
  • You need complex data transformations
  • You’re working with aggregations, window functions, or CTEs
  • You’re joining data from multiple sources
  • The logic is naturally expressed in SQL
Use traditional Vadalog when:
  • You need recursion or fixpoint computation
  • The logic involves complex logical rules
  • You’re doing rule-based reasoning or inference

2. Use Appropriate Column Naming

When querying tables from the same database, use actual column names for cleaner, more readable queries:

3. Column Naming Clarity

Always use aliases to make your output schema clear:

4. Use Backticks for Case-Sensitive Identifiers

For databases with case-sensitive columns, use backticks for portability:

6. Leverage Data Source Bindings

Use @bind annotations to connect to diverse data sources, then query them uniformly with SQL:

7. Filter Data in SQL Queries

You can filter data directly within SQL queries passed to graph functions:

8. Validate Table References

Ensure all tables in your SQL queries are either:
  • Bound via @bind annotations
  • Defined as facts in the program
  • Derived from other rules

Troubleshooting

Error: “Table not defined”

Cause: SQL query references a table that has no @bind annotation, no facts, and no deriving rules. Solution: Add a @bind annotation or define the predicate as facts:

Error: “Column not found”

Cause: Using wrong column naming convention (e.g., actual column names in multi-table query). Solution: Use predicateName_columnIndex for multi-table queries:

Error: “Invalid SQL syntax”

Cause: SQL query contains syntax errors. Solution: Validate your SQL query using standard SQL syntax. Vadalog supports most ANSI SQL features including window functions, CTEs, and complex aggregations.

Summary

SQL integration in Vadalog provides a powerful bridge between declarative logic programming and industrial-strength SQL: Embed SQL SELECT statements directly in rule bodies
Pass SQL queries to graph analytics functions
Query across data sources – PostgreSQL, MariaDB, Neo4j, CSV, facts, and more
Use full SQL expressiveness – JOINs, aggregations, CTEs, window functions
Flexible column naming – use actual column names for same-database queries, or predicateName_i for cross-source queries
Universal backtick notation – write portable queries with automatic quote conversion
Automatic parallelization and optimization across distributed compute resources
Seamless integration with Vadalog rules and reasoning
This hybrid approach combines the strengths of both paradigms: use SQL when you need its familiar syntax and expressive power, and use Vadalog for recursion, reasoning, and complex logical rules.