UNPKG

ddl-manager

Version:

store postgres procedures and triggers in files

100 lines 3.68 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.replaceAmpArrayToAny = void 0; const assert_1 = __importDefault(require("assert")); const ast_1 = require("../../../ast"); // try using btree-index scan // input (cannot use btree-index): // from companies where new.companies_ids && array[ companies.id ] // from companies where new.companies_ids @> array[ companies.id ] // output (can use btree-index): // from companies where companies.id = any( new.companies_ids ) function replaceAmpArrayToAny(cacheFor, input) { if (!input.isBinary("&&") && !input.isBinary("@>") && !input.isBinary("<@")) { return input; } const [leftOperand, rightOperand] = input.getOperands(); const columnOperand = detectColumnOperand(leftOperand, rightOperand); const arrOperand = detectArrOperand(leftOperand, rightOperand); if (!columnOperand || !arrOperand) { return input; } const columnRefs = arrOperand.getColumnReferences(); const isCacheId = (columnRefs.length === 1 && columnRefs[0].name === "id" && columnRefs[0].tableReference.equal(cacheFor)); if (!isCacheId) { return input; } // cannot optimize if (input.isBinary("<@")) { if (columnOperand === leftOperand) { return input; } } if (input.isBinary("@>")) { if (columnOperand === rightOperand) { return input; } } const arrContent = executeArrayContent(arrOperand); const castingSQL = executeArrayCasting(arrOperand); const output = new ast_1.Expression([ arrContent, new ast_1.Operator("="), ast_1.UnknownExpressionElement.fromSql(`any( ${columnOperand}${castingSQL} )`, { [columnOperand.toString()]: columnOperand }) ]); return output; } exports.replaceAmpArrayToAny = replaceAmpArrayToAny; function detectColumnOperand(leftOperand, rightOperand) { if (leftOperand instanceof ast_1.ColumnReference) { return leftOperand; } if (rightOperand instanceof ast_1.ColumnReference) { return rightOperand; } } function detectArrOperand(leftOperand, rightOperand) { if (isArrayExpression(leftOperand)) { return leftOperand; } if (isArrayExpression(rightOperand)) { return rightOperand; } } function isArrayExpression(operand) { const operandSQL = operand.toString().trim().toLowerCase(); return (/^array\s*\[.*\](\s*::\s*(\w+)\[\])?$/.test(operandSQL)); } function executeArrayContent(anyOperand) { const matchResult = anyOperand.toString().match(/\[([^\]]+)\]/); assert_1.default.ok(matchResult && matchResult[1]); const columnsMap = {}; if (anyOperand instanceof ast_1.UnknownExpressionElement) { Object.assign(columnsMap, anyOperand.columnsMap); } else if (anyOperand instanceof ast_1.Expression) { for (const subElem of anyOperand.elements) { const subMap = subElem.columnsMap || {}; Object.assign(columnsMap, subMap); } } const arrContentSQL = matchResult[1].trim(); const arrContentElem = ast_1.UnknownExpressionElement.fromSql(arrContentSQL, columnsMap); return arrContentElem; } function executeArrayCasting(anyOperand) { if (!(anyOperand instanceof ast_1.Expression)) { return ""; } if (anyOperand.isBinary("::")) { const castType = anyOperand.elements[2]; return `::${castType}`; } return ""; } //# sourceMappingURL=replaceAmpArrayToAny.js.map