1717import org .labkey .api .query .QueryForeignKey ;
1818import org .labkey .api .query .QueryKey ;
1919import org .labkey .api .query .QueryParseException ;
20+ import org .labkey .api .query .QueryParseWarning ;
21+ import org .labkey .api .query .QuerySchema ;
22+ import org .labkey .api .query .QueryService ;
2023import org .labkey .api .query .SchemaKey ;
2124import org .labkey .api .query .SimpleSchemaTreeVisitor ;
2225import org .labkey .api .query .UserSchema ;
@@ -78,7 +81,7 @@ String listSchemas(ToolContext toolContext)
7881
7982 @ Tool (description = "Provide list of tables within the provided schema." )
8083 @ RequiresPermission (ReadPermission .class )
81- String listTables (ToolContext toolContext , @ ToolParam (description = "Fully qualified schema name as it would appear in SQL e.g. Study or \" Study. Datasets\" " ) String schemaName )
84+ String listTables (ToolContext toolContext , @ ToolParam (description = "Fully qualified schema name as it would appear in SQL e.g. Study or \" Study\" . \" Datasets\" " ) String schemaName )
8285 {
8386 var json = _listTables (getContext (toolContext ), schemaName );
8487 return json .toString ();
@@ -100,7 +103,7 @@ String listColumns(
100103 @ RequiresPermission (ReadPermission .class )
101104 String getSourceForSavedQuery (
102105 ToolContext toolContext ,
103- @ ToolParam (description = "Fully qualified schema name as it would appear in SQL e.g. Study or \" Study. Datasets\" " ) String schemaName ,
106+ @ ToolParam (description = "Fully qualified schema name as it would appear in SQL e.g. Study or \" Study\" . \" Datasets\" " ) String schemaName ,
104107 @ ToolParam (description = "Table or query name as it would appear in SQL e.g. MyTable, MyQuery, or \" MyTable\" " ) String queryName
105108 )
106109 {
@@ -111,6 +114,49 @@ String getSourceForSavedQuery(
111114 throw new NotFoundException ("Could not find the source for " + schemaName + "." + queryName );
112115 }
113116
117+ @ Tool (description = "Validate SQL syntax." )
118+ @ RequiresPermission (ReadPermission .class )
119+ String validateSQL (
120+ ToolContext toolContext ,
121+ @ ToolParam (description = "Fully qualified schema name as it would appear in SQL e.g. Study or \" Study\" .\" Datasets\" " ) String schemaName ,
122+ @ ToolParam (description = "SQL source" ) String sql
123+ )
124+ {
125+ var context = getContext (toolContext );
126+
127+ SchemaKey schemaKey = getSchemaKey (schemaName );
128+ QuerySchema schema = DefaultSchema .get (context .getUser (), context .getContainer (), schemaKey );
129+
130+ try
131+ {
132+ TableInfo ti = QueryService .get ().createTable (schema , sql , null , true );
133+ var warnings = ti .getWarnings ();
134+ if (null != warnings )
135+ {
136+ var warning = warnings .stream ().findFirst ();
137+ if (warning .isPresent ())
138+ throw warning .get ();
139+ }
140+ // TODO if that worked, let have the DB check it too
141+ // if (ti.getSqlDialect().isPostgreSQL())
142+ // {
143+ // var parameters = ti.getNamedParameters();
144+ // if (parameters.isEmpty())
145+ // {
146+ // SQLFragment sqlPrepare = new SQLFragment("PREPARE validate AS SELECT * FROM ").append(ti.getFromSQL("MYVALIDATEQUERY__"));
147+ // new SqlExecutor(ti.getSchema().getScope()).execute(sqlPrepare);
148+ // }
149+ // }
150+ }
151+ catch (Exception x )
152+ {
153+ // CONSIDER remove line line/character information from DB errors as they won't match the LabKey SQL
154+ return "That SQL caused the " + (x instanceof QueryParseWarning ? "warning" : "error" ) + " below:\n ```" + x .getMessage () + "```" ;
155+ }
156+ return "success" ;
157+ }
158+
159+
114160 /* For now, list all schemas. CONSIDER support incremental querying. */
115161 public static Map <SchemaKey , UserSchema > _listAllSchemas (DefaultSchema root )
116162 {
@@ -309,7 +355,7 @@ static String normalizeIdentifier(String compoundIdentifier)
309355 return new SqlParser ().parseIdentifier (compoundIdentifier ).toSQLString (true ).toLowerCase ();
310356 }
311357
312- /** JSON schema example provided by GEMINI, using triple tick-marks to delimit the machine-readable structured data
358+ /* JSON schema example provided by GEMINI, using triple tick-marks to delimit the machine-readable structured data
313359 *
314360 * Here is the database schema in JSON format:
315361 * ```{
0 commit comments