Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@visactor/calculator
Advanced tools
The tool inputs "Raw Detailed Data" obtained through analysis functions. Utilizing a query configuration structured similar to "SQL-like Query Syntax", it computes "Result Data".
The query calculation parameters are aligned with the structure of an "SQL Query Statement," and the methods for aggregation, filtering, and other computational processes are also in line with those in SQL. However, flexibility support is tailored according to the "Usage Scenarios", simplifying some syntax and functionalities of SQL.
A common SQL format example:
select <column>, ...
from <table>
where (... and ...)
group by ..., ...
having (... or ...)
order by ..., ...
limit 1000
Corresponding query configuration structure:
import { query, type Query } from '@visactor/vmind/calculator'
query({
from: data,
select: { columns: [...] },
where: { ... },
groupBy: [...],
having: { ... },
orderBy: [...],
limit: 1000,
})
While aligning with SQL syntax and processing, some parts are simplified and specially supported according to "Usage Scenarios". Below are some examples of similarities and differences:
from
section:
join
support, union
not supported.join
section:
Left Join
, Right Join
, Inner Join
, Cross Join
as per current usage scenarios, does not support Full
type joins.using
condition, equivalent to the simplest on
condition for joining two fields with the same name. As there are no other use cases, there is no support for conditions like on between
, on like
.join
process is provided as a separate computational process, not described within the query({ from })
model. Its result is used as input for the from
section.select
section:
select
, does not support select *
.id + 5
=> { alias: 'id', column: ({ row }) => row.id + 5 }
sum(sale) / count(sale)
=> { alias: 'id', aggregate: ({ group }) => sum(group, 'sale') / count(group, 'sale') }
alias
in select
, but other query configurations do not support referencing aliases.offset
section:
offset
, only limit
, as there are no use cases for offset
, and its addition would be straightforward and unobstructed.Calculation Functions:
Field-level
distinct
is completed before aggregation, e.g.,count(distinct <column>)
.
select
.Data Format:
string
, number
, null
format fields.Date
/ boolean
type fields (no special judgments and processing).
Date
types can be converted into basic ISO 8601 string format YYYY-MM-DD
, equivalent to calculation as string
.string
for calculations.undefined
, i.e., missing field values should be filled with null
.Performance Optimization:
indexes
, logical optimizers
(query planners), execution optimizers
.indexes
, the filtering process iterates through all row data.logical optimizer
, such as simplification of where
/having
logic within equivalent ranges.execution logic optimization
, like advancing the limit
process or sorting process within equivalent ranges.order by
(usage scenario-specific, not standard SQL support).
calculation values" (no use case).
Aggregation, filtering, sorting processes for null
values align with SQL.
is null
operator matches null
values (=/!=
are ineffective).null
values follow SQL's default rules (NULLS LAST).In filtering options,
between
comparison is the same as in SQL, a closed interval.number
/ string
.having
can perform aggregate calculations on fields.Apart from group by
, if there are aggregate functions in the select
column, they are also aggregated (aggregated into one row).
group by
, and if there are no aggregate functions in select
, order by
cannot use aggregate calculations alone.The execution process within calculator
for a query()
call also fully references the general execution process of an SQL engine for a single SQL query.
A typical SQL query process includes the following steps:
Except for where
and select
, the rest are optional steps.
In the execution process of the calculator
's query()
function, these step names and meanings are consistent with SQL.
From
In SQL, From
identifies the "data source table" for providing data. In the query({ from })
function, there are no table entities; the from
field is directly the row data itself from: Row[];
.
In SQL, the "source table" in From
can also be a virtual table, such as the result of another nested SQL query (subquery), e.g.,
select <column>
from (
select <column>
from <table>
where ...
)
where ...
In query()
, subquery syntax is not supported, but it can be achieved by nested calls by the user, e.g.,
query({
from: query({
from: data,
select: { columns: [...] },
where: { ... },
...
}),
select: { columns: [...] },
where: { ... },
...
})
join
In SQL, join
is a sub-clause of from
, executed according to different join
types (left / right / inner / full / exclude
, etc.) and corresponding field matching rules. For each matched field, the corresponding M, N rows are selected from the left and right tables, respectively, forming a Cartesian product virtual table of M x N rows.
In the calculation library usage, join
is provided as a separate computational process, not described within the query({ from })
model. Its result is used as input for the from
section, used as follows:
query({
from: leftJoin({
left: query( ... ),
right: query( ... ),
}),
select: { columns: [...] },
where: { ... },
...
})
Where
Filters "Raw Detailed Data" (TableData
) (un-grouped/non-aggregated data). In SQL syntax, filtering conditions support multiple nested and
and or
relationships.
In the query({ where })
function, the where
field correspondingly supports different filtering conditions combined into a "tree structure" (filter tree) through multiple nested and
and or
.
Group By
Groups raw data based on one or more fields, outputting multiple "Grouped Data" sets, divided by different column values for subsequent aggregation calculations. Each group's data is aggregated separately.
SQL queries inherently return "row-level data," unable to represent a pivoted structure. The multiple pivoted structure is maintained internally during the Group By
stage for grouping, and it's converted to a flat detail table structure when outputting.
The order of each group in the "Grouped Data" is maintained as the order of the first row of each group in the raw data. The order of all rows within each group is also maintained as their original relative order.
Group By
only groups and does not perform aggregation calculations (count
/sum
...).
Having
Applies filters to each group in "Grouped Data" (GroupedData
). The filtering conditions have a tree-like logical structure similar to that in Where
,
However, Having
allows the use of "aggregate functions" during filter processing. It performs an "aggregate calculation" on all rows within a group, producing a single value used in filtering conditions,
having id > 5 and count(email) > 5 and count(distinct email) > 5
When fields not using aggregate functions are present, the first row of each group is used by default, effectively representing the entire group;
During aggregate calculations, the distinct
keyword can be used for deduplication, indicating that the calculation is performed on a deduplicated set of values for that field;
Order By
Sorts the input data. Without a preceding Group By
, the input is "raw detailed data" and sorting is based only on individual rows.
For "Grouped Data", "aggregate functions" can be used to determine the order of groups, with the aggregation process being the same as in Having
;
Order By
only changes the order of groups in "Grouped Data", not the order of the original detailed rows within each group;
In platform use cases, "Manual Sorting" is implemented by converting manually set order values into case when
statements in the Order By
part of SQL statements, like:
order by case
when name = '...' then 1
when name = '...' then 2
when name = '...' then 3
else 4
end ASC
In the query()
function, there is no support for case when
, but manual sorting configurations are added in the orderBy
field.
Select
Select
is used to "extract" specific field columns from the output data. This process involves two steps:
Having
;
Essentially transforming "Grouped Data" into "detailed data" rows equal in number to the groups.Distinct
This is equivalent to the SQL syntax select distinct ...
, indicating deduplication of rows in the final output data of Select
.
Offset
/Limit
Truncates the output data to the first N items, or offsets by the first M items before truncating to N items.
FAQs
SQL-like query executor with DSL
We found that @visactor/calculator demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.