### Install extensions and attach DuckLake catalog Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Sets up the DuckDB session for the walkthrough: installs and loads the ducklake and duckgql extensions, attaches the SNB relational database as read-only, and attaches a new DuckLake catalog with a data path. The catalog metadata is stored in snb10.ducklake and table data under snb10-data. ```sql INSTALL ducklake; LOAD ducklake; INSTALL duckgql FROM community; LOAD duckgql; ATTACH 'snb10-relational.duckdb' AS raw (READ_ONLY); ATTACH 'ducklake:snb10.ducklake' AS lake ( DATA_PATH 'snb10-data' ); ``` -------------------------------- ### Attach DuckLake with SQL Source: https://duckgql.com/docs/guides/ducklake.html SQL setup to install and load DuckLake and DuckGQL, then attach the lake under the alias 'lake'. The alias is part of the persistent graph mapping and must be reused after reopening the database. ```sql INSTALL ducklake; LOAD ducklake; LOAD duckgql; ATTACH 'ducklake:lakehouse.ducklake' AS lake; ``` -------------------------------- ### Query clauses example Source: https://duckgql.com/docs/reference/gql.html Example of a directed MATCH query with WHERE, RETURN DISTINCT, ORDER BY, and LIMIT clauses. ```sql MATCH (a:Person)-[e:KNOWS]->(b:Person) WHERE a.active = true RETURN DISTINCT a.name, b.name, e.since ORDER BY e.since DESC LIMIT 20; ``` -------------------------------- ### Source key qualification example Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Shows how DuckGQL qualifies source keys by their physical node mapping, so identical numeric values in different entity types do not collide. ```text lake.main.person_nodes (person_key = 42) -> (Person, 42) lake.main.message_nodes (message_key = 42) -> (Message, 42) ``` -------------------------------- ### DuckGQL startup error: WebGL2 not supported Source: https://duckgql.com/docs Error output shown when DuckGQL cannot start because WebGL2 is not supported. The stack trace points to the DuckDB WebAssembly shell and addon loading. ```text Error: WebGL2 not supported null at new I (https://duckgql.com/assets/index-D2z3FjYS.js:69:8673) at g.activate (https://duckgql.com/assets/index-D2z3FjYS.js:69:88601) at r.AddonManager.loadAddon (https://duckgql.com/assets/index-D2z3FjYS.js:11:31251) at p.loadAddon (https://duckgql.com/assets/index-D2z3FjYS.js:12:208) at Ld.i.wbg.__wbg_loadAddon_143d540bb5725490 (https://duckgql.com/assets/index-D2z3FjYS.js:70:5877) at duckdb_wasm_shell.wasm.__wbg_loadAddon_143d540bb5725490 externref shim (https://duckgql.com/assets/shell_bg--yOGsJmn.wasm:wasm-function[2296]:0x1017bc) at duckdb_wasm_shell.wasm.duckdb_wasm_shell[51fc3e94c22557a7]::shell_api::embed (https://duckgql.com/assets/shell_bg--yOGsJmn.wasm:wasm-function[544]:0xb29a4) at duckdb_wasm_shell.wasm.embed (https://duckgql.com/assets/shell_bg--yOGsJmn.wasm:wasm-function[1732]:0xfc4d7) at duckdb_wasm_shell.wasm.embed externref shim (https://duckgql.com/assets/shell_bg--yOGsJmn.wasm:wasm-function[1898]:0xfeb72) at duckdb_wasm_shell.wasm.embed externref shim multivalue shim (https://duckgql.com/assets/shell_bg--yOGsJmn.wasm:wasm-function[1889]:0xfe9ff) ``` -------------------------------- ### Create graph air_routes with DROP GRAPH and CREATE GRAPH Source: https://duckgql.com/docs Step 1 of the guided demo: creates a graph named air_routes, dropping any existing graph with the same name first. The ANY keyword allows any node/edge types. ```sql DROP GRAPH IF EXISTS air_routes; CREATE GRAPH air_routes ANY; ``` -------------------------------- ### MATCH query using property index Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Example query where the property index is used for point-like access on person.id. ```sql MATCH (person:Person) WHERE person.id = 123 RETURN person.name; ``` -------------------------------- ### CALL algo.degree Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Demonstrates the projection controls shared by most algorithms, using algo.degree as an example. ```APIDOC ## CALL algo.degree ### Description Computes the degree of vertices in a projected graph, with optional vertex and edge label filters. ### Method CALL ### Endpoint CALL algo.degree(graph, vertex_label, edge_label) ### Parameters #### Parameters - **graph** (string) - Required - Graph name. - **vertex_label** (string) - Optional - Induced vertex projection; only vertices with this label are returned. - **edge_label** (string) - Optional - Retains only edges with this label; case-insensitive. ### Request Example ```sql CALL algo.degree( 'social', vertex_label := 'Person', edge_label := 'FOLLOWS' ); ``` ### Response #### Success Response Returns rows for each vertex in the projection with its degree. #### Response Example No explicit response example provided. ``` -------------------------------- ### Run algo.bfs with direction, max_depth, and target_vertex_id Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Runs breadth-first search from a single source. The frontier is the start element ID (42) or IDs from a preceding MATCH. The direction defaults to 'out', max_depth is unlimited by default, and target_vertex_id stops after the target is emitted. Output columns include vertex_id, depth, parent_vertex_id, edge_id, and visit_order. ```sql CALL algo.bfs( 'social', 42, direction := 'out', max_depth := 4, edge_label := 'FOLLOWS', vertex_label := 'Person', target_vertex_id := 9001 ); ``` -------------------------------- ### Build CSR snapshot with gql_build_csr Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Use this call to prepare the full optimizer and inspection snapshot explicitly when a workload should have CSR capabilities from its first query. Ordinary MATCH does not require CSR; without a current suitable snapshot it uses relational scans, joins, and recursive expansion. Graph algorithms build their own minimal compatible CSR automatically and no longer require an explicit gql_build_csr setup call. ```sql CALL gql_build_csr('social'); ``` -------------------------------- ### Graph-header vertex CSV example Source: https://duckgql.com/docs/guides/graph-lifecycle.html Vertex input requires one :ID field and may contain one :LABEL field plus properties. The example shows a CSV with a named ID group, properties, and a semicolon-delimited label set. ```csv personId:ID(People),name:string,age:int,tags:string[],:LABEL p1,Ada,42,engineer;mathematician,Person;Researcher p2,Grace,37,compiler,Person ``` -------------------------------- ### MATCH query with selective predicate Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Example query showing a selective predicate on person.id and explicit relationship type KNOWS, which helps the planner use indexed access. ```sql MATCH (person:Person)-[:KNOWS]->(friend:Person) WHERE person.id = 123 RETURN friend.name; ``` -------------------------------- ### Get per-edge-label statistics with gql_csr_edge_stats Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Returns per-edge-label statistics after a full snapshot has prepared them. Rows include edge count, active source and destination counts, average directional degree, and maximum directional degree. The optimizer can use them to compare selective CSR expansion with a bulk edge-table scan. ```sql SELECT * FROM gql_csr_edge_stats('social') ORDER BY edge_label; ``` -------------------------------- ### Run algo.bfs with element_id from MATCH Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Runs BFS from a starting vertex obtained from a MATCH clause. The element_id() function converts the matched vertex to its graph element ID, which is required because algorithm inputs use element IDs, not business keys. ```sql MATCH (seed:Person) FILTER seed.name = 'Ada' CALL algo.bfs('social', element_id(seed)) YIELD vertex_id, depth RETURN vertex_id, depth ORDER BY depth, vertex_id; ``` -------------------------------- ### Build DuckGQL from source Source: https://duckgql.com/docs/getting-started.html Clone the DuckGQL repository with submodules, set up vcpkg, build the release binary, and run the DuckDB shell with DuckGQL preloaded. Requires DuckDB v1.5.5, C++17, and ANTLR 4.13.2. ```sh git clone --recurse-submodules https://github.com/rahul-iyer/duckdb-gql.git cd duckdb-gql make setup-vcpkg VCPKG_TOOLCHAIN_PATH="$PWD/vcpkg/scripts/buildsystems/vcpkg.cmake" make release ./build/release/duckdb ``` -------------------------------- ### Explain execution with EXPLAIN, EXPLAIN ANALYZE, and EXPLAIN (FORMAT JSON) Source: https://duckgql.com/docs/guides/querying.html Shows standard, analyzed, and JSON execution plans for read-only MATCH queries. The plan appears after GQL lowering and includes authoritative graph tables, DuckDB scans and joins, and optionally property-index scans, CSR expansion, or batched element fetches. EXPLAIN ANALYZE executes the query and adds runtime measurements; do not use it for statements whose effects you are not prepared to execute. ```sql EXPLAIN MATCH (person:Person) WHERE person.age >= 35 RETURN person.name; EXPLAIN ANALYZE MATCH (person:Person) RETURN person.name; EXPLAIN (FORMAT JSON) MATCH (person:Person) RETURN person.name; ``` -------------------------------- ### Correlate with DuckDB catalog Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Query duckdb_indexes() to find physical indexes with names starting with 'gql_property_index_' for diagnostics. ```sql SELECT database_name, schema_name, table_name, index_name, sql FROM duckdb_indexes() WHERE starts_with(index_name, 'gql_property_index_'); ``` -------------------------------- ### Read physical plan with EXPLAIN Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Displays the chosen plan for a match query without executing. Look for index scans for property lookups, gql_csr_vertices for label postings, gql_csr_expand for fixed hops, gql_csr_path_expand for quantified expansion, and gql_vertex_fetch or gql_edge_fetch for small row batches. ```sql EXPLAIN MATCH (source:Person)-[:KNOWS]->(target:Person) WHERE source.id = 123 RETURN target.name; ``` -------------------------------- ### DROP GRAPH example Source: https://duckgql.com/docs/guides/graph-lifecycle.html Drops the managed graph 'social_typed'. This removes graph metadata, owned tables, sequences, and related registrations. ```sql DROP GRAPH social_typed; ``` -------------------------------- ### Create, load, and query a graph Source: https://duckgql.com/docs/getting-started.html Create a graph named social, load it from the CSV files, set it as the session graph, and run a MATCH query returning people connected by KNOWS edges with since >= 2020. ```sql CREATE GRAPH social ANY; COPY GRAPH social FROM ( VERTICES 'nodes.csv', EDGES 'relationships.csv' ) FORMAT GRAPH; SESSION SET GRAPH social; MATCH (a:Person)-[e:KNOWS]->(b:Person) WHERE e.since >= 2020 RETURN a.name AS source_name, e.since AS since, b.name AS target_name; ``` -------------------------------- ### Import graph-header files with COPY GRAPH Source: https://duckgql.com/docs/guides/graph-lifecycle.html Loads one vertex file and one edge file into an empty graph. Supported inputs are .csv, .csv.gz, .csv.zst, and .parquet. The target graph must still be empty; this is a full-load operation, not append or upsert. ```sql COPY GRAPH social FROM ( VERTICES 'nodes.parquet', EDGES 'relationships.parquet' ) FORMAT GRAPH; ``` -------------------------------- ### Caller-controlled transaction with ROLLBACK Source: https://duckgql.com/docs/guides/graph-lifecycle.html Shows a caller-controlled transaction: BEGIN starts it, INSERT adds a node, MATCH/RETURN reads it, and ROLLBACK undoes the insert. After rollback, the inserted node is absent. ```sql BEGIN; INSERT (temporary:Person {id: 999, name: 'Temporary'}); MATCH (person:Person) WHERE person.id = 999 RETURN person.name; ROLLBACK; ``` -------------------------------- ### Zero-copy pipeline overview Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Shows the high-level pipeline from SNB relational tables to DuckLake projection, DuckGQL mapping, and graph queries. The arrow notation emphasizes that only the first step is a data movement; the mapping is metadata-only. ```text SNB relational tables -> one-time projection into DuckLake -> typed DuckGQL mapping (metadata only) -> MATCH and graph algorithms ``` -------------------------------- ### DROP GRAPH IF EXISTS example Source: https://duckgql.com/docs/guides/graph-lifecycle.html Drops the graph if it exists. For a referenced DuckLake graph, this only removes DuckGQL's mapping and derived state, leaving source tables and data untouched. ```sql DROP GRAPH IF EXISTS social_typed; ``` -------------------------------- ### Create an import target with CREATE GRAPH ... ANY Source: https://duckgql.com/docs/guides/graph-lifecycle.html Creates an empty catalog entry for a managed graph. The managed vertex and edge tables are not created until COPY GRAPH succeeds. Creation fails if the name already exists. ```sql CREATE GRAPH social ANY; ``` -------------------------------- ### Rejected: CSR algorithm inside explicit transaction Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Shows that CSR construction and CSR algorithms are rejected inside an explicit transaction. This example is not currently supported and will fail; use autocommit mode instead. ```sql -- Not currently supported: BEGIN; CALL algo.pagerank('social'); COMMIT; ``` -------------------------------- ### Procedures for graph metadata and indexes Source: https://duckgql.com/docs/reference/gql.html Procedures to list graphs and property indexes, and to create or drop a property index. ```sql SELECT * FROM gql_graphs(); SELECT * FROM gql_property_indexes(); CALL gql_create_property_index('social', 'id'); CALL gql_drop_property_index('social', 'id'); ``` -------------------------------- ### Managed graph storage tables layout Source: https://duckgql.com/docs/guides/graph-lifecycle.html Managed graphs use graph-owned wide tables with names like gql_data.graph__vertices and gql_data.graph__edges. The example shows the naming pattern; actual IDs are placeholders. ```text gql_data.graph__vertices gql_data.graph__edges gql_internal.* ``` -------------------------------- ### Unbounded path with * Source: https://duckgql.com/docs/guides/querying.html The * quantifier includes a zero-hop result, so the source can also bind as the target. ```sql MATCH (source:Person)-[:KNOWS]->*(target:Person) WHERE source.id = 123 RETURN element_id(target), target.name; ``` -------------------------------- ### Run algo.sssp with edge_label and ORDER BY Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Computes minimum hop counts from exactly one source using a breadth-first traversal. The controls are direction, max_depth, edge_label, vertex_label, and target_vertex_id, with the same defaults as BFS. Unreachable vertices do not appear, and edge properties are not interpreted as weights, so this is not Dijkstra's algorithm. ```sql CALL algo.sssp( 'social', 42, direction := 'out', edge_label := 'FOLLOWS' ) YIELD vertex_id, distance, parent_vertex_id RETURN vertex_id, distance, parent_vertex_id ORDER BY distance, vertex_id; ``` -------------------------------- ### Read physical plan with EXPLAIN ANALYZE Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Executes the query and reports observed operator timing and cardinality. Compare cold and warm runs separately; the first CSR-consuming operation may include construction while later ones can reuse compatible state. ```sql EXPLAIN ANALYZE MATCH (source:Person)-[:KNOWS]->(target:Person) WHERE source.id = 123 RETURN target.name; ``` -------------------------------- ### Run first graph query with MATCH and RETURN Source: https://duckgql.com/docs First graph query in the DuckGQL playground. Finds routes from Atlanta (ATL) and returns origin, destination, and distance, limited to 10 rows. ```cypher MATCH (a:airport)-[r:route]->(b:airport) WHERE a.code = 'ATL' RETURN a.code AS origin, b.code AS destination, r.dist AS miles LIMIT 10; ``` -------------------------------- ### Set LIVE snapshot policy with OPTIONS Source: https://duckgql.com/docs/guides/ducklake.html Use this OPTIONS block to configure a DuckGQL graph for LIVE snapshot policy, which follows the latest committed snapshot of the attached DuckLake catalog. Requires ACCESS_MODE 'READ_ONLY' and VALIDATE TRUE. Newly committed rows appear without recreating the graph mapping, but two statements can see different snapshots if a writer commits between them. ```sql OPTIONS ( SNAPSHOT_POLICY 'LIVE', ACCESS_MODE 'READ_ONLY', VALIDATE TRUE ) ``` -------------------------------- ### Set session graph and query mapped graph Source: https://duckgql.com/docs/guides/ducklake.html Sets the session graph to 'commerce' and runs a MATCH query with a WHERE clause, RETURN, and ORDER BY. This demonstrates the query surface for referenced graphs, which supports variable-length patterns, optional matching, aggregation, sorting, and paging. ```sql SESSION SET GRAPH commerce; MATCH (customer:Customer)-[purchase:BOUGHT]->(product:Product) WHERE purchase.quantity >= 2 RETURN customer.name, product.name, product.price, purchase.quantity ORDER BY product.price DESC; ``` -------------------------------- ### Build and inspect CSR with gql_build_csr Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Explicitly builds a full CSR for adjacency inspection or predictable cold-start timing. The first statement builds the CSR; the second queries its statistics. This is optional because algorithms build compatible projections on demand. ```sql CALL gql_build_csr('snb10'); SELECT source_catalog, source_snapshot_id, vertex_count, edge_count FROM gql_csr_stats('snb10'); ``` -------------------------------- ### Find shortest path length with algo.shortest_path_length Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Use this procedure when only one source-to-target hop count is needed. It runs target-aware outgoing BFS and returns one row. The optional fourth and fifth arguments are vertex_label and edge_label. The procedure follows outgoing edges; it has no direction option. Distance is the number of edges, 0 when source equals target, and -1 when the target is unreachable. The matched input must identify exactly one distinct source and one distinct target. ```sql MATCH (source:Person), (target:Person) FILTER source.name = 'Ada' AND target.name = 'Grace' CALL algo.shortest_path_length( 'social', element_id(source), element_id(target), 'Person', 'FOLLOWS' ) YIELD distance RETURN distance; ``` -------------------------------- ### CSR expansion plan steps Source: https://duckgql.com/docs/guides/indexes-and-optimization.html This text block outlines the plan steps for a full CSR expansion: ART equality lookup, source element ID, CSR KNOWS expansion, batched target row fetch, and property projection. It illustrates the execution path for selective expansion. ```text ART equality lookup -> source element ID -> CSR KNOWS expansion -> batched target row fetch -> property projection ``` -------------------------------- ### Run weakly connected components (algo.wcc) Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Finds weakly connected components in the 'social' graph using the FOLLOWS edge label. component_id is stable and deterministic, being the smallest stored element ID in the component; isolated vertices form components of size 1. Parallel edges and self-loops do not change membership, and the algorithm is near-linear in V + E. ```sql CALL algo.wcc('social', edge_label := 'FOLLOWS') YIELD vertex_id, component_id, component_size RETURN vertex_id, component_id, component_size ORDER BY component_size DESC, component_id, vertex_id; ``` -------------------------------- ### Quantified path with {1,3} Source: https://duckgql.com/docs/guides/querying.html Quantifier {1,3} matches one through three repetitions; different path lengths are combined before DISTINCT, ordering, offset, and limit. ```sql MATCH (source:Person)-[:KNOWS]->{1,3}(target:Person) WHERE source.id = 123 RETURN DISTINCT target.name ORDER BY target.name; ``` -------------------------------- ### Fixed-length path with explicit hops Source: https://duckgql.com/docs/guides/querying.html Write each hop explicitly when intermediate variables or properties are needed in a fixed-length path. ```sql MATCH (source:Person)-[first:KNOWS]->(middle:Person) -[second:KNOWS]->(target:Person) WHERE source.id = 123 RETURN middle.name, target.name, first.since, second.since; ``` -------------------------------- ### Pagination with ORDER BY and LIMIT Source: https://duckgql.com/docs/guides/querying.html With DISTINCT or an algorithm CALL, every ordering expression must appear in the returned shape; add a deterministic tie-breaker when paginating. ```sql MATCH (person:Person) RETURN person.name, element_id(person) AS person_id ORDER BY person.name, person_id OFFSET 20 LIMIT 10; ``` -------------------------------- ### Set PINNED snapshot policy with OPTIONS Source: https://duckgql.com/docs/guides/ducklake.html Use this OPTIONS block to configure a DuckGQL graph for PINNED snapshot policy, which reproduces results against the snapshot attached in the preceding ATTACH statement. DuckGQL records snapshot 42 in graph metadata and fails if the lake is attached at a different snapshot. ```sql OPTIONS ( SNAPSHOT_POLICY 'PINNED', ACCESS_MODE 'READ_ONLY', VALIDATE TRUE ) ``` -------------------------------- ### Inspect graphs with gql_graphs() Source: https://duckgql.com/docs/getting-started.html Query the gql_graphs() function to inspect the graphs available in the current session. ```sql SELECT * FROM gql_graphs(); ``` -------------------------------- ### Graph lifecycle operations Source: https://duckgql.com/docs/reference/gql.html Commands to create, copy, set, and drop a graph. The COPY command loads vertices and edges from CSV files. ```sql CREATE GRAPH graph_name ANY; COPY GRAPH graph_name FROM ( VERTICES 'nodes.csv', EDGES 'relationships.csv' ) FORMAT GRAPH; SESSION SET GRAPH graph_name; DROP GRAPH graph_name; ``` -------------------------------- ### Run PageRank and inspect execution metrics Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Runs PageRank and then queries the latest run's metrics for the current connection. csr_built = false means that run reused a compatible snapshot. Algorithm metrics are currently instrumented for PageRank; an unknown or not-yet-run algorithm produces no metrics row. ```sql CALL algo.pagerank('social'); SELECT csr_built, csr_seconds, initialization_seconds, iteration_seconds, output_seconds, total_seconds, worker_count, vertex_count, edge_count, iterations, converged FROM gql_algorithm_stats('social', 'pagerank'); ``` -------------------------------- ### Create an import target idempotently with IF NOT EXISTS Source: https://duckgql.com/docs/guides/graph-lifecycle.html Use IF NOT EXISTS to avoid failure when the graph already exists. It keeps the existing graph and does not compare or replace its schema. ```sql CREATE GRAPH IF NOT EXISTS social ANY; ``` -------------------------------- ### Call algo.pagerank with YIELD and RETURN Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Runs PageRank on the 'social' graph and uses the GQL YIELD/RETURN pipeline to select, order, and limit results. The YIELD clause exposes the output columns vertex_id and rank. ```sql CALL algo.pagerank('social') YIELD vertex_id, rank RETURN vertex_id, rank ORDER BY rank DESC LIMIT 10; ``` -------------------------------- ### MATCH query with typed pattern Source: https://duckgql.com/docs/guides/ducklake.html Query the graph using a typed MATCH pattern to select a specific branch. Requires a graph session and returns customer, product, and purchase quantity. ```sql SESSION SET GRAPH commerce; MATCH (customer:Customer)-[purchase:BOUGHT]->(product:Product) RETURN customer.name, product.name, purchase.quantity; ``` -------------------------------- ### Map several vertex and edge tables with repeated VERTEX TABLE and EDGE TABLE Source: https://duckgql.com/docs/guides/ducklake.html Repeats VERTEX TABLE and EDGE TABLE entries to form a heterogeneous graph with multiple node and edge types. The OPTIONS block sets SNAPSHOT_POLICY to 'LIVE', ACCESS_MODE to 'READ_ONLY', and VALIDATE to TRUE. Each mapping declares its source table, key, and selected properties. ```sql CREATE GRAPH commerce TYPED { (Customer :Customer { id INT64 NOT NULL, name STRING }), (Product :Product { id INT64 NOT NULL, name STRING, price FLOAT64 }), (Customer)-[:BOUGHT { id INT64 NOT NULL, quantity INT32 }]->(Product), (Customer)-[:VIEWED { id INT64 NOT NULL, viewed_at ZONEDDATETIME }]->(Product) } FROM TABLES ( VERTEX TABLE lake.main.customers MAP TO NODE TYPE Customer KEY (customer_id) PROPERTIES ( customer_id AS id, customer_name AS name ), VERTEX TABLE lake.main.products MAP TO NODE TYPE Product KEY (product_id) PROPERTIES ( product_id AS id, product_name AS name, price AS price ), EDGE TABLE lake.main.orders MAP TO EDGE TYPE BOUGHT KEY (order_id) SOURCE (customer_id) REFERENCES NODE TYPE Customer DESTINATION (product_id) REFERENCES NODE TYPE Product PROPERTIES ( order_id AS id, quantity AS quantity ), EDGE TABLE lake.main.product_views MAP TO EDGE TYPE VIEWED KEY (view_id) SOURCE (customer_id) REFERENCES NODE TYPE Customer DESTINATION (product_id) REFERENCES NODE TYPE Product PROPERTIES ( view_id AS id, viewed_at AS viewed_at ) ) OPTIONS ( SNAPSHOT_POLICY 'LIVE', ACCESS_MODE 'READ_ONLY', VALIDATE TRUE ); ``` -------------------------------- ### Apply vertex_label and edge_label filters to algo.degree Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Shows how to pass vertex_label and edge_label filters to algorithms that accept them. The vertex_label creates an induced vertex projection, and edge_label retains only edges with that label. Label matching is case-insensitive, and these filters affect the graph seen by the algorithm, not the result after computation. ```sql CALL algo.degree( 'social', vertex_label := 'Person', edge_label := 'FOLLOWS' ); ``` -------------------------------- ### Create property index Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Calls gql_create_property_index to create an ART index on the 'id' property of the 'social' graph. The call is idempotent and returns a result set with columns success, graph_name, property_name, and index_name. ```sql CALL gql_create_property_index('social', 'id'); ``` -------------------------------- ### Create typed graph with inline schema Source: https://duckgql.com/docs/guides/graph-lifecycle.html Creates empty managed tables immediately with a typed schema. Node aliases identify schema elements; edge declarations reference those aliases. Duplicate properties, unknown endpoint aliases, unknown types, and incompatible declarations reject the command. ```sql CREATE GRAPH social_typed TYPED { (Person :Person { id INT64 NOT NULL, name STRING, active BOOLEAN }), (Company :Company { id INT64 NOT NULL, name STRING NOT NULL }), (Person)-[:KNOWS { since INT32 }]->(Person), (Person)-[:WORKS_AT { role STRING }]->(Company) }; ``` -------------------------------- ### Run PageRank algorithm on referenced graph Source: https://duckgql.com/docs/guides/ducklake.html Calls the PageRank algorithm on the 'commerce' graph, yielding vertex IDs and ranks, then orders by rank descending. No explicit CSR build is required; the algorithm builds the minimal compatible CSR automatically. ```sql CALL algo.pagerank('commerce') YIELD vertex_id, rank RETURN vertex_id, rank ORDER BY rank DESC; ``` -------------------------------- ### Inspect the graph catalog with gql_graphs() Source: https://duckgql.com/docs/guides/graph-lifecycle.html Query the graph catalog to see graph names, versions, vertex and edge counts, and creation timestamps. graph_version changes when DuckGQL publishes graph mutations or lifecycle changes. ```sql SELECT graph_name, graph_version, vertex_count, edge_count, created_at FROM gql_graphs() ORDER BY graph_name; ``` -------------------------------- ### CALL algo.sssp Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Unweighted single-source shortest paths algorithm that computes minimum hop counts from exactly one source. ```APIDOC ## CALL algo.sssp ### Description Computes unweighted single-source shortest paths from exactly one source, implemented as a breadth-first traversal because every edge has unit cost. ### Method CALL ### Endpoint CALL algo.sssp(graph, frontier, direction, max_depth, edge_label, vertex_label, target_vertex_id) ### Parameters #### Parameters - **graph** (string) - Required - Graph name. - **frontier** (element ID) - Required - Start element ID, or IDs supplied by a preceding MATCH. - **direction** (string) - Optional - Adjacency direction to traverse. Default: 'out'. Accepts 'out', 'in', 'both'. - **max_depth** (integer) - Optional - Greatest emitted depth. Must be non-negative. Default: unlimited. - **edge_label** (string) - Optional - Restricts traversable edges. Default: all edges. - **vertex_label** (string) - Optional - Restricts traversal to an induced vertex projection. Default: all vertices. - **target_vertex_id** (element ID) - Optional - Stop after the target is emitted. Default: none. ### Request Example ```sql CALL algo.sssp( 'social', 42, direction := 'out', edge_label := 'FOLLOWS' ) YIELD vertex_id, distance, parent_vertex_id RETURN vertex_id, distance, parent_vertex_id ORDER BY distance, vertex_id; ``` ### Response #### Success Response Returns columns: vertex_id, distance, parent_vertex_id, edge_id, settled_order. Unreachable vertices do not appear. #### Response Example No explicit response example provided. ``` -------------------------------- ### Count components with system.algo.wcc table function Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Uses the wcc algorithm as a table function in the system.algo schema to count distinct connected components. This form is useful when ordinary SQL aggregation is more convenient. ```sql SELECT count(*) AS component_count FROM ( SELECT DISTINCT component_id FROM system.algo.wcc('social') ); ``` -------------------------------- ### Inspect per-type CSR statistics with gql_csr_edge_stats Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Shows per-edge-label statistics used for expansion estimates verdicts. Like gql_csr_stats, this requires prepared compatible state and a full CSR build for a predictable measurements surface. ```sql SELECT edge_label, edge_count, outgoing_vertex_count, incoming_vertex_count, avg_outgoing_degree, avg_incoming_degree, max_outgoing_degree, max_incoming_degree FROM gql_csr_edge_stats('social') ORDER BY edge_label; ``` -------------------------------- ### Run algo.dfs with direction 'both' and max_depth Source: https://duckgql.com/docs/guides/csr-and-algorithms.html Runs depth-first search from a single source. It uses an iterative stack, so deep graphs do not depend on the C++ call stack. The output schema is the same as BFS, but depth belongs to the DFS tree and is not a shortest-path distance. Use DFS for reachability, exhaustive exploration, or tree construction. ```sql CALL algo.dfs( 'social', 42, direction := 'both', max_depth := 6 ) YIELD vertex_id, depth, parent_vertex_id, edge_id, visit_order RETURN vertex_id, depth, parent_vertex_id, edge_id, visit_order; ``` -------------------------------- ### Create vertex projections in DuckLake Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Creates the two vertex projections in DuckLake, mapping source keys and user-facing IDs, with a CASE expression to distinguish Comment from Post. ```sql CREATE TABLE lake.main.person_nodes AS SELECT p_personid AS person_key, p_personid AS id, p_firstname AS first_name, p_lastname AS last_name, p_creationdate AS creation_date FROM raw.main.person; CREATE TABLE lake.main.message_nodes AS SELECT m_messageid AS message_key, m_messageid AS id, CASE WHEN m_ps_forumid IS NULL THEN 'Comment' ELSE 'Post' END AS kind, m_creationdate AS creation_date, m_content AS content, m_ps_imagefile AS image_file, m_length AS length FROM raw.main.message; ``` -------------------------------- ### Inspect property indexes Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Query the gql_property_indexes() table function to list registered property indexes with their catalog and table details. ```sql SELECT graph_name, property_name, index_name, catalog_name, schema_name, table_name, column_name FROM gql_property_indexes() ORDER BY graph_name, property_name; ``` -------------------------------- ### OPTIONAL MATCH with LET and FILTER Source: https://duckgql.com/docs/guides/querying.html LET introduces a named scalar and establishes a clause boundary; a FILTER after the optional join eliminates null-extended rows. ```sql MATCH (person:Person) OPTIONAL MATCH (person)-[:KNOWS]->(friend:Person) LET friend_age = friend.age FILTER friend_age >= 35 RETURN person.name, friend.name; ``` -------------------------------- ### PageRank on Person and KNOWS Source: https://duckgql.com/docs/blog/ducklake-snb10-zero-copy.html Runs PageRank on Person vertices and KNOWS edges. Output uses DuckGQL's snapshot-local vertex ID, so retain the mapped Person.id property for a durable external identifier. ```sql SELECT vertex_id, rank FROM system.algo.pagerank( 'snb10', vertex_label := 'Person', edge_label := 'KNOWS', damping := 0.85, tolerance := 1e-8 ) ORDER BY rank DESC LIMIT 20; ``` -------------------------------- ### Create property index with case-insensitive property name Source: https://duckgql.com/docs/guides/indexes-and-optimization.html Property names are resolved case-insensitively, so 'ID' is equivalent to 'id'. ```sql CALL gql_create_property_index('social', 'ID'); ```