UNPKG

node-sql-parser

Version:
260 lines (259 loc) 10.4 kB
(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "./collate", "./constrain", "./expr", "./func", "./tables", "./util"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("./collate"), require("./constrain"), require("./expr"), require("./func"), require("./tables"), require("./util")); } else { var mod = { exports: {} }; factory(mod.exports, global.collate, global.constrain, global.expr, global.func, global.tables, global.util); global.column = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _collate, _constrain, _expr, _func, _tables, _util) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.arrayIndexToSQL = arrayIndexToSQL; _exports.asToSQL = asToSQL; _exports.columnDataType = columnDataType; _exports.columnDefinitionToSQL = columnDefinitionToSQL; _exports.columnOffsetToSQL = columnOffsetToSQL; _exports.columnOrderToSQL = columnOrderToSQL; _exports.columnRefToSQL = columnRefToSQL; _exports.columnReferenceDefinitionToSQL = columnReferenceDefinitionToSQL; _exports.columnToSQL = columnToSQL; _exports.columnsToSQL = columnsToSQL; _exports.fullTextSearchToSQL = fullTextSearchToSQL; _exports.getDual = getDual; function columnOffsetToSQL(column, isDual) { if (typeof column === 'string') return (0, _util.identifierToSql)(column, isDual); const { expr, offset, suffix } = column; const offsetExpr = offset && offset.map(offsetItem => ['[', offsetItem.name, `${offsetItem.name ? '(' : ''}`, (0, _util.literalToSQL)(offsetItem.value), `${offsetItem.name ? ')' : ''}`, ']'].filter(_util.hasVal).join('')).join(''); const result = [(0, _expr.exprToSQL)(expr), offsetExpr, suffix].filter(_util.hasVal).join(''); return result; } function arrayIndexToSQL(arrayIndexList) { if (!arrayIndexList || arrayIndexList.length === 0) return ''; const result = []; for (const arrayIndex of arrayIndexList) { let arrayIndexStr = arrayIndex.brackets ? `[${(0, _expr.exprToSQL)(arrayIndex.index)}]` : `${arrayIndex.notation}${(0, _expr.exprToSQL)(arrayIndex.index)}`; if (arrayIndex.property) arrayIndexStr = `${arrayIndexStr}.${(0, _util.literalToSQL)(arrayIndex.property)}`; result.push(arrayIndexStr); } return result.join(''); } function columnRefToSQL(expr) { const { array_index, as, column, collate, db, isDual, notations = [], options, schema, table, parentheses, suffix, order_by, subFields = [] } = expr; let str = column === '*' ? '*' : columnOffsetToSQL(column, isDual); const prefix = [db, schema, table].filter(_util.hasVal).map(val => `${typeof val === 'string' ? (0, _util.identifierToSql)(val) : (0, _expr.exprToSQL)(val)}`); let prefixStr = prefix[0]; if (prefixStr) { let i = 1; for (; i < prefix.length; ++i) { prefixStr = `${prefixStr}${notations[i] || '.'}${prefix[i]}`; } str = `${prefixStr}${notations[i] || '.'}${str}`; } str = [`${str}${arrayIndexToSQL(array_index)}`, ...subFields].join('.'); const result = [str, (0, _collate.collateToSQL)(collate), (0, _expr.exprToSQL)(options), (0, _util.commonOptionConnector)('AS', _expr.exprToSQL, as)]; result.push(typeof suffix === 'string' ? (0, _util.toUpper)(suffix) : (0, _expr.exprToSQL)(suffix)); result.push((0, _util.toUpper)(order_by)); const sql = result.filter(_util.hasVal).join(' '); return parentheses ? `(${sql})` : sql; } function columnDataType(definition) { if (!definition) return; const { dataType, length, suffix, scale, expr } = definition; const parentheses = length != null && true || false; let result = (0, _util.dataTypeToSQL)({ dataType, length, suffix, scale, parentheses }); if (expr) result += (0, _expr.exprToSQL)(expr); if (definition.array) { const arrayExpr = (0, _func.arrayDimensionToSymbol)(definition); const space = /^\[.*\]$/.test(arrayExpr) ? '' : ' '; result += [space, arrayExpr].join(''); } return result; } function columnReferenceDefinitionToSQL(referenceDefinition) { const reference = []; if (!referenceDefinition) return reference; const { definition, keyword, match, table, on_action: onAction } = referenceDefinition; reference.push((0, _util.toUpper)(keyword)); reference.push((0, _tables.tablesToSQL)(table)); reference.push(definition && `(${definition.map(col => (0, _expr.exprToSQL)(col)).join(', ')})`); reference.push((0, _util.toUpper)(match)); onAction.map(onRef => reference.push((0, _util.toUpper)(onRef.type), (0, _expr.exprToSQL)(onRef.value))); return reference.filter(_util.hasVal); } function generatedExpressionToSQL(generated) { if (!generated) return; const result = [(0, _util.toUpper)(generated.value), `(${(0, _expr.exprToSQL)(generated.expr)})`, (0, _util.toUpper)(generated.storage_type)]; return result.filter(_util.hasVal).join(' '); } function columnOption(definition) { const columnOpt = []; const { nullable, character_set: characterSet, check, comment, constraint, collate, storage, using, default_val: defaultOpt, generated, auto_increment: autoIncrement, unique: uniqueKey, primary_key: primaryKey, column_format: columnFormat, reference_definition: referenceDefinition, generated_by_default: generateByDefault } = definition; const nullSQL = [(0, _util.toUpper)(nullable && nullable.action), (0, _util.toUpper)(nullable && nullable.value)].filter(_util.hasVal).join(' '); if (!generated) columnOpt.push(nullSQL); if (defaultOpt) { const { type, value } = defaultOpt; columnOpt.push(type.toUpperCase(), (0, _expr.exprToSQL)(value)); } const { database } = (0, _util.getParserOpt)(); if (constraint) columnOpt.push((0, _util.toUpper)(constraint.keyword), (0, _util.literalToSQL)(constraint.constraint)); columnOpt.push((0, _constrain.constraintDefinitionToSQL)(check)); columnOpt.push(generatedExpressionToSQL(generated)); if (generated) columnOpt.push(nullSQL); columnOpt.push((0, _util.autoIncrementToSQL)(autoIncrement), (0, _util.toUpper)(primaryKey), (0, _util.toUpper)(uniqueKey), (0, _util.literalToSQL)(generateByDefault), (0, _util.commentToSQL)(comment)); columnOpt.push(...(0, _util.commonTypeValue)(characterSet)); if (database.toLowerCase() !== 'sqlite') columnOpt.push((0, _expr.exprToSQL)(collate)); columnOpt.push(...(0, _util.commonTypeValue)(columnFormat)); columnOpt.push(...(0, _util.commonTypeValue)(storage)); columnOpt.push(...columnReferenceDefinitionToSQL(referenceDefinition)); columnOpt.push((0, _util.commonOptionConnector)('USING', _expr.exprToSQL, using)); return columnOpt.filter(_util.hasVal).join(' '); } function columnOrderToSQL(columnOrder) { const { column, collate, nulls, opclass, order_by } = columnOrder; const columnExpr = typeof column === 'string' ? { type: 'column_ref', table: columnOrder.table, column } : columnOrder; columnExpr.collate = null; const result = [(0, _expr.exprToSQL)(columnExpr), (0, _expr.exprToSQL)(collate), opclass, (0, _util.toUpper)(order_by), (0, _util.toUpper)(nulls)]; return result.filter(_util.hasVal).join(' '); } function columnDefinitionToSQL(columnDefinition) { const column = []; const name = columnRefToSQL(columnDefinition.column); const dataType = columnDataType(columnDefinition.definition); column.push(name); column.push(dataType); column.push(columnOption(columnDefinition)); return column.filter(_util.hasVal).join(' '); } function asToSQL(asStr) { if (!asStr) return ''; if (typeof asStr === 'object') return ['AS', (0, _expr.exprToSQL)(asStr)].join(' '); return ['AS', /^(`?)[a-z_][0-9a-z_]*(`?)$/i.test(asStr) ? (0, _util.identifierToSql)(asStr) : (0, _util.columnIdentifierToSql)(asStr)].join(' '); } function fullTextSearchToSQL(expr) { const { against, as, columns, match, mode } = expr; const matchExpr = [(0, _util.toUpper)(match), `(${columns.map(col => columnRefToSQL(col)).join(', ')})`].join(' '); const againstExpr = [(0, _util.toUpper)(against), ['(', (0, _expr.exprToSQL)(expr.expr), mode && ` ${(0, _util.literalToSQL)(mode)}`, ')'].filter(_util.hasVal).join('')].join(' '); return [matchExpr, againstExpr, asToSQL(as)].filter(_util.hasVal).join(' '); } function columnToSQL(column, isDual) { const { expr, type } = column; if (type === 'cast') return (0, _func.castToSQL)(column); if (isDual) expr.isDual = isDual; let str = (0, _expr.exprToSQL)(expr); const { expr_list: exprList } = column; if (exprList) { const result = [str]; const columnsStr = exprList.map(col => columnToSQL(col, isDual)).join(', '); result.push([(0, _util.toUpper)(type), type && '(', columnsStr, type && ')'].filter(_util.hasVal).join('')); return result.filter(_util.hasVal).join(' '); } if (expr.parentheses && Reflect.has(expr, 'array_index') && expr.type !== 'cast') str = `(${str})`; if (expr.array_index && expr.type !== 'column_ref' && expr.type !== 'function') { str = `${str}${arrayIndexToSQL(expr.array_index)}`; } return [str, asToSQL(column.as)].filter(_util.hasVal).join(' '); } function getDual(tables) { const baseTable = Array.isArray(tables) && tables[0]; if (baseTable && baseTable.type === 'dual') return true; return false; } /** * Stringify column expressions * * @param {Array} columns * @return {string} */ function columnsToSQL(columns, tables) { if (!columns || columns === '*') return columns; const isDual = getDual(tables); return columns.map(col => columnToSQL(col, isDual)).join(', '); } });