Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@balena/abstract-sql-compiler

Package Overview
Dependencies
Maintainers
3
Versions
467
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@balena/abstract-sql-compiler - npm Package Compare versions

Comparing version 9.0.1 to 9.0.2-build-184-operator-precedence-light-be84fe9af991e4b921673872f6dffd33f1427db8-1

5

CHANGELOG.md

@@ -7,2 +7,7 @@ # Change Log

## 9.0.2 - 2023-05-15
* Wrap expressions with parenthesis based on their precedence [Thodoris Greasidis]
* Wrap composite comparison operations with parenthesis when necessary [Thodoris Greasidis]
## 9.0.1 - 2023-05-15

@@ -9,0 +14,0 @@

88

out/AbstractSQLRules2SQL.js

@@ -251,4 +251,4 @@ "use strict";

(0, exports.checkArgs)(comparison, args, 2);
const a = AnyValue((0, exports.getAbstractSqlQuery)(args, 0), indent);
const b = AnyValue((0, exports.getAbstractSqlQuery)(args, 1), indent);
const a = precedenceSafeOpValue(comparison, AnyValue, args, 0, indent);
const b = precedenceSafeOpValue(comparison, AnyValue, args, 1, indent);
return a + exports.comparisons[comparison] + b;

@@ -315,18 +315,46 @@ };

};
const mathOperatorNodeTypes = new Set([
...Object.keys(mathOps),
'AddDateDuration',
'AddDateNumber',
'SubtractDateDate',
'SubtractDateDuration',
'SubtractDateNumber',
]);
const mathOpValue = (valueMatchFn, args, index, indent) => {
const opsPrecedence = (() => {
const operatorsByPrecedence = [
['Multiply', 'Divide'],
[
'Add',
'AddDateDuration',
'AddDateNumber',
'Subtract',
'SubtractDateDate',
'SubtractDateDuration',
'SubtractDateNumber',
],
['Between', 'Like'],
[
'Equals',
'NotEquals',
'GreaterThan',
'GreaterThanOrEqual',
'LessThan',
'LessThanOrEqual',
],
];
const operatorPrecedence = {};
let precedence = 0;
for (const samePrecedenceOps of operatorsByPrecedence) {
for (const op of samePrecedenceOps) {
operatorPrecedence[op] = precedence;
}
precedence++;
}
return operatorPrecedence;
})();
const precedenceSafeOpValue = (parentNodeType, valueMatchFn, args, index, indent) => {
const operandAbstractSql = (0, exports.getAbstractSqlQuery)(args, index);
const numericValue = valueMatchFn(operandAbstractSql, indent);
const valueExpr = valueMatchFn(operandAbstractSql, indent);
const [childNodeType] = operandAbstractSql;
if (mathOperatorNodeTypes.has(childNodeType)) {
return `(${numericValue})`;
const parentOperatorPrecedence = opsPrecedence[parentNodeType];
const childOperatorPrecedence = opsPrecedence[childNodeType];
if (childOperatorPrecedence != null &&
parentOperatorPrecedence != null &&
parentOperatorPrecedence <= childOperatorPrecedence) {
return `(${valueExpr})`;
}
return numericValue;
return valueExpr;
};

@@ -336,4 +364,4 @@ const MathOp = (type) => {

(0, exports.checkArgs)(type, args, 2);
const a = mathOpValue(NumericValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue(type, NumericValue, args, 0, indent);
const b = precedenceSafeOpValue(type, NumericValue, args, 1, indent);
return `${a} ${mathOps[type]} ${b}`;

@@ -406,4 +434,4 @@ };

(0, exports.checkArgs)('AddDateNumber', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue('AddDateNumber', DateValue, args, 0, indent);
const b = precedenceSafeOpValue('AddDateNumber', NumericValue, args, 1, indent);
if (engine === "postgres") {

@@ -421,4 +449,4 @@ return `${a} + ${b}`;

(0, exports.checkArgs)('AddDateDuration', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DurationValue, args, 1, indent);
const a = precedenceSafeOpValue('AddDateDuration', DateValue, args, 0, indent);
const b = precedenceSafeOpValue('AddDateDuration', DurationValue, args, 1, indent);
if (engine === "postgres") {

@@ -436,4 +464,4 @@ return `${a} + ${b}`;

(0, exports.checkArgs)('SubtractDateDuration', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DurationValue, args, 1, indent);
const a = precedenceSafeOpValue('SubtractDateDuration', DateValue, args, 0, indent);
const b = precedenceSafeOpValue('SubtractDateDuration', DurationValue, args, 1, indent);
if (engine === "postgres") {

@@ -451,4 +479,4 @@ return `${a} - ${b}`;

(0, exports.checkArgs)('SubtractDateNumber', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue('SubtractDateNumber', DateValue, args, 0, indent);
const b = precedenceSafeOpValue('SubtractDateNumber', NumericValue, args, 1, indent);
if (engine === "postgres") {

@@ -466,4 +494,4 @@ return `${a} - ${b}`;

(0, exports.checkArgs)('SubtractDateDate', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DateValue, args, 1, indent);
const a = precedenceSafeOpValue('SubtractDateDate', DateValue, args, 0, indent);
const b = precedenceSafeOpValue('SubtractDateDate', DateValue, args, 1, indent);
if (engine === "postgres") {

@@ -840,5 +868,5 @@ return `${a} - ${b}`;

(0, exports.checkArgs)('Between', args, 3);
const v = AnyValue((0, exports.getAbstractSqlQuery)(args, 0), indent);
const a = AnyValue((0, exports.getAbstractSqlQuery)(args, 1), indent);
const b = AnyValue((0, exports.getAbstractSqlQuery)(args, 2), indent);
const v = precedenceSafeOpValue('Between', AnyValue, args, 0, indent);
const a = precedenceSafeOpValue('Between', AnyValue, args, 1, indent);
const b = precedenceSafeOpValue('Between', AnyValue, args, 2, indent);
return `${v} BETWEEN ${a} AND (${b})`;

@@ -845,0 +873,0 @@ },

{
"name": "@balena/abstract-sql-compiler",
"version": "9.0.1",
"version": "9.0.2-build-184-operator-precedence-light-be84fe9af991e4b921673872f6dffd33f1427db8-1",
"description": "A translator for abstract sql into sql.",

@@ -64,4 +64,4 @@ "main": "out/AbstractSQLCompiler.js",

"versionist": {
"publishedAt": "2023-05-15T12:42:37.997Z"
"publishedAt": "2023-05-15T21:42:55.457Z"
}
}

@@ -318,4 +318,4 @@ import * as _ from 'lodash';

checkArgs(comparison, args, 2);
const a = AnyValue(getAbstractSqlQuery(args, 0), indent);
const b = AnyValue(getAbstractSqlQuery(args, 1), indent);
const a = precedenceSafeOpValue(comparison, AnyValue, args, 0, indent);
const b = precedenceSafeOpValue(comparison, AnyValue, args, 1, indent);
return a + comparisons[comparison] + b;

@@ -389,12 +389,40 @@ };

const mathOperatorNodeTypes = new Set([
...Object.keys(mathOps),
'AddDateDuration',
'AddDateNumber',
'SubtractDateDate',
'SubtractDateDuration',
'SubtractDateNumber',
]);
const opsPrecedence = (() => {
const operatorsByPrecedence = [
['Multiply', 'Divide'],
[
'Add',
'AddDateDuration',
'AddDateNumber',
'Subtract',
'SubtractDateDate',
'SubtractDateDuration',
'SubtractDateNumber',
],
['Between', 'Like'],
[
'Equals',
'NotEquals',
'GreaterThan',
'GreaterThanOrEqual',
'LessThan',
'LessThanOrEqual',
],
// In, Exists, NotExists, 'IsDistinctFrom', 'IsNotDistinctFrom', Not,
// And, Or are already adding parenthesis.
] as const;
const mathOpValue = (
const operatorPrecedence = {} as Record<string, number>;
let precedence = 0;
for (const samePrecedenceOps of operatorsByPrecedence) {
for (const op of samePrecedenceOps) {
operatorPrecedence[op] = precedence;
}
precedence++;
}
return operatorPrecedence;
})();
const precedenceSafeOpValue = (
parentNodeType: string,
valueMatchFn: MetaMatchFn,

@@ -406,8 +434,14 @@ args: AbstractSqlType[],

const operandAbstractSql = getAbstractSqlQuery(args, index);
const numericValue = valueMatchFn(operandAbstractSql, indent);
const valueExpr = valueMatchFn(operandAbstractSql, indent);
const [childNodeType] = operandAbstractSql;
if (mathOperatorNodeTypes.has(childNodeType)) {
return `(${numericValue})`;
const parentOperatorPrecedence = opsPrecedence[parentNodeType];
const childOperatorPrecedence = opsPrecedence[childNodeType];
if (
childOperatorPrecedence != null &&
parentOperatorPrecedence != null &&
parentOperatorPrecedence <= childOperatorPrecedence
) {
return `(${valueExpr})`;
}
return numericValue;
return valueExpr;
};

@@ -418,4 +452,4 @@

checkArgs(type, args, 2);
const a = mathOpValue(NumericValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue(type, NumericValue, args, 0, indent);
const b = precedenceSafeOpValue(type, NumericValue, args, 1, indent);
return `${a} ${mathOps[type]} ${b}`;

@@ -489,4 +523,10 @@ };

checkArgs('AddDateNumber', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue('AddDateNumber', DateValue, args, 0, indent);
const b = precedenceSafeOpValue(
'AddDateNumber',
NumericValue,
args,
1,
indent,
);

@@ -504,4 +544,16 @@ if (engine === Engines.postgres) {

checkArgs('AddDateDuration', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DurationValue, args, 1, indent);
const a = precedenceSafeOpValue(
'AddDateDuration',
DateValue,
args,
0,
indent,
);
const b = precedenceSafeOpValue(
'AddDateDuration',
DurationValue,
args,
1,
indent,
);

@@ -519,4 +571,16 @@ if (engine === Engines.postgres) {

checkArgs('SubtractDateDuration', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DurationValue, args, 1, indent);
const a = precedenceSafeOpValue(
'SubtractDateDuration',
DateValue,
args,
0,
indent,
);
const b = precedenceSafeOpValue(
'SubtractDateDuration',
DurationValue,
args,
1,
indent,
);

@@ -534,4 +598,16 @@ if (engine === Engines.postgres) {

checkArgs('SubtractDateNumber', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(NumericValue, args, 1, indent);
const a = precedenceSafeOpValue(
'SubtractDateNumber',
DateValue,
args,
0,
indent,
);
const b = precedenceSafeOpValue(
'SubtractDateNumber',
NumericValue,
args,
1,
indent,
);

@@ -549,4 +625,16 @@ if (engine === Engines.postgres) {

checkArgs('SubtractDateDate', args, 2);
const a = mathOpValue(DateValue, args, 0, indent);
const b = mathOpValue(DateValue, args, 1, indent);
const a = precedenceSafeOpValue(
'SubtractDateDate',
DateValue,
args,
0,
indent,
);
const b = precedenceSafeOpValue(
'SubtractDateDate',
DateValue,
args,
1,
indent,
);
if (engine === Engines.postgres) {

@@ -956,5 +1044,5 @@ return `${a} - ${b}`;

checkArgs('Between', args, 3);
const v = AnyValue(getAbstractSqlQuery(args, 0), indent);
const a = AnyValue(getAbstractSqlQuery(args, 1), indent);
const b = AnyValue(getAbstractSqlQuery(args, 2), indent);
const v = precedenceSafeOpValue('Between', AnyValue, args, 0, indent);
const a = precedenceSafeOpValue('Between', AnyValue, args, 1, indent);
const b = precedenceSafeOpValue('Between', AnyValue, args, 2, indent);
return `${v} BETWEEN ${a} AND (${b})`;

@@ -961,0 +1049,0 @@ },

@@ -0,1 +1,2 @@

import { stripIndent } from 'common-tags';
import { AnyTypeNodes } from '../../src/AbstractSQLCompiler';

@@ -27,1 +28,158 @@

});
describe('Comparison Operator Precedence', () => {
// Different precedence
test(
[
'SelectQuery',
[
'Select',
[
[
'Equals',
['Boolean', true],
['Equals', ['Boolean', true], ['Boolean', true]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid Equals statement when the second operand is also an Equals', () => {
sqlEquals(result.query, 'SELECT TRUE = (TRUE = TRUE)');
});
},
);
test(
[
'SelectQuery',
[
'Select',
[
[
'NotEquals',
['Equals', ['Boolean', false], ['Boolean', false]],
['Equals', ['Boolean', true], ['Boolean', true]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid NotEquals statement when both operands are Equals comparisons', () => {
sqlEquals(result.query, 'SELECT (FALSE = FALSE) != (TRUE = TRUE)');
});
},
);
test(
[
'SelectQuery',
[
'Select',
[
[
'NotEquals',
['Add', ['Integer', 1], ['Add', ['Integer', 2], ['Integer', 3]]],
['Add', ['Integer', 1], ['Integer', 0]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid NotEquals statement when the operands are math expressions', () => {
sqlEquals(
result.query,
stripIndent`
SELECT 1 + (2 + 3) != 1 + 0
`,
);
});
},
);
test(
[
'SelectQuery',
[
'Select',
[
[
'And',
[
'Or',
['GreaterThan', ['Integer', 1], ['Integer', 0]],
['LessThan', ['Integer', 1], ['Integer', 0]],
],
['GreaterThan', ['Integer', 1], ['Integer', 0]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid And statement when the operands are composite boolean expressions', () => {
sqlEquals(
result.query,
stripIndent`
SELECT (1 > 0
OR 1 < 0)
AND 1 > 0
`,
);
});
},
);
test(
[
'SelectQuery',
[
'Select',
[
[
'Between',
['Add', ['Integer', 1], ['Integer', 0]],
['Add', ['Integer', 1], ['Integer', 0]],
['Add', ['Integer', 1], ['Integer', 0]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid Between statement when the operands are math expressions', () => {
sqlEquals(
result.query,
stripIndent`
SELECT 1 + 0 BETWEEN 1 + 0 AND (1 + 0)
`,
);
});
},
);
test(
[
'SelectQuery',
[
'Select',
[
[
'Between',
['Equals', ['Integer', 1], ['Integer', 0]],
['LessThan', ['Integer', 1], ['Integer', 0]],
['GreaterThan', ['Integer', 1], ['Integer', 0]],
],
],
],
],
(result, sqlEquals) => {
it('should produce a valid Between statement when the operands are comparison expressions', () => {
sqlEquals(
result.query,
stripIndent`
SELECT (1 = 0) BETWEEN (1 < 0) AND ((1 > 0))
`,
);
});
},
);
});

@@ -131,3 +131,3 @@ import { AnyTypeNodes } from '../../src/AbstractSQLCompiler';

it('should produce a valid Add statement when the first operand is a Multiply', () => {
sqlEquals(result.query, 'SELECT (2 * 3) + 4');
sqlEquals(result.query, 'SELECT 2 * 3 + 4');
});

@@ -147,3 +147,3 @@ },

it('should produce a valid Add statement when the second operand is a Multiply', () => {
sqlEquals(result.query, 'SELECT 2 + (3 * 4)');
sqlEquals(result.query, 'SELECT 2 + 3 * 4');
});

@@ -169,3 +169,3 @@ },

it('should produce a valid Add statement of two Multiplications', () => {
sqlEquals(result.query, 'SELECT (2 * 3) + (4 * 5)');
sqlEquals(result.query, 'SELECT 2 * 3 + 4 * 5');
});

@@ -242,3 +242,3 @@ },

it('should produce a valid Subtract statement of two Multiplications', () => {
sqlEquals(result.query, 'SELECT (2 * 3) - (4 * 5)');
sqlEquals(result.query, 'SELECT 2 * 3 - 4 * 5');
});

@@ -264,3 +264,3 @@ },

it('should produce a valid Subtract statement of two Divisions', () => {
sqlEquals(result.query, 'SELECT (2 / 3) - (4 / 5)');
sqlEquals(result.query, 'SELECT 2 / 3 - 4 / 5');
});

@@ -267,0 +267,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc