ddl-manager
Version:
store postgres procedures and triggers in files
68 lines • 2.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.replaceOperatorAnyToIndexedOperator = void 0;
const ast_1 = require("../../../ast");
// try using gin-index scan
// input (cannot use gin-index):
// from companies where orders.id = any(companies.order_ids)
// output (can use gin-index):
// from companies where array[ orders.id_client ] && companies.order_ids
function replaceOperatorAnyToIndexedOperator(cacheFor, input) {
if (!input.isBinary("=")) {
return input;
}
const [leftOperand, rightOperand] = input.getOperands();
const columnOperand = detectColumnOperand(leftOperand, rightOperand);
const anyOperand = detectAnyOperand(leftOperand, rightOperand);
if (!columnOperand || !anyOperand) {
return input;
}
if (columnOperand.tableReference.equal(cacheFor)) {
return input;
}
const arrOperand = executeAnyContent(anyOperand);
let arrayLiteral = `ARRAY[${columnOperand}]`;
const arrColumns = arrOperand.getColumnReferences();
if (arrColumns.length === 1) {
const table = arrColumns[0].tableReference.table;
const columnName = arrColumns[0].name;
arrayLiteral = `cm_build_array_for((null::${table.schema}.${table.name}).${columnName}, ${columnOperand})`;
}
const output = new ast_1.Expression([
arrOperand,
new ast_1.Operator("&&"),
// TODO: cast bigint to same type with array
// array[]::bigint[] && some_bigint_ids
ast_1.UnknownExpressionElement.fromSql(arrayLiteral, { [columnOperand.toString()]: columnOperand })
]);
return output;
}
exports.replaceOperatorAnyToIndexedOperator = replaceOperatorAnyToIndexedOperator;
function detectColumnOperand(leftOperand, rightOperand) {
if (leftOperand instanceof ast_1.ColumnReference) {
return leftOperand;
}
if (rightOperand instanceof ast_1.ColumnReference) {
return rightOperand;
}
}
function detectAnyOperand(leftOperand, rightOperand) {
if (isAny(leftOperand)) {
return leftOperand;
}
if (isAny(rightOperand)) {
return rightOperand;
}
}
function isAny(operand) {
return (/^any\s*\(.*\)$/.test(operand.toString().trim().toLowerCase()));
}
function executeAnyContent(anyOperand) {
const sql = anyOperand.toString()
.trim()
.replace(/^any\s*\(/, "")
.replace(/\)$/, "");
const arrOperand = ast_1.UnknownExpressionElement.fromSql(sql, anyOperand.columnsMap);
return arrOperand;
}
//# sourceMappingURL=replaceOperatorAnyToIndexedOperator.js.map