SQLoom: Set-Contrastive Learning of Syntactic, Semantic, and Logical Dependencies for Text-to-SQL
Organizations: Virginia Tech · Computer Network Information Center, Chinese Academy of Sciences
Abstract
Text-to-SQL translates natural language questions into SQL queries, enabling database access without writing SQL. Fine-tuning open-weight large language models (LLMs) is cost-effective, but existing methods treat SQL as ordinary text and optimize token-level likelihood without explicitly modeling its syntactic, semantic, and logical requirements. Thus, a single incorrect alias or comparison operator can invalidate a query while contributing little to training loss. We propose SQLoom, a constraint-aware fine-tuning framework with supervision at three levels: syntactic validity under SQL grammar and database schema, semantic alignment between query decisions and the question, and logical consistency across dependent clause decisions. SQLoom extends supervised fine-tuning with a unified set-contrastive objective favoring sets of correct outputs over minimally different incorrect ones at each level. LLM agents propose this supervision, which a SQL parser and execution on counterexample databases verify. We also release Spider-Refined, a training dataset correcting 378 flawed Spider annotations and enriching database schemas. Experiments on Spider, BIRD, and three perturbed Spider variants show that SQLoom improves execution accuracy for Qwen3-1.7B from 62.9% zero-shot to 88.7% on Spider development, reaching 89.2% on Spider test and 73.4% on BIRD development. It outperforms fine-tuning, reinforcement learning, and agent-based baselines with up to 70 billion parameters. On question perturbations, SQLoom loses at most 0.6 accuracy points versus up to 12.1 for agent-based methods. It generates SQL in a single pass at 0.42s per query, 23 faster than a GPT-4-based agent method. These results demonstrate the effectiveness of set-contrastive supervision over token-level training.
Figures & tables
| Method | Training signal | Syn. | Sem. | Log. |
| CodeS ( Li et al., 2024b ) , OmniSQL ( Li et al., 2025 ) | token likelihood | ✗ | ✗ | ✗ |
| ROUTE ( Qin et al., 2025 ) , JOLT-SQL ( Song et al., 2025 ) | + schema linking | ✗ | ✗ | ✗ |
| ExCoT ( Zhai et al., 2025 ) | query-level preference | ✗ | ✗ | ✗ |
| SQL-R1 ( Ma et al., 2025 ) , Arctic ( Yao et al., 2026 ) | query-level reward | ✗ | ✗ | ✗ |
| Ma et al. ( Ma et al., 2026 ) | AST-matching reward | ✓ | ✗ | ✗ |
| EXPO-SQL ( Lee et al., 2026 ) | clause-level reward | ✓ | ✗ | ✗ |
| Syntactic | Semantic | Logical | |
| Unit | decision position | AST node aligned to element | dependent decision pair (edge of ) |
| valid next tokens | reference decision | propagated | |
| invalid next tokens | verified confusions | partially propagated | |
| position | tokens of | tokens of affected clauses | |
| Oracle | parser | execution on | execution on |
| Negatives | invalid | valid, misaligned | valid, aligned, inconsistent |
| Spider | BIRD | ||
| Method | Dev | Test | Dev |
| Fine-tuning | |||
| T5-3B + PICARD | 79.3 | 75.1 | – |
| RESDSQL-3B + NatSQL | 84.1 | 79.9 | – |
| SQL-PaLM | 82.8 | – | – |
| CodeS-7B | 85.4 | 83.5 | 57.2 |
Appendix figures & tables11 assets
Supplementary material from the paper’s appendix.
Appendix
| Edit on | Dependent | Required check |
| join path (1:N added) | aggregation, SELECT | duplicate counting; DISTINCT or key |
| target entity | GROUP BY , SELECT , join | grouping granularity |
| quantifier | HAVING , sub-query | “at least” / “all” / “none” |
| boundary / comparison | WHERE , HAVING | inclusive vs. exclusive |
| superlative / top- | ORDER BY , LIMIT , aggregation | ties; MAX vs. sort |
| filter scope | WHERE vs. HAVING | pre- vs. post-aggregation |
| Name | Value |
| Base LLM | Qwen3-1.7B |
| Agent LLM | GPT-4 |
| Fine-tuning method | LoRA, rank 16, 32, dropout 0.05 |
| LoRA target modules | q, k, v, o, gate, up, down projections |
| Learning rate / batch size | 5e-5 / 1 |
| Epochs (Stage 1 / 2 / 3) | 1 / 2 / 2 |
| Edge | Edited question | Propagated | Partially propagated |
| join path | Courses with a lab section per student? | …JOIN section …COUNT(DISTINCT T.course_id) | same join, keeps COUNT(*) |
| target entity | Students per department ? | …COUNT(DISTINCT T.id) …GROUP BY D.dept_id | keeps GROUP BY T.id |
| quantifier | Students who passed all courses. | …NOT EXISTS (…T.grade = ’F’) | keeps WHERE T.grade <> ’F’ (any passed) |
| boundary | Courses with at least 4 credits. | WHERE credits >= 4 | keeps WHERE credits > 4 |
| top- | Top student in each course. | …grade = (SELECT MAX(grade) …) | keeps ORDER BY grade DESC LIMIT 1 |
| filter scope | Departments with over 100 enrollments in total . | …GROUP BY dept_id HAVING COUNT(*) > 100 | keeps the condition in WHERE |
| Type | Definition | Example |
| Wrong table | wrong or misunderstood table | takes instead of student |
| Wrong column | mismatched, wrong-key, or non-existent column | course_id when the title is asked |
| Semantic error | misread question, wrong alias or aggregate, or missing condition | AVG for “total” |
| Wrong ordering or LIMIT | wrong LIMIT or sort direction | ASC for “highest” |
| Other model error | e.g., hard-coded outputs | returns a constant |
| Element | Reference decision | Confusion |
| entity | FROM student | FROM takes |
| attribute | course.title | course.course_id |
| value | dept_name = ’Physics’ | dept_name = ’physics’ |
| aggregation | COUNT(DISTINCT course_id) | COUNT(*) |
| comparison | credits >= 4 | credits > 4 |
| quantifier | NOT EXISTS (…) | NOT IN with nullable key |
Text-to-SQL
Text-to-SQL translates natural-language questions into executable database queries, linking user intent to schemas, values, and SQL logic.
See all 185 papers