Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

console: surround varchar, character (bpchar), char and name type value with single quotes (close #4371) #4423

Merged
merged 5 commits into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The order, collapsed state of columns and page size is now persisted across page
- console: decouple data rows and count fetch in data browser to account for really large tables (close #3793) (#4269)
- console: update cookie policy for API calls to "same-origin"
- console: redirect to /:table/browse from /:table (close #4330) (#4374)
- console: surround varchar type value with single quotes (close #4371) (#4423)
- docs: add One-Click Render deployment guide (close #3683) (#4209)
- server: reserved keywords in column references break parser (fix #3597) #3927
- server: fix postgres specific error message that exposed database type on invalid query parameters (#4294)
Expand Down
4 changes: 2 additions & 2 deletions console/src/components/Services/Data/Add/AddActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { UPDATE_MIGRATION_STATUS_ERROR } from '../../../Main/Actions';
import { setTable } from '../DataActions.js';

import { isPostgresFunction } from '../utils';
import { isColTypeQuote, isPostgresFunction } from '../utils';
import { sqlEscapeText } from '../../../Common/utils/sqlUtils';
import { getRunSqlQuery } from '../../../Common/utils/v1QueryUtils';
import { getTableModifyRoute } from '../../../Common/utils/routesUtils';
Expand Down Expand Up @@ -188,7 +188,7 @@ const createTableSql = () => {
currentCols[i].default.value !== ''
) {
if (
currentCols[i].type === 'text' &&
isColTypeQuote(currentCols[i].type) &&
!isPostgresFunction(currentCols[i].default.value)
) {
// if a column type is text and if it has a non-func default value, add a single quote by default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
getUniqueConstraintName,
} from '../Common/Components/utils';

import { isPostgresFunction } from '../utils';
import { isColTypeQuote, isPostgresFunction } from '../utils';
import {
sqlEscapeText,
getCreateCheckConstraintSql,
Expand Down Expand Up @@ -797,7 +797,7 @@ ${trigger.action_timing} ${trigger.event_manipulation} ON "${tableSchema}"."${ta
FOR EACH ${trigger.action_orientation} ${trigger.action_statement};`;

if (trigger.comment) {
downMigrationSql += `COMMENT ON TRIGGER "${triggerName}" ON "${tableSchema}"."${tableName}"
downMigrationSql += `COMMENT ON TRIGGER "${triggerName}" ON "${tableSchema}"."${tableName}"
IS ${sqlEscapeText(trigger.comment)};`;
}
const migrationDown = [getRunSqlQuery(downMigrationSql)];
Expand Down Expand Up @@ -1182,7 +1182,7 @@ const addColSql = (
let defWithQuotes = "''";

const checkIfFunctionFormat = isPostgresFunction(colDefault);
if (colType === 'text' && colDefault !== '' && !checkIfFunctionFormat) {
if (isColTypeQuote(colType) && colDefault !== '' && !checkIfFunctionFormat) {
defWithQuotes = "'" + colDefault + "'";
} else {
defWithQuotes = colDefault;
Expand Down Expand Up @@ -1544,11 +1544,11 @@ const saveColumnChangesSql = (colName, column, onSuccess) => {
}

const colDefaultWithQuotes =
colType === 'text' && !isPostgresFunction(colDefault)
isColTypeQuote(colType) && !isPostgresFunction(colDefault)
? `'${colDefault}'`
: colDefault;
const originalColDefaultWithQuotes =
colType === 'text' && !isPostgresFunction(originalColDefault)
isColTypeQuote(colType) && !isPostgresFunction(originalColDefault)
? `'${originalColDefault}'`
: originalColDefault;

Expand Down
99 changes: 51 additions & 48 deletions console/src/components/Services/Data/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,23 +315,23 @@ const generateWhereClause = options => {
export const fetchTrackedTableFkQuery = options => {
const whereQuery = generateWhereClause(options);

const runSql = `select
const runSql = `select
COALESCE(
json_agg(
row_to_json(info)
),
),
'[]' :: JSON
) AS tables
FROM
) AS tables
FROM
(
select
hdb_fkc.*,
fk_ref_table.table_name IS NOT NULL AS is_ref_table_tracked
from
hdb_catalog.hdb_table AS ist
JOIN hdb_catalog.hdb_foreign_key_constraint AS hdb_fkc ON hdb_fkc.table_schema = ist.table_schema
and hdb_fkc.table_name = ist.table_name
LEFT OUTER JOIN hdb_catalog.hdb_table AS fk_ref_table ON fk_ref_table.table_schema = hdb_fkc.ref_table_table_schema
hdb_fkc.*,
fk_ref_table.table_name IS NOT NULL AS is_ref_table_tracked
from
hdb_catalog.hdb_table AS ist
JOIN hdb_catalog.hdb_foreign_key_constraint AS hdb_fkc ON hdb_fkc.table_schema = ist.table_schema
and hdb_fkc.table_name = ist.table_name
LEFT OUTER JOIN hdb_catalog.hdb_table AS fk_ref_table ON fk_ref_table.table_schema = hdb_fkc.ref_table_table_schema
and fk_ref_table.table_name = hdb_fkc.ref_table
${whereQuery}
) as info
Expand All @@ -346,24 +346,24 @@ FROM
export const fetchTrackedTableReferencedFkQuery = options => {
const whereQuery = generateWhereClause(options);

const runSql = `select
const runSql = `select
COALESCE(
json_agg(
row_to_json(info)
),
),
'[]' :: JSON
) AS tables
FROM
) AS tables
FROM
(
select DISTINCT ON (hdb_fkc.constraint_oid)
hdb_fkc.*,
hdb_fkc.*,
fk_ref_table.table_name IS NOT NULL AS is_table_tracked,
hdb_uc.constraint_name IS NOT NULL AS is_unique
from
hdb_catalog.hdb_table AS ist
JOIN hdb_catalog.hdb_foreign_key_constraint AS hdb_fkc ON hdb_fkc.ref_table_table_schema = ist.table_schema
and hdb_fkc.ref_table = ist.table_name
LEFT OUTER JOIN hdb_catalog.hdb_table AS fk_ref_table ON fk_ref_table.table_schema = hdb_fkc.table_schema
from
hdb_catalog.hdb_table AS ist
JOIN hdb_catalog.hdb_foreign_key_constraint AS hdb_fkc ON hdb_fkc.ref_table_table_schema = ist.table_schema
and hdb_fkc.ref_table = ist.table_name
LEFT OUTER JOIN hdb_catalog.hdb_table AS fk_ref_table ON fk_ref_table.table_schema = hdb_fkc.table_schema
and fk_ref_table.table_name = hdb_fkc.table_name
LEFT OUTER JOIN hdb_catalog.hdb_unique_constraint AS hdb_uc ON hdb_uc.table_schema = hdb_fkc.table_schema
and hdb_uc.table_name = hdb_fkc.table_name and ARRAY(select json_array_elements_text(hdb_uc.columns) ORDER BY json_array_elements_text) = ARRAY(select json_object_keys(hdb_fkc.column_mapping) ORDER BY json_object_keys)
Expand All @@ -382,36 +382,36 @@ export const fetchTableListQuery = options => {

// TODO: optimise this. Multiple OUTER JOINS causes data bloating
const runSql = `
select
select
COALESCE(
json_agg(
row_to_json(info)
),
),
'[]' :: JSON
) AS tables
FROM
) AS tables
FROM
(
select
ist.table_schema,
select
ist.table_schema,
ist.table_name,
ist.table_type,
obj_description(
(
quote_ident(ist.table_schema) || '.' || quote_ident(ist.table_name)
):: regclass,
):: regclass,
'pg_class'
) AS comment,
) AS comment,
COALESCE(json_agg(
DISTINCT row_to_json(is_columns) :: JSONB || jsonb_build_object(
'comment',
(
SELECT
SELECT
pg_catalog.col_description(
c.oid, is_columns.ordinal_position :: int
)
FROM
pg_catalog.pg_class c
WHERE
)
FROM
pg_catalog.pg_class c
WHERE
c.oid = (quote_ident(ist.table_schema) || '.' || quote_ident(ist.table_name)):: regclass :: oid
AND c.relname = is_columns.table_name
)
Expand All @@ -421,27 +421,27 @@ FROM
DISTINCT row_to_json(is_triggers) :: JSONB || jsonb_build_object(
'comment',
(
SELECT description FROM pg_description JOIN pg_trigger ON pg_description.objoid = pg_trigger.oid
WHERE
tgname = is_triggers.trigger_name
SELECT description FROM pg_description JOIN pg_trigger ON pg_description.objoid = pg_trigger.oid
WHERE
tgname = is_triggers.trigger_name
AND tgrelid = (quote_ident(is_triggers.event_object_schema) || '.' || quote_ident(is_triggers.event_object_table)):: regclass :: oid
)
)
) FILTER (WHERE is_triggers.trigger_name IS NOT NULL), '[]' :: JSON) AS triggers,
row_to_json(is_views) AS view_info
FROM
information_schema.tables AS ist
LEFT OUTER JOIN information_schema.columns AS is_columns ON
is_columns.table_schema = ist.table_schema
AND is_columns.table_name = ist.table_name
FROM
information_schema.tables AS ist
LEFT OUTER JOIN information_schema.columns AS is_columns ON
is_columns.table_schema = ist.table_schema
AND is_columns.table_name = ist.table_name
LEFT OUTER JOIN information_schema.views AS is_views ON is_views.table_schema = ist.table_schema
AND is_views.table_name = ist.table_name
LEFT OUTER JOIN information_schema.triggers AS is_triggers ON
is_triggers.event_object_schema = ist.table_schema AND
LEFT OUTER JOIN information_schema.triggers AS is_triggers ON
is_triggers.event_object_schema = ist.table_schema AND
is_triggers.event_object_table = ist.table_name
${whereQuery}
GROUP BY
ist.table_schema,
${whereQuery}
GROUP BY
ist.table_schema,
ist.table_name,
ist.table_type,
is_views.*
Expand Down Expand Up @@ -617,7 +617,7 @@ export const commonDataTypes = [
* Filter types whose typename is unknown and type category is not 'Pseudo' and it is valid and available to be used
* */
export const fetchColumnTypesQuery = `
SELECT
SELECT
string_agg(t.typname, ',') as "Type Name",
string_agg(pg_catalog.format_type(t.oid, NULL), ',') as "Display Name",
string_agg(coalesce(pg_catalog.obj_description(t.oid, 'pg_type'), ''), ':') as "Descriptions",
Expand Down Expand Up @@ -667,3 +667,6 @@ WHERE
AND relname = '${tableName}';
`;
};

export const isColTypeQuote = colType =>
colType === 'text' || colType === 'varchar';