mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 11:55:05 +03:00
chore: add source and description labels to all dashboard SQL queries
Adds `-- source: dashboard` and `-- description: ...` comment headers to all SQL queries in pg-meta to make it easier to identify and trace queries originating from the dashboard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
ebf9bc4955
commit
58b6aa8d78
75 files changed
+313
-69
No files matched your search
@@ -63,7 +63,10 @@ function list({
|
||||
sql: SafeSqlFragment
|
||||
zod: typeof pgColumnPrivilegesArrayZod
|
||||
} {
|
||||
let sql = safeSql`
|
||||
let sql =
|
||||
safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all column privileges with metadata
|
||||
with column_privileges as (${COLUMN_PRIVILEGES_SQL})
|
||||
select *
|
||||
from column_privileges
|
||||
@@ -102,7 +105,10 @@ function list({
|
||||
|
||||
type ColumnPrivilegesGrant = z.infer<typeof privilegeGrant>
|
||||
function grant(grants: ColumnPrivilegesGrant[]): { sql: SafeSqlFragment } {
|
||||
const sql = safeSql`
|
||||
const sql =
|
||||
safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Grant column privilege on table
|
||||
do $$
|
||||
declare
|
||||
col record;
|
||||
@@ -134,6 +140,8 @@ end $$;
|
||||
type ColumnPrivilegesRevoke = Omit<ColumnPrivilegesGrant, 'isGrantable'>
|
||||
function revoke(revokes: ColumnPrivilegesRevoke[]): { sql: SafeSqlFragment } {
|
||||
const sql = safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Revoke column privilege from table
|
||||
do $$
|
||||
declare
|
||||
col record;
|
||||
|
||||
@@ -50,6 +50,8 @@ function list({
|
||||
zod: typeof pgColumnArrayZod
|
||||
} {
|
||||
let sql = `
|
||||
-- source: dashboard
|
||||
-- description: List all columns with metadata
|
||||
with
|
||||
columns as (${COLUMNS_SQL})
|
||||
select
|
||||
@@ -99,7 +101,7 @@ function retrieve(identifier: ColumnIdentifier): {
|
||||
sql: string
|
||||
zod: typeof pgColumnOptionalZod
|
||||
} {
|
||||
const sql = `WITH columns AS (${COLUMNS_SQL}) SELECT * FROM columns WHERE ${getIdentifierWhereClause(identifier)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single column by identifier\nWITH columns AS (${COLUMNS_SQL}) SELECT * FROM columns WHERE ${getIdentifierWhereClause(identifier)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgColumnOptionalZod,
|
||||
@@ -167,6 +169,8 @@ function create({
|
||||
: `COMMENT ON COLUMN ${ident(schema)}.${ident(table)}.${ident(name)} IS ${literal(comment)}`
|
||||
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Create a new column
|
||||
ALTER TABLE ${ident(schema)}.${ident(table)} ADD COLUMN ${ident(name)} ${typeIdent(type)}
|
||||
${defaultValueClause}
|
||||
${isNullableClause}
|
||||
@@ -376,6 +380,8 @@ $$;
|
||||
// NOTE: nameSql must be last. defaultValueSql must be after typeSql.
|
||||
// identitySql must be after isNullableSql.
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Update column properties
|
||||
BEGIN;
|
||||
${isNullableSql}
|
||||
${typeSql}
|
||||
@@ -394,7 +400,7 @@ function remove(
|
||||
column: Pick<PGColumn, 'name' | 'schema' | 'table'>,
|
||||
{ cascade = false } = {}
|
||||
): { sql: string } {
|
||||
const sql = `ALTER TABLE ${ident(column.schema)}.${ident(column.table)} DROP COLUMN ${ident(
|
||||
const sql = `-- source: dashboard\n-- description: Drop a column\nALTER TABLE ${ident(column.schema)}.${ident(column.table)} DROP COLUMN ${ident(
|
||||
column.name
|
||||
)} ${cascade ? 'CASCADE' : 'RESTRICT'};`
|
||||
return { sql }
|
||||
|
||||
@@ -36,7 +36,9 @@ function list({
|
||||
sql: string
|
||||
zod: typeof pgConfigArrayZod
|
||||
} {
|
||||
let sql = CONFIG_SQL
|
||||
let sql =
|
||||
`-- source: dashboard\n-- description: List all configuration settings with metadata\n` +
|
||||
CONFIG_SQL
|
||||
if (limit) {
|
||||
sql += ` LIMIT ${limit}`
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ function list({
|
||||
sql: string
|
||||
zod: typeof pgExtensionArrayZod
|
||||
} {
|
||||
let sql = EXTENSIONS_SQL
|
||||
let sql =
|
||||
`-- source: dashboard\n-- description: List all extensions with metadata\n` + EXTENSIONS_SQL
|
||||
if (limit) {
|
||||
sql = `${sql} LIMIT ${limit}`
|
||||
}
|
||||
@@ -43,7 +44,7 @@ function retrieve({ name }: { name: string }): {
|
||||
sql: string
|
||||
zod: typeof pgExtensionOptionalZod
|
||||
} {
|
||||
const sql = `${EXTENSIONS_SQL} WHERE name = ${literal(name)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single extension by identifier\n${EXTENSIONS_SQL} WHERE name = ${literal(name)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgExtensionOptionalZod,
|
||||
@@ -61,6 +62,8 @@ function create({ name, schema, version, cascade = false }: ExtensionCreateParam
|
||||
sql: string
|
||||
} {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Create a new extension
|
||||
CREATE EXTENSION ${ident(name)}
|
||||
${schema === undefined ? '' : `SCHEMA ${ident(schema)}`}
|
||||
${version === undefined ? '' : `VERSION ${literal(version)}`}
|
||||
@@ -87,7 +90,7 @@ function update(
|
||||
const schemaSql =
|
||||
schema === undefined ? '' : `ALTER EXTENSION ${ident(name)} SET SCHEMA ${ident(schema)};`
|
||||
|
||||
const sql = `BEGIN; ${updateSql} ${schemaSql} COMMIT;`
|
||||
const sql = `-- source: dashboard\n-- description: Update extension properties\nBEGIN; ${updateSql} ${schemaSql} COMMIT;`
|
||||
return { sql }
|
||||
}
|
||||
|
||||
@@ -96,7 +99,7 @@ type ExtensionRemoveParams = {
|
||||
}
|
||||
|
||||
function remove(name: string, { cascade = false }: ExtensionRemoveParams = {}): { sql: string } {
|
||||
const sql = `DROP EXTENSION ${ident(name)} ${cascade ? 'CASCADE' : 'RESTRICT'};`
|
||||
const sql = `-- source: dashboard\n-- description: Drop an extension\nDROP EXTENSION ${ident(name)} ${cascade ? 'CASCADE' : 'RESTRICT'};`
|
||||
return { sql }
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,8 @@ const generateEnrichedForeignTablesSql = ({
|
||||
}: {
|
||||
includeColumns?: boolean
|
||||
}) => safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all foreign tables with metadata
|
||||
with foreign_tables as (${FOREIGN_TABLES_SQL})
|
||||
${includeColumns ? safeSql`, columns as (${COLUMNS_SQL})` : safeSql``}
|
||||
select
|
||||
|
||||
@@ -59,6 +59,8 @@ export function list({
|
||||
zod: typeof pgFunctionArrayZod
|
||||
} {
|
||||
let sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all functions with metadata
|
||||
with f as (
|
||||
${FUNCTIONS_SQL}
|
||||
)
|
||||
@@ -115,6 +117,8 @@ export function retrieve({
|
||||
}): FunctionsRetrieveReturn {
|
||||
if (id) {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Retrieve a single function by identifier
|
||||
with f as (
|
||||
${FUNCTIONS_SQL}
|
||||
)
|
||||
@@ -127,7 +131,7 @@ export function retrieve({
|
||||
zod: pgFunctionOptionalZod,
|
||||
}
|
||||
} else if (name && schema && args) {
|
||||
const sql = /* SQL */ `with f as (
|
||||
const sql = /* SQL */ `-- source: dashboard\n-- description: Retrieve a single function by identifier\nwith f as (
|
||||
${FUNCTIONS_SQL}
|
||||
)
|
||||
select
|
||||
@@ -196,6 +200,8 @@ function _generateCreateFunctionSql(
|
||||
{ replace = false } = {}
|
||||
): string {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create a new function
|
||||
CREATE ${replace ? 'OR REPLACE' : ''} FUNCTION ${ident(schema!)}.${ident(name!)}(${
|
||||
args?.join(', ') || ''
|
||||
})
|
||||
@@ -287,6 +293,8 @@ export function update(currentFunc: PGFunction, { name, schema, definition }: PG
|
||||
: ''
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Update function properties
|
||||
DO LANGUAGE plpgsql $$
|
||||
BEGIN
|
||||
IF ${typeof definition === 'string' ? 'TRUE' : 'FALSE'} THEN
|
||||
@@ -325,7 +333,7 @@ export const pgFunctionDeleteZod = z.object({
|
||||
export type PGFunctionDelete = z.infer<typeof pgFunctionDeleteZod>
|
||||
|
||||
export function remove(func: PGFunction, { cascade = false }: PGFunctionDelete = {}) {
|
||||
const sql = /* SQL */ `DROP FUNCTION ${ident(func.schema)}.${ident(func.name)}
|
||||
const sql = /* SQL */ `-- source: dashboard\n-- description: Drop a function\nDROP FUNCTION ${ident(func.schema)}.${ident(func.name)}
|
||||
(${func.identity_argument_types})
|
||||
${cascade ? 'CASCADE' : 'RESTRICT'};`
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@ function list({
|
||||
zod: typeof pgIndexArrayZod
|
||||
} {
|
||||
let sql = `
|
||||
-- source: dashboard
|
||||
-- description: List all indexes with metadata
|
||||
with indexes as (${INDEXES_SQL})
|
||||
select *
|
||||
from indexes
|
||||
@@ -84,6 +86,8 @@ function list({
|
||||
|
||||
function retrieve({ id }: { id: number }): { sql: string; zod: typeof pgIndexOptionalZod } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Retrieve a single index by identifier
|
||||
with indexes as (${INDEXES_SQL})
|
||||
select *
|
||||
from indexes
|
||||
|
||||
@@ -101,6 +101,8 @@ const generateEnrichedMaterializedViewsSql = ({
|
||||
}: {
|
||||
includeColumns?: boolean
|
||||
}) => safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all materialized views with metadata
|
||||
with materialized_views as (${MATERIALIZED_VIEWS_SQL})
|
||||
${includeColumns ? safeSql`, columns as (${COLUMNS_SQL})` : safeSql``}
|
||||
select
|
||||
|
||||
@@ -56,6 +56,8 @@ function list({
|
||||
zod: typeof pgPolicyArrayZod
|
||||
} {
|
||||
let sql = `
|
||||
-- source: dashboard
|
||||
-- description: List all policies with metadata
|
||||
with policies as (${POLICIES_SQL})
|
||||
select *
|
||||
from policies
|
||||
@@ -84,7 +86,7 @@ function retrieve(identifier: PolicyIdentifier): {
|
||||
sql: string
|
||||
zod: typeof pgPolicyOptionalZod
|
||||
} {
|
||||
const sql = `with policies as (${POLICIES_SQL}) select * from policies where ${getIdentifierWhereClause(identifier)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single policy by identifier\nwith policies as (${POLICIES_SQL}) select * from policies where ${getIdentifierWhereClause(identifier)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgPolicyOptionalZod,
|
||||
@@ -113,6 +115,8 @@ function create({
|
||||
roles = ['public'],
|
||||
}: PolicyCreateParams): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Create a new policy
|
||||
create policy ${ident(name)} on ${ident(schema)}.${ident(table)}
|
||||
as ${action}
|
||||
for ${command}
|
||||
@@ -142,13 +146,13 @@ function update(
|
||||
const rolesSql = roles === undefined ? '' : `${alter} TO ${roles.map(ident).join(',')};`
|
||||
|
||||
// nameSql must be last
|
||||
const sql = `BEGIN; ${definitionSql} ${checkSql} ${rolesSql} ${nameSql} COMMIT;`
|
||||
const sql = `-- source: dashboard\n-- description: Update policy properties\nBEGIN; ${definitionSql} ${checkSql} ${rolesSql} ${nameSql} COMMIT;`
|
||||
|
||||
return { sql }
|
||||
}
|
||||
|
||||
function remove(identifier: Pick<PGPolicy, 'name' | 'schema' | 'table'>): { sql: string } {
|
||||
const sql = `DROP POLICY ${ident(identifier.name)} ON ${ident(identifier.schema)}.${ident(
|
||||
const sql = `-- source: dashboard\n-- description: Drop a policy\nDROP POLICY ${ident(identifier.name)} ON ${ident(identifier.schema)}.${ident(
|
||||
identifier.table
|
||||
)};`
|
||||
return { sql }
|
||||
|
||||
@@ -35,7 +35,7 @@ function list({
|
||||
sql: string
|
||||
zod: typeof pgPublicationArrayZod
|
||||
} {
|
||||
let sql = `with publications as (${PUBLICATIONS_SQL}) select * from publications`
|
||||
let sql = `-- source: dashboard\n-- description: List all publications with metadata\nwith publications as (${PUBLICATIONS_SQL}) select * from publications`
|
||||
if (limit) {
|
||||
sql += ` limit ${limit}`
|
||||
}
|
||||
@@ -63,7 +63,7 @@ function retrieve(identifier: PublicationIdentifier): {
|
||||
sql: string
|
||||
zod: typeof pgPublicationOptionalZod
|
||||
} {
|
||||
const sql = `with publications as (${PUBLICATIONS_SQL}) select * from publications where ${getIdentifierWhereClause(identifier)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single publication by identifier\nwith publications as (${PUBLICATIONS_SQL}) select * from publications where ${getIdentifierWhereClause(identifier)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgPublicationOptionalZod,
|
||||
@@ -113,6 +113,8 @@ function create({
|
||||
if (publish_truncate) publishOps.push('truncate')
|
||||
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Create a new publication
|
||||
CREATE PUBLICATION ${ident(name)} ${tableClause}
|
||||
WITH (publish = '${publishOps.join(',')}');`
|
||||
|
||||
@@ -142,6 +144,8 @@ function update(
|
||||
}: PublicationUpdateParams
|
||||
): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Update publication properties
|
||||
do $$
|
||||
declare
|
||||
id oid := ${literal(id)};
|
||||
@@ -238,7 +242,7 @@ end $$;
|
||||
}
|
||||
|
||||
function remove(publication: Pick<PGPublication, 'name'>): { sql: string } {
|
||||
const sql = `DROP PUBLICATION IF EXISTS ${ident(publication.name)};`
|
||||
const sql = `-- source: dashboard\n-- description: Drop a publication\nDROP PUBLICATION IF EXISTS ${ident(publication.name)};`
|
||||
return { sql }
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ function list({
|
||||
zod: typeof pgRoleArrayZod
|
||||
} {
|
||||
let sql = `
|
||||
-- source: dashboard
|
||||
-- description: List all roles with metadata
|
||||
with
|
||||
roles as (${ROLES_SQL})
|
||||
select
|
||||
@@ -83,7 +85,7 @@ function retrieve(identifier: RoleIdentifier): {
|
||||
sql: string
|
||||
zod: typeof pgRoleOptionalZod
|
||||
} {
|
||||
const sql = `with roles as (${ROLES_SQL}) select * from roles where ${getIdentifierWhereClause(identifier)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single role by identifier\nwith roles as (${ROLES_SQL}) select * from roles where ${getIdentifierWhereClause(identifier)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgRoleOptionalZod,
|
||||
@@ -125,6 +127,8 @@ function create({
|
||||
config = {},
|
||||
}: RoleCreateParams): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Create a new role
|
||||
create role ${ident(name)}
|
||||
${isSuperuser ? 'superuser' : ''}
|
||||
${canCreateDb ? 'createdb' : ''}
|
||||
@@ -175,6 +179,8 @@ function update(identifier: RoleIdentifier, params: RoleUpdateParams): { sql: st
|
||||
validUntil,
|
||||
} = params
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Update role properties
|
||||
do $$
|
||||
declare
|
||||
old record;
|
||||
@@ -222,6 +228,8 @@ function remove(
|
||||
{ ifExists = false }: RoleRemoveParams = {}
|
||||
): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Drop a role
|
||||
do $$
|
||||
declare
|
||||
old record;
|
||||
|
||||
@@ -25,7 +25,7 @@ function list({
|
||||
sql: string
|
||||
zod: typeof pgSchemaArrayZod
|
||||
} {
|
||||
let sql = SCHEMAS_SQL
|
||||
let sql = `-- source: dashboard\n-- description: List all schemas with metadata\n` + SCHEMAS_SQL
|
||||
if (!includeSystemSchemas) {
|
||||
sql = `${sql} and not (n.nspname in (${DEFAULT_SYSTEM_SCHEMAS.map(literal).join(',')}))`
|
||||
}
|
||||
@@ -48,13 +48,13 @@ function retrieve({ id, name }: { id?: number; name?: string }): {
|
||||
zod: typeof pgSchemaOptionalZod
|
||||
} {
|
||||
if (id) {
|
||||
const sql = `${SCHEMAS_SQL} and n.oid = ${literal(id)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single schema by identifier\n${SCHEMAS_SQL} and n.oid = ${literal(id)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgSchemaOptionalZod,
|
||||
}
|
||||
} else {
|
||||
const sql = `${SCHEMAS_SQL} and n.nspname = ${literal(name)};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single schema by identifier\n${SCHEMAS_SQL} and n.nspname = ${literal(name)};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgSchemaOptionalZod,
|
||||
@@ -67,7 +67,7 @@ type SchemaCreateParams = {
|
||||
owner?: string
|
||||
}
|
||||
function create({ name, owner }: SchemaCreateParams): { sql: string } {
|
||||
const sql = `create schema ${ident(name)}
|
||||
const sql = `-- source: dashboard\n-- description: Create a new schema\ncreate schema ${ident(name)}
|
||||
${owner === undefined ? '' : `authorization ${ident(owner)}`};
|
||||
`
|
||||
return { sql }
|
||||
@@ -90,6 +90,8 @@ function update(
|
||||
{ name: newName, owner }: SchemaUpdateParams
|
||||
): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Update schema properties
|
||||
do $$
|
||||
declare
|
||||
id oid := ${id === undefined ? `${literal(name)}::regnamespace` : literal(id)};
|
||||
@@ -132,6 +134,8 @@ function remove(
|
||||
{ cascade = false }: SchemaRemoveParams = {}
|
||||
): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Drop a schema
|
||||
do $$
|
||||
declare
|
||||
id oid := ${id === undefined ? `${literal(name)}::regnamespace` : literal(id)};
|
||||
|
||||
@@ -54,6 +54,8 @@ function list({
|
||||
zod: typeof pgTablePrivilegesArrayZod
|
||||
} {
|
||||
let sql = `
|
||||
-- source: dashboard
|
||||
-- description: List all table privileges with metadata
|
||||
with table_privileges as (${TABLE_PRIVILEGES_SQL})
|
||||
select *
|
||||
from table_privileges
|
||||
@@ -97,6 +99,8 @@ function retrieve({
|
||||
} {
|
||||
if (id) {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Retrieve a single table privilege by identifier
|
||||
with table_privileges as (${TABLE_PRIVILEGES_SQL})
|
||||
select *
|
||||
from table_privileges
|
||||
@@ -107,6 +111,8 @@ where table_privileges.relation_id = ${literal(id)};`
|
||||
}
|
||||
} else {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Retrieve a single table privilege by identifier
|
||||
with table_privileges as (${TABLE_PRIVILEGES_SQL})
|
||||
select *
|
||||
from table_privileges
|
||||
@@ -137,6 +143,8 @@ type TablePrivilegesGrant = {
|
||||
}
|
||||
function grant(grants: TablePrivilegesGrant[]): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Grant privilege on table
|
||||
do $$
|
||||
begin
|
||||
${grants
|
||||
@@ -168,6 +176,8 @@ type TablePrivilegesRevoke = {
|
||||
}
|
||||
function revoke(revokes: TablePrivilegesRevoke[]): { sql: string } {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Revoke privilege from table
|
||||
do $$
|
||||
begin
|
||||
${revokes
|
||||
|
||||
@@ -130,19 +130,25 @@ function remove(
|
||||
table: Pick<PGTable, 'name' | 'schema'>,
|
||||
{ cascade = false } = {}
|
||||
): { sql: SafeSqlFragment } {
|
||||
const sql = safeSql`DROP TABLE ${ident(table.schema)}.${ident(table.name)} ${
|
||||
const sql = safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Drop a table
|
||||
DROP TABLE ${ident(table.schema)}.${ident(table.name)} ${
|
||||
cascade ? safeSql`CASCADE` : safeSql`RESTRICT`
|
||||
};`
|
||||
return { sql }
|
||||
}
|
||||
|
||||
const generateEnrichedTablesSql = ({ includeColumns }: { includeColumns?: boolean }) => safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all tables with metadata
|
||||
with tables as (${TABLES_SQL})
|
||||
${includeColumns ? safeSql`, columns as (${COLUMNS_SQL})` : safeSql``}
|
||||
select
|
||||
*
|
||||
${includeColumns ? safeSql`, ${coalesceRowsToArray('columns', safeSql`columns.table_id = tables.id`)}` : safeSql``}
|
||||
from tables`
|
||||
from tables
|
||||
`
|
||||
|
||||
type TableCreateParams = {
|
||||
name: string
|
||||
@@ -161,10 +167,16 @@ function create({ name, schema = 'public', comment, no_transaction = false }: Ta
|
||||
: safeSql``
|
||||
|
||||
if (no_transaction) {
|
||||
const sql = safeSql`${tableSql} ${commentSql}`
|
||||
const sql = safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Create a new table
|
||||
${tableSql} ${commentSql}`
|
||||
return { sql }
|
||||
}
|
||||
const sql = safeSql`BEGIN; ${tableSql} ${commentSql} COMMIT;`
|
||||
const sql = safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Create a new table
|
||||
BEGIN; ${tableSql} ${commentSql} COMMIT;`
|
||||
return { sql }
|
||||
}
|
||||
|
||||
@@ -256,6 +268,8 @@ $$;
|
||||
|
||||
// nameSql must be last, right below schemaSql
|
||||
const sql = safeSql`
|
||||
-- source: dashboard
|
||||
-- description: Update table properties
|
||||
BEGIN;
|
||||
${enableRls}
|
||||
${forceRls}
|
||||
|
||||
@@ -54,7 +54,7 @@ export function list({
|
||||
sql: string
|
||||
zod: typeof pgTriggerArrayZod
|
||||
} {
|
||||
let sql = `with triggers as (${TRIGGERS_SQL}) select * from triggers`
|
||||
let sql = `-- source: dashboard\n-- description: List all triggers with metadata\nwith triggers as (${TRIGGERS_SQL}) select * from triggers`
|
||||
const filter = filterByList(
|
||||
includedSchemas,
|
||||
excludedSchemas,
|
||||
@@ -83,7 +83,7 @@ type TriggersRetrieveReturn = {
|
||||
export function retrieve(identifier: TriggerIdentifier): TriggersRetrieveReturn
|
||||
export function retrieve(params: TriggerIdentifier): TriggersRetrieveReturn {
|
||||
const whereIdentifierCondition = getIdentifierWhereClause(params)
|
||||
const sql = `with triggers as (${TRIGGERS_SQL}) select * from triggers where ${whereIdentifierCondition};`
|
||||
const sql = `-- source: dashboard\n-- description: Retrieve a single trigger by identifier\nwith triggers as (${TRIGGERS_SQL}) select * from triggers where ${whereIdentifierCondition};`
|
||||
return {
|
||||
sql,
|
||||
zod: pgTriggerOptionalZod,
|
||||
@@ -127,7 +127,7 @@ export function create({
|
||||
const triggerCondition = condition ? `when (${condition})` : ''
|
||||
const functionArgsStr = function_args.map(literal).join(',')
|
||||
|
||||
const sql = `create trigger ${ident(
|
||||
const sql = `-- source: dashboard\n-- description: Create a new trigger\ncreate trigger ${ident(
|
||||
name
|
||||
)} ${activation} ${triggerEvents} on ${qualifiedTableName} ${triggerOrientation} ${triggerCondition} execute function ${qualifiedFunctionName}(${functionArgsStr});`
|
||||
|
||||
@@ -176,7 +176,7 @@ export function update(
|
||||
: ''
|
||||
|
||||
// updateNameSql must be last
|
||||
const sql = `begin; ${enabledModeSql}; ${updateNameSql}; commit;`
|
||||
const sql = `-- source: dashboard\n-- description: Update trigger properties\nbegin; ${enabledModeSql}; ${updateNameSql}; commit;`
|
||||
|
||||
return {
|
||||
sql,
|
||||
@@ -193,7 +193,7 @@ export function remove(
|
||||
} {
|
||||
const qualifiedTableName = `${ident(id.schema)}.${ident(id.table)}`
|
||||
|
||||
const sql = `drop trigger ${ident(id.name)} on ${qualifiedTableName} ${cascade ? 'cascade' : ''};`
|
||||
const sql = `-- source: dashboard\n-- description: Drop a trigger\ndrop trigger ${ident(id.name)} on ${qualifiedTableName} ${cascade ? 'cascade' : ''};`
|
||||
|
||||
return {
|
||||
sql,
|
||||
|
||||
@@ -39,7 +39,7 @@ function list({
|
||||
sql: string
|
||||
zod: typeof pgTypeArrayZod
|
||||
} {
|
||||
let sql = TYPES_SQL
|
||||
let sql = `-- source: dashboard\n-- description: List all types with metadata\n` + TYPES_SQL
|
||||
if (!includeArrayTypes) {
|
||||
sql += ` and not exists (
|
||||
select from pg_type el
|
||||
|
||||
@@ -11,7 +11,9 @@ export const pgVersionZod = z.object({
|
||||
|
||||
function retrieve() {
|
||||
return {
|
||||
sql: VERSION_SQL,
|
||||
sql:
|
||||
`-- source: dashboard\n-- description: Retrieve a single PostgreSQL version by identifier\n` +
|
||||
VERSION_SQL,
|
||||
zod: pgVersionZod,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,8 @@ export function retrieve(identifier: ViewIdentifier): {
|
||||
}
|
||||
|
||||
const generateEnrichedViewsSql = ({ includeColumns }: { includeColumns?: boolean }) => safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all views with metadata
|
||||
with views as (${VIEWS_SQL})
|
||||
${includeColumns ? safeSql`, columns as (${COLUMNS_SQL})` : safeSql``}
|
||||
select
|
||||
|
||||
@@ -235,11 +235,17 @@ export const getTableRowsSql = ({
|
||||
}
|
||||
})
|
||||
|
||||
const selectClause = selectExpressions.join(',')
|
||||
const selectClause = `${selectExpressions.join(',')}`
|
||||
const finalQuery = new Query()
|
||||
// Now, we apply our selection logic with the tables truncation on the _base_query constructed before
|
||||
const finalQueryChain = finalQuery.from('_base_query').select(selectClause)
|
||||
return `${baseSelectQuery}
|
||||
|
||||
const DASHBOARD_QUERY_COMMENT = `
|
||||
-- source: dashboard
|
||||
-- description: Fetch table rows with filtering, sorting, pagination, and truncation
|
||||
`
|
||||
return `${DASHBOARD_QUERY_COMMENT}
|
||||
${baseSelectQuery}
|
||||
${finalQueryChain.toSql({ isCTE: true, isFinal: true })}`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const COLUMN_PRIVILEGES_SQL = /* SQL */ safeSql`
|
||||
-- Lists each column's privileges in the form of:
|
||||
-- source: dashboard
|
||||
-- description: List column-level privileges for all relations in the form of:
|
||||
--
|
||||
-- [
|
||||
-- {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const COLUMNS_SQL = /* SQL */ safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all columns with metadata for tables, views, and foreign tables
|
||||
-- Adapted from information_schema.columns
|
||||
|
||||
SELECT
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const CONFIG_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all PostgreSQL configuration settings from pg_settings
|
||||
SELECT
|
||||
name,
|
||||
setting,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const EXTENSIONS_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all available and installed PostgreSQL extensions
|
||||
SELECT
|
||||
e.name,
|
||||
n.nspname AS schema,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const FOREIGN_TABLES_SQL = /* SQL */ safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all foreign tables with their server and data wrapper info
|
||||
select
|
||||
c.oid::int8 as id,
|
||||
n.nspname as schema,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const FUNCTIONS_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all PostgreSQL functions with arguments, return types, and configuration
|
||||
-- CTE with sane arg_modes, arg_names, and arg_types.
|
||||
-- All three are always of the same length.
|
||||
-- All three include all args, including OUT and TABLE args.
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const INDEXES_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all indexes with attributes, access methods, and definition
|
||||
SELECT
|
||||
idx.indexrelid::int8 AS id,
|
||||
idx.indrelid::int8 AS table_id,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const MATERIALIZED_VIEWS_SQL = /* SQL */ safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all materialized views with schema and population status
|
||||
select
|
||||
c.oid::int8 as id,
|
||||
n.nspname as schema,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const POLICIES_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all row-level security policies with their conditions and roles
|
||||
select
|
||||
pol.oid :: int8 as id,
|
||||
n.nspname as schema,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const PUBLICATIONS_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all logical replication publications with their subscribed tables
|
||||
SELECT
|
||||
p.oid :: int8 AS id,
|
||||
p.pubname AS name,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const ROLES_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all database roles with connection limits and configuration
|
||||
-- Can't use pg_authid here since some managed Postgres providers don't expose it
|
||||
-- https://github.com/supabase/postgres-meta/issues/212
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const SCHEMAS_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all schemas with owner and comments
|
||||
-- Adapted from information_schema.schemata
|
||||
|
||||
select
|
||||
|
||||
@@ -10,7 +10,8 @@ export function getTableIndexAdvisorSql(schema: string, table: string): string {
|
||||
const regexTable = escapedTable.toLowerCase().replace(/[.+*?^${}()|[\]\\]/g, '\\$&')
|
||||
|
||||
return /* SQL */ `
|
||||
-- Get top 5 SELECT queries involving this table and run through index_advisor
|
||||
-- source: dashboard
|
||||
-- description: Find top 5 SELECT queries for a table and run them through index_advisor for recommendations
|
||||
set search_path to public, extensions;
|
||||
|
||||
with top_queries as (
|
||||
|
||||
@@ -23,7 +23,9 @@ ${query}
|
||||
* - Replace docs url with docsUrl (${docsUrl})
|
||||
*/
|
||||
export const getLintsSQL = ({ docsUrl }: { docsUrl: string }) =>
|
||||
/* SQL */ `set local search_path = '';
|
||||
/* SQL */ `-- source: dashboard
|
||||
-- description: Run database linting checks for security, performance, and best practice issues
|
||||
set local search_path = '';
|
||||
|
||||
(
|
||||
with foreign_keys as (
|
||||
|
||||
@@ -11,7 +11,7 @@ export const USER_SEARCH_INDEXES = [
|
||||
]
|
||||
|
||||
export const getIndexStatusesSQL = () => {
|
||||
return `SELECT c.relname as index_name, i.indisvalid as is_valid, i.indisready as is_ready
|
||||
return `-- source: dashboard\n-- description: Check validity and readiness of auth user search indexes\nSELECT c.relname as index_name, i.indisvalid as is_valid, i.indisready as is_ready
|
||||
FROM pg_index i
|
||||
JOIN pg_class c ON c.oid = i.indexrelid
|
||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const INDEX_WORKER_ADVISORY_LOCK_KEY = 'auth_index_worker'
|
||||
|
||||
export const getIndexWorkerStatusSQL = () => {
|
||||
return `SELECT EXISTS (
|
||||
return `-- source: dashboard\n-- description: Check if the auth index worker advisory lock is currently held\nSELECT EXISTS (
|
||||
SELECT 1 FROM pg_locks
|
||||
WHERE locktype = 'advisory'
|
||||
AND (classid::bigint << 32 | objid::bigint) = hashtext('${INDEX_WORKER_ADVISORY_LOCK_KEY}')::bigint
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const getUserSQL = (userId: string) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch a single auth user by ID with their identity providers
|
||||
select
|
||||
auth.users.id,
|
||||
auth.users.email,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { COUNT_ESTIMATE_SQL, THRESHOLD_COUNT } from '../database/get-count-estim
|
||||
import { prefixToUUID, stringRange } from './get-users-common'
|
||||
import type { OptimizedSearchColumns } from './get-users-types'
|
||||
|
||||
export const USERS_COUNT_ESTIMATE_SQL = `select reltuples as estimate from pg_class where oid = 'auth.users'::regclass`
|
||||
export const USERS_COUNT_ESTIMATE_SQL = `-- source: dashboard\n-- description: Estimate total number of auth users from pg_class statistics\nselect reltuples as estimate from pg_class where oid = 'auth.users'::regclass`
|
||||
|
||||
export const getUsersCountSQL = ({
|
||||
filter,
|
||||
@@ -92,6 +92,8 @@ export const getUsersCountSQL = ({
|
||||
const escapedSelectSql = literal(selectBaseSql)
|
||||
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Count auth users with optional filters using estimate or exact count
|
||||
${COUNT_ESTIMATE_SQL}
|
||||
|
||||
with approximation as (${USERS_COUNT_ESTIMATE_SQL})
|
||||
|
||||
@@ -143,6 +143,8 @@ export const getPaginatedUsersSQL = ({
|
||||
${whereStatement}`
|
||||
|
||||
let usersQuery = `
|
||||
-- source: dashboard
|
||||
-- description: Paginated list of auth users with providers and optional filters
|
||||
with
|
||||
users_data as (${usersData})
|
||||
select
|
||||
@@ -295,6 +297,8 @@ export const getImprovedPaginatedUsersSQL = ({
|
||||
${limit}`
|
||||
|
||||
const usersQuery = `
|
||||
-- source: dashboard
|
||||
-- description: Improved paginated list of auth users using index-optimized cursor-based pagination
|
||||
WITH
|
||||
users_data AS (${usersData})
|
||||
SELECT
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*/
|
||||
export const getTablesWithAnonAuthenticatedAccessSQL = ({ schema }: { schema: string }) =>
|
||||
/* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List tables in a schema accessible by anon or authenticated roles
|
||||
SELECT c.relname AS table_name
|
||||
FROM pg_catalog.pg_class AS c
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
|
||||
|
||||
@@ -16,6 +16,8 @@ export const getUnsafeEntitiesInApiSql = ({ schemas }: { schemas: Array<string>
|
||||
const schemaList = schemas.map(literal).join(', ')
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List API-exposed entities with potential security issues such as missing RLS or security invoker
|
||||
select
|
||||
n.nspname as schema,
|
||||
c.relname as name,
|
||||
|
||||
@@ -10,7 +10,8 @@ export const getTableColumnsSql = ({ table, schema }: { table?: string; schema?:
|
||||
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''
|
||||
|
||||
const sql = /* SQL */ `
|
||||
|
||||
-- source: dashboard
|
||||
-- description: List tables and views with their columns, optionally filtered by table and schema
|
||||
SELECT
|
||||
tbl.schemaname,
|
||||
tbl.tablename,
|
||||
|
||||
@@ -10,13 +10,15 @@ export const getCronJobsMinimalSql = ({
|
||||
limit: number
|
||||
}) =>
|
||||
`
|
||||
SELECT
|
||||
-- source: dashboard
|
||||
-- description: List cron jobs with minimal fields, optionally filtered by name
|
||||
SELECT
|
||||
job.jobid,
|
||||
job.jobname,
|
||||
job.schedule,
|
||||
job.command,
|
||||
job.active
|
||||
FROM
|
||||
FROM
|
||||
cron.job job
|
||||
${!!searchTerm ? `WHERE job.jobname ILIKE ${literal(`%${searchTerm}%`)}` : ''}
|
||||
ORDER BY job.jobid
|
||||
@@ -34,6 +36,8 @@ export const getCronJobsSql = ({
|
||||
limit: number
|
||||
}) =>
|
||||
`
|
||||
-- source: dashboard
|
||||
-- description: List cron jobs with their latest run status and timestamps
|
||||
WITH latest_runs AS (
|
||||
SELECT
|
||||
jobid,
|
||||
@@ -93,6 +97,8 @@ export const getDeleteOldCronJobRunDetailsByCtidSql = (
|
||||
const safeCtidEnd = literal(`(${endPage},0)`)
|
||||
|
||||
return `
|
||||
-- source: dashboard
|
||||
-- description: Delete old cron job run details within a ctid page range older than a given interval
|
||||
WITH deleted AS (
|
||||
DELETE FROM cron.job_run_details
|
||||
WHERE ctid >= ${safeCtidStart}::tid
|
||||
@@ -109,6 +115,8 @@ const CRON_CLEANUP_SCHEDULE_EXPRESSION = '0 12 * * *'
|
||||
|
||||
export const getScheduleDeleteCronJobRunDetailsSql = (interval: string) =>
|
||||
`
|
||||
-- source: dashboard
|
||||
-- description: Schedule a cron job to delete old job run details on a recurring schedule
|
||||
SELECT cron.schedule(
|
||||
${literal(CRON_CLEANUP_SCHEDULE_NAME)},
|
||||
${literal(CRON_CLEANUP_SCHEDULE_EXPRESSION)},
|
||||
@@ -122,6 +130,8 @@ SELECT cron.schedule(
|
||||
*/
|
||||
export const getJobRunDetailsPageCountSql = () =>
|
||||
`
|
||||
-- source: dashboard
|
||||
-- description: Get the total number of storage pages in the cron job_run_details table
|
||||
SELECT pg_relation_size(oid) / current_setting('block_size')::int8 AS num_pages
|
||||
FROM pg_class
|
||||
WHERE relname = 'job_run_details'
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { ident } from '../../../pg-format'
|
||||
import pgMetaExtensions from '../../../pg-meta-extensions'
|
||||
import { safeSql } from '../../../pg-format'
|
||||
|
||||
export const getDatabaseExtensionsSQL = () =>
|
||||
`
|
||||
safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all available extensions with their default schema and version
|
||||
SELECT
|
||||
e.name,
|
||||
n.nspname AS schema,
|
||||
|
||||
@@ -6,6 +6,8 @@ type SimplifiedWrapperMeta = {
|
||||
|
||||
export const getFDWsSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all foreign data wrappers with their servers, handlers, and linked foreign tables
|
||||
select
|
||||
s.oid as "id",
|
||||
w.fdwname as "name",
|
||||
@@ -69,6 +71,8 @@ export function getCreateFDWSql({
|
||||
.join('\n')
|
||||
|
||||
const createWrapperSql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create a new foreign data wrapper
|
||||
create foreign data wrapper "${formState.wrapper_name}"
|
||||
handler "${wrapperMeta.handlerName}"
|
||||
validator "${wrapperMeta.validatorName}";
|
||||
@@ -239,6 +243,8 @@ export function getCreateFDWSql({
|
||||
const options = [...schemaOptions, "strict 'true'"].join(', ')
|
||||
|
||||
const importForeignSchemaSql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Import a foreign schema into a local schema from a foreign server
|
||||
import foreign schema "${sourceSchema}" from server ${formState.server_name} into ${targetSchema} options (${options});
|
||||
`
|
||||
|
||||
@@ -317,6 +323,8 @@ export const getDeleteFDWSql = ({
|
||||
const deleteEncryptedSecretsSql = deleteEncryptedSecretsSqlArray.join('\n')
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Drop a foreign data wrapper and delete its associated encrypted secrets
|
||||
drop foreign data wrapper if exists "${wrapper.name}" cascade;
|
||||
|
||||
${deleteEncryptedSecretsSql}
|
||||
@@ -347,6 +355,8 @@ export const getUpdateFDWSql = ({
|
||||
})
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Update a foreign data wrapper by deleting and recreating it with new configuration
|
||||
${deleteWrapperSql}
|
||||
|
||||
${createWrapperSql}
|
||||
@@ -369,6 +379,8 @@ export function getImportForeignSchemaSql({
|
||||
const options = [...schemaOptions, "strict 'true'"].join(', ')
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Import a foreign schema from a named server into a target schema
|
||||
import foreign schema "${sourceSchema}" from server ${serverName} into ${targetSchema} options (${options});
|
||||
`
|
||||
|
||||
@@ -377,6 +389,8 @@ export function getImportForeignSchemaSql({
|
||||
|
||||
export function getDropForeignTableSql({ schema, table }: { schema: string; table: string }) {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Drop a foreign table if it exists
|
||||
drop foreign table if exists "${schema}"."${table}";
|
||||
`
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
export const THRESHOLD_COUNT = 50000
|
||||
|
||||
export const COUNT_ESTIMATE_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create a temporary function to estimate row count from a query's execution plan
|
||||
CREATE OR REPLACE FUNCTION pg_temp.count_estimate(
|
||||
query text
|
||||
) RETURNS integer LANGUAGE plpgsql AS $$
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const getIndexesSQL = ({ schema }: { schema: string }) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all indexes for a given schema with their columns and definitions
|
||||
SELECT
|
||||
n.nspname AS schema,
|
||||
t.relname AS "table",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const getMigrationsSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all schema migrations ordered by version descending
|
||||
select
|
||||
*
|
||||
from supabase_migrations.schema_migrations sm
|
||||
@@ -11,6 +13,8 @@ export const getMigrationsSql = () => {
|
||||
|
||||
export const getCreateMigrationsTableSQL = () => {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create the supabase_migrations schema and schema_migrations table if they do not exist
|
||||
create schema if not exists supabase_migrations;
|
||||
create table if not exists supabase_migrations.schema_migrations (
|
||||
version text not null primary key,
|
||||
@@ -30,6 +34,8 @@ export const getInsertMigrationSQL = ({
|
||||
statements: string
|
||||
}) => {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Insert a new migration record into the schema_migrations table
|
||||
insert into supabase_migrations.schema_migrations (version, statements, name)
|
||||
select '${version}', array_agg(jsonb_statements)::text[], '${name}'
|
||||
from jsonb_array_elements_text($statements$${statements}$statements$::jsonb) as jsonb_statements;
|
||||
|
||||
@@ -2,6 +2,8 @@ import { literal } from '../../../pg-format'
|
||||
|
||||
export const getDatabaseSizeSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch total size of all databases in bytes
|
||||
select sum(pg_database_size(pg_database.datname))::bigint as db_size from pg_database;
|
||||
`.trim()
|
||||
|
||||
@@ -10,6 +12,8 @@ select sum(pg_database_size(pg_database.datname))::bigint as db_size from pg_dat
|
||||
|
||||
export const getLiveTupleEstimate = (table: string, schema: string = 'public') => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch live tuple estimate for a specific table from pg_stat_user_tables
|
||||
SELECT n_live_tup AS live_tuple_estimate
|
||||
FROM pg_stat_user_tables
|
||||
WHERE schemaname = ${literal(schema)}
|
||||
@@ -20,14 +24,16 @@ AND relname = ${literal(table)};
|
||||
}
|
||||
|
||||
export const getMaxConnectionsSql = () => {
|
||||
const sql = /* SQL */ `show max_connections`
|
||||
const sql = /* SQL */ `-- source: dashboard\n-- description: Fetch the maximum number of allowed database connections\nshow max_connections`
|
||||
|
||||
return sql
|
||||
}
|
||||
|
||||
export const replicationLagSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
select
|
||||
-- source: dashboard
|
||||
-- description: Fetch physical replication lag in seconds from the replica's last replayed transaction
|
||||
select
|
||||
case
|
||||
when (select count(*) from pg_stat_wal_receiver) = 1 and pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()
|
||||
then 0
|
||||
|
||||
@@ -90,6 +90,8 @@ export function getExposedTablesSql({
|
||||
ignoredSchemas?: string[]
|
||||
}) {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List tables with their grant status for anon, authenticated, and service_role
|
||||
with ${getTableGrantsCTEs({ search, ignoredSchemas })}
|
||||
select
|
||||
(select count(*)::int from table_grants) as total_count,
|
||||
@@ -127,6 +129,8 @@ export function getExposedTableCountsSql({
|
||||
selectedSchemas.length > 0 ? selectedSchemas.map((s) => `'${s}'`).join(', ') : "''"
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Count total tables and granted tables for selected schemas
|
||||
with ${getTableGrantsCTEs({ ignoredSchemas })}
|
||||
select
|
||||
count(*)::int as total_count,
|
||||
@@ -197,6 +201,8 @@ export function getExposedFunctionsSql({
|
||||
ignoredSchemas?: string[]
|
||||
}) {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List functions with their execute grant status for anon, authenticated, and service_role
|
||||
with ${getFunctionGrantsCTEs({ search, ignoredSchemas })}
|
||||
select
|
||||
(select count(*)::int from function_grants) as total_count,
|
||||
@@ -233,6 +239,8 @@ export function getExposedFunctionCountsSql({
|
||||
selectedSchemas.length > 0 ? selectedSchemas.map((s) => `'${s}'`).join(', ') : "''"
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Count total functions and granted functions for selected schemas
|
||||
with ${getFunctionGrantsCTEs({ ignoredSchemas })}
|
||||
select
|
||||
count(*)::int as total_count,
|
||||
@@ -243,6 +251,8 @@ export function getExposedFunctionCountsSql({
|
||||
|
||||
export function getDefaultPrivilegesStateSql({ schema = 'public' }: { schema?: string } = {}) {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Check if default privileges are set for anon, authenticated, and service_role in a schema
|
||||
select
|
||||
count(*)::int as grant_count
|
||||
from pg_default_acl d
|
||||
@@ -302,6 +312,8 @@ export const buildTablePrivilegesSql = (oids: number[], action: 'grant' | 'revok
|
||||
: 'revoke all on table %I.%I from anon, authenticated, service_role'
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Grant or revoke table privileges for anon, authenticated, and service_role by table OIDs
|
||||
do $$
|
||||
declare
|
||||
nspname name;
|
||||
@@ -337,6 +349,8 @@ export const buildFunctionPrivilegesSql = (schemaNames: string[], action: 'grant
|
||||
: 'revoke all on function %I.%I(%s) from anon, authenticated, service_role'
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Grant or revoke function execute privileges for anon, authenticated, and service_role
|
||||
do $$
|
||||
declare
|
||||
nspname name;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export const QUEUES_SCHEMA = 'pgmq_public'
|
||||
|
||||
export const HIDE_QUEUES_FROM_POSTGREST_SQL = /* SQL */ `
|
||||
drop function if exists
|
||||
-- source: dashboard
|
||||
-- description: Drop pgmq_public wrapper functions and revoke permissions to hide queues from PostgREST
|
||||
drop function if exists
|
||||
${QUEUES_SCHEMA}.pop(queue_name text),
|
||||
${QUEUES_SCHEMA}.send(queue_name text, message jsonb, sleep_seconds integer),
|
||||
${QUEUES_SCHEMA}.send_batch(queue_name text, message jsonb[], sleep_seconds integer),
|
||||
@@ -32,6 +34,8 @@ export const getExposeQueuesSQL = ({ isNewerPgmqversion }: { isNewerPgmqversion:
|
||||
const jsonBArg = isNewerPgmqversion ? `, jsonb` : ''
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Expose pgmq queues through PostgREST by creating wrapper functions and granting permissions
|
||||
create schema if not exists ${QUEUES_SCHEMA};
|
||||
grant usage on schema ${QUEUES_SCHEMA} to postgres, anon, authenticated, service_role;
|
||||
|
||||
@@ -210,6 +214,8 @@ export const getExposeQueuesSQL = ({ isNewerPgmqversion }: { isNewerPgmqversion:
|
||||
// [Joshen] Check if all the relevant functions exist to indicate whether PGMQ has been exposed through PostgREST
|
||||
export const getQueuesExposePostgrestStatusSQL = () => {
|
||||
return /**SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Check if pgmq queues are currently exposed through PostgREST
|
||||
SELECT exists (select schema_name FROM information_schema.schemata WHERE schema_name = '${QUEUES_SCHEMA}');
|
||||
`.trim()
|
||||
}
|
||||
@@ -50,13 +50,15 @@ export const getTableRowsCountSql = ({
|
||||
|
||||
if (isUsingReadReplica) {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Count rows in a table using estimates or exact count, optimized for read replicas
|
||||
with approximation as (
|
||||
select reltuples as estimate
|
||||
from pg_class
|
||||
where oid = ${table.id}
|
||||
)
|
||||
select
|
||||
case
|
||||
select
|
||||
case
|
||||
when estimate > ${THRESHOLD_COUNT} then (select -1)
|
||||
else (${countBaseSql})
|
||||
end as count,
|
||||
@@ -67,6 +69,8 @@ from approximation;
|
||||
return sql
|
||||
} else {
|
||||
const sql = `
|
||||
-- source: dashboard
|
||||
-- description: Count rows in a table using query plan estimates or exact count with optional filters
|
||||
${COUNT_ESTIMATE_SQL}
|
||||
|
||||
with approximation as (
|
||||
@@ -74,8 +78,8 @@ with approximation as (
|
||||
from pg_class
|
||||
where oid = ${table.id}
|
||||
)
|
||||
select
|
||||
case
|
||||
select
|
||||
case
|
||||
when estimate > ${THRESHOLD_COUNT} then ${filters.length > 0 ? `pg_temp.count_estimate('${selectBaseSql.replaceAll("'", "''")}')` : 'estimate'}
|
||||
else (${countBaseSql})
|
||||
end as count,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*/
|
||||
|
||||
export const CREATE_PG_GET_TABLEDEF_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create temporary helper functions to generate a full CREATE TABLE DDL definition
|
||||
DROP TYPE IF EXISTS pg_temp.tabledefs CASCADE;
|
||||
CREATE TYPE pg_temp.tabledefs AS ENUM ('PKEY_INTERNAL','PKEY_EXTERNAL','FKEYS_INTERNAL', 'FKEYS_EXTERNAL', 'COMMENTS', 'FKEYS_NONE', 'INCLUDE_TRIGGERS', 'NO_TRIGGERS');
|
||||
|
||||
@@ -706,10 +708,12 @@ export const CREATE_PG_GET_TABLEDEF_SQL = /* SQL */ `
|
||||
|
||||
export const getTableDefinitionSql = ({ id }: { id: number }) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Generate a CREATE TABLE DDL definition for a single table by OID
|
||||
${CREATE_PG_GET_TABLEDEF_SQL}
|
||||
|
||||
with table_info as (
|
||||
select
|
||||
select
|
||||
n.nspname::text as schema,
|
||||
c.relname::text as name
|
||||
from pg_class c
|
||||
@@ -737,6 +741,8 @@ export const getEntityDefinitionsSql = ({
|
||||
limit?: number
|
||||
}) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Generate CREATE TABLE/VIEW DDL definitions for all entities in given schemas
|
||||
${CREATE_PG_GET_TABLEDEF_SQL}
|
||||
|
||||
with records as (
|
||||
|
||||
@@ -28,6 +28,8 @@ export function getDatabaseTriggerUpdateSQL({
|
||||
const { name, activation, events, schema, table, function_schema, function_name, function_args } =
|
||||
updatedTrigger
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Update a trigger by dropping and recreating it within a transaction
|
||||
BEGIN;
|
||||
DROP TRIGGER "${originalTrigger.name}" ON "${originalTrigger.schema}"."${originalTrigger.table}";
|
||||
CREATE TRIGGER "${name}" ${activation} ${events.join(' OR ')} ON "${schema}"."${table}"
|
||||
|
||||
@@ -11,7 +11,7 @@ export const getCreateEnumeratedTypeSQL = ({
|
||||
values: string[]
|
||||
description?: string
|
||||
}) => {
|
||||
const createSql = `create type "${schema}"."${name}" as enum (${values
|
||||
const createSql = `-- source: dashboard\n-- description: Create a new enumerated type in the specified schema\ncreate type "${schema}"."${name}" as enum (${values
|
||||
.map((x) => `'${x}'`)
|
||||
.join(', ')});`
|
||||
const commentSql =
|
||||
@@ -21,7 +21,7 @@ export const getCreateEnumeratedTypeSQL = ({
|
||||
}
|
||||
|
||||
export const getDeleteEnumeratedTypeSQL = ({ schema, name }: { schema: string; name: string }) => {
|
||||
return `drop type if exists ${schema}."${name}"`
|
||||
return `-- source: dashboard\n-- description: Drop an enumerated type if it exists\ndrop type if exists ${schema}."${name}"`
|
||||
}
|
||||
|
||||
export const getUpdateEnumeratedTypeSQL = ({
|
||||
@@ -35,7 +35,9 @@ export const getUpdateEnumeratedTypeSQL = ({
|
||||
description?: string
|
||||
values?: { original: string; updated: string; isNew: boolean }[]
|
||||
}) => {
|
||||
const statements: string[] = []
|
||||
const statements: string[] = [
|
||||
'-- source: dashboard\n-- description: Update an enumerated type by renaming, adding, or modifying values',
|
||||
]
|
||||
if (name.original !== name.updated) {
|
||||
statements.push(`alter type "${schema}"."${name.original}" rename to "${name.updated}";`)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ export const getCreateVaultSecretSQL = ({
|
||||
description?: string
|
||||
}) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Create a new secret in the Vault with optional name and description
|
||||
select vault.create_secret(
|
||||
new_secret := ${literal(secret)}
|
||||
${name ? `, new_name := ${literal(name)}` : ''}
|
||||
@@ -32,6 +34,8 @@ export const getUpdateVaultSecretSQL = ({
|
||||
description?: string
|
||||
}) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Update an existing Vault secret by ID with optional new value, name, or description
|
||||
select vault.update_secret(
|
||||
secret_id := ${literal(id)}
|
||||
${secret ? `, new_secret := ${literal(secret)}` : ''}
|
||||
|
||||
@@ -4,8 +4,10 @@ export const getViewDefinitionSql = ({ id }: { id: number }) => {
|
||||
}
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch the SQL definition of a view by its OID
|
||||
with table_info as (
|
||||
select
|
||||
select
|
||||
n.nspname::text as schema,
|
||||
c.relname::text as name,
|
||||
to_regclass(concat('"', n.nspname, '"."', c.relname, '"')) as regclass
|
||||
|
||||
@@ -8,6 +8,8 @@ function getPostgrestRoleImpersonationSql({
|
||||
unexpiredClaims: Object
|
||||
}) {
|
||||
return `
|
||||
-- source: dashboard
|
||||
-- description: Set PostgREST role and JWT claims for role impersonation in a session
|
||||
select set_config('role', ${literal(role)}, true),
|
||||
set_config('request.jwt.claims', ${literal(JSON.stringify(unexpiredClaims))}, true),
|
||||
set_config('request.method', 'POST', true),
|
||||
@@ -18,6 +20,8 @@ set_config('request.headers', '{"accept": "*/*"}', true);
|
||||
|
||||
function getCustomRoleImpersonationSql(roleName: string) {
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Set the local role for custom role impersonation in a session
|
||||
set local role ${literal(roleName)};
|
||||
`.trim()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export const getAbortQuerySQL = ({ pid }: { pid: number }) => {
|
||||
return `select pg_terminate_backend(${pid})`.trim()
|
||||
return `-- source: dashboard\n-- description: Terminate a running backend process by PID\nselect pg_terminate_backend(${pid})`.trim()
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
export const getKeywordsSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch all PostgreSQL reserved and non-reserved keywords
|
||||
SELECT word FROM pg_get_keywords();
|
||||
`.trim()
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const getOngoingQueriesSql = () => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List currently active queries with PID, query text, and start time
|
||||
select pid, query, query_start from pg_stat_activity where state = 'active' and datname = 'postgres';
|
||||
`.trim()
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ export const getDeleteBucketPrefixSQL = ({
|
||||
prefix: string
|
||||
}) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Delete all storage objects matching a prefix within a bucket
|
||||
select storage.delete_prefix('${bucketId}', '${prefix}');
|
||||
`.trim()
|
||||
return sql
|
||||
|
||||
@@ -7,6 +7,8 @@ export const LARGEST_SIZE_LIMIT_BUCKETS_COUNT = 50
|
||||
* there is no index on `file_size_limit` in the `storage.buckets` table.
|
||||
*/
|
||||
export const getLargestSizeLimitBucketsSqlUnoptimized = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List storage buckets with the largest file size limits
|
||||
SELECT id, name, file_size_limit
|
||||
FROM storage.buckets
|
||||
WHERE file_size_limit IS NOT NULL
|
||||
|
||||
@@ -2,8 +2,10 @@ import { ident } from '../../../pg-format'
|
||||
|
||||
export const getTableConstraintsSql = ({ id }: { id: number }) => {
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List constraints for a table by OID including type and name
|
||||
with table_info as (
|
||||
select
|
||||
select
|
||||
n.nspname::text as schema,
|
||||
c.relname::text as name,
|
||||
to_regclass(concat('"', n.nspname, '"."', c.relname, '"')) as regclass
|
||||
@@ -36,4 +38,5 @@ export const getDropConstraintSQL = ({
|
||||
schema: string
|
||||
table: string
|
||||
name: string
|
||||
}) => `ALTER TABLE ${ident(schema)}.${ident(table)} DROP CONSTRAINT ${ident(name)}`
|
||||
}) =>
|
||||
`-- source: dashboard\n-- description: Drop a named constraint from a table\nALTER TABLE ${ident(schema)}.${ident(table)} DROP CONSTRAINT ${ident(name)}`
|
||||
@@ -17,6 +17,8 @@ export const getEntityTypesSQL = ({
|
||||
const outerOrderBy = sort === 'alphabetical' ? `r.name asc` : `r.type_sort asc, r.name asc`
|
||||
|
||||
const sql = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List entities (tables, views, etc.) in given schemas with type, comment, and RLS status
|
||||
with records as (
|
||||
select
|
||||
c.oid::int8 as "id",
|
||||
|
||||
@@ -68,9 +68,11 @@ export const getForeignKeyConstraintsSql = ({ schema }: { schema: string }) => {
|
||||
if (!schema) throw new Error('schema is required')
|
||||
|
||||
const sql = /* SQL */ `
|
||||
SELECT
|
||||
con.oid as id,
|
||||
con.conname as constraint_name,
|
||||
-- source: dashboard
|
||||
-- description: List all foreign key constraints in a schema with source and target columns
|
||||
SELECT
|
||||
con.oid as id,
|
||||
con.conname as constraint_name,
|
||||
con.confdeltype as deletion_action,
|
||||
con.confupdtype as update_action,
|
||||
rel.oid as source_id,
|
||||
|
||||
@@ -9,7 +9,7 @@ export const getUpdateIdentitySequenceSQL = ({
|
||||
table: string
|
||||
column: string
|
||||
}) => {
|
||||
return `SELECT setval('${ident(schema)}.${ident(`${table}_${column}_seq`)}', (SELECT COALESCE(MAX(${ident(column)}), 1) FROM ${ident(schema)}.${ident(table)}))`
|
||||
return `-- source: dashboard\n-- description: Reset an identity sequence to the current max value in the column\nSELECT setval('${ident(schema)}.${ident(`${table}_${column}_seq`)}', (SELECT COALESCE(MAX(${ident(column)}), 1) FROM ${ident(schema)}.${ident(table)}))`
|
||||
}
|
||||
|
||||
export const getDuplicateIdentitySequenceSQL = ({
|
||||
@@ -23,5 +23,5 @@ export const getDuplicateIdentitySequenceSQL = ({
|
||||
sourceTableName: string
|
||||
sourceTableSchema: string
|
||||
}) => {
|
||||
return `SELECT setval('${ident(sourceTableSchema)}.${ident(`${duplicatedTableName}_${columnName}_seq`)}', (SELECT COALESCE(MAX(${ident(columnName)}), 1) FROM ${ident(sourceTableSchema)}.${ident(sourceTableName)}));`
|
||||
return `-- source: dashboard\n-- description: Sync the identity sequence of a duplicated table to match the source table's max value\nSELECT setval('${ident(sourceTableSchema)}.${ident(`${duplicatedTableName}_${columnName}_seq`)}', (SELECT COALESCE(MAX(${ident(columnName)}), 1) FROM ${ident(sourceTableSchema)}.${ident(sourceTableName)}));`
|
||||
}
|
||||
@@ -14,5 +14,5 @@ export const getAddPrimaryKeySQL = ({
|
||||
columns: string[]
|
||||
}) => {
|
||||
const primaryKeyColumns = columns.map((col) => ident(col)).join(', ')
|
||||
return `ALTER TABLE ${ident(schema)}.${ident(table)} ADD PRIMARY KEY (${primaryKeyColumns})`
|
||||
return `-- source: dashboard\n-- description: Add a primary key constraint to a table\nALTER TABLE ${ident(schema)}.${ident(table)} ADD PRIMARY KEY (${primaryKeyColumns})`
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ident } from '../../../pg-format'
|
||||
|
||||
export const getEnableRLSSQL = ({ schema, table }: { schema: string; table: string }) => {
|
||||
return `ALTER TABLE ${ident(schema)}.${ident(table)} ENABLE ROW LEVEL SECURITY`
|
||||
return `-- source: dashboard\n-- description: Enable row level security on a table\nALTER TABLE ${ident(schema)}.${ident(table)} ENABLE ROW LEVEL SECURITY`
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export const getDuplicateTableSQL = ({
|
||||
sourceTableSchema: string
|
||||
}) => {
|
||||
return [
|
||||
`CREATE TABLE ${ident(sourceTableSchema)}.${ident(duplicatedTableName)} (LIKE ${ident(sourceTableSchema)}.${ident(sourceTableName)} INCLUDING ALL);`,
|
||||
`-- source: dashboard\n-- description: Create a duplicate table with the same structure as the source table\nCREATE TABLE ${ident(sourceTableSchema)}.${ident(duplicatedTableName)} (LIKE ${ident(sourceTableSchema)}.${ident(sourceTableName)} INCLUDING ALL);`,
|
||||
comment != undefined
|
||||
? `comment on table ${ident(sourceTableSchema)}.${ident(duplicatedTableName)} is ${literal(comment)};`
|
||||
: '',
|
||||
@@ -28,13 +28,15 @@ export const getDuplicateRowsSQL = ({
|
||||
sourceTableName: string
|
||||
sourceTableSchema: string
|
||||
}) => {
|
||||
return `INSERT INTO ${ident(sourceTableSchema)}.${ident(duplicatedTableName)} SELECT * FROM ${ident(sourceTableSchema)}.${ident(sourceTableName)};`
|
||||
return `-- source: dashboard\n-- description: Copy all rows from the source table into the duplicated table\nINSERT INTO ${ident(sourceTableSchema)}.${ident(duplicatedTableName)} SELECT * FROM ${ident(sourceTableSchema)}.${ident(sourceTableName)};`
|
||||
}
|
||||
|
||||
export const getTableEditorSql = ({ id }: { id?: number }) => {
|
||||
if (!id) return ''
|
||||
|
||||
return /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch comprehensive table editor data including columns, relationships, indexes, and RLS status
|
||||
with base_table_info as (
|
||||
select
|
||||
c.oid::int8 as id,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const TABLE_PRIVILEGES_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List privileges for all relations including tables, views, and materialized views
|
||||
-- Despite the name \`table_privileges\`, this includes other kinds of relations:
|
||||
-- views, matviews, etc. "Relation privileges" just doesn't roll off the tongue.
|
||||
--
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const TABLES_SQL = /* SQL */ safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all tables with size, RLS status, primary keys, and relationships
|
||||
SELECT
|
||||
c.oid :: int8 AS id,
|
||||
nc.nspname AS schema,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const TRIGGERS_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all triggers with events, orientation, timing, and function details
|
||||
SELECT
|
||||
pg_t.oid AS id,
|
||||
pg_t.tgrelid AS table_id,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const TYPES_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: List all PostgreSQL types with enum values and composite attributes
|
||||
select
|
||||
t.oid::int8 as id,
|
||||
t.typname as name,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const VERSION_SQL = /* SQL */ `
|
||||
-- source: dashboard
|
||||
-- description: Fetch PostgreSQL version, active connections, and max connections
|
||||
select
|
||||
version(),
|
||||
current_setting('server_version_num')::int8 as version_number,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { safeSql } from '../pg-format'
|
||||
|
||||
export const VIEWS_SQL = /* SQL */ safeSql`
|
||||
-- source: dashboard
|
||||
-- description: List all views with updatability status and comments
|
||||
SELECT
|
||||
c.oid :: int8 AS id,
|
||||
n.nspname AS schema,
|
||||
|
||||
Reference in new issue
Block a user