diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts
index caef7eaad6c4..ce9dd82b126d 100644
--- a/app/client/src/ce/constants/messages.ts
+++ b/app/client/src/ce/constants/messages.ts
@@ -2503,3 +2503,9 @@ export const EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON = () =>
"Create a datasource to power your app with data.";
export const FIELD_REQUIRED_MESSAGE = () => `This field is required`;
+
+export const PREPARED_STATEMENT_WARNING = {
+ MESSAGE: () =>
+ "Prepared Statements are currently enabled, which may be causing the query error. Turn them off and try running the query again",
+ LINK: () => "Open settings",
+};
diff --git a/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.test.tsx b/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.test.tsx
new file mode 100644
index 000000000000..6615ebbaf390
--- /dev/null
+++ b/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.test.tsx
@@ -0,0 +1,235 @@
+import React from "react";
+import { render } from "@testing-library/react";
+import { Provider } from "react-redux";
+import configureStore from "redux-mock-store";
+import QueryResponseTab from "./QueryResponseTab";
+import { ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
+import type { Action } from "entities/Action";
+import { unitTestBaseMockStore } from "layoutSystems/common/dropTarget/unitTestUtils";
+import { EditorViewMode } from "ee/entities/IDE/constants";
+import { lightTheme } from "selectors/themeSelectors";
+import { ThemeProvider } from "styled-components";
+import { BrowserRouter as Router } from "react-router-dom";
+
+// Mock store
+const mockStore = configureStore([]);
+
+const defaultProps = {
+ actionName: "Test Action",
+ actionSource: {
+ name: "test source",
+ id: "test-source-id",
+ type: ENTITY_TYPE.ACTION,
+ },
+ currentActionConfig: {
+ id: "test-action-id",
+ name: "Test Action",
+ actionConfiguration: { pluginSpecifiedTemplates: [{ value: true }] },
+ userPermissions: ["execute"],
+ } as Action,
+ isRunning: false,
+ onRunClick: jest.fn(),
+ runErrorMessage: "",
+};
+
+const storeData = {
+ ...unitTestBaseMockStore,
+ evaluations: {
+ tree: {},
+ },
+ entities: {
+ plugins: {
+ list: [],
+ },
+ datasources: {
+ structure: {},
+ },
+ },
+ ui: {
+ ...unitTestBaseMockStore.ui,
+ users: {
+ featureFlag: {
+ data: {},
+ overriddenFlags: {},
+ },
+ },
+ ide: {
+ view: EditorViewMode.FullScreen,
+ },
+ debugger: {
+ context: {
+ errorCount: 0,
+ },
+ },
+ queryPane: {
+ debugger: {
+ open: true,
+ responseTabHeight: 200,
+ selectedTab: "response",
+ },
+ },
+ },
+};
+
+describe("QueryResponseTab", () => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ let store: any;
+
+ beforeEach(() => {
+ store = mockStore(storeData);
+ });
+
+ /** Test use prepared statement warning **/
+ it("1. Prepared statement warning should not be showing", () => {
+ const { container } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ // Check if the prepared statement warning is not showing
+ expect(
+ container.querySelector("[data-testid='t--prepared-statement-warning']"),
+ ).toBeNull();
+ });
+
+ it("2. Check if prepared statement warning is not showing while running the query", () => {
+ const { container } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ // Check if the prepared statement warning is showing
+ expect(
+ container.querySelector("[data-testid='t--prepared-statement-warning']"),
+ ).toBeNull();
+ });
+
+ it("3. Check if prepared statement warning is not showing when run is successful", () => {
+ store = mockStore({
+ ...storeData,
+ entities: {
+ ...storeData.entities,
+ actions: [
+ {
+ config: {
+ id: "test-action-id",
+ name: "Test Action",
+ },
+ isLoading: false,
+ data: {
+ body: [{ key: "value" }],
+ isExecutionSuccess: true,
+ },
+ },
+ ],
+ },
+ });
+
+ const { container } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ // Check if the prepared statement warning is showing
+ expect(
+ container.querySelector("[data-testid='t--prepared-statement-warning']"),
+ ).toBeNull();
+ });
+
+ it("4. Check if prepared statement warning is showing when run is failed", () => {
+ store = mockStore({
+ ...storeData,
+ entities: {
+ ...storeData.entities,
+ actions: [
+ {
+ config: {
+ id: "test-action-id",
+ name: "Test Action",
+ },
+ isLoading: false,
+ data: {
+ body: "ERROR: relation 'userssss' does not exist Position: 15",
+ isExecutionSuccess: false,
+ },
+ },
+ ],
+ },
+ });
+
+ const { container } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ // Check if the prepared statement warning is showing
+ expect(
+ container.querySelector("[data-testid='t--prepared-statement-warning']"),
+ ).not.toBeNull();
+ });
+
+ it("5. Check if prepared statement warning is not showing when prepared statement is turned off", () => {
+ store = mockStore({
+ ...storeData,
+ entities: {
+ ...storeData.entities,
+ actions: [
+ {
+ config: {
+ id: "test-action-id",
+ name: "Test Action",
+ },
+ isLoading: false,
+ data: {
+ body: "ERROR: relation 'userssss' does not exist Position: 15",
+ isExecutionSuccess: false,
+ },
+ },
+ ],
+ },
+ });
+
+ const props = {
+ ...defaultProps,
+ currentActionConfig: {
+ ...defaultProps.currentActionConfig,
+ actionConfiguration: { pluginSpecifiedTemplates: [{ value: false }] },
+ } as Action,
+ };
+
+ const { container } = render(
+
+
+
+
+
+
+ ,
+ );
+
+ // Check if the prepared statement warning is showing
+ expect(
+ container.querySelector("[data-testid='t--prepared-statement-warning']"),
+ ).toBeNull();
+ });
+});
diff --git a/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.tsx b/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.tsx
index c2d5295e65b1..a95c0cc0277b 100644
--- a/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.tsx
+++ b/app/client/src/pages/Editor/QueryEditor/QueryResponseTab.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useCallback, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import ReactJson from "react-json-view";
import {
@@ -13,7 +13,12 @@ import LogAdditionalInfo from "components/editorComponents/Debugger/ErrorLogs/co
import LogHelper from "components/editorComponents/Debugger/ErrorLogs/components/LogHelper";
import LOG_TYPE from "entities/AppsmithConsole/logtype";
import { JsonWrapper } from "components/editorComponents/Debugger/ErrorLogs/components/LogCollapseData";
-import { Callout, Flex, SegmentedControl } from "@appsmith/ads";
+import {
+ Callout,
+ Flex,
+ SegmentedControl,
+ type CalloutLinkProps,
+} from "@appsmith/ads";
import styled from "styled-components";
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
@@ -32,6 +37,12 @@ import ActionExecutionInProgressView from "components/editorComponents/ActionExe
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import BindDataButton from "./BindDataButton";
import { getQueryPaneDebuggerState } from "selectors/queryPaneSelectors";
+import { setQueryPaneConfigSelectedTabIndex } from "actions/queryPaneActions";
+import { EDITOR_TABS } from "constants/QueryEditorConstants";
+import {
+ createMessage,
+ PREPARED_STATEMENT_WARNING,
+} from "ee/constants/messages";
const HelpSection = styled.div``;
@@ -151,6 +162,7 @@ const QueryResponseTab = (props: Props) => {
let error = runErrorMessage;
let hintMessages: Array = [];
+ let showPreparedStatementWarning = false;
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let output: Record[] | null = null;
@@ -189,8 +201,31 @@ const QueryResponseTab = (props: Props) => {
error = "";
hintMessages = actionResponse.messages;
}
+
+ const { pluginSpecifiedTemplates } =
+ currentActionConfig.actionConfiguration;
+
+ if (
+ error &&
+ pluginSpecifiedTemplates &&
+ pluginSpecifiedTemplates.length > 0 &&
+ pluginSpecifiedTemplates[0].value === true
+ ) {
+ showPreparedStatementWarning = true;
+ }
}
+ const navigateToSettings = useCallback(() => {
+ dispatch(setQueryPaneConfigSelectedTabIndex(EDITOR_TABS.SETTINGS));
+ }, []);
+
+ const preparedStatementCalloutLinks: CalloutLinkProps[] = [
+ {
+ onClick: navigateToSettings,
+ children: createMessage(PREPARED_STATEMENT_WARNING.LINK),
+ },
+ ];
+
if (isRunning) {
return (
{
return (
+ {showPreparedStatementWarning && (
+
+ {createMessage(PREPARED_STATEMENT_WARNING.MESSAGE)}
+
+ )}
{error && (