fix(PostgreSQL): various issues in query results

This commit is contained in:
Fabio Di Stasio 2021-03-19 18:49:26 +01:00
parent d465e18dba
commit fccfe92453
6 changed files with 75 additions and 44 deletions

View File

@ -73,6 +73,7 @@
"mysql2": "^2.2.5",
"node-sql-parser": "^3.1.0",
"pg": "^8.5.1",
"pgsql-ast-parser": "^7.0.2",
"source-map-support": "^0.5.16",
"spectre.css": "^0.5.9",
"v-mask": "^2.2.4",

View File

@ -19,7 +19,7 @@ module.exports = {
schedulers: false,
// Settings
databaseEdit: false,
tableSettings: false,
tableSettings: true,
viewSettings: false,
triggerSettings: false,
routineSettings: false,

View File

@ -118,7 +118,7 @@ module.exports = [
group: 'time',
types: [
{
name: 'TIMESTAMP',
name: 'TIMESTAMP WITHOUT TIME ZONE',
length: false,
unsigned: false
},

View File

@ -1,5 +1,5 @@
module.exports = [
'PRIMARY',
'INDEX',
'KEY',
'UNIQUE'
];

View File

@ -1,6 +1,6 @@
'use strict';
import pg, { Pool, Client, types } from 'pg';
import { Parser } from 'node-sql-parser';
import { parse } from 'pgsql-ast-parser';
import { AntaresCore } from '../AntaresCore';
import dataTypes from 'common/data-types/postgresql';
@ -322,6 +322,27 @@ export class PostgreSQLClient extends AntaresCore {
});
}
/**
*
* @param {Number} id
* @returns {Array}
*/
async getTableByIDs (ids) {
const { rows } = await this.raw(`
SELECT relid AS tableid, relname, schemaname FROM pg_statio_all_tables WHERE relid IN (${ids})
UNION
SELECT pg_class.oid AS tableid,relname, nspname AS schemaname FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE pg_class.oid IN (${ids})
`);
return rows.reduce((acc, curr) => {
acc[curr.tableid] = {
table: curr.relname,
schema: curr.schemaname
};
return acc;
}, {});
}
/**
* @param {Object} params
* @param {String} params.schema
@ -330,34 +351,28 @@ export class PostgreSQLClient extends AntaresCore {
* @memberof PostgreSQLClient
*/
async getKeyUsage ({ schema, table }) {
const { rows } = await this
.select('*')
.schema('information_schema')
.from('key_column_usage')
.where({ TABLE_SCHEMA: `= '${schema}'`, TABLE_NAME: `= '${table}'` })
.run();
const { rows: extras } = await this
.select('*')
.schema('information_schema')
.from('referential_constraints')
.where({ constraint_schema: `= '${schema}'`, constraint_name: `= '${table}'` })
.run();
const { rows } = await this.raw(`
SELECT *
FROM information_schema.key_column_usage
JOIN information_schema.referential_constraints ON
referential_constraints.constraint_name = key_column_usage.constraint_name
WHERE table_schema = '${schema}'
AND table_name = '${table}'
`);
return rows.map(field => {
const extra = extras.find(x => x.CONSTRAINT_NAME === field.CONSTRAINT_NAME);
return {
schema: field.TABLE_SCHEMA,
table: field.TABLE_NAME,
field: field.COLUMN_NAME,
position: field.ORDINAL_POSITION,
constraintPosition: field.POSITION_IN_UNIQUE_CONSTRAINT,
constraintName: field.CONSTRAINT_NAME,
schema: field.table_schema,
table: field.table_name,
field: field.column_name,
position: field.ordinal_position,
constraintPosition: field.position_inUnique_constraint,
constraintName: field.constraint_name,
refSchema: field.REFERENCED_TABLE_SCHEMA,
refTable: field.REFERENCED_TABLE_NAME,
refField: field.REFERENCED_COLUMN_NAME,
onUpdate: extra ? extra.UPDATE_RULE : '',
onDelete: extra ? extra.DELETE_RULE : ''
onUpdate: field.update_rule,
onDelete: field.delete_rule
};
});
}
@ -1228,22 +1243,38 @@ export class PostgreSQLClient extends AntaresCore {
let keysArr = [];
const { rows, report, fields, keys, duration } = await new Promise((resolve, reject) => {
this._connection.query({ text: query }, async (err, res) => {
this._connection.query({
rowMode: args.nest ? 'array' : null,
text: query
}, async (err, res) => {
timeStop = new Date();
if (err)
reject(err);
else {
const { rows, fields } = res;
const queryResult = rows;
const parser = new Parser();
let ast;
try {
ast = parser.astify(query);
}
catch (err) {
try {
[ast] = parse(query);
}
catch (err) {}
const { rows, fields } = res;
let queryResult;
if (args.nest) {
const tablesID = [...new Set(fields.map(field => field.tableID))].toString();
const tablesInfo = await this.getTableByIDs(tablesID);
queryResult = rows.map(row => {
return row.reduce((acc, curr, i) => {
const table = tablesInfo[fields[i].tableID].table;
acc[`${table}.${fields[i].name}`] = curr;
return acc;
}, {});
});
}
else
queryResult = rows;
let remappedFields = fields
? fields.map(field => {
@ -1251,26 +1282,24 @@ export class PostgreSQLClient extends AntaresCore {
return false;
return {
...field,
name: field.name,
alias: field.name,
schema: ast && ast.from ? ast.from[0].db : this._schema,
table: ast && ast.from ? ast.from[0].table : null,
schema: ast && ast.from && 'schema' in ast.from[0] ? ast.from[0].schema : this._schema,
table: ast && ast.from ? ast.from[0].name : null,
tableAlias: ast && ast.from ? ast.from[0].as : null,
orgTable: ast && ast.from ? ast.from[0].table : null,
type: this.types[field.dataTypeID]
orgTable: ast && ast.from ? ast.from[0].name : null,
type: this.types[field.dataTypeID] || field.format
};
}).filter(Boolean)
: [];
if (args.details) {
let cachedTable;
if (remappedFields.length) {
paramsArr = remappedFields.map(field => {
if (field.table) cachedTable = field.table;// Needed for some queries on information_schema
return {
table: field.table || cachedTable,
schema: field.schema || 'INFORMATION_SCHEMA'
table: field.table,
schema: field.schema
};
}).filter((val, i, arr) => arr.findIndex(el => el.schema === val.schema && el.table === val.table) === i);

View File

@ -15,7 +15,8 @@
}
&.key-mul,
&.key-INDEX {
&.key-INDEX,
&.key-KEY {
color: palegreen;
}