Skip to main content

Data Queries - Complete Guide

Placeholder for Demo

๐Ÿ“ Build and Execute Queriesโ€‹

SQL Queries ยท Parameters ยท Testing ยท Caching ยท Execution


๐Ÿ“‹ Table of Contentsโ€‹


Overviewโ€‹

Data Queries are reusable query definitions that execute against your configured datasources. They are the foundation for:

  • โœ… Dashboard widgets
  • โœ… Workflow automation
  • โœ… Data transformations
  • โœ… API endpoints
  • โœ… Scheduled jobs

Key Featuresโ€‹

  • Native SQL - Write queries in PostgreSQL dialect
  • Parameterized Queries - Use dynamic variables
  • Query Testing - Test before saving
  • Result Caching - Optimize performance
  • Run on Load - Auto-execute options
  • AI Assistance - Generate queries with AI
  • Bulk Operations - Create multiple queries

Query Typesโ€‹

Query TypeDescriptionUse Case
SELECTRetrieve dataDashboards, reports
INSERTCreate recordsForm submissions
UPDATEModify recordsData updates
DELETERemove recordsCleanup operations
UPSERTInsert or updateSync operations

Creating a Data Queryโ€‹

Step-by-Step Guideโ€‹

  1. Navigate to Data Queries in sidebar
  2. Click "Create Data Query" button
  3. Select datasource from dropdown
  4. Configure query settings
  5. Write SQL query
  6. Define parameters (if any)
  7. Test the query
  8. Save for reuse

Required Fieldsโ€‹

FieldTypeRequiredDescription
Query TitleStringโœ… YesUnique name for the query
DatasourceDatasourceโœ… YesDatabase connection to use
Query TypeStringโœ… Yesquery (SQL) or gui (visual)
QueryStringโœ… YesSQL statement to execute

Optional Fieldsโ€‹

FieldTypeDefaultDescription
Run on LoadBooleanfalseExecute automatically when loaded
DescriptionString-Query documentation
TagsArray[]Organizational tags
TimeoutInteger300sQuery execution timeout

Query Configurationโ€‹

Query Titleโ€‹

Purpose: Identify this query in lists and dropdowns.

Validation:

  • Required: Yes
  • Min Length: 1 character
  • Max Length: 255 characters

Best Practices:

โœ… Good: "GetActiveUsers"
โœ… Good: "CreateNewOrder"
โœ… Good: "UpdateProductInventory"
โŒ Bad: "Query1"
โŒ Bad: "test"

Datasource Selectionโ€‹

Purpose: Choose which database connection to use.

Options:

  • Any configured PostgreSQL datasource
  • REST API datasource (for API calls)
  • Datasource dropdown with refresh button

How to Select:

  1. Click datasource dropdown
  2. Select from available datasources
  3. Click refresh icon if datasource not showing
  4. Datasource loads with connection details

Query Typeโ€‹

Purpose: Choose query input method.

Options:

TypeValueDescription
Raw SQLqueryWrite SQL directly (Recommended)
GUI BuilderguiVisual query builder (Coming soon)

Recommended: Use Raw SQL for full control

Query Editorโ€‹

Purpose: Write the SQL statement to execute.

Features:

  • Syntax highlighting (PostgreSQL dialect)
  • Auto-completion
  • Line numbers
  • Code folding
  • Format/Beautify button

Editor Options:

{
"queryType": "query",
"query": "SELECT * FROM users WHERE active = true;"
}

Query Parametersโ€‹

Overviewโ€‹

Parameters allow you to create dynamic queries that accept input values at execution time.

Parameter Structureโ€‹

FieldTypeRequiredOptionsDescription
KeyStringโœ… Yes-Parameter name
TypeStringโœ… YesSee belowParameter data type

Parameter Typesโ€‹

TypeDescriptionExampleSQL Usage
stringText value"active"WHERE status = {{status}}
numberNumeric value42WHERE age > {{minAge}}
booleanTrue/falsetrueWHERE active = {{isActive}}
array (, separated)List of values"1,2,3"WHERE id IN ({{ids}})
object (JSON stringified)JSON object{"name":"John"}Complex filters

Adding Parametersโ€‹

Step 1: Click "Add Parameter" button

Step 2: Configure parameter:

{
"key": "userId",
"type": "string"
}

Step 3: Use in query:

SELECT * FROM users WHERE id = {{userId}};

Parameter Usage in Queriesโ€‹

String Parametersโ€‹

Configuration:

{
"key": "status",
"type": "string"
}

Query:

SELECT * FROM orders WHERE status = {{status}};

Execution:

{
"status": "pending"
}

Result:

SELECT * FROM orders WHERE status = 'pending';

Number Parametersโ€‹

Configuration:

{
"key": "minAmount",
"type": "number"
}

Query:

SELECT * FROM orders WHERE amount > {{minAmount}};

Execution:

{
"minAmount": 100
}

Result:

SELECT * FROM orders WHERE amount > 100;

Boolean Parametersโ€‹

Configuration:

{
"key": "isActive",
"type": "boolean"
}

Query:

SELECT * FROM users WHERE active = {{isActive}};

Execution:

{
"isActive": true
}

Result:

SELECT * FROM users WHERE active = true;

Array Parametersโ€‹

Configuration:

{
"key": "userIds",
"type": "array (, separated)"
}

Query:

SELECT * FROM users WHERE id IN ({{userIds}});

Execution:

{
"userIds": "1,2,3,4,5"
}

Result:

SELECT * FROM users WHERE id IN (1,2,3,4,5);

Object Parameters (JSON)โ€‹

Configuration:

{
"key": "filters",
"type": "object (JSON stringified)"
}

Query:

SELECT * FROM products WHERE metadata @> {{filters}};

Execution:

{
"filters": "{\"category\":\"electronics\"}"
}

Result:

SELECT * FROM products WHERE metadata @> '{"category":"electronics"}';

Multiple Parametersโ€‹

Example Query with Multiple Parameters:

SELECT 
u.id,
u.name,
u.email,
o.total,
o.status
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE
u.status = {{userStatus}}
AND o.created_at >= {{startDate}}
AND o.created_at <= {{endDate}}
AND o.total >= {{minAmount}}
ORDER BY o.created_at DESC
LIMIT {{limit}};

Parameters:

[
{
"key": "userStatus",
"type": "string"
},
{
"key": "startDate",
"type": "string"
},
{
"key": "endDate",
"type": "string"
},
{
"key": "minAmount",
"type": "number"
},
{
"key": "limit",
"type": "number"
}
]

Query Executionโ€‹

Execution Methodsโ€‹

1. Manual Executionโ€‹

How to:

  1. Open query in editor
  2. Click "Test" or "Run" button
  3. Provide parameter values (if any)
  4. View results

Use Case: Testing and debugging

2. Run on Loadโ€‹

Configuration:

{
"runOnLoad": true
}

Behavior:

  • Query executes automatically when page loads
  • Useful for dashboard widgets
  • Parameters can be passed via URL or context

Use Case: Dashboard widgets, auto-refreshing data

3. API Executionโ€‹

Endpoint:

POST /api/v1/tenants/:tenantID/data-queries/:queryID/execute

Request Body:

{
"parameters": {
"userId": "123",
"status": "active"
}
}

Use Case: External integrations, custom applications

4. Workflow Executionโ€‹

In Workflow Node:

  1. Add "Data Query" node
  2. Select query from dropdown
  3. Map parameters
  4. Configure output variable

Use Case: Automation, multi-step processes

Execution Optionsโ€‹

Timeoutโ€‹

Purpose: Maximum execution time before query is cancelled.

Type: Integer (seconds)

Default: 300 seconds (5 minutes)

Configuration:

{
"dataQueryOptions": {
"timeout": 60
}
}

When to Adjust:

  • Increase for complex analytical queries: 600 (10 min)
  • Decrease for simple lookups: 30 (30 sec)
  • Default for most queries: 300 (5 min)

Cachingโ€‹

Purpose: Store query results to improve performance.

Cache Key Components:

  • Query SQL
  • Parameter values
  • Datasource ID
  • User/Tenant context

Cache Behavior:

  • Results cached for duration of session
  • Cache invalidated on data changes
  • Manual refresh available

Testing Queriesโ€‹

Test Panelโ€‹

Location: Right side of query editor

Features:

  • Parameter input fields
  • Execute button
  • Results display
  • Error messages
  • Execution time

Testing Stepsโ€‹

Step 1: Configure Parameters

Enter values for each parameter:
- userId: 123
- status: active

Step 2: Click "Test Query"

Step 3: Review Results

Test Resultsโ€‹

Successโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โœ“ Query Executed Successfully โ”‚
โ”‚ โ”‚
โ”‚ Execution Time: 45ms โ”‚
โ”‚ Rows Affected: 150 โ”‚
โ”‚ โ”‚
โ”‚ Results: โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ id โ”‚ name โ”‚ email โ”‚ status โ”‚ โ”‚
โ”‚ โ”œโ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚
โ”‚ โ”‚ 1 โ”‚ John โ”‚ j@ex.com โ”‚ active โ”‚ โ”‚
โ”‚ โ”‚ 2 โ”‚ Jane โ”‚ j@ex.com โ”‚ active โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Errorโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โœ— Query Execution Failed โ”‚
โ”‚ โ”‚
โ”‚ Error: relation "userss" does not existโ”‚
โ”‚ SQL State: 42P01 โ”‚
โ”‚ Position: 15 โ”‚
โ”‚ โ”‚
โ”‚ Query: โ”‚
โ”‚ SELECT * FROM userss WHERE ... โ”‚
โ”‚ โ”‚
โ”‚ Suggestions: โ”‚
โ”‚ โ€ข Check table name spelling โ”‚
โ”‚ โ€ข Verify table exists in database โ”‚
โ”‚ โ€ข Check schema permissions โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Common Test Errorsโ€‹

ErrorCauseSolution
relation does not existTypo in table nameCheck spelling
column does not existInvalid columnVerify column names
permission deniedInsufficient privilegesGrant permissions
syntax errorSQL syntax issueCheck SQL syntax
parameter undefinedMissing parameterDefine all parameters
type mismatchWrong parameter typeMatch parameter types

Query Resultsโ€‹

Result Formatโ€‹

Standard Format:

{
"success": true,
"data": [
{ "id": 1, "name": "John" },
{ "id": 2, "name": "Jane" }
],
"rowCount": 2,
"executionTime": 45,
"fields": [
{ "name": "id", "dataType": "uuid" },
{ "name": "name", "dataType": "text" }
]
}

Result Metadataโ€‹

FieldTypeDescription
successBooleanWhether query succeeded
dataArrayQuery result rows
rowCountIntegerNumber of rows returned
executionTimeIntegerExecution time in ms
fieldsArrayColumn metadata
errorObjectError details (if failed)

Accessing Resultsโ€‹

In Widgetsโ€‹

// Widget data binding
{
"queryId": "query-uuid",
"resultPath": "data"
}

In Workflowsโ€‹

// Workflow node output
{
"outputVariable": "queryResult",
"accessAs": "{{ctx.queryResult}}"
}

In JavaScriptโ€‹

// Access in script nodes
const users = ctx.queryResult.data;
const count = ctx.queryResult.rowCount;

Advanced Featuresโ€‹

AI Query Generationโ€‹

Purpose: Generate SQL queries using natural language.

How to Use:

  1. Click "AI Generate" button
  2. Enter description in plain English
  3. AI generates SQL query
  4. Review and edit as needed
  5. Save query

Example:

Input: "Get all active users with their orders from last month"

Output:
SELECT u.*, o.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
AND o.created_at >= NOW() - INTERVAL '1 month'

Bulk Query Creationโ€‹

Purpose: Create multiple queries at once.

Use Case:

  • Batch operations
  • Multiple related queries
  • Import/export queries

Format:

{
"dataQueries": [
{
"dataQueryTitle": "GetUsers",
"dataQueryOptions": {
"query": "SELECT * FROM users"
}
},
{
"dataQueryTitle": "GetOrders",
"dataQueryOptions": {
"query": "SELECT * FROM orders"
}
}
]
}

Query Templatesโ€‹

Purpose: Reuse common query patterns.

Built-in Templates:

  • SELECT with pagination
  • INSERT with return
  • UPDATE with conditions
  • DELETE with soft delete
  • Aggregation queries
  • JOIN queries

Custom Templates: Create your own templates for common operations in your organization.

Query Versioningโ€‹

Purpose: Track query changes over time.

Features:

  • Version history
  • Rollback to previous versions
  • Change comments
  • Comparison view

Examplesโ€‹

Example 1: Simple SELECTโ€‹

Title: GetActiveUsers

Datasource: Production PostgreSQL

Query:

SELECT id, name, email, created_at
FROM users
WHERE active = true
ORDER BY created_at DESC;

Parameters: None

Use Case: Dashboard user list


Example 2: Parameterized SELECTโ€‹

Title: GetUserOrders

Datasource: Production PostgreSQL

Query:

SELECT 
o.id,
o.order_number,
o.total,
o.status,
o.created_at,
u.name as customer_name,
u.email as customer_email
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE
o.user_id = {{userId}}
AND o.status = {{status}}
ORDER BY o.created_at DESC;

Parameters:

[
{
"key": "userId",
"type": "string"
},
{
"key": "status",
"type": "string"
}
]

Use Case: User order history page


Example 3: INSERT with Returnโ€‹

Title: CreateUser

Datasource: Production PostgreSQL

Query:

INSERT INTO users (name, email, status, created_at)
VALUES ({{name}}, {{email}}, {{status}}, NOW())
RETURNING id, name, email, created_at;

Parameters:

[
{
"key": "name",
"type": "string"
},
{
"key": "email",
"type": "string"
},
{
"key": "status",
"type": "string"
}
]

Use Case: User registration form


Example 4: UPDATE with Conditionsโ€‹

Title: UpdateOrderStatus

Datasource: Production PostgreSQL

Query:

UPDATE orders
SET
status = {{newStatus}},
updated_at = NOW(),
updated_by = {{updatedBy}}
WHERE
id = {{orderId}}
AND status != 'cancelled'
RETURNING id, status, updated_at;

Parameters:

[
{
"key": "orderId",
"type": "string"
},
{
"key": "newStatus",
"type": "string"
},
{
"key": "updatedBy",
"type": "string"
}
]

Use Case: Order status update workflow


Example 5: Aggregation Queryโ€‹

Title: GetDailyRevenue

Datasource: Analytics PostgreSQL

Query:

SELECT 
DATE(created_at) as date,
COUNT(*) as order_count,
SUM(total) as total_revenue,
AVG(total) as avg_order_value
FROM orders
WHERE
created_at >= {{startDate}}
AND created_at <= {{endDate}}
AND status = 'completed'
GROUP BY DATE(created_at)
ORDER BY date DESC;

Parameters:

[
{
"key": "startDate",
"type": "string"
},
{
"key": "endDate",
"type": "string"
}
]

Use Case: Revenue dashboard chart


Example 6: Complex JOIN with Array Parameterโ€‹

Title: GetUsersByIds

Datasource: Production PostgreSQL

Query:

SELECT 
u.id,
u.name,
u.email,
COUNT(o.id) as order_count,
SUM(o.total) as total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = ANY(STRING_TO_ARRAY({{userIds}}, ','))
GROUP BY u.id, u.name, u.email
HAVING COUNT(o.id) > 0
ORDER BY total_spent DESC;

Parameters:

[
{
"key": "userIds",
"type": "array (, separated)"
}
]

Use Case: Bulk user analysis


Next Stepsโ€‹