diff --git a/frontend/src/lib/components/apps/components/display/dbtable/AppDbExplorer.svelte b/frontend/src/lib/components/apps/components/display/dbtable/AppDbExplorer.svelte index 5b8b1cfb4b..ae2135ae96 100644 --- a/frontend/src/lib/components/apps/components/display/dbtable/AppDbExplorer.svelte +++ b/frontend/src/lib/components/apps/components/display/dbtable/AppDbExplorer.svelte @@ -249,7 +249,12 @@ { table: { selectOptions: dbSchemas - ? getTablesByResource(dbSchemas, resolvedConfig?.type?.selected) + ? await getTablesByResource( + dbSchemas, + resolvedConfig?.type?.selected, + resource.split(':')[1], + $workspaceStore! + ) : [], loading: false } diff --git a/frontend/src/lib/components/apps/components/display/dbtable/queries/count.ts b/frontend/src/lib/components/apps/components/display/dbtable/queries/count.ts index 6dd4f8469e..3efd8d0904 100644 --- a/frontend/src/lib/components/apps/components/display/dbtable/queries/count.ts +++ b/frontend/src/lib/components/apps/components/display/dbtable/queries/count.ts @@ -34,7 +34,7 @@ function makeCountQuery( } else { quicksearchCondition += ` (:quicksearch = '' OR 1 = 1)` } - query += `SELECT COUNT(*) as count FROM \`${table}\`` + query += `SELECT COUNT(*) as count FROM ${table}` break case 'postgresql': if (filteredColumns.length > 0) { @@ -44,7 +44,7 @@ function makeCountQuery( } else { quicksearchCondition += `($1 = '' OR 1 = 1)` } - query += `SELECT COUNT(*) as count FROM "${table}"` + query += `SELECT COUNT(*) as count FROM ${table}` break case 'ms_sql_server': if (filteredColumns.length > 0) { diff --git a/frontend/src/lib/components/apps/components/display/dbtable/queries/select.ts b/frontend/src/lib/components/apps/components/display/dbtable/queries/select.ts index 992010fe81..8e6a487794 100644 --- a/frontend/src/lib/components/apps/components/display/dbtable/queries/select.ts +++ b/frontend/src/lib/components/apps/components/display/dbtable/queries/select.ts @@ -28,7 +28,7 @@ function makeSnowflakeSelectQuery( const filteredColumns = buildVisibleFieldList(columnDefs, 'snowflake') const selectClause = filteredColumns.join(', ') - query += `SELECT ${selectClause} FROM "${table}"` + query += `SELECT ${selectClause} FROM ${table}` const quicksearchCondition = [ 'LENGTH(?) = 0', @@ -119,7 +119,7 @@ CASE WHEN :order_by = '${column.field}' AND :is_desc IS true THEN \`${column.fie ', ' )}) LIKE CONCAT('%', :quicksearch, '%'))` - query += `SELECT ${selectClause} FROM \`${table}\`` + query += `SELECT ${selectClause} FROM ${table}` query += ` WHERE ${whereClause ? `${whereClause} AND` : ''} ${quicksearchCondition}` query += ` ORDER BY ${orderBy}` query += ` LIMIT :limit OFFSET :offset` @@ -144,7 +144,7 @@ CASE WHEN :order_by = '${column.field}' AND :is_desc IS true THEN \`${column.fie query += `SELECT ${filteredColumns .map((column) => `${column}::text`) - .join(', ')} FROM "${table}"\n` + .join(', ')} FROM ${table}\n` query += ` WHERE ${whereClause ? `${whereClause} AND` : ''} ${quicksearchCondition}\n` query += ` ORDER BY ${orderBy}\n` query += ` LIMIT $1::INT OFFSET $2::INT` @@ -179,7 +179,8 @@ CASE WHEN :order_by = '${column.field}' AND :is_desc IS true THEN \`${column.fie if ( column.datatype === 'JSON' || column.datatype.startsWith('STRUCT') || - column.datatype.startsWith('ARRAY') + column.datatype.startsWith('ARRAY') || + column.datatype === 'GEOGRAPHY' ) { return ` (CASE WHEN @order_by = '${column.field}' AND @is_desc = false THEN TO_JSON_STRING(${column.field}) END) ASC, @@ -197,11 +198,12 @@ CASE WHEN :order_by = '${column.field}' AND :is_desc IS true THEN \`${column.fie if ( def?.datatype === 'JSON' || def?.datatype.startsWith('STRUCT') || - def?.datatype.startsWith('ARRAY') + def?.datatype.startsWith('ARRAY') || + def?.datatype === 'GEOGRAPHY' ) { return `TO_JSON_STRING(${col})` } - return `${col}` + return `CAST(${col} AS STRING)` }) .join(',') quicksearchCondition = ` (@quicksearch = '' OR REGEXP_CONTAINS(CONCAT(${searchClause}), '(?i)' || @quicksearch))` diff --git a/frontend/src/lib/components/apps/components/display/dbtable/utils.ts b/frontend/src/lib/components/apps/components/display/dbtable/utils.ts index 8d8a046434..89efcd8938 100644 --- a/frontend/src/lib/components/apps/components/display/dbtable/utils.ts +++ b/frontend/src/lib/components/apps/components/display/dbtable/utils.ts @@ -1,4 +1,4 @@ -import { JobService, Preview } from '$lib/gen' +import { JobService, Preview, ResourceService } from '$lib/gen' import type { DBSchema, DBSchemas, GraphqlSchema, SQLSchema } from '$lib/stores' import { buildClientSchema, @@ -64,6 +64,10 @@ export async function loadTableMetaData( let code: string = '' if (resourceType === 'mysql') { + const resourceObj = await ResourceService.getResourceValue({ + workspace, + path: resource.split(':')[1] + }) code = ` SELECT COLUMN_NAME as field, @@ -76,7 +80,9 @@ export async function loadTableMetaData( FROM INFORMATION_SCHEMA.COLUMNS WHERE - TABLE_NAME = '${table}' + TABLE_NAME = '${table.split('.').reverse()[0]}' AND TABLE_SCHEMA = '${ + table.split('.').reverse()[1] ?? resourceObj?.database ?? '' + }' ORDER BY ORDINAL_POSITION; ` @@ -105,7 +111,9 @@ export async function loadTableMetaData( FROM pg_catalog.pg_enum e WHERE e.enumtypid = a.atttypid FETCH FIRST ROW ONLY) as IsEnum FROM pg_catalog.pg_attribute a - WHERE a.attrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = '${table}') + WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace ns ON c.relnamespace = ns.oid WHERE relname = '${ + table.split('.').reverse()[0] + }' AND ns.nspname = '${table.split('.').reverse()[1] ?? 'public'}') AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum; @@ -138,7 +146,9 @@ ORDER BY CASE WHEN IS_NULLABLE = 'YES' THEN 'YES' ELSE 'NO' END as IsNullable, CASE WHEN DATA_TYPE = 'enum' THEN 1 ELSE 0 END as IsEnum from information_schema.columns - where table_name = '${table}' + where table_name = '${table.split('.').reverse()[0]}' and table_schema = '${ + table.split('.').reverse()[1] ?? 'PUBLIC' + }' order by ORDINAL_POSITION; ` } else if (resourceType === 'bigquery') { @@ -151,7 +161,7 @@ ORDER BY IS_NULLABLE as IsNullable, false as IsEnum FROM - test_dataset.INFORMATION_SCHEMA.COLUMNS c + ${table.split('.')[0]}.INFORMATION_SCHEMA.COLUMNS c LEFT JOIN test_dataset.INFORMATION_SCHEMA.KEY_COLUMN_USAGE p on c.table_name = p.table_name AND c.column_name = p.COLUMN_NAME @@ -674,34 +684,75 @@ export function getPrimaryKeys(tableMetadata?: TableMetadata): string[] { return r ?? [] } -export function getTablesByResource( +export async function getTablesByResource( schema: Partial>, - dbType: DbType | undefined -): string[] { + dbType: DbType | undefined, + resourcePath: string, + workspace: string +): Promise { const s = Object.values(schema)?.[0] switch (dbType) { - case 'postgresql': - case 'mysql': - case 'ms_sql_server': - case 'snowflake': - return Object.entries(s?.schema ?? {}).reduce((acc: string[], [k, v]) => { - acc.push(...Object.keys(v ?? {})) - return acc - }, []) - - case 'bigquery': { + case 'ms_sql_server': { const paths: string[] = [] for (const key in s?.schema) { - if (s?.schema.hasOwnProperty(key)) { - const subObj = s?.schema[key] - for (const subKey in subObj) { - if (subObj.hasOwnProperty(subKey)) { - paths.push(`${key}.${subKey}`) - } + for (const subKey in s.schema[key]) { + if (key === 'dbo') { + paths.push(`${subKey}`) } } } - + return paths + } + case 'mysql': { + const resourceObj = await ResourceService.getResourceValue({ + workspace, + path: resourcePath + }) + const paths: string[] = [] + for (const key in s?.schema) { + for (const subKey in s.schema[key]) { + if (key === resourceObj?.database) { + paths.push(`${subKey}`) + } else { + paths.push(`${key}.${subKey}`) + } + } + } + return paths + } + case 'snowflake': { + const paths: string[] = [] + for (const key in s?.schema) { + for (const subKey in s.schema[key]) { + if (key === 'PUBLIC') { + paths.push(`${subKey}`) + } else { + paths.push(`${key}.${subKey}`) + } + } + } + return paths + } + case 'postgresql': { + const paths: string[] = [] + for (const key in s?.schema) { + for (const subKey in s.schema[key]) { + if (key === 'public') { + paths.push(`${subKey}`) + } else { + paths.push(`${key}.${subKey}`) + } + } + } + return paths + } + case 'bigquery': { + const paths: string[] = [] + for (const key in s?.schema) { + for (const subKey in s.schema[key]) { + paths.push(`${key}.${subKey}`) + } + } return paths } diff --git a/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte index d78b08b69c..3e6c1ba99b 100644 --- a/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/flows/get/[...path]/+page.svelte @@ -12,7 +12,6 @@ import ShareModal from '$lib/components/ShareModal.svelte' import { runFormStore, userStore, workspaceStore } from '$lib/stores' import { sendUserToast } from '$lib/toast' - import Urlize from '$lib/components/Urlize.svelte' import DeployWorkspaceDrawer from '$lib/components/DeployWorkspaceDrawer.svelte' import SavedInputs from '$lib/components/SavedInputs.svelte' import {