Natural language to SQL with an LLM

更新时间:
复制 MD 格式

To make data analysis accessible for users unfamiliar with SQL, PolarDB for AI features a proprietary, built-in AI model for large language model-based Natural Language to SQL (LLM-based NL2SQL). Compared to traditional NL2SQL methods, the LLM-based NL2SQL model offers more powerful language understanding and generates SQL statements supporting more functions, such as date arithmetic. The model can even understand simple mapping relationships, such as valid->isValid=1. With proper fine-tuning, it can learn your common SQL patterns, such as automatically applying conditions like datastatus=1.

Example

/*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'List the names and leave counts of the 2 students with the most leave requests, sorted in descending order.') WITH (basic_index_name='schema_index');
output: SELECT s.student_name, COUNT(sc.id) AS leave_count FROM students s JOIN student_courses sc ON s.id = sc.student_id WHERE sc.status = 0 GROUP BY s.student_name ORDER BY leave_count DESC LIMIT 2;

NL2SQL workflow

To help you implement NL2SQL applications, we have divided the process into three stages: quick start, optimization and tuning, and production deployment.

  • Quick start stage: This stage helps you quickly build basic NL2SQL capabilities from scratch.

  • Optimization and tuning stage: This stage focuses on in-depth optimization for your specific business scenarios.

  • Production deployment stage: This stage involves deploying your NL2SQL system to the production environment.

image

Prerequisites

  • Add an AI node and set up a database account for it. For more information, see Enable the PolarDB for AI feature.

    Note
    • If you added an AI node when you purchased the cluster, you can directly set up a database account for the AI node.

    • The database account for the AI node must have Read/Write permissions to read from and write to the target database.

  • Connect to the PolarDB cluster by using the Cluster Endpoint. For more information, see Log in to PolarDB for AI.

    Important
    • When you connect to the cluster from the command line, add the -c option.

    • When you use PolarDB for AI in Data Management (DMS), DMS connects to the PolarDB cluster by using the Primary address by default, which prevents SQL statements from being routed to the AI node. You must manually change the connection address to the Cluster Endpoint.

Notes

  • How to phrase questions: A well-phrased question includes a condition, target column values, and a possible column name. For example:

    SELECT 'What is the property name of a "house" or "apartment" with more than one room?'

    In this example, 'with more than one room' is the condition, 'house' and 'apartment' are the column values, and 'property name' is a possible column name.

  • Query result accuracy: The performance of the LLM-based NL2SQL model is influenced by several factors. To ensure the query results meet your expectations, consider the following:

    • Richness of table and column comments: Adding detailed comments to each table and column improves query accuracy.

    • Match between your question and column comments: The closer the semantic match between the keywords in your question and the column comments, the higher the query accuracy.

    • Length of the generated SQL statement: The fewer columns involved and the simpler the conditions, the more accurate the query.

    • Logical complexity of the generated SQL statement: The less advanced syntax the statement uses, the more accurate the query.

Usage

Standardize data tables

For LLM-based NL2SQL to work, the model must understand your data tables and their columns. Therefore, add comments to your most-used data tables and columns before you begin.

  • Table comments

    Table comments help the LLM-based NL2SQL model understand a table's contents, which helps it accurately locate the tables required for a query. A good comment concisely summarizes the table's data (e.g., "orders" or "inventory"), should be ten words or fewer, and must avoid excessive detail.

  • Column comments

    Column comments should be common nouns or phrases that accurately describe the column's data, such as "Order ID," "Date," or "Store Name." You can also include sample data or value mappings in the column comment. For example, for a column named isValid, the comment can be Indicates whether the item is valid. 0: No. 1: Yes..

Note

If you cannot modify existing comments, you can override them using the custom table and column comment feature. For more information, see Advanced usage - Custom table and column comments.

Data preparation

Note

You can prepare test data that reflects your business scenario. The examples in this topic use the following test dataset: Test Dataset.sql.

  1. Create a retrieval index table

    To extract data from a data table, you must create a retrieval index table for it. You can specify a custom table name that complies with database naming conventions. This topic uses schema_index as an example. The following SQL statement creates a retrieval index table:

    /*polar4ai*/CREATE TABLE schema_index(id integer, table_name varchar, table_comment text_ik_max_word, table_ddl text_ik_max_word, column_names text_ik_max_word, column_comments text_ik_max_word, sample_values text_ik_max_word, vecs vector_768, ext text_ik_max_word, PRIMARY KEY (id));
    Note
    • The retrieval index table does not appear in the standard table list. To view its information, run the /*polar4ai*/SHOW TABLES; statement.

    • To drop a retrieval index table, such as schema_index, run the /*polar4ai*/DROP TABLE IF EXISTS schema_index; statement.

  2. Import data table information into the retrieval index table

    The following statement instructs PolarDB for AI to perform vectorization on all tables in the current database. By default, column value sampling is disabled.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, SELECT '') WITH (mode='async', resource='schema') INTO schema_index;

    Parameters

    • _polar4ai_text2vec is the text embedding model.

    • After INTO, specify the name of the retrieval index table that you created in Step 1: Create a retrieval index table.

    • You can configure the following parameters in the WITH() clause:

      Parameter

      Required

      Description

      mode

      Yes

      The data writing mode. This parameter must be set to async, which specifies the asynchronous mode.

      resource

      Yes

      The resource type. This parameter must be set to schema, which indicates that vectorization is performed on data table information.

      tables_included

      No

      Specifies the tables to be vectorized.

      The default is '', meaning all tables are vectorized. To specify multiple tables, provide their names as a single, comma-separated string.

      to_sample

      No

      Determines whether to sample column values. Sampling increases data import time but can improve the generated SQL quality for tables with fewer than 15 columns. Valid values:

      • 0 (default): Does not sample column values.

      • 1: Samples column values.

      columns_excluded

      No

      Specifies the columns to exclude from LLM-based NL2SQL operations.

      The default value is '', which means that all columns from all tables involved in vector conversion participate in the subsequent LLM-based NL2SQL operation. When you set this parameter, you need to concatenate the columns to be excluded from the subsequent LLM-based NL2SQL operation into a string in the table_name1.column_name1,table_name1.column_name2,table_name2.column_name1 format.

      Example: This statement performs vectorization on the graph_info, image_info, and text_info tables in the current database and enables column value sampling. It also excludes the time column in the graph_info table and the ext column in the text_info table from LLM-based NL2SQL operations.

      /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, SELECT '') WITH (mode='async', resource='schema', tables_included='graph_info,image_info,text_info', to_sample=1, columns_excluded='graph_info.time,text_info.ext') INTO schema_index;
  3. Check the task status

    The import statement returns a task_id, such as bce632ea-97e9-11ee-bdd2-492f4dfe0918. Use this ID with the following command to check the task status. The task is complete when the status shows finish.

    /*polar4ai*/SHOW TASK `bce632ea-97e9-11ee-bdd2-492f4dfe0918`;

    You can run the following SQL statement to view the retrieval index information:

    /*polar4ai*/SELECT * FROM schema_index;

Use LLM-based NL2SQL

Syntax

/*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT '<question>') WITH (basic_index_name='<basic_index_name>');

Parameters

  • Replace <question> with your natural language question. The following table provides examples.

    Topic examples

    Other scenarios

    Show the names of teachers and the courses they teach, sorted in ascending alphabetical order by teacher name.

    Find the 10 students with the most leave requests, sort them in descending order by the number of leave requests, and show their names and the leave count.

    Query the names and locations of courses held between October 1, 2023, and October 3, 2023.

    For students who have enrolled in more than two courses, show their names and course counts, sorted in descending order by the course count.

    Find the names and phone numbers of students whose address contains "Beijing" or "Shanghai".

    What are the IDs, roles, and names of professionals who have performed two or more treatments?

    What is the breed name of the most commonly kept dog breed?

    Which owner paid the most for their dog's treatment? List the owner's ID and last name.

    Tell me the ID and last name of the owner who spent the most on their dog's treatment.

    What is the description of the treatment type with the lowest total cost?

  • You can configure the following parameters in the WITH() clause:

    Parameter

    Required

    Description

    basic_index_name

    Yes

    The name of the retrieval index table in the current database.

    to_optimize

    No

    Specifies whether to perform SQL optimization. Valid values:

    • 0 (default): No optimization is performed.

    • 1: Enables SQL optimization. PolarDB for AI rewrites the generated SQL to improve its performance.

    basic_index_top

    No

    The maximum number of relevant tables to recall. Must be an integer from 1 to 10.

    • The default value is 3. A value of 1 is usually sufficient for single-table queries.

    • If a query involves multiple tables, you can set this value to 4 or higher to expand the recall and improve results.

    basic_index_threshold

    No

    The similarity threshold for table recall. The value must be in the range of (0,1].

    The default is 0.1. A table is recalled only if its relevance score exceeds this threshold.

Examples

  • Example 1: Basic query with sorting

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'Show the names of teachers and the courses they teach, sorted in ascending alphabetical order by teacher name.') WITH (basic_index_name='schema_index');
    SELECT t.teacher_name, c.course_name FROM teachers t JOIN courses c ON t.id = c.teacher_id ORDER BY t.teacher_name ASC;
  • Example 2: Conditional query with limiting and sorting

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'Find the 2 students with the most leave requests, sort them in descending order by the number of leave requests, and show their names and the leave count.') WITH (basic_index_name='schema_index');
    SELECT s.student_name, COUNT(sc.id) AS leave_count FROM students s JOIN student_courses sc ON s.id = sc.student_id WHERE sc.status = 0 GROUP BY s.student_name ORDER BY leave_count DESC LIMIT 2;

Advanced usage

PolarDB for AI provides four advanced usage scenarios. If you encounter the following issues, refer to the corresponding instructions.

  • configure question template: Configure generic question templates so the model can generate SQL statements based on specific knowledge.

  • build configuration table: Pre-process questions or post-process the generated SQL statements.

  • custom table and column comments: If you cannot modify the original table or column comments, you can add new comments to override them.

  • wide table support: When a table contains too many columns or you encounter the Please use column index to avoid oversize table information. error, you can build a column index table so the model can work with wide tables.

Configure question templates

Question templates help the model understand user questions in specific knowledge domains. You can configure general question templates to provide the model with specific knowledge, which it uses to generate SQL.

Procedure

  1. Create a question template table

    The name of the question template table must start with polar4ai_nl2sql_pattern, and its schema must include the five columns defined in the following CREATE TABLE statement.

    DROP TABLE IF EXISTS `polar4ai_nl2sql_pattern`;
    CREATE TABLE `polar4ai_nl2sql_pattern` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
      `pattern_question` text COMMENT 'Template question',
      `pattern_description` text COMMENT 'Template description',
      `pattern_sql` text COMMENT 'Template SQL',
      `pattern_params` text COMMENT 'Template parameters',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

    Column descriptions

    Parameter

    Description

    template question

    A parameterized question that is the input for the LLM-based NL2SQL model.

    In the template question, write parameters in the #{XXX} format.

    template description

    A summary of the template question, with entities such as dates, years, or organizations extracted as parameters. These entities typically map to specific columns in a table.

    In the template description, you must write parameters in the [XXX] format, and their order must be consistent with the order of the parameters in the template question.

    template SQL

    The correct SQL for the template question. In this SQL, parameters from the template question are treated as variables.

    Note

    The parameters in the template question and template SQL do not have to be identical, but they must be related. For example, parameters can share a common prefix, and their values can have a one-to-one mapping. With #{category} and #{categoryCode}, when the parameter values for category are "ordinary trademark", "special trademark", and "collective trademark", the corresponding categoryCode values are 0, 1, and 2, respectively. For details, see the example below.

    template parameters

    A JSON string consisting of three parameters: table_name, param_info, and explanation.

    • table_name string: The table name used in the template SQL.

    • param_info array: Description of the parameters in the template SQL.

      • param_name string: The parameter name.

      • value array: Sample values for the parameter.

        Note
        • If the parameter has a finite set of enumerated values, list all of them in the value array if possible.

        • If you provide only sample values, list 2 to 4 examples.

        • If parameters are interdependent, map them using the array index. For example, with #{category} and #{categoryCode}, "ordinary trademark" in category corresponds to 0 in categoryCode, and "special trademark" corresponds to 1 in categoryCode. For details, see the example below.

    • explanation string: Additional notes, which usually describe requirements for the generated SQL, such as what information to return or how to interpret specific fields.

    Note

    If template parameters are not needed, you can set the value to one of the following:

    • NULL

    • An empty string

    • An empty list string: []

    Example

    Template question

    Template description

    Template SQL

    Template parameters

    Query for courses with course name #{courseName} and teaching status #{status}

    What are the courses with [Course Name] and [Teaching Status]?

    SELECT course_name, course_time, course_location 
    FROM courses 
    WHERE 
    course_name=#{courseName} 
    AND status=#{statusCode}

    [{"table_name":"courses","param_info":[{"param_name":"#{courseName}","value":["Mathematics","Physics","Chemistry","English","History","Geography","Biology","Computer Science","Art","Music","Physical Education","Programming","Literature","Psychology","Philosophy","Economics","Sociology","Physics Lab","Chemistry Lab","Biology Lab"]},{"param_name": "#{status}", "value": ["Not started","In progress"]},{"param_name": "#{statusCode}","value": [0,1]}], "explanation": "Output the course name (course_name), course time (course_time), and course location (course_location). Note: status is a constant mapping type. The variable mapping field is statusCode."}]

    What are the national standards planned for release in year #{issueDate} with project status #{projectStat}?

    What are the [Project Status] national standards planned for release in [Year]?

    SELECT DISTINCT planNum, projectCnName, projectStat 
    FROM sy_cd_me_buss_std_gjbzjh 
    WHERE 
    `planNum` IS NOT NULL 
    AND `dataStatus` != 3 
    AND `isValid` = 1 
    AND projectStat=#{projectStat} 
    AND DATE_FORMAT(`issueDate`, '%Y')=#{issueDate}

    [{"table_name":"sy_cd_me_buss_std_gjbzjh","param_info":[{"param_name":"#{issueDate}","value":[2009,2010,2011,2012]},{"param_name":"#{projectStat}","value":["Seeking comments","Published","Under review"]}],"explanation":"Output standard name (projectCnName), plan number, and project status."}]

    What are the trademarks with category #{category} and international classification #{intCls}?

    What are the trademarks for [Trademark Type] in [International Classification]?

    SELECT DISTINCT tmName, regNo, status 
    FROM sy_cd_me_buss_ip_tdmk_new 
    WHERE 
    dataStatus!=3 
    AND isValid = 1 
    AND category=#{categoryCode} 
    AND intCls=#{intClsCode}

    [{"table_name":"sy_cd_me_buss_ip_tdmk_new","param_info":[{"param_name":"#{intCls}","value":["Chemical raw materials","Paints","Cosmetics and cleaning preparations","Fuels and lubricants","Pharmaceuticals"]},{"param_name":"#{category}","value":["ordinary trademark","special trademark","collective trademark"]},{"param_name":"#{intClsCode}","value":[1,2,3,4,5]},{"param_name":"#{categoryCode}","value":[0,1,2]}],"explanation":"Output trademark name (tmName), application/registration number (regNo), and trademark status (status). Note: category is a constant mapping type. The variable mapping field is categoryCode. intCls is a constant mapping type. The variable mapping field is intClsCode."}]

    For example, to create the first template question shown in the table above, run the following SQL:

    INSERT INTO `polar4ai_nl2sql_pattern` (`pattern_question`,`pattern_description`,`pattern_sql`,`pattern_params`) VALUES ('Query for courses with course name #{courseName} and teaching status #{status}','What are the courses with 【Course Name】【Teaching Status】?','SELECT course_name, course_time, course_location FROM courses WHERE course_name=#{courseName} AND status=#{statusCode}','[{"table_name":"courses","param_info":[{"param_name":"#{courseName}","value":["Mathematics","Physics","Chemistry","English","History","Geography","Biology","Computer Science","Art","Music","Physical Education","Programming","Literature","Psychology","Philosophy","Economics","Sociology","Physics Lab","Chemistry Lab","Biology Lab"]},{"param_name": "#{status}", "value": ["Not started","In progress"]},{"param_name": "#{statusCode}","value": [0,1]}], "explanation": "Output the course name (course_name), course time (course_time), and course location (course_location). Note: status is a constant mapping type. The variable mapping field is statusCode."}]');
  2. Create a question template index table

    You can use a custom name for the index table, as long as it follows database naming conventions. This example uses pattern_index. Run the following SQL to create the question template index table:

    /*polar4ai*/CREATE TABLE pattern_index(id integer, pattern_question text_ik_max_word, pattern_description text_ik_max_word, pattern_sql text_ik_max_word, pattern_params text_ik_max_word, pattern_tables text_ik_max_word, vecs vector_768, PRIMARY KEY (id));
    Note
    • The question template index table does not appear in the database object list. To view it, run /*polar4ai*/SHOW TABLES;.

    • To delete the question template index table, for example, pattern_index, run the SQL statement /*polar4ai*/DROP TABLE IF EXISTS pattern_index;.

  3. Import data into the index table

    Note

    The question template table cannot be empty. Before running the SQL to import data, add at least one record.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, SELECT '') WITH (mode='async', resource='pattern') INTO pattern_index;

    Parameters

    • _polar4ai_text2vec is the text-to-vectorization model.

    • After INTO, specify the name of the question template index table created in Step 2.

    • You can configure multiple parameters in the WITH() clause:

      Parameter

      Required

      Description

      mode

      Yes

      Specifies the write mode. It must be async for asynchronous mode.

      resource

      Yes

      Specifies the resource type. It must be pattern to vectorize question template information.

      pattern_table_name

      No

      The name of the question template table to vectorize. This is the table name from Step 1.

      The default value is polar4ai_nl2sql_pattern, meaning vectorization is performed on the polar4ai_nl2sql_pattern table. If you set this parameter, you must specify a table name that starts with polar4ai_nl2sql_pattern.

      If you want to maintain different question template index tables for different scenarios or business domains, you can specify different table names when creating them. For example, if you create a polar4ai_nl2sql_pattern_user table for user-related scenarios, you can set the index name to pattern_index_user in Step 2. When importing the information, use the following SQL statement:

      /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, SELECT '') WITH (mode='async', resource='pattern', pattern_table_name='polar4ai_nl2sql_pattern_user') INTO pattern_index_user;
  4. Check the task status

    After running the import statement, the system returns a task_id, such as bce632ea-97e9-11ee-bdd2-492f4dfe0918. You can run the following command to check the task status.

    /*polar4ai*/SHOW TASK `bce632ea-97e9-11ee-bdd2-492f4dfe0918`;

    When the task status is finish, the import is complete, and the model can reference the question template information. You can run the following SQL statement to view the question template index information:

    /*polar4ai*/SELECT * FROM pattern_index;
    Note

    If the data in the polar4ai_nl2sql_pattern table changes, you must re-run the procedure in Step 3.

  5. Run an online query with question templates

    Run the following SQL statement to perform an online query using LLM-based NL2SQL and question templates:

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'Query for courses with the course name Mathematics and status in progress') WITH (basic_index_name='schema_index', pattern_index_name='pattern_index');
    SELECT course_name, course_time, course_location FROM courses WHERE course_name='Mathematics' AND status=1;

    Parameters

    • After SELECT, enter the question to be converted into SQL.

    • basic_index_name is the name of the current database search index table.

    • pattern_index_name is the name of the question template index table.

    • You can configure multiple parameters in the WITH() clause. For descriptions of other parameters, see Run an online query with LLM-based NL2SQL.

      Parameter

      Description

      Value range

      pattern_index_top

      The number of closest question templates to recall.

      Value range: [1,10].

      The default value is 2, which means only the top 2 templates are recalled for the current question.

      pattern_index_threshold

      The similarity threshold for recalling a question template.

      Value range: (0,1].

      The default value is 0.85, which means a template is selected only if its vector similarity score exceeds 0.85.

Create a configuration table

Use a configuration table to pre-process questions or post-process the generated SQL.

Use cases

  • Scenario 1: Replace specific terms in a question, such as names, industry jargon, or product names.

    For example: for all questions involving Zhang San, replace Zhang San with ZS001. In this case, for the questions What were Zhang San's sales last month? and What are Zhang San's total sales for this year?, you can use a configuration table to preprocess them into What were ZS001's sales last month? and What are ZS001's total sales for this year? before the final call to the large language model.

  • Scenario 2: Add extra context to questions that contain specific terms.

    For example, for all questions involving Total Sales, the calculation formula Total Sales = SUM(Sales) should be appended. Before the final call to the large model, this information can be added through a configuration table and is appended when the question meets the corresponding condition.

  • Scenario 3: Map and replace values for specific tables or columns in the final SQL.

    For example, for all SQL statements that ultimately involve the student_courses table, replace status = 'leave' with status = 0 as a fallback measure for column value mapping.

Syntax

Use the following SQL statement to create the configuration table. The table name polar4ai_nl2sql_llm_config is fixed and cannot be changed.

DROP TABLE IF EXISTS `polar4ai_nl2sql_llm_config`;
CREATE TABLE `polar4ai_nl2sql_llm_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
  `is_functional` int(11) NOT NULL DEFAULT '1' COMMENT 'Indicates if the configuration row is active',
  `text_condition` text COMMENT 'Text condition for pre-processing',
  `query_function` text COMMENT 'Query processing function',
  `formula_function` text COMMENT 'Formula information function',
  `sql_condition` text COMMENT 'SQL condition for post-processing',
  `sql_function` text COMMENT 'SQL processing function',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Note

Changes to the data in the polar4ai_nl2sql_llm_config table take effect immediately. You do not need to perform any additional operations.

Parameters

Parameter

Description

Value

Example

is_functional

Indicates if the rule in this row is active.

By default, all rules in the configuration table are applied to every NL2SQL query. To temporarily disable a configuration rule without deleting it, set is_functional to 0.
  • 1 (default): active

  • 0: inactive

  • If is_functional=1, the configuration is active.

  • If is_functional=0, the configuration is inactive.

text_condition

Pre-processing: Evaluates a condition against the question text.

If the condition is met, the functions in the query_function and formula_function columns are applied.
  • Supports three logical operators: && (AND), || (OR), and !! (NOT).

  • If text_condition is empty or an empty string, the condition matches all questions.

If text_condition is John||Lisa&&!Wang, this indicates that the condition is matched if the question contains John, or if it contains "Lisa" and does not contain "Wang".

For example:

  • Question: What are Zhang San's total sales this year? Answer: The condition is met.

  • Question What are Li Si's total sales this year?: The condition is met.

  • Question What is the total sales amount for Lisi and Wangwu this year?: Condition mismatch.

query_function

Pre-processing: Transforms the question text.

This function is applied when text_condition matches.
  • Supported methods: append, delete, and replace.

  • The value must be a JSON string.

If query_function is {"append":["一","二"],"delete":["?"],"replace":{"张三":"a","李四":"b"}}, this means that when text_condition matches, and are appended to the end of the question, and ? is deleted from the question. Finally, 张三 in the question is replaced with a, and 李四 is replaced with b.

For example:

  • Question Zhang San this year total sales is how much?: When text_condition is matched, it is ultimately processed as a this year total sales is how much one two.

  • The question What is Li Si's total sales for this year?: When text_condition is matched, it is finally processed into b what is the total sales for this year one two.

formula_function

Pre-processing: Adds contextual information, such as a formula, for business-specific concepts in a question.

This function is applied when text_condition matches.

-

If formula_function is Total Sales: SUM(Sales Amount), then during final processing, the total sales amount in the question is processed along with the SUM(Sales Amount) formula as additional information.

sql_condition

Post-processing: Evaluates a condition against the model-generated SQL statement.

If the condition is met, the function in the sql_function column is applied.

  • Supports three logical operators: && (AND), || (OR), and !! (NOT).

  • If sql_condition is empty or an empty string, the condition matches all generated SQL statements.

If sql_condition is students||student_courses&&!!courses, the condition matches if the SQL statement references the students table or the student_courses table, but not the courses table.

For example:

  • SQL statement SELECT * FROM student_courses: Matches.

  • SQL statement SELECT c.course_name FROM student_courses sc JOIN courses c ON sc.courses_id = c.id;: Does not match.

sql_function

Post-processing: Transforms the generated SQL. This is useful for enforcing value mappings based on business logic.

This function is applied when sql_condition matches.

  • Only the replace method is currently supported.

  • The value must be a JSON string.

If sql_function is set to {"replace":{"status = 'on leave'":"status = 0","status = 'on duty'":"status = 1"}}, when the sql_condition matches, status = 'on leave' in the SQL is replaced with status = 0, and status = 'on duty' is replaced with status = 1.

Example

is_functional

text_condition

query_function

formula_function

sql_condition

sql_function

1

Zhang San||Li Si&&!!Wang Wu

{"append":["one","two"],"delete":["?"],"replace":{"Zhangsan":"a","Lisi":"b"}}

1

Total Sales: SUM(Sales)

1

students||student_courses&&!!courses

{"replace":{"status = 'Leave'":"status = 0","status = 'Present'":"status = 1"}}

  1. When run without a configuration table, the following query:

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT '筛选出2个请假次数最多的学生,按照学生的请假次数降序排列,显示学生的名字和请假次数。') WITH (basic_index_name='schema_index');
    SELECT s.student_name, COUNT(sc.id) AS leave_count FROM students s JOIN student_courses sc ON s.id = sc.student_id WHERE sc.status = 0 GROUP BY s.student_name ORDER BY leave_count DESC LIMIT 2;
  2. Create the configuration table as described in the Syntax section.

  3. Add a configuration record. This rule specifies that if an SQL statement references the students table or the student_courses table, but not the courses table, the system replaces status = 0 with status = 10.

    INSERT INTO `polar4ai_nl2sql_llm_config` (`is_functional`,`sql_condition`,`sql_function`) VALUES (1,'students||student_courses&&!!courses','{"replace":{"status = 0":"status = 10"}}');
  4. Run the query from Step 1 again. The status value in the generated SQL is now replaced as specified by the rule.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT '筛选出2个请假次数最多的学生,按照学生的请假次数降序排列,显示学生的名字和请假次数。') WITH (basic_index_name='schema_index');
    SELECT s.student_name, COUNT(sc.id) AS leave_count FROM students s JOIN student_courses sc ON s.id = sc.student_id WHERE sc.status = 10 GROUP BY s.student_name ORDER BY leave_count DESC LIMIT 2;

Customize table and column comments

If you cannot modify the original comments for a table or column as described in Prepare your data tables, you can add custom comments to the polar4ai_nl2sql_table_extra_info table. These comments override the original ones when you use LLM-based NL2SQL.

Syntax

The following SQL statement creates the custom comments table. The table name polar4ai_nl2sql_table_extra_info cannot be changed.

DROP TABLE IF EXISTS `polar4ai_nl2sql_table_extra_info`;
CREATE TABLE `polar4ai_nl2sql_table_extra_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
  `table_name` text COMMENT 'Table name',
  `table_comment` text COMMENT 'Table description',
  `column_name` text COMMENT 'Column name',
  `column_comment` text COMMENT 'Column description',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Note

If you change the data in the polar4ai_nl2sql_table_extra_info table, you must re-run the step to import data table information into the schema index for the changes to take effect.

Example

  1. Create the custom comments table.

  2. Update the comment for the status column in the student_courses table. This example adds a new option mapping: 2-Absent.

    INSERT INTO `polar4ai_nl2sql_table_extra_info` (`table_name`,`table_comment`,`column_name`,`column_comment`) VALUES ('student_courses','Student-course information table','status','Student status: 0-On leave, 1-Normal, 2-Absent.');
  3. Re-run the step to import data table information into the schema index.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, SELECT '') WITH (mode='async', resource='schema') INTO schema_index;
  4. Check the task status.

    After you run the import statement, the system returns a task_id, such as bce632ea-97e9-11ee-bdd2-492f4dfe0918. Use the following command to check the import status. When taskStatus is finish, the task is complete.

    /*polar4ai*/SHOW TASK `bce632ea-97e9-11ee-bdd2-492f4dfe0918`;
  5. Run a query using LLM-based NL2SQL.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'Show the names and number of absences for the 2 students with the most absences, sorted in descending order.') WITH (basic_index_name='schema_index');
    SELECT s.student_name, COUNT(sc.id) AS absence_count FROM student_courses sc JOIN students s ON sc.student_id = s.id WHERE sc.status = 2 GROUP BY s.student_name ORDER BY absence_count DESC LIMIT 2;

    The output shows that the LLM-based NL2SQL model now correctly maps Absent to the value 2 for the status column in the student_courses table.

Support for wide tables

If your data tables include wide tables with many columns, or if you receive the Please use column index to avoid oversize table information. error when using LLM-based NL2SQL, use this procedure.

Note

When you use LLM-based NL2SQL online, both basic_index_name and pattern_index_name in the WITH() clause can use the same column_index_name. Unlike with schema or pattern indexing, this method is used only to simplify information.

For most requests, the column_index_name parameter has no effect. It is required only for NL2SQL requests that trigger the length limit. In these cases, column_index_name simplifies the table information. This may cause some loss of accuracy but effectively prevents errors in the LLM-based NL2SQL model caused by an overly long prompt.

  1. Create a column index table.

    You can use a custom name for the column index table, but it must follow database naming conventions and not conflict with the names of existing tables. Only one column index table is needed per database. Use the following CREATE TABLE statement:

    /*polar4ai*/CREATE TABLE column_index(id integer, table_name varchar, table_comment text_ik_max_word, column_name text_ik_max_word, column_comment text_ik_max_word, is_primary integer, is_foreign integer, vecs vector_768, ext text_ik_max_word, PRIMARY KEY (id));
    Note
    • The column index table is not directly displayed in the database. To view its information, run the SQL statement /*polar4ai*/SHOW TABLES;.

    • To delete the column index table, for example column_index, run the SQL statement /*polar4ai*/DROP TABLE IF EXISTS column_index;.

  2. Import column-level information from the data tables into the column index table.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_text2vec, select '') WITH (mode='async', resource='column') into column_index;
  3. Check the task status.

    After you run the import statement, the system returns a task_id, such as bce632ea-97e9-11ee-bdd2-492f4dfe0918. You can run the following command to view the import status. The task is complete when the taskStatus is finish.

    /*polar4ai*/SHOW TASK `bce632ea-97e9-11ee-bdd2-492f4dfe0918`;
  4. Use LLM-based NL2SQL online with wide tables.

    /*polar4ai*/SELECT * FROM PREDICT (MODEL _polar4ai_nl2sql, SELECT 'Sort by teacher name in ascending alphabetical order, and display the teacher''s name and the names of the courses they teach.') WITH (basic_index_name='schema_index', column_index_name='column_index');

FAQ

Syntax error with AI SQL

Running an AI SQL query (a SQL statement prefixed with /*polar4ai*/) with the PolarDB for AI feature in DMS may trigger the following error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxx' at line xxx. This error occurs because the DMS connection is not set to the Cluster Endpoint of your PolarDB cluster.

The PolarDB for AI feature runs on an AI node, but DMS connects to a PolarDB cluster using the Primary address by default. Therefore, you must modify the connection address in DMS.

  1. In DMS, after you connect to the cluster, go to the Database Instance > Logged-in Instances list in the left-side navigation pane. Right-click the target cluster and select Edit Instance.

  2. In the Edit Instance dialog box, under Overview, change Entry Method to Connection String. Then, enter the Cluster Endpoint and click Save.

  3. The original SQL window still uses the Primary address. After you change the Connection String, you must close the original SQL window and open a new one. This action applies the new connection settings.