@thierrynakoa/fire-flow 12.2.2 → 13.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CREDITS.md +25 -0
- package/DOMINION-FLOW-OVERVIEW.md +182 -38
- package/README.md +399 -690
- package/TROUBLESHOOTING.md +264 -367
- package/agents/fire-debugger.md +54 -0
- package/agents/fire-executor.md +1610 -1033
- package/agents/fire-fact-checker.md +1 -1
- package/agents/fire-planner.md +85 -17
- package/agents/fire-project-researcher.md +1 -1
- package/agents/fire-researcher.md +4 -22
- package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
- package/agents/fire-reviewer.md +552 -499
- package/agents/fire-verifier.md +114 -19
- package/bin/cli.js +18 -101
- package/commands/fire-0-orient.md +2 -2
- package/commands/fire-1a-new.md +50 -15
- package/commands/fire-1c-setup.md +33 -5
- package/commands/fire-1d-discuss.md +87 -1
- package/commands/fire-2-plan.md +556 -527
- package/commands/fire-3-execute.md +2046 -1356
- package/commands/fire-4-verify.md +975 -906
- package/commands/fire-5-handoff.md +46 -5
- package/commands/fire-6-resume.md +2 -31
- package/commands/fire-add-new-skill.md +138 -19
- package/commands/fire-autonomous.md +14 -2
- package/commands/fire-complete-milestone.md +1 -1
- package/commands/fire-cost.md +179 -183
- package/commands/fire-debug.md +1 -6
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +2 -15
- package/commands/fire-map-codebase.md +1 -1
- package/commands/fire-migrate-database.md +548 -0
- package/commands/fire-new-milestone.md +1 -1
- package/commands/fire-reflect.md +1 -2
- package/commands/fire-research.md +142 -21
- package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
- package/commands/fire-scaffold.md +297 -0
- package/commands/fire-search.md +1 -2
- package/commands/fire-security-scan.md +483 -484
- package/commands/fire-setup.md +359 -0
- package/commands/fire-skill.md +770 -0
- package/commands/fire-skills-diff.md +506 -506
- package/commands/fire-skills-history.md +388 -388
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +470 -470
- package/commands/fire-test.md +5 -5
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/commands/fire-validate-skills.md +282 -0
- package/commands/fire-verify-uat.md +9 -177
- package/commands/fire-vuln-scan.md +492 -493
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -25
- package/plugin.json +7 -7
- package/references/autonomy-levels.md +235 -0
- package/references/behavioral-directives.md +95 -3
- package/references/blocker-tracking.md +1 -1
- package/references/circuit-breaker.md +93 -2
- package/references/context-engineering.md +227 -9
- package/references/honesty-protocols.md +70 -1
- package/references/issue-to-pr-pipeline.md +149 -150
- package/references/metrics-and-trends.md +1 -2
- package/references/research-improvements.md +4 -108
- package/references/sdlc-mapping.md +73 -0
- package/references/state-machine.md +151 -0
- package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
- package/skills-library/SKILLS-INDEX.md +57 -558
- package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
- package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
- package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
- package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
- package/skills-library/_general/automation/settings-gui-generator.md +172 -0
- package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
- package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
- package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
- package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
- package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
- package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
- package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
- package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
- package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
- package/skills-library/_general/frontend/color-token-migration.md +112 -0
- package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
- package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
- package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
- package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
- package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
- package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
- package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
- package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
- package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
- package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
- package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
- package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
- package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
- package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
- package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
- package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
- package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
- package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
- package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
- package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
- package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
- package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
- package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
- package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
- package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
- package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
- package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
- package/skills-library/_general/methodology/dead-code-activation.md +123 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
- package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
- package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
- package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
- package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
- package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
- package/skills-library/_general/performance/liveclock-extraction.md +112 -0
- package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
- package/skills-library/_general/performance/use-visible-interval.md +131 -0
- package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
- package/skills-library/_quarantine/README.md +30 -0
- package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
- package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
- package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
- package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
- package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
- package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
- package/skills-library/api-patterns/graphql-content-queries.md +708 -0
- package/skills-library/appointment-scheduler-design.md +423 -0
- package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
- package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
- package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
- package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
- package/skills-library/automation/scheduled-content-publishing.md +608 -0
- package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
- package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
- package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
- package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
- package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
- package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
- package/skills-library/cms-patterns/content-branch-preview.md +515 -0
- package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
- package/skills-library/cms-patterns/mdx-component-content.md +649 -0
- package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
- package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
- package/skills-library/complexity-metrics/complexity-divider.md +707 -0
- package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
- package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
- package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
- package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
- package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
- package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
- package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
- package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
- package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
- package/skills-library/creative-multimedia/og-image-generator.md +635 -0
- package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
- package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
- package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
- package/skills-library/creative-multimedia/svg-generation.md +750 -0
- package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
- package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
- package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
- package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
- package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
- package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
- package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
- package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
- package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
- package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
- package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
- package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
- package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
- package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
- package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
- package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
- package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
- package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
- package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
- package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
- package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
- package/skills-library/database-solutions/content-publishing-states.md +631 -0
- package/skills-library/database-solutions/database-schema-designer.md +522 -0
- package/skills-library/database-solutions/er-diagram-components.md +569 -0
- package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
- package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
- package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
- package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
- package/skills-library/database-solutions/normalization-validator.md +778 -0
- package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
- package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
- package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
- package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
- package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
- package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
- package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
- package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
- package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
- package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
- package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
- package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
- package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
- package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
- package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
- package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
- package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
- package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
- package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
- package/skills-library/deployment-security/SECURITY.md +41 -0
- package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
- package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
- package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
- package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
- package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
- package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
- package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
- package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
- package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
- package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
- package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
- package/skills-library/deployment-security/vps-deployment.md +135 -0
- package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
- package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
- package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
- package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
- package/skills-library/document-processing/md-to-word-converter.md +318 -0
- package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
- package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
- package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
- package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
- package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
- package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
- package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
- package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
- package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
- package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
- package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
- package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
- package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
- package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
- package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
- package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
- package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
- package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
- package/skills-library/ecommerce/inventory-stock-management.md +270 -0
- package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
- package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
- package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
- package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
- package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
- package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
- package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
- package/skills-library/excalidraw-diagrams/LICENSE +21 -0
- package/skills-library/excalidraw-diagrams/README.md +178 -0
- package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
- package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
- package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
- package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
- package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
- package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
- package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
- package/skills-library/infrastructure/observability-designer.md +264 -0
- package/skills-library/infrastructure/performance-profiler.md +621 -0
- package/skills-library/installer-wizard-patterns.md +249 -0
- package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
- package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
- package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
- package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
- package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
- package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
- package/skills-library/integrations/headless-cms-architecture.md +484 -0
- package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
- package/skills-library/integrations/payload-cms-patterns.md +674 -0
- package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
- package/skills-library/integrations/rss-podcast-integration.md +300 -0
- package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/marketing/campaign-analytics.md +97 -0
- package/skills-library/marketing/content-creator.md +105 -0
- package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
- package/skills-library/marketing/social-media-analyzer.md +81 -0
- package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
- package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
- package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
- package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
- package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
- package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
- package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
- package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
- package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
- package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
- package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
- package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
- package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
- package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
- package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
- package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
- package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
- package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
- package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
- package/skills-library/methodology/tech-debt-tracker.md +570 -0
- package/skills-library/parallel-debug/SKILL.md +60 -0
- package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
- package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
- package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
- package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
- package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
- package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
- package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
- package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
- package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
- package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
- package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
- package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
- package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
- package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
- package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
- package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
- package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
- package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
- package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
- package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
- package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
- package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
- package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
- package/skills-library/security/admin-deletion-safety.md +396 -0
- package/skills-library/security/application-vuln-patterns.md +477 -0
- package/skills-library/security/env-secrets-manager.md +686 -0
- package/skills-library/security/secure-ai-application-templates.md +347 -0
- package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
- package/skills-library/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
- package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
- package/skills-library/system-context/SKILL.md +40 -0
- package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
- package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
- package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
- package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
- package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
- package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
- package/skills-library/testing/playwright-api-security-tests.md +202 -0
- package/skills-library/toolbox/SKILL.md +84 -0
- package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
- package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
- package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
- package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
- package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
- package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills-library/wordpress-style-theme-components.md +1526 -0
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/DECISION_LOG.md +0 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +6 -6
- package/templates/skill-api-integration.md +106 -0
- package/templates/skill-architecture-pattern.md +92 -0
- package/templates/skill-debug-pattern.md +98 -0
- package/templates/skill-devops-recipe.md +107 -0
- package/templates/skill-general.md +65 -0
- package/templates/skill-ui-component.md +113 -0
- package/version.json +7 -3
- package/workflows/handoff-session.md +2 -2
- package/workflows/new-project.md +2 -2
- package/workflows/plan-phase.md +1 -1
- package/.claude-plugin/plugin.json +0 -64
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
- package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
- package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
- package/skills-library/specialists/api-architecture/api-designer.md +0 -49
- package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
- package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
- package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
- package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
- package/skills-library/specialists/backend/django-expert.md +0 -52
- package/skills-library/specialists/backend/fastapi-expert.md +0 -52
- package/skills-library/specialists/backend/laravel-specialist.md +0 -52
- package/skills-library/specialists/backend/nestjs-expert.md +0 -51
- package/skills-library/specialists/backend/rails-expert.md +0 -53
- package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
- package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
- package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
- package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
- package/skills-library/specialists/data-ml/rag-architect.md +0 -51
- package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
- package/skills-library/specialists/frontend/angular-architect.md +0 -52
- package/skills-library/specialists/frontend/flutter-expert.md +0 -51
- package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
- package/skills-library/specialists/frontend/react-native-expert.md +0 -50
- package/skills-library/specialists/frontend/vue-expert.md +0 -51
- package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
- package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
- package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
- package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
- package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
- package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
- package/skills-library/specialists/languages/cpp-pro.md +0 -74
- package/skills-library/specialists/languages/csharp-developer.md +0 -69
- package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
- package/skills-library/specialists/languages/golang-pro.md +0 -51
- package/skills-library/specialists/languages/java-architect.md +0 -49
- package/skills-library/specialists/languages/javascript-pro.md +0 -68
- package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
- package/skills-library/specialists/languages/php-pro.md +0 -49
- package/skills-library/specialists/languages/python-pro.md +0 -52
- package/skills-library/specialists/languages/react-expert.md +0 -51
- package/skills-library/specialists/languages/rust-engineer.md +0 -50
- package/skills-library/specialists/languages/sql-pro.md +0 -56
- package/skills-library/specialists/languages/swift-expert.md +0 -69
- package/skills-library/specialists/languages/typescript-pro.md +0 -51
- package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
- package/skills-library/specialists/platform/embedded-systems.md +0 -53
- package/skills-library/specialists/platform/game-developer.md +0 -53
- package/skills-library/specialists/platform/salesforce-developer.md +0 -53
- package/skills-library/specialists/platform/shopify-expert.md +0 -49
- package/skills-library/specialists/platform/wordpress-pro.md +0 -49
- package/skills-library/specialists/quality/browser-use-expert.md +0 -210
- package/skills-library/specialists/quality/code-documenter.md +0 -51
- package/skills-library/specialists/quality/code-reviewer.md +0 -67
- package/skills-library/specialists/quality/debugging-wizard.md +0 -51
- package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
- package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
- package/skills-library/specialists/quality/playwright-expert.md +0 -65
- package/skills-library/specialists/quality/spec-miner.md +0 -56
- package/skills-library/specialists/quality/test-master.md +0 -65
- package/skills-library/specialists/security/secure-code-guardian.md +0 -55
- package/skills-library/specialists/security/security-reviewer.md +0 -53
- package/skills-library/specialists/workflow/architecture-designer.md +0 -53
- package/skills-library/specialists/workflow/cli-developer.md +0 -70
- package/skills-library/specialists/workflow/feature-forge.md +0 -65
- package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
- package/skills-library/specialists/workflow/the-fool.md +0 -62
- /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: postgresql-to-mysql-runtime-translation
|
|
3
|
+
category: database-solutions
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
contributed: 2026-02-20
|
|
6
|
+
contributor: ministry-lms
|
|
7
|
+
last_updated: 2026-03-06
|
|
8
|
+
tags: [postgresql, mysql, mariadb, sql-translation, migration, runtime, knex, mern]
|
|
9
|
+
difficulty: hard
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# PostgreSQL to MySQL Runtime SQL Translation Layer
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
Migrating a large application from PostgreSQL to MySQL/MariaDB is not just a schema migration. The application code contains thousands of PG-specific SQL patterns embedded in queries: type casts (`::text`), `RETURNING` clauses, `ON CONFLICT ... DO UPDATE`, `ILIKE`, `json_agg()`, `gen_random_uuid()`, interval arithmetic, `DATE_TRUNC()`, and more.
|
|
19
|
+
|
|
20
|
+
Rewriting every query in the application is impractical for a 709K-line codebase. A **runtime translation layer** intercepts SQL before it hits the database and rewrites PG syntax to MySQL syntax, allowing gradual migration without touching every file.
|
|
21
|
+
|
|
22
|
+
**Scale of the problem:** A scan of MINISTRY-LMS found 2,639 PG-specific patterns across the server code:
|
|
23
|
+
- 671 RETURNING clauses
|
|
24
|
+
- 659 type casts (::text, ::int, etc.)
|
|
25
|
+
- 281 gen_random_uuid() calls
|
|
26
|
+
- 280 ON CONFLICT clauses
|
|
27
|
+
- 185 INTERVAL expressions
|
|
28
|
+
- 179 FILTER (WHERE) clauses
|
|
29
|
+
- 161 ILIKE operators
|
|
30
|
+
- 157 JSON operators (->>, #>>)
|
|
31
|
+
|
|
32
|
+
## Solution Pattern
|
|
33
|
+
|
|
34
|
+
Build a **sql-compat.js** middleware that sits between the application's database calls and the actual database driver. It intercepts every query, applies a chain of regex-based translations, and forwards the rewritten SQL to MySQL via Knex.
|
|
35
|
+
|
|
36
|
+
**Architecture:**
|
|
37
|
+
```
|
|
38
|
+
Application Code (PG syntax)
|
|
39
|
+
|
|
|
40
|
+
sql-compat.js (translation layer)
|
|
41
|
+
|
|
|
42
|
+
Knex Query Builder (MySQL driver)
|
|
43
|
+
|
|
|
44
|
+
MySQL/MariaDB
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Key design decisions:**
|
|
48
|
+
1. **Intercept at the tagged template level** -- PostgreSQL's `postgres.js` uses tagged template syntax. The compat layer mimics this API.
|
|
49
|
+
2. **Translation chain order matters** -- Some translations must run before others (e.g., strip type casts before parsing function calls).
|
|
50
|
+
3. **RETURNING handled via separate SELECT** -- MySQL doesn't support RETURNING; execute the INSERT/UPDATE, then SELECT the affected rows.
|
|
51
|
+
4. **Use depth-tracking for nested functions** -- Regex `[^)]+` fails on nested parens; use a parenthesis-counting loop.
|
|
52
|
+
|
|
53
|
+
## Code Example
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// sql-compat.js -- Core translation function (20+ rules)
|
|
57
|
+
function translateToMySQL(sql) {
|
|
58
|
+
let s = sql;
|
|
59
|
+
|
|
60
|
+
// 1. Strip PG type casts (longest first!)
|
|
61
|
+
s = s.replace(/::(timestamptz|timestamp|date|time|text|varchar|integer|int|bigint|boolean|bool|numeric|decimal|float|double precision|json|jsonb|uuid|bytea|smallint|real|regclass|oid|interval)/gi, '');
|
|
62
|
+
|
|
63
|
+
// 2. gen_random_uuid() -> UUID()
|
|
64
|
+
s = s.replace(/\bgen_random_uuid\(\)/gi, 'UUID()');
|
|
65
|
+
|
|
66
|
+
// 3. ILIKE -> LIKE (MySQL is case-insensitive by default with ci collation)
|
|
67
|
+
s = s.replace(/\bILIKE\b/gi, 'LIKE');
|
|
68
|
+
|
|
69
|
+
// 4. || string concat -> CONCAT()
|
|
70
|
+
// (careful: don't touch || inside quotes)
|
|
71
|
+
s = s.replace(/(\w+(?:\.\w+)?)\s*\|\|\s*('[^']*'|\w+(?:\.\w+)?)/g, 'CONCAT($1, $2)');
|
|
72
|
+
|
|
73
|
+
// 5. NOW() + INTERVAL '7 days' -> DATE_ADD(NOW(), INTERVAL 7 DAY)
|
|
74
|
+
s = s.replace(/(\w+)\s*\+\s*INTERVAL\s+'(\d+)\s+(\w+)'/gi,
|
|
75
|
+
(_, expr, num, unit) => `DATE_ADD(${expr}, INTERVAL ${num} ${unit.replace(/s$/i, '')})`);
|
|
76
|
+
|
|
77
|
+
// 6. NOW() - INTERVAL -> DATE_SUB
|
|
78
|
+
s = s.replace(/(\w+)\s*-\s*INTERVAL\s+'(\d+)\s+(\w+)'/gi,
|
|
79
|
+
(_, expr, num, unit) => `DATE_SUB(${expr}, INTERVAL ${num} ${unit.replace(/s$/i, '')})`);
|
|
80
|
+
|
|
81
|
+
// 7. DATE_TRUNC('month', col) -> DATE_FORMAT(col, '%Y-%m-01')
|
|
82
|
+
s = translateDateTrunc(s);
|
|
83
|
+
|
|
84
|
+
// 8. ON CONFLICT ... DO UPDATE -> ON DUPLICATE KEY UPDATE
|
|
85
|
+
s = translateOnConflict(s);
|
|
86
|
+
|
|
87
|
+
// 9. RETURNING clause -> strip (handled separately)
|
|
88
|
+
s = s.replace(/\s+RETURNING\s+.*/gi, '');
|
|
89
|
+
|
|
90
|
+
// 10. json_agg/array_agg -> GROUP_CONCAT wrapper (MariaDB 10.4)
|
|
91
|
+
s = replaceAggFunc(s, 'json_agg');
|
|
92
|
+
s = replaceAggFunc(s, 'array_agg');
|
|
93
|
+
|
|
94
|
+
// 11. json_build_object -> JSON_OBJECT
|
|
95
|
+
s = s.replace(/\bjson_build_object\s*\(/gi, 'JSON_OBJECT(');
|
|
96
|
+
|
|
97
|
+
// 12. COALESCE with jsonb default -> COALESCE with JSON string
|
|
98
|
+
s = s.replace(/'(\[\])'/g, "'$1'");
|
|
99
|
+
|
|
100
|
+
// 13. Boolean literals
|
|
101
|
+
s = s.replace(/\btrue\b/gi, '1');
|
|
102
|
+
s = s.replace(/\bfalse\b/gi, '0');
|
|
103
|
+
|
|
104
|
+
// 14. EXTRACT(EPOCH FROM ...) -> UNIX_TIMESTAMP(...)
|
|
105
|
+
s = s.replace(/EXTRACT\s*\(\s*EPOCH\s+FROM\s+(\w+)\s*\)/gi, 'UNIX_TIMESTAMP($1)');
|
|
106
|
+
|
|
107
|
+
// 15. Double-quoted identifiers -> backticks
|
|
108
|
+
s = translateQuotedIdentifiers(s);
|
|
109
|
+
|
|
110
|
+
// ... more rules as needed
|
|
111
|
+
|
|
112
|
+
return s;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Implementation Steps
|
|
117
|
+
|
|
118
|
+
1. **Audit the codebase** -- Run a scanner to find all PG-specific patterns and their frequency
|
|
119
|
+
2. **Create the translation function** -- Start with the top 5 most frequent patterns
|
|
120
|
+
3. **Wire into the database layer** -- Replace the PG driver import with the compat layer
|
|
121
|
+
4. **Test endpoint by endpoint** -- Hit each API route and verify the translated SQL works
|
|
122
|
+
5. **Handle RETURNING separately** -- After INSERT/UPDATE, run a SELECT to get affected rows
|
|
123
|
+
6. **Add depth-tracking** for any function replacement (not just regex)
|
|
124
|
+
7. **Order translations carefully** -- Type cast stripping must happen before function translation
|
|
125
|
+
|
|
126
|
+
## The 20+ Translation Rules (Priority Order)
|
|
127
|
+
|
|
128
|
+
| # | PG Pattern | MySQL Equivalent | Frequency |
|
|
129
|
+
|---|-----------|-----------------|-----------|
|
|
130
|
+
| 1 | `::type` casts | Strip entirely | 659 |
|
|
131
|
+
| 2 | `RETURNING *` | Separate SELECT after INSERT/UPDATE | 671 |
|
|
132
|
+
| 3 | `gen_random_uuid()` | `UUID()` | 281 |
|
|
133
|
+
| 4 | `ON CONFLICT ... DO UPDATE` | `ON DUPLICATE KEY UPDATE` | 280 |
|
|
134
|
+
| 5 | `+ INTERVAL '7 days'` | `DATE_ADD(..., INTERVAL 7 DAY)` | 185 |
|
|
135
|
+
| 6 | `FILTER (WHERE ...)` | `CASE WHEN ... THEN ... END` inside aggregate | 179 |
|
|
136
|
+
| 7 | `ILIKE` | `LIKE` (with ci collation) | 161 |
|
|
137
|
+
| 8 | `->>`/`#>>` JSON | `JSON_UNQUOTE(JSON_EXTRACT(...))` | 157 |
|
|
138
|
+
| 9 | `json_agg()` | `CONCAT('[', GROUP_CONCAT(...), ']')` | ~50 |
|
|
139
|
+
| 10 | `array_agg()` | `CONCAT('[', GROUP_CONCAT(...), ']')` | ~30 |
|
|
140
|
+
| 11 | `DATE_TRUNC('unit', col)` | `DATE_FORMAT(col, pattern)` | ~40 |
|
|
141
|
+
| 12 | `string \|\| string` | `CONCAT(a, b)` | ~30 |
|
|
142
|
+
| 13 | Boolean `true`/`false` | `1`/`0` | ~100 |
|
|
143
|
+
| 14 | `EXTRACT(EPOCH FROM)` | `UNIX_TIMESTAMP()` | ~10 |
|
|
144
|
+
| 15 | `json_build_object()` | `JSON_OBJECT()` | ~20 |
|
|
145
|
+
| 16 | `to_jsonb(expr)` | `JSON_QUOTE(expr)` | ~5 |
|
|
146
|
+
| 17 | `TO_CHAR(date, fmt)` | `DATE_FORMAT(date, fmt)` | ~20 |
|
|
147
|
+
| 18 | `split_part(str, d, n)` | `SUBSTRING_INDEX()` nesting | ~10 |
|
|
148
|
+
| 19 | `NULLS LAST/FIRST` | Strip (MySQL default) | ~15 |
|
|
149
|
+
| 20 | `LATERAL` | Strip keyword | ~5 |
|
|
150
|
+
| 21 | Full-text `@@` search | `LIKE '%term%'` fallback | ~10 |
|
|
151
|
+
|
|
152
|
+
## When to Use
|
|
153
|
+
|
|
154
|
+
- Migrating a large application from PostgreSQL to MySQL/MariaDB
|
|
155
|
+
- When rewriting every query is impractical (1000+ queries)
|
|
156
|
+
- As a temporary bridge during gradual migration
|
|
157
|
+
- When the application uses raw SQL (not just ORM/query builder)
|
|
158
|
+
- For cPanel shared hosting where only MySQL is available
|
|
159
|
+
|
|
160
|
+
## When NOT to Use
|
|
161
|
+
|
|
162
|
+
- New applications (use the target database from the start)
|
|
163
|
+
- When the application uses only ORM-generated queries (ORM handles dialect)
|
|
164
|
+
- When PostgreSQL-specific features are core to the architecture (PostGIS, full-text search, CTEs heavily)
|
|
165
|
+
- For high-performance systems where translation overhead matters
|
|
166
|
+
|
|
167
|
+
## Runtime Compatibility Fixes (v2.0 — March 2026)
|
|
168
|
+
|
|
169
|
+
These critical fixes address **driver-level behavioral differences** between PostgreSQL's `pg` driver and MySQL's `mysql2`/`knex`. They are not SQL syntax translations — they fix how JavaScript values are handled by the drivers.
|
|
170
|
+
|
|
171
|
+
### Fix 1: Undefined → Null Binding Conversion
|
|
172
|
+
|
|
173
|
+
**Problem:** PostgreSQL's `pg` driver silently converts `undefined` JavaScript values to `NULL`. MySQL's `mysql2` driver throws: `"Undefined binding(s) detected for keys [5, 19]"`. This surfaces in any INSERT/UPDATE with optional fields.
|
|
174
|
+
|
|
175
|
+
**Root cause:** Application code passes `undefined` for optional parameters (e.g., `req.body.tribute_name` when not provided). PG tolerates this; MySQL rejects it.
|
|
176
|
+
|
|
177
|
+
**Solution:** Convert `undefined → null` systemically in the compat layer — both in the tagged template parser and the `unsafe()` method:
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
// In tagged template parser (_parseTemplate):
|
|
181
|
+
else {
|
|
182
|
+
sql += '?';
|
|
183
|
+
let safeVal = value === undefined ? null : value;
|
|
184
|
+
// ... (also handle object serialization, see Fix 2)
|
|
185
|
+
params.push(safeVal);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// In unsafe() method:
|
|
189
|
+
async unsafe(query, values = []) {
|
|
190
|
+
const safeValues = values.map(v => v === undefined ? null : v);
|
|
191
|
+
// ... rest of method uses safeValues
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Why systemic > per-call:** There are hundreds of INSERT/UPDATE calls across 32 plugins. Fixing each caller is impractical. The compat layer is the single chokepoint.
|
|
196
|
+
|
|
197
|
+
### Fix 2: Object Auto-Serialization for JSON Columns
|
|
198
|
+
|
|
199
|
+
**Problem:** PostgreSQL's `pg` driver auto-serializes JavaScript objects to `jsonb` columns. MySQL's `mysql2` driver passes the raw object, which fails or produces `[object Object]`.
|
|
200
|
+
|
|
201
|
+
**Solution:** In the tagged template parser, detect objects/arrays and JSON.stringify() them:
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// In _parseTemplate, after undefined→null conversion:
|
|
205
|
+
if (safeVal !== null && typeof safeVal === 'object' && !Array.isArray(safeVal) && !(safeVal instanceof Date)) {
|
|
206
|
+
safeVal = JSON.stringify(safeVal);
|
|
207
|
+
} else if (Array.isArray(safeVal)) {
|
|
208
|
+
safeVal = JSON.stringify(safeVal);
|
|
209
|
+
}
|
|
210
|
+
params.push(safeVal);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Date exclusion:** `Date` objects must NOT be stringified — MySQL expects them as Date objects for DATETIME columns.
|
|
214
|
+
|
|
215
|
+
### Fix 3: 4-Strategy RETURNING Emulation
|
|
216
|
+
|
|
217
|
+
**Problem:** PostgreSQL's `RETURNING *` returns the affected row(s) after INSERT/UPDATE/DELETE. MySQL has no equivalent.
|
|
218
|
+
|
|
219
|
+
**Solution:** Strip RETURNING from the SQL, execute the mutation, then re-SELECT the affected row using one of 4 strategies (tried in order):
|
|
220
|
+
|
|
221
|
+
| Strategy | Trigger | Method |
|
|
222
|
+
|----------|---------|--------|
|
|
223
|
+
| 1. UUID lookup | INSERT has `id` column with UUID value | `SELECT * FROM table WHERE id = ?` using the UUID from params |
|
|
224
|
+
| 2. Unique key | ON DUPLICATE KEY UPDATE present | `SELECT * FROM table WHERE first_col = ? LIMIT 1` |
|
|
225
|
+
| 3. LAST_INSERT_ID | Auto-increment table | `SELECT LAST_INSERT_ID()` then lookup |
|
|
226
|
+
| 4. Most recent | Fallback (has `created_at`) | `SELECT * FROM table ORDER BY created_at DESC LIMIT 1` |
|
|
227
|
+
|
|
228
|
+
For UPDATE: extract the WHERE clause and params, re-SELECT with the same WHERE.
|
|
229
|
+
|
|
230
|
+
### Fix 4: JSON Column Auto-Parsing on Read
|
|
231
|
+
|
|
232
|
+
**Problem:** PostgreSQL returns `jsonb` columns as parsed JavaScript objects. MySQL returns them as JSON strings (`'{"key":"value"}'`).
|
|
233
|
+
|
|
234
|
+
**Solution:** After every MySQL query result, auto-parse string values that look like JSON:
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
_parseJSONColumns(rows) {
|
|
238
|
+
return rows.map(row => {
|
|
239
|
+
const parsed = { ...row };
|
|
240
|
+
for (const key in parsed) {
|
|
241
|
+
const val = parsed[key];
|
|
242
|
+
if (typeof val === 'string' && val.length > 1) {
|
|
243
|
+
const first = val[0];
|
|
244
|
+
if (first === '{' || first === '[') {
|
|
245
|
+
try { parsed[key] = JSON.parse(val); } catch (e) {}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return parsed;
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Common Mistakes
|
|
255
|
+
|
|
256
|
+
- Regex alternation ordering (see companion skill: regex-alternation-ordering-sql-types)
|
|
257
|
+
- Simple `[^)]+` for function argument matching (see: mariadb-aggregate-function-replacement)
|
|
258
|
+
- Forgetting that RETURNING needs a separate SELECT (can't just strip it)
|
|
259
|
+
- Not killing stale processes after code changes (old code keeps running on the same port)
|
|
260
|
+
- Quoting reserved words without context awareness (see: reserved-word-context-aware-quoting)
|
|
261
|
+
- **Forgetting to exclude Date objects** from JSON serialization — MySQL needs Date objects for DATETIME columns
|
|
262
|
+
- **Fixing undefined→null per-call** instead of systemically — there are too many call sites
|
|
263
|
+
- **Not auto-parsing JSON on read** — causes `Object.entries()` to iterate character-by-character (see: POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX)
|
|
264
|
+
|
|
265
|
+
## Companion Tool: pg2mysql
|
|
266
|
+
|
|
267
|
+
A complete Python tool was built alongside this pattern:
|
|
268
|
+
- **Location:** `C:\path\to\repos\pg2mysql\`
|
|
269
|
+
- **Commands:** `migrate` (full migration), `schema` (DDL only), `scan` (find PG patterns), `translate` (convert single query)
|
|
270
|
+
- **Scan report:** Found 2,639 PG-specific patterns in MINISTRY-LMS
|
|
271
|
+
|
|
272
|
+
## Related Skills
|
|
273
|
+
|
|
274
|
+
- [regex-alternation-ordering-sql-types](regex-alternation-ordering-sql-types.md) - Critical regex bug pattern
|
|
275
|
+
- [mariadb-aggregate-function-replacement](mariadb-aggregate-function-replacement.md) - Aggregate function translation
|
|
276
|
+
- [reserved-word-context-aware-quoting](reserved-word-context-aware-quoting.md) - Safe reserved word handling
|
|
277
|
+
- [KNEX_DATABASE_ABSTRACTION](../deployment-security/KNEX_DATABASE_ABSTRACTION.md) - Knex as the MySQL driver
|
|
278
|
+
- [CONDITIONAL_SQL_MIGRATION_PATTERN](CONDITIONAL_SQL_MIGRATION_PATTERN.md) - Schema migration patterns
|
|
279
|
+
|
|
280
|
+
## References
|
|
281
|
+
|
|
282
|
+
- PostgreSQL to MySQL compatibility: https://dev.mysql.com/doc/refman/8.0/en/sql-function-reference.html
|
|
283
|
+
- MariaDB 10.4 function reference: https://mariadb.com/kb/en/built-in-functions/
|
|
284
|
+
- Discovered during: MINISTRY-LMS migration from Supabase PostgreSQL to XAMPP MariaDB 10.4
|
|
285
|
+
- Files: `server/database/sql-compat.js`, `C:\path\to\repos\pg2mysql\`
|
|
286
|
+
- Contributed from: ministry-lms
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: regex-alternation-ordering-sql-types
|
|
3
|
+
category: database-solutions
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-02-20
|
|
6
|
+
contributor: ministry-lms
|
|
7
|
+
last_updated: 2026-02-20
|
|
8
|
+
tags: [regex, postgresql, mysql, type-casting, mariadb, sql-translation]
|
|
9
|
+
difficulty: medium
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Regex Alternation Ordering for SQL Type Casts
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
When stripping PostgreSQL type casts (e.g., `::timestamp`, `::timestamptz`) using regex alternation, shorter prefixes match before longer ones, leaving residual characters. This causes silent data corruption that is extremely hard to debug.
|
|
19
|
+
|
|
20
|
+
**Symptom:** `NULL::timestamptz` becomes `NULLtz` instead of `NULL`. No error thrown -- the `tz` residue silently passes through to MySQL, causing downstream failures or corrupted data.
|
|
21
|
+
|
|
22
|
+
**Error message (downstream):**
|
|
23
|
+
```
|
|
24
|
+
Unknown column 'NULLtz' in 'field list'
|
|
25
|
+
```
|
|
26
|
+
or simply wrong data in results with no error at all.
|
|
27
|
+
|
|
28
|
+
## Solution Pattern
|
|
29
|
+
|
|
30
|
+
**Always order regex alternation from longest match to shortest.** When multiple alternatives share a common prefix, the longer one must come first. Regex engines try alternatives left-to-right and stop at the first match.
|
|
31
|
+
|
|
32
|
+
This is a universal regex principle but is especially dangerous in SQL translation layers where partial matches produce valid-looking but semantically wrong output.
|
|
33
|
+
|
|
34
|
+
## Code Example
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
// BEFORE (buggy) -- timestamp matches before timestamptz gets a chance
|
|
38
|
+
s = s.replace(/::(timestamp|timestamptz|date|time)/gi, '');
|
|
39
|
+
// Input: "NULL::timestamptz"
|
|
40
|
+
// Match: "::timestamp" (first alternative matches)
|
|
41
|
+
// Output: "NULLtz" <-- WRONG
|
|
42
|
+
|
|
43
|
+
// AFTER (fixed) -- longest prefix first
|
|
44
|
+
s = s.replace(/::(timestamptz|timestamp|date|time)/gi, '');
|
|
45
|
+
// Input: "NULL::timestamptz"
|
|
46
|
+
// Match: "::timestamptz" (first alternative matches the full word)
|
|
47
|
+
// Output: "NULL" <-- CORRECT
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Implementation Steps
|
|
51
|
+
|
|
52
|
+
1. Identify all regex alternation groups that strip or translate SQL tokens
|
|
53
|
+
2. Sort alternatives by length (longest first) within each group
|
|
54
|
+
3. Test with the longest variant of each prefix group (e.g., `timestamptz` not just `timestamp`)
|
|
55
|
+
|
|
56
|
+
## When to Use
|
|
57
|
+
|
|
58
|
+
- Building SQL dialect translation layers (PG -> MySQL, PG -> SQLite, etc.)
|
|
59
|
+
- Stripping type casts, function names, or keywords with regex
|
|
60
|
+
- Any regex alternation where alternatives share a common prefix
|
|
61
|
+
- Runtime SQL rewriting in middleware or compat layers
|
|
62
|
+
|
|
63
|
+
## When NOT to Use
|
|
64
|
+
|
|
65
|
+
- When alternatives don't share prefixes (no risk of partial match)
|
|
66
|
+
- When using a proper SQL parser (AST-based) instead of regex -- parsers handle this correctly
|
|
67
|
+
- Single-alternative replacements (no alternation involved)
|
|
68
|
+
|
|
69
|
+
## Common Mistakes
|
|
70
|
+
|
|
71
|
+
- Alphabetically ordering alternatives (`date|time|timestamp|timestamptz`) -- this guarantees the bug
|
|
72
|
+
- Not testing with the longest variant of shared-prefix groups
|
|
73
|
+
- Assuming the regex engine will "prefer" a longer match -- it won't; it takes the first match left-to-right
|
|
74
|
+
|
|
75
|
+
## The Debugging Trap
|
|
76
|
+
|
|
77
|
+
This bug is uniquely hard to find because:
|
|
78
|
+
- No error is thrown at the translation layer
|
|
79
|
+
- The residue (`tz`) looks like a typo, not a regex bug
|
|
80
|
+
- The failure appears at the database layer, far from the regex code
|
|
81
|
+
- Adding debug logging at the regex shows the wrong match but you must know to look there
|
|
82
|
+
|
|
83
|
+
## Related Skills
|
|
84
|
+
|
|
85
|
+
- [KNEX_DATABASE_ABSTRACTION](../deployment-security/KNEX_DATABASE_ABSTRACTION.md) - Database abstraction layer
|
|
86
|
+
- [CONDITIONAL_SQL_MIGRATION_PATTERN](CONDITIONAL_SQL_MIGRATION_PATTERN.md) - Safe SQL migration patterns
|
|
87
|
+
|
|
88
|
+
## References
|
|
89
|
+
|
|
90
|
+
- Discovered during: MINISTRY-LMS PostgreSQL to MySQL migration
|
|
91
|
+
- File: `server/database/sql-compat.js` line 76
|
|
92
|
+
- Contributed from: ministry-lms
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reserved-word-context-aware-quoting
|
|
3
|
+
category: database-solutions
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-02-20
|
|
6
|
+
contributor: pg2mysql
|
|
7
|
+
last_updated: 2026-02-20
|
|
8
|
+
tags: [mysql, mariadb, reserved-words, sql-translation, quoting, backticks]
|
|
9
|
+
difficulty: medium
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Reserved Word Context-Aware Quoting
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
When translating SQL between dialects, MySQL reserved words used as column/table names must be backtick-quoted. However, blindly quoting every occurrence of a reserved word breaks SQL keywords that happen to appear before the reserved word in a syntactic role.
|
|
19
|
+
|
|
20
|
+
**Example:** `KEY` is a MySQL reserved word. Column named `key` needs quoting: `` `key` ``. But `ON DUPLICATE KEY UPDATE` must NOT become `` ON DUPLICATE `KEY` UPDATE `` -- that's a syntax error.
|
|
21
|
+
|
|
22
|
+
**Error message:**
|
|
23
|
+
```
|
|
24
|
+
You have an error in your SQL syntax; check the manual... near '`KEY` UPDATE ...'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Solution Pattern
|
|
28
|
+
|
|
29
|
+
Maintain a **SAFE_BEFORE** set of SQL keywords that, when found immediately before a reserved word, indicate the reserved word is being used as a SQL keyword (not an identifier). Skip quoting in these contexts.
|
|
30
|
+
|
|
31
|
+
The key insight: certain keyword combinations are unambiguous. `DUPLICATE KEY`, `PRIMARY KEY`, `FOREIGN KEY`, `UNIQUE KEY`, `INDEX KEY` always use `KEY` as a keyword, never as an identifier.
|
|
32
|
+
|
|
33
|
+
## Code Example
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
# BEFORE (broken) -- blindly quotes all reserved words
|
|
37
|
+
RESERVED = {'KEY', 'STATUS', 'ORDER', 'GROUP', 'INDEX', ...}
|
|
38
|
+
|
|
39
|
+
def quote_reserved(sql):
|
|
40
|
+
for word in RESERVED:
|
|
41
|
+
sql = re.sub(
|
|
42
|
+
rf'\b{word}\b',
|
|
43
|
+
f'`{word}`',
|
|
44
|
+
sql, flags=re.IGNORECASE
|
|
45
|
+
)
|
|
46
|
+
return sql
|
|
47
|
+
# "ON DUPLICATE KEY UPDATE" -> "ON DUPLICATE `KEY` UPDATE" BROKEN
|
|
48
|
+
|
|
49
|
+
# AFTER (fixed) -- context-aware quoting
|
|
50
|
+
SAFE_BEFORE = {'DUPLICATE', 'PRIMARY', 'FOREIGN', 'UNIQUE', 'INDEX'}
|
|
51
|
+
|
|
52
|
+
def _quote_reserved_columns(self, sql: str) -> str:
|
|
53
|
+
result = sql
|
|
54
|
+
for word in RESERVED_WORDS:
|
|
55
|
+
pattern = re.compile(
|
|
56
|
+
r'(?<!\w)' + re.escape(word) + r'(?!\w)',
|
|
57
|
+
re.IGNORECASE
|
|
58
|
+
)
|
|
59
|
+
new_result = []
|
|
60
|
+
last_end = 0
|
|
61
|
+
for m in pattern.finditer(result):
|
|
62
|
+
# Look at the word immediately before this match
|
|
63
|
+
before_text = result[:m.start()].rstrip()
|
|
64
|
+
preceding_word = before_text.split()[-1].upper() if before_text.split() else ''
|
|
65
|
+
|
|
66
|
+
if preceding_word in SAFE_BEFORE:
|
|
67
|
+
# This is a SQL keyword in context, don't quote
|
|
68
|
+
new_result.append(result[last_end:m.end()])
|
|
69
|
+
else:
|
|
70
|
+
# This is an identifier, quote it
|
|
71
|
+
new_result.append(result[last_end:m.start()])
|
|
72
|
+
new_result.append(f'`{m.group()}`')
|
|
73
|
+
last_end = m.end()
|
|
74
|
+
new_result.append(result[last_end:])
|
|
75
|
+
result = ''.join(new_result)
|
|
76
|
+
return result
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
// JavaScript equivalent:
|
|
81
|
+
const SAFE_BEFORE = new Set(['DUPLICATE', 'PRIMARY', 'FOREIGN', 'UNIQUE', 'INDEX']);
|
|
82
|
+
|
|
83
|
+
function quoteReserved(sql, word) {
|
|
84
|
+
const re = new RegExp('(?<!\\w)' + word + '(?!\\w)', 'gi');
|
|
85
|
+
return sql.replace(re, (match, offset) => {
|
|
86
|
+
const before = sql.substring(0, offset).trimEnd();
|
|
87
|
+
const prevWord = before.split(/\s+/).pop().toUpperCase();
|
|
88
|
+
if (SAFE_BEFORE.has(prevWord)) return match; // keyword context
|
|
89
|
+
return '`' + match + '`'; // identifier context
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Implementation Steps
|
|
95
|
+
|
|
96
|
+
1. Build a set of MySQL reserved words that commonly appear as column names
|
|
97
|
+
2. Build a SAFE_BEFORE set of keywords that indicate syntactic (non-identifier) usage
|
|
98
|
+
3. For each reserved word occurrence, check the preceding word
|
|
99
|
+
4. If preceding word is in SAFE_BEFORE, skip quoting
|
|
100
|
+
5. Otherwise, wrap in backticks
|
|
101
|
+
|
|
102
|
+
## When to Use
|
|
103
|
+
|
|
104
|
+
- Building SQL translators that target MySQL/MariaDB
|
|
105
|
+
- PostgreSQL to MySQL migration tools (PG uses double-quotes, MySQL uses backticks)
|
|
106
|
+
- Any runtime SQL rewriting that needs to protect reserved word columns
|
|
107
|
+
- Code generators that produce MySQL DDL or DML
|
|
108
|
+
|
|
109
|
+
## When NOT to Use
|
|
110
|
+
|
|
111
|
+
- When using parameterized queries with a query builder (Knex, Sequelize, etc.) -- they handle quoting
|
|
112
|
+
- When the SQL is hand-written and you control the column names
|
|
113
|
+
- When targeting only PostgreSQL or SQLite (different reserved word lists)
|
|
114
|
+
|
|
115
|
+
## Common Mistakes
|
|
116
|
+
|
|
117
|
+
- Only checking for `DUPLICATE` but missing `PRIMARY`, `FOREIGN`, `UNIQUE`, `INDEX`
|
|
118
|
+
- Not handling case-insensitive matching (SQL keywords can be any case)
|
|
119
|
+
- Quoting inside string literals (`'some KEY value'` should NOT be touched)
|
|
120
|
+
- Not accounting for multiple spaces or newlines between the preceding keyword and the reserved word
|
|
121
|
+
|
|
122
|
+
## SAFE_BEFORE Reference
|
|
123
|
+
|
|
124
|
+
| Before Word | Context | Example |
|
|
125
|
+
|------------|---------|---------|
|
|
126
|
+
| DUPLICATE | ON DUPLICATE KEY UPDATE | Upsert syntax |
|
|
127
|
+
| PRIMARY | PRIMARY KEY | Table constraint |
|
|
128
|
+
| FOREIGN | FOREIGN KEY | Reference constraint |
|
|
129
|
+
| UNIQUE | UNIQUE KEY | Unique constraint |
|
|
130
|
+
| INDEX | INDEX/KEY | Index definition |
|
|
131
|
+
|
|
132
|
+
## Related Skills
|
|
133
|
+
|
|
134
|
+
- [regex-alternation-ordering-sql-types](regex-alternation-ordering-sql-types.md) - Type cast translation
|
|
135
|
+
- [mariadb-aggregate-function-replacement](mariadb-aggregate-function-replacement.md) - Aggregate translation
|
|
136
|
+
|
|
137
|
+
## References
|
|
138
|
+
|
|
139
|
+
- MySQL Reserved Words: https://dev.mysql.com/doc/refman/8.0/en/keywords.html
|
|
140
|
+
- Discovered during: pg2mysql tool development
|
|
141
|
+
- File: `pg2mysql/translator.py`, `_quote_reserved_columns()` method
|
|
142
|
+
- Contributed from: pg2mysql
|