diff --git a/.github/workflows/issue-auto-assign.yml b/.github/workflows/issue-auto-assign.yml new file mode 100644 index 0000000..40dadc3 --- /dev/null +++ b/.github/workflows/issue-auto-assign.yml @@ -0,0 +1,74 @@ +name: Auto Assign Issue on Command + +on: + issue_comment: + types: [created] + +jobs: + assign_on_command: + runs-on: ubuntu-latest + permissions: + issues: write + contents: read + steps: + - name: Assign to user on /assign command + uses: actions/github-script@v6 + with: + github-token: ${{secrets.IVORY_TOKEN}} + script: | + const commentBody = context.payload.comment.body.trim().toLowerCase(); + const commenter = context.payload.comment.user.login; + const issueNumber = context.issue.number; + const repoOwner = context.repo.owner; + const repoName = context.repo.repo; + + if (commentBody === '/assign') { + console.log(`User @${commenter} commented "/assign" on issue #${issueNumber}. Attempting to assign.`); + + if (commenter.endsWith('[bot]') || commenter === 'github-actions[bot]') { + console.log(`Skipping assignment for bot user: ${commenter}`); + return; + } + + const { data: issue } = await github.rest.issues.get({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber + }); + + if (issue.assignees && issue.assignees.some(a => a.login === commenter)) { + console.log(`Issue #${issueNumber} is already assigned to @${commenter}. No action needed.`); + return; + } + + if (issue.state === 'closed') { + console.log(`Issue #${issueNumber} is closed. No assignment will be made.`); + await github.rest.issues.createComment({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber, + body: `Hi @${commenter}, issue #${issueNumber} is closed and cannot be assigned.` + }); + return; + } + + try { + await github.rest.issues.addAssignees({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber, + assignees: [commenter] + }); + console.log(`Successfully assigned issue #${issueNumber} to @${commenter}.`); + } catch (error) { + console.error(`Error assigning issue #${issueNumber} to @${commenter}:`, error); + await github.rest.issues.createComment({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber, + body: `Hi @${commenter}, I encountered an error trying to assign you to issue #${issueNumber}. Please check permissions or assign manually. \nError: ${error.message}` + }); + } + } else { + console.log(`Comment by @${commenter} on issue #${issueNumber} was not an "/assign" command. Body: "${context.payload.comment.body.trim()}"`); + } diff --git a/.github/workflows/merge-build-push.yml b/.github/workflows/merge-build-push.yml new file mode 100644 index 0000000..607fe56 --- /dev/null +++ b/.github/workflows/merge-build-push.yml @@ -0,0 +1,269 @@ +name: Build , Push to web, Deploy Antora Docs + +on: + pull_request_target: + types: + - closed + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + if: github.event.pull_request.merged == true + permissions: + contents: write + pull-requests: write + + steps: + - name: PR was merged + run: | + echo "PR #${{ github.event.pull_request.number }} was merged into ${{ github.event.pull_request.base.ref }}." + echo "Head commit was: ${{ github.event.pull_request.head.sha }}" + + - name: Checkout Documentation Repository (ivorysql_doc) + uses: actions/checkout@v4 + with: + path: ivorysql_doc + + - name: Checkout Doc Builder Repository (doc_builder) + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/ivory-doc-builder + path: ivory-doc-builder + + - name: Determine Latest Version from ivorysql_docs branches + id: latest_version_step + shell: bash + run: | + echo "Detecting latest version from remote branches of IvorySQL/ivorysql_docs..." + LATEST_VERSION_NUMBER=$( \ + git ls-remote --heads --refs "https://github.com/IvorySQL/ivorysql_docs.git" 'refs/heads/v*.*' | \ + sed 's_^[^\t]*\trefs/heads/v__g' | \ + grep -E '^[0-9]+\.[0-9]+(\.[0-9]+)?$' | \ + sort -V | \ + tail -n1 \ + ) + + if [[ -z "$LATEST_VERSION_NUMBER" ]]; then + echo "::error::Could not determine latest version from branches. Please check git ls-remote command and repo accessibility." + exit 1 + fi + + echo "Detected latest version number: $LATEST_VERSION_NUMBER" + echo "version=$LATEST_VERSION_NUMBER" >> "$GITHUB_OUTPUT" + + - name: Install yq + run: | + sudo apt-get update -y + sudo apt-get install -y jq + sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq + sudo chmod +x /usr/bin/yq + yq --version + + - name: Modify Antora Playbooks + working-directory: ./ivory-doc-builder + env: + DETECTED_VERSION: '${{ steps.latest_version_step.outputs.version }}' + START_PAGE_COMPONENT_NAME: "ivorysql-doc" + START_PAGE_FILE_PATH: "welcome.adoc" + run: | + PLAYBOOK_FILES=("antora-playbook-CN.yml" "antora-playbook-EN.yml") + + for PLAYBOOK_FILE in "${PLAYBOOK_FILES[@]}"; do + if [ -f "$PLAYBOOK_FILE" ]; then + echo "--- Modifying Playbook: $PLAYBOOK_FILE ---" + echo "Original content of $PLAYBOOK_FILE:" + cat "$PLAYBOOK_FILE" + echo # Newline for better readability + + if [[ -n "$DETECTED_VERSION" ]]; then + NEW_START_PAGE="${START_PAGE_COMPONENT_NAME}::v${DETECTED_VERSION}/${START_PAGE_FILE_PATH}" + yq -i ".site.start_page = \"$NEW_START_PAGE\"" "$PLAYBOOK_FILE" + echo "Updated .site.start_page in $PLAYBOOK_FILE to: $NEW_START_PAGE" + else + echo "WARNING: DETECTED_VERSION is empty. Skipping start_page update for $PLAYBOOK_FILE." + fi + echo "Modified content of $PLAYBOOK_FILE:" + cat "$PLAYBOOK_FILE" + echo "--- Finished modification for $PLAYBOOK_FILE ---" + echo # Newline + else + echo "WARNING: Playbook file $PLAYBOOK_FILE not found in $(pwd)." + fi + done + + - name: Checkout Web Repository (web) + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/ivorysql_web + path: www_publish_target + token: ${{ secrets.WEB_TOKEN }} + + - name: Setup Ruby and Bundler + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0' + + - name: Install Asciidoctor PDF and related Gems + run: | + echo "Installing Asciidoctor PDF gems..." + gem install asciidoctor-pdf --version "~>2.3.19" + gem install rouge + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.15' + + - name: Install Antora CLI + run: | + echo "Installing Antora packages local..." + npm install --global antora@3.1.7 @antora/lunr-extension @antora/pdf-extension @node-rs/jieba + + - name: Build English Documentation + working-directory: ./ivory-doc-builder + run: | + echo "Current directory: $(pwd)" + echo "Building English site..." + ls ../www_publish_target/ + npx antora generate --stacktrace --to-dir ../www_publish_target/docs/en antora-playbook-EN.yml + + - name: Build Chinese Documentation + working-directory: ./ivory-doc-builder + run: | + echo "Building Chinese site..." + npx antora generate --stacktrace --to-dir ../www_publish_target/docs/cn antora-playbook-CN.yml + + - name: Move and Rename PDF Files + id: process_pdfs + working-directory: ./www_publish_target + run: | + echo "--- Searching for PDF files to move and rename ---" + + PDF_FILES_FOUND=$(find . -type f -path '*/_exports/index.pdf') + + if [ -z "${PDF_FILES_FOUND}" ]; then + echo "No PDF files found to move. Skipping." + else + echo "Found PDF files to process:" + echo "${PDF_FILES_FOUND}" + + echo "${PDF_FILES_FOUND}" | while read PDF_FILE; do + # ./docs/cn/ivorysql-doc/master/_exports/index.pdf -> ./docs/cn/ivorysql-doc/master + BASE_DIR="${PDF_FILE%/_exports/index.pdf}" + + NEW_PDF_PATH="${BASE_DIR}/ivorysql.pdf" + + echo "Moving '${PDF_FILE}' to '${NEW_PDF_PATH}'" + mv "${PDF_FILE}" "${NEW_PDF_PATH}" + done + + echo "--- Cleaning up empty _exports directories ---" + find . -type d -name '_exports' -empty -delete + fi + + echo "--- PDF processing complete ---" + + - name: Commit and Push to web Repository new branch , pull request + id: commit_push_new_branch + working-directory: ./www_publish_target + env: + OPEN_PUSH_PR: true + run: | + echo "push_pr=${OPEN_PUSH_PR}" >> $GITHUB_OUTPUT + echo "--- Preparing to commit and push changes ---" + echo "--- Git status ---" + GIT_STATUS_OUTPUT=$(git status --porcelain) + echo "${GIT_STATUS_OUTPUT}" + echo "--- End of git status --porcelain output ---" + + git config user.name "IvorySQL Actions Bot" + git config user.email "actions-bot@users.noreply.github.com" + + if [ -z "${GIT_STATUS_OUTPUT}" ]; then + echo "No changes to commit." + echo "changes_detected=false" >> $GITHUB_OUTPUT + else + echo "Changes detected. Proceeding with add, commit, and push." + if [[ "${OPEN_PUSH_PR}" == "true" ]]; then + NEW_BRANCH_NAME="docs-update-${{ github.run_attempt }}-$(date +'%Y-%m-%d-%H%M%S')" + echo "Generated new branch name: ${NEW_BRANCH_NAME}" + echo "new_branch_name=${NEW_BRANCH_NAME}" >> $GITHUB_OUTPUT + echo "changes_detected=true" >> $GITHUB_OUTPUT + git checkout -b "${NEW_BRANCH_NAME}" + git add . + COMMIT_MESSAGE="docs: Regenerate Antora site from IvorySQL/ivorysql_docs commit ${{ github.event.head_commit.id || github.sha }}" + git commit -m "${COMMIT_MESSAGE}" + git push origin "${NEW_BRANCH_NAME}" + else + echo "Pushing changes to master branch." + git add . + COMMIT_MESSAGE="docs: Regenerate Antora site from IvorySQL/ivorysql_docs commit ${{ github.event.head_commit.id || github.sha }}" + git commit -m "${COMMIT_MESSAGE}" + git push origin master + fi + fi + + - name: Create or Update Pull Request with GitHub CLI + id: cpr + if: steps.commit_push_new_branch.outputs.push_pr == 'true' && steps.commit_push_new_branch.outputs.changes_detected == 'true' && steps.commit_push_new_branch.outputs.new_branch_name != '' + working-directory: ./www_publish_target + env: + GH_TOKEN: ${{ secrets.WEB_TOKEN }} + PARAM_BASE_BRANCH: master + PARAM_HEAD_BRANCH: ${{ steps.commit_push_new_branch.outputs.new_branch_name }} + PARAM_TITLE: "Docs: Automated update from IvorySQL/ivorysql_docs commit ${{ github.event.head_commit.id || github.sha }}" + PARAM_BODY: | + Automated Antora site regeneration based on changes in the IvorySQL/ivorysql_docs repository. + + Source commit: `${{ github.server_url }}/${{ github.repository_owner }}/ivorysql_docs/commit/${{ github.event.head_commit.id || github.sha }}` + + - Auto-generated by gh pr create + PARAM_DRAFT: "false" + run: | + echo "Attempting to create or update Pull Request for branch '${PARAM_HEAD_BRANCH}' into '${PARAM_BASE_BRANCH}'" + + DRAFT_FLAG_STRING="" + if [[ "${PARAM_DRAFT}" == "true" ]]; then + DRAFT_FLAG_STRING="--draft" + fi + + echo "Executing: gh pr create --base \"${PARAM_BASE_BRANCH}\" --head \"${PARAM_HEAD_BRANCH}\" --title --body-file <(echo body) ${DRAFT_FLAG_STRING}" + + if gh pr create \ + --base "${PARAM_BASE_BRANCH}" \ + --head "${PARAM_HEAD_BRANCH}" \ + --title "${PARAM_TITLE}" \ + --body-file <(echo "${PARAM_BODY}") \ + ${DRAFT_FLAG_STRING}; then + echo "Pull Request created or already exists and metadata might have been updated." + else + echo "'gh pr create' command indicated an issue or no action was taken." + + EXISTING_PR_URL=$(gh pr view "${PARAM_HEAD_BRANCH}" --json url -q ".url" 2>/dev/null || echo "") + if [[ -n "$EXISTING_PR_URL" ]]; then + echo "An existing PR was found for branch '${PARAM_HEAD_BRANCH}': ${EXISTING_PR_URL}" + echo "Proceeding to enable auto-merge for this existing PR." + else + echo "::error::Failed to create PR and no existing PR found for branch '${PARAM_HEAD_BRANCH}'. Cannot enable auto-merge." + exit 1 + fi + fi + + - name: Enable Auto-Merge for PR + if: steps.cpr.outcome == 'success' && steps.commit_push_new_branch.outputs.push_pr == 'true' && steps.commit_push_new_branch.outputs.changes_detected == 'true' && steps.commit_push_new_branch.outputs.new_branch_name != '' + working-directory: ./www_publish_target + env: + GH_TOKEN: ${{ secrets.WEB_TOKEN }} + PR_HEAD_BRANCH: ${{ steps.commit_push_new_branch.outputs.new_branch_name }} + PR_BASE_BRANCH: master + MERGE_STRATEGY: MERGE + run: | + echo "Attempting to enable auto-merge for PR from branch '$PR_HEAD_BRANCH' to '$PR_BASE_BRANCH'" + if gh pr merge "$PR_HEAD_BRANCH" \ + --${MERGE_STRATEGY,,} \ + --delete-branch; then + echo "Auto-merge enabled successfully for PR from branch '$PR_HEAD_BRANCH'." + else + echo "::warning::Failed to enable auto-merge for PR from branch '$PR_HEAD_BRANCH'." + echo "This might be because the PR is not mergeable (e.g., has conflicts, is a draft PR), requires reviews, auto-merge is already enabled, or the PR could not be uniquely identified by branch name." + fi diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml new file mode 100644 index 0000000..d121485 --- /dev/null +++ b/.github/workflows/pr-preview.yml @@ -0,0 +1,187 @@ +name: Pr preview + +on: + pull_request_target: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + deployments: write + statuses: write + + steps: + - name: Checkout Documentation Repository (ivorysql_doc) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + path: ivorysql_doc + + - name: Fetch All Relevant Branches into Local Docs Repo + working-directory: ./ivorysql_doc + run: | + echo "Fetching all branches from origin to update local remote-tracking branches..." + git fetch origin --prune --no-tags + + echo "--- Fetched Remote-Tracking Branches ---" + git branch -r + + - name: Checkout Doc Builder Repository (doc_builder) + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/ivory-doc-builder + path: ivory-doc-builder + + - name: Determine Latest Version from ivorysql_docs branches + id: latest_version_step + shell: bash + run: | + echo "Detecting latest version from remote branches of ${{ github.repository_owner }}/ivorysql_docs..." + LATEST_VERSION_NUMBER=$( \ + git ls-remote --heads --refs "https://github.com/${{ github.repository_owner }}/ivorysql_docs.git" 'refs/heads/v*.*' | \ + sed 's_^[^\t]*\trefs/heads/v__g' | \ + grep -E '^[0-9]+\.[0-9]+(\.[0-9]+)?$' | \ + sort -V | \ + tail -n1 \ + ) + + if [[ -z "$LATEST_VERSION_NUMBER" ]]; then + echo "::error::Could not determine latest version from branches. Please check git ls-remote command and repo accessibility." + exit 1 + fi + + echo "Detected latest version number: $LATEST_VERSION_NUMBER" + echo "version=$LATEST_VERSION_NUMBER" >> "$GITHUB_OUTPUT" + + - name: Install yq + run: | + sudo apt-get update -y + sudo apt-get install -y jq + sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq + sudo chmod +x /usr/bin/yq + yq --version + + - name: Modify Antora Playbooks for Local PR Build + working-directory: ./ivory-doc-builder + env: + DETECTED_VERSION: '${{ steps.latest_version_step.outputs.version }}' + START_PAGE_COMPONENT_NAME: "ivorysql-doc" + START_PAGE_FILE_PATH: "welcome.adoc" + run: | + PLAYBOOK_FILES=("antora-playbook-CN.yml" "antora-playbook-EN.yml") + NEW_LOCAL_URL="../ivorysql_doc" + + for PLAYBOOK_FILE in "${PLAYBOOK_FILES[@]}"; do + if [ -f "$PLAYBOOK_FILE" ]; then + echo "--- Modifying Playbook: $PLAYBOOK_FILE ---" + echo "Original content of $PLAYBOOK_FILE:" + cat "$PLAYBOOK_FILE" + echo # Newline for better readability + + yq -i ".content.sources[0].url = \"$NEW_LOCAL_URL\"" "$PLAYBOOK_FILE" + + yq -i ".content.sources[0].branches = [\"HEAD\"]" "$PLAYBOOK_FILE" + + yq -i ".content.sources[0].edit_url = false" "$PLAYBOOK_FILE" + if [[ -n "$DETECTED_VERSION" ]]; then + NEW_START_PAGE="${START_PAGE_COMPONENT_NAME}::v${DETECTED_VERSION}/${START_PAGE_FILE_PATH}" + yq -i ".site.start_page = \"$NEW_START_PAGE\"" "$PLAYBOOK_FILE" + echo "Updated .site.start_page in $PLAYBOOK_FILE to: $NEW_START_PAGE" + else + echo "WARNING: DETECTED_VERSION is empty. Skipping start_page update for $PLAYBOOK_FILE." + fi + yq -i ".site.title = .site.title + \" (PR Preview)\"" "$PLAYBOOK_FILE" + echo "Modified content of $PLAYBOOK_FILE:" + cat "$PLAYBOOK_FILE" + echo "--- Finished modification for $PLAYBOOK_FILE ---" + echo # Newline + else + echo "WARNING: Playbook file $PLAYBOOK_FILE not found in $(pwd)." + fi + done + + - name: Checkout WWW Repository (www) + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/ivorysql_web + path: www_publish_target + + - name: Setup Ruby and Bundler + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0' + + - name: Install Asciidoctor PDF and related Gems + run: | + echo "Installing Asciidoctor PDF gems..." + gem install asciidoctor-pdf --version "~>2.3.19" + gem install rouge + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.15' + + - name: Install Antora CLI + run: | + echo "Installing Antora packages local..." + npm install --global antora@3.1.7 @antora/lunr-extension @antora/pdf-extension @node-rs/jieba + + - name: Build English Documentation + working-directory: ./ivory-doc-builder + run: | + echo "Current directory: $(pwd)" + echo "Building English site..." + #mkdir -p ../www_publish_target/docs/en + npx antora generate --stacktrace --to-dir ../www_publish_target/docs/en antora-playbook-EN.yml + + - name: Build Chinese Documentation + working-directory: ./ivory-doc-builder + run: | + echo "Building Chinese site..." + #mkdir -p ../www_publish_target/docs/cn + npx antora generate --stacktrace --to-dir ../www_publish_target/docs/cn antora-playbook-CN.yml + + - name: Deploy to Netlify + id: netlify_deploy + uses: nwtgck/actions-netlify@v3.0 + with: + publish-dir: './www_publish_target/docs' + production-branch: test + github-token: ${{ secrets.GITHUB_TOKEN }} + deploy-message: "Deploy preview for PR #${{ github.event.number }}" + enable-pull-request-comment: false + enable-commit-comment: false + enable-commit-status: true + alias: pr-${{ github.event.number }}-doc + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + timeout-minutes: 5 + + - name: Post Custom Preview Links Comment + if: steps.netlify_deploy.outputs.deploy-url + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const baseUrl = '${{ steps.netlify_deploy.outputs.deploy-url }}'; + + const enUrl = `${baseUrl}/en`; + + const body = ` + 🚀 **IvorySQL-Docs Preview Ready** + + - **Chinese Preview:** [${baseUrl}](${baseUrl}) + - **English Preview:** [${enUrl}](${enUrl}) + `; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: body + }); \ No newline at end of file diff --git a/CN/antora.yml b/CN/antora.yml index 1d17feb..c7c6738 100644 --- a/CN/antora.yml +++ b/CN/antora.yml @@ -1,7 +1,7 @@ name: ivorysql-doc title: IvorySQL -version: v3.0 -start_page: v3.0/welcome.adoc +version: v1.17 +start_page: v1.17/welcome.adoc asciidoc: attributes: source-language: asciidoc@ diff --git a/CN/modules/ROOT/images/p20.jpg b/CN/modules/ROOT/images/p20.jpg new file mode 100644 index 0000000..b200c5a Binary files /dev/null and b/CN/modules/ROOT/images/p20.jpg differ diff --git a/CN/modules/ROOT/images/p21.jpg b/CN/modules/ROOT/images/p21.jpg new file mode 100644 index 0000000..a0c62a6 Binary files /dev/null and b/CN/modules/ROOT/images/p21.jpg differ diff --git a/CN/modules/ROOT/images/p22.jpg b/CN/modules/ROOT/images/p22.jpg new file mode 100644 index 0000000..1736f47 Binary files /dev/null and b/CN/modules/ROOT/images/p22.jpg differ diff --git a/CN/modules/ROOT/images/p31.png b/CN/modules/ROOT/images/p31.png new file mode 100644 index 0000000..51e0e02 Binary files /dev/null and b/CN/modules/ROOT/images/p31.png differ diff --git a/CN/modules/ROOT/images/p32.png b/CN/modules/ROOT/images/p32.png new file mode 100644 index 0000000..d8cc211 Binary files /dev/null and b/CN/modules/ROOT/images/p32.png differ diff --git a/CN/modules/ROOT/nav.adoc b/CN/modules/ROOT/nav.adoc index 889241c..f9b77a8 100644 --- a/CN/modules/ROOT/nav.adoc +++ b/CN/modules/ROOT/nav.adoc @@ -1,24 +1,38 @@ -* xref:v3.0/welcome.adoc[欢迎] -* xref:v3.0/1.adoc[发行说明] -* xref:v3.0/2.adoc[关于IvorySQL] +* xref:v1.17/welcome.adoc[欢迎] +* xref:v1.17/1.adoc[发行说明] +* xref:v1.17/2.adoc[关于IvorySQL] * IvorySQL入门 -** xref:v3.0/3.adoc[用户使用手册] -** xref:v3.0/4.adoc[管理员指南] -** xref:v3.0/5.adoc[运维人员指南] -* xref:v3.0/6.adoc[安装部署] -* xref:v3.0/7.adoc[开发者指南] -* xref:v3.0/8.adoc[运维管理指南] -* xref:v3.0/9.adoc[迁移指南] -* xref:v3.0/10.adoc[社区贡献指南] -* xref:v3.0/11.adoc[工具参考] -* xref:v3.0/12.adoc[FAQ] -* 功能列表 -** xref:v3.0/14.adoc[1、Ivorysql框架设计] -** xref:v3.0/15.adoc[2、GUC框架] -** xref:v3.0/16.adoc[3、大小写转换] -** xref:v3.0/17.adoc[4、双模式设计] -** xref:v3.0/18.adoc[5、兼容Oracle like] -** xref:v3.0/19.adoc[6、兼容Oracle匿名块] -** xref:v3.0/20.adoc[7、兼容Oracle函数与存储过程] -** xref:v3.0/21.adoc[8、内置数据类型与内置函数] -** xref:v3.0/22.adoc[9、新增Oracle兼容模式的端口与Ip] +** xref:v1.17/3.adoc[快速开始] +** xref:v1.17/4.adoc[日常监控] +** xref:v1.17/5.adoc[日常维护] +* IvorySQL高级 +** xref:v1.17/6.adoc[安装指南] +** xref:v1.17/7.adoc[开发者指南] +** xref:v1.17/8.adoc[运维管理指南] +* IvorySQL生态 +** xref:v1.17/33.adoc[概述] +** xref:v1.17/9.adoc[PostGIS] +** xref:v1.17/10.adoc[pgvector] +** xref:v1.17/34.adoc[PGroonga] +** xref:v1.17/35.adoc[pgddl (DDL Extractor)] +** xref:v1.17/36.adoc[pgRouting] +** xref:v1.17/37.adoc[pg_cron] +** xref:v1.17/38.adoc[pgsql-http] +** xref:v1.17/40.adoc[pgvectorscale] +* Oracle兼容功能列表 +** xref:v1.17/11.adoc[1、Ivorysql框架设计] +** xref:v1.17/12.adoc[2、GUC框架] +** xref:v1.17/13.adoc[3、大小写转换] +** xref:v1.17/14.adoc[4、双模式设计] +** xref:v1.17/15.adoc[5、兼容Oracle like] +** xref:v1.17/16.adoc[6、兼容Oracle匿名块] +** xref:v1.17/17.adoc[7、兼容Oracle函数与存储过程] +** xref:v1.17/18.adoc[8、内置数据类型与内置函数] +** xref:v1.17/19.adoc[9、新增Oracle兼容模式的端口与IP] +* IvorySQL试验田 +** xref:v1.17/41.adoc[1、全局唯一索引] +** xref:v1.17/42.adoc[2、新增无主键表默认支持逻辑复制] +** xref:v1.17/43.adoc[3、修改列类型时自动重建依赖视图] +* xref:v1.17/20.adoc[社区贡献指南] +* xref:v1.17/21.adoc[工具参考] +* xref:v1.17/22.adoc[FAQ] diff --git a/CN/modules/ROOT/pages/v1.17/1.adoc b/CN/modules/ROOT/pages/v1.17/1.adoc new file mode 100644 index 0000000..0574bab --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/1.adoc @@ -0,0 +1,53 @@ +:sectnums: +:sectnumlevels: 5 + + +== 版本介绍 + +[**发行日期:2025年3月26日**] + +IvorySQL 1.17 基于 PostgreSQL 14.17 ,包含来自 PostgreSQL 14.17 的各种修复。有关更新的完整内容,请访问我们的 https://docs.ivorysql.org/[文档网站] 。 + +== 已知问题 + +* 暂无 + +== 增强功能 + +* PostgreSQL 14.17 +1. 禁止在扩展脚本中替换包含引号、反斜杠或美元符号的 schema 名称或所有者名称。 +2. 修复 DISTINCT "any" 聚合函数对未知类型参数的处理问题。 +3. 加强 REFRESH MATERIALIZED VIEW CONCURRENTLY 的安全限制。 +4. 限制 pg_stats_ext 和 pg_stats_ext_exprs 条目仅对表所有者可见。 +5. 防止 pg_dump 过程中未经授权的代码执行。 +6. 当行级安全策略(RLS)应用于非顶级表引用时,确保缓存计划标记为依赖于调用角色。 +7. 修复与 struct ResultRelInfo 交互的扩展的 ABI 兼容性问题。 +8. 增强 PQescapeString 及相关函数对非法编码输入字符串的防护能力。 +9. 优化 libpq 引用函数的行为。 + +* IvorySQL 1.17 +1. 全平台ARM64打包支持: + +提供ARM架构的多平台介质包,兼容国内外主流操作系统,包括Red Hat、Debian、麒麟、统信UOS和凝思NSAR OS等。 +2. 全平台X86打包支持 + +提供X86架构的多平台介质包,兼容国内外主流操作系统,包括Red Hat、Debian、麒麟、统信UOS和凝思NSAR OS等。 +3. 支持更多开源插件 + +包括ddlx0.20、pgvector v0.8.0、PGroonga 3.0.0、PostGIS 3.4.0及pgRouting 3.5.1等。 + +== 源代码 + +IvorySQL 的研发工作主要通过以下两个核心代码库进行维护: + +* IvorySQL 数据库源代码库: https://github.com/IvorySQL/IvorySQL[https://github.com/IvorySQL/IvorySQL] +* IvorySQL 官方网站代码库: https://github.com/IvorySQL/Ivory-www[https://github.com/IvorySQL/Ivory-www] + +== 贡献人员 +以下个人作为补丁作者、提交者、审阅者、测试者或问题报告者为本版本做出了贡献。 + +- Grant Zhou +- 高雪玉 +- 矫顺田 +- 吕新杰 +- 牛世继 +- 潘振浩 +- 陶郑 +- 王大鹏 diff --git a/CN/modules/ROOT/pages/v1.17/10.adoc b/CN/modules/ROOT/pages/v1.17/10.adoc new file mode 100644 index 0000000..8d10d41 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/10.adoc @@ -0,0 +1,120 @@ +:sectnums: +:sectnumlevels: 5 + += pgvector + +== 概述 +向量数据库是生成式人工智能(GenAI)的关键组成部分。pgvector作为PostgreSQL的重要扩展,不仅能够支持高达16000维度的向量计算,还提供了强大的向量操作和索引功能,使得PostgreSQL能够直接转化为高效的向量数据库。由于IvorySQL基于PostgreSQL研发,这使得它具备了与pgvector扩展无缝集成的能力,从而为用户提供了更广泛的数据处理和分析选项。在Oracle兼容模式下,pgvector扩展同样可用,这为Oracle用户使用向量数据库提供了极大的便利,使其能够轻松地迁移和管理数据,实现更高效的业务操作。 + + +== 原理介绍 + +IVFFLAT和HNSW是PGVector的两个索引算法 + +=== IVFFLAT + +IVFFLAT的工作原理是将相似的向量聚类为区域,并建立一个倒排索引,将每个区域映射到其向量。这使得查询可以集中在数据的一个子集上,从而实现快速搜索。通过调整列表和探针参数,ivfflat 可以平衡数据集的速度和准确性,使 PostgreSQL 有能力对复杂数据进行快速的语义相似性搜索。通过简单的查询,应用程序可以在数百万个高维向量中找到与查询向量最近的邻居。对于自然语言处理、信息检索等,ivfflat 是一个比较好的解决方案 +在建立 ivfflat 索引时,你需要决定索引中包含多少个 list。每个 list 代表一个 "中心";这些中心通过 k-means 算法计算而来。一旦确定了所有中心,ivfflat 就会确定每个向量最靠近哪个中心,并将其添加到索引中。当需要查询向量数据时,你可以决定要检查多少个中心,这由 ivfflat.probes 参数决定。这就是 ANN 性能/召回率的结果:访问的中心越多,结果就越精确,但这是以牺牲性能为代价的。 + +=== HNSW + +HNSW (Hierarchical Navigating Small World) 是一种基于图的索引算法,它由多层的邻近图组成,因此称为分层的 NSW 方法。它会为一张图按规则建成多层导航图,并让越上层的图越稀疏,结点间的距离越远;越下层的图越稠密,结点间的距离越近。HNSW 算法是一种经典的空间换时间的算法,它的搜索质量和搜索速度都比较高,但是它的内存开销也比较大,因为不仅需要将所有的向量都存储在内存中。还需要维护一个图的结构,也同样需要存储。 + +== 安装 + +=== 源码安装 + +** 设置PG_CONFIG环境变量 +``` +export PG_CONFIG=/usr/local/ivorysql/ivorysql-1.17/bin/pg_config +``` + +** 拉取pg_vector源码 +``` +git clone --branch v0.8.0 https://github.com/pgvector/pgvector.git +``` + +** 安装 pgvector +``` +cd pgvector + +sudo --preserve-env=PG_CONFIG make +sudo --preserve-env=PG_CONFIG make install +``` + +** 创建pgvector扩展 +``` +[ivorysql@localhost ivorysql-1.17]$ psql +psql +Type "help" for help. + +ivorysql=# create extension vector; +CREATE EXTENSION +``` +至此,pgvector扩展安装已完成。 +更多用例,请参考 https://github.com/pgvector/pgvector?tab=readme-ov-file#getting-started[pgvector文档] + +== Oracle兼容性 + +在IvorySQL Oracle兼容模式下,pgvector扩展同样可以正确运行 +[TIP] +建议用户使用1521端口进行测试, psql -p 1521 + +=== 数据类型 + +``` +ivorysql=# CREATE TABLE items5 (id bigserial PRIMARY KEY, name varchar2(20), num number(20), embedding bit(3)); +CREATE TABLE +ivorysql=# INSERT INTO items5 (name, num, embedding) VALUES ('1st oracle data',0, '000'), ('2nd oracle data', 111, '111'); +INSERT 0 2 +ivorysql=# SELECT * FROM items5 ORDER BY bit_count(embedding # '101') LIMIT 5; + id | name | num | embedding +----+-----------------+-----+----------- + 2 | 2nd oracle data | 111 | 111 + 1 | 1st oracle data | 0 | 000 +``` + +=== 匿名块 + +``` +ivorysql=# declare +i vector(3) := '[1,2,3]'; +begin +raise notice '%', i; +end; +ivorysql-# / +NOTICE: [1,2,3] +DO +``` + +=== 存储过程(PROCEDURE) +``` +ivorysql=# CREATE OR REPLACE PROCEDURE ora_procedure() +AS +p vector(3) := '[4,5,6]'; +begin +raise notice '%', p; +end; +/ +CREATE PROCEDURE +ivorysql=# call ora_procedure(); +NOTICE: [4,5,6] +CALL +``` + +==== 函数(FUNCTION) +``` +ivorysql=# CREATE OR REPLACE FUNCTION AddVector(a vector(3), b vector(3)) +RETURN vector(3) +IS +BEGIN +RETURN a + b; +END; +/ +CREATE FUNCTION +ivorysql=# SELECT AddVector('[1,2,3]','[4,5,6]') FROM DUAL; + addvector +---------------- + [5,7,9] +(1 row) +``` \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/14.adoc b/CN/modules/ROOT/pages/v1.17/11.adoc similarity index 100% rename from CN/modules/ROOT/pages/v3.0/14.adoc rename to CN/modules/ROOT/pages/v1.17/11.adoc diff --git a/CN/modules/ROOT/pages/v3.0/15.adoc b/CN/modules/ROOT/pages/v1.17/12.adoc similarity index 97% rename from CN/modules/ROOT/pages/v3.0/15.adoc rename to CN/modules/ROOT/pages/v1.17/12.adoc index 3585295..5615018 100644 --- a/CN/modules/ROOT/pages/v3.0/15.adoc +++ b/CN/modules/ROOT/pages/v1.17/12.adoc @@ -24,7 +24,6 @@ | ivorysql.database_mode | 表示当前数据库的模式(pg/oracle),可以通过show命令查看,set/reset/reset all命令不影响该变量 | ivorysql.datetime_ignore_nls_mask | 表示日期格式是否会受NLS参数影响,默认为0,可以通过set命令设置,reset 命令重置,reset all命令会重置该变量 | ivorysql.enable_emptystring_to_NULL | 取值为(on/off),该变量为on时,会将插入的空字符串转成NULL值存储 -| ivorysql.identifier_case_switch | 设置字符大小写转换模式 | ivorysql.listen_address | 表示兼容模式监听的地址,在初始化数据库时,从ivorysql.conf文件中读取该配置,在配置文件中修改该值,需要重启数据库生效,可以通过show命令查看 | ivorysql.port | 表示兼容模式下连接的端口号,在初始化数据库时,从ivorysql.conf文件中读取该配置,在配置文件中修改该值,需要重启数据库生效,可以通过show命令查看 | nls_date_format | 表示默认的日期格式,可以通过show命令查看,默认为‘YYYY-MM-DD’,可以通过set命令设置,可以通过reset命令重置回默认值,reset all 命令会重置该变量 diff --git a/CN/modules/ROOT/pages/v1.17/13.adoc b/CN/modules/ROOT/pages/v1.17/13.adoc new file mode 100644 index 0000000..e46f642 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/13.adoc @@ -0,0 +1,285 @@ + +:sectnums: +:sectnumlevels: 5 + += 引用标识符的大小写转换设计 + +== 目的 + +- 为了满足PG和Oracle的引用标识符大小写兼容,ivorysql设计了三种引用标识符的大小写转换模式。通过guc参数“identifier_case_switch”选择转换模式; + +== 功能 + +=== 大小写转换的三种模式(默认为interchange) + +- 如果 guc参数“identifier_case_switch”值为“normal” + + 1). 保持双引号所引用的标识符中的字母大小写不变。 + +- 如果 guc参数“identifier_case_switch”值为“interchange”: + + 1). 如果双引号所引用的标识符中的字母全部为大写,则将大写转换为小写。 + + 2). 如果双引号所引用的标识符中的字母全部为小写,则将小写转换为大写。 + + 3). 如果用双引号引起来的标识符中的字母是大小写混合的,则保持标识符不变。 + +- 如果 guc参数“identifier_case_switch”值为“lowercase” + + 1). 如果双引号所引用的标识符中的字母全部为大写,则将大写转换为小写。 + + 2). 如果用双引号引起来的标识符中的字母是大小写混合的,则保持标识符不变。 + +=== 初始化数据库集簇时 + +- 在initdb程序中加入 -C选项设置大小写转换模式,-C对应的值为: + + "normal" ------ "0"同义 + + "interchange" ------ "1"同义 + + "lowercase" ------ "2"同义 + + 在初始化数据库集簇的过程中,将大小写转换模式保存到data目录的global/pg_control文件中。 + +=== 经典用例 + +**normal** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = normal; +SET + +ivorysql=# CREATE TABLE "NORMAL_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Normal_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "normal_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "NORMAL_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Normal_1"; +ERROR: relation "Normal_1" does not exist +LINE 1: select * from "Normal_1"; + +ivorysql=# select * from "normal_1"; +ERROR: relation "normal" does not exist +LINE 1: select * from "normal"; + +ivorysql=# select * from NORMAL_1; +ERROR: relation "normal_1" does not exist +LINE 1: select * from NORMAL_1; + +ivorysql=# select * from "Normal_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "NORMAL_2"; +ERROR: relation "NORMAL_2" does not exist +LINE 1: select * from "NORMAL_2"; + +ivorysql=# select * from "normal_2"; +ERROR: relation "normal_2" does not exist +LINE 1: select * from "normal_2"; + +ivorysql=# select * from Normal_2; +ERROR: relation "normal_2" does not exist +LINE 1: select * from Normal_2; + +ivorysql=# select * from "normal_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "NORMAL_3"; +ERROR: relation "NORMAL_3" does not exist +LINE 1: select * from "NORMAL_3"; + +ivorysql=# select * from "Normal_3"; +ERROR: relation "Normal_3" does not exist +LINE 1: select * from "Normal_3"; + +ivorysql=# drop table "NORMAL_1"; +DROP TABLE +ivorysql=# drop table "Normal_2"; +DROP TABLE +ivorysql=# drop table "normal_3"; +DROP TABLE +``` + +**interchange** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = interchange; +SET + +ivorysql=# CREATE TABLE "INTER_CHANGE_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Inter_Change_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "inter_change_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "INTER_CHANGE_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Inter_Change_1"; +ERROR: relation "Inter_Change_1" does not exist +LINE 1: select * from "Inter_Change_1"; + +ivorysql=# select * from "inter_change_1"; +ERROR: relation "INTER_CHANGE_1" does not exist +LINE 1: select * from "inter_change_1"; + +ivorysql=# select * from INTER_CHANGE_1; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Inter_Change_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "INTER_CHANGE_2"; +ERROR: relation "inter_change_2" does not exist +LINE 1: select * from "INTER_CHANGE_2"; + +ivorysql=# select * from "inter_change_2"; +ERROR: relation "INTER_CHANGE_2" does not exist +LINE 1: select * from "inter_change_2"; + +ivorysql=# select * from Inter_Change_2; +ERROR: relation "inter_change_2" does not exist +LINE 1: select * from Inter_Change_2; + +ivorysql=# select * from "inter_change_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "INTER_CHANGE_3"; +ERROR: relation "inter_change_3" does not exist +LINE 1: select * from "INTER_CHANGE_3"; + +ivorysql=# select * from "Inter_Change_3"; +ERROR: relation "Inter_Change_3" does not exist +LINE 1: select * from "Inter_Change_3"; + +ivorysql=# select * from inter_change_3; +ERROR: relation "inter_change_3" does not exist +LINE 1: select * from "INTER_CHANGE_3"; + +ivorysql=# drop table "INTER_CHANGE_1"; +DROP TABLE +ivorysql=# drop table "Inter_Change_2"; +DROP TABLE +ivorysql=# drop table "inter_change_3"; +DROP TABLE +``` + +**lowercase** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = lowercase; +SET + +ivorysql=# CREATE TABLE "LOWER_CASE_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Lower_Case_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "lower_case_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "LOWER_CASE_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Lower_Case_1"; +ERROR: relation "Lower_Case_1" does not exist +LINE 1: select * from "Lower_Case_1"; + +ivorysql=# select * from "lower_case_1"; + c1 | c2 +----+---- +(0 行记录) + + +ivorysql=# select * from LOWER_CASE_1; + c1 | c2 +----+---- +(0 行记录) + + +ivorysql=# select * from "Lower_Case_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "LOWER_CASE_2"; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from "LOWER_CASE_2"; + +ivorysql=# select * from "lower_case_2"; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from "lower_case_2"; + +ivorysql=# select * from Lower_Case_2; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from Lower_Case_2; + +ivorysql=# select * from "lower_case_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "LOWER_CASE_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Lower_Case_3"; +ERROR: relation "Lower_Case_3" does not exist +LINE 1: select * from "Lower_Case_3"; + +ivorysql=# select * from LOWER_CASE_3; + c1 | c2 +----+---- +(0 行记录) + +ivorysql=# drop table "NORMAL_1"; +DROP TABLE +ivorysql=# drop table "Normal_2"; +DROP TABLE +ivorysql=# drop table "normal_3"; +DROP TABLE +``` \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/17.adoc b/CN/modules/ROOT/pages/v1.17/14.adoc similarity index 95% rename from CN/modules/ROOT/pages/v3.0/17.adoc rename to CN/modules/ROOT/pages/v1.17/14.adoc index d8efbf6..9f72a34 100644 --- a/CN/modules/ROOT/pages/v3.0/17.adoc +++ b/CN/modules/ROOT/pages/v1.17/14.adoc @@ -1,33 +1,33 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 双模式设计 - -== 目的 - -- 为了满足PG模式和兼容Oracle模式,Ivorysql设计了pg和oracle两种模式。并且可以在initdb时指定模式; - -== 功能 - -- Initdb -m 初始化,需要判断不同的模式,其中Oracle模式下,需要执行postgres_oracle.bki的SQL语句; -- 启动时会根据初始化模式,判断是否为oracle兼容模式。 - -``` -database_mode:用于表示初始化模式; -database_mode=DB_PG,PG模式,且不可切换; -database_mode=DB_ORACLE,Oracle兼容模式; -``` - -== 测试用例 - -``` -初始化PG模式: -./initdb -D ../data -m pg - -初始化oracle兼容模式: -./initdb -D ../data -m oracle -或 -./initdb -D ../data -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 双模式设计 + +== 目的 + +- 为了满足PG模式和兼容Oracle模式,Ivorysql设计了pg和oracle两种模式。并且可以在initdb时指定模式; + +== 功能 + +- Initdb -m 初始化,需要判断不同的模式,其中Oracle模式下,需要执行postgres_oracle.bki的SQL语句; +- 启动时会根据初始化模式,判断是否为oracle兼容模式。 + +``` +database_mode:用于表示初始化模式; +database_mode=DB_PG,PG模式,且不可切换; +database_mode=DB_ORACLE,Oracle兼容模式; +``` + +== 测试用例 + +``` +初始化PG模式: +./initdb -D ../data -m pg + +初始化oracle兼容模式: +./initdb -D ../data -m oracle +或 +./initdb -D ../data +``` diff --git a/CN/modules/ROOT/pages/v3.0/18.adoc b/CN/modules/ROOT/pages/v1.17/15.adoc similarity index 98% rename from CN/modules/ROOT/pages/v3.0/18.adoc rename to CN/modules/ROOT/pages/v1.17/15.adoc index 0cf48a5..890b3f1 100644 --- a/CN/modules/ROOT/pages/v3.0/18.adoc +++ b/CN/modules/ROOT/pages/v1.17/15.adoc @@ -1,69 +1,69 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 兼容Oracle like - -== 目的 - -- 本文档意在为使用 like 模糊查询的人员提供一个深入了解兼容Oracle 的模糊查询like实现的过程,是like兼容的实现文档。 - -== 功能说明 -|==== -|数据库名称|like模糊查询 -|oracle|oracle的字符串类型是varchar2,支持对数字、日期、字符串字段类型的列用Like关键字配合通配符来实现模糊查询 -|IvorySQL|IvorySQL的字符串基本类型是text,所以like是以text为基础上,其他IvorySQL的类型能隐式转换成text,这样不用创建opeartor就能自动转换 -|==== - -== 测试用例 - -``` - -create table t_ora_like (id int ,str1 varchar(8), date1 timestamp with time zone, date2 time with time zone, num int, str2 varchar(8)); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123456,'test1','2022-09-26 16:39:20','2022-09-26 16:39:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123457,'test2','2022-09-26 16:40:20','2022-09-26 16:40:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (223456,'test3','2022-09-26 16:41:20','2022-09-26 16:41:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123458,'test4','2022-09-26 16:42:20','2022-09-26 16:42:20'); - -select * from t_ora_like where str1 like 'test%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where date1 like '2022%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where date2 like '16%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where id like '123%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(3 rows) - -select * from t_ora_like where id like null; - id | str1 | date1 | date2 | num | str2 -----+------+-------+-------+-----+------ -(0 rows) - -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 兼容Oracle like + +== 目的 + +- 本文档意在为使用 like 模糊查询的人员提供一个深入了解兼容Oracle 的模糊查询like实现的过程,是like兼容的实现文档。 + +== 功能说明 +|==== +|数据库名称|like模糊查询 +|oracle|oracle的字符串类型是varchar2,支持对数字、日期、字符串字段类型的列用Like关键字配合通配符来实现模糊查询 +|IvorySQL|IvorySQL的字符串基本类型是text,所以like是以text为基础上,其他IvorySQL的类型能隐式转换成text,这样不用创建opeartor就能自动转换 +|==== + +== 测试用例 + +``` + +create table t_ora_like (id int ,str1 varchar(8), date1 timestamp with time zone, date2 time with time zone, num int, str2 varchar(8)); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123456,'test1','2022-09-26 16:39:20','2022-09-26 16:39:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123457,'test2','2022-09-26 16:40:20','2022-09-26 16:40:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (223456,'test3','2022-09-26 16:41:20','2022-09-26 16:41:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123458,'test4','2022-09-26 16:42:20','2022-09-26 16:42:20'); + +select * from t_ora_like where str1 like 'test%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where date1 like '2022%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where date2 like '16%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where id like '123%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(3 rows) + +select * from t_ora_like where id like null; + id | str1 | date1 | date2 | num | str2 +----+------+-------+-------+-----+------ +(0 rows) + +``` diff --git a/CN/modules/ROOT/pages/v3.0/19.adoc b/CN/modules/ROOT/pages/v1.17/16.adoc similarity index 91% rename from CN/modules/ROOT/pages/v3.0/19.adoc rename to CN/modules/ROOT/pages/v1.17/16.adoc index ef13fd8..e552dc6 100644 --- a/CN/modules/ROOT/pages/v3.0/19.adoc +++ b/CN/modules/ROOT/pages/v1.17/16.adoc @@ -1,49 +1,47 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 兼容Oracle匿名块 - -== 目的 - -- 本文档是PLSQL匿名块(anonymous block)兼容Oracle语法功能的设计文档,目的是可以在IvorySQL中兼容Oracle的匿名块语句。 - -== 功能说明 - -- 匿名块是能够动态地创建和执行过程代码的PLSQL结构,而不需要以持久化的方式将代码作为数据库对象储存在系统目录中。本次实现中IvorySQL主要兼容的是PLSQL匿名块的语法格式,我们主要处理的部分包括客户端工具psql、主服务器和PSQL端支持。 - -== 测试用例 - -``` - -declare -i integer := 10; -begin - raise notice '%', i; - raise notice '%', main.i; -end; -/ -NOTICE: 10 -NOTICE: 10 - -``` - -``` - -DECLARE - grade CHAR(1); -BEGIN - grade := 'B'; - CASE grade - WHEN 'A' THEN raise notice 'Excellent'; - WHEN 'B' THEN raise notice 'Very Good'; - END CASE; -EXCEPTION - WHEN CASE_NOT_FOUND THEN - raise notice 'No such grade'; -END; -/ -NOTICE: Very Good - -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 兼容Oracle匿名块 + +== 目的 + +- 本文档是PLSQL匿名块(anonymous block)兼容Oracle语法功能的设计文档,目的是可以在IvorySQL中兼容Oracle的匿名块语句。 + +== 功能说明 + +- 匿名块是能够动态地创建和执行过程代码的PLSQL结构,而不需要以持久化的方式将代码作为数据库对象储存在系统目录中。本次实现中IvorySQL主要兼容的是PLSQL匿名块的语法格式,我们主要处理的部分包括客户端工具psql、主服务器和PSQL端支持。 + +== 测试用例 + +``` + +declare +i integer := 10; +begin + raise notice '%', i; +end; +/ +NOTICE: 10 + +``` + +``` + +DECLARE + grade CHAR(1); +BEGIN + grade := 'B'; + CASE grade + WHEN 'A' THEN raise notice 'Excellent'; + WHEN 'B' THEN raise notice 'Very Good'; + END CASE; +EXCEPTION + WHEN CASE_NOT_FOUND THEN + raise notice 'No such grade'; +END; +/ +NOTICE: Very Good + +``` diff --git a/CN/modules/ROOT/pages/v3.0/20.adoc b/CN/modules/ROOT/pages/v1.17/17.adoc similarity index 95% rename from CN/modules/ROOT/pages/v3.0/20.adoc rename to CN/modules/ROOT/pages/v1.17/17.adoc index 33b7ea2..8801dc4 100644 --- a/CN/modules/ROOT/pages/v3.0/20.adoc +++ b/CN/modules/ROOT/pages/v1.17/17.adoc @@ -1,101 +1,97 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 兼容Oracle函数与存储过程 - -== 目的 - -- 本文档意在兼容Oracle PLSQL函数和存储过程的语法,在IvorySQL中我们称其为PLISQL语言。 - -== 功能说明 - -.函数(FUNCTION) -|==== -|CREATE FUNCTION语法支持EDITIONABLE/NONEDITIONABLE -|CREATE FUNCTION语法支持RETURN, IS关键字,不指定language -|CREATE FUNCTION语法函数没有参数,函数名后面不带() -|CREATE FUNCTION参数个数最多是32767 -|CREATE FUNCTION语法中END; 在psql中以/结束 -|CREATE FUNCTION语法变量声明前面没有DECLARE关键字 -|CREATE FUNCTION语法支持OUT 参数NOCOPY功能 -|CREATE FUNCTION语法支持sharing_clause -|CREATE FUNCTION语法支持invoker_rights_clause,默认权限改成DR(DEFINER) -|CREATE FUNCTION语法支持ACCESSIBLE BY  -|CREATE FUNCTION语法支持DEFAULT COLLATION -|CREATE FUNCTION语法支持result_cache_clause  -|CREATE FUNCTION语法支持aggregate_clause -|CREATE FUNCTION语法支持pipelined_clause -|CREATE FUNCTION语法支持sql_macro_clause -|ALTER FUNCTION语法 -|函数和存储过程相关的视图 -|==== - - -.存储过程(PROCEDURE) -|==== -|CREATE PROCEDURE语法支持EDITIONABLE/NONEDITIONABLE -|CREATE PROCEDURE语法函数没有参数,函数名后面不带() -|CREATE PROCEDURE参数个数最多是32767 -|CREATE PROCEDURE语法中END; 在psql中以/结束 -|CREATE PROCEDURE语法支持sharing_clause -|CREATE PROCEDURE语法支持DEFAULT COLLATION -|CREATE PROCEDURE语法支持invoker_rights_clause -|CREATE PROCEDURE语法支持ACCESSIBLE BY  -|ALTER PROCEDURE语法 -|存储过程没有参数,调用支持不带() -|存储过程调用支持EXEC -|在PL/SQL 中调用存储过程,可以省略CALL,直接使用存储过程名字 -|支持--和/**/两种注释方法 -|==== - - -== 测试用例 - -``` - -CREATE or replace FUNCTION ora_func RETURN integer AS -BEGIN - RETURN 1; -END; -/ - -CREATE OR REPLACE FUNCTION test_nocopy(a IN int, b OUT NOCOPY int, c IN OUT NOCOPY int) -RETURN record -IS -BEGIN - b := a; - c := a; -END; -/ - -``` -``` - -CREATE OR REPLACE PROCEDURE ora_procedure() -AS - p integer := 20; -begin - raise notice '%', p; -end; -/ -call ora_procedure(); - -CREATE OR REPLACE PROCEDURE ora_procedure -SHARING = METADATA -DEFAULT COLLATION USING_NLS_COMP -AUTHID CURRENT_USER -ACCESSIBLE BY ( FUNCTION A.B ) -IS - p integer := 20; -begin - raise notice '%', p; -end; -/ - -``` - - - - +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 兼容Oracle函数与存储过程 + +== 目的 + +- 本文档意在兼容Oracle PLSQL函数和存储过程的语法,在IvorySQL中我们称其为PLISQL语言。 + +== 功能说明 + +.函数(FUNCTION) +|==== +|CREATE FUNCTION语法支持EDITIONABLE/NONEDITIONABLE +|CREATE FUNCTION语法支持RETURN, IS关键字,不指定language +|CREATE FUNCTION语法函数没有参数,函数名后面不带() +|CREATE FUNCTION参数个数最多是32767 +|CREATE FUNCTION语法中END; 在psql中以/结束 +|CREATE FUNCTION语法变量声明前面没有DECLARE关键字 +|CREATE FUNCTION语法支持OUT 参数NOCOPY功能 +|CREATE FUNCTION语法支持sharing_clause +|CREATE FUNCTION语法支持invoker_rights_clause,默认权限改成DR(DEFINER) +|CREATE FUNCTION语法支持ACCESSIBLE BY  +|CREATE FUNCTION语法支持DEFAULT COLLATION +|CREATE FUNCTION语法支持result_cache_clause  +|CREATE FUNCTION语法支持aggregate_clause +|CREATE FUNCTION语法支持pipelined_clause +|CREATE FUNCTION语法支持sql_macro_clause +|ALTER FUNCTION语法 +|函数和存储过程相关的视图 +|==== + + +.存储过程(PROCEDURE) +|==== +|CREATE PROCEDURE语法支持EDITIONABLE/NONEDITIONABLE +|CREATE PROCEDURE语法函数没有参数,函数名后面不带() +|CREATE PROCEDURE参数个数最多是32767 +|CREATE PROCEDURE语法中END; 在psql中以/结束 +|CREATE PROCEDURE语法支持sharing_clause +|CREATE PROCEDURE语法支持DEFAULT COLLATION +|CREATE PROCEDURE语法支持invoker_rights_clause +|CREATE PROCEDURE语法支持ACCESSIBLE BY  +|ALTER PROCEDURE语法 +|存储过程没有参数,调用支持不带() +|存储过程调用支持EXEC +|在PL/SQL 中调用存储过程,可以省略CALL,直接使用存储过程名字 +|支持--和/**/两种注释方法 +|==== + + +== 测试用例 + +``` + +CREATE or replace FUNCTION ora_func RETURN integer AS +BEGIN + RETURN 1; +END; +/ + +CREATE OR REPLACE FUNCTION test_nocopy(a IN int, b OUT NOCOPY int, c IN OUT NOCOPY int) +RETURN record +IS +BEGIN + b := a; + c := a; +END; +/ + +``` +``` + +CREATE OR REPLACE PROCEDURE ora_procedure() +AS + p integer := 20; +begin + raise notice '%', p; +end; +/ +call ora_procedure(); + +CREATE OR REPLACE PROCEDURE ora_procedure +SHARING = METADATA +DEFAULT COLLATION USING_NLS_COMP +AUTHID CURRENT_USER +ACCESSIBLE BY ( FUNCTION A.B ) +IS + p integer := 20; +begin + raise notice '%', p; +end; +/ + +``` diff --git a/CN/modules/ROOT/pages/v3.0/21.adoc b/CN/modules/ROOT/pages/v1.17/18.adoc similarity index 93% rename from CN/modules/ROOT/pages/v3.0/21.adoc rename to CN/modules/ROOT/pages/v1.17/18.adoc index 91d1171..1a511db 100644 --- a/CN/modules/ROOT/pages/v3.0/21.adoc +++ b/CN/modules/ROOT/pages/v1.17/18.adoc @@ -1,965 +1,1033 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 内置数据类型与内置函数 - -== 内置数据类型 - -|==== -|char -|varchar -|varchar2 -|number -|binary_float -|binary_double -|date -|timestamp -|timestamp with time zone -|timestamp with local time zone -|interval year to month -|interval day to second -|raw -|long -|==== - -== 内置函数类型 - -|==== -|sysdate -|systimestamp -|add_months -|last_day -|next_day -|months_between -|current_date -|current_timestamp -|new_time -|tz_offset -|trunc -|instrb -|substr -|substrb -|trim -|ltrim -|rtrim -|length -|lengthb -|rawtohex -|replace -|regexp_replace -|regexp_substr -|regexp_instr -|regexp_like -|to_number -|to_char -|to_date -|to_timestamp -|to_timestamp_tz -|to_yminterval -|to_dsinterval -|numtodsinterval -|numtoyminterval -|localtimestamp -|from_tz -|sys_extract_utc -|sessiontimezone -|hextoraw -|uid -|USERENV -|==== - -== 内置函数说明 - -1、兼容sysdate函数,功能:查看对应的日期与时间,测试用例如下: -查询当前系统的日期: - -``` -select sysdate() from dual; - sysdate ------------- - 2023-07-06 -(1 row) -``` - -查询往前推1天的日期: - -``` -select sysdate()-1 from dual; - ?column? ------------- - 2023-07-05 -(1 row) -``` - -2、兼容systimestamp函数,功能:返回本机数据库上当前系统日期和时间(包括微秒和时区),测试用例如下: -查询当前日期的日期和时间: - -``` -select systimestamp() from dual; - systimestamp ------------------------------------ - 2023-07-06 10:18:31.674322 +08:00 -(1 row) -``` - -3、兼容add_months函数,功能:函数将一个月数(n)添加一个日期,并返回相隔n月的同一天,支持参数:date, number;测试用例如下: -查询当前日期(七月六日)的下个月的同一天: - -``` -select add_months(sysdate(),1) from dual; - add_months ------------- - 2023-08-06 -(1 row) -``` - -查询当前日期的上个月的同一天: - -``` -select add_months(sysdate(),-1) from dual; - add_months ------------- - 2023-06-06 -(1 row) -``` - -4、兼容last_day函数,功能:返回指定日期所在月份的最后一天,支持参数:date,测试用例如下: -查询当天所在月份的最后一天: - -``` -select last_day(sysdate())from dual; - last_day ------------- - 2023-07-31 -(1 row) -``` - -查询某一天所在月份的最后一天: - -``` -select last_day(to_date('2019-09-01'))from dual; - last_day ------------- - 2019-09-30 -(1 row) -``` - -5、兼容next_day函数,功能:返回指定日期的下一个日期。支持参数:date, integer /date ,text, 说明:当函数中第二个参数传的星期数比现有星期数小时,会返回下一个星期的日期;当函数中第二个参数所传的日期比现有星期数大,会返回本周相应星期日期。测试用例如下: -查询当前日期的下一天: - -``` -select next_day(sysdate(),1) from dual; - next_day ------------- - 2023-07-07 -(1 row) -``` - -查询当前日期的下个星期五: - -``` -select next_day(sysdate(),'FRIDAY') from dual; - next_day ------------- - 2023-07-07 -(1 row) -``` - -6、兼容months_between函数,功能:返回日期类型的date1和date2之间相差的月份,支持参数:date,date,说明:如果date1晚于date2,返回正数;如果date1早于date2返回负数;如果date1和date2是某月里的同一天,返回结果为整数;如果不是同一天,会在每月31天的基础上返回带有小数部分的结果。测试用例如下: -查询不同月份同一天之间相差的月份: - -``` -select months_between(to_date('2023-07-06'),to_date('2023-08-06')) from dual; - months_between ----------------- - -1 -(1 row) -``` - -查询不同月份不同日期之间相差的月份: - -``` -select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; - months_between --------------------- - -0.967741935483871 -(1 row) -``` - -7、兼容current_date函数,功能:返回当前时区的当前日期,测试用例如下: -查询当前时区的当前日期: - -``` -select current_date from dual; - current_date --------------- - 2023-07-06 -(1 row) -``` - -8、兼容current_timestamp函数,功能:返回当前时区的当前日期与当前时间,包含当前时区信息。支持参数:integer, 说明:返回的时间可调整精度。测试用例如下: -查询当前时区的当前日期与时间: - -``` -select current_timestamp from dual; - current_timestamp ------------------------------------ - 2023-07-06 10:27:01.440600 +08:00 -(1 row) -``` - -查询当前时区的当前日期与时间(精度调整为前三位小数): - -``` -select current_timestamp(3) from dual; - current_timestamp ------------------------------------ - 2023-07-06 10:27:14.182000 +08:00 -(1 row) -``` - -9、兼容new_time函数,功能:返回某个时间在某时区所对应的在另一个时区的日期,支持参数:date, text, text ,测试用例如下: -返回当前日期在另一个时区对应的日期: - -``` -select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; - bj_time | los_angles -------------+------------ - 2023-07-06 | 2023-07-06 -(1 row) -``` - -10、兼容tz_offset函数,功能:返回给定时区与标准时区的偏移量,支持参数:text,测试用例如下: -返回给定时区与标准时区偏移量: - -``` -select tz_offset('US/Eastern') from dual; - tz_offset ------------ - -04:00 -(1 row) -``` - -11、兼容trunc函数,功能:可以截取日期,得到想要的数值,如年,月,日,时,分,支持参数:date/date,text,测试用例如下: -截取当前日期: - -``` -select trunc(sysdate()) from dual; - trunc ------------- - 2023-07-06 -(1 row) -``` - -截取年,返回值只有年是正确的,月和日不是准确值: - -``` -select trunc(sysdate(),'yyyy') from dual; - trunc ------------- - 2023-01-01 -(1 row) -``` - -截取月,返回值只有月是正确的,年和日不是准确值: - -``` -select trunc(sysdate(),'mm') from dual; - trunc ------------- - 2023-07-01 -(1 row) -``` - -12、兼容instrb函数,功能:字符串查找函数,返回字符串的位置,支持参数: varchar2, text, number DEFAULT 1, number DEFAULT 1,以下为测试用例: -返回CORPORATE FLOOR中默认第一次出现OR时字符串的位置: - -``` -SELECT INSTRB('CORPORATE FLOOR','OR') "Instring in bytes" FROM DUAL; - Instring in bytes -------------------- - 2 -(1 row) -``` - -返回corporate floor中从第五个字符开始查询,第二次出现or时字符串的位置: - -``` -SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; - Instring in bytes -------------------- - 14 -(1 row) -``` - -13、兼容substr函数,功能:截取字符串函数,以字符为单位截取,支持参数:text, integer, 测试用例如下: -截取’今天天气很好’中从第五个字符开始,往后的字符串: - -``` -SELECT SUBSTR('今天天气很好',5) "Substring with bytes" FROM DUAL; - - Substring with bytes ----------------------- - 很好 -(1 row) -``` - -14、兼容substrb函数,功能:截取字符串函数,以字节为单位截取,支持参数:varchar2, number/varchar2, number,number,测试用例如下: -截取’今天天气很好’中从第五个字节开始,往后的字符串: - -``` -SELECT SUBSTRB('今天天气很好',5) "Substring with bytes" FROM DUAL; - Substring with bytes ----------------------- - 天气很好 -(1 row) -``` - -截取’今天天气很好’中从第五个字节开始,第八个字节结束的字符串: - -``` -SELECT SUBSTRB('今天天气很好',5,8) "Substring with bytes" FROM DUAL; - Substring with bytes ----------------------- - 天气 -(1 row) -``` - -15、兼容trim函数,功能:去除指定字符串的左右空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: -去除' aaa bbb ccc '的左右空格: - -``` -select trim(' aaa bbb ccc ')trim from dual; - trim -------------- - aaa bbb ccc -(1 row) -``` - -去除'aaa bbb ccc'中的aaa: - -``` -select trim('aaa bbb ccc','aaa')trim from dual; - trim ----------- - bbb ccc -(1 row) -``` - -16、兼容ltrim函数,功能:去除指定字符串的左侧空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: -去除' abcdefg '的左侧空格: - -``` -select ltrim(' abcdefg ')ltrim from dual; - ltrim ------------- - abcdefg -(1 row) -``` - -从'abcdefg'左侧开始遍历,一旦存在某字符出现在'fegab'中就去除,不存在则返回结果: - -``` -select ltrim('abcdefg','fegab')ltrim from dual; - ltrim -------- - cdefg -(1 row) -``` - -17、兼容rtrim函数,功能:去除指定字符串的右侧空格,测试用例如下: -去除' abcdefg '的右侧空格: - -``` -select rtrim(' abcdefg ')rtrim from dual; - rtrim ----------------- - abcdefg -(1 row) -``` - -从'abcdefg'右侧开始遍历,一旦存在某字符出现在'fegab'中就去除,不存在则返回结果: - -``` -select rtrim('abcdefg','fegab')rtrim from dual; - rtrim -------- - abcd -(1 row) -``` - -18、兼容length函数,功能:求取指定字符串字符的长度,支持参数:char/integer/varchar2测试用例如下: -查询223的字符长度: - -``` -select length(223) from dual; - length --------- - 3 -(1 row) -``` - -查询'223'的字符长度: - -``` -select length('223') from dual; - length --------- - 3 -(1 row) -``` - -查询'ivorysql数据库'的字符长度: - -``` -select length('ivorysql数据库') from dual; - length --------- - 11 -(1 row) -``` - -19、兼容lengthb功能:求取指定字符串字节的长度,支持参数:char/bytea/varchar2测试用例如下: -查询'ivorysql'的字节长度: - -``` -select lengthb('ivorysq'::char) from dual; - lengthb ---------- - 1 -(1 row) -``` - -查询'0x2C'的字节长度: - -``` -select lengthb('0x2C'::bytea) from dual; - lengthb ---------- - 4 -(1 row) -``` - -查询'ivorysql数据库'的字节长度: - -``` -select lengthb('ivorysql数据库'::varchar2) from dual; - lengthb ---------- - 17 -(1 row) -``` - -20、兼容replace函数,功能:替换指定字符串中的字符或删除字符,支持参数:text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, 测试用例如下: -替换'jack and jue'中的'j'为'bl': - -``` -select replace('jack and jue','j','bl') from dual; - replace ----------------- - black and blue -(1 row) -``` - -删除'jack and jue'中的'j': - -``` -select replace('jack and jue','j') from dual; - replace ------------- - ack and ue -(1 row) -``` - -21、兼容regexp_replace函数,此函数为replace函数的扩展。功能:用于通过正则表达式来进行匹配替换。支持参数:text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, 测试用例如下: -将匹配到的数字替换为*#: - -``` -select regexp_replace('01234abcd56789','[0-9]','*#')from dual; - regexp_replace --------------------------- - *#*#*#*#*#abcd*#*#*#*#*# -(1 row) -``` - -从第二个数开始将匹配到的数字替换为*#: - -``` -select regexp_replace('01234abcd56789','[0-9]','*#',2)from dual; - regexp_replace -------------------------- - 0*#*#*#*#abcd*#*#*#*#*# -``` - -删除'01234abcd56789'中的'01': - -``` -select regexp_replace('01234abcd56789','01')from dual; - regexp_replace ----------------- - 234abcd56789 -(1 row) -``` - -用'xxx'替换01234abcd56789'中的012: - -``` -select regexp_replace('01234abcd56789','012','xxx')from dual; - regexp_replace ----------------- - xxx34abcd56789 -(1 row) -``` - -22、兼容regexp_substr函数,功能:拾取合符正则表达式描述的字符子串,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text /varchar2 ,varchar2,测试用例如下: -查询'012ab34'中从第一个数开始的012字串: - -``` -select regexp_substr('012ab34', '012',1) from dual; - regexp_substr ---------------- - 012 -(1 row) -``` - -查询'012ab34'中从第一个数第一组开始的012字串: -``` -select regexp_substr('012ab34', '012',1,1) from dual; - regexp_substr ---------------- - 012 -(1 row) -``` - -查询'012a012Ab34'中从第一个数第一组开始不区分大小写的012字串: - -``` -select regexp_substr('012a012Ab34', '012A',1,1,'i') from dual; - regexp_substr ---------------- - 012a -(1 row) -``` - -查询'012a012Ab34'中从第一个数第一组开始区分大小写的012字串: - -``` -select regexp_substr('012a012Ab34', '012A',1,1,'c') from dual; - regexp_substr ---------------- - 012A -(1 row) -``` - -查询'数据库'中 '数据'子串: - -``` -select regexp_substr('数据库', '数据') from dual; - regexp_substr ---------------- - 数据 -(1 row) -``` - -23、兼容regexp_instr函数,功能:用于标定符合正则表达式的字符子串的开始位置,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text/text, text, integer, integer, text, integer/ varchar2, varchar2,测试用例如下: -查询'abcaBcabc'中从第一个字符开始,出现abc子串的位置: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1); - regexp_instr --------------- - 1 -(1 row) -``` - -查询'abcaBcabc'中从第一个字符开始,第三次出现abc子串的位置: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1, 3); - regexp_instr --------------- - 7 -(1 row) -``` - -查询'abcabcabc'中从第一个字符开始,第二次出现abc子串后发生的位置: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1, 2,1); - regexp_instr --------------- - 7 -(1 row) -``` - -查询'abcaBcabc'中从第一个字符开始,第一次出现abc子串后发生的位置(区分大小写): - -``` -SELECT regexp_instr('abcaBcabc', 'abc',1,2,1,'c'); - regexp_instr --------------- - 7 -(1 row) -``` - -查询'数据库'中'库'出现的位置: - -``` -SELECT regexp_instr('数据库', '库'); - regexp_instr --------------- - 3 -(1 row) -``` - -24、兼容regexp_like函数,功能:与like类似,用于模糊查询。支持参数:varchar2, varchar2 /varchar2, varchar2 varchar2, -首先创建一个regexp_like表用于测试用例查询: - -``` -create table t_regexp_like -( - id varchar(4), - value varchar(10) - -); -insert into t_regexp_like values ('1','1234560'); -insert into t_regexp_like values ('2','1234560'); -insert into t_regexp_like values ('3','1b3b560'); -insert into t_regexp_like values ('4','abc'); -insert into t_regexp_like values ('5','abcde'); -insert into t_regexp_like values ('6','ADREasx'); -insert into t_regexp_like values ('7','123 45'); -insert into t_regexp_like values ('8','adc de'); -insert into t_regexp_like values ('9','adc,.de'); -insert into t_regexp_like values ('10','abcbvbnb'); -insert into t_regexp_like values ('11','11114560'); -``` - -测试用例如下: -查询t_regexp_like表中带有abc的列: - -``` -select * from t_regexp_like where regexp_like(value,'abc'); - id | value -----+---------- - 4 | abc - 5 | abcde - 10 | abcbvbnb -(3 rows) - -``` - -查询t_regexp_like表中带有ABC的列(不区分大小写): - -``` -select * from t_regexp_like where regexp_like(value,'ABC','i'); - id | value -----+---------- - 4 | abc - 5 | abcde - 10 | abcbvbnb -(3 rows) - -``` - -25、兼容to_number函数,功能:是将一些处理过的按一定格式编排过的字符串变回数值型的格式,支持参数:text/text,text测试用例如下: -将字符串'-34,338,492'转换为数值型格式: - -``` -SELECT to_number('34,338,492', '99,999,999') from dual; - to_number ------------ - -34338492 -(1 row) -``` - -将字符串'5.01-'转换为数值型格式: - -``` -SELECT to_number('5.01-', '9.99S'); - - to_number ------------ - -5.01 -(1 row) -``` - -26、兼容to_char函数,功能:将数字或日期转换为字符类型,支持参数:date/date,text/timestamp/timestamp,text测试用例如下: -将当前系统日期转换为字符格式: - -``` -select to_char(sysdate()) from dual; - to_char ------------- - 2023-07-10 -(1 row) -``` - -将当前系统日期转换为月份/日期/年字符格式: - -``` -select to_char(sysdate(),'mm/dd/yyyy') from dual; - to_char ------------- - 07/10/2023 -(1 row) -``` - -将当前日期的timestamp格式转换为字符格式: - -``` -SELECT to_char(sysdate()::timestamp); - to_char ----------------------------- - 2023-07-10 09:46:44.000000 -``` - -将当前日期的timestamp格式转换为月份/日期/年字符格式: - -``` -SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); - to_char ------------- - 07-2023-10 -(1 row) -``` - -27、兼容to_date函数,功能:将字符类型转换为日期类型,支持参数:text/text,text测试用例如下: -将'2023/07/06'转换为日期类型: - -``` -select to_date('20230706') from dual; - to_date ------------- - 2023-07-06 -(1 row) -``` - -将'-44-02-01'转换为日期类型: - -``` -SELECT to_date('-44,0201','YYYY-MM-DD'); - to_date ------------- - 0044-02-01 -(1 row) -``` - -28、兼容to_timestamp函数,功能:可以存储年、月、日、小时、分钟、秒,同时还可以存储秒的小数部分。支持参数:text/text,text测试用例如下: -查询'2018-11-02 12:34:56.025'以日期形式输出: - -``` -SELECT to_timestamp('20181102.12.34.56.025'); - to_timestamp ----------------------------- - 2018-11-02 12:34:56.025000 -(1 row) -``` - -查询’2011,12,18 11:38’以日期形式输出: - -``` -SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ----------------------------- - 2011-12-18 11:38:00.000000 -(1 row) -``` - -29、兼容to_timestamp_tz函数,功能:根据时间查询,时间字符串有T,Z并有毫秒,时区。测试用例如下: -查询'2016-10-9 14:10:10.123000'以日期形式输出: - -``` - SELECT to_timestamp_tz('2016-10-9 14:10:10.123000') FROM DUAL; - to_timestamp_tz ------------------------------------ - 2016-10-09 14:10:10.123000 +08:00 -(1 row) -``` - -查询'10-9-2016 14:10:10.123000 +8:30'以日期形式输出: - -``` - SELECT to_timestamp_tz('10-9-2016 14:10:10.123000 +8:30', 'DD-MM-YYYY HH24:MI:SS.FF TZH:TZM') FROM DUAL; - to_timestamp_tz ------------------------------------ - 2016-09-10 13:40:10.123000 +08:00 -(1 row) -``` - -30、兼容to_yminterval函数,功能:将一个字符串类型转化为年和月的时间差类型,支持参数:text, 测试用例如下: -查询'20110101'以后两个年零八个月后的日期: - -``` -select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; - ?column? ------------- - 2013-09-01 -(1 row) -``` - -31、兼容to_dsinterval函数,功能:将一个日期加上一定的小时或者天数变成另外一个日期,支持参数:text,测试用例如下: -查询当前系统时间加上9个半小时后的日期(当前为2023-07-06,18:00): - -``` -select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; - newdate ------------- - 2023-07-07 -(1 row) -``` - -32、兼容numtodsinterval函数,功能:将数字转换成时间间隔类型的数据。支持参数:double precision, text测试用例如下: -转换100.00个小时为时间间隔类型数据: - -``` -SELECT NUMTODSINTERVAL(100.00, 'hour'); - numtodsinterval -------------------------------- - +000000004 04:00:00.000000000 -(1 row) -``` - -转换100分钟为时间间隔类型数据: - -``` -SELECT NUMTODSINTERVAL(100, 'minute'); - numtodsinterval -------------------------------- - +000000000 01:40:00.000000000 -(1 row) -``` - -33、兼容numtoyminterval函数,功能:将数字转换成日期间隔类型的数据。 -支持参数:double precision,text,测试用例如下: -转换1.00,year为日期间隔: - -``` -SELECT NUMTOYMINTERVAL(1.00,'year'); - numtoyminterval ------------------ - +000000001-00 -(1 row) -``` - -转换1,mouth为日期间隔: - -``` -SELECT NUMTOYMINTERVAL(1,'month'); - numtoyminterval ------------------ - +000000000-01 -(1 row) -``` - -34、兼容localtimestamp函数,功能:返回会话中的日期和时间,支持参数:integer, 函数中增加参数为精度,测试用例如下: -返回当前会话中的日期和时间: - -``` -select localtimestamp from dual; - localtimestamp ----------------------------- - 2023-07-07 09:18:15.896472 -(1 row) -``` - -返回当前会话中的日期和时间(精度为1): - -``` -select localtimestamp(1) from dual; - localtimestamp ----------------------------- - 2023-07-07 09:18:16.100000 -(1 row) -``` - -35、兼容from_tz函数,功能:将时间从一个时区转换为另一个时区,支持参数;timestamp, text ,测试用例如下: -将'2000-03-28 08:00:00', '3:00'转换为当前时区: - -``` -SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; - from_tz ------------------------------------ - 2000-03-28 13:00:00.000000 +08:00 -(1 row) -``` - -36、兼容sys_extract_utc函数,功能:将一个timestamptz转换为UTC时区时间。支持参数:timestamp with time zone 测试用例如下: -查询转换timestamp '2000-03-28 11:30:00.00 -8:00'为UTC时区后的时间: - -``` -select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; - sys_extract_utc ----------------------------- - 2000-03-28 19:30:00.000000 -(1 row) -``` - -37、兼容sessiontimezone函数,功能:查看时区详细信息,测试用例如下: -查看当前时区的详细信息: - -``` -select sessiontimezone() from dual; - sessiontimezone ------------------ - Asia/Shanghai -(1 row) -``` - -修改timezone后,查看时区相信信息: - -``` -set timezone = 'Asia/Hong_Kong'; -SET -select sessiontimezone() from dual; - sessiontimezone ------------------ - Asia/Hong_Kong -(1 row) -``` - -38、兼容hextoraw函数,功能:将字符串表示的二进制数值转换为一个raw数值。支持参数:text,测试用例如下: -将字符串'abcdef'转换为raw数值: - -``` -select hextoraw('abcdef')from dual; - hextoraw ----------- - \xabcdef -(1 row) -``` - -39、兼容uid函数,功能:获取数据库的实例名。测试用例如下: -获取当前数据库的实例名: - -``` -select uid() from dual; - uid ------ - 10 -(1 row) -``` - -40、兼容USERENV函数,功能:返回当前用户环境的信息,测试用例如下: -查看当前用户是否是dba,如果是返回ture: - -``` -select userenv('isdba')from dual; - get_isdba ------------ - TRUE -(1 row) -``` - -查看会话标志: - -``` -select userenv('sessionid')from dual; - get_sessionid ---------------- - 1 -(1 row) -``` - +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 内置数据类型与内置函数 + +== 内置数据类型 + +|==== +|char +|varchar +|varchar2 +|number +|binary_float +|binary_double +|date +|timestamp +|timestamp with time zone +|timestamp with local time zone +|interval year to month +|interval day to second +|raw +|long +|==== + +== 内置函数类型 + +|==== +|sysdate +|systimestamp +|add_months +|last_day +|next_day +|months_between +|current_date +|current_timestamp +|new_time +|tz_offset +|trunc +|instrb +|substr +|substrb +|trim +|ltrim +|rtrim +|length +|lengthb +|replace +|regexp_replace +|regexp_substr +|regexp_instr +|regexp_like +|to_number +|to_char +|to_date +|to_timestamp +|to_timestamp_tz +|to_yminterval +|to_dsinterval +|numtodsinterval +|numtoyminterval +|localtimestamp +|from_tz +|sys_extract_utc +|sessiontimezone +|hextoraw +|uid +|USERENV +|asciistr +|to_multi_byte +|to_single_byte +|compose +|decompose +|==== + +== 内置函数说明 + +1、兼容sysdate函数,功能:查看对应的日期与时间,测试用例如下: +查询当前系统的日期: + +``` +select sysdate() from dual; + sysdate +------------ + 2023-07-06 +(1 row) +``` + +查询往前推1天的日期: + +``` +select sysdate()-1 from dual; + ?column? +------------ + 2023-07-05 +(1 row) +``` + +2、兼容systimestamp函数,功能:返回本机数据库上当前系统日期和时间(包括微秒和时区),测试用例如下: +查询当前日期的日期和时间: + +``` +select systimestamp() from dual; + systimestamp +----------------------------------- + 2023-07-06 10:18:31.674322 +08:00 +(1 row) +``` + +3、兼容add_months函数,功能:函数将一个月数(n)添加一个日期,并返回相隔n月的同一天,支持参数:date, number;测试用例如下: +查询当前日期(七月六日)的下个月的同一天: + +``` +select add_months(sysdate(),1) from dual; + add_months +------------ + 2023-08-06 +(1 row) +``` + +查询当前日期的上个月的同一天: + +``` +select add_months(sysdate(),-1) from dual; + add_months +------------ + 2023-06-06 +(1 row) +``` + +4、兼容last_day函数,功能:返回指定日期所在月份的最后一天,支持参数:date,测试用例如下: +查询当天所在月份的最后一天: + +``` +select last_day(sysdate())from dual; + last_day +------------ + 2023-07-31 +(1 row) +``` + +查询某一天所在月份的最后一天: + +``` +select last_day(to_date('2019-09-01'))from dual; + last_day +------------ + 2019-09-30 +(1 row) +``` + +5、兼容next_day函数,功能:返回指定日期的下一个日期。支持参数:date, integer /date ,text, 说明:当函数中第二个参数传的星期数比现有星期数小时,会返回下一个星期的日期;当函数中第二个参数所传的日期比现有星期数大,会返回本周相应星期日期。测试用例如下: +查询当前日期的下一天: + +``` +select next_day(sysdate(),1) from dual; + next_day +------------ + 2023-07-07 +(1 row) +``` + +查询当前日期的下个星期五: + +``` +select next_day(sysdate(),'FRIDAY') from dual; + next_day +------------ + 2023-07-07 +(1 row) +``` + +6、兼容months_between函数,功能:返回日期类型的date1和date2之间相差的月份,支持参数:date,date,说明:如果date1晚于date2,返回正数;如果date1早于date2返回负数;如果date1和date2是某月里的同一天,返回结果为整数;如果不是同一天,会在每月31天的基础上返回带有小数部分的结果。测试用例如下: +查询不同月份同一天之间相差的月份: + +``` +select months_between(to_date('2023-07-06'),to_date('2023-08-06')) from dual; + months_between +---------------- + -1 +(1 row) +``` + +查询不同月份不同日期之间相差的月份: + +``` +select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; + months_between +-------------------- + -0.967741935483871 +(1 row) +``` + +7、兼容current_date函数,功能:返回当前时区的当前日期,测试用例如下: +查询当前时区的当前日期: + +``` +select current_date from dual; + current_date +-------------- + 2023-07-06 +(1 row) +``` + +8、兼容current_timestamp函数,功能:返回当前时区的当前日期与当前时间,包含当前时区信息。支持参数:integer, 说明:返回的时间可调整精度。测试用例如下: +查询当前时区的当前日期与时间: + +``` +select current_timestamp from dual; + current_timestamp +----------------------------------- + 2023-07-06 10:27:01.440600 +08:00 +(1 row) +``` + +查询当前时区的当前日期与时间(精度调整为前三位小数): + +``` +select current_timestamp(3) from dual; + current_timestamp +----------------------------------- + 2023-07-06 10:27:14.182000 +08:00 +(1 row) +``` + +9、兼容new_time函数,功能:返回某个时间在某时区所对应的在另一个时区的日期,支持参数:date, text, text ,测试用例如下: +返回当前日期在另一个时区对应的日期: + +``` +select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; + bj_time | los_angles +------------+------------ + 2023-07-06 | 2023-07-06 +(1 row) +``` + +10、兼容tz_offset函数,功能:返回给定时区与标准时区的偏移量,支持参数:text,测试用例如下: +返回给定时区与标准时区偏移量: + +``` +select tz_offset('US/Eastern') from dual; + tz_offset +----------- + -04:00 +(1 row) +``` + +11、兼容trunc函数,功能:可以截取日期,得到想要的数值,如年,月,日,时,分,支持参数:date/date,text,测试用例如下: +截取当前日期: + +``` +select trunc(sysdate()) from dual; + trunc +------------ + 2023-07-06 +(1 row) +``` + +截取年,返回值只有年是正确的,月和日不是准确值: + +``` +select trunc(sysdate(),'yyyy') from dual; + trunc +------------ + 2023-01-01 +(1 row) +``` + +截取月,返回值只有月是正确的,年和日不是准确值: + +``` +select trunc(sysdate(),'mm') from dual; + trunc +------------ + 2023-07-01 +(1 row) +``` + +12、兼容instrb函数,功能:字符串查找函数,返回字符串的位置,支持参数: varchar2, text, number DEFAULT 1, number DEFAULT 1,以下为测试用例: +返回CORPORATE FLOOR中默认第一次出现OR时字符串的位置: + +``` +SELECT INSTRB('CORPORATE FLOOR','OR') "Instring in bytes" FROM DUAL; + Instring in bytes +------------------- + 2 +(1 row) +``` + +返回corporate floor中从第五个字符开始查询,第二次出现or时字符串的位置: + +``` +SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; + Instring in bytes +------------------- + 14 +(1 row) +``` + +13、兼容substr函数,功能:截取字符串函数,以字符为单位截取,支持参数:text, integer, 测试用例如下: +截取’今天天气很好’中从第五个字符开始,往后的字符串: + +``` +SELECT SUBSTR('今天天气很好',5) "Substring with bytes" FROM DUAL; + + Substring with bytes +---------------------- + 很好 +(1 row) +``` + +14、兼容substrb函数,功能:截取字符串函数,以字节为单位截取,支持参数:varchar2, number/varchar2, number,number,测试用例如下: +截取’今天天气很好’中从第五个字节开始,往后的字符串: + +``` +SELECT SUBSTRB('今天天气很好',5) "Substring with bytes" FROM DUAL; + Substring with bytes +---------------------- + 天气很好 +(1 row) +``` + +截取’今天天气很好’中从第五个字节开始,第八个字节结束的字符串: + +``` +SELECT SUBSTRB('今天天气很好',5,8) "Substring with bytes" FROM DUAL; + Substring with bytes +---------------------- + 天气 +(1 row) +``` + +15、兼容trim函数,功能:去除指定字符串的左右空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: +去除' aaa bbb ccc '的左右空格: + +``` +select trim(' aaa bbb ccc ')trim from dual; + trim +------------- + aaa bbb ccc +(1 row) +``` + +去除'aaa bbb ccc'中的aaa: + +``` +select trim('aaa bbb ccc','aaa')trim from dual; + trim +---------- + bbb ccc +(1 row) +``` + +16、兼容ltrim函数,功能:去除指定字符串的左侧空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: +去除' abcdefg '的左侧空格: + +``` +select ltrim(' abcdefg ')ltrim from dual; + ltrim +------------ + abcdefg +(1 row) +``` + +从'abcdefg'左侧开始遍历,一旦存在某字符出现在'fegab'中就去除,不存在则返回结果: + +``` +select ltrim('abcdefg','fegab')ltrim from dual; + ltrim +------- + cdefg +(1 row) +``` + +17、兼容rtrim函数,功能:去除指定字符串的右侧空格,测试用例如下: +去除' abcdefg '的右侧空格: + +``` +select rtrim(' abcdefg ')rtrim from dual; + rtrim +---------------- + abcdefg +(1 row) +``` + +从'abcdefg'右侧开始遍历,一旦存在某字符出现在'fegab'中就去除,不存在则返回结果: + +``` +select rtrim('abcdefg','fegab')rtrim from dual; + rtrim +------- + abcd +(1 row) +``` + +18、兼容length函数,功能:求取指定字符串字符的长度,支持参数:char/integer/varchar2测试用例如下: +查询223的字符长度: + +``` +select length(223) from dual; + length +-------- + 3 +(1 row) +``` + +查询'223'的字符长度: + +``` +select length('223') from dual; + length +-------- + 3 +(1 row) +``` + +查询'ivorysql数据库'的字符长度: + +``` +select length('ivorysql数据库') from dual; + length +-------- + 11 +(1 row) +``` + +19、兼容lengthb功能:求取指定字符串字节的长度,支持参数:char/bytea/varchar2测试用例如下: +查询'ivorysql'的字节长度: + +``` +select lengthb('ivorysq'::char) from dual; + lengthb +--------- + 1 +(1 row) +``` + +查询'0x2C'的字节长度: + +``` +select lengthb('0x2C'::bytea) from dual; + lengthb +--------- + 4 +(1 row) +``` + +查询'ivorysql数据库'的字节长度: + +``` +select lengthb('ivorysql数据库'::varchar2) from dual; + lengthb +--------- + 17 +(1 row) +``` + +20、兼容replace函数,功能:替换指定字符串中的字符或删除字符,支持参数:text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, 测试用例如下: +替换'jack and jue'中的'j'为'bl': + +``` +select replace('jack and jue','j','bl') from dual; + replace +---------------- + black and blue +(1 row) +``` + +删除'jack and jue'中的'j': + +``` +select replace('jack and jue','j') from dual; + replace +------------ + ack and ue +(1 row) +``` + +21、兼容regexp_replace函数,此函数为replace函数的扩展。功能:用于通过正则表达式来进行匹配替换。支持参数:text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, 测试用例如下: +将匹配到的数字替换为*#: + +``` +select regexp_replace('01234abcd56789','[0-9]','*#')from dual; + regexp_replace +-------------------------- + *#*#*#*#*#abcd*#*#*#*#*# +(1 row) +``` + +从第二个数开始将匹配到的数字替换为*#: + +``` +select regexp_replace('01234abcd56789','[0-9]','*#',2)from dual; + regexp_replace +------------------------- + 0*#*#*#*#abcd*#*#*#*#*# +``` + +删除'01234abcd56789'中的'01': + +``` +select regexp_replace('01234abcd56789','01')from dual; + regexp_replace +---------------- + 234abcd56789 +(1 row) +``` + +用'xxx'替换01234abcd56789'中的012: + +``` +select regexp_replace('01234abcd56789','012','xxx')from dual; + regexp_replace +---------------- + xxx34abcd56789 +(1 row) +``` + +22、兼容regexp_substr函数,功能:拾取合符正则表达式描述的字符子串,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text /varchar2 ,varchar2,测试用例如下: +查询'012ab34'中从第一个数开始的012字串: + +``` +select regexp_substr('012ab34', '012',1) from dual; + regexp_substr +--------------- + 012 +(1 row) +``` + +查询'012ab34'中从第一个数第一组开始的012字串: +``` +select regexp_substr('012ab34', '012',1,1) from dual; + regexp_substr +--------------- + 012 +(1 row) +``` + +查询'012a012Ab34'中从第一个数第一组开始不区分大小写的012字串: + +``` +select regexp_substr('012a012Ab34', '012A',1,1,'i') from dual; + regexp_substr +--------------- + 012a +(1 row) +``` + +查询'012a012Ab34'中从第一个数第一组开始区分大小写的012字串: + +``` +select regexp_substr('012a012Ab34', '012A',1,1,'c') from dual; + regexp_substr +--------------- + 012A +(1 row) +``` + +查询'数据库'中 '数据'子串: + +``` +select regexp_substr('数据库', '数据') from dual; + regexp_substr +--------------- + 数据 +(1 row) +``` + +23、兼容regexp_instr函数,功能:用于标定符合正则表达式的字符子串的开始位置,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text/text, text, integer, integer, text, integer/ varchar2, varchar2,测试用例如下: +查询'abcaBcabc'中从第一个字符开始,出现abc子串的位置: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1); + regexp_instr +-------------- + 1 +(1 row) +``` + +查询'abcaBcabc'中从第一个字符开始,第三次出现abc子串的位置: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1, 3); + regexp_instr +-------------- + 7 +(1 row) +``` + +查询'abcabcabc'中从第一个字符开始,第二次出现abc子串后发生的位置: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1, 2,1); + regexp_instr +-------------- + 7 +(1 row) +``` + +查询'abcaBcabc'中从第一个字符开始,第一次出现abc子串后发生的位置(区分大小写): + +``` +SELECT regexp_instr('abcaBcabc', 'abc',1,2,1,'c'); + regexp_instr +-------------- + 7 +(1 row) +``` + +查询'数据库'中'库'出现的位置: + +``` +SELECT regexp_instr('数据库', '库'); + regexp_instr +-------------- + 3 +(1 row) +``` + +24、兼容regexp_like函数,功能:与like类似,用于模糊查询。支持参数:varchar2, varchar2 /varchar2, varchar2 varchar2, +首先创建一个regexp_like表用于测试用例查询: + +``` +create table t_regexp_like +( + id varchar(4), + value varchar(10) + +); +insert into t_regexp_like values ('1','1234560'); +insert into t_regexp_like values ('2','1234560'); +insert into t_regexp_like values ('3','1b3b560'); +insert into t_regexp_like values ('4','abc'); +insert into t_regexp_like values ('5','abcde'); +insert into t_regexp_like values ('6','ADREasx'); +insert into t_regexp_like values ('7','123 45'); +insert into t_regexp_like values ('8','adc de'); +insert into t_regexp_like values ('9','adc,.de'); +insert into t_regexp_like values ('10','abcbvbnb'); +insert into t_regexp_like values ('11','11114560'); +``` + +测试用例如下: +查询t_regexp_like表中带有abc的列: + +``` +select * from t_regexp_like where regexp_like(value,'abc'); + id | value +----+---------- + 4 | abc + 5 | abcde + 10 | abcbvbnb +(3 rows) + +``` + +查询t_regexp_like表中带有ABC的列(不区分大小写): + +``` +select * from t_regexp_like where regexp_like(value,'ABC','i'); + id | value +----+---------- + 4 | abc + 5 | abcde + 10 | abcbvbnb +(3 rows) + +``` + +25、兼容to_number函数,功能:是将一些处理过的按一定格式编排过的字符串变回数值型的格式,支持参数:text/text,text测试用例如下: +将字符串'-34,338,492'转换为数值型格式: + +``` +SELECT to_number('34,338,492', '99,999,999') from dual; + to_number +----------- + -34338492 +(1 row) +``` + +将字符串'5.01-'转换为数值型格式: + +``` +SELECT to_number('5.01-', '9.99S'); + + to_number +----------- + -5.01 +(1 row) +``` + +26、兼容to_char函数,功能:将数字或日期转换为字符类型,支持参数:date/date,text/timestamp/timestamp,text测试用例如下: +将当前系统日期转换为字符格式: + +``` +select to_char(sysdate()) from dual; + to_char +------------ + 2023-07-10 +(1 row) +``` + +将当前系统日期转换为月份/日期/年字符格式: + +``` +select to_char(sysdate(),'mm/dd/yyyy') from dual; + to_char +------------ + 07/10/2023 +(1 row) +``` + +将当前日期的timestamp格式转换为字符格式: + +``` +SELECT to_char(sysdate()::timestamp); + to_char +---------------------------- + 2023-07-10 09:46:44.000000 +``` + +将当前日期的timestamp格式转换为月份/日期/年字符格式: + +``` +SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); + to_char +------------ + 07-2023-10 +(1 row) +``` + +27、兼容to_date函数,功能:将字符类型转换为日期类型,支持参数:text/text,text测试用例如下: +将'2023/07/06'转换为日期类型: + +``` +select to_date('20230706') from dual; + to_date +------------ + 2023-07-06 +(1 row) +``` + +将'-44-02-01'转换为日期类型: + +``` +SELECT to_date('-44,0201','YYYY-MM-DD'); + to_date +------------ + 0044-02-01 +(1 row) +``` + +28、兼容to_timestamp函数,功能:可以存储年、月、日、小时、分钟、秒,同时还可以存储秒的小数部分。支持参数:text/text,text测试用例如下: +查询'2018-11-02 12:34:56.025'以日期形式输出: + +``` +SELECT to_timestamp('20181102.12.34.56.025'); + to_timestamp +---------------------------- + 2018-11-02 12:34:56.025000 +(1 row) +``` + +查询’2011,12,18 11:38’以日期形式输出: + +``` +SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); + to_timestamp +---------------------------- + 2011-12-18 11:38:00.000000 +(1 row) +``` + +29、兼容to_timestamp_tz函数,功能:根据时间查询,时间字符串有T,Z并有毫秒,时区。测试用例如下: +查询'2016-10-9 14:10:10.123000'以日期形式输出: + +``` + SELECT to_timestamp_tz('2016-10-9 14:10:10.123000') FROM DUAL; + to_timestamp_tz +----------------------------------- + 2016-10-09 14:10:10.123000 +08:00 +(1 row) +``` + +查询'10-9-2016 14:10:10.123000 +8:30'以日期形式输出: + +``` + SELECT to_timestamp_tz('10-9-2016 14:10:10.123000 +8:30', 'DD-MM-YYYY HH24:MI:SS.FF TZH:TZM') FROM DUAL; + to_timestamp_tz +----------------------------------- + 2016-09-10 13:40:10.123000 +08:00 +(1 row) +``` + +30、兼容to_yminterval函数,功能:将一个字符串类型转化为年和月的时间差类型,支持参数:text, 测试用例如下: +查询'20110101'以后两个年零八个月后的日期: + +``` +select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; + ?column? +------------ + 2013-09-01 +(1 row) +``` + +31、兼容to_dsinterval函数,功能:将一个日期加上一定的小时或者天数变成另外一个日期,支持参数:text,测试用例如下: +查询当前系统时间加上9个半小时后的日期(当前为2023-07-06,18:00): + +``` +select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; + newdate +------------ + 2023-07-07 +(1 row) +``` + +32、兼容numtodsinterval函数,功能:将数字转换成时间间隔类型的数据。支持参数:double precision, text测试用例如下: +转换100.00个小时为时间间隔类型数据: + +``` +SELECT NUMTODSINTERVAL(100.00, 'hour'); + numtodsinterval +------------------------------- + +000000004 04:00:00.000000000 +(1 row) +``` + +转换100分钟为时间间隔类型数据: + +``` +SELECT NUMTODSINTERVAL(100, 'minute'); + numtodsinterval +------------------------------- + +000000000 01:40:00.000000000 +(1 row) +``` + +33、兼容numtoyminterval函数,功能:将数字转换成日期间隔类型的数据。 +支持参数:double precision,text,测试用例如下: +转换1.00,year为日期间隔: + +``` +SELECT NUMTOYMINTERVAL(1.00,'year'); + numtoyminterval +----------------- + +000000001-00 +(1 row) +``` + +转换1,mouth为日期间隔: + +``` +SELECT NUMTOYMINTERVAL(1,'month'); + numtoyminterval +----------------- + +000000000-01 +(1 row) +``` + +34、兼容localtimestamp函数,功能:返回会话中的日期和时间,支持参数:integer, 函数中增加参数为精度,测试用例如下: +返回当前会话中的日期和时间: + +``` +select localtimestamp from dual; + localtimestamp +---------------------------- + 2023-07-07 09:18:15.896472 +(1 row) +``` + +返回当前会话中的日期和时间(精度为1): + +``` +select localtimestamp(1) from dual; + localtimestamp +---------------------------- + 2023-07-07 09:18:16.100000 +(1 row) +``` + +35、兼容from_tz函数,功能:将时间从一个时区转换为另一个时区,支持参数;timestamp, text ,测试用例如下: +将'2000-03-28 08:00:00', '3:00'转换为当前时区: + +``` +SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; + from_tz +----------------------------------- + 2000-03-28 13:00:00.000000 +08:00 +(1 row) +``` + +36、兼容sys_extract_utc函数,功能:将一个timestamptz转换为UTC时区时间。支持参数:timestamp with time zone 测试用例如下: +查询转换timestamp '2000-03-28 11:30:00.00 -8:00'为UTC时区后的时间: + +``` +select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; + sys_extract_utc +---------------------------- + 2000-03-28 19:30:00.000000 +(1 row) +``` + +37、兼容sessiontimezone函数,功能:查看时区详细信息,测试用例如下: +查看当前时区的详细信息: + +``` +select sessiontimezone() from dual; + sessiontimezone +----------------- + Asia/Shanghai +(1 row) +``` + +修改timezone后,查看时区相信信息: + +``` +set timezone = 'Asia/Hong_Kong'; +SET +select sessiontimezone() from dual; + sessiontimezone +----------------- + Asia/Hong_Kong +(1 row) +``` + +38、兼容hextoraw函数,功能:将字符串表示的二进制数值转换为一个raw数值。支持参数:text,测试用例如下: +将字符串'abcdef'转换为raw数值: + +``` +select hextoraw('abcdef')from dual; + hextoraw +---------- + \xabcdef +(1 row) +``` + +39、兼容uid函数,功能:获取数据库的实例名。测试用例如下: +获取当前数据库的实例名: + +``` +select uid() from dual; + uid +----- + 10 +(1 row) +``` + +40、兼容USERENV函数,功能:返回当前用户环境的信息,测试用例如下: +查看当前用户是否是dba,如果是返回ture: + +``` +select userenv('isdba')from dual; + get_isdba +----------- + TRUE +(1 row) +``` + +查看会话标志: + +``` +select userenv('sessionid')from dual; + get_sessionid +--------------- + 1 +(1 row) +``` + +41、兼容ASCIISTR函数,功能:传入字符串,返回对应的ASCII字符,测试用例如下: +只有ASCII字符: +``` + select asciistr('Hello, World!') from dual; + asciistr +--------------- + Hello, World! +(1 row) +``` + +非ASCII字符: +``` + select asciistr('你好') from dual; + asciistr +------------ + \4F60\597D +``` + +同时包含ASCII字符和非ASCII字符: +``` + select asciistr('ABÄCDE') from dual; + asciistr +------------ + AB\00C4CDE +(1 row) +``` + +42、兼容TO_MULTI_BYTE函数, 功能:将字符串中的半角字符转换为全角字符: +输入半角字符,转换为全角字符: +``` +select to_multi_byte('1.2'::text) ; + to_multi_byte +--------------- + 1.2 +``` + +43、兼容TO_SINGLE_BYTE函数, 功能:将字符串中的半角字符转换为全角字符 +输入全角字符,转换为半角字符: +``` +select to_single_byte('1.2'); + to_single_byte +---------------- + 1.2 +``` + +44、兼容COMPOSE函数,功能:将基本字符和组合标记组合一个复合Unicode字符: +输入基本字符a和组合标记768, 返回法语à +``` +select compose('a'||chr(768)) from dual; + compose +--------- + à +(1 row) +``` + + +45、兼容DECOMPOSE函数,功能:将复合Unicode字符(如带有重音或特殊符号的字符)分解为其基本字符和组合标记 +输入法语é,返回基本字符e和组合标记301: +``` +select asciistr(decompose('é')) from dual; + asciistr +---------- + e\0301 +``` \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/22.adoc b/CN/modules/ROOT/pages/v1.17/19.adoc similarity index 95% rename from CN/modules/ROOT/pages/v3.0/22.adoc rename to CN/modules/ROOT/pages/v1.17/19.adoc index 64846f7..e95971b 100644 --- a/CN/modules/ROOT/pages/v3.0/22.adoc +++ b/CN/modules/ROOT/pages/v1.17/19.adoc @@ -1,28 +1,28 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= 新增Oracle兼容模式的端口与Ip - -== 目的 - -- 为了将Oracle端口、Ip与PG的端口Ip进行区分。现需要增加对ORAPORT和ORAHOST的处理; - -== 功能 - -- 新增ivoryhost:需要在连接时新增参数ivoryhost即可指定,其功能类似 host; - -- 新增ivoryport:相较于host,port的功能相对复杂一些。其中涉及到可以在configure阶段配置,连接阶段指定端口; - -== 测试用例: -``` - ./configure --with-oraport=5555 - ./initdb .... - ./pg_ctl -D ../data start - - ./pg_ctl -o “-p 5433 -o 1522” -D ../data -``` - - -​ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 新增Oracle兼容模式的端口与Ip + +== 目的 + +- 为了将Oracle端口、Ip与PG的端口Ip进行区分。现需要增加对ORAPORT和ORAHOST的处理; + +== 功能 + +- 新增ivoryhost:需要在连接时新增参数ivoryhost即可指定,其功能类似 host; + +- 新增ivoryport:相较于host,port的功能相对复杂一些。其中涉及到可以在configure阶段配置,连接阶段指定端口; + +== 测试用例: +``` + ./configure --with-oraport=5555 + ./initdb .... + ./pg_ctl -D ../data start + + ./pg_ctl -o “-p 5433 -o 1522” -D ../data +``` + + +​ diff --git a/CN/modules/ROOT/pages/v3.0/2.adoc b/CN/modules/ROOT/pages/v1.17/2.adoc similarity index 77% rename from CN/modules/ROOT/pages/v3.0/2.adoc rename to CN/modules/ROOT/pages/v1.17/2.adoc index 355f2c7..ebc200d 100644 --- a/CN/modules/ROOT/pages/v3.0/2.adoc +++ b/CN/modules/ROOT/pages/v1.17/2.adoc @@ -13,8 +13,6 @@ IvorySQL社区始终承诺与PostgreSQL数据库保持100%兼容,并且可以 IvorySQL增加了一个名为 `ivorysql.compatible_mode` 的GUC参数用以控制IvorySQL的兼容模式,该参数有 `oracle` 和 `pg` 两种值。在初始化数据目录的时候,通过指定 `-m` 参数来指定数据目录的兼容模式,`-m pg` 则数据目录为PostgreSQL模式,该模式下 `ivorysql.compatible_mode` 参数将会失效,`-m oracle` 或者不指定 `-m` 参数则数据目录为兼容Oracle模式,该模式下 `ivorysql.compatible_mode` 参数初始值为 `oracle` 并且不支持部分PostgreSQL的语法,通过 `set ivorysql.compatible_mode to pg` 就可以使得数据库100%支持PostgreSQL的语法及功能。 -IvorySQL的亮点之一是PL/iSQL过程语言,它支持Oracle的PL/SQL语法。同时,IvorySQL通过增加与内核绑定的插件 *ivorysql_ora* 来实现兼容Oracle的功能,目前实现的功能包括内置函数、数据类型、系统视图、merge以及GUC参数的增加,未来将会继续以绑定内核的插件的形式来实现新的兼容功能。 - IvorySQL项目是在Apache 2.0许可证下发布的,社区鼓励且欢迎所有类型的贡献和参与。 === 产品目标和范围 @@ -69,12 +67,12 @@ IvorySQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS) == 与Oracle的兼容性 -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/14[ivorysql框架设计] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/15[GUC框架] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/16[大小写转换] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/17[双模式设计] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/18[兼容Oracle like] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/19[兼容Oracle匿名块] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/20[兼容Oracle函数与存储过程] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/21[内置数据类型与内置函数] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/22[新增Oracle兼容模式的端口与ip] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/11[1.ivorysql框架设计] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/12[2.GUC框架] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/13[3.大小写转换] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/14[4.双模式设计] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/15[5.兼容Oracle like] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/16[6.兼容Oracle匿名块] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/17[7.兼容Oracle函数与存储过程] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/18[8.内置数据类型与内置函数] +* https://docs.ivorysql.org/cn/ivorysql-doc/v1.17/v1.17/19[9.新增Oracle兼容模式的端口与IP] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/10.adoc b/CN/modules/ROOT/pages/v1.17/20.adoc similarity index 100% rename from CN/modules/ROOT/pages/v3.0/10.adoc rename to CN/modules/ROOT/pages/v1.17/20.adoc diff --git a/CN/modules/ROOT/pages/v3.0/11.adoc b/CN/modules/ROOT/pages/v1.17/21.adoc similarity index 100% rename from CN/modules/ROOT/pages/v3.0/11.adoc rename to CN/modules/ROOT/pages/v1.17/21.adoc diff --git a/CN/modules/ROOT/pages/v3.0/12.adoc b/CN/modules/ROOT/pages/v1.17/22.adoc similarity index 100% rename from CN/modules/ROOT/pages/v3.0/12.adoc rename to CN/modules/ROOT/pages/v1.17/22.adoc diff --git a/CN/modules/ROOT/pages/v3.0/3.adoc b/CN/modules/ROOT/pages/v1.17/3.adoc similarity index 75% rename from CN/modules/ROOT/pages/v3.0/3.adoc rename to CN/modules/ROOT/pages/v1.17/3.adoc index bc66d1a..21b964a 100644 --- a/CN/modules/ROOT/pages/v3.0/3.adoc +++ b/CN/modules/ROOT/pages/v1.17/3.adoc @@ -3,14 +3,12 @@ :sectnumlevels: 5 :imagesdir: ./_images -== 用户使用手册 +== **快速开始** === 入门指南 ==== 新用户指南 -如果您刚开始接触IvorySQL,您可以访问我们的 https://docs.ivorysql.org/cn/ivorysql-doc/beta/beta/1[地址]来初步了解IvorySQL的各项特性。您同样可以前往我们的 https://github.com/IvorySQL/IvorySQL[Github]将我们的项目源代码下载到您的终端中。 - 如果您想快速安装IvorySQL并且进行一些数据库体验,您可以参考如下: 笔者的OS版本如下 @@ -28,18 +26,19 @@ Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc v [highgo@ivorysql /]$ cd /home/highgo ---- -**使用git命令下载项目源代码** +**使用wget命令下载项目源代码** [source,] ---- -[highgo@ivorysql ~]$ git clone https://github.com/IvorySQL/IvorySQL.git +[highgo@ivorysql ~]$ wget https://github.com/IvorySQL/IvorySQL/archive/refs/tags/IvorySQL_1.17.tar.gz +[highgo@ivorysql ~]$ tar -zxvf IvorySQL_1.17.tar.gz ---- **进入下载好的项目目录中** [source,] ---- -[highgo@ivorysql ~]$ ls +[highgo@ivorysql ~]$ mv IvorySQL-IvorySQL_1.17 IvorySQL; ls IvorySQL [highgo@ivorysql ~]$ cd IvorySQL/ ---- @@ -115,7 +114,7 @@ image::p19.png[] [source,] ---- [highgo@ivorysql ~]$ psql -d postgres -psql (16devel) +psql (14.17) Type "help" for help. postgres=# @@ -138,7 +137,7 @@ undefined [root@localhost ~]# su - ivorysql Last login: Wed Feb 24 10:47:32 CST 2023 on pts/0 -bash-4.2$ psql -psql (14.2) +psql (14.17) Type "help" for help. ivorysql=# @@ -169,28 +168,21 @@ image::p2.png[] 安装包:rpm -下载YUM源:在Centos7上使用wget下载 +下载RPM包:在Centos7上使用wget下载 -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -安装源 -[source,] ----- -yum install ivorysql-release-1.0-2.noarch.rpm ----- - -安装库 +安装IvorySQL [source,] ---- -yum install -y ivorysql2-server +yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm ---- 初始化单机数据库 [source,] ---- -cd /usr/local/ivorysql/ivorysql-2/bin -./initdb -D ../data +/opt/IvorySQL-1.17/bin/initdb -D data/ ---- ===== 集群安装(一主一备) @@ -199,28 +191,23 @@ cd /usr/local/ivorysql/ivorysql-2/bin 安装包:rpm -下载YUM源:在Centos7上使用wget下载 +下载RPM包:在Centos7上使用wget下载 -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -安装源 +安装IvorySQL [source,] ---- -yum install ivorysql-release-1.0-2.noarch.rpm +yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm ---- -安装库 -[source,] ----- -yum install -y ivorysql2-server ----- **主节点** 初始化主节点 [source,] ---- -cd /usr/local/ivorysql/ivorysql-2/bin +/opt/IvorySQL-1.17/bin/initdb -D data/ ./initdb ../data-primary -U postgres ---- @@ -247,7 +234,7 @@ host replication all 0.0.0.0/0 trust 1、 基础备份 [source,shell] ---- -cd /usr/local/ivorysql/ivorysql-2/bin +cd /opt/IvorySQL-1.17/bin ./pg_basebackup -h 127.0.0.1 -p 5333 -U repl -W -Fp -Xs -Pv -R -D ../data-standby01 ---- @@ -270,29 +257,20 @@ vi ../data-standby01/postgresql.conf 安装包:rpm -下载YUM源:在Centos7上使用wget下载 +下载RPM包:在Centos7上使用wget下载 -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm - -安装源 +安装IvorySQL [source,] ---- -yum install ivorysql-release-1.0-2.noarch.rpm ----- - - -安装库 -[source,] ----- -yum install -y ivorysql2-server +yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm ---- 初始化主节点 [source,] ---- -cd /usr/local/ivorysql/ivorysql-2/bin -./initdb ../data-primary -U postgres +/opt/IvorySQL-1.17/bin/initdb -D data/ ---- 启动服务,创建用户 @@ -332,22 +310,18 @@ host replication all 0.0.0.0/0 trust 安装包:rpm -下载YUM源:在Centos7上使用wget下载 - -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm - -安装源 +下载RPM包:在Centos7上使用wget下载 - yum install ivorysql-release-1.0-2.noarch.rpm +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -安装库 +安装IvorySQL - yum install -y ivorysql2-server + yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm 1、 基础备份 [source,shell] ---- -cd /usr/local/ivorysql/ivorysql-2/bin +cd /opt/IvorySQL-1.17/bin ./pg_basebackup -h 192.168.xx.xx -p 5333 -U repl -W -Fp -Xs -Pv -R -D ../data-standby01 ---- diff --git a/CN/modules/ROOT/pages/v1.17/33.adoc b/CN/modules/ROOT/pages/v1.17/33.adoc new file mode 100644 index 0000000..194587e --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/33.adoc @@ -0,0 +1,27 @@ +:sectnums: +:sectnumlevels: 5 + + +[discrete] +== IvorySQL生态插件适配列表 + +IvorySQL 作为一款兼容 Oracle 且基于 PostgreSQL 的高级开源数据库,具备强大的扩展能力,支持丰富的生态系统插件。这些插件可以帮助用户在不同场景下增强数据库功能,包括地理信息处理、向量检索、全文搜索、数据定义提取和路径规划等。以下是当前 IvorySQL 官方兼容和支持的主要插件列表: + ++ + +[cols="2,1,3,3"] +|==== +|*插件名称*|*版本*|*功能描述*|*适用场景* +| xref:v1.17/9.adoc[PostGIS] | 3.4.0 | 为 IvorySQL 提供地理空间数据支持,包括空间索引、空间函数和地理对象存储 | 地理信息系统(GIS)、地图服务、位置数据分析 +| xref:v1.17/10.adoc[pgvector] | 0.8.0 | 支持向量相似性搜索,可用于存储和检索高维向量数据| AI 应用、图像检索、推荐系统、语义搜索 +| xref:v1.17/34.adoc[PGroonga] | 4.0.1 | 提供多语言全文搜索功能,支持超高速文本检索和模糊匹配 | 日志分析、多语言内容搜索、实时搜索引擎 +| xref:v1.17/35.adoc[pgddl (DDL Extractor)] | 0.20 | 提取数据库中的 DDL(数据定义语言)语句,便于版本管理和迁移 | 数据库版本控制、CI/CD 集成、结构比对与同步 +| xref:v1.17/36.adoc[pgRouting] | 3.5.1 | 基于地理数据的路径规划扩展,支持最短路径、旅行商问题等算法 | 物流规划、交通网络分析、路径优化服务 +| xref:v1.17/37.adoc[pg_cron]​ | 1.6.0 | 提供数据库内部的定时任务调度功能,支持定期执行SQL语句 | 数据清理、定期统计、自动化维护任务 +| xref:v1.17/38.adoc[pgsql-http]​ | 1.7.0 | 允许在SQL中发起HTTP请求,与外部Web服务进行交互 | 数据采集、API集成、微服务调用 +| xref:v1.17/40.adoc[pgvectorscale] | 0.8.0 | 提供向量数据的分片和分布式扩展支持,提升大规模向量处理性能 | 分布式向量数据库、高并发向量查询 +|==== + +这些插件均经过 IvorySQL 团队的测试和适配,确保在 IvorySQL 环境下稳定运行。用户可以根据业务需求选择合适的插件,进一步提升数据库系统的能力和灵活性。 + +我们也将持续扩展和丰富 IvorySQL 的插件生态,欢迎社区开发者提交新的插件适配建议或代码贡献。如需了解更多每个插件的详细使用方法和最新兼容版本,请参阅各插件对应的文档章节。 \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v1.17/34.adoc b/CN/modules/ROOT/pages/v1.17/34.adoc new file mode 100644 index 0000000..4142902 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/34.adoc @@ -0,0 +1,111 @@ + +:sectnums: +:sectnumlevels: 5 + += PGroonga + +== 概述 +PostgreSQL 内置了全文搜索功能,但在处理​​大规模数据​​、​​复杂查询​​以及​​非英语语言(特别是中日韩等 CJK 语言)​​ 时,其功能和性能可能无法满足高性能应用的需求。 + +PGroonga 应运而生,它是一个 PostgreSQL 的扩展插件,将 ​​Groonga​​ 这款高性能的全功能全文搜索引擎与 PostgreSQL 数据库深度融合。Groonga 本身是一个优秀的开源搜索引擎,以其极致的速度和丰富的功能著称,尤其擅长处理多语言文本。PGroonga 的使命就是将 Groonga 的强大能力无缝地带入 PostgreSQL 的世界,为用户提供远超原生全文搜索的体验。 + +== 安装 +根据开发环境,用户可从 https://pgroonga.github.io/install[PGroonga安装] 页面选择适合自己的方式进行PGroonga安装。 +IvorySQL的安装包里已经集成了PGroonga插件,如果使用安装包安装的IvorySQL,通常不需要再手动安装PGroonga即可使用。 + +=== 源码安装 +除PGroonga社区提供的安装方式以外,IvorySQL社区也提供了源码安装方式,源码安装环境为 Ubuntu 24.04(x86_64)。 + +[TIP] +环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +==== 安装 groonga + +** 安装依赖 kytea +[literal] +---- +git clone https://github.com/neubig/kytea.git +autoreconf -i +./configure +make +sudo make install +---- + +** 安装依赖 libzmq +[literal] +---- +从https://github.com/zeromq/libzmq/releases/tag/v4.3.5 下载zeromq-4.3.5.tar.gz +tar xvf zeromq-4.3.5.tar.gz +cd zeromq-4.3.5/ +./configure +make +sudo make install +---- + +** 下载 groonga包,安装指定依赖 +[literal] +---- +wget https://packages.groonga.org/source/groonga/groonga-latest.tar.gz +tar xvf groonga-15.1.5.tar.gz +cd groonga-15.1.5 +#运行这个脚本安装依赖,支持apt和dnf包管理工具 +./ setup.sh +---- + +** 编译安装 +[literal] +---- +# -S 指定groonga源码目录, -B 指定build目录,这个目录是个源码目录之外的一个只用于build的目录 +cmake -S /home/ivorysql/groonga-15.1.5 -B /home/ivorysql/groonga_build --preset=release-maximum +cmake --build /home/ivorysql/groonga_build +sudo cmake --install /home/ivorysql/groonga_build +# 更新动态链接库缓存 +sudo ldconfig +---- + +** 验证 groonga安装成功 +[literal] +---- +$ groonga --version +Groonga 15.1.5 [Linux,x86_64,utf8,match-escalation-threshold=0,nfkc,mecab,message-pack,mruby,onigmo,zlib,lz4,zstandard,epoll,apache-arrow,xxhash,blosc,bfloat16,h3,simdjson,llama.cpp] +---- + +==== 安装 pgroonga +[literal] +---- +wget https://packages.groonga.org/source/pgroonga/pgroonga-4.0.1.tar.gz +tar xvf pgroonga-4.0.1.tar.gz +cd pgroonga-4.0.1 +---- + +编译PGroonga,有个选项:HAVE_MSGPACK=1,它是用于支持WAL,使用这个选项需要安装msgpack-c 1.4.1或者更高版本。在基于Debian的平台使用libmsgpack-dev包,在CentOS 7上用msgpack-devel +[literal] +---- +#安装依赖 +sudo apt install libmsgpack-dev +---- + +运行make前确保pg_config命令的路径在PATH环境变量里 +[literal] +---- +make HAVE_MSGPACK=1 +make install +---- + +== 创建Extension并确认PGroonga版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE extension pgroonga; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pgroonga'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+------------------------------------------------------------------------------- + pgroonga| 4.0.1 | 4.0.1 | Super fast and all languages supported full text search index based on Groonga +(1 row) +---- + +== 使用 +关于PGroonga的使用,请参阅 https://pgroonga.github.io/tutorial[PGroonga官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v1.17/35.adoc b/CN/modules/ROOT/pages/v1.17/35.adoc new file mode 100644 index 0000000..f0131ab --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/35.adoc @@ -0,0 +1,47 @@ + +:sectnums: +:sectnumlevels: 5 + += pgddl (DDL Extractor) + +== 概述 +pgddl 是一个专为 PostgreSQL 数据库设计的 SQL 函数扩展,它能够直接从数据库系统目录中生成清晰、格式化的 SQL DDL (数据定义语言) 脚本,例如 CREATE TABLE 或 ALTER FUNCTION。它解决了 PostgreSQL 原生缺乏类似 SHOW CREATE TABLE 命令的问题,让用户无需借助外部工具(如 pg_dump)即可在纯 SQL 环境中轻松获取对象的创建语句。 + +该扩展通过一组简单的 SQL 函数提供了一套完整的解决方案,其优势包括:仅需使用 SQL 查询即可操作、支持通过 WHERE 子句灵活筛选对象、并能智能处理对象之间的依赖关系,生成包含 Drop 和 Create 步骤的完整脚本。这使得它特别适用于数据库变更管理、升级脚本编写和结构审计等场景。 + +需要注意的是,ddlx 仍在发展中,可能尚未覆盖所有 PostgreSQL 对象类型和高级选项。生成的脚本建议始终在非生产环境中先行检查和测试,以确保其正确性与安全性。 + +== 安装 +IvorySQL的安装包里已经集成了pgddl插件,如果使用安装包安装的IvorySQL,通常不需要再手动安装pgddl即可使用。其它安装方式可以参考下面的源码安装步骤。 + +[TIP] +源码安装环境为 Ubuntu 24.04(x86_64),环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +=== 源码安装 +从https://github.com/lacanoid/pgddl/releases/tag/0.20 下载pgddl-0.20.tar.gz,解压缩。 + +[literal] +---- +cd pgddl-0.20 +# 设置PG_CONFIG环境变量值为pg_config路径,eg:/usr/local/ivorysql/ivorysql-1/bin/pg_config +make PG_CONFIG=/path/to/pg_config +make PG_CONFIG=/path/to/pg_config install +---- + +== 创建Extension并确认ddlx版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE extension ddlx; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'ddlx'; + name | default_version | installed_version | comment +------+-----------------+-------------------+------------------------- + ddlx | 0.20 | 0.20 | DDL eXtractor functions +(1 row) +---- + +== 使用 +关于pgddl的使用,请参阅 https://github.com/lacanoid/pgddl[ddlx官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v1.17/36.adoc b/CN/modules/ROOT/pages/v1.17/36.adoc new file mode 100644 index 0000000..295f510 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/36.adoc @@ -0,0 +1,61 @@ + +:sectnums: +:sectnumlevels: 5 + += pgRouting + +== 概述 +pgRouting 是一个基于 PostgreSQL/PostGIS 数据库构建的开源地理空间路由扩展库。它为数据库赋予了强大的网络分析功能,使其能够处理复杂的路径规划与图论计算问题,例如计算两点之间的最短路径、执行旅行推销员(TSP)分析或计算服务区范围等。它将路由算法直接嵌入到数据库中,从而避免了在应用层进行复杂的数据传输与计算。 + +该扩展的核心优势在于能够利用 PostgreSQL 强大的数据管理能力和 PostGIS 丰富的空间函数,直接在数据库内部对空间网络数据执行高效计算。这不仅简化了应用程序的开发流程,还通过减少数据移动大幅提升了大规模网络分析的性能。 + +pgRouting 广泛应用于物流配送、交通导航、网络分析、城市规划及供应链管理等多个领域。其开源特性吸引了全球开发者持续的贡献与完善,使其成为空间数据库领域进行路径分析和网络求解的首选工具之一。 + +== 安装 +IvorySQL的安装包里已经集成了pgRouting插件,如果使用安装包安装的IvorySQL,通常不需要再手动安装pgRouting即可使用。其它安装方式可以参考下面的源码安装步骤。 + +[TIP] +源码安装环境为 Ubuntu 24.04(x86_64),环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +=== 源码安装 + +** 安装依赖 + +对perl有依赖,perl一般在装IvorySQL时已经装上了,这里不用再装。 +CMake版本要求 >= 3.12, Boost版本 >= 1.56 +[literal] +---- +#安装依赖 +sudo apt install cmake libboost-all-dev +---- + +** 编译安装 +[literal] +---- +wget https://github.com/pgRouting/pgrouting/releases/download/v3.5.1/pgrouting-3.5.1.tar.gz +tar xvf pgrouting-3.5.1.tar.gz +cd pgrouting-3.5.1 +mkdir build +cd build +cmake .. -DPOSTGRESQL_PG_CONFIG=/path/to/pg_config # eg: /usr/local/ivorysql/ivorysql-1/bin/pg_config +make +sudo make install +---- + +== 创建Extension并确认ddlx版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE extension pgrouting; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pgrouting'; + name | default_version | installed_version | comment +-----------+-----------------+-------------------+--------------------- + pgrouting | 3.5.1 | | pgRouting Extension +(1 row) +---- + +== 使用 +关于pgRouting的使用,请参阅 https://docs.pgrouting.org/[pgRouting官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v1.17/37.adoc b/CN/modules/ROOT/pages/v1.17/37.adoc new file mode 100644 index 0000000..b006569 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/37.adoc @@ -0,0 +1,114 @@ + +:sectnums: +:sectnumlevels: 5 +:imagesdir: ./_images + += pg_cron + +== 概述 +在 PostgreSQL 中运行周期性任务,例如执行 VACUUM或删除旧数据,是一种常见需求。实现这一点的简单方法是配置 cron或其他外部守护进程,使其定期连接到数据库并运行命令。然而,随着数据库越来越多地作为托管服务或独立容器运行,配置和运行一个单独的守护进程通常变得不切实际。此外,很难让您的 cron任务感知故障转移,或者跨集群节点调度任务。 + +pg_cron 是 PostgreSQL 的开源定时任务扩展,允许直接在数据库内部设置 cron 风格的任务调度,用于自动化数据维护任务(清理,聚合), 数据库健康检查,执行存储过程和自定义函数等操作。它将cron任务存储在表中,周期性任务会随着 PostgreSQL 服务器自动进行故障转移。详情可以参见 https://github.com/citusdata/pg_cron[pg_cron文档]。 + +== 安装配置 + +[TIP] +源码安装环境为 Ubuntu 24.04(x86_64),环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +=== 源码安装 + +[literal] +---- +# 拉取pg_cron源码 +git clone https://github.com/citusdata/pg_cron.git +cd pg_cron +# 将pg_config的路径设置到PATH环境变量里,eg: +export PATH=/usr/local/ivorysql/ivorysql-1/bin/:$PATH +make +make install +---- + +=== 配置文件 (ivorysql.conf) + +[literal] +---- +# 共享预加载扩展 +shared_preload_libraries = 'pg_cron' + +# 指定任务元数据存储库(默认当前库) +cron.database_name = 'ivorysql' + +# 允许的最大并发任务数 +cron.max_running_jobs = 5 +---- + +=== 重启服务 + +[literal] +---- +pg_ctl restart -D ./data -l logfile +---- + +=== 创建Extension并确认pg_cron版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE extension pg_cron; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pg_cron'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+--------------------------- + pg_cron | 1.6 | |Job scheduler for PostgreSQL +(1 row) +---- + +== 核心功能使用 + +=== 创建定时任务 + +``` +SELECT cron.schedule( + 'nightly-data-cleanup', -- 任务名称(唯一标识) + '0 3 * * *', -- cron表达式(每天UTC 3:00) + $$DELETE FROM logs + WHERE created_at < now() - interval '30 days'$$ -- 执行SQL +); +``` + +cron表达式速查表: + +|==== +|示例|含义 +|'0 * * * *'|每小时整点执行 +|'*/15 * * * *'|每15分钟执行 +|'0 9 * * 1-5'|工作日早9点执行 +|'0 1 1 * *'|每月1日凌晨1点执行 +|==== + +pg_cron还允许使用 '$'表示月份的最后一天。 + +=== 任务管理 + +``` +# 查看所有任务 +SELECT * FROM cron.job; +``` + +image::p31.png[] + +``` +# 查看任务执行历史 +SELECT * FROM cron.job_run_details ORDER BY start_time DESC LIMIT 10; +``` + +image::p32.png[] + +``` +# 删除任务 +SELECT cron.unschedule('nightly-data-cleanup'); + +# 暂停任务(更新状态) +UPDATE cron.job SET active = false WHERE jobname = 'delete-job-run-details'; +``` diff --git a/CN/modules/ROOT/pages/v1.17/38.adoc b/CN/modules/ROOT/pages/v1.17/38.adoc new file mode 100644 index 0000000..1f60ff7 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/38.adoc @@ -0,0 +1,59 @@ + +:sectnums: +:sectnumlevels: 5 + += pgsql-http + +== 概述 +pgsql-http 是一个为 PostgreSQL 数据库设计的开源扩展,它允许用户直接在数据库内部发起 HTTP 请求,扮演了一个内置 Web 客户端的角色。该扩展的核心目的是打通数据库与外部 Web 服务之间的壁垒,使得通过简单的 SQL 函数调用即可与外部 Web 服务、API 端点进行交互,无需依赖外部应用程序或中间件。 + +借助此扩展,开发者可以在 SQL 查询、触发器或存储过程中直接获取网络数据(GET)、提交数据(POST/PUT)、更新(PATCH)或删除(DELETE)远程资源。它提供了丰富的功能,包括设置请求头、自动处理 URL 编码、发送 JSON 数据以及解析响应状态、头部和内容,极大简化了将外部数据集成到数据库操作中的流程。 + +其典型应用场景包括:实时获取外部数据(如汇率、天气信息)并存入表;在数据变更时通过触发器自动通知微服务;对数据库中的数据进行清洗后直接提交至外部 API 等。它为构建以数据库为中心的集成应用提供了强大而灵活的解决方案。 + +== 安装 +IvorySQL的安装包里已经集成了pgsql-http插件,如果使用安装包安装的IvorySQL,通常不需要再手动安装pgsql-http即可使用。其它安装方式可以参考下面的源码安装步骤。 + +[TIP] +源码安装环境为 Ubuntu 24.04(x86_64),环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +=== 源码安装 + +** 安装依赖 + +对libcurl有依赖,libcurl的开发文件(例如 libcurl4-openssl-dev)需要提前安装上 +[literal] +---- +#安装依赖 +sudo apt install libcurl4-openssl-dev +---- + +** 编译安装 + +从https://github.com/pramsey/pgsql-http/releases/tag/v1.7.0 下载 1.7.0的源码包 pgsql-http-1.7.0.tar.gz +[literal] +---- +tar xvf pgsql-http-1.7.0.tar.gz +cd pgsql-http-1.7.0 +# 确保pg_config在PATH里可以访问,eg: /usr/local/ivorysql/ivorysql-1/bin/pg_config +make +sudo make install +---- + +== 创建Extension并确认http版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE extension http; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'http'; + name | default_version | installed_version | comment +-----------+-----------------+-------------------+------------------------------------------------------------------------- + http | 1.7 | 1.7 | HTTP client for PostgreSQL, allows web page retrieval inside the database. +(1 row) +---- + +== 使用 +关于pgsql-http的使用,请参阅 https://github.com/pramsey/pgsql-http[pgsql-http官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/4.adoc b/CN/modules/ROOT/pages/v1.17/4.adoc similarity index 99% rename from CN/modules/ROOT/pages/v3.0/4.adoc rename to CN/modules/ROOT/pages/v1.17/4.adoc index be0721b..3b86474 100644 --- a/CN/modules/ROOT/pages/v3.0/4.adoc +++ b/CN/modules/ROOT/pages/v1.17/4.adoc @@ -3,7 +3,7 @@ :sectnumlevels: 5 -= 管理员指南 += **日常监控** == 监控数据活动 diff --git a/CN/modules/ROOT/pages/v1.17/40.adoc b/CN/modules/ROOT/pages/v1.17/40.adoc new file mode 100644 index 0000000..0a10a19 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/40.adoc @@ -0,0 +1,69 @@ + +:sectnums: +:sectnumlevels: 5 + += pgvectorscale + +== 概述 +pgvectorscale 是 Timescale 公司推出的 PostgreSQL 扩展,旨在对流行的 pgvector 扩展进行高性能、高成本效益的补充。它专为 AI 应用中的大规模向量工作负载而设计,通过引入创新的索引算法和压缩技术,显著提升了向量相似性搜索的性能并降低了存储成本。 + +该扩展的核心特性包括基于微软 DiskANN 研究的新索引类型 StreamingDiskANN、改进的统计二进制量化(SBQ)压缩方法,以及支持标签过滤的向量搜索功能。在基准测试中,它在处理大规模嵌入向量时展现出卓越的性能:与专用向量数据库服务相比,可实现高达 28 倍的低延迟和 16 倍的查询吞吐量,同时节省约 75% 的成本。 + +pgvectorscale 完全兼容 pgvector 的数据类型和查询语法,确保了无缝的集成和迁移体验。它使用 Rust 语言和 PGRX 框架开发,非常适合需要在 PostgreSQL 内进行高效海量向量搜索的生产级应用。 + +== 安装 +IvorySQL的安装包里已经集成了pgvectorscale插件,如果使用安装包安装的IvorySQL,通常不需要再手动安装pgvectorscale即可使用。其它安装方式可以参考下面的源码安装步骤。 + +[TIP] +源码安装环境为 Ubuntu 24.04(x86_64),环境中已经安装了IvorySQL1.17及以上版本,安装路径为/usr/local/ivorysql/ivorysql-1 + +=== 源码安装 + +** 安装Rust工具链 + +[literal] +---- +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +---- + +** 下载pgvectorscale源码 + +从https://github.com/timescale/pgvectorscale/releases/tag/0.8.0 下载 0.8.0的源码包 pgvectorscale-0.8.0.tar.gz +[literal] +---- +tar xvf pgvectorscale-0.8.0.tar.gz +cd pgvectorscale-0.8.0/pgvectorscale +---- + +** 安装cargo-pgrx + +[literal] +---- +cargo install --locked cargo-pgrx --version $(cargo metadata --format-version 1 | jq -r '.packages[] | select(.name == "pgrx") | .version') +cargo pgrx init --pg14 pg_config +---- + +** 编译并安装扩展 + +[literal] +---- +cargo pgrx install --release +---- + +== 创建Extension并确认pgvectorscale版本 + +psql 连接到数据库,执行如下命令: +[literal] +---- +ivorysql=# CREATE EXTENSION IF NOT EXISTS vectorscale CASCADE; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'vectorscale'; + name | default_version | installed_version | comment +----------- +-----------------+-------------------+-------------------------------------------- + vectorscale | 0.8.0 | 0.8.0 | diskann access method for vector search. +(1 row) +---- + +== 使用 +关于pgvectorscale的使用,请参阅 https://github.com/timescale/pgvectorscale[pgvectorscale官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v1.17/41.adoc b/CN/modules/ROOT/pages/v1.17/41.adoc new file mode 100644 index 0000000..b707768 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/41.adoc @@ -0,0 +1,106 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 全局唯一索引 + +== 功能介绍 + +全局唯一索引(Global Unique Index)是 IvorySQL 针对分区表提供的跨分区唯一性约束能力。 + +标准 PostgreSQL 的唯一索引仅在单个分区内强制执行唯一性,无法保证跨分区的数据唯一。IvorySQL 引入 `GLOBAL` 关键字,在创建唯一索引时指定该关键字后,数据库在执行插入或更新操作时会扫描所有分区,确保整张分区表范围内不存在重复数据。 + +该功能同时支持 PG 兼容模式与 Oracle 兼容模式。 + +== 语法 + +[source,sql] +---- +CREATE UNIQUE INDEX [ index_name ] ON partitioned_table ( column [, ...] ) GLOBAL; +---- + +参数说明: + +- `UNIQUE`:必须与 `GLOBAL` 同时使用,指定唯一性约束; +- `GLOBAL`:启用跨分区唯一性检查,仅对分区表有效; +- `index_name`:可选,省略时数据库自动生成索引名。 + +== 测试用例 + +=== 创建分区表与全局唯一索引 + +[source,sql] +---- +-- 创建分区表 +CREATE TABLE gidxpart (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE gidxpart1 PARTITION OF gidxpart FOR VALUES FROM (1) TO (10); +CREATE TABLE gidxpart2 PARTITION OF gidxpart FOR VALUES FROM (10) TO (100); +CREATE TABLE gidxpart3 PARTITION OF gidxpart FOR VALUES FROM (100) TO (200); + +-- 在分区表上创建全局唯一索引(指定索引名) +CREATE UNIQUE INDEX gidx_u ON gidxpart USING btree(b) GLOBAL; + +-- 在分区表上创建全局唯一索引(不指定索引名) +CREATE UNIQUE INDEX ON gidxpart (b) GLOBAL; +---- + +=== 插入数据:跨分区唯一性验证 + +[source,sql] +---- +-- 以下插入成功(各分区间 b 列无重复) +INSERT INTO gidxpart VALUES (1, 1, 'first'); +INSERT INTO gidxpart VALUES (11, 11, 'eleventh'); +INSERT INTO gidxpart VALUES (2, 120, 'second'); +INSERT INTO gidxpart VALUES (12, 2, 'twelfth'); +INSERT INTO gidxpart VALUES (150, 13, 'no duplicate b'); + +-- 以下插入失败:b=11 已存在于其他分区,违反跨分区唯一性约束 +INSERT INTO gidxpart VALUES (2, 11, 'duplicated (b)=(11) on other partition'); +-- ERROR: duplicate key value violates unique constraint + +INSERT INTO gidxpart VALUES (12, 1, 'duplicated (b)=(1) on other partition'); +-- ERROR: duplicate key value violates unique constraint + +INSERT INTO gidxpart VALUES (150, 11, 'duplicated (b)=(11) on other partition'); +-- ERROR: duplicate key value violates unique constraint +---- + +=== 更新数据:跨分区唯一性验证 + +[source,sql] +---- +-- 更新操作同样受全局唯一索引约束 +UPDATE gidxpart SET b = 2 WHERE a = 2; +-- ERROR: duplicate key value violates unique constraint(b=2 已存在) + +UPDATE gidxpart SET b = 12 WHERE a = 12; +-- 成功(b=12 在全局范围内唯一) +---- + +=== 分区的 ATTACH 与 DETACH + +[source,sql] +---- +-- 创建一个独立的表,用于后续 ATTACH +CREATE TABLE gidxpart_new (a int, b int, c text); +INSERT INTO gidxpart_new VALUES (100001, 11, 'conflict with gidxpart1'); + +-- ATTACH 时若存在跨分区重复值,操作将失败 +ALTER TABLE gidxpart ATTACH PARTITION gidxpart_new + FOR VALUES FROM (100000) TO (199999); +-- ERROR: duplicate key value violates unique constraint + +-- DETACH 分区后,该分区的全局索引类型恢复为普通索引 +ALTER TABLE gidxpart DETACH PARTITION gidxpart2; +---- + +== 功能限制 + +. `GLOBAL` 关键字必须与 `UNIQUE` 配合使用,不支持创建全局非唯一索引; +. 全局唯一索引仅适用于**分区表**,普通表不支持该关键字; +. 每次插入或更新操作均需扫描所有分区以验证唯一性,在分区数量较多或数据量较大时存在**性能开销**; +. 通过 `ATTACH PARTITION` 挂载分区时,若新分区中存在与其他分区重复的数据,挂载操作将失败; +. 分区被 `DETACH` 后,其对应的全局索引自动降级为普通局部索引; +. 不支持在子分区(二级分区)上单独创建全局唯一索引,全局唯一性约束由顶层分区表统一管理。 diff --git a/CN/modules/ROOT/pages/v1.17/42.adoc b/CN/modules/ROOT/pages/v1.17/42.adoc new file mode 100644 index 0000000..b89488f --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/42.adoc @@ -0,0 +1,129 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 新增无主键表默认支持逻辑复制 + +== 功能介绍 + +在 PostgreSQL/IvorySQL 的逻辑复制中,UPDATE 和 DELETE 操作需要依赖复制标识(Replica Identity)来定位订阅端的目标行。默认情况下,表使用 `REPLICA IDENTITY DEFAULT`,此时系统依赖主键(Primary Key)来定位行。如果表没有主键,复制策略将回退为 `REPLICA IDENTITY NOTHING`,此时 UPDATE 和 DELETE 操作将因无法定位行而报错。 + +IvorySQL 新增了 GUC 参数 `logical_replication_fallback_to_full_identity`。当该参数开启后,如果表的复制标识为 `DEFAULT` 且没有主键,系统会自动将其回退为 `REPLICA IDENTITY FULL`——即在 WAL 中记录完整的旧行数据,使无主键表的 UPDATE 和 DELETE 操作能够通过逻辑复制正常执行。 + +该功能仅在发布端(Publisher)生效,订阅端无需任何额外配置。 + +== 参数说明 + +[source,sql] +---- +# postgresql.conf +logical_replication_fallback_to_full_identity = on +---- + +参数说明: + +- 类型:`boolean`; +- 默认值:`off`; +- 作用域:`sighup`,可通过修改 `postgresql.conf` 后执行 `SELECT pg_reload_conf();` 使配置生效,无需重启数据库; +- 适用节点:仅在发布端(Publisher)生效,订阅端无需配置。 + +== 测试用例 + +=== 未开启参数时,无主键表的 UPDATE 和 DELETE 复制失败 + +[source,sql] +---- +-- 发布端:创建无主键表 +CREATE TABLE test_no_pk (id int, name text); + +-- 订阅端:创建相同的表结构 +CREATE TABLE test_no_pk (id int, name text); + +-- 发布端:创建发布并添加表 +CREATE PUBLICATION tap_pub FOR TABLE test_no_pk; + +-- 订阅端:创建订阅 +CREATE SUBSCRIPTION tap_sub CONNECTION 'host=publisher dbname=postgres' PUBLICATION tap_pub; + +-- 发布端:INSERT 操作始终正常(不依赖复制标识) +INSERT INTO test_no_pk VALUES (1, 'alice'); + +-- 发布端:UPDATE 操作失败(无主键,无法定位目标行) +UPDATE test_no_pk SET name = 'bob' WHERE id = 1; +-- ERROR: cannot update table "test_no_pk" because it does not have a replica identity and publishes updates + +-- 发布端:DELETE 操作同样失败 +DELETE FROM test_no_pk WHERE id = 1; +-- ERROR: cannot delete from table "test_no_pk" because it does not have a replica identity and publishes deletes +---- + +=== 开启参数后,无主键表的 UPDATE 和 DELETE 复制正常 + +[source,sql] +---- +-- 发布端:开启参数并重新加载配置 +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = on; +SELECT pg_reload_conf(); + +-- 发布端:INSERT 正常 +INSERT INTO test_no_pk VALUES (1, 'alice'); + +-- 发布端:UPDATE 正常(自动按 FULL 方式记录完整旧行数据) +UPDATE test_no_pk SET name = 'bob' WHERE id = 1; + +-- 发布端:DELETE 正常 +DELETE FROM test_no_pk WHERE id = 1; +---- + +=== 参数不影响有主键的表 + +[source,sql] +---- +-- 有主键的表始终使用主键定位行,不受该参数影响 +CREATE TABLE test_with_pk (id int PRIMARY KEY, name text); + +-- 无论参数是否开启,UPDATE 和 DELETE 均正常工作 +INSERT INTO test_with_pk VALUES (1, 'alice'); +UPDATE test_with_pk SET name = 'bob' WHERE id = 1; +DELETE FROM test_with_pk WHERE id = 1; +---- + +=== 参数不影响显式设置为 REPLICA IDENTITY NOTHING 的表 + +[source,sql] +---- +-- 创建表并显式设置为 REPLICA IDENTITY NOTHING +CREATE TABLE test_nothing (id int, data text); +ALTER TABLE test_nothing REPLICA IDENTITY NOTHING; + +-- 即使开启了 logical_replication_fallback_to_full_identity, +-- UPDATE 和 DELETE 仍然失败(参数不会覆盖显式的 NOTHING 设置) +INSERT INTO test_nothing VALUES (1, 'test'); +UPDATE test_nothing SET data = 'modified' WHERE id = 1; +-- ERROR: cannot update table "test_nothing" because it does not have a replica identity and publishes updates + +DELETE FROM test_nothing WHERE id = 1; +-- ERROR: cannot delete from table "test_nothing" because it does not have a replica identity and publishes deletes +---- + +=== 运行时动态切换参数 + +[source,sql] +---- +-- 关闭参数:无主键表的 UPDATE/DELETE 将恢复为报错行为 +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = off; +SELECT pg_reload_conf(); + +-- 开启参数:无主键表的 UPDATE/DELETE 将正常工作 +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = on; +SELECT pg_reload_conf(); +---- + +== 功能限制 + +. 该参数仅对复制标识为 `REPLICA IDENTITY DEFAULT` 且没有主键的表生效;已显式设置为 `FULL`、`USING INDEX` 或 `NOTHING` 的表不受影响; +. 开启该参数后,无主键表的 UPDATE 和 DELETE 会在 WAL 中记录完整的旧行数据(与 `REPLICA IDENTITY FULL` 效果相同),相比有主键时只记录主键列,会增加 WAL 体积和网络传输量; +. 该参数仅在发布端生效,订阅端无需配置; +. INSERT 操作不依赖复制标识,无论该参数是否开启均可正常复制; +. 该参数不替代显式的 `ALTER TABLE ... REPLICA IDENTITY FULL` 设置,也不会覆盖显式设置为 `NOTHING` 的表。 diff --git a/CN/modules/ROOT/pages/v1.17/43.adoc b/CN/modules/ROOT/pages/v1.17/43.adoc new file mode 100644 index 0000000..dfdb6e6 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/43.adoc @@ -0,0 +1,170 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += 修改列类型时自动重建依赖视图 + +== 功能介绍 + +在标准 PostgreSQL 中,若某列被视图所引用,执行 `ALTER TABLE ... ALTER COLUMN ... TYPE` 修改该列的数据类型时,数据库会直接报错: + +---- +ERROR: cannot alter type of a column used by a view or rule +---- + +用户必须手动删除所有依赖视图,完成列类型修改后再逐一重建,操作繁琐且容易出错,在存在多层视图依赖时尤为困难。 + +IvorySQL 对此行为进行了增强:执行列类型变更时,数据库会自动保存所有依赖视图(包括间接依赖的级联视图)的定义,在完成类型修改后按正确顺序重建这些视图 +,对用户完全透明。若重建过程中发生错误(例如视图使用了新类型不支持的操作符),整个 `ALTER TABLE` 操作将整体回滚,保证数据一致性。 + +该功能同时支持 PG 兼容模式与 Oracle 兼容模式。 + +== 语法 + +语法与标准 `ALTER TABLE` 完全一致,无需额外关键字: + +[source,sql] +---- +ALTER TABLE table_name ALTER COLUMN column_name TYPE new_type; +---- + +参数说明: + +- `table_name`:目标表名,可带 schema 前缀; +- `column_name`:需要修改类型的列名; +- `new_type`:目标数据类型,需与原类型兼容或可隐式转换。 + +== 测试用例 + +=== 单视图依赖:自动重建 + +[source,sql] +---- +-- 创建基表 +CREATE TABLE t (a int, b text); + +-- 创建依赖列 a 的视图 +CREATE VIEW v AS SELECT a, b FROM t; + +-- 标准 PostgreSQL 此处会报错,IvorySQL 自动重建视图 +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- 验证视图仍然有效,且列类型已更新 +SELECT pg_typeof(a) FROM v LIMIT 1; +-- 返回 bigint + pg_typeof +----------- +(0 rows) + + +\d v + View "public.v" + Column | Type | Collation | Nullable | Default +--------+--------+-----------+----------+--------- + a | bigint | | | + b | text | | | +---- + +=== 级联视图依赖:按序自动重建 + +[source,sql] +---- +-- 创建基表 +CREATE TABLE t (a int, b text); + +-- 创建两层视图依赖:v2 依赖 v1,v1 依赖 t +CREATE VIEW v1 AS SELECT a, b FROM t; +CREATE VIEW v2 AS SELECT a FROM v1; + +-- 修改列类型,自动按依赖顺序重建 v1、v2 +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- 验证两个视图均已正确重建 +SELECT pg_typeof(a) FROM v1 LIMIT 1; +-- 返回 bigint + pg_typeof +----------- +(0 rows) + +SELECT pg_typeof(a) FROM v2 LIMIT 1; +-- 返回 bigint + pg_typeof +----------- +(0 rows) +---- + +=== 保留视图选项:security_barrier + +[source,sql] +---- +-- 创建带 security_barrier 选项的视图 +CREATE VIEW v WITH (security_barrier) AS SELECT a, b FROM t; + +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- 验证 security_barrier 选项在重建后被正确保留 +SELECT relname, reloptions FROM pg_class WHERE relname = 'v'; +-- reloptions: {security_barrier=true} + relname | reloptions +---------+------------------------- + v | {security_barrier=true} +(1 row) +---- + +=== 保留视图选项:WITH CHECK OPTION + +[source,sql] +---- +-- 创建带 WITH LOCAL CHECK OPTION 的视图 +CREATE VIEW v AS SELECT a, b FROM t WHERE a > 0 + WITH LOCAL CHECK OPTION; + +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- 验证 CHECK OPTION 在重建后被正确保留 +\d+ v + View "public.v" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+--------+-----------+----------+---------+----------+------------- + a | bigint | | | | plain | + b | text | | | | extended | +View definition: + SELECT t.a, + t.b + FROM t + WHERE t.a > 0; +Options: check_option=local +---- + +=== 重建失败时整体回滚 + +[source,sql] +---- +CREATE TABLE t (a int, b text); +CREATE VIEW v AS SELECT a::integer + 1 AS a_plus FROM t; + +-- 若新类型与视图中的表达式不兼容,整个操作回滚 +-- 例如将 a 改为 text 类型,视图中的 a::integer + 1 将无法执行 +ALTER TABLE t ALTER COLUMN a TYPE text; +ERROR: operator does not exist: text + integer +LINE 1: ALTER TABLE t ALTER COLUMN a TYPE text; + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. + +-- 确认表结构与视图均未受影响 +\d t + Table "public.t" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | text | | | +---- + +== 功能限制 + +. 若视图中使用了与新列类型不兼容的操作符或函数(例如对 `text` 类型列执行算术运算),重建将失败,整个 `ALTER TABLE` 操作回滚; +. 仅支持视图(view)的自动重建,依赖该列的**规则(rule)**仍会报错; +. 列类型变更需满足 PostgreSQL 类型转换规则,不支持任意两种类型之间的直接转换; +. 视图重建按依赖拓扑顺序执行,循环依赖(通常由数据库约束避免)不在处理范围内; +. 重建过程在同一事务内完成,期间依赖视图处于不可用状态,高并发场景下需注意对查询的影响。 diff --git a/CN/modules/ROOT/pages/v3.0/5.adoc b/CN/modules/ROOT/pages/v1.17/5.adoc similarity index 99% rename from CN/modules/ROOT/pages/v3.0/5.adoc rename to CN/modules/ROOT/pages/v1.17/5.adoc index b50ea7b..601ee64 100644 --- a/CN/modules/ROOT/pages/v3.0/5.adoc +++ b/CN/modules/ROOT/pages/v1.17/5.adoc @@ -3,7 +3,7 @@ :sectnumlevels: 5 -= 运维人员指南 += **日常维护** == 日常清理 diff --git a/CN/modules/ROOT/pages/v1.17/6.adoc b/CN/modules/ROOT/pages/v1.17/6.adoc new file mode 100644 index 0000000..b17f319 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/6.adoc @@ -0,0 +1,539 @@ + +:sectnums: +:sectnumlevels: 5 + + += **安装指南** + +== CentOS安装概述 + +本文介绍 IvorySQL 在Linux平台(以CentOS 7为例)的安装过程及注意事项。本文主要演示数据库在Centos 7环境下rpm包安装步骤、源码安装步骤。 + +=== 软硬件要求 + +==== 软件资源介绍 + +|==== +|操作系统|RPM包下载地址 +|CentOS 7|https://github.com/IvorySQL/IvorySQL/releases +|==== + + +==== 硬件资源准备 +|==== +|**配置参数**|**最低配置**|**推荐配置** +|**CPU**|4核|16核 +|**内存**|4GB|64GB +|**存储**|800MB,机械硬盘|5GB以上,SSD或NvMe +|**网络**|千兆网络|万兆网络 +|==== + +=== 环境和配置检查 + +部署 IvorySQL 数据库前,您需要进行系统环境和配置检查 + +==== 查看资源 + +IvorySQL 数据库支持CentOS 7.X操作系统。详细信息,参考<<#_软硬件要求>> + + +==== 查看操作系统 + +**CentOS 7.X** + +运行以下命令,查看操作系统信息: + + cat /etc/redhat-release + +==== 查看内核参数 + + uname -r + +==== 查看内存,清理缓存 +---- + free -g + + echo 3 > /proc/sys/vm/drop_caches +---- + +=== 获取安装包 + +您可以通过 源码安装 IvorySQL 数据库或 RPM 包安装。 + +==== 使用源码构建IvorySQL数据库 + +1.获取源代码:运行以下命令,克隆 IvorySQL 数据库源代码到您的构建机器: +---- +git clone https://github.com/IvorySQL/IvorySQL.git +---- + +> 注意:克隆代码需要先安装配置 Git。详细信息,参考 https://git-scm.com/doc[Git 文档] + + +2.安装依赖包:要从源代码编译 IvorySQL,必须确保系统上有可用的先决条件包。 执行以下命令安装相关包: +---- +sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget +sudo yum groupinstall -y 'Development Tools' +---- + +> 说明:“Development Tools” 包含了gcc,make,flex,bison。 + +3.自行编译安装:前面通过获取的源码在文件夹IvorySQL里,接下来我们就进入这个文件夹进行操作。 + +3.1 配置:Root用户执行以下命令进行配置: +---- +git checkout tags/Ivory_REL_1_17 +./configure --prefix=/usr/local/ivorysql/ivorysql-1.17 +---- +> 说明: 如果没有提供 `--prefix`,默认将安装在 `/usr/local/ivorysql`。 +> +> 注意:我们要记住指定的目录,因为系统查不出已经编译安装的程序在哪。更多 configure 参数通过 `./configure --help` 查看。还可以查看 PostgreSQL 手册。 + +3.2 编译安装:配置完成后,执行 make 进行编译: + + make + +要在安装新编译的服务之前使用回归测试测试一下,以下命令均可: + +---- +make check +make all-check-world +---- + +然后安装: + + sudo make install + + +==== 使用 RPM 包安装 IvorySql 数据库 + +1. 运行以下命令,下载 IvorySQL 安装包。 +---- +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm +---- + +> 注意:示例中的安装包可能不是最新版本,建议您下载最新的安装包。 + +2.运行以下命令,安装 IvorySQL 。 +---- +-- 先安装依赖 +yum install -y libicu libxslt python3 +rpm -ivh IvorySQL-1.17-fde5539-20250326.x86_64.rpm +---- + +=== 初始化数据库服务 + +==== 初始化数据库 + +1. 创建操作系统用户:用户root会话下,新建用户 ivorysql: +---- +/usr/sbin/groupadd ivorysql +/usr/sbin/useradd -g ivorysql ivorysql -c "IvorySQL1.17" +passwd ivorysql +---- + + +2.环境变量:切换到用户ivorysql,修改文件 `/home/ivorysql/.bash_profile`,配置环境变量: +---- +umask 022 +export LD_LIBRARY_PATH=/opt/IvorySQL-1.17/lib:$LD_LIBRARY_PATH +export PATH=/opt/IvorySQL-1.17/bin:$PATH +export PGDATA=/home/ivorysql/data +---- + +使环境变量在当前ivorysql用户会话中生效: + + source .bash_profile + +也可以重新登录或开启一个新的用户ivorysql的会话。 + +3.设置防火墙:如果开启了防火墙,还需要将端口1521或者5432开放: +---- +firewall-cmd --zone=public --add-port=1521/tcp --permanent +firewall-cmd --reload +---- + +> 说明:默认端口是1521,如果不开放该端口,外部客户端通过ip连接会失败。 + +4.初始化:在用户ivorysql下,简单执行initdb就可以完成初始化: + + initdb + + +> 说明:initdb操作与PostgreSQL一样,可以按照PG的习惯去初始化。 + +5.启动数据库:使用pg_ctl启动数据库服务: + + pg_ctl start + +查看状态,启动成功: + + pg_ctl status + +=== 配置服务 + +1. 客户端验证:修改 /home/ivorysql/data/pg_hba.conf,追加以下内容: + + host all all 0.0.0.0/0 trust + + +> 注意:trust,设置免密登录。 + +执行以下命令加载配置: + + pg_ctl reload + +2.基本参数 + +通过psql连接数据库: + + psql + +修改监听地址 + + alter system set listen_address = '*'; + +> 说明:默认是监听在127.0.0.1,主机外是连不上服务的。 + +3.守护服务 + +创建service文件: + + touch /usr/lib/systemd/system/ivorysql.service + +编辑内容如下: +---- +[Unit] +Description=IvorySQL 1.17 database server +Documentation=https://www.ivorysql.org +Requires=network.target local-fs.target +After=network.target local-fs.target + +[Service] +Type=forking + +User=ivorysql +Group=ivorysql + +Environment=PGDATA=/home/ivorysql/data + +OOMScoreAdjust=-1000 + +ExecStart=/opt/IvorySQL-1.17/bin/pg_ctl start -D ${PGDATA} +ExecStop=/opt/IvorySQL-1.17/bin/pg_ctl stop -D ${PGDATA} +ExecReload=/opt/IvorySQL-1.17/bin/pg_ctl reload -D ${PGDATA} + +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target + +---- + +> 说明:service的写法有很多,在生产环境使用时需谨慎,请多次重复测试。 + +停止pg_ctl启动的数据库服务,启用systemd服务并启动: + + systemctl enable --now ivorysql.service + +IvorSQL数据库服务操作命令: +---- +systemctl start ivorysql.service --启动数据库服务 +systemctl stop ivorysql.service --停止数据库服务 +systemctl restart ivorysql.service --重启数据库 +systemctl status ivorysql.service --查看数据库状态 +systemctl reload ivorysql.service --可以满足部分数据库配置修改完后生效 +---- + +=== 卸载 IvorySQL 数据库 + +==== 编译卸载 + +1.备份数据:我们需要将数据目录保护好,最好停止数据库服务后做备份。 + +``` +systemctl stop ivorysql.service +``` + +2.编译卸载:root会话下切到源码目录下,分别执行以下命令: + +``` +make uninstall +make clean +``` + +3.删除残余目录和文件: + +``` +systemctl disable ivorysql.servicemake --禁用服务 +mv /usr/lib/systemd/system/ivorysql.service /tmp/ --服务文件移到/tmp,删除也可以 +rm -fr /opt/IvorySQL-1.17 --删除残留安装目录 +``` + +> 说明:还有用户ivorysql以及对应的环境变量,可以根据情况是否清理。剩下的就是数据目录了,请务必做好备份再做处理。还有安装的依赖包,可根据情况决定是否卸载。 + +== Ubuntu安装概述 + +本文介绍 IvorySQL 在Linux平台Ubuntu(以Ubuntu2404为例)的安装过程及注意事项。演示数据库在Ubuntu 2404环境下deb包安装步骤、源码安装步骤。 + +=== 软硬件要求 + +==== 软件资源介绍 + +|==== +|操作系统|DEB包下载地址 +|Ubuntu 2404|https://github.com/IvorySQL/IvorySQL/releases +|==== + + +==== 硬件资源准备 +|==== +|**配置参数**|**最低配置**|**推荐配置** +|**CPU**|4核|16核 +|**内存**|4GB|64GB +|**存储**|800MB,机械硬盘|5GB以上,SSD或NvMe +|**网络**|千兆网络|万兆网络 +|==== + +=== 环境和配置检查 + +部署 IvorySQL 数据库前,您需要进行系统环境和配置检查 + +==== 查看资源 + +IvorySQL 数据库支持Ubuntu24.x操作系统。详细信息,参考<<#_软硬件要求>> + + +==== 查看操作系统 + +**Ubuntu 24/22.0x** + +运行以下命令,查看操作系统信息: + + cat /etc/os-release + +==== 查看内核参数 + + uname -r + +=== 获取安装包 + +您可以通过源码安装IvorySQL数据库或DEB包安装。 + +==== 使用源码构建IvorySQL数据库 + +1.获取源代码:运行以下命令,克隆 IvorySQL 数据库源代码到您的构建机器: +---- +git clone https://github.com/IvorySQL/IvorySQL.git +---- + +> 注意:克隆代码需要先安装配置 Git。详细信息,参考 https://git-scm.com/doc[Git 文档] + + +2.安装依赖包:要从源代码编译 IvorySQL,必须确保系统上有可用的先决条件包。 执行以下命令安装相关包: +---- +sudo apt install -y bison-devel readline-devel zlib-devel openssl-devel wget +sudo apt install -y gcc make flex bison +---- + +3.自行编译安装:前面通过获取的源码在文件夹IvorySQL里,接下来我们就进入这个文件夹进行操作。 + +3.1 配置:Root用户执行以下命令进行配置: +---- +git checkout tags/Ivory_REL_1_17 +./configure --prefix=/usr/local/ivorysql/ivorysql-1.17 + +---- +> 说明: 如果没有提供 `--prefix`,默认将安装在 `/usr/local/ivorysql`。 +> +> 注意:我们要记住指定的目录,因为系统查不出已经编译安装的程序在哪。更多 configure 参数通过 `./configure --help` 查看。还可以查看 PostgreSQL 手册。 + +3.2 编译安装:配置完成后,执行 make 进行编译: + + make + +在安装新编译的服务之前,建议先进行回归测试以确保稳定性,可以使用以下任意命令执行测试: + +---- +make check +make all-check-world +---- + +然后安装: + + sudo make install + + +==== 使用 DEB 包安装 IvorySQL 数据库 + +1. 运行以下命令,下载 IvorySQL 安装包。 +---- +wget https://github.com/IvorySQL/IvorySQL/releases/download/IvorySQL_1.17/IvorySQL-1.17-fde5539-20250326.amd64.deb +---- + +> 注意:示例中的安装包可能不是最新版本,建议您下载最新的安装包。 + +2.运行以下命令,安装 IvorySQL 。 +---- +sudo apt install ./IvorySQL-1.17-fde5539-20250326.amd64.deb +---- + +=== 初始化数据库服务 + +==== 初始化数据库 + +1. 创建操作系统用户:用户root会话下,新建用户 ivorysql: +---- +/usr/sbin/groupadd ivorysql +/usr/sbin/useradd -m -g ivorysql -s /bin/bash -c "IvorySQL1.17" ivorysql +usermod -a -G sudo ivorysql +passwd ivorysql + +mkdir /home/ivorysql +chown -R ivorysql:ivorysql /home/ivorysql +chmod 755 /home/ivorysql +---- + + +2.环境变量:切换到用户ivorysql,修改文件 `/home/ivorysql/.bashrc`,配置环境变量: +---- +umask 022 +export LD_LIBRARY_PATH=/opt/IvorySQL-1.17/lib:$LD_LIBRARY_PATH +export PATH=/opt/IvorySQL-1.17/bin:/usr/local/ivorysql/ivorysql-1.17/bin:$PATH #取决于安装路径 +export PGDATA=/home/ivorysql/data +---- + +使环境变量在当前ivorysql用户会话中生效: + + source .bashrc + +也可以重新登录或开启一个新的用户ivorysql的会话。 + +3.设置防火墙:如果开启了防火墙,还需要将端口1521或者5432开放: +---- +firewall-cmd --zone=public --add-port=1521/tcp --permanent +firewall-cmd --reload +---- + +> 说明:默认端口是1521,外部客户端若想通过此端口连接需开放该端口。 + +4.初始化:在用户ivorysql下,简单执行initdb就可以完成初始化: + + initdb -D $PGDATA + + +> 说明:initdb操作与PostgreSQL一样,可以按照PG的习惯去初始化。 + +5.启动数据库:使用pg_ctl启动数据库服务: + + pg_ctl -D $PGDATA -l logfile start + +查看状态: + + pg_ctl -D $PGDATA status + +启动成功会有如下输出: + + pg_ctl: server is running (PID: 2273) + +=== 配置服务 + +1. 客户端验证:修改 $PGDATA/pg_hba.conf,追加以下内容: + + host all all 0.0.0.0/0 trust + + +> 注意:trust,设置免密登录。 + +监听地址:修改$PGDATA/postgresql.conf ,追加以下内容: + + listen_addresses = '*' + +> 说明:默认是监听在127.0.0.1,主机外是连不上服务的。 + +执行以下命令加载配置: + + pg_ctl reload + +2.连接数据库 + +通过psql连接数据库: + + psql + +3.守护服务 + +创建service文件: + + sudo vi /etc/systemd/system/ivorysql.service + +编辑内容如下: +---- +[Unit] +Description=IvorySQL 1.17 database server +Documentation=https://www.ivorysql.org +Requires=network.target local-fs.target +After=network.target local-fs.target + +[Service] +Type=forking + +User=ivorysql +Group=ivorysql + +Environment=PGDATA=/home/ivorysql/data + +OOMScoreAdjust=-1000 + +ExecStart=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl start -D ${PGDATA} +ExecStop=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl stop -D ${PGDATA} +ExecReload=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl reload -D ${PGDATA} + +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target + +---- + +> 说明:service的写法有很多,在生产环境使用时需谨慎,请多次重复测试。 + +停止pg_ctl启动的数据库服务,启用systemd服务并启动: + + systemctl enable --now ivorysql.service + +IvorSQL数据库服务操作命令: +---- +systemctl start ivorysql.service --启动数据库服务 +systemctl stop ivorysql.service --停止数据库服务 +systemctl restart ivorysql.service --重启数据库 +systemctl status ivorysql.service --查看数据库状态 +systemctl reload ivorysql.service --可以满足部分数据库配置修改完后生效 +---- + +=== 卸载 IvorySQL 数据库 + +==== 编译卸载 + +1.备份数据:我们需要将数据目录保护好,最好停止数据库服务后做备份。 + +``` +systemctl stop ivorysql.service +``` + +2.编译卸载:root会话下切到源码目录下,分别执行以下命令: + +``` +make uninstall +make clean +``` + +3.删除残余目录和文件: + +``` +systemctl disable ivorysql.service --禁用服务 +mv /usr/lib/systemd/system/ivorysql.service /tmp/ --服务文件移到/tmp +rm -fr /usr/local/ivorysql/ivorysql-1.17 --删除残留安装目录 +``` + +> 说明:还有用户ivorysql以及对应的环境变量,可以根据情况是否清理。剩下的就是数据目录了,请务必做好备份再做处理。还有安装的依赖包,可根据情况决定是否卸载。 \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/7.adoc b/CN/modules/ROOT/pages/v1.17/7.adoc similarity index 62% rename from CN/modules/ROOT/pages/v3.0/7.adoc rename to CN/modules/ROOT/pages/v1.17/7.adoc index b57fff6..90b9d09 100644 --- a/CN/modules/ROOT/pages/v3.0/7.adoc +++ b/CN/modules/ROOT/pages/v1.17/7.adoc @@ -16,7 +16,7 @@ IvorySQL提供的扩展功能将使用户能够建立高性能和可扩展的Pos ### 架构概述 -为了对原有的 PostgreSQL 改动最小的前提下,实现对 Oracle 兼容。我们需要实现双 parser、双端口、模式 PL/pgSQL 实现 PL/iSQL 的框架。实现流程图如下: +在对原有的PostgreSQL改动最小的前提下,实现对Oracle的兼容。我们需要实现双parser、双端口、模式PL/pgSQL实现PL/iSQL的框架。实现流程图如下: image::p4.png[] image::p5.png[] @@ -31,9 +31,9 @@ image::p6.png[] === 创建一个数据库 -看看你能否访问数据库服务器的第一个例子就是试着创建一个数据库。 一台运行着的IvorySQL服务器可以管理许多数据库。 通常我们会为每个项目和每个用户单独使用一个数据库。 +看看你能否访问数据库服务器的第一个例子就是试着创建一个数据库。一台运行着的IvorySQL服务器可以管理许多数据库。通常我们会为每个项目和每个用户单独使用一个数据库。 -你的站点管理员可能已经为你创建了可以使用的数据库。 如果这样你就可以省略这一步, 并且跳到下一节。 +你的站点管理员可能已经为你创建了可以使用的数据库。如果这样你就可以省略这一步,并且跳到下一节。 要创建一个新的数据库,在我们这个例子里叫`mydb`,你可以使用下面的命令: @@ -49,7 +49,7 @@ $ createdb mydb createdb: command not found ``` -那么就是IvorySQL没有安装好。或者是根本没安装, 或者是你的shell搜索路径没有设置正确。尝试用绝对路径调用该命令试试: +那么就是IvorySQL没有安装好。或者是根本没安装,或者是你的shell搜索路径没有设置正确。尝试用绝对路径调用该命令试试: ``` $ /usr/local/pgsql/bin/createdb mydb @@ -64,7 +64,7 @@ createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No Is the server running locally and accepting connections on that socket? ``` -这意味着该服务器没有启动,或者在`createdb`期望去连接它的时候没有在监听。同样, 你也要查看安装指导或者咨询管理员。 +这意味着该服务器没有启动,或者在`createdb`期望去连接它的时候没有在监听。同样,你也要查看安装指导或者咨询管理员。 另外一个响应可能是这样: @@ -72,7 +72,7 @@ createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: role "joe" does not exist ``` -在这里提到了你自己的登录名。如果管理员没有为你创建IvorySQL用户帐号, 就会发生这些现象。(IvorySQL用户帐号和操作系统用户帐号是不同的。) 如果你是管理员,参阅 http://www.postgres.cn/docs/14/user-manag.html[第 22 章] 获取创建用户帐号的帮助。 你需要变成安装IvorySQL的操作系统用户的身份(通常是 `postgres`)才能创建第一个用户帐号。 也有可能是赋予你的IvorySQL用户名和你的操作系统用户名不同; 这种情况下,你需要使用`-U`选项或者使用`PGUSER`环境变量指定你的IvorySQL用户名。 +在这里提到了你自己的登录名。如果管理员没有为你创建IvorySQL用户帐号,就会发生这些现象。(IvorySQL用户帐号和操作系统用户帐号是不同的。) 如果你是管理员,参阅 http://www.postgresql.org/docs/17/user-manag.html[第 22 章] 获取创建用户帐号的帮助。你需要变成安装IvorySQL的操作系统用户的身份(通常是 `postgres`)才能创建第一个用户帐号。也有可能是赋予你的IvorySQL用户名和你的操作系统用户名不同;这种情况下,你需要使用`-U`选项或者使用`PGUSER`环境变量指定你的IvorySQL用户名。 如果你有个数据库用户帐号,但是没有创建数据库所需要的权限,那么你会看到下面的信息: @@ -80,25 +80,23 @@ createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FAT createdb: error: database creation failed: ERROR: permission denied to create database ``` -并非所有用户都被许可创建新数据库。 如果IvorySQL拒绝为你创建数据库, 那么你需要让站点管理员赋予你创建数据库的权限。出现这种情况时请咨询你的站点管理员。 如果你自己安装了IvorySQL, 那么你应该以你启动数据库服务器的用户身份登录然后参考手册完成权限的赋予工作。 http://www.postgres.cn/docs/14/tutorial-createdb.html#ftn.id-1.4.3.4.10.4[[1\]] +并非所有用户都被许可创建新数据库。如果IvorySQL拒绝为你创建数据库,那么你需要让站点管理员赋予你创建数据库的权限。出现这种情况时请咨询你的站点管理员。如果你自己安装了IvorySQL,那么你应该以你启动数据库服务器的用户身份登录然后参考手册完成权限的赋予工作。http://www.postgresql.org/docs/17/tutorial-createdb.html#ftn.id-1.4.3.4.10.4[[1\]] -你还可以用其它名字创建数据库。IvorySQL允许你在一个站点上创建任意数量的数据库。 数据库名必须是以字母开头并且小于 63 个字符长。 一个方便的做法是创建和你当前用户名同名的数据库。 许多工具假设该数据库名为缺省数据库名,所以这样可以节省你的敲键。 要创建这样的数据库,只需要键入: +你还可以用其它名字创建数据库。IvorySQL允许你在一个站点上创建任意数量的数据库。数据库名必须是以字母开头并且小于63个字符长。一个方便的做法是创建和你当前用户名同名的数据库。许多工具假设该数据库名为缺省数据库名,所以这样可以节省你的敲键。要创建这样的数据库,只需要键入: ``` $ createdb ``` - - -如果你再也不想使用你的数据库了,那么你可以删除它。 比如,如果你是数据库`mydb`的所有人(创建人), 那么你就可以用下面的命令删除它: +如果你再也不想使用你的数据库了,那么你可以删除它。比如,如果你是数据库`mydb`的所有人(创建人),那么你就可以用下面的命令删除它: ``` $ dropdb mydb ``` -(对于这条命令而言,数据库名不是缺省的用户名,因此你就必须声明它) 。这个动作将在物理上把所有与该数据库相关的文件都删除并且不可取消, 因此做这中操作之前一定要考虑清楚。 +(对于这条命令而言,数据库名不是缺省的用户名,因此你就必须声明它)。这个动作将在物理上把所有与该数据库相关的文件都删除并且不可取消,因此做这中操作之前一定要考虑清楚。 -更多关于 `createdb` 和 `dropdb` 的信息可以分别在 http://www.postgres.cn/docs/14/app-createdb.html[createdb] 和 http://www.postgres.cn/docs/14/app-dropdb.html[dropdb] 中找到。 +更多关于 `createdb` 和 `dropdb` 的信息可以分别在 http://www.postgresql.org/docs/17/app-createdb.html[createdb]和 http://www.postgresql.org/docs/17/app-dropdb.html[dropdb]中找到。 === 创建一个新表 @@ -116,11 +114,11 @@ CREATE TABLE weather ( 你可以在 `psql` 输入这些命令以及换行符。`psql` 可以识别该命令直到分号才结束。 -你可以在 SQL 命令中自由使用空白(即空格、制表符和换行符)。 这就意味着你可以用和上面不同的对齐方式键入命令,或者将命令全部放在一行中。两个划线(“`--`”)引入注释。 任何跟在它后面直到行尾的东西都会被忽略。SQL 是对关键字和标识符大小写不敏感的语言,只有在标识符用双引号包围时才能保留它们的大小写(上例没有这么做)。 +你可以在SQL命令中自由使用空白(即空格、制表符和换行符)。这就意味着你可以用和上面不同的对齐方式键入命令,或者将命令全部放在一行中。两个划线(“`--`”)引入注释。任何跟在它后面直到行尾的东西都会被忽略。SQL是对关键字和标识符大小写不敏感的语言,只有在标识符用双引号包围时才能保留它们的大小写(上例没有这么做)。 -`varchar(80)` 指定了一个可以存储最长 80 个字符的任意字符串的数据类型。 `int` 是普通的整数类型。 `real` 是一种用于存储单精度浮点数的类型。 `date` 类型应该可以自解释(没错,类型为`date`的列名字也是 `date`。 这么做可能比较方便或者容易让人混淆 — 你自己选择)。 +`varchar(80)` 指定了一个可以存储最长80个字符的任意字符串的数据类型。`int` 是普通的整数类型。`real` 是一种用于存储单精度浮点数的类型。`date` 类型应该可以自解释(没错,类型为`date`的列名字也是`date`。这么做可能比较方便或者容易让人混淆 — 你自己选择)。 -IvorySQL支持标准的SQL类型 `int`、`smallint`、`real`、`double precision`、`char(*N*)`、`varchar(*N*)`、`date`、`time`、`timestamp` 和 `interval`,还支持其他的通用功能的类型和丰富的几何类型。IvorySQL中可以定制任意数量的用户定义数据类型。因而类型名并不是语法关键字,除了SQL标准要求支持的特例外。 +IvorySQL支持标准的SQL类型`int`、`smallint`、`real`、`double precision`、`char(*N*)`、`varchar(*N*)`、`date`、`time`、`timestamp`和`interval`,还支持其他的通用功能的类型和丰富的几何类型。IvorySQL中可以定制任意数量的用户定义数据类型。因而类型名并不是语法关键字,除了SQL标准要求支持的特例外。 第二个例子将保存城市和它们相关的地理位置: @@ -131,7 +129,7 @@ CREATE TABLE cities ( ); ``` -类型 `point` 就是一种IvorySQL特有数据类型的例子。 +类型`point`就是一种IvorySQL特有数据类型的例子。 最后,我们还要提到如果你不再需要某个表,或者你想以不同的形式重建它,那么你可以用下面的命令删除它: @@ -143,7 +141,7 @@ DROP TABLE tablename; 当一个表被创建后,它不包含任何数据。在数据库发挥作用之前,首先要做的是插入数据。一次插入一行数据。你也可以在一个命令中插入多行,但不能插入不完整的行。即使只知道其中一些列的值,也必须创建完整的行。 -要创建一个新行,使用 http://www.postgres.cn/docs/14/sql-insert.html[INSERT] 命令。这条命令要求提供表的名字和其中列的值。例如,考虑 http://www.postgres.cn/docs/14/ddl.html[第 5 章] 中的产品表: +要创建一个新行,使用 http://www.postgresql.org/docs/17/sql-insert.html[INSERT]命令。这条命令要求提供表的名字和其中列的值。例如,考虑 http://www.postgresql.org/docs/17/ddl.html[第 5 章]中的产品表: ``` CREATE TABLE products ( @@ -186,8 +184,6 @@ INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT); INSERT INTO products DEFAULT VALUES; ``` - - 你可以在一个命令中插入多行: ``` @@ -197,8 +193,6 @@ INSERT INTO products (product_no, name, price) VALUES (3, 'Milk', 2.99); ``` - - 也可以插入查询的结果(可能没有行、一行或多行): ``` @@ -207,18 +201,18 @@ INSERT INTO products (product_no, name, price) WHERE release_date = 'today'; ``` -这提供了用于计算要插入的行的SQL查询机制( http://www.postgres.cn/docs/14/queries.html[第 7 章] )的全部功能。 +这提供了用于计算要插入的行的SQL查询机制( http://www.postgresql.org/docs/17/queries.html[第 7 章])的全部功能。 .提示 **** -在一次性插入大量数据时,考虑使用 http://www.postgres.cn/docs/14/sql-copy.html[COPY] 命令。它不如 http://www.postgres.cn/docs/14/sql-insert.html[INSERT] 命令那么灵活,但是更高效。 +在一次性插入大量数据时,考虑使用 http://www.postgresql.org/docs/17/sql-copy.html[COPY]命令。它不如 http://www.postgresql.org/docs/17/sql-insert.html[INSERT]命令那么灵活,但是更高效。 **** == 查询数据 参考 第七章查询的组合查询 第十五章 并行查询 === 组合查询 -两个查询的结果可以用集合操作并、交、差进行组合。语法是 +两个查询的结果可以用集合操作并、交、差进行组合。语法是: ``` query1 UNION [ALL] query2 @@ -226,7 +220,7 @@ query1 INTERSECT [ALL] query2 query1 EXCEPT [ALL] query2 ``` -*`query1`*和*`query2`*都是可以使用以上所有特性的查询。集合操作也可以嵌套和级连,例如 +*`query1`*和*`query2`*都是可以使用以上所有特性的查询。集合操作也可以嵌套和级连,例如: ``` query1 UNION query2 UNION query3 @@ -238,15 +232,13 @@ query1 UNION query2 UNION query3 (query1 UNION query2) UNION query3 ``` +`UNION`有效地把*`query2`*的结果附加到*`query1`*的结果上(不过我们不能保证这就是这些行实际被返回的顺序)。此外,它将删除结果中所有重复的行,就像`DISTINCT`做的那样,除非你使用了`UNION ALL`。 - -`UNION`有效地把*`query2`*的结果附加到*`query1`*的结果上(不过我们不能保证这就是这些行实际被返回的顺序)。此外,它将删除结果中所有重复的行, 就象`DISTINCT`做的那样,除非你使用了`UNION ALL`。 - -`INTERSECT`返回那些同时存在于*`query1`*和*`query2`*的结果中的行,除非声明了`INTERSECT ALL`, 否则所有重复行都被消除。 +`INTERSECT`返回那些同时存在于*`query1`*和*`query2`*的结果中的行,除非声明了`INTERSECT ALL`,否则所有重复行都被消除。 `EXCEPT`返回所有在*`query1`*的结果中但是不在*`query2`*的结果中的行(有时侯这叫做两个查询的*差*)。同样的,除非声明了`EXCEPT ALL`,否则所有重复行都被消除。 -为了计算两个查询的并、交、差,这两个查询必须是“并操作兼容的”,也就意味着它们都返回同样数量的列, 并且对应的列有兼容的数据类型,如 http://www.postgres.cn/docs/14/typeconv-union-case.html[第 10.5 节] 中描述的那样。 +为了计算两个查询的并、交、差,这两个查询必须是“并操作兼容的”,也就意味着它们都返回同样数量的列,并且对应的列有兼容的数据类型,如 http://www.postgresql.org/docs/17/typeconv-union-case.html[第 10.5 节]中描述的那样。 === 并行查询 @@ -265,11 +257,9 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; (4 rows) ``` - - 在所有的情形下,`Gather`或*Gather Merge*节点都只有一个子计划,它是将被并行执行的计划的一部分。如果`Gather`或*Gather Merge*节点位于计划树的最顶层,那么整个查询将并行执行。如果它位于计划树的其他位置,那么只有查询中在它之下的那一部分会并行执行。在上面的例子中,查询只访问了一个表,因此除`Gather`节点本身之外只有一个计划节点。因为该计划节点是`Gather`节点的孩子节点,所以它会并行执行。 -http://www.postgres.cn/docs/14/using-explain.html[使用 EXPLAIN] 命令, 你能看到规划器选择的工作者数量。当查询执行期间到达`Gather`节点时,实现用户会话的进程将会请求和规划器选中的工作者数量一样多的 http://www.postgres.cn/docs/14/bgworker.html[后台工作者进程] 。规划器将考虑使用的后台工作者的数量被限制为最多 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather] 个。任何时候能够存在的后台工作者进程的总数由 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES[max_worker_processes] 和 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS[max_parallel_workers] 限制。因此,一个并行查询可能会使用比规划中少的工作者来运行,甚至有可能根本不使用工作者。最优的计划可能取决于可用的工作者的数量,因此这可能会导致不好的查询性能。如果这种情况经常发生,那么就应当考虑一下提高`max_worker_processes`和`max_parallel_workers`的值,这样更多的工作者可以同时运行;或者降低`max_parallel_workers_per_gather`,这样规划器会要求少一些的工作者。 +http://www.postgresql.org/docs/17/using-explain.html[使用 EXPLAIN]命令, 你能看到规划器选择的工作者数量。当查询执行期间到达`Gather`节点时,实现用户会话的进程将会请求和规划器选中的工作者数量一样多的 http://www.postgresql.org/docs/17/bgworker.html[后台工作者进程]。规划器将考虑使用的后台工作者的数量被限制为最多 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather]个。任何时候能够存在的后台工作者进程的总数由 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES[max_worker_processes]和 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS[max_parallel_workers]限制。因此,一个并行查询可能会使用比规划中少的工作者来运行,甚至有可能根本不使用工作者。最优的计划可能取决于可用的工作者的数量,因此这可能会导致不好的查询性能。如果这种情况经常发生,那么就应当考虑一下提高`max_worker_processes`和`max_parallel_workers`的值,这样更多的工作者可以同时运行;或者降低`max_parallel_workers_per_gather`,这样规划器会要求少一些的工作者。 为一个给定并行查询成功启动的后台工作者进程都将会执行计划的并行部分。这些工作者的领导者也将执行该计划,不过它还有一个额外的任务:它还必须读取所有由工作者产生的元组。当整个计划的并行部分只产生了少量元组时,领导者通常将表现为一个额外的加速查询执行的工作者。反过来,当计划的并行部分产生大量的元组时,领导者将几乎全用来读取由工作者产生的元组并且执行`Gather`或`Gather Merge`节点上层计划节点所要求的任何进一步处理。在这些情况下,领导者所作的执行并行部分的工作将会很少。 @@ -279,22 +269,22 @@ http://www.postgres.cn/docs/14/using-explain.html[使用 EXPLAIN] 命令, 你能 有几种设置会导致查询规划器在任何情况下都不生成并行查询计划。为了让并行查询计划能够被生成,必须配置好下列设置。 -- http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather] 必须被设置为大于零的值。这是一种特殊情况,更加普遍的原则是所用的工作者数量不能超过`max_parallel_workers_per_gather`所配置的数量。 +- http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather]必须被设置为大于零的值。这是一种特殊情况,更加普遍的原则是所用的工作者数量不能超过`max_parallel_workers_per_gather`所配置的数量。 此外,系统一定不能运行在单用户模式下。因为在单用户模式下,整个数据库系统运行在单个进程中,没有后台工作者进程可用。 如果下面的任一条件为真,即便对一个给定查询通常可以产生并行查询计划,规划器都不会为它产生并行查询计划: -- 查询要写任何数据或者锁定任何数据库行。如果一个查询在顶层或者 CTE 中包含了数据修改操作,那么不会为该查询产生并行计划。一种例外是,`CREATE TABLE ... AS`、`SELECT INTO`以及`CREATE MATERIALIZED VIEW`这些创建新表并填充它的命令可以使用并行计划。 -- 查询可能在执行过程中被暂停。只要在系统认为可能发生部分或者增量式执行,就不会产生并行计划。例如:用 http://www.postgres.cn/docs/14/sql-declare.html[DECLARE CURSOR] 创建的游标将永远不会使用并行计划。类似地,一个`FOR x IN query LOOP .. END LOOP`形式的 PL/pgSQL 循环也永远不会使用并行计划,因为当并行查询进行时,并行查询系统无法验证循环中的代码执行起来是安全的。 -- 使用了任何被标记为`PARALLEL UNSAFE`的函数的查询。大多数系统定义的函数都被标记为`PARALLEL SAFE`,但是用户定义的函数默认被标记为`PARALLEL UNSAFE`。参见 http://www.postgres.cn/docs/14/parallel-safety.html[第 15.4 节] 中的讨论。 +- 查询要写任何数据或者锁定任何数据库行。如果一个查询在顶层或者CTE中包含了数据修改操作,那么不会为该查询产生并行计划。一种例外是,`CREATE TABLE ... AS`、`SELECT INTO`以及`CREATE MATERIALIZED VIEW`这些创建新表并填充它的命令可以使用并行计划。 +- 查询可能在执行过程中被暂停。只要在系统认为可能发生部分或者增量式执行,就不会产生并行计划。例如:用 http://www.postgresql.org/docs/17/sql-declare.html[DECLARE CURSOR]创建的游标将永远不会使用并行计划。类似地,一个`FOR x IN query LOOP .. END LOOP`形式的 PL/pgSQL 循环也永远不会使用并行计划,因为当并行查询进行时,并行查询系统无法验证循环中的代码执行起来是安全的。 +- 使用了任何被标记为`PARALLEL UNSAFE`的函数的查询。大多数系统定义的函数都被标记为`PARALLEL SAFE`,但是用户定义的函数默认被标记为`PARALLEL UNSAFE`。参见 http://www.postgresql.org/docs/17/parallel-safety.html[第 15.4 节]中的讨论。 - 该查询运行在另一个已经存在的并行查询内部。例如,如果一个被并行查询调用的函数自己发出一个 SQL 查询,那么该查询将不会使用并行计划。这是当前实现的一个限制,但是或许不值得移除这个限制,因为它会导致单个查询使用大量的进程。 即使对于一个特定的查询已经产生了并行查询计划,在一些情况下执行时也不会并行执行该计划。如果发生这种情况,那么领导者将会自己执行该计划在`Gather`节点之下的部分,就好像`Gather`节点不存在一样。上述情况将在满足下面的任一条件时发生: -- 因为后台工作者进程的总数不能超过 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES[max_worker_processes],导致不能得到后台工作者进程。 -- 由于为并行查询目的启动的后台工作者数量不能超过 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS[max_parallel_workers] 这一限制而不能得到后台工作者。 -- 客户端发送了一个执行消息,并且消息中要求取元组的数量不为零。执行消息可见 http://www.postgres.cn/docs/14/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY[扩展查询协议] 中的讨论。因为 http://www.postgres.cn/docs/14/libpq.html[libpq] 当前没有提供方法来发送这种消息,所以这种情况只可能发生在不依赖 libpq 的客户端中。如果这种情况经常发生,那在它可能发生的会话中设置 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather] 为零是一个很好的主意,这样可以避免产生连续运行时次优的查询计划。 +- 因为后台工作者进程的总数不能超过 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES[max_worker_processes],导致不能得到后台工作者进程。 +- 由于为并行查询目的启动的后台工作者数量不能超过 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS[max_parallel_workers]这一限制而不能得到后台工作者。 +- 客户端发送了一个执行消息,并且消息中要求取元组的数量不为零。执行消息可见 http://www.postgresql.org/docs/17/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY[扩展查询协议]中的讨论。因为 http://www.postgresql.org/docs/17/libpq.html[libpq]当前没有提供方法来发送这种消息,所以这种情况只可能发生在不依赖 libpq 的客户端中。如果这种情况经常发生,那在它可能发生的会话中设置 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER[max_parallel_workers_per_gather]为零是一个很好的主意,这样可以避免产生连续运行时次优的查询计划。 ==== 并行计划 @@ -324,7 +314,7 @@ IvorySQL通过按两个阶段进行聚集来支持并行聚集。首先,每个 因为`Finalize Aggregate`节点运行在领导者进程上,如果查询产生的分组数相对于其输入行数来说比较大,则查询规划器不会喜欢它。例如,在最坏的情况下,`Finalize Aggregate`节点看到的分组数可能与所有工作者进程在`Partial Aggregate`阶段看到的输入行数一样多。对于这类情况,使用并行聚集显然得不到性能收益。查询规划器会在规划过程中考虑这一点并且不太会在这种情况下选择并行聚集。 -并行聚集并非在所有情况下都被支持。每一个聚集都必须是对并行 http://www.postgres.cn/docs/14/parallel-safety.html[安全的] 并且必须有一个组合函数。如果该聚集有一个类型为`internal`的转移状态,它必须有序列化和反序列化函数。更多细节请参考 http://www.postgres.cn/docs/14/sql-createaggregate.html[CREATE AGGREGATE]。如果任何聚集函数调用包含`DISTINCT`或`ORDER BY`子句,则不支持并行聚集。对于有序集聚集或者当查询涉及`GROUPING SETS`时,也不支持并行聚集。只有在查询中涉及的所有连接也是该计划并行部分的组成部分时,才能使用并行聚集。 +并行聚集并非在所有情况下都被支持。每一个聚集都必须是对并行 http://www.postgresql.org/docs/17/parallel-safety.html[安全的]并且必须有一个组合函数。如果该聚集有一个类型为`internal`的转移状态,它必须有序列化和反序列化函数。更多细节请参考 http://www.postgresql.org/docs/17/sql-createaggregate.html[CREATE AGGREGATE]。如果任何聚集函数调用包含`DISTINCT`或`ORDER BY`子句,则不支持并行聚集。对于有序集聚集或者当查询涉及`GROUPING SETS`时,也不支持并行聚集。只有在查询中涉及的所有连接也是该计划并行部分的组成部分时,才能使用并行聚集。 ===== 并行Append @@ -334,11 +324,11 @@ IvorySQL通过按两个阶段进行聚集来支持并行聚集。首先,每个 此外,和常规的`Append`节点不同(在并行计划中使用时仅有部分子计划),`Parallel Append`节点既可以有部分子计划也可以有非部分子计划。非部分子计划将仅被单个进程扫描,因为扫描它们不止一次会产生重复的结果。因此涉及到追加多个结果集的计划即使在没有有效的部分计划可用时,也能实现粗粒度的并行。例如,考虑一个针对分区表的查询,它只能通过使用一个不支持并行扫描的索引来实现。规划器可能会选择常规`Index Scan`计划的`Parallel Append`。每个索引扫描必须被单一的进程执行完,但不同的扫描可以由不同的进程同时执行。 -http://www.postgres.cn/docs/14/runtime-config-query.html#GUC-ENABLE-PARALLEL-APPEND[enable_parallel_append] 可以被用来禁用这种特性。 +http://www.postgresql.org/docs/17/runtime-config-query.html#GUC-ENABLE-PARALLEL-APPEND[enable_parallel_append]可以被用来禁用这种特性。 ===== 并行计划小贴士 -如果我们想要一个查询能产生并行计划但事实上又没有产生,可以尝试减小 http://www.postgres.cn/docs/14/runtime-config-query.html#GUC-PARALLEL-SETUP-COST[parallel_setup_cost] 或者 http://www.postgres.cn/docs/14/runtime-config-query.html#GUC-PARALLEL-TUPLE-COST[parallel_tuple_cost]。当然,这个计划可能比规划器优先产生的顺序计划还要慢,但也不总是如此。如果将这些设置为很小的值(例如把它们设置为零)也不能得到并行计划,那就可能是有某种原因导致查询规划器无法为你的查询产生并行计划。可能的原因可见 http://www.postgres.cn/docs/14/when-can-parallel-query-be-used.html[第 15.2 节] 和 http://www.postgres.cn/docs/14/parallel-safety.html[第 15.4 节]。 +如果我们想要一个查询能产生并行计划但事实上又没有产生,可以尝试减小 http://www.postgresql.org/docs/17/runtime-config-query.html#GUC-PARALLEL-SETUP-COST[parallel_setup_cost]或者 http://www.postgresql.org/docs/17/runtime-config-query.html#GUC-PARALLEL-TUPLE-COST[parallel_tuple_cost]。当然,这个计划可能比规划器优先产生的顺序计划还要慢,但也不总是如此。如果将这些设置为很小的值(例如把它们设置为零)也不能得到并行计划,那就可能是有某种原因导致查询规划器无法为你的查询产生并行计划。可能的原因可见 http://www.postgresql.org/docs/17/when-can-parallel-query-be-used.html[第 15.2 节]和 http://www.postgresql.org/docs/17/parallel-safety.html[第 15.4 节]。 在执行一个并行计划时,可以用`EXPLAIN (ANALYZE,VERBOSE)`来显示每个计划节点在每个工作者上的统计信息。这些信息有助于确定是否所有的工作被均匀地分发到所有计划节点以及从总体上理解计划的性能特点。 @@ -354,7 +344,7 @@ ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] ==== 描述 -`ABORT`回滚当前事务并且导致由该事务所作的所有更新被丢弃。这个命令的行为与标准SQL命令 http://www.postgres.cn/docs/14/sql-rollback.html[`ROLLBACK`] 的行为一样,并且只是为了历史原因存在。 +`ABORT`回滚当前事务并且导致由该事务所作的所有更新被丢弃。这个命令的行为与标准SQL命令 http://www.postgresql.org/docs/17/sql-rollback.html[`ROLLBACK`]的行为一样,并且只是为了历史原因存在。 ==== 参数 @@ -364,11 +354,11 @@ ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] - `AND CHAIN` - 如果规定了`AND CHAIN` ,新事务立即启动,具有与刚刚完成的事务相同的事务特征(参见 http://www.postgres.cn/docs/14/sql-set-transaction.html[`SET TRANSACTION`])。否则,不会启动新事务。 + 如果规定了`AND CHAIN` ,新事务立即启动,具有与刚刚完成的事务相同的事务特征(参见 http://www.postgresql.org/docs/17/sql-set-transaction.html[`SET TRANSACTION`])。否则,不会启动新事务。 ==== 注解 -使用 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`] 成功地终止一个事务。 +使用 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]成功地终止一个事务。 在一个事务块之外发出`ABORT`会发出一个警告消息并且不会产生效果。 @@ -382,7 +372,7 @@ ABORT; ==== 兼容性 -这个命令是一个因为历史原因而存在的IvorySQL扩展。`ROLLBACK`是等效的标准 SQL 命令。 +这个命令是一个因为历史原因而存在的IvorySQL扩展。`ROLLBACK`是等效的标准SQL命令。 === BEGIN — 开始一个事务块 @@ -399,28 +389,28 @@ BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ] ``` ==== 描述 + +`BEGIN` 开始一个事务块,也就是说所有 `BEGIN` 命令之后的所有语句将被在一个事务中执行,直到给出一个显式的 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]或者 http://www.postgresql.org/docs/17/sql-rollback.html[`ROLLBACK`]。默认情况下(没有 `BEGIN` ),IvorySQL在“自动提交”模式中执行事务,也就是说每个语句都在自己的事务中执行并且在语句结束时隐式地执行一次提交(如果执行成功,否则会完成一次回滚)。 -`BEGIN`开始一个事务块,也就是说所有 `BEGIN`命令之后的所有语句将被在一个 事务中执行,直到给出一个显式的 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`] 或者 http://www.postgres.cn/docs/14/sql-rollback.html[`ROLLBACK`]。 默认情况下(没有`BEGIN`), IvorySQL在 “自动提交”模式中执行事务,也就是说每个语句都 在自己的事务中执行并且在语句结束时隐式地执行一次提交(如果执 行成功,否则会完成一次回滚)。 - -在一个事务块内的语句会执行得更快,因为事务的开始/提交也要求可观 的 CPU 和磁盘活动。在进行多个相关更改时,在一个事务内执行多个语 句也有助于保证一致性:在所有相关更新还没有完成之前,其他会话将不 能看到中间状态。 +在一个事务块内的语句会执行得更快,因为事务的开始/提交也要求可观的CPU和磁盘活动。在进行多个相关更改时,在一个事务内执行多个语句也有助于保证一致性:在所有相关更新还没有完成之前,其他会话将不能看到中间状态。 -如果指定了隔离级别、读/写模式或者延迟模式,新事务也会有那些特性, 就像执行了 http://www.postgres.cn/docs/14/sql-set-transaction.html[`SET TRANSACTION`]一样。 +如果指定了隔离级别、读/写模式或者延迟模式,新事务也会有那些特性,就像执行了 http://www.postgresql.org/docs/17/sql-set-transaction.html[`SET TRANSACTION`]一样。 ==== 参数 -- `WORK` `TRANSACTION` +- `WORK``TRANSACTION` 可选的关键词。它们没有效果。 -这个语句其他参数的含义请参考 http://www.postgres.cn/docs/14/sql-set-transaction.html[SET TRANSACTION]。 +这个语句其他参数的含义请参考 http://www.postgresql.org/docs/17/sql-set-transaction.html[SET TRANSACTION]。 ==== 注解 -http://www.postgres.cn/docs/14/sql-start-transaction.html[`START TRANSACTION`]具有和`BEGIN` 相同的功能。 +http://www.postgresql.org/docs/17/sql-start-transaction.html[`START TRANSACTION`]具有和`BEGIN` 相同的功能。 -使用 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`] 或者 http://www.postgres.cn/docs/14/sql-rollback.html[`ROLLBACK`]来终止一个事务块。 +使用 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]或者 http://www.postgresql.org/docs/17/sql-rollback.html[`ROLLBACK`]来终止一个事务块。 -在已经在一个事务块中时发出`BEGIN`将惹出一个警告 消息。事务状态不会被影响。要在一个事务块中嵌套事务,可以使用保 存点(见 http://www.postgres.cn/docs/14/sql-savepoint.html[SAVEPOINT])。 +在已经在一个事务块中时发出`BEGIN`将惹出一个警告消息。事务状态不会被影响。要在一个事务块中嵌套事务,可以使用保存点(见 http://www.postgresql.org/docs/17/sql-savepoint.html[SAVEPOINT])。 由于向后兼容的原因,连续的 *`transaction_modes`* 之间的逗号可以被省略。 @@ -434,11 +424,11 @@ BEGIN; ==== 兼容性 -`BEGIN` 是一种 IvorySQL语言扩展。它等效于 SQL 标准的命令 http://www.postgres.cn/docs/14/sql-start-transaction.html[`START TRANSACTION`],它的参考页 包含额外的兼容性信息。 +`BEGIN` 是一种IvorySQL语言扩展。它等效于SQL标准的命令 http://www.postgresql.org/docs/17/sql-start-transaction.html[`START TRANSACTION`],它的参考页包含额外的兼容性信息。 `DEFERRABLE` *`transaction_mode`* 是一种IvorySQL语言扩展。 -附带地,`BEGIN` 关键词被用于嵌入式 SQL 中的一种 不同目的。在移植数据库应用时,我们建议小心对待事务语义。 +附带地,`BEGIN`关键词被用于嵌入式SQL中的一种不同目的。在移植数据库应用时,我们建议小心对待事务语义。 === COMMIT — 提交当前事务 @@ -453,13 +443,13 @@ BEGIN; 可选的关键词。它们没有效果。 `AND CHAIN`:: -如果指定了 `AND CHAIN`,则立即启动与刚刚完成的事务具有相同事务特征(参见 http://www.postgres.cn/docs/14/sql-set-transaction.html[SET TRANSACTION])的新事务。 否则,没有新事务被启动。 +如果指定了 `AND CHAIN`,则立即启动与刚刚完成的事务具有相同事务特征(参见 http://www.postgresql.org/docs/17/sql-set-transaction.html[SET TRANSACTION])的新事务。否则,没有新事务被启动。 ==== 注解 -使用http://www.postgres.cn/docs/14/sql-rollback.html[ROLLBACK]中止一个事务。 +使用 http://www.postgresql.org/docs/17/sql-rollback.html[ROLLBACK]中止一个事务。 -当不在一个事务内时发出 `COMMIT` 不会 产生危害,但是它会产生一个警告消息。当 `COMMIT AND CHAIN` 不在事务内时是一个错误。 +当不在一个事务内时发出 `COMMIT` 不会产生危害,但是它会产生一个警告消息。当`COMMIT AND CHAIN`不在事务内时是一个错误。 ==== 示例 @@ -471,7 +461,7 @@ COMMIT; ==== 兼容性 -命令 `COMMIT` 符合 SQL 标准。 表单 `COMMIT TRANSACTION` 为IvorySQL扩展。 +命令 `COMMIT`符合SQL标准。表单`COMMIT TRANSACTION`为IvorySQL扩展。 === COMMIT PREPARED — 提交一个早前为两阶段提交预备的事务 @@ -483,7 +473,7 @@ COMMIT PREPARED transaction_id ==== 描述 -`COMMIT PREPARED` 提交一个处于预备状态的事务。 +`COMMIT PREPARED`提交一个处于预备状态的事务。 ==== 参数 @@ -492,11 +482,11 @@ COMMIT PREPARED transaction_id ==== 注解 -要提交一个预备的事务,你必须是原先执行该事务的同一用户或者超级用户。 但是不需要处于执行该事务的同一会话中。 +要提交一个预备的事务,你必须是原先执行该事务的同一用户或者超级用户。但是不需要处于执行该事务的同一会话中。 这个命令不能在一个事务块中执行。该预备事务将被立刻提交。 -http://www.postgres.cn/docs/14/view-pg-prepared-xacts.html[`pg_prepared_xacts`] 系统视图中列出了所有当前可用的预备事务。 +http://www.postgresql.org/docs/17/view-pg-prepared-xacts.html[`pg_prepared_xacts`]系统视图中列出了所有当前可用的预备事务。 ==== 例子 @@ -508,7 +498,7 @@ COMMIT PREPARED 'foobar'; ==== 兼容性 -`COMMIT PREPARED` 是一种 IvorySQL扩展。其意图是用于 外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA), 但是那些系统的 SQL 方面未被标准化。 +`COMMIT PREPARED` 是一种IvorySQL扩展。其意图是用于外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA),但是那些系统的SQL方面未被标准化。 === END - 提交当前事务 @@ -520,7 +510,7 @@ END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] ==== 描述 -`END`提交当前事务。 所有该事务做的更改便得对他人可见并且被保证发生崩溃时仍然是持久的。 这个命令是一种IvorySQL扩展,它等效于 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`]。 +`END` 提交当前事务。所有该事务做的更改便得对他人可见并且被保证发生崩溃时仍然是持久的。这个命令是一种IvorySQL扩展,它等效于 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]。 ==== 参数 @@ -528,13 +518,13 @@ END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 可选关键词,它们没有效果。 `AND CHAIN`:: -如果规定了`AND CHAIN`,则立即启动与刚完成事务具有相同事务特征(参见 http://www.postgres.cn/docs/14/sql-set-transaction.html[SET TRANSACTION])的新事务。否则,没有新事务被启动。 +如果规定了`AND CHAIN`,则立即启动与刚完成事务具有相同事务特征(参见 http://www.postgresql.org/docs/17/sql-set-transaction.html[SET TRANSACTION])的新事务。否则,没有新事务被启动。 ==== 注解 -使用 http://www.postgres.cn/docs/14/sql-rollback.html[`ROLLBACK`]可以中止一个事务。 +使用 http://www.postgresql.org/docs/17/sql-rollback.html[`ROLLBACK`]可以中止一个事务。 -当不在一个事务中时发出 `END` 没有危害,但是会 产生一个警告消息。 +当不在一个事务中时发出`END`没有危害,但是会产生一个警告消息。 ==== 示例 @@ -546,7 +536,7 @@ END; ==== 兼容性 -`END` 是一种IvorySQL扩展,它提供和 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`]等效的功能,后者在 SQL 标准中指定。 +`END` 是一种IvorySQL扩展,它提供和 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]等效的功能,后者在SQL标准中指定。 === PREPARE TRANSACTION — 为两阶段提交准备当前事务 @@ -558,40 +548,40 @@ PREPARE TRANSACTION transaction_id ==== 描述 -`PREPARE TRANSACTION` 为两阶段提交准备 当前事务。在这个命令之后,该事务不再与当前会话关联。相反,它的状态 被完全存储在磁盘上,并且有很高的可能性它会被提交成功(即便在请求提 交前发生数据库崩溃)。 +`PREPARE TRANSACTION`为两阶段提交准备当前事务。在这个命令之后,该事务不再与当前会话关联。相反,它的状态被完全存储在磁盘上,并且有很高的可能性它会被提交成功(即便在请求提交前发生数据库崩溃)。 -一旦被准备好,事务稍后就可以分别用 http://www.postgres.cn/docs/14/sql-commit-prepared.html[`COMMIT PREPARED`]或者 http://www.postgres.cn/docs/14/sql-rollback-prepared.html[`ROLLBACK PREPARED`]提交或者回滚。 可以从任何会话而不仅仅是执行原始事务的会话中发出这些命令。 +一旦被准备好,事务稍后就可以分别用 http://www.postgresql.org/docs/17/sql-commit-prepared.html[`COMMIT PREPARED`]或者 http://www.postgresql.org/docs/17/sql-rollback-prepared.html[`ROLLBACK PREPARED`]提交或者回滚。可以从任何会话而不仅仅是执行原始事务的会话中发出这些命令。 -从发出命令的会话的角度来看,`PREPARE TRANSACTION`不像 `ROLLBACK` 命令: 在执行它之后,就没有活跃的当前事务,并且该预备事务的效果也不再可见( 如果该事务被提交,效果将重新变得可见)。 +从发出命令的会话的角度来看,`PREPARE TRANSACTION`不像`ROLLBACK`命令:在执行它之后,就没有活跃的当前事务,并且该预备事务的效果也不再可见(如果该事务被提交,效果将重新变得可见)。 -如果由于任何原因 `PREPARE TRANSACTION` 命令失败,它会变成一个 `ROLLBACK` :当前事务会被取消。 +如果由于任何原因`PREPARE TRANSACTION`命令失败,它会变成一个`ROLLBACK`:当前事务会被取消。 ==== 参数 *`transaction_id`*:: -一个任意的事务标识符, `COMMIT PREPARED` 或者`ROLLBACK PREPARED` 以后将用这个标识符来标识这个事务。该标识符必须写成一个字符串,并且长度必须小于 200 字节。它也不能与任何当前已经准备好的事务的标识符相同。 +一个任意的事务标识符,`COMMIT PREPARED`或者`ROLLBACK PREPARED`以后将用这个标识符来标识这个事务。该标识符必须写成一个字符串,并且长度必须小于200字节。它也不能与任何当前已经准备好的事务的标识符相同。 ==== 注解 -`PREPARE TRANSACTION` 并不是设计为在应用或者交互式 会话中使用。它的目的是允许一个外部事务管理器在多个数据库或者其他事务性 来源之间执行原子的全局事务。除非你在编写一个事务管理器,否则你可能不会 用到`PREPARE TRANSACTION`。 +`PREPARE TRANSACTION`并不是设计为在应用或者交互式会话中使用。它的目的是允许一个外部事务管理器在多个数据库或者其他事务性来源之间执行原子的全局事务。除非你在编写一个事务管理器,否则你可能不会用到`PREPARE TRANSACTION`。 -这个命令必须在一个事务块中使用。事务块用 http://www.postgres.cn/docs/14/sql-begin.html[`BEGIN`]开始。 +这个命令必须在一个事务块中使用。事务块用 http://www.postgresql.org/docs/17/sql-begin.html[`BEGIN`]开始。 -当前在已经执行过任何涉及到临时表或者会话的临时命名空间、创建带 `WITH HOLD` 的游标或者执行 `LISTEN`、`UNLISTEN` 或 `NOTIFY` 的 事务中,不允许`PREPARE`该事务。这些特性与当前会话 绑定得太过紧密,所以对一个要被准备的事务来说没有什么用处。 +当前在已经执行过任何涉及到临时表或者会话的临时命名空间、创建带`WITH HOLD`的游标或者执行`LISTEN`、`UNLISTEN`或 `NOTIFY`的事务中,不允许`PREPARE`该事务。这些特性与当前会话绑定得太过紧密,所以对一个要被准备的事务来说没有什么用处。 -如果用 `SET`(不带 `LOCAL` 选项)修改过事务的 任何运行时参数,这些效果会持续到 `PREPARE TRANSACTION` 之后,并且将不会被后续的任何 `COMMIT PREPARED` 或 `ROLLBACK PREPARED` 所影响。因此,在这一 方面`PREPARE TRANSACTION` 的行为更像 `COMMIT` 而不是`ROLLBACK`。 +如果用`SET`(不带`LOCAL`选项)修改过事务的任何运行时参数,这些效果会持续到`PREPARE TRANSACTION`之后,并且将不会被后续的任何`COMMIT PREPARED`或`ROLLBACK PREPARED`所影响。因此,在这一 方面`PREPARE TRANSACTION`的行为更像`COMMIT`而不是`ROLLBACK`。 -所有当前可用的准备好事务被列在 http://www.postgres.cn/docs/14/view-pg-prepared-xacts.html[`pg_prepared_xacts`]系统视图中。 +所有当前可用的准备好事务被列在 http://www.postgresql.org/docs/17/view-pg-prepared-xacts.html[`pg_prepared_xacts`]系统视图中。 ==== 小心 -让一个事务处于准备好状态太久是不明智的。这将会干扰 `VACUUM` 回收存储的能力,并且在极限情况下可能导致 数据库关闭以阻止事务 ID 回卷(见 http://www.postgres.cn/docs/14/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND[第 25.1.5 节])。还要记住,该事务会继续持有 它已经持有的锁。该特性的设计用法是,只要一个外部事务管理器已经验证 其他数据库也准备好了要提交,一个准备好的事务将被正常地提交或者回滚。 +让一个事务处于准备好状态太久是不明智的。这将会干扰`VACUUM`回收存储的能力,并且在极限情况下可能导致数据库关闭以阻止事务ID回卷(见 http://www.postgresql.org/docs/17/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND[第 25.1.5 节])。还要记住,该事务会继续持有它已经持有的锁。该特性的设计用法是,只要一个外部事务管理器已经验证其他数据库也准备好了要提交,一个准备好的事务将被正常地提交或者回滚。 -如果没有建立一个外部事务管理器来跟踪准备好的事务并且确保它们被迅速地 结束,最好禁用准备好事务特性(设置 http://www.postgres.cn/docs/14/runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS[max_prepared_transactions] 为零)。这将防止意外 地创建准备好事务,不然该事务有可能被忘记并且最终导致问题。 +如果没有建立一个外部事务管理器来跟踪准备好的事务并且确保它们被迅速地结束,最好禁用准备好事务特性(设置 http://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS[max_prepared_transactions]为零)。这将防止意外地创建准备好事务,不然该事务有可能被忘记并且最终导致问题。 ==== 例子 -为两阶段提交准备当前事务,使用 `foobar` 作为事务标识符: +为两阶段提交准备当前事务,使用`foobar`作为事务标识符: ``` PREPARE TRANSACTION 'foobar'; @@ -599,7 +589,7 @@ PREPARE TRANSACTION 'foobar'; ==== 兼容性 -`PREPARE TRANSACTION` 是一种 IvorySQL扩展。其意图是用于 外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA), 但是那些系统的 SQL 方面未被标准化。 +`PREPARE TRANSACTION`是一种IvorySQL扩展。其意图是用于外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA),但是那些系统的SQL方面未被标准化。 === ROLLBACK — 中止当前事务 @@ -611,7 +601,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] ==== 描述 -`ROLLBACK` 回滚当前事务并且导致 该事务所作的所有更新都被抛弃。 +`ROLLBACK`回滚当前事务并且导致该事务所作的所有更新都被抛弃。 ==== 参数 @@ -619,13 +609,13 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 可选关键词,没有效果。 `AND CHAIN`:: -如果指定了 `AND CHAIN` ,则立即启动与刚刚完成事务具有相同事务特征(参见 http://www.postgres.cn/docs/14/sql-set-transaction.html[SET TRANSACTION])的新事务。 否则,不会启动任何新事务。 +如果指定了`AND CHAIN`,则立即启动与刚刚完成事务具有相同事务特征(参见 http://www.postgresql.org/docs/17/sql-set-transaction.html[SET TRANSACTION])的新事务。否则,不会启动任何新事务。 ==== 注解 -使用 http://www.postgres.cn/docs/14/sql-commit.html[`COMMIT`]可成功地终止一个事务。 +使用 http://www.postgresql.org/docs/17/sql-commit.html[`COMMIT`]可成功地终止一个事务。 -在一个事务块之外发出 `ROLLBACK` 会发出一个警告并且不会有效果。 事务块之外的 `ROLLBACK AND CHAIN` 是一个错误。 +在一个事务块之外发出`ROLLBACK`会发出一个警告并且不会有效果。事务块之外的`ROLLBACK AND CHAIN`是一个错误。 ==== 示例 @@ -637,7 +627,7 @@ ROLLBACK; ==== 兼容性 -命令 `ROLLBACK` 符合 SQL 标准。窗体 `ROLLBACK TRANSACTION` 是一个IvorySQL扩展。 +命令`ROLLBACK`符合SQL标准。窗体`ROLLBACK TRANSACTION`是一个IvorySQL扩展。 === ROLLBACK PREPARED — 取消一个之前为两阶段提交准备好的事务 @@ -649,7 +639,7 @@ ROLLBACK PREPARED transaction_id ==== 描述 -`ROLLBACK PREPARED` 回滚一个处于准备好状态的事务。 +`ROLLBACK PREPARED`回滚一个处于准备好状态的事务。 ==== 参数 @@ -658,15 +648,15 @@ ROLLBACK PREPARED transaction_id ==== 注解 -要回滚一个准备好的事务,你必须是原先执行该事务的同一个用户或者 是一个超级用户。但是你必须处在执行该事务的同一个会话中。 +要回滚一个准备好的事务,你必须是原先执行该事务的同一个用户或者是一个超级用户。但是你必须处在执行该事务的同一个会话中。 这个命令不能在一个事务块内被执行。准备好的事务会被立刻回滚。 -http://www.postgres.cn/docs/14/view-pg-prepared-xacts.html[`pg_prepared_xacts`] 系统视图中列出了当前可用的所有准备好的事务。 +http://www.postgresql.org/docs/17/view-pg-prepared-xacts.html[`pg_prepared_xacts`]系统视图中列出了当前可用的所有准备好的事务。 ==== 例子 -用事务标识符 `foobar` 回滚对应的事务: +用事务标识符`foobar`回滚对应的事务: ``` ROLLBACK PREPARED 'foobar'; @@ -674,7 +664,7 @@ ROLLBACK PREPARED 'foobar'; ==== 兼容性 -`ROLLBACK PREPARED` 是一种 IvorySQL扩展。其意图是用于 外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA), 但是那些系统的 SQL 方面未被标准化。 +`ROLLBACK PREPARED`是一种IvorySQL扩展。其意图是用于外部事务管理系统,其中有些已经被标准涵盖(例如 X/Open XA),但是那些系统的SQL方面未被标准化。 === SAVEPOINT — 在当前事务中定义一个新的保存点 @@ -686,7 +676,7 @@ SAVEPOINT savepoint_name ==== 描述 -`SAVEPOINT` 在当前事务中建立一个新保存点。 +`SAVEPOINT`在当前事务中建立一个新保存点。 保存点是事务内的一种特殊标记,它允许所有在它被建立之后执行的命令被回滚,把该事务的状态恢复到它处于保存点时的样子。 @@ -697,7 +687,7 @@ SAVEPOINT savepoint_name ==== 注解 -使用 http://www.postgres.cn/docs/14/sql-rollback-to.html[`ROLLBACK TO`]回滚到一个保存点。 使用 http://www.postgres.cn/docs/14/sql-release-savepoint.html[`RELEASE SAVEPOINT`]销毁一个保存点, 但保持在它被建立之后执行的命令的效果。 +使用 http://www.postgresql.org/docs/17/sql-rollback-to.html[`ROLLBACK TO`]回滚到一个保存点。使用 http://www.postgresql.org/docs/17/sql-release-savepoint.html[`RELEASE SAVEPOINT`]销毁一个保存点,但保持在它被建立之后执行的命令的效果。 保存点只能在一个事务块内建立。可以在一个事务内定义多个保存点。 @@ -732,7 +722,7 @@ COMMIT; ==== 兼容性 -当建立另一个同名保存点时,SQL要求之前的那个保存点自动被销毁。在IvorySQL中,旧的保存点会被保留,不过在进行 回滚或释放时只能使用最近的那一个(用 `RELEASE SAVEPOINT`释放较新的保存点将会导致较旧的保存点再次变得可以被 `ROLLBACK TO SAVEPOINT` 和 `RELEASE SAVEPOINT` 访问)。在其他方面,`SAVEPOINT`完全符合SQL。 +当建立另一个同名保存点时,SQL要求之前的那个保存点自动被销毁。在IvorySQL中,旧的保存点会被保留,不过在进行回滚或释放时只能使用最近的那一个(用 `RELEASE SAVEPOINT`释放较新的保存点将会导致较旧的保存点再次变得可以被`ROLLBACK TO SAVEPOINT`和`RELEASE SAVEPOINT`访问)。在其他方面,`SAVEPOINT`完全符合SQL。 === SET CONSTRAINTS — 为当前事务设置约束检查时机 @@ -744,27 +734,27 @@ SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE } ==== 描述 -`SET CONSTRAINTS` 设置当前事务内约束检查的行为。`IMMEDIATE` 约束在每个语句结束时被检查。 `DEFERRED` 约束直到事务提交时才被检查。每个约束都有 自己的 `IMMEDIATE` 或 `DEFERRED` 模式。 +`SET CONSTRAINTS`设置当前事务内约束检查的行为。`IMMEDIATE`约束在每个语句结束时被检查。`DEFERRED`约束直到事务提交时才被检查。每个约束都有自己的`IMMEDIATE`或`DEFERRED`模式。 -在创建时,一个约束会被给定三种特性之一: `DEFERRABLE INITIALLY DEFERRED`、 `DEFERRABLE INITIALLY IMMEDIATE` 或者 `NOT DEFERRABLE` 。第三类总是 `IMMEDIATE` 并且不会受到 `SET CONSTRAINTS` 命令的影响。前两类在每个 事务开始时都处于指定的模式,但是它们的行为可以在一个事务内用 `SET CONSTRAINTS` 更改。 +在创建时,一个约束会被给定三种特性之一:`DEFERRABLE INITIALLY DEFERRED`、`DEFERRABLE INITIALLY IMMEDIATE`或者`NOT DEFERRABLE`。第三类总是`IMMEDIATE`并且不会受到`SET CONSTRAINTS`命令的影响。前两类在每个事务开始时都处于指定的模式,但是它们的行为可以在一个事务内用`SET CONSTRAINTS`更改。 -带有一个约束名称列表的 `SET CONSTRAINTS` 只更改那些约束(都必须是可延迟的)的模式。每一个约束名称都可以是 模式限定的。如果没有指定模式名称,则当前的模式搜索路径将被用来寻找 第一个匹配的名称。`SET CONSTRAINTS ALL` 更改所有可延迟约束的模式。 +带有一个约束名称列表的`SET CONSTRAINTS`只更改那些约束(都必须是可延迟的)的模式。每一个约束名称都可以是模式限定的。如果没有指定模式名称,则当前的模式搜索路径将被用来寻找第一个匹配的名称。`SET CONSTRAINTS ALL`更改所有可延迟约束的模式。 -当 `SET CONSTRAINTS` 把一个约束的模式从 `DEFERRED` 改成 `IMMEDIATE` 时, 新模式会有追溯效果:任何还没有解决的数据修改(本来会在事务结束时 被检查)会转而在 `SET CONSTRAINTS` 命令 的执行期间被检查。如果任何这种约束被违背, `SET CONSTRAINTS` 将会失败(并且不会改 变该约束模式)。这样,`SET CONSTRAINTS` 可以被用来在一个事务中的特定点强制进 行约束检查。 +当`SET CONSTRAINTS`把一个约束的模式从`DEFERRED`改成`IMMEDIATE`时,新模式会有追溯效果:任何还没有解决的数据修改(本来会在事务结束时被检查)会转而在`SET CONSTRAINTS`命令的执行期间被检查。如果任何这种约束被违背,`SET CONSTRAINTS`将会失败(并且不会改变该约束模式)。这样,`SET CONSTRAINTS` 可以被用来在一个事务中的特定点强制进行约束检查。 -当前,只有 `UNIQUE`、`PRIMARY KEY`、 `REFERENCES`(外键)以及 `EXCLUDE` 约束受到这个设置的影响。 `NOT NULL` 以及 `CHECK` 约束总是在一行 被插入或修改时立即检查(**不是**在语句结束时)。 没有被声明为 `DEFERRABLE` 的唯一和排除约束也会被 立刻检查。 +当前,只有`UNIQUE`、`PRIMARY KEY`、`REFERENCES`(外键)以及`EXCLUDE`约束受到这个设置的影响。`NOT NULL`以及`CHECK`约束总是在一行被插入或修改时立即检查(**不是**在语句结束时)。没有被声明为`DEFERRABLE`的唯一和排除约束也会被立刻检查。 -被声明为“约束触发器”的触发器的引发也受到这个设置 的控制 — 它们会在相关约束被检查的同时被引发。 +被声明为“约束触发器”的触发器的引发也受到这个设置的控制 — 它们会在相关约束被检查的同时被引发。 ==== 注解 -因为IvorySQL并不要求约束名称在模式内唯一(但是在表内要求唯一),可能有多于一个约束匹配指定的约束名称。在这种 情况下 `SET CONSTRAINTS` 将会在所有的匹配上操作。 对于一个非模式限定的名称,一旦在搜索路径中的某个模式中发现一个或者多个匹配,路径中后面的模式将不会被搜索。 +因为IvorySQL并不要求约束名称在模式内唯一(但是在表内要求唯一),可能有多于一个约束匹配指定的约束名称。在这种情况下`SET CONSTRAINTS`将会在所有的匹配上操作。对于一个非模式限定的名称,一旦在搜索路径中的某个模式中发现一个或者多个匹配,路径中后面的模式将不会被搜索。 这个命令只修改当前事务内约束的行为。在事务块外部发出这个命令会产生一个警告并且也不会有任何效果。 ==== 兼容性 -这个命令符合 SQL 标准中定义的行为,但有一点限制:在 IvorySQL中,它不会应用在 `NOT NULL` 和 `CHECK` 约束上。还有,IvorySQL会立刻检查非可延迟的 唯一约束,而不是按照标准建议的在语句结束时检查。 +这个命令符合SQL标准中定义的行为,但有一点限制:在 IvorySQL中,它不会应用在`NOT NULL`和`CHECK`约束上。还有,IvorySQL会立刻检查非可延迟的唯一约束,而不是按照标准建议的在语句结束时检查。 === SET TRANSACTION — 设置当前事务的特性 @@ -775,7 +765,7 @@ SET TRANSACTION transaction_mode [, ...] SET TRANSACTION SNAPSHOT snapshot_id SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...] -其中 transaction_mode 是下列之一: +其中transaction_mode是下列之一: ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } READ WRITE | READ ONLY @@ -784,9 +774,9 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...] ==== 描述 -`SET TRANSACTION` 命令设置当前 会话的特性。`SET SESSION CHARACTERISTICS` 设置一个会话后续事务的默认 事务特性。在个体事务中可以用 `SET TRANSACTION`覆盖这些默认值。 +`SET TRANSACTION`命令设置当前会话的特性。`SET SESSION CHARACTERISTICS`设置一个会话后续事务的默认事务特性。在个体事务中可以用`SET TRANSACTION`覆盖这些默认值。 -可用的事务特性是事务隔离级别、事务访问模式(读/写或只读)以及 可延迟模式。此外,可以选择一个快照,不过只能用于当前事务而不能 作为会话默认值。 +可用的事务特性是事务隔离级别、事务访问模式(读/写或只读)以及可延迟模式。此外,可以选择一个快照,不过只能用于当前事务而不能作为会话默认值。 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: @@ -799,29 +789,29 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...] `SERIALIZABLE`:: 当前事务的所有语句只能看到这个事务中执行的第一个查询或者数据修改语句之前提交的行。如果并发的可序列化事务间的读写模式可能导致一种那些事务串行(一次一个)执行时不可能出现的情况,其中之一将会被回滚并且得到一个 `serialization_failure`错误。 -SQL 标准定义了一种额外的级别:`READ UNCOMMITTED`。在IvorySQL中 `READ UNCOMMITTED` 被视作 `READ COMMITTED`。 +SQL标准定义了一种额外的级别:`READ UNCOMMITTED`。在IvorySQL中`READ UNCOMMITTED`被视作`READ COMMITTED`。 -一个事务执行了第一个查询或者数据修改语句( `SELECT`、 `INSERT`、`DELETE`、 `UPDATE`、`FETCH` 或 `COPY`)之后就无法更改事务隔离级别。 更多有关事务隔离级别和并发控制的信息可见 http://www.postgres.cn/docs/14/mvcc.html[第 13 章]。 +一个事务执行了第一个查询或者数据修改语句(`SELECT`、`INSERT`、`DELETE`、`UPDATE`、`FETCH`或`COPY`)之后就无法更改事务隔离级别。更多有关事务隔离级别和并发控制的信息可见 http://www.postgresql.org/docs/17/mvcc.html[第 13 章]。 -事务的访问模式决定该事务是否为读/写或者只读。读/写是默认值。 当一个事务为只读时,如果SQL命令 `INSERT`、`UPDATE`、 `DELETE` 和 `COPY FROM` 要写的表不是一个临时表,则它们不被允许。不允许 `CREATE`、`ALTER`以及 `DROP` 命令。不允许 `COMMENT`、 `GRANT`、`REVOKE`、 `TRUNCATE`。如果 `EXPLAIN ANALYZE` 和`EXECUTE` 要执行的命令是上述命令之一,则它们也不被允许。这是一种高层的只读概念,它不能阻止所有对磁盘的写入。 +事务的访问模式决定该事务是否为读/写或者只读。读/写是默认值。当一个事务为只读时,如果SQL命令`INSERT`、`UPDATE`、`DELETE`和`COPY FROM`要写的表不是一个临时表,则它们不被允许。不允许`CREATE`、`ALTER`以及`DROP`命令。不允许`COMMENT`、`GRANT`、`REVOKE`、`TRUNCATE`。如果`EXPLAIN ANALYZE`和`EXECUTE`要执行的命令是上述命令之一,则它们也不被允许。这是一种高层的只读概念,它不能阻止所有对磁盘的写入。 -只有事务也是 `SERIALIZABLE` 以及 `READ ONLY` 时,`DEFERRABLE` 事务属性才会有效。当一个事务的所有这三个属性都被选择时,该事务在第一次获取其快照时可能会阻塞,在那之后它运行时就不会有 `SERIALIZABLE` 事务的开销并且不会有任何牺牲或者被一次序列化失败取消的风险。这种模式很适合于长时间运行的报表或者备份。 +只有事务也是`SERIALIZABLE`以及`READ ONLY`时,`DEFERRABLE`事务属性才会有效。当一个事务的所有这三个属性都被选择时,该事务在第一次获取其快照时可能会阻塞,在那之后它运行时就不会有`SERIALIZABLE`事务的开销并且不会有任何牺牲或者被一次序列化失败取消的风险。这种模式很适合于长时间运行的报表或者备份。 -`SET TRANSACTION SNAPSHOT` 命令允许新的事务使用与一个现有事务相同的 *快照* 运行。已经存在的事务必须已经把它的快照用 `pg_export_snapshot` 函数(见 http://www.postgres.cn/docs/14/functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION[第 9.27.5 节])导出。该函数会返回一个快照标识符,`SET TRANSACTION SNAPSHOT` 需要被给定一个快照标识符来指定要导入的快照。在这个命令中该标识符必须被写成一个字符串,例如 `'000003A1-1'`。 `SET TRANSACTION SNAPSHOT` 只能在一个事务的开始执行,并且要在该事务的第一个查询或者数据修改语句( `SELECT`、 `INSERT`、`DELETE`、 `UPDATE`、`FETCH`或 `COPY`)之前执行。此外,该事务必须已经被设置为`SERIALIZABLE` 或者 `REPEATABLE READ` 隔离级别(否则,该快照将被立刻抛弃,因为 `READ COMMITTED` 模式会为每一个命令取一个新快照)。如果导入事务使用了`SERIALIZABLE` 隔离级别,那么导入快照的事务必须也使用该隔离级别。还有,一个非只读可序列化事务不能导入来自只读事务的快照。 +`SET TRANSACTION SNAPSHOT`命令允许新的事务使用与一个现有事务相同的*快照*运行。已经存在的事务必须已经把它的快照用`pg_export_snapshot` 函数(见 http://www.postgresql.org/docs/17/functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION[第 9.27.5 节])导出。该函数会返回一个快照标识符,`SET TRANSACTION SNAPSHOT`需要被给定一个快照标识符来指定要导入的快照。在这个命令中该标识符必须被写成一个字符串,例如`'000003A1-1'`。`SET TRANSACTION SNAPSHOT`只能在一个事务的开始执行,并且要在该事务的第一个查询或者数据修改语句(`SELECT`、`INSERT`、`DELETE`、`UPDATE`、`FETCH`或 `COPY`)之前执行。此外,该事务必须已经被设置为`SERIALIZABLE`或者`REPEATABLE READ`隔离级别(否则,该快照将被立刻抛弃,因为`READ COMMITTED`模式会为每一个命令取一个新快照)。如果导入事务使用了`SERIALIZABLE`隔离级别,那么导入快照的事务必须也使用该隔离级别。还有,一个非只读可序列化事务不能导入来自只读事务的快照。 ==== 注解 -如果执行 `SET TRANSACTION` 之前没有 `START TRANSACTION` 或者 `BEGIN`,它会发出一个警告并且不会有任何效果。 +如果执行`SET TRANSACTION`之前没有`START TRANSACTION`或者`BEGIN`,它会发出一个警告并且不会有任何效果。 -可以通过在 `BEGIN` 或者 `START TRANSACTION` 中指定想要的 `*transaction_modes*` 来省掉 `SET TRANSACTION`。但是在 `SET TRANSACTION SNAPSHOT` 中该选项不可用。 +可以通过在`BEGIN`或者`START TRANSACTION`中指定想要的`*transaction_modes*`来省掉`SET TRANSACTION`。但是在`SET TRANSACTION SNAPSHOT`中该选项不可用。 -会话默认的事务模式也可以通过配置参数 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-ISOLATION[default_transaction_isolation]、 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY[default_transaction_read_only] 和 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE[default_transaction_deferrable] 来设置或检查(实际上 `SET SESSION CHARACTERISTICS`只是用 `SET` 设置这些变量的等效体)。这意味着可以通过配置文件、 `ALTER DATABASE` 等方式设置默认值。详见 http://www.postgres.cn/docs/14/runtime-config.html[第 20 章]。 +会话默认的事务模式也可以通过配置参数 http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-ISOLATION[default_transaction_isolation]、http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY[default_transaction_read_only]和 http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE[default_transaction_deferrable]来设置或检查(实际上`SET SESSION CHARACTERISTICS`只是用`SET`设置这些变量的等效体)。这意味着可以通过配置文件、`ALTER DATABASE` 等方式设置默认值。详见 http://www.postgresql.org/docs/17/runtime-config.html[第 20 章]。 -当前事务的模式可以类似的通过配置参数 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-TRANSACTION-ISOLATION[transaction_isolation]、 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-TRANSACTION-READ-ONLY[transaction_read_only]、和 http://www.postgres.cn/docs/14/runtime-config-client.html#GUC-TRANSACTION-DEFERRABLE[transaction_deferrable] 来设置或检查。设置这其中一个参数的作用与相应的 `SET TRANSACTION` 选项相同,在它何时可以完成方面,也有相同的限制。但是,这些参数不能在配置文件中设置,或者从活动SQL以外的任何来源来设置。 +当前事务的模式可以类似的通过配置参数 http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-TRANSACTION-ISOLATION[transaction_isolation]、 http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-TRANSACTION-READ-ONLY[transaction_read_only]、和 http://www.postgresql.org/docs/17/runtime-config-client.html#GUC-TRANSACTION-DEFERRABLE[transaction_deferrable]来设置或检查。设置这其中一个参数的作用与相应的`SET TRANSACTION`选项相同,在它何时可以完成方面,也有相同的限制。但是,这些参数不能在配置文件中设置,或者从活动SQL以外的任何来源来设置。 ==== 示例 -要用一个已经存在的事务的同一快照开始一个新事务,首先要从该现有 事务导出快照。这将会返回快照标识符,例如: +要用一个已经存在的事务的同一快照开始一个新事务,首先要从该现有事务导出快照。这将会返回快照标识符,例如: ``` BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; @@ -832,7 +822,7 @@ SELECT pg_export_snapshot(); (1 row) ``` -然后在一个新开始的事务的开头把该快照标识符用在一个 `SET TRANSACTION SNAPSHOT` 命令中: +然后在一个新开始的事务的开头把该快照标识符用在一个`SET TRANSACTION SNAPSHOT`命令中: ``` BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; @@ -841,13 +831,13 @@ SET TRANSACTION SNAPSHOT '00000003-0000001B-1'; ==== 兼容性 -SQL标准中定义了这些命令,不过 `DEFERRABLE` 事务模式和 `SET TRANSACTION SNAPSHOT` 形式除外,这两者是 IvorySQL扩展。 +SQL标准中定义了这些命令,不过`DEFERRABLE`事务模式和`SET TRANSACTION SNAPSHOT`形式除外,这两者是IvorySQL扩展。 -`SERIALIZABLE` 是标准中默认的事务隔离级别。在 IvorySQL中默认值是普通的 `READ COMMITTED`,但是你可以按上述的方式更改。 +`SERIALIZABLE`是标准中默认的事务隔离级别。在IvorySQL中默认值是普通的`READ COMMITTED`,但是你可以按上述的方式更改。 -在SQL标准中,可以用这些命令设置一个其他的事务特性:诊断区域 的尺寸。这个概念与嵌入式SQL有关,并且因此没有在IvorySQL服务器中实现。 +在SQL标准中,可以用这些命令设置一个其他的事务特性:诊断区域的尺寸。这个概念与嵌入式SQL有关,并且因此没有在IvorySQL服务器中实现。 -SQL 标准要求连续的 *`transaction_modes`* 之间有逗号,但是出于历史原因IvorySQL允许省略逗号。 +SQL标准要求连续的 *`transaction_modes`* 之间有逗号,但是出于历史原因IvorySQL允许省略逗号。 === START TRANSACTION — 开始一个事务块 @@ -865,15 +855,15 @@ START TRANSACTION [ transaction_mode [, ...] ] ==== 描述 -这个命令开始一个新的事务块。如果指定了隔离级别、读写模式 或者可延迟模式,新的事务将会具有这些特性,就像执行了 http://www.postgres.cn/docs/14/sql-set-transaction.html[`SET TRANSACTION`]一样。这和 http://www.postgres.cn/docs/14/sql-begin.html[`BEGIN`]命令一样。 +这个命令开始一个新的事务块。如果指定了隔离级别、读写模式或者可延迟模式,新的事务将会具有这些特性,就像执行了 http://www.postgresql.org/docs/17/sql-set-transaction.html[`SET TRANSACTION`]一样。这和 http://www.postgresql.org/docs/17/sql-begin.html[`BEGIN`]命令一样。 ==== 参数 -这些参数对于这个语句的含义可参考 http://www.postgres.cn/docs/14/sql-set-transaction.html[SET TRANSACTION]。 +这些参数对于这个语句的含义可参考 http://www.postgresql.org/docs/17/sql-set-transaction.html[SET TRANSACTION]。 ==== 兼容性 -在标准中,没有必要发出 `START TRANSACTION` 来开始一个事务块:任何SQL命令会隐式地开始一个块。 IvorySQL的行为可以被视作在每个命令之后隐式地发出一个没有跟随在 `START TRANSACTION` ( 或者`BEGIN`)之后的 `COMMIT` 并且因此通常被称作 “自动提交”。为了方便,其他关系型数据库系统也可能会 提供自动提交特性。 +在标准中,没有必要发出`START TRANSACTION`来开始一个事务块:任何SQL命令会隐式地开始一个块。IvorySQL的行为可以被视作在每个命令之后隐式地发出一个没有跟随在`START TRANSACTION`(或者`BEGIN`)之后的`COMMIT`并且因此通常被称作 “自动提交”。为了方便,其他关系型数据库系统也可能会提供自动提交特性。 `DEFERRABLE` *`transaction_mode`* 是一种IvorySQL语言扩展。 @@ -899,15 +889,15 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 另外,*注释* 也可以出现在SQL输入中。它们不是记号,它们和空白完全一样。 -根据标识命令、操作符、参数的记号不同,SQL的语法不很一致。最前面的一些记号通常是命令名,因此在上面的例子中我们通常会说一个“SELECT”、一个“UPDATE”和一个“INSERT”命令。但是例如 `UPDATE` 命令总是要求一个 `SET` 记号出现在一个特定位置,而 `INSERT` 则要求一个 `VALUES` 来完成命令。每个命令的精确语法规则在 http://www.postgres.cn/docs/14/reference.html[第 VI 部分] 中介绍。 +根据标识命令、操作符、参数的记号不同,SQL的语法不很一致。最前面的一些记号通常是命令名,因此在上面的例子中我们通常会说一个“SELECT”、一个“UPDATE”和一个“INSERT”命令。但是例如`UPDATE`命令总是要求一个`SET`记号出现在一个特定位置,而`INSERT`则要求一个`VALUES`来完成命令。每个命令的精确语法规则在 http://www.postgresql.org/docs/17/reference.html[第 VI 部分]中介绍。 ==== 标识符和关键词 -上例中的 `SELECT`、`UPDATE` 或 `VALUES` 记号是 *关键词* 的例子,即SQL语言中具有特定意义的词。记号 `MY_TABLE` 和 `A` 则是 *标识符* 的例子。它们标识表、列或者其他数据库对象的名字,取决于使用它们的命令。因此它们有时也被简称为“名字”。关键词和标识符具有相同的词法结构,这意味着我们无法在没有语言知识的前提下区分一个标识符和关键词。一个关键词的完整列表可以在 http://www.postgres.cn/docs/14/sql-keywords-appendix.html[附录 C]中找到。 +上例中的`SELECT`、`UPDATE`或`VALUES`记号是 *关键词* 的例子,即SQL语言中具有特定意义的词。记号`MY_TABLE`和`A`则是 *标识符* 的例子。它们标识表、列或者其他数据库对象的名字,取决于使用它们的命令。因此它们有时也被简称为“名字”。关键词和标识符具有相同的词法结构,这意味着我们无法在没有语言知识的前提下区分一个标识符和关键词。一个关键词的完整列表可以在 http://www.postgresql.org/docs/17/sql-keywords-appendix.html[附录 C]中找到。 -SQL标识符和关键词必须以一个字母(`a`-`z`,也可以是带变音符的字母和非拉丁字母)或一个下划线( _ )开始。后续字符可以是字母、下划线( `_`)、数字(`0`-`9`)或美元符号(`$`)。注意根据SQL标准的字母规定,美元符号是不允许出现在标识符中的,因此它们的使用可能会降低应用的可移植性。SQL标准不会定义包含数字或者以下划线开头或结尾的关键词,因此这种形式的标识符不会与未来可能的标准扩展冲突 。 +SQL标识符和关键词必须以一个字母(`a`-`z`,也可以是带变音符的字母和非拉丁字母)或一个下划线( _ )开始。后续字符可以是字母、下划线(`_`)、数字(`0`-`9`)或美元符号(`$`)。注意根据SQL标准的字母规定,美元符号是不允许出现在标识符中的,因此它们的使用可能会降低应用的可移植性。SQL标准不会定义包含数字或者以下划线开头或结尾的关键词,因此这种形式的标识符不会与未来可能的标准扩展冲突。 -系统中一个标识符的长度不能超过 `NAMEDATALEN`-1 字节,在命令中可以写超过此长度的标识符,但是它们会被截断。默认情况下,`NAMEDATALEN` 的值为64,因此标识符的长度上限为63字节。如果这个限制有问题,可以在 `src/include/pg_config_manual.h` 中修改 `NAMEDATALEN` 常量。 +系统中一个标识符的长度不能超过`NAMEDATALEN`-1字节,在命令中可以写超过此长度的标识符,但是它们会被截断。默认情况下,`NAMEDATALEN`的值为64,因此标识符的长度上限为63字节。如果这个限制有问题,可以在`src/include/pg_config_manual.h`中修改`NAMEDATALEN`常量。 关键词和不被引号修饰的标识符是大小写不敏感的。因此: @@ -927,9 +917,7 @@ uPDaTE my_TabLE SeT a = 5; UPDATE my_table SET a = 5; ``` - - -这里还有第二种形式的标识符:*受限标识符*或*被引号修饰的标识符*。它是由双引号(`"`)包围的一个任意字符序列。一个受限标识符总是一个标识符而不会是一个关键字。因此 `"select"` 可以用于引用一个名为“select”的列或者表,而一个没有引号修饰的 `select` 则会被当作一个关键词,从而在本应使用表或列名的地方引起解析错误。在上例中使用受限标识符的例子如下: +这里还有第二种形式的标识符:*受限标识符*或*被引号修饰的标识符*。它是由双引号(`"`)包围的一个任意字符序列。一个受限标识符总是一个标识符而不会是一个关键字。因此`"select"`可以用于引用一个名为“select”的列或者表,而一个没有引号修饰的`select`则会被当作一个关键词,从而在本应使用表或列名的地方引起解析错误。在上例中使用受限标识符的例子如下: ``` UPDATE "my_table" SET "a" = 5; @@ -937,25 +925,22 @@ UPDATE "my_table" SET "a" = 5; 受限标识符可以包含任何字符,除了代码为0的字符(如果要包含一个双引号,则写两个双引号)。这使得可以构建原本不被允许的表或列的名称,例如包含空格或花号的名字。但是长度限制依然有效。 -引用标识符也使其区分大小写,而未引用的名称总是折叠成小写。例如,标识符 `FOO`、`foo` 和 `"foo"` 在IvorySQL中被认为是相同的,但是 `"Foo"` 和 `"FOO"` 与这三个不同,并且彼此不同。(在IvorySQL中,将不带引号的名称折叠为小写与SQL标准不兼容,SQL标准规定不带引号的名称应折叠为大写。因此,根据标准,`foo` 应等同于 `"FOO"` 而不是 `"foo"`。如果您想编写可移植应用程序,建议您始终引用某个特定的名称,或者永远不要引用它。) +引用标识符也使其区分大小写,而未引用的名称总是折叠成小写。例如,标识符`FOO`、`foo`和`"foo"`在IvorySQL中被认为是相同的,但是`"Foo"`和`"FOO"`与这三个不同,并且彼此不同。(在IvorySQL中,将不带引号的名称折叠为小写与SQL标准不兼容,SQL标准规定不带引号的名称应折叠为大写。因此,根据标准,`foo`应等同于`"FOO"`而不是`"foo"`。如果您想编写可移植应用程序,建议您始终引用某个特定的名称,或者永远不要引用它。) - -一种受限标识符的变体允许包括转义的用代码点标识的Unicode字符。这种变体以 `U&` (大写或小写U跟上一个花号)开始,后面紧跟双引号修饰的名称,两者之间没有任何空白,如 `U&"foo"`(注意这里与操作符 `&` 似乎有一些混淆,但是在`&`操作符周围使用空白避免了这个问题) 。在引号内,Unicode字符可以以转义的形式指定:反斜线接上4位16进制代码点号码或者反斜线和加号接上6位16进制代码点号码。例如,标识符 `"data"` 可以写成: +一种受限标识符的变体允许包括转义的用代码点标识的Unicode字符。这种变体以`U&`(大写或小写U跟上一个花号)开始,后面紧跟双引号修饰的名称,两者之间没有任何空白,如`U&"foo"`(注意这里与操作符`&`似乎有一些混淆,但是在`&`操作符周围使用空白避免了这个问题)。在引号内,Unicode字符可以以转义的形式指定:反斜线接上4位16进制代码点号码或者反斜线和加号接上6位16进制代码点号码。例如,标识符`"data"`可以写成: ``` U&"d\0061t\+000061" ``` -下面的例子用斯拉夫语字母写出了俄语单词 “slon”(大象): +下面的例子用斯拉夫语字母写出了俄语单词“slon”(大象): ``` U&"\0441\043B\043E\043D" ``` - - -如果希望使用其他转义字符来代替反斜线,可以在字符串后使用 `UESCAPE` 子句,例如: +如果希望使用其他转义字符来代替反斜线,可以在字符串后使用`UESCAPE`子句,例如: ``` U&"d!0061t!+000061" UESCAPE '!' @@ -975,7 +960,7 @@ U&"d!0061t!+000061" UESCAPE '!' ===== 字符串常量 -在SQL中,一个字符串常量是一个由单引号( `'` )包围的任意字符序列,例如 `'This is a string'`。为了在一个字符串中包括一个单引号,可以写两个相连的单引号,例如 `'Dianne''s horse'`。注意这和一个双引号( `"` )**不**同。 +在SQL中,一个字符串常量是一个由单引号( `'` )包围的任意字符序列,例如`'This is a string'`。为了在一个字符串中包括一个单引号,可以写两个相连的单引号,例如`'Dianne''s horse'`。注意这和一个双引号(`"`)**不**同。 两个只由空白及**至少一个新行**分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -1000,7 +985,7 @@ SELECT 'foo' 'bar'; ===== C风格转义的字符串常量 -IvorySQL也接受“转义”字符串常量,这也是SQL标准的一个扩展。一个转义字符串常量可以通过在开单引号前面写一个字母 `E`(大写或小写形式)来指定,例如 `E'foo'`(当一个转义字符串常量跨行时,只在第一个开引号之前写 `E` )。在一个转义字符串内部,一个反斜线字符( `\` )会开始一个 C 风格的 *反斜线转义* 序列,在其中反斜线和后续字符的组合表示一个特殊的字节值(如 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-BACKSLASH-TABLE[表 4.1] 中所示)。 +IvorySQL也接受“转义”字符串常量,这也是SQL标准的一个扩展。一个转义字符串常量可以通过在开单引号前面写一个字母`E`(大写或小写形式)来指定,例如`E'foo'`(当一个转义字符串常量跨行时,只在第一个开引号之前写`E`)。在一个转义字符串内部,一个反斜线字符(`\`)会开始一个C风格的 *反斜线转义* 序列,在其中反斜线和后续字符的组合表示一个特殊的字节值(如 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-BACKSLASH-TABLE[表 4.1]中所示)。 **表 4.1. 反斜线转义序列** |==== @@ -1015,18 +1000,18 @@ IvorySQL也接受“转义”字符串常量,这也是SQL标准的一个扩展 | `\u*`xxxx`*`, `\U*`xxxxxxxx`*` (*`x`* = 0–9, A–F) | 16 或 32-位十六进制 Unicode 字符值 |==== -跟随在一个反斜线后面的任何其他字符被当做其字面意思。因此,要包括一个反斜线字符,请写两个反斜线( `\\` )。在一个转义字符串中包括一个单引号除了普通方法 `''` 之外,还可以写成 `\'` 。 +跟随在一个反斜线后面的任何其他字符被当做其字面意思。因此,要包括一个反斜线字符,请写两个反斜线(`\\`)。在一个转义字符串中包括一个单引号除了普通方法`''`之外,还可以写成`\'`。 -你要负责保证你创建的字节序列由服务器字符集编码中合法的字符组成,特别是在使用八进制或十六进制转义时。一个有用的替代方法是使用Unicode转义或替代的Unicode转义语法,如 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE[第 4.1.2.3 节] 中所述;然后服务器将检查字符转换是否可行。 +你要负责保证你创建的字节序列由服务器字符集编码中合法的字符组成,特别是在使用八进制或十六进制转义时。一个有用的替代方法是使用Unicode转义或替代的Unicode转义语法,如 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE[第 4.1.2.3 节]中所述;然后服务器将检查字符转换是否可行。 .小心 **** -如果配置参数 http://www.postgres.cn/docs/14/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings] 为 `off` ,那么IvorySQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从IvorySQL 9.1 开始,该参数的默认值为 `on` ,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为 `off` ,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个 `E`。在 `standard_conforming_strings` 之外,配置参数 http://www.postgres.cn/docs/14/runtime-config-compatible.html#GUC-ESCAPE-STRING-WARNING[escape_string_warning] 和 http://www.postgres.cn/docs/14/runtime-config-compatible.html#GUC-BACKSLASH-QUOTE[backslash_quote] 也决定了如何对待字符串常量中的反斜线。代码零的字符不能出现在一个字符串常量中。 +如果配置参数 http://www.postgresql.org/docs/17/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings]为`off`,那么IvorySQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,在IvorySQL中该参数的默认值为`on`,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为`off`,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个`E`。在`standard_conforming_strings`之外,配置参数 http://www.postgresql.org/docs/17/runtime-config-compatible.html#GUC-ESCAPE-STRING-WARNING[escape_string_warning]和 http://www.postgresql.org/docs/17/runtime-config-compatible.html#GUC-BACKSLASH-QUOTE[backslash_quote]也决定了如何对待字符串常量中的反斜线。代码零的字符不能出现在一个字符串常量中。 **** ===== 带有 Unicode 转义的字符串常量 -IvorySQL也支持另一种类型的字符串转义语法,它允许用代码点指定任意 Unicode 字符。一个 Unicode 转义字符串常量开始于 `U&` (大写或小写形式的字母 U,后跟花号),后面紧跟着开引号,之间没有任何空白,例如 `U&'foo'` (注意这产生了与操作符 `&` 的混淆。在操作符周围使用空白来避免这个问题)。在引号内,Unicode 字符可以通过写一个后跟 4 位十六进制代码点编号或者一个前面有加号的 6 位十六进制代码点编号的反斜线来指定。例如,字符串 `'data'` 可以被写为 +IvorySQL也支持另一种类型的字符串转义语法,它允许用代码点指定任意Unicode字符。一个Unicode转义字符串常量开始于`U&`(大写或小写形式的字母U,后跟花号),后面紧跟着开引号,之间没有任何空白,例如`U&'foo'`(注意这产生了与操作符`&`的混淆。在操作符周围使用空白来避免这个问题)。在引号内,Unicode字符可以通过写一个后跟4位十六进制代码点编号或者一个前面有加号的6位十六进制代码点编号的反斜线来指定。例如,字符串`'data'`可以被写为 ``` U&'d\0061t\+000061' @@ -1039,8 +1024,7 @@ U&'\0441\043B\043E\043D' ``` - -如果想要一个不是反斜线的转义字符,可以在字符串之后使用 `UESCAPE` 子句来指定,例如: +如果想要一个不是反斜线的转义字符,可以在字符串之后使用`UESCAPE`子句来指定,例如: ``` U&'d!0061t!+000061' UESCAPE '!' @@ -1050,15 +1034,15 @@ U&'d!0061t!+000061' UESCAPE '!' 要在一个字符串中包括一个表示其字面意思的转义字符,把它写两次。 -4位或6位转义形式可用于指定UTF-16代理项对,以组成代码点大于U+FFFF的字符,尽管从技术上讲,6位形式的可用性使得这是不必要的(代理项对不是直接存储的,而是合并到单个代码点中。) +4位或6位转义形式可用于指定UTF-16代理项对,以组成代码点大于U+FFFF的字符,尽管从技术上讲,6位形式的可用性使得这是不必要的(代理项对不是直接存储的,而是合并到单个代码点中。) -如果服务器编码不是 UTF-8,则由这些转义序列之一标识的 Unicode 代码点将转换为实际的服务器编码; 如果不可能,则会报告错误。 +如果服务器编码不是UTF-8,则由这些转义序列之一标识的Unicode代码点将转换为实际的服务器编码;如果不可能,则会报告错误。 -此外,字符串常量的 Unicode 转义语法仅在配置参数 http://www.postgres.cn/docs/14/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings] 开启时才有效。 这是因为否则这种语法可能会混淆解析 SQL 语句的客户端,可能导致 SQL 注入和类似的安全问题。 如果该参数设置为 off,则此语法将被拒绝并显示错误消息。 +此外,字符串常量的Unicode转义语法仅在配置参数 http://www.postgresql.org/docs/17/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings]开启时才有效。这是因为否则这种语法可能会混淆解析SQL语句的客户端,可能导致SQL注入和类似的安全问题。如果该参数设置为off,则此语法将被拒绝并显示错误消息。 ===== 美元引用的字符串常量 -虽然用于指定字符串常量的标准语法通常都很方便,但是当字符串中包含了很多单引号或反斜线时很难理解它,因为每一个都需要被双写。要在这种情形下允许可读性更好的查询,IvorySQL提供了另一种被称为“美元引用”的方式来书写字符串常量。一个美元引用的字符串常量由一个美元符号( `$` )、一个可选的另个或更多字符的“标签”、另一个美元符号、一个构成字符串内容的任意字符序列、一个美元符号、开始这个美元引用的相同标签和一个美元符号组成。例如,这里有两种不同的方法使用美元引用指定字符串“Dianne's horse”: +虽然用于指定字符串常量的标准语法通常都很方便,但是当字符串中包含了很多单引号或反斜线时很难理解它,因为每一个都需要被双写。要在这种情形下允许可读性更好的查询,IvorySQL提供了另一种被称为“美元引用”的方式来书写字符串常量。一个美元引用的字符串常量由一个美元符号(`$`)、一个可选的另个或更多字符的“标签”、另一个美元符号、一个构成字符串内容的任意字符序列、一个美元符号、开始这个美元引用的相同标签和一个美元符号组成。例如,这里有两种不同的方法使用美元引用指定字符串“Dianne's horse”: ``` $$Dianne's horse$$ @@ -1077,9 +1061,9 @@ END; $function$ ``` -这里,序列 `$q$[\t\r\n\v\\]$q$` 表示一个美元引用的文字串 `[\t\r\n\v\\]`,当该函数体被IvorySQL执行时它将被识别。但是因为该序列不匹配外层的美元引用的定界符 `$function$`,它只是一些在外层字符串所关注的常量中的字符而已。 +这里,序列`$q$[\t\r\n\v\\]$q$`表示一个美元引用的文字串`[\t\r\n\v\\]`,当该函数体被IvorySQL执行时它将被识别。但是因为该序列不匹配外层的美元引用的定界符`$function$`,它只是一些在外层字符串所关注的常量中的字符而已。 -一个美元引用字符串的标签(如果有)遵循一个未被引用标识符的相同规则,除了它不能包含一个美元符号之外。标签是大小写敏感的,因此 `$tag$String content$tag$` 是正确的,但是 `$TAG$String content$tag$` 不正确。 +一个美元引用字符串的标签(如果有)遵循一个未被引用标识符的相同规则,除了它不能包含一个美元符号之外。标签是大小写敏感的,因此`$tag$String content$tag$`是正确的,但是`$TAG$String content$tag$`不正确。 一个跟着一个关键词或标识符的美元引用字符串必须用空白与之分隔开,否则美元引用定界符可能会被作为前面标识符的一部分。 @@ -1087,9 +1071,9 @@ $function$ ===== 位串常量 -位串常量看起来像常规字符串常量在开引号之前(中间无空白)加了一个 `B`(大写或小写形式),例如 `B'1001'` 。位串常量中允许的字符只有 `0` 和 `1` 。 +位串常量看起来像常规字符串常量在开引号之前(中间无空白)加了一个`B`(大写或小写形式),例如`B'1001'`。位串常量中允许的字符只有`0`和`1`。 -作为一种选择,位串常量可以用十六进制记号法指定,使用一个前导 `X`(大写或小写形式),例如 `X'1FF'`。这种记号法等价于一个用四个二进制位取代每个十六进制位的位串常量。 +作为一种选择,位串常量可以用十六进制记号法指定,使用一个前导`X`(大写或小写形式),例如`X'1FF'`。这种记号法等价于一个用四个二进制位取代每个十六进制位的位串常量。 两种形式的位串常量可以以常规字符串常量相同的方式跨行继续。美元引用不能被用在位串常量中。 @@ -1104,7 +1088,7 @@ digits.[digits][e[+-]digits] digitse[+-]digits ``` -其中 *`digits`* 是一个或多个十进制数字(0 到 9)。如果使用了小数点,在小数点前面或后面必须至少有一个数字。如果存在一个指数标记( `e` ),在其后必须跟着至少一个数字。在该常量中不能嵌入任何空白或其他字符。注意任何前导的加号或减号并不实际被考虑为常量的一部分,它是一个应用到该常量的操作符。 +其中 *`digits`* 是一个或多个十进制数字(0到9)。如果使用了小数点,在小数点前面或后面必须至少有一个数字。如果存在一个指数标记(`e`),在其后必须跟着至少一个数字。在该常量中不能嵌入任何空白或其他字符。注意任何前导的加号或减号并不实际被考虑为常量的一部分,它是一个应用到该常量的操作符。 这些是合法数字常量的例子: @@ -1118,9 +1102,9 @@ digitse[+-]digits ---- -如果一个不包含小数点和指数的数字常量的值适合类型 `integer` (32 位),它首先被假定为类型 `integer` 。否则如果它的值适合类型 `bigint` (64 位),它被假定为类型 `bigint` 。再否则它会被取做类型 `numeric` 。包含小数点和/或指数的常量总是首先被假定为类型 `numeric` 。 +如果一个不包含小数点和指数的数字常量的值适合类型`integer`(32 位),它首先被假定为类型`integer`。否则如果它的值适合类型`bigint`(64 位),它被假定为类型`bigint`。再否则它会被取做类型`numeric`。包含小数点和/或指数的常量总是首先被假定为类型`numeric`。 -一个数字常量初始指派的数据类型只是类型转换算法的一个开始点。在大部分情况中,常量将被根据上下文自动被强制到最合适的类型。必要时,你可以通过造型它来强制一个数字值被解释为一种指定数据类型。例如,你可以这样强制一个数字值被当做类型 `real` ( `float4` ): +一个数字常量初始指派的数据类型只是类型转换算法的一个开始点。在大部分情况中,常量将被根据上下文自动被强制到最合适的类型。必要时,你可以通过造型它来强制一个数字值被解释为一种指定数据类型。例如,你可以这样强制一个数字值被当做类型`real`(`float4`): ``` REAL '1.23' -- string style @@ -1141,7 +1125,7 @@ CAST ( 'string' AS type ) 字符串常量的文本被传递到名为 *`type`* 的类型的输入转换例程中。其结果是指定类型的一个常量。如果对该常量的类型没有歧义(例如,当它被直接指派给一个表列时),显式类型造型可以被忽略,在那种情况下它会被自动强制。 -字符串常量可以使用常规 SQL 记号或美元引用书写。 +字符串常量可以使用常规SQL记号或美元引用书写。 也可以使用一个类似函数的语法来指定一个类型强制: @@ -1149,15 +1133,15 @@ CAST ( 'string' AS type ) typename ( 'string' ) ``` -但是并非所有类型名都可以用在这种方法中,详见 http://www.postgres.cn/docs/14/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节]。 +但是并非所有类型名都可以用在这种方法中,详见 http://www.postgresql.org/docs/17/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节]。 -如 http://www.postgres.cn/docs/14/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节] 中讨论的,`::`、`CAST()` 以及函数调用语法也可以被用来指定任意表达式的运行时类型转换。要避免语法歧义,`*type 'string'*` 语法只能被用来指定简单文字常量的类型。`*type 'string'*` 语法上的另一个限制是它无法对数组类型工作,指定一个数组常量的类型可使用 `::` 或 `CAST()` 。 +如 http://www.postgresql.org/docs/17/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节]中讨论的,`::`、`CAST()`以及函数调用语法也可以被用来指定任意表达式的运行时类型转换。要避免语法歧义,`*type 'string'*`语法只能被用来指定简单文字常量的类型。`*type 'string'*` 语法上的另一个限制是它无法对数组类型工作,指定一个数组常量的类型可使用`::`或`CAST()`。 -`CAST()` 语法符合SQL。`type 'string'` 语法是该标准的一般化:SQL指定这种语法只用于一些数据类型,但是IvorySQL允许它用于所有类型。带有 `::` 的语法是IvorySQL的历史用法,就像函数调用语法一样。 +`CAST()`语法符合SQL。`type 'string'`语法是该标准的一般化:SQL指定这种语法只用于一些数据类型,但是IvorySQL允许它用于所有类型。带有`::`的语法是IvorySQL的历史用法,就像函数调用语法一样。 ==== 操作符 -一个操作符名是最多 `NAMEDATALEN` -1(默认为 63)的一个字符序列,其中的字符来自下面的列表: +一个操作符名是最多`NAMEDATALEN`-1(默认为63)的一个字符序列,其中的字符来自下面的列表: ---- \+ - * / < > = ~ ! @ # % ^ & | ` ? @@ -1165,18 +1149,17 @@ typename ( 'string' ) 不过,在操作符名上有一些限制: -- `--` 和 `/*` 不能在一个操作符名的任何地方出现,因为它们将被作为一段注释的开始。 +- `--`和`/*`不能在一个操作符名的任何地方出现,因为它们将被作为一段注释的开始。 -- 一个多字符操作符名不能以 `+` 或 `-` 结尾,除非该名称也至少包含这些字符中的一个: +- 一个多字符操作符名不能以`+`或`-`结尾,除非该名称也至少包含这些字符中的一个: ~ ! @ # % ^ & | ` ? -例如,`@-` 是一个被允许的操作符名,但 `*-` 不是。这些限制允许IvorySQL解析 SQL 兼容的查询而不需要在记号之间有空格。 - +例如,`@-`是一个被允许的操作符名,但`*-`不是。这些限制允许IvorySQL解析SQL兼容的查询而不需要在记号之间有空格。 -当使用非 SQL 标准的操作符名时,你通常需要用空格分隔相邻的操作符来避免歧义。例如,如果你定义了一个名为 `@` 的前缀操作符,你不能写 `X*@Y`,你必须写 `X* @Y` 来确保IvorySQL把它读作两个操作符名而不是一个。 +当使用非SQL标准的操作符名时,你通常需要用空格分隔相邻的操作符来避免歧义。例如,如果你定义了一个名为`@`的前缀操作符,你不能写`X*@Y`,你必须写`X* @Y`来确保IvorySQL把它读作两个操作符名而不是一个。 ==== 特殊字符 @@ -1184,10 +1167,10 @@ typename ( 'string' ) - 跟随在一个美元符号( `$` )后面的数字被用来表示在一个函数定义或一个预备语句中的位置参数。在其他上下文中该美元符号可以作为一个标识符或者一个美元引用字符串常量的一部分。 - 圆括号( `()` )具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 -- 方括号( `[]` )被用来选择一个数组中的元素。更多关于数组的信息见 http://www.postgres.cn/docs/14/arrays.html[第 8.15 节]。 +- 方括号( `[]` )被用来选择一个数组中的元素。更多关于数组的信息见 http://www.postgresql.org/docs/17/arrays.html[第 8.15 节]。 - 逗号( `,` )被用在某些语法结构中来分割一个列表的元素。 - 分号( `;` )结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 -- 冒号( `:` )被用来从数组中选择“切片”(见 http://www.postgres.cn/docs/14/arrays.html[第 8.15 节])。在某些 SQL 的“方言”(例如嵌入式 SQL)中,冒号被用来作为变量名的前缀。 +- 冒号( `:` )被用来从数组中选择“切片”(见 http://www.postgresql.org/docs/17/arrays.html[第 8.15 节])。在某些 SQL 的“方言”(例如嵌入式 SQL)中,冒号被用来作为变量名的前缀。 - 星号( `*` )被用在某些上下文中标记一个表的所有域或者组合值。当它被用作一个聚集函数的参数时,它还有一种特殊的含义,即该聚集不要求任何显式参数。 - 句点( `.` )被用在数字常量中,并且被用来分割模式、表和列名。 @@ -1207,13 +1190,13 @@ typename ( 'string' ) */ ``` -这里该注释开始于 `/*` 并且延伸到匹配出现的 `*/`。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 +这里该注释开始于 `/*` 并且延伸到匹配出现的 `*/`。这些注释块可按照SQL标准中指定的方式嵌套,但和C中不同。这样我们可以注释掉一大段可能包含注释块的代码。 在进一步的语法分析前,注释会被从输入流中被移除并且实际被替换为空白。 ===== 操作符优先级 -http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE[表 4.2] 显示了IvorySQL中操作符的优先级和结合性。大部分操作符具有相同的优先并且是左结合的。操作符的优先级和结合性被硬写在解析器中。 如果您希望以不同于优先级规则所暗示的方式解析具有多个运算符的表达式,请添加括号。 +http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE[表 4.2]显示了IvorySQL中操作符的优先级和结合性。大部分操作符具有相同的优先并且是左结合的。操作符的优先级和结合性被硬写在解析器中。如果您希望以不同于优先级规则所暗示的方式解析具有多个运算符的表达式,请添加括号。 **表 4.2. 操作符优先级(从高到低)** |==== @@ -1242,16 +1225,16 @@ http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE[表 SELECT 3 OPERATOR(pg_catalog.+) 4; ``` -`OPERATOR`结构被用来为“任意其他操作符”获得 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE[表 4.2] 中默认的优先级。不管出现在`OPERATOR()`中的是哪个指定操作符,这都是真的。 +`OPERATOR`结构被用来为“任意其他操作符”获得 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE[表 4.2]中默认的优先级。不管出现在`OPERATOR()`中的是哪个指定操作符,这都是真的。 .注意 **** -版本 9.5 之前的IvorySQL使用的操作符优先级 规则略有不同。特别是,`<=`、`>=` 和 `<>` 习惯于被当作普通操作符,`IS` 测试习惯于具有较高的优先级。并且在一些认为 `NOT` 比 `BETWEEN` 优先级高的情况下,`NOT BETWEEN` 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, 这些变化不会导致行为上的变化,或者可能会产生“no such operator” 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 没有被报告解析错误的情况下发生行为的改变。 +版本9.5之前的PostgreSQL使用的操作符优先级规则略有不同。特别是,`<=`、`>=` 和 `<>`习惯于被当作普通操作符,`IS`测试习惯于具有较高的优先级。并且在一些认为`NOT`比`BETWEEN`优先级高的情况下,`NOT BETWEEN`和相关的结构的行为不一致。为了更好地兼容SQL标准并且减少对 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下,这些变化不会导致行为上的变化,或者可能会产生“no such operator”错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在没有被报告解析错误的情况下发生行为的改变。 **** === 值表达式 -值表达式被用于各种各样的环境中,例如在 `SELECT` 命令的目标列表中、作为 `INSERT` 或 `UPDATE` 中的新列值或者若干命令中的搜索条件。为了区别于一个表表达式(是一个表)的结果,一个值表达式的结果有时候被称为一个 *标量*。值表达式因此也被称为 *标量表达式*(或者甚至简称为 *表达式*)。表达式语法允许使用算数、逻辑、集合和其他操作从原始部分计算值。 +值表达式被用于各种各样的环境中,例如在`SELECT`命令的目标列表中、作为`INSERT`或`UPDATE`中的新列值或者若干命令中的搜索条件。为了区别于一个表表达式(是一个表)的结果,一个值表达式的结果有时候被称为一个 *标量*。值表达式因此也被称为 *标量表达式*(或者甚至简称为 *表达式*)。表达式语法允许使用算数、逻辑、集合和其他操作从原始部分计算值。 一个值表达式是下列之一: @@ -1271,9 +1254,9 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - 一个行构造器 - 另一个在圆括号(用来分组子表达式以及重载优先级)中的值表达式 -在这个列表之外,还有一些结构可以被分类为一个表达式,但是它们不遵循任何一般语法规则。这些通常具有一个函数或操作符的语义并且在 http://www.postgres.cn/docs/14/functions.html[第 9 章] 中的合适位置解释。一个例子是 `IS NULL` 子句。 +在这个列表之外,还有一些结构可以被分类为一个表达式,但是它们不遵循任何一般语法规则。这些通常具有一个函数或操作符的语义并且在 http://www.postgresql.org/docs/17/functions.html[第 9 章]中的合适位置解释。一个例子是`IS NULL`子句。 -我们已经在 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS[第 4.1.2 节] 中讨论过常量。下面的小节会讨论剩下的选项。 +我们已经在 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS[第 4.1.2 节]中讨论过常量。下面的小节会讨论剩下的选项。 ==== 列引用 @@ -1284,20 +1267,18 @@ correlation.columnname ``` - -*`correlation`* 是一个表(有可能以一个模式名限定)的名字,或者是在 `FROM` 子句中为一个表定义的别名。如果列名在当前索引所使用的表中都是唯一的,关联名称和分隔用的句点可以被忽略(另见 http://www.postgres.cn/docs/14/queries.html[第 7 章])。 +*`correlation`* 是一个表(有可能以一个模式名限定)的名字,或者是在`FROM`子句中为一个表定义的别名。如果列名在当前索引所使用的表中都是唯一的,关联名称和分隔用的句点可以被忽略(另见 http://www.postgresql.org/docs/17/queries.html[第 7 章])。 ==== 位置参数 -一个位置参数引用被用来指示一个由 SQL 语句外部提供的值。参数被用于 SQL 函数定义和预备查询中。某些客户端库还支持独立于 SQL 命令字符串来指定数据值,在这种情况中参数被用来引用那些线外数据值。一个参数引用的形式是: +一个位置参数引用被用来指示一个由SQL语句外部提供的值。参数被用于SQL函数定义和预备查询中。某些客户端库还支持独立于SQL命令字符串来指定数据值,在这种情况中参数被用来引用那些线外数据值。一个参数引用的形式是: ``` $number ``` - -例如,考虑一个函数 `dept` 的定义: +例如,考虑一个函数`dept`的定义: ``` CREATE FUNCTION dept(text) RETURNS dept @@ -1332,11 +1313,11 @@ $1[10:42] (arrayfunction(a,b))[42] ``` -最后一个例子中的圆括号是必需的。详见 http://www.postgres.cn/docs/14/arrays.html[第 8.15 节]。 +最后一个例子中的圆括号是必需的。详见 http://www.postgresql.org/docs/17/arrays.html[第 8.15 节]。 ==== 域选择 -如果一个表达式得到一个组合类型(行类型)的值,那么可以抽取该行的指定域 +如果一个表达式得到一个组合类型(行类型)的值,那么可以抽取该行的指定域: ``` expression.fieldname @@ -1367,7 +1348,7 @@ $1.somecolumn (compositecol).* ``` -这种记法的行为根据上下文会有不同,详见 http://www.postgres.cn/docs/14/rowtypes.html#ROWTYPES-USAGE[第 8.16.5 节]。 +这种记法的行为根据上下文会有不同,详见 http://www.postgresql.org/docs/17/rowtypes.html#ROWTYPES-USAGE[第 8.16.5 节]。 ==== 操作符调用 @@ -1377,13 +1358,13 @@ $1.somecolumn | *`operator`* *`expression`*(一元前缀操作符) |==== -其中 *`operator`* 记号遵循 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS[第 4.1.3 节] 的语法规则,或者是关键词`AND`、`OR`和`NOT`之一,或者是一个如下形式的受限定操作符名: +其中 *`operator`* 记号遵循 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS[第 4.1.3 节] 的语法规则,或者是关键词`AND`、`OR`和`NOT`之一,或者是一个如下形式的受限定操作符名: ``` OPERATOR(schema.operatorname) ``` -哪个特定操作符存在以及它们是一元的还是二元的取决于由系统或用户定义的那些操作符。 http://www.postgres.cn/docs/14/functions.html[第 9 章] 描述了内建操作符。 +哪个特定操作符存在以及它们是一元的还是二元的取决于由系统或用户定义的那些操作符。 http://www.postgresql.org/docs/17/functions.html[第 9 章] 描述了内建操作符。 ==== 函数调用 @@ -1394,7 +1375,6 @@ function_name ([expression [, expression ... ]] ) ``` - 例如,下面会计算 2 的平方根: ``` @@ -1402,12 +1382,11 @@ sqrt(2) ``` +当在一个某些用户不信任其他用户的数据库中发出查询时,在编写函数调用时应遵守 http://www.postgresql.org/docs/17/typeconv-func.html[第 10.3 节] 中的安全防范措施。 -当在一个某些用户不信任其他用户的数据库中发出查询时,在编写函数调用时应遵守 http://www.postgres.cn/docs/14/typeconv-func.html[第 10.3 节] 中的安全防范措施。 - -内建函数的列表在 http://www.postgres.cn/docs/14/functions.html[第 9 章] 中。其他函数可以由用户增加。 +内建函数的列表在 http://www.postgresql.org/docs/17/functions.html[第 9 章] 中。其他函数可以由用户增加。 -参数可以有选择地被附加名称。详见 http://www.postgres.cn/docs/14/sql-syntax-calling-funcs.html[第 4.3 节]。 +参数可以有选择地被附加名称。详见 http://www.postgresql.org/docs/17/sql-syntax-calling-funcs.html[第 4.3 节]。 .注意 **** @@ -1435,14 +1414,13 @@ aggregate_name ( [ expression [ , ... ] ] ) WITHIN GROUP ( order_by_clause ) [ F 例如,`count(*)` 得到输入行的总数。 `count(f1)` 得到输入行中 `f1` 为非空的数量,因为 `count` 忽略空值。而 `count(distinct f1)` 得到 `f1` 的非空可区分值的数量。 -一般地,交给聚集函数的输入行是未排序的。在很多情况中这没有关系,例如不管接收到什么样的输入, `min` 总是产生相同的结果。但是,某些聚集函数(例如 `array_agg` 和 `string_agg` )依据输入行的排序产生结果。当使用这类聚集时,可选的 *`order_by_clause`* 可以被用来指定想要的顺序。*`order_by_clause`* 与查询级别的 `ORDER BY` 子句(如 http://www.postgres.cn/docs/14/queries-order.html[第 7.5 节] 所述)具有相同的语法,除非它的表达式总是仅有表达式并且不能是输出列名称或编号。例如: +一般地,交给聚集函数的输入行是未排序的。在很多情况中这没有关系,例如不管接收到什么样的输入, `min` 总是产生相同的结果。但是,某些聚集函数(例如 `array_agg` 和 `string_agg` )依据输入行的排序产生结果。当使用这类聚集时,可选的 *`order_by_clause`* 可以被用来指定想要的顺序。*`order_by_clause`* 与查询级别的 `ORDER BY` 子句(如 http://www.postgresql.org/docs/17/queries-order.html[第 7.5 节] 所述)具有相同的语法,除非它的表达式总是仅有表达式并且不能是输出列名称或编号。例如: ``` SELECT array_agg(a ORDER BY b DESC) FROM table; ``` - 在处理多参数聚集函数时,注意 `ORDER BY` 出现在所有聚集参数之后。例如,要这样写: ``` @@ -1488,11 +1466,11 @@ FROM generate_series(1,10) AS s(i); (1 row) ``` -预定义的聚集函数在 http://www.postgres.cn/docs/14/functions-aggregate.html[第 9.21 节] 中描述。其他聚集函数可以由用户增加。 +预定义的聚集函数在 http://www.postgresql.org/docs/17/functions-aggregate.html[第 9.21 节] 中描述。其他聚集函数可以由用户增加。 一个聚集表达式只能出现在 `SELECT` 命令的结果列表或是 `HAVING` 子句中。在其他子句(如 `WHERE` )中禁止使用它,因为那些子句的计算在逻辑上是在聚集的结果被形成之前。 -当一个聚集表达式出现在一个子查询中(见 http://www.postgres.cn/docs/14/sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES[第 4.2.11 节] 和 http://www.postgres.cn/docs/14/functions-subquery.html[第 9.23 节]),聚集通常在该子查询的行上被计算。但是如果该聚集的参数(以及 *`filter_clause`*,如果有)只包含外层变量则会产生一个异常:该聚集则属于最近的那个外层,并且会在那个查询的行上被计算。该聚集表达式从整体上则是对其所出现于的子查询的一种外层引用,并且在那个子查询的任意一次计算中都作为一个常量。只出现在结果列表或 `HAVING` 子句的限制适用于该聚集所属的查询层次。 +当一个聚集表达式出现在一个子查询中(见 http://www.postgresql.org/docs/17/sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES[第 4.2.11 节] 和 http://www.postgresql.org/docs/17/functions-subquery.html[第 9.23 节]),聚集通常在该子查询的行上被计算。但是如果该聚集的参数(以及 *`filter_clause`*,如果有)只包含外层变量则会产生一个异常:该聚集则属于最近的那个外层,并且会在那个查询的行上被计算。该聚集表达式从整体上则是对其所出现于的子查询的一种外层引用,并且在那个子查询的任意一次计算中都作为一个常量。只出现在结果列表或 `HAVING` 子句的限制适用于该聚集所属的查询层次。 ==== 窗口函数调用 @@ -1544,7 +1522,7 @@ EXCLUDE NO OTHERS 这里,*`expression`* 表示任何自身不含有窗口函数调用的值表达式。 -*`window_name`* 是对定义在查询的 `WINDOW` 子句中的一个命名窗口声明的引用。还可以使用在 `WINDOW` 子句中定义命名窗口的相同语法在圆括号内给定一个完整的 *`window_definition`*,详见 http://www.postgres.cn/docs/14/sql-select.html[SELECT] 参考页。值得指出的是,`OVER wname` 并不严格地等价于 `OVER (wname ...)`,后者表示复制并修改窗口定义,并且在被引用窗口声明包括一个帧子句时会被拒绝。 +*`window_name`* 是对定义在查询的 `WINDOW` 子句中的一个命名窗口声明的引用。还可以使用在 `WINDOW` 子句中定义命名窗口的相同语法在圆括号内给定一个完整的 *`window_definition`*,详见 http://www.postgresql.org/docs/17/sql-select.html[SELECT] 参考页。值得指出的是,`OVER wname` 并不严格地等价于 `OVER (wname ...)`,后者表示复制并修改窗口定义,并且在被引用窗口声明包括一个帧子句时会被拒绝。 `PARTITION BY` 选项将查询的行分组成为 *分区*,窗口函数会独立地处理它们。`PARTITION BY` 工作起来类似于一个查询级别的 `GROUP BY` 子句,不过它的表达式总是只是表达式并且不能是输出列的名称或编号。如果没有 `PARTITION BY`,该查询产生的所有行被当作一个单一分区来处理。`ORDER BY` 选项决定被窗口函数处理的一个分区中的行的顺序。它工作起来类似于一个查询级别的 `ORDER BY` 子句,但是同样不能使用输出列的名称或编号。如果没有 `ORDER BY`,行将被以未指定的顺序被处理。 @@ -1572,13 +1550,13 @@ EXCLUDE NO OTHERS 如果指定了 `FILTER` ,那么只有对 *`filter_clause`* 计算为真的输入行会被交给该窗口函数,其他行会被丢弃。只有是聚集的窗口函数才接受 `FILTER` 。 -内建的窗口函数在 http://www.postgres.cn/docs/14/functions-window.html#FUNCTIONS-WINDOW-TABLE[表 9.60] 中介绍。用户可以加入其他窗口函数。此外,任何内建的或者用户定义的通用聚集或者统计性聚集都可以被用作窗口函数(有序集和假想集聚集当前不能被用作窗口函数)。 +内建的窗口函数在 http://www.postgresql.org/docs/17/functions-window.html#FUNCTIONS-WINDOW-TABLE[表 9.60] 中介绍。用户可以加入其他窗口函数。此外,任何内建的或者用户定义的通用聚集或者统计性聚集都可以被用作窗口函数(有序集和假想集聚集当前不能被用作窗口函数)。 使用 `\*` 的语法被用来把参数较少的聚集函数当作窗口函数调用,例如 `count(*) OVER (PARTITION BY x ORDER BY y)`。星号(`*`)通常不被用于窗口相关的函数。窗口相关的函数不允许在函数参数列表中用 `DISTINCT` 或 `ORDER BY`。 只有在 `SELECT` 列表和查询的 `ORDER BY` 子句中才允许窗口函数调用。 -更多关于窗口函数的信息可以在 http://www.postgres.cn/docs/14/tutorial-window.html[第 3.5 节]、 http://www.postgres.cn/docs/14/functions-window.html[第 9.22 节] 以及 http://www.postgres.cn/docs/14/queries-table-expressions.html#QUERIES-WINDOW[第 7.2.5 节] 中找到。 +更多关于窗口函数的信息可以在 http://www.postgresql.org/docs/17/tutorial-window.html[第 3.5 节]、 http://www.postgresql.org/docs/17/functions-window.html[第 9.22 节] 以及 http://www.postgresql.org/docs/17/queries-table-expressions.html#QUERIES-WINDOW[第 7.2.5 节] 中找到。 ==== 类型转换 @@ -1591,7 +1569,7 @@ expression::type `CAST` 语法遵从 SQL,而用 `::` 的语法是IvorySQL的历史用法。 -当一个造型被应用到一种未知类型的值表达式上时,它表示一种运行时类型转换。只有已经定义了一种合适的类型转换操作时,该造型才会成功。注意这和常量的造型(如 http://www.postgres.cn/docs/14/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC[第 4.1.2.7 节] 中所示)使用不同。应用于一个未修饰串文字的造型表示一种类型到一个文字常量值的初始赋值,并且因此它将对任意类型都成功(如果该串文字的内容对于该数据类型的输入语法是可接受的)。 +当一个造型被应用到一种未知类型的值表达式上时,它表示一种运行时类型转换。只有已经定义了一种合适的类型转换操作时,该造型才会成功。注意这和常量的造型(如 http://www.postgresql.org/docs/17/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC[第 4.1.2.7 节] 中所示)使用不同。应用于一个未修饰串文字的造型表示一种类型到一个文字常量值的初始赋值,并且因此它将对任意类型都成功(如果该串文字的内容对于该数据类型的输入语法是可接受的)。 如果一个值表达式必须产生的类型没有歧义(例如当它被指派给一个表列),通常可以省略显式类型造型,在这种情况下系统会自动应用一个类型造型。但是,只有对在系统目录中被标记为“OK to apply implicitly”的造型才会执行自动造型。其他造型必须使用显式造型语法调用。这种限制是为了防止出人意料的转换被无声无息地应用。 @@ -1605,7 +1583,7 @@ typename ( expression ) .注意 **** -函数风格的语法事实上只是一次函数调用。当两种标准造型语法之一被用来做一次运行时转换时,它将在内部调用一个已注册的函数来执行该转换。简而言之,这些转换函数具有和它们的输出类型相同的名字,并且因此“函数风格的语法”无非是对底层转换函数的一次直接调用。显然,一个可移植的应用不应当依赖于它。详见 http://www.postgres.cn/docs/14/sql-createcast.html[CREATE CAST]。 +函数风格的语法事实上只是一次函数调用。当两种标准造型语法之一被用来做一次运行时转换时,它将在内部调用一个已注册的函数来执行该转换。简而言之,这些转换函数具有和它们的输出类型相同的名字,并且因此“函数风格的语法”无非是对底层转换函数的一次直接调用。显然,一个可移植的应用不应当依赖于它。详见 http://www.postgresql.org/docs/17/sql-createcast.html[CREATE CAST]。 **** ==== 排序规则表达式 @@ -1632,7 +1610,7 @@ SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C"; SELECT * FROM tbl WHERE a > 'foo' COLLATE "C"; ``` -注意在后一种情况中,`COLLATE` 子句被附加到我们希望影响的操作符的一个输入参数上。`COLLATE` 子句被附加到该操作符或函数调用的哪个参数上无关紧要,因为被操作符或函数应用的排序规则是考虑所有参数得来的,并且一个显式的 `COLLATE` 子句将重载所有其他参数的排序规则(不过,附加非匹配 `COLLATE` 子句到多于一个参数是一种错误。详见 http://www.postgres.cn/docs/14/collation.html[第 24.2 节])。因此,这会给出和前一个例子相同的结果: +注意在后一种情况中,`COLLATE` 子句被附加到我们希望影响的操作符的一个输入参数上。`COLLATE` 子句被附加到该操作符或函数调用的哪个参数上无关紧要,因为被操作符或函数应用的排序规则是考虑所有参数得来的,并且一个显式的 `COLLATE` 子句将重载所有其他参数的排序规则(不过,附加非匹配 `COLLATE` 子句到多于一个参数是一种错误。详见 http://www.postgresql.org/docs/17/collation.html[第 24.2 节])。因此,这会给出和前一个例子相同的结果: ``` SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; @@ -1648,7 +1626,7 @@ SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; ==== 标量子查询 -一个标量子查询是一种圆括号内的普通 `SELECT` 查询,它刚好返回一行一列(关于书写查询可见 http://www.postgres.cn/docs/14/queries.html[第 7 章])。`SELECT`查询被执行并且该单一返回值被使用在周围的值表达式中。将一个返回超过一行或一列的查询作为一个标量子查询使用是一种错误(但是如果在一次特定执行期间该子查询没有返回行则不是错误,该标量结果被当做为空)。该子查询可以从周围的查询中引用变量,这些变量在该子查询的任何一次计算中都将作为常量。对于其他涉及子查询的表达式还可见 http://www.postgres.cn/docs/14/functions-subquery.html[第 9.23 节]。 +一个标量子查询是一种圆括号内的普通 `SELECT` 查询,它刚好返回一行一列(关于书写查询可见 http://www.postgresql.org/docs/17/queries.html[第 7 章])。`SELECT`查询被执行并且该单一返回值被使用在周围的值表达式中。将一个返回超过一行或一列的查询作为一个标量子查询使用是一种错误(但是如果在一次特定执行期间该子查询没有返回行则不是错误,该标量结果被当做为空)。该子查询可以从周围的查询中引用变量,这些变量在该子查询的任何一次计算中都将作为常量。对于其他涉及子查询的表达式还可见 http://www.postgresql.org/docs/17/functions-subquery.html[第 9.23 节]。 例如,下列语句会寻找每个州中最大的城市人口: @@ -1669,7 +1647,7 @@ SELECT ARRAY[1,2,3+4]; (1 row) ``` -默认情况下,数组元素类型是成员表达式的公共类型,使用和 `UNION` 或 `CASE` 结构(见 http://www.postgres.cn/docs/14/typeconv-union-case.html[第 10.5 节])相同的规则决定。你可以通过显式将数组构造器造型为想要的类型来重载,例如: +默认情况下,数组元素类型是成员表达式的公共类型,使用和 `UNION` 或 `CASE` 结构(见 http://www.postgresql.org/docs/17/typeconv-union-case.html[第 10.5 节])相同的规则决定。你可以通过显式将数组构造器造型为想要的类型来重载,例如: ``` SELECT ARRAY[1,2,22.7]::integer[]; @@ -1679,7 +1657,7 @@ SELECT ARRAY[1,2,22.7]::integer[]; (1 row) ``` -这和把每一个表达式单独地造型为数组元素类型的效果相同。关于造型的更多信息请见 http://www.postgres.cn/docs/14/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节]。 +这和把每一个表达式单独地造型为数组元素类型的效果相同。关于造型的更多信息请见 http://www.postgresql.org/docs/17/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS[第 4.2.9 节]。 多维数组值可以通过嵌套数组构造器来构建。在内层的构造器中,关键词 `ARRAY` 可以被忽略。例如,这些语句产生相同的结果: @@ -1745,7 +1723,7 @@ SELECT ARRAY(SELECT ARRAY[i, i*2] FROM generate_series(1,5) AS a(i)); 子查询必须返回一个单一列。如果子查询的输出列是非数组类型, 结果的一维数组将为该子查询结果中的每一行有一个元素, 并且有一个与子查询的输出列匹配的元素类型。如果子查询的输出列 是一种数组类型,结果将是同类型的一个数组,但是要高一个维度。 在这种情况下,该子查询的所有行必须产生同样维度的数组,否则结果 就不会是矩形形式。 -用 `ARRAY` 构建的一个数组值的下标总是从一开始。更多关于数组的信息,请见 http://www.postgres.cn/docs/14/arrays.html[第 8.15 节]。 +用 `ARRAY` 构建的一个数组值的下标总是从一开始。更多关于数组的信息,请见 http://www.postgresql.org/docs/17/arrays.html[第 8.15 节]。 ==== 行构造器 @@ -1757,7 +1735,7 @@ SELECT ROW(1,2.5,'this is a test'); 当在列表中有超过一个表达式时,关键词 `ROW` 是可选的。 -一个行构造器可以包括语法 *`rowvalue`* `.\*`,它将被扩展为该行值的元素的一个列表,就像在一个顶层 `SELECT` 列表(见 http://www.postgres.cn/docs/14/rowtypes.html#ROWTYPES-USAGE[第 8.16.5 节])中使用 `.*` 时发生的事情一样。例如,如果表 `t` 有列 `f1` 和 `f2`,那么这些是相同的: +一个行构造器可以包括语法 *`rowvalue`* `.\*`,它将被扩展为该行值的元素的一个列表,就像在一个顶层 `SELECT` 列表(见 http://www.postgresql.org/docs/17/rowtypes.html#ROWTYPES-USAGE[第 8.16.5 节])中使用 `.*` 时发生的事情一样。例如,如果表 `t` 有列 `f1` 和 `f2`,那么这些是相同的: ``` SELECT ROW(t.*, 42) FROM t; @@ -1766,7 +1744,7 @@ SELECT ROW(t.f1, t.f2, 42) FROM t; .注意 **** -在IvorySQL 8.2 以前,`.\*` 语法不会在行构造器中被扩展,这样写 `ROW(t.*, 42)` 会创建一个有两个域的行,其第一个域是另一个行值。新的行为通常更有用。如果你需要嵌套行值的旧行为,写内层行值时不要用 `.*`,例如 `ROW(t, 42)`。 +在PostgreSQL 8.2 以前,`.\*` 语法不会在行构造器中被扩展,这样写 `ROW(t.*, 42)` 会创建一个有两个域的行,其第一个域是另一个行值。新的行为通常更有用。如果你需要嵌套行值的旧行为,写内层行值时不要用 `.*`,例如 `ROW(t, 42)`。 **** 默认情况下,由一个 `ROW` 表达式创建的值是一种匿名记录类型。如果必要,它可以被造型为一种命名的组合类型 — 或者是一个表的行类型,或者是一种用 `CREATE TYPE AS` 创建的组合类型。为了避免歧义,可能需要一个显式造型。例如: @@ -1814,7 +1792,7 @@ SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows ``` -详见 http://www.postgres.cn/docs/14/functions-comparisons.html[第 9.24 节]。如 http://www.postgres.cn/docs/14/functions-subquery.html[第 9.23 节] 中所讨论的,行构造器也可以被用来与子查询相连接。 +详见 http://www.postgresql.org/docs/17/functions-comparisons.html[第 9.24 节]。如 http://www.postgresql.org/docs/17/functions-subquery.html[第 9.23 节] 中所讨论的,行构造器也可以被用来与子查询相连接。 ==== 表达式计算规则 @@ -1836,7 +1814,7 @@ SELECT somefunc() OR true; 因此,在复杂表达式中使用带有副作用的函数是不明智的。在 `WHERE` 和 `HAVING` 子句中依赖副作用或计算顺序尤其危险,因为在建立一个执行计划时这些子句会被广泛地重新处理。这些子句中布尔表达式( `AND` / `OR` / `NOT` 的组合)可能会以布尔代数定律所允许的任何方式被重组。 -当有必要强制计算顺序时,可以使用一个 `CASE` 结构(见 http://www.postgres.cn/docs/14/functions-conditional.html[第 9.18 节])。例如,在一个 `WHERE` 子句中使用下面的方法尝试避免除零是不可靠的: +当有必要强制计算顺序时,可以使用一个 `CASE` 结构(见 http://www.postgresql.org/docs/17/functions-conditional.html[第 9.18 节])。例如,在一个 `WHERE` 子句中使用下面的方法尝试避免除零是不可靠的: ``` SELECT ... WHERE x > 0 AND y/x > 1.5; @@ -1850,7 +1828,7 @@ SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END; 一个以这种风格使用的 `CASE` 结构将使得优化尝试失败,因此只有必要时才这样做(在这个特别的例子中,最好通过写 `y > 1.5*x` 来回避这个问题)。 -不过,`CASE` 不是这类问题的万灵药。上述技术的一个限制是, 它无法阻止常量子表达式的提早计算。如 http://www.postgres.cn/docs/14/xfunc-volatility.html[第 38.7 节] 中所述,当查询被规划而不是被执行时,被标记成 `IMMUTABLE` 的函数和操作符可以被计算。因此 +不过,`CASE` 不是这类问题的万灵药。上述技术的一个限制是, 它无法阻止常量子表达式的提早计算。如 http://www.postgresql.org/docs/17/xfunc-volatility.html[第 38.7 节] 中所述,当查询被规划而不是被执行时,被标记成 `IMMUTABLE` 的函数和操作符可以被计算。因此 ``` SELECT CASE WHEN x > 0 THEN x ELSE 1/0 END FROM tab; @@ -1873,7 +1851,7 @@ SELECT CASE WHEN min(employees) > 0 === 调用函数 -IvorySQL允许带有命名参数的函数被使用 *位置* 或 *命名* 记号法调用。命名记号法对于有大量参数的函数特别有用,因为它让参数和实际参数之间的关联更明显和可靠。在位置记号法中,书写一个函数调用时,其参数值要按照它们在函数声明中被定义的顺序书写。在命名记号法中,参数根据名称匹配函数参数,并且可以以任何顺序书写。对于每一种记法,还要考虑函数参数类型的效果,这些在 http://www.postgres.cn/docs/14/typeconv-func.html[第 10.3 节] 有介绍。 +IvorySQL允许带有命名参数的函数被使用 *位置* 或 *命名* 记号法调用。命名记号法对于有大量参数的函数特别有用,因为它让参数和实际参数之间的关联更明显和可靠。在位置记号法中,书写一个函数调用时,其参数值要按照它们在函数声明中被定义的顺序书写。在命名记号法中,参数根据名称匹配函数参数,并且可以以任何顺序书写。对于每一种记法,还要考虑函数参数类型的效果,这些在 http://www.postgresql.org/docs/17/typeconv-func.html[第 10.3 节] 有介绍。 在任意一种记号法中,在函数声明中给出了默认值的参数根本不需要在调用中写出。但是这在命名记号法中特别有用,因为任何参数的组合都可以被忽略。而在位置记号法中参数只能从右往左忽略。 @@ -1894,7 +1872,7 @@ $$ LANGUAGE SQL IMMUTABLE STRICT; ``` -函数 `concat_lower_or_upper` 有两个强制参数,`a` 和 `b`。此外,有一个可选的参数 `uppercase`,其默认值为 `false`。`a` 和 `b` 输入将被串接,并且根据 `uppercase` 参数被强制为大写或小写形式。这个函数的剩余细节对这里并不重要(详见 http://www.postgres.cn/docs/14/extend.html[第 38 章])。 +函数 `concat_lower_or_upper` 有两个强制参数,`a` 和 `b`。此外,有一个可选的参数 `uppercase`,其默认值为 `false`。`a` 和 `b` 输入将被串接,并且根据 `uppercase` 参数被强制为大写或小写形式。这个函数的剩余细节对这里并不重要(详见 http://www.postgresql.org/docs/17/extend.html[第 38 章])。 ==== 使用位置记号 @@ -1985,9 +1963,9 @@ SELECT concat_lower_or_upper('Hello', 'World', uppercase => true); 参数设置采用与原生 PostgreSQL 相同的方法。 所有参数名称都不区分大小写。每个参数都采用以下五种类型之一的值:布尔值、字符串、整数、浮点数或枚举 (enum)。 -==== `compatible_mode (enum)` +==== `ivorysql.compatible_mode (enum)` -此参数控制数据库服务器的行为。 默认值为 `postgres`,表示它是原生安装,服务器将作为原生 PG 安装。 如果它设置为“oracle”,那么查询的输出和系统行为整体会发生变化,因为它会更像 Oracle。 +此参数控制数据库服务器的行为。 如果它设置为`pg`,表示它是原生安装,服务器将作为原生 PG 安装。 如果它设置为“oracle”,那么查询的输出和系统行为整体会发生变化,因为它会更像 Oracle。 当设置为 `oracle` 时,此参数会隐式地将同样名字的Schema添加到 `search_path`。 以便可以定位 Oracle 兼容对象。 @@ -2001,405 +1979,6 @@ SELECT concat_lower_or_upper('Hello', 'World', uppercase => true); - https://www.ivorysql.org/zh-CN/docs/tags/compatibility-parameters[Compatibility Parameters] -=== 包 - -本节将介绍PostgreSQL的“Oracle风格包”。根据定义,包是一个对象或一组对象打包在一起。就数据库而言,这将转换为一个命名的模式对象,该对象将过程、函数、变量、游标、用户定义的记录类型和引用记录的逻辑分组集合打包在自己内部。希望用户熟悉PostgreSQL,并且对SQL语言有很好的理解,以便更好地理解这些包并更有效地使用它们。 - -==== 对软件包的需求 - -与其他各种编程语言中的类似构造一样,将包与SQL一起使用有很多好处。在本节中,我们将要讲几个。 - -1.代码包的可靠性和可复用性:: - - Packages使您能够创建封装代码的模块化对象。这使得总体设计和实现更加简单。通过封装变量和相关类型、存储过程/函数以及游标,它允许您创建一个简单、易于理解、易于维护和使用的独立的模块。封装通过公开包接口而不是包体的实现细节发挥作用。因此,这在许多方面都有好处。它允许应用程序和用户引用一致的界面,而不必担心其主体的内容。此外,它还防止用户根据代码实现做出任何决策,因为代码实现从来没有向他们公开过。 - -2.易用性:: - - 在PostgreSQL中创建一致的功能接口的能力有助于简化应用程序开发,因为它允许在没有主体的情况下编译包。在开发阶段之后,包允许用户管理整个包的访问控制,而不是单个对象。这非常有价值,尤其是当包包含许多模式对象时。 - -3.性能:: - - 包是加载到内存中进行维护,因此使用的I/O资源最少。重新编译很简单,仅限于更改的对象;不重新编译从属对象。 - -4.附加功能:: - - 除了性能和易用性之外,软件包还为变量和游标提供了会话范围的持久性。这意味着变量和游标与数据库会话具有相同的生存期,并在会话被销毁时被销毁。 - -==== 包组件 - -包有一个接口和一个主体,这是组成包的主要组件。 - -1.包规格 - -包规格指定了包内从外部使用的任何对象。这指的是可公开访问的接口。它不包含它们的定义或实现,即功能和程序。它只定义了标题,而没有正文定义。可以初始化变量。以下是可在规范中列出的对象列表: - - - Functions - - Procedures - - Cursors - - Types - - Variables - - Constants - - Record types - -2.包体 - -包体包含包的所有实现代码,包括公共接口和私有对象。如果规范不包含任何子程序或游标,则包体是可选的。 - -它必须包含规范中声明的子程序的定义,并且相应的定义必须匹配。 - -包体可以包含其自己的子程序和规范中未指定的任何内部对象的类型声明。这些对象被认为是私有的。无法在包外部访问私有对象。 - -除了子程序定义外,它还可以选择性地包含一个初始化程序块,用于初始化规范中声明的变量,并且在会话中首次调用包时仅执行一次。 - -.**注意** -**** -如果规范更改,则包体将失效。在标识公共接口和私有接口时,必须小心,以避免将关键函数和变量暴露在包之外。 -**** - -==== 包语法 - -===== 包规范语法 - -```SQL -CREATE [ OR REPLACE ] PACKAGE [schema.] *package_name* [invoker_rights_clause] [IS | AS] - item_list[, item_list ...] -END [*package_name*]; - - -invoker_rights_clause: - AUTHID [CURRENT_USER | DEFINER] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - - -function_declaration: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype; - -procedure_declaration: - PROCEDURE procedure_name [(parameter_declaration[, ...])] - -type_definition: - record_type_definition | - ref_cursor_type_definition - -cursor_declaration: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype; - -item_declaration: - cursor_declaration | - cursor_variable_declaration | - record_variable_declaration | - variable_declaration | - -record_type_definition: - TYPE record_type IS RECORD ( variable_declaration [, variable_declaration]... ) ; - -ref_cursor_type_definition: - TYPE type IS REF CURSOR [ RETURN type%ROWTYPE ]; - -cursor_variable_declaration: - curvar curtype; - -record_variable_declaration: - recvar { record_type | rowtype_attribute | record_type%TYPE }; - -variable_declaration: - varname datatype [ [ NOT NULL ] := expr ] - -parameter_declaration: - parameter_name [IN] datatype [[:= | DEFAULT] expr] -``` - -===== 包体语法 - -```SQL -CREATE [ OR REPLACE ] PACKAGE BODY [schema.] package_name [IS | AS] - [item_list[, item_list ...]] | - item_list_2 [, item_list_2 ...] - [initialize_section] -END [package_name]; - - -initialize_section: - BEGIN statement[, ...] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - -item_list_2: -[ - function_declaration - function_definition - procedure_declaration - procedure_definition - cursor_definition -] - -function_definition: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype [IS | AS] - [declare_section] body; - -procedure_definition: - PROCEDURE procedure_name [(parameter_declaration[, ...])] [IS | AS] - [declare_section] body; - -cursor_definition: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype IS select_statement; - -body: - BEGIN statement[, ...] END [name]; - -statement: - [<<LABEL>>] pl_statments[, ...]; -``` - -===== **描述** - -创建包定义一个新包。创建或替换包将创建新包或替换现有定义。 - -如果包含架构名称,则在指定架构中创建包。否则,它将在当前架构中创建。新包的名称在架构中必须是唯一的。 - -使用“创建或替换包”替换现有包时,包的所有权和权限不会更改。所有其他包属性都被指定为命令中指定或隐含的值。您必须拥有该包才能替换它(这包括作为所属角色的成员)。 - -创建包的用户成为包的所有者。 - -===== **参数** - -`package_name` 要创建的包的名称(可选架构限定)。 - -`invoker_rights_clause` 调用方权限定义包对数据库对象的访问权限。可供选择的选项有: - -- *CURRENT_USER* 将使用执行包的当前用户的访问权限。 -- *DEFINER* 将使用包创建者的访问权限。 - -`item_list` 这是可以作为包的一部分的项目列表。 - -`procedure_declaration` 指定过程名称及其参数列表。这只是一个声明,不会定义过程。 - -当此声明是包规范的一部分时,它是一个公共过程,必须将其定义添加到包体中。 - -当它是包体的一部分时,它充当转发声明,是一个只有包元素才能访问的私有过程。 - -`procedure_definition` 程序在包体中定义。这定义了先前声明的过程。它还可以定义一个过程,而不需要任何先前的声明,这将使它成为一个私有过程。 - -`function_declaration` 定义函数名、参数及其返回类型。它只是一个声明,不会定义函数。 - -当此声明是包规范的一部分时,它是一个公共函数,必须将其定义添加到包体中。 - -当它是包体的一部分时,它充当转发声明,是一个只有包元素才能访问的私有函数。 - -`function_definition` 这些函数在包体中定义。这定义了前面声明的函数。它还可以定义一个函数,而不需要任何先前的声明,这将使它成为一个私有函数。 - -`type_definition` 建议您可以定义记录或光标类型。 - -`cursor_declaration` 定义游标声明必须包括其参数和返回类型作为所需的行类型。 - -`item_declaration` 允许声明: - -- Cursors -- Cursor variables -- Record variables -- Variables - -`parameter_declaration` 定义用于声明参数的语法。如果指定了关键字“IN”,则表示这是一个输入参数。后跟表达式(或值)的默认关键字只能特定于输入参数。 - -`declare_section` 它包含函数或过程本地的所有元素,并且可以在其主体中引用。 - -`body` 主体由PL/iSQL语言支持的SQL语句或PL控制结构组成。 - -==== 创建和访问包 - -===== 创建包 - -在本节中,我们将进一步了解包的构造过程以及如何访问其公共元素。 - -创建包时,PostgreSQL将编译并报告任何它可能发现的问题。一旦成功编译包,它将被删除随时可用。 - -===== 访问包元素 - -当包第一次在会话中被引用时,它将被实例化和初始化。以下操作在过程中执行这个过程: - -- 将初始值分配给公共常量和变量 -- 执行包的初始值设定项块 - -有几种方法可以访问包元素: - -- 包函数可以像SELECT语句或其他PL块中的任何其他函数一样使用 - -- 包过程可以使用CALL直接调用,也可以从其他PL块调用 - -- 包变量可以使用PL块中的包名称限定或从SQL提示符直接读取和写入。 - -- 使用点符号直接访问: 在点表示法中,可以通过以下方式访问元素: - - * package_name.func('foo'); - - * package_name.proc('foo'); - - * package_name.variable; - - * package_name.constant; - - * package_name.other_package.func('foo'); - - 这些语句可以从PL块内部使用,如果元素不是类型声明或过程,则可以在SELECT语句中使用。 - -- SQL调用语句: 另一种方法是使用CALL语句。CALL语句执行独立过程,或在类型或包中定义的函数。 - - * CALL package_name.func('foo'); - * CALL package_name.proc('foo'); - -==== 了解可见性的范围 - -PL/SQL块中声明的变量范围仅限于该块。如果它有嵌套块,则它将是嵌套块的全局变量。 - -类似地,如果两个块都声明了相同的名称变量,那么在嵌套块内部,它自己声明的变量是可见的,父变量是不可见的。要访问父变量,该变量必须完全限定。 - -考虑下面的代码片段。 - -==== **示例:可见性和限定变量名** - -```SQL -<<blk_1>> -DECLARE - x INT; - y INT; -BEGIN - -- both blk_1.x and blk_1.y are visible - <<blk_2>> - DECLARE - x INT; - z INT; - BEGIN - -- blk_2.x, y and z are visible - -- to access blk_1.x it has to be a qualified name. blk_1.x := 0; NULL; - END; - -- both x and y are visible -END; -``` - -上面的示例显示了当嵌套包包含同名变量时,必须如何完全限定变量名。 - -变量名限定有助于解决在以下情况下由作用域优先级引入的可能混淆: - -- 包和嵌套包变量:如果没有限定,嵌套的优先 -- 包变量和列名:如果没有限定,列名优先 -- 功能或程序变量和包变量:如果没有限定,包变量优先。 - -以下类型中的字段或方法需要进行类型限定。 - -- 记录类型 - -**示例:记录类型可见性和访问权限** - -```SQL -DECLARE - x INT; - TYPE xRec IS RECORD (x char, y INT); -BEGIN - x := 1; -- will always refer to x(INT) type. - xRec.x := '2'; -- to refer the CHAR type, it will have to be -qualified name -END; -``` - -==== 包示例 - -===== 包规格 - -```SQL -CREATE TABLE test(x INT, y VARCHAR2(100)); -INSERT INTO test VALUES (1, 'One'); -INSERT INTO test VALUES (2, 'Two'); -INSERT INTO test VALUES (3, 'Three'); - --- Package specification: -CREATE OR REPLACE PACKAGE example AUTHID DEFINER AS - -- Declare public type, cursor, and exception: - TYPE rectype IS RECORD (a INT, b VARCHAR2(100)); - CURSOR curtype RETURN rectype%rowtype; - - rec rectype; - - -- Declare public subprograms: - FUNCTION somefunc ( - last_name VARCHAR2, - first_name VARCHAR2, - email VARCHAR2 - ) RETURN NUMBER; - - -- Overload preceding public subprogram: - PROCEDURE xfunc (emp_id NUMBER); - PROCEDURE xfunc (emp_email VARCHAR2); -END example; -/ -``` -===== 包体 - -```SQL --- Package body: -CREATE OR REPLACE PACKAGE BODY example AS - nelems NUMBER; -- private variable, visible only in this package - - -- Define cursor declared in package specification: - CURSOR curtype RETURN rectype%rowtype IS SELECT x, y - FROM test - ORDER BY x; - -- Define subprograms declared in package specification: - FUNCTION somefunc ( - last_name VARCHAR2, - first_name VARCHAR2, - email VARCHAR2 - ) RETURN NUMBER IS - id NUMBER := 0; - BEGIN - OPEN curtype; - LOOP - FETCH curtype INTO rec; - EXIT WHEN NOT FOUND; - END LOOP; - RETURN rec.a; - END; - - PROCEDURE xfunc (emp_id NUMBER) IS - BEGIN - NULL; - END; - - PROCEDURE xfunc (emp_email VARCHAR2) IS - BEGIN - NULL; - END; - -BEGIN -- initialization part of package body - nelems := 0; -END example; -/ -SELECT example.somefunc('Joe', 'M.', 'email@example.com'); -``` - -==== 局限性 - -记录类型支持作为包变量,但是它们只能在包元素中使用,即包函数/过程可以使用它们。它们不能在包外访问,这一限制将在IvorySQL 的下一次更新中解决。 - -**标识** - -- https://www.ivorysql.org/zh-CN/docs/tags/oracle-style-packages[Oracle Style Packages] -- https://www.ivorysql.org/zh-CN/docs/tags/包[包] - === 更改表 ==== 语法 @@ -3666,281 +3245,6 @@ insert into test values ('李老师您好'); INSERT 0 1 ``` -=== PL/iSQL - -PL/iSQL 是 IvorySQL 的过程语言,用于为 IvorySQL 编写自定义函数、过程和包。 PL/iSQL 派生自 PostgreSQL 的 PL/pgsql,并增加了一些功能,但在语法上 PL/iSQL 更接近 Oracle 的 PL/SQL。 本文档描述了 PL/iSQL 程序的基本结构和构造。 - -==== PL/iSQL 程序的结构 - -iSQL 是一种程序化的块结构语言,支持四种不同的 程序类型,即 **PACKAGES**、**PROCEDURES**、**FUNCTIONS** 和 **TRIGGERS**。 iSQL 对每种类型的受支持程序使用相同的块结构。 一个块最多由三个部分组成:声明部分,可执行文件,和异常部分。 而声明和异常部分是可选的。 - -```SQL -[DECLARE - declarations] - BEGIN - statements - [ EXCEPTION - WHEN <exception_condition> THEN - statements] - END; -``` - -一个块至少可以由一个可执行部分组成 在 **BEGIN** 和 **END** 关键字中包含一个或多个 iSQL 语句。 - -```SQL -CREATE OR REPLACE FUNCTION null_func() RETURN VOID AS -BEGIN - NULL; -END; -/ -``` - -所有关键字都不区分大小写。 标识符被隐式转换为小写,除非双引号, 就像它们在普通 SQL 命令中一样。 声明部分可用于声明变量和游标,并取决于使用块的上下文, 声明部分可以以关键字 **DECLARE** 开头。 - -```SQL -CREATE OR REPLACE FUNCTION null_func() RETURN VOID AS -DECLARE - quantity integer := 30; - c_row pg_class%ROWTYPE; - r_cursor refcursor; - CURSOR c1 RETURN pg_proc%ROWTYPE; -BEGIN - NULL; -end; -/ -``` - -可选的异常部分也可以包含在 **BEGIN - END** 块中。 异常部分以关键字 **EXCEPTION** 开始,一直持续到它出现的块的末尾。 如果块内的语句抛出异常,程序控制转到异常部分,根据异常和异常部分的内容,可能会或不会处理抛出的异常。 - -```SQL -CREATE OR REPLACE FUNCTION reraise_test() RETURN void AS -BEGIN - - BEGIN - RAISE syntax_error; - EXCEPTION - WHEN syntax_error THEN - - BEGIN - raise notice 'exception % thrown in inner block, reraising', sqlerrm; - RAISE; - EXCEPTION - WHEN OTHERS THEN - raise notice 'RIGHT - exception % caught in inner block', sqlerrm; - END; - END; - EXCEPTION - WHEN OTHERS THEN - raise notice 'WRONG - exception % caught in outer block', sqlerrm; -END; -/ -``` - -.注意 -**** -与 PL/pgSQL 类似,PL/iSQL 使用 **BEGIN/END** 对语句进行分组, 并且不要将它们与用于事务控制的同名 SQL 命令混淆。 PL/iSQL 的 BEGIN/END 仅用于分组; 他们不开始或结束事务 -**** - -==== **psql** 对 PL/iSQL 程序的支持 - -要从 psql 客户端创建 PL/iSQL 程序,您可以使用类似于 PL/pgSQL 的**$$**语法 - -```SQL -CREATE FUNCTION func() RETURNS void as -$$ -.. -end$$ language plisql; -``` - -或者,您可以使用不带 **$$** 的 Oracle 兼容语法的引用和语言规范, 并使用 **/(正斜杠)** 结束程序定义。 /(正斜杠)必须在换行符上 - -```SQL -CREATE FUNCTION func() RETURN void AS -… -END; -/ -``` - -==== PL/iSQL 程序语法 - -===== PROCEDURES - -```SQL -CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter_list)] -is -[DECLARE] - -- variable declaration -BEGIN - -- stored procedure body -END; -/ -``` - -===== FUNCTIONS - -```SQL -CREATE [OR REPLACE] FUNCTION function_name ([parameter_list]) -RETURN return_type AS -[DECLARE] - -- variable declaration -BEGIN - -- function body - return statement -END; -/ -``` - -===== PACKAGES - -====== PACKAGE HEADER - -```SQL -CREATE [ OR REPLACE ] PACKAGE [schema.] *package_name* [invoker_rights_clause] [IS | AS] - item_list[, item_list ...] -END [*package_name*]; - - -invoker_rights_clause: - AUTHID [CURRENT_USER | DEFINER] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - - -function_declaration: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype; - -procedure_declaration: - PROCEDURE procedure_name [(parameter_declaration[, ...])] - -type_definition: - record_type_definition | - ref_cursor_type_definition - -cursor_declaration: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype; - -item_declaration: - cursor_declaration | - cursor_variable_declaration | - record_variable_declaration | - variable_declaration | - -record_type_definition: - TYPE record_type IS RECORD ( variable_declaration [, variable_declaration]... ) ; - -ref_cursor_type_definition: - TYPE type IS REF CURSOR [ RETURN type%ROWTYPE ]; - -cursor_variable_declaration: - curvar curtype; - -record_variable_declaration: - recvar { record_type | rowtype_attribute | record_type%TYPE }; - -variable_declaration: - varname datatype [ [ NOT NULL ] := expr ] - -parameter_declaration: - parameter_name [IN] datatype [[:= | DEFAULT] expr] -``` - -====== PACKAGE BODY - -```SQL -CREATE [ OR REPLACE ] PACKAGE BODY [schema.] package_name [IS | AS] - [item_list[, item_list ...]] | - item_list_2 [, item_list_2 ...] - [initialize_section] -END [package_name]; - - -initialize_section: - BEGIN statement[, ...] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - -item_list_2: -[ - function_declaration - function_definition - procedure_declaration - procedure_definition - cursor_definition -] - -function_definition: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype [IS | AS] - [declare_section] body; - -procedure_definition: - PROCEDURE procedure_name [(parameter_declaration[, ...])] [IS | AS] - [declare_section] body; - -cursor_definition: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype IS select_statement; - -body: - BEGIN statement[, ...] END [name]; - -statement: - [<<LABEL>>] pl_statments[, ...]; -``` - -=== 层级查询 - -==== 语法 - -```undefined - { - CONNECT BY [ NOCYCLE ] [PRIOR] condition [AND [PRIOR] condition]... [ START WITH condition ] - | START WITH condition CONNECT BY [ NOCYCLE ] [PRIOR] condition [AND [PRIOR] condition]... - } -``` - -**CONNECT BY** 查询语法以 CONNECT BY 关键字开头,这些关键字定义了父行和子行之间的分层相互依赖关系。 必须通过在 CONNECT BY 子句的条件部分指定 PRIOR 关键字来进一步限定结果. - -**PRIOR** PRIOR 关键字是一元运算符,它将前一行与当前行联系起来。 此关键字可以用在相等条件的左边或右边。 - -**START WITH** 该子句指定从哪一行开始层次结构。 - -**NOCYCLE** 无操作语句。 目前只有语法支持。 该子句表示即使存在循环也返回数据。 - -==== **附加列** - -**LEVEL** 返回层次结构中当前行的级别,从根节点的 1 开始,之后每级别递增 1。 - -**CONNECT_BY_ROOT expr** 返回层次结构中当前行的父列。 - -**SYS_CONNECT_BY_PATH(col, chr)** 它是一个返回从根到当前节点的列值的函数,由字符“chr”分隔。 - -==== **限制** - -目前此功能有以下限制: - -- 附加列可用于大多数表达式,如函数调用、CASE 语句和通用表达式,但有一些不受支持的列,如 ROW、TYPECAST、COLLATE、GROUPING 子句等 - -- 两个或多个列相同的情况下,可能需要输出列名,例如 - - > SELECT CONNECT_BY_ROOT col AS "col1", CONNECT_BY_ROOT col AS "col2" .... - -- 不支持间接运算符或“*” - -- 不支持循环检测(Loop detection) - == 全局唯一索引 === 创建全局唯一索引 diff --git a/CN/modules/ROOT/pages/v3.0/8.adoc b/CN/modules/ROOT/pages/v1.17/8.adoc similarity index 99% rename from CN/modules/ROOT/pages/v3.0/8.adoc rename to CN/modules/ROOT/pages/v1.17/8.adoc index 8ccf9c0..97de034 100644 --- a/CN/modules/ROOT/pages/v3.0/8.adoc +++ b/CN/modules/ROOT/pages/v1.17/8.adoc @@ -5,17 +5,17 @@ = 运维管理指南 -由于IvorySQL基于PostgreSQL开发而成,运维人员在阅读理解本节内容时,建议同时参阅 https://www.postgresql.org/docs/15/index.html[手册]。 +由于IvorySQL基于PostgreSQL开发而成,运维人员在阅读理解本节内容时,建议同时参阅 https://www.postgresql.org/docs/17/index.html[手册]。 == 升级IvorySQL版本 === 升级方案概述 -IvorySQL版本号由主要版本和次要版本组成。例如,IvorySQL 1.3 中的1是主要版本,3是次要版本。 +IvorySQL版本号由主要版本和次要版本组成。例如,IvorySQL 3.2 中的3是主要版本,2是次要版本。 -​发布次要版本是不会改变内存的存储格式,因此总是和相同的主要版本兼容。例如,IvorySQL 1.3 和Ivory SQL 1.0 以及后续的 Ivory SQL 1.x 兼容。对于这些兼容版本的升级非常简单,只要关闭数据库服务,安装替换二进制的可执行文件,重新启动服务即可。 +​发布次要版本是不会改变内存的存储格式,因此总是和相同的主要版本兼容。例如,IvorySQL 3.2 和Ivory SQL 3.0 以及后续的 Ivory SQL 3.x 兼容。对于这些兼容版本的升级非常简单,只要关闭数据库服务,安装替换二进制的可执行文件,重新启动服务即可。 -​接下来,我们主要讨论IvorySQL的跨版本升级问题,例如,从 IvorySQL 1.3 升级到 IvorySQL 2.1 。主要版本的升级可能会修改内部数据的存储格式,因此需要执行额外的操作。常用的跨版本升级方法和适用场景如下: +​接下来,我们主要讨论IvorySQL的跨版本升级问题,例如,从 IvorySQL 2.3 升级到 IvorySQL 3.4 。主要版本的升级可能会修改内部数据的存储格式,因此需要执行额外的操作。常用的跨版本升级方法和适用场景如下: |==== |升级方法|适用场景|停机时间 @@ -99,7 +99,7 @@ pg_upgrade 工具可以支持IvorySQL跨版本的就地升级。 升级可以在 == 管理IvorySQL版本 -IvorySQL基于PostgreSQL开发,版本更新频率与PostgreSQL版本更新频率保持一致,每年更新一个大版本,每季度更新一个小版本。IvorySQL目前发布的版本有1.0到3.0,分别基于PostgreSQL 14.0到16.0进行开发,最新版本为IvorySQL 3.0, 基于PostgreSQL 16.0 进行开发。IvorySQL 的所有版本全部都做到了向下兼容。相关版本特性可以查看 https://deploy-preview-83--ivorysql.netlify.app/zh-CN/releases-page[官网]。 +IvorySQL基于PostgreSQL开发,版本更新频率与PostgreSQL版本更新频率保持一致,每年更新一个大版本,每季度更新一个小版本。IvorySQL目前发布的版本有1.0到4.2,分别基于PostgreSQL 14.0到17.2进行开发,最新版本为IvorySQL 4.2,基于PostgreSQL 17.2进行开发。IvorySQL 的所有版本全部都做到了向下兼容。相关版本特性可以查看 https://www.ivorysql.org/zh-CN/releases-page[官网]。 == 管理IvorySQL数据库访问 @@ -148,7 +148,7 @@ psql程序的\du元命令也可以用来列出现有角色。 由于角色可以拥有数据库对象并且能持有访问其他对象的特权,删除一个角色常常并非一次DROP ROLE就能解决。 任何被该用户所拥有的对象必须首先被删除或者转移给其他拥有者,并且任何已被授予给该角色的权限必须被收回。 -更多有关数据库访问管理的细节,可以参阅 https://www.postgresql.org/docs/15/user-manag.html[手册]。 +更多有关数据库访问管理的细节,可以参阅 https://www.postgresql.org/docs/17/user-manag.html[手册]。 == 定义数据对象 @@ -336,7 +336,7 @@ pg_dump -Fc dbname > filename pg_restore -d dbname filename ---- -​更多细节可以参阅 https://www.postgresql.org/docs/15/reference-client.html[手册]。 +​更多细节可以参阅 https://www.postgresql.org/docs/17/reference-client.html[手册]。 ​对于非常大型的数据库,你可能需要将split配合其他两种方法之一进行使用。 @@ -386,7 +386,7 @@ tar -cf backup.tar /usr/local/pgsql/data ​ 就简单的文件系统备份技术来说,这种方法只能支持整个数据库集簇的恢复,却无法支持其中一个子集的恢复。另外,它需要大量的归档存储:一个基础备份的体积可能很庞大,并且一个繁忙的系统将会产生大量需要被归档的WAL流量。尽管如此,在很多需要高可靠性的情况下,它是首选的备份技术。 -​ 要使用连续归档(也被很多数据库厂商称为“在线备份”)成功地恢复,你需要一个从基础备份时间开始的连续的归档WAL文件序列。为了开始,在你建立第一个基础备份之前,你应该建立并测试用于归档WAL文件的过程。对应地,我们首先讨论归档WAL文件的机制。关于如何建立归档和备份的方式以及操作过程中的要点,请参阅 https://www.postgresql.org/docs/15/backup.html[手册]。 +​ 要使用连续归档(也被很多数据库厂商称为“在线备份”)成功地恢复,你需要一个从基础备份时间开始的连续的归档WAL文件序列。为了开始,在你建立第一个基础备份之前,你应该建立并测试用于归档WAL文件的过程。对应地,我们首先讨论归档WAL文件的机制。关于如何建立归档和备份的方式以及操作过程中的要点,请参阅 https://www.postgresql.org/docs/17/backup.html[手册]。 == 装卸数据 @@ -424,7 +424,7 @@ COPY { table_name [ ( column_name [, ...] ) ] | ( query ) } FORCE_NULL ( column_name [, ...] ) ENCODING 'encoding_name' ---- -详细参数设置,请参阅 https://www.postgresql.org/docs/15/sql-copy.html[手册]。 +详细参数设置,请参阅 https://www.postgresql.org/docs/17/sql-copy.html[手册]。 === 输出 @@ -616,7 +616,7 @@ ZW ZIMBABWE 0000160 377 377 \0 003 \0 \0 \0 002 Z W \0 \0 \0 \b Z I 0000200 M B A B W E 377 377 377 377 377 377 ---- -剩余的详细信息可以参阅 https://www.postgresql.org/docs/15/sql-copy.html[手册]。 +剩余的详细信息可以参阅 https://www.postgresql.org/docs/17/sql-copy.html[手册]。 == 性能管理 @@ -1158,7 +1158,7 @@ WHERE tablename = 'road'; ​ ANALYZE在pg_statistic中存储的信息量(特别是每个列的most_common_vals中的最大项数和histogram_bounds数组)可以用ALTER TABLE SET STATISTICS命令为每一列设置, 或者通过设置配置变量default_statistics_target进行全局设置。 目前的默认限制是 100 个项。提升该限制可能会让规划器做出更准确的估计(特别是对那些有不规则数据分布的列), 其代价是在pg_statistic中消耗了更多空间,并且需要略微多一些的时间来计算估计数值。 相比之下,比较低的限制可能更适合那些数据分布比较简单的列。 -更多规划器对统计信息的使用可以参阅 https://www.postgresql.org/docs/15/planner-stats-details.html[手册]。 +更多规划器对统计信息的使用可以参阅 https://www.postgresql.org/docs/17/planner-stats-details.html[手册]。 ==== 扩展统计信息 diff --git a/CN/modules/ROOT/pages/v1.17/9.adoc b/CN/modules/ROOT/pages/v1.17/9.adoc new file mode 100644 index 0000000..8c910b7 --- /dev/null +++ b/CN/modules/ROOT/pages/v1.17/9.adoc @@ -0,0 +1,115 @@ + +:sectnums: +:sectnumlevels: 5 + += PostGIS + +== 概述 +IvorySQL原生100%兼容PostgreSQL,因此,PostGIS可以完美适配IvorySQL。 + +== 安装 +根据开发环境,用户可从 https://postgis.net/documentation/getting_started/#installing-postgis[PostGIS安装] 页面选择适合自己的方式进行安装PostGIS安装。 + +=== 源码安装 +除PostGIS社区提供的安装方式以外,IvorySQL社区也提供了源码安装方式,源码安装环境为 CentOS Stream 9(x86_64)。 + + +** 安装依赖 +``` +dnf install -y gcc gcc-c++ libtiff libtiff-devel.x86_64 libcurl-devel.x86_64 libtool libxml2-devel redhat-rpm-config clang llvm geos311 automake protobuf-c-devel +``` + +** 安装SQLITE +``` +$ wget https://www.sqlite.org/2022/sqlite-autoconf-3400000.tar.gz +$ tar -xvf sqlite-autoconf-3400000.tar.gz +$ cd sqlite-autoconf-3400000 +$ sed -n '1i\#define SQLITE_ENABLE_COLUMN_METADATA 1' sqlite3.c +$ ./configure --prefix=/usr/local/sqlite +$ make && make install +$ rm usr/bin/sqlite3 && ln -s /usr/local/sqlite/bin/sqlite3 /usr/bin/sqlite3 +$ sqlite3 -version +$ export PKG_CONFIG_PATH=/usr/local/sqlite/lib/pkgconfig:$PKG_CONFIG_PATH +``` + +** 安装PROJ +``` +$ wget https://download.osgeo.org/proj/proj-8.2.1.tar.gz +$ tar -xvf proj-8.2.1.tar.gz +$ cd proj-8.2.1 +$ ./configure --prefix=/usr/local/proj-8.2.1 +$ make && make install +``` + +** 安装 GDAL +``` +$ wget https://github.com/OSGeo/gdal/releases/download/v3.4.3/gdal-3.4.3.tar.gz +$ tar -xvf gdal-3.4.3.tar.gz +$ cd gdal-3.4.3 +$ sh autogen.sh +$ ./configure --prefix=/usr/local/gdal-3.4.3 --with-proj=/usr/local/proj-8.2.1 +$ make && make install +``` + +** 安装 GEOS +``` +$ wget https://download.osgeo.org/geos/geos-3.9.2.tar.bz2 +$ tar -xvf geos-3.9.2.tar.bz2 +$ cd geos-3.9.2 +$ ./configure --prefix=/usr/local/geos-3.9.2 +$ make && make install +``` + +** 安装 Protobuf +``` +$ wget https://plug-neomirror.rcac.purdue.edu/adelie/source/archive/protobuf-3.20.1/protobuf-3.20.1.tar.gz +$ tar -xvf protobuf-3.20.1.tar.gz +$ cd protobuf-3.20.1 +$ sh autogen.sh +$ ./configure  --prefix=/usr/local/protobuf-3.20.1 +$ make && make install +$ export PROTOBUF_HOME=/usr/local/protobuf-3.20.1 +$ export PATH=$PROTOBUF_HOME/bin:$PATH +$ export PKG_CONFIG_PATH=$PROTOBUF_HOME/lib/pkgconfig:$PKG_CONFIG_PATH +``` + +** 安装 Protobuf-c +``` +$ wget --no-check-certificate https://sources.buildroot.net/protobuf-c/protobuf-c-1.4.1.tar.gz +$ tar -xvf protobuf-c-1.4.1.tar.gz +$ cd protobuf-c-1.4.1 +$ ./configure --prefix=/usr/local/protobuf-c-1.4.1 +$ make && make install +$ export PROTOBUFC_HOME=/usr/local/protobuf-c-1.4.1 +$ export PATH=$PROTOBUF_HOME/bin:$PROTOBUFC_HOME/bin:$PATH +$ export PKG_CONFIG_PATH=$PROTOBUFC_HOME/lib:$PKG_CONFIG_PATH +``` + +** 安装 PostGIS +``` +$ wget https://download.osgeo.org/postgis/source/postgis-3.4.0.tar.gz +$ tar -xvf postgis-3.4.0.tar.gz +$ cd postgis-3.4.0 +$ sh autogen.sh +$ ./configure --with-geosconfig=/usr/local/geos-3.9.2/bin/geos-config --with-projdir=/usr/local/proj-8.2.1 --with-gdalconfig=/usr/local/gdal-3.4.3/bin/gdal-config --with-protobufdir=/usr/local/protobuf-c-1.4.1 --with-pgconfig=/usr/local/ivorysql/ivorysql-4/bin/pg_config +$ make && make install +``` +[TIP] +如出现PGXS报错, 请根据环境中IvorySQL安装路径, 修改--with-pgconfig的参数值。 + +== 创建Extension并确认PostGIS版本 + +psql 连接到数据库,执行如下命令: +``` +ivorysql=# CREATE extension postgis; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'postgis'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+------------------------------------------------------------ + postgis | 3.4.0 | 3.4.0 | PostGIS geometry and geography spatial types and functions +(1 row) +``` + +== 使用 +关于PostGIS的使用,请参阅 https://postgis.net/docs/manual-3.4[PostGIS3.4官方文档] \ No newline at end of file diff --git a/CN/modules/ROOT/pages/v3.0/welcome.adoc b/CN/modules/ROOT/pages/v1.17/welcome.adoc similarity index 94% rename from CN/modules/ROOT/pages/v3.0/welcome.adoc rename to CN/modules/ROOT/pages/v1.17/welcome.adoc index fcebaaf..81c49cf 100644 --- a/CN/modules/ROOT/pages/v3.0/welcome.adoc +++ b/CN/modules/ROOT/pages/v1.17/welcome.adoc @@ -12,4 +12,4 @@ == 关于 IvorySQL IvorySQL 项目是瀚高软件提出的一个开源项目,旨在将 Oracle 兼容性功能添加到流行的 PostgreSQL 数据库中。 -IvorySQL 开源并且可以免费使用,如果您有任何建议请联系 contact@highgo.ca +IvorySQL 开源并且可以免费使用,如果您有任何建议请联系 support@ivorysql.org diff --git a/CN/modules/ROOT/pages/v3.0/1.adoc b/CN/modules/ROOT/pages/v3.0/1.adoc deleted file mode 100644 index fe8ad99..0000000 --- a/CN/modules/ROOT/pages/v3.0/1.adoc +++ /dev/null @@ -1,203 +0,0 @@ -:sectnums: -:sectnumlevels: 5 - - -== 版本介绍 - -[**发行日期:2023年11月17日**] - -IvorySQL 3.0 基于 PostgreSQL 16.0 ,包含来自 PostgreSQL 16.0 的各种修复。有关 PostgreSQL 16.0 中更详细的更新和错误修复,请参阅官方 https://www.postgresql.org/docs/release/16.0/[PostgreSQL 16.0 发行说明] 。 - - -== 版本差异 -IvorySQL 3.0 版本在架构上发生了很大的变化,其使用方式与 2.3 版本不同。还有一些以前在 2.3 版本中可用的功能尚不受支持,以下是两个版本的功能差异。 - -|==== -| 功能模块 | 功能|IvorySQL-2.3|IvorySQL-3.0 -.14+|内置数据类型|char|不支持|支持 -|varchar|支持|支持 -|varchar2|支持|支持 -|number|不支持|支持 -|binary_float|不支持|支持 -|binary_double|不支持|支持 -|date|支持|支持 -|timestamp|不支持|支持 -|timestamp with time zone|不支持|支持 -|timestamp with local time zone|不支持|支持 -|interval year to month|不支持|支持 -|interval day to second|不支持|支持 -|raw|不支持|支持 -|long|不支持|支持 -.44+|内置函数|char|不支持|支持 -|sysdate|支持|支持 -|systimestamp|支持|支持 -|add_months|支持|支持 -|last_day|支持|支持 -|next_day| 不支持|支持 -|months_between|支持 | 支持 -|current_date | 不支持 | 支持 -|current_timestamp | 不支持 | 支持 -|new_time | 支持 | 支持 -|tz_offset | 不支持 | 支持 -|trunc | 支持 | 支持 -|instr | 不支持 | 支持 -|instrb | 不支持 | 支持 -|substr | 不支持 | 支持 -|substrb | 支持 | 支持 -|trim | 不支持 | 支持 -|ltrim | 不支持 | 支持 -|rtrim | 不支持 | 支持 -|length | 不支持 | 支持 -|lengthb | 不支持 | 支持 -|rawtohex | 不支持 | 支持 -|replace | 不支持 | 支持 -|regexp_replace | 不支持 | 支持 -|regexp_substr | 不支持 | 支持 -|regexp_instr | 不支持 | 支持 -|regexp_like | 不支持 | 支持 -|to_number | 支持 | 支持 -|to_char | 支持 | 支持 -|to_date | 支持 | 支持 -|to_timestamp | 支持 | 支持 -|to_timestamp_tz | 支持 | 支持 -|to_yminterval | 不支持 | 支持 -|to_dsinterval | 支持 | 支持 -|numtodsinterval | 支持 | 支持 -|numtoyminterval | 支持 | 支持 -|localtimestamp | 不支持 | 支持 -|new_time | 不支持 | 支持 -|from_tz | 支持 | 支持 -|sys_extract_utc | 支持 | 支持 -|sessiontimezone | 支持 | 支持 -|hextoraw | 不支持 | 支持 -|uid | 不支持 | 支持 -|USERENV | 不支持 | 支持 -.4+|NLS参数|NLS_LENGTH_SEMANTICS|不支持|支持 -|NLS_DATE_FORMAT|不支持|支持 -|NLS_TIMESTAMP_FORMAT|不支持|支持 -|NLS_TIMESTAMP_TZ_FORMAT|不支持|支持 -|Function(函数)|支持语法兼容,并支持OUT参数|支持 | 支持 -|Procedure(存储过程|支持语法兼容,并支持OUT参数|支持 | 支持 -|Anonymous block(匿名块)|支持语法兼容,并支持OUT参数|不支持 | 支持 -|嵌套子过程|支持嵌套存储过程、函数等|不支持 | 支持 -|Merge|支持PG的Merge功能以及兼容Oralce语法的Merge功能|不支持 | 支持 -|q`|支持兼容的转义符|支持 | 支持 -|关键字处理|支持数据库中关键字的处理|不支持 | 支持 -.4+|对象大小写转换|全部大写加双引号转换为小写|不支持 | 支持 -|全部小写加双引号转换为大写|不支持 | 支持 -|大小写混合加双引号保持不变|不支持 | 支持 -|不加双引号(默认)全部转为小写|不支持 | 支持 -|Search Path|支持兼容模式下,默认搜索为sys模式,再搜索pg_catalog模式|不支持 | 支持 -|空串|支持Oracle兼容将空串转为NULL|不支持 | 支持 -|词法解析器分离|3.0框架的一部分|不支持 | 支持 -|包||支持|不支持 -|全局唯一索引||支持 | 支持 -|GUC切换oracle或pg||支持 | 支持 -|层级查询||支持 | 不支持 -|NANVL ||支持 | 不支持 -|GREATEST||支持 | 不支持 -|LEAST||支持 | 不支持 -|ADD_DAYS_TO_TIMESTAMP||支持 | 不支持 -|DAYS_BETWEEN ||支持 | 不支持 -|DAYS_BETWEEN_TMTZ ||支持 | 不支持 -|DBTIMEZONE||支持 | 不支持 -|TO_MULTI_BYTE||支持 | 不支持 -|TO_SINGLE_BYTE||支持 | 不支持 -|INTERVAL_TO_SECONDS||支持 |不支持 -|HEX_TO_DECIMAL||支持 | 不支持 -|TO_BINARY_DOUBLE||支持 | 不支持 -|TO_BINARY_FLOAT||支持 | 不支持 -|BIN_TO_NUM||支持 | 不支持 -|==== - -== 已知问题 - -* 暂无 - -== 增强功能 - -=== IvorySQL 框架 - - -* 添加双Parser支持不同的数据库parser https://github.com/IvorySQL/IvorySQL/issues/208[问题细节] -* 添加双端口支持不同的数据库端口号 https://github.com/IvorySQL/IvorySQL/issues/200[问题细节] -* 添加 initdb -m,支持postgres模式或 Oracle模式 https://github.com/IvorySQL/IvorySQL/issues/212[问题细节] - - -=== SQL兼容 - -* 兼容oracle merge command https://github.com/IvorySQL/IvorySQL/issues/262[问题细节] -* 兼容oracle q转义 https://github.com/IvorySQL/IvorySQL/issues/293[问题细节] -* 兼容oracle like https://github.com/IvorySQL/IvorySQL/issues/291[问题细节] - -=== PL/SQL兼容 - -* 解决PL/SQL 创建函数/存储过程存在问题 https://github.com/IvorySQL/IvorySQL/issues/477[问题细节] -* 兼容Oracle匿名块 https://github.com/IvorySQL/IvorySQL/issues/304[问题细节] -* 在 SQL parser中创建函数或过程支持嵌套子过程 https://github.com/IvorySQL/IvorySQL/issues/312[问题细节] -* 嵌套的子进程和函数 is/as 不需要声明 https://github.com/IvorySQL/IvorySQL/issues/303[问题细节] - -=== 其它 -* 在action中增加meson编译 https://github.com/IvorySQL/IvorySQL/issues/512[问题细节] -* 支持meson编译 https://github.com/IvorySQL/IvorySQL/issues/325[问题细节] -* 添加兼容的测试用例 https://github.com/IvorySQL/IvorySQL/issues/479[问题细节] -* 添加contrib回归 https://github.com/IvorySQL/IvorySQL/issues/452[问题细节] -* 兼容btree_gist索引 https://github.com/IvorySQL/IvorySQL/issues/354[问题细节] -* 兼容btree_gin索引 https://github.com/IvorySQL/IvorySQL/issues/353[问题细节] -* 添加Oracle数据类型 GIN索引操作 https://github.com/IvorySQL/IvorySQL/issues/347[问题细节] -* 添加Oracle数据类型 Gist索引操作 https://github.com/IvorySQL/IvorySQL/issues/341[问题细节] -* 兼容Oracle内置数据类型与内置函数 https://github.com/IvorySQL/IvorySQL/issues/239[问题细节] -* 添加plisql扩展 https://github.com/IvorySQL/IvorySQL/issues/211[问题细节] - -> 说明:关于新增功能更多介绍请参考本文档中心功能列表 - - -== 问题修复 - -* 使用meson编译后,initdb执行失败 https://github.com/IvorySQL/IvorySQL/issues/520[问题细节] -* 字符类型 null 值的运算符结果不正确 https://github.com/IvorySQL/IvorySQL/issues/499[问题细节] -* 还原备份时出错 https://github.com/IvorySQL/IvorySQL/issues/483[问题细节] -* ivorysql_ora部分测试用例失败 https://github.com/IvorySQL/IvorySQL/issues/461[问题细节] -* nls参数指定ff精度与表指定精度的三种关系下,对超出长度的数据处理不一致 https://github.com/IvorySQL/IvorySQL/issues/436[问题细节] -* 日期格式中的DD HH.MI,SS AM中数据出现特殊符号后的数据处理与Oracle不一致 https://github.com/IvorySQL/IvorySQL/issues/435[问题细节] -* 对日期格式,各部分 位数校验均存在问题 https://github.com/IvorySQL/IvorySQL/issues/434[问题细节] -* NLS相关参数校验问题 https://github.com/IvorySQL/IvorySQL/issues/433[问题细节] -* 解决NLS参数设置为12小时制,默认完成AM/PM关键字的规则与Oracle不一致问题 https://github.com/IvorySQL/IvorySQL/issues/405[问题细节] -* 带默认值创建的函数/存储过程xx_arguments视图中DEFAULTED字段值为N 问题 https://github.com/IvorySQL/IvorySQL/issues/379[问题细节] -* 无权限的函数/存储过程 可以被all_procedures/all_arguments/all_source视图查看 https://github.com/IvorySQL/IvorySQL/issues/378[问题细节] -* 当自增列类型为numer类型,且指定了精度时,by default on null插入null值时,不是插入的具体序列值,而是插入的null值 https://github.com/IvorySQL/IvorySQL/issues/386[问题细节] - - -== 源代码 - -IvorySQL主要包含2个代码仓库,数据库IvorySQL代码仓、IvorySQL网站仓: - -* IvorySQL代码仓: https://github.com/IvorySQL/IvorySQL[https://github.com/IvorySQL/IvorySQL] -* IvorySQL网站仓: https://github.com/IvorySQL/Ivory-www[https://github.com/IvorySQL/Ivory-www] - -== 贡献人员 -以下个人作为补丁作者、提交者、审阅者、测试者或问题报告者为本版本做出了贡献。 - -- IvorySQL Pro开发及测试团队 -- 谭洋 -- 王杰 -- 穆帅楠 -- 张洪源 -- Cary Huang -- Grant Zhou -- David Zhang -- 王守波 -- 任娇 -- 刘政 -- 肖哲凯 -- 金华建 -- 王丽 -- 宋金周 -- Leo X.M. Zeng -- 严少安 -- M.Imran Zaheer -- Yunhe Xu -- 王皓 -- 董小姐 -- 韩伟博 - diff --git a/CN/modules/ROOT/pages/v3.0/16.adoc b/CN/modules/ROOT/pages/v3.0/16.adoc deleted file mode 100644 index 16c334b..0000000 --- a/CN/modules/ROOT/pages/v3.0/16.adoc +++ /dev/null @@ -1,65 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - -= 引用标识符的大小写转换设计 - -== 目的 - -- 为了满足PG和Oracle的引用标识符大小写兼容,ivorysql设计了三种引用标识符的大小写转换模式。通过guc参数“identifier_case_switch”选择转换模式; - -== 功能 - -=== 大小写转换的三种模式(默认为interchange) - -- 如果 guc参数“identifier_case_switch”值为“interchange”: - - 1). 如果双引号所引用的标识符中的字母全部为大写,则将大写转换为小写。 - - 2). 如果双引号所引用的标识符中的字母全部为小写,则将小写转换为大写。 - - 3). 如果用双引号引起来的标识符中的字母是大小写混合的,则保持标识符不变。 - -=== 初始化数据库集簇时 - -- 在initdb程序中加入 -C选项设置大小写转换模式,-C对应的值为: - - "normal" ------ "0"同义 - - "interchange" ------ "1"同义 - - "lowercase" ------ "2"同义 - - 在初始化数据库集簇的过程中,将大小写转换模式保存到data目录的global/pg_control文件中。 - -=== 测试用例 - -``` -SET ivorysql.enable_case_switch = true; -SET ivorysql.identifier_case_switch = interchange; -CREATE TABLE "ABC"(c1 int, c2 int); -SELECT relname FROM pg_class WHERE relname = 'ABC'; -SELECT relname FROM pg_class WHERE relname = 'abc'; -SELECT * FROM "ABC"; -SELECT * FROM ABC; -SELECT * FROM abc; -SELECT * FROM Abc; -SELECT * FROM "Abc"; -- ERROR -DROP TABLE abc; - -CREATE TABLE "Abc"(c1 int, c2 int); -SELECT relname FROM pg_class WHERE relname = 'ABC'; -SELECT relname FROM pg_class WHERE relname = 'abc'; -SELECT relname FROM pg_class WHERE relname = 'Abc'; -SELECT * FROM "ABC"; -- ERROR -SELECT * FROM ABC; -- ERROR -SELECT * FROM abc; -- ERROR -SELECT * FROM Abc; -- ERROR -SELECT * FROM "Abc"; -DROP TABLE "Abc"; - -``` - - - - diff --git a/CN/modules/ROOT/pages/v3.0/6.adoc b/CN/modules/ROOT/pages/v3.0/6.adoc deleted file mode 100644 index 422f3a0..0000000 --- a/CN/modules/ROOT/pages/v3.0/6.adoc +++ /dev/null @@ -1,427 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - - -= **安装部署** - -== 安装概述 - -本文介绍 Ivorysql 在Linux平台(以CentOS 7为例)的安装过程及注意事项。本文主要演示数据库在Centos 7环境下yum源安装步骤、rpm包安装步骤、源码安装步骤。 - -=== 软硬件要求 - -==== 软件资源介绍 - -|==== -|操作系统|Yum源下载地址 -|CentOS 7、CentOS 8|https://yum.highgo.ca/ivorysql.html -|==== - - -==== 硬件资源准备 -|==== -|**配置参数**|**最低配置**|**推荐配置** -|**CPU**|4核|16核 -|**内存**|4GB|64GB -|**存储**|800MB,机械硬盘|5GB以上,SSD或NvMe -|**网络**|千兆网络|万兆网络 -|==== - -=== 环境和配置检查 - -部署 IvorySQL 数据库前,您需要进行系统环境和配置检查 - -==== 查看资源 - -IvorySQL 数据库支持CentOS 7.X,8.X操作系统。详细信息,参考<<#_软硬件要求>> - - -==== 查看操作系统 - -**CentOS 7.X** - -运行以下命令,查看操作系统信息: - - cat /etc/redhat-release - -==== 查看内核参数 - - uname -r - -==== 查看内存,清理缓存 ----- - free -g - - echo 3 > /proc/sys/vm/drop_caches ----- - -=== 获取安装包 - -您可以通过 源码安装 IvorySQL 数据库或 RPM 包安装。 - -==== 使用源码构建IvorySQL数据库 - -1.获取源代码:运行以下命令,克隆 IvorySQL 数据库源代码到您的构建机器: ----- -git clone https://github.com/IvorySQL/IvorySQL.git ----- - -> 注意:克隆代码需要先安装配置 Git。详细信息,参考 https://git-scm.com/doc[Git 文档] - - -2.安装依赖包:要从源代码编译 IvorySQL,必须确保系统上有可用的先决条件包。 执行以下命令安装相关包: ----- -sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget -sudo yum groupinstall -y 'Development Tools' ----- - -> 说明:“Development Tools” 包含了gcc,make,flex,bison。 - -3.自行编译安装:前面通过获取的源码在文件夹IvorySQL里,接下来我们就进入这个文件夹进行操作。 - -3.1 配置:Root用户执行以下命令进行配置: - - ./configure --prefix=/usr/local/ivorysql/ivorysql-3 - -> 说明: 由于没有提供 `--prefix`,默认安装在 `/usr/local/ivorysql`,故需要指定路径。 -> -> 注意:我们要记住指定的目录,因为系统查不出已经编译安装的程序在哪。更多 configure 参数通过 `./configure --help` 查看。还可以查看 PostgreSQL 手册。 - -3.2 编译安装:配置完成后,执行 make 进行编译: - - make - -要在安装新编译的服务之前使用回归测试测试一下,以下命令均可: - ----- -make check -make all-check-world ----- - -然后安装: - - sudo make install - - -==== 使用 RPM 包安装 IvorySql 数据库 - -1. 运行以下命令,下载 IvorySQL 安装包。 ----- -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-contrib-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-libs-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-server-3.0-1.rhel7.x86_64.rpm ----- - -> 注意:示例中的安装包可能不是最新版本,建议您下载最新的安装包。 - -2.运行以下命令,安装 IvorySQL 。 ----- --- 先安装依赖 -yum install -y libicu libxslt python3 -rpm -ivh ivorysql3-libs-3.0-1.rhel7.x86_64.rpm -rpm -ivh ivorysql3-3.0-1.rhel7.x86_64.rpm -rpm -ivh ivorysql3-contrib-3.0-1.rhel7.x86_64.rpm --nodeps -rpm -ivh ivorysql3-server-3.0-1.rhel7.x86_64.rpm ----- - -=== 初始化数据库服务 - -==== 初始化数据库 - -1. 创建操作系统用户:用户root会话下,新建用户 ivorysql: ----- -/usr/sbin/groupadd ivorysql -/usr/sbin/useradd -g ivorysql ivorysql -c "IvorySQL3.0 Server" -passwd ivorysql ----- - -2.修改权限:在root会话下执行以下命令: ----- -chown -R ivorysql.ivorysql /var/lib/ivorysql/ivorysql-3 ----- - -> 注意:这里没按RPM安装将数据目录放置到 `/var/lib/ivorysql/ivorysql-3/data`。 - -3.环境变量:切换到用户ivorysql,修改文件 `/home/ivorysql/.bash_profile`,配置环境变量: ----- -umask 022 -export LD_LIBRARY_PATH=/usr/local/ivorysql/ivorysql-3/lib:$LD_LIBRARY_PATH -export PATH=/usr/local/ivorysql/ivorysql-3/bin:$PATH -export PGDATA=/var/lib/ivorysql/ivorysql-3/data ----- - -使环境变量在当前ivorysql用户会话中生效: - - source .bash_profile - -也可以重新登录或开启一个新的用户ivorysql的会话。 - -4.设置防火墙:如果开启了防火墙,还需要将端口1521或者5432开放: ----- -firewall-cmd --zone=public --add-port=1521/tcp --permanent -firewall-cmd --reload ----- - -> 说明:默认端口是1521,如果不开放该端口,外部客户端通过ip连接会失败。 - -5.初始化:在用户ivorysql下,简单执行initdb就可以完成初始化: - - initdb - - -> 说明:initdb操作与PostgreSQL一样,可以按照PG的习惯去初始化。 - -6.启动数据库:使用pg_ctl启动数据库服务: - - pg_ctl start - -查看状态,启动成功: - - pg_ctl status - -=== 配置服务 - -1. 客户端验证:修改 /ivorysql/1.2/data/pg_hba.conf,追加以下内容: - - host all all 0.0.0.0/0 trust - - -> 注意:这里是trust,就是说可以免密登录。 - -执行以下命令加载配置: - - pg_ctl reload - -2.基本参数 - -通过psql连接数据库: - - psql - -修改监听地址 - - alter system set listen_address = '*'; - -> 说明:默认是监听在127.0.0.1,主机外是连不上服务的。 - -3.守护服务 - -创建service文件: - - touch /usr/lib/systemd/system/ivorysql.service - -编辑内容如下: ----- -[Unit] -Description=IvorySQL 3.0 database server -Documentation=https://www.ivorysql.org -Requires=network.target local-fs.target -After=network.target local-fs.target - -[Service] -Type=forking - -User=ivorysql -Group=ivorysql - -Environment=PGDATA=/var/lib/ivorysql/ivorysql-3/data - -OOMScoreAdjust=-1000 - -ExecStart=/usr/local/ivorysql/bin/pg_ctl start -D ${PGDATA} -ExecStop=/usr/local/ivorysql/bin/pg_ctl stop -D ${PGDATA} -ExecReload=/usr/local/ivorysql/bin/pg_ctl reload -D ${PGDATA} - -TimeoutSec=0 - -[Install] -WantedBy=multi-user.target ----- - -> 说明:service的写法有很多,在生产环境使用时需谨慎,请多次重复测试。 - -停止pg_ctl启动的数据库服务,启用systemd服务并启动: - - systemctl enable --now ivorysql.service - -IvorSQL数据库服务操作命令: ----- -systemctl start ivorysql.service --启动数据库服务 -systemctl stop ivorysql.service --停止数据库服务 -systemctl restart ivorysql.service --重启数据库 -systemctl status ivorysql.service --查看数据库状态 -systemctl reload ivorysql.service --可以满足部分数据库配置修改完后生效 ----- - -=== 安装 - -==== yum源 - -1. 下载YUM源:在Centos7上使用wget下载 - - wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-1.noarch.rpm - -安装ivorysql-release-1.0-1.noarch.rpm: - - rpm -ivh ivorysql-release-1.0-1.noarch.rpm - -安装后,将创建YUM源配置文件:/etc/yum.repos.d/ivorysql.repo。 - -搜索查看相关安装包: - - yum search ivorysql - -搜索结果说明见表1: - -.YUN源说明 -|==== -|**序号**|**包名**|**描述** -|1| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-1.2-1.rhel7.x86_64.rpm[ivorysql1.x86_64] | IvorySQL客户端程序和库文件 -|2| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-contrib-1.2-1.rhel7.x86_64.rpm[ivorysql1-contrib.x86_64] | 随IvorySQL发布的已贡献的源代码和二进制文件 -|3| ivorysql1-devel.x86_64| IvorySQL开发头文件和库 -|4| ivorysql1-docs.x86_64| IvorySQL的额外文档 -|5| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-libs-1.2-1.rhel7.x86_64.rpm[ivorysql1-libs.x86_64] | 所有IvorySQL客户端所需的共享库 -|6| ivorysql1-llvmjit.x86_64 | 对IvorySQL的即时编译支持 -|7| ivorysql1-plperl.x86_64 | 用于IvorySQL的过程语言Perl -|8| ivorysql1-plpython3.x86_64 | 用于IvorySQL的过程语言Python3 -|9| ivorysql1-pltcl.x86_64 | 用于IvorySQL的过程语言Tcl -|10| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-server-1.2-1.rhel7.x86_64.rpm[ivorysql1-server.x86_64] | 创建和运行IvorySQL服务器所需的程序 -|11| ivorysql1-test.x86_64 | 随IvorySQL发布的测试套件 -|12| ivorysql-release.noarch | 瀚高基础软件股份有限公司的Yum源配置RPM包 -|==== - - -2.安装IvorySQL - -要安装数据库服务,需要安装ivorysql1-server。 在用户root会话下执行以下命令: - - yum install -y ivorysql1-server - -**安装清单:** - - ivorysql1-server.x86_64 0:1.2-1.rhel7 - -**依赖安装:** ----- -ivorysql1.x86_64 0:1.2-1.rhel7 ivorysql1-contrib.x86_64 0:1.2-1.rhel7 -ivorysql1-libs.x86_64 0:1.2-1.rhel7 libicu.x86_64 0:50.2-4.el7_7 -libtirpc.x86_64 0:0.2.4-0.16.el7 libxslt.x86_64 0:1.1.28-6.el7 -python3.x86_64 0:3.6.8-18.el7 python3-libs.x86_64 0:3.6.8-18.el7 -python3-pip.noarch 0:9.0.3-8.el7 python3-setuptools.noarch 0:39.2.0-10.el7 ----- - -3.已安装目录 - -表2 对YUM安装过程产生的文件目录进行说明。 - -.安装目录文件说明 -|==== -|**序号**|**文件路径**|**描述** -|1| /usr/local/ivorysql/ivorysql-3 |软件安装目录 -|2| /var/lib/ivorysql/ivorysql-3/data| 数据目录(默认) -|3| /usr/bin/ivorysql-3-setup | 帮助管理员进行基本的数据库集群管理 -|4| /usr/lib/systemd/system/ivorysql-3.service | 守护服务 -|==== - -==== deb安装 - -验证环境:Linux 20.04.1-Ubuntu - -1、从官网获取deb包 - -> 说明:目前还未提供。 - -2、安装deb包 - -``` -dpkg -i ivorysql.deb -``` -> 说明:ivorysql.deb 为待安装包名。 - -3、配置环境变量 - -``` -vi ~/.bashrc - export PATH=/xxx/ivorysql/bin:$PATH - export LD_LIBRARY_PATH=/xxx/ivorysql/lib - -source .bashrc -``` - -> 说明:根据实际情况添加,有的可以不用添加。 -> - -4、卸载deb包 - -``` -dpkg -r ivorysql -``` - -=== 卸载 IvorySQL 数据库 - -==== 编译卸载 - -1.备份数据:数据目录在“/var/lib/ivorysql/ivorysql-3/data”下,所以我们将该目录保护好就可以,最好停止数据库服务后做备份。 - -``` -systemctl stop ivorysql.service -``` - -2.编译卸载:oot会话下切到源码目录下,分别执行以下命令: - -``` -make uninstall -make clean -``` - -3.删除残余目录和文件: - -``` -systemctl disable ivorysql.servicemake --禁用服务 -mv /usr/lib/systemd/system/ivorysql.service /tmp/ --服务文件移到/tmp,删除也可以 -rm -fr /usr/local/ivorysql/ivorysql-3 --删除残留安装目录 -``` - -> 说明:还有用户ivorysql以及对应的环境变量,可以根据情况是否清理。剩下的就是数据目录“/var/lib/ivorysql/ivorysql-3/data”了,请务必做好备份再做处理。还有安装的依赖包,可根据情况决定是否卸载。 - -==== YUM卸载 - -1.停止数据库服务: - -``` -systemctl stop ivorysql-3.service -``` - -先使用“yum history list”确定yum安装的事务ID: - -``` -[root@Node02 ~]# yum history list -Loaded plugins: fastestmirror -ID | Login user | Date and time | Action(s) | Altered -------------------------------------------------------------------------------- - 5 | root <root> | 2022-04-27 12:38 | Install | 11 < - 4 | root <root> | 2022-03-26 16:08 | Install | 35 > - 3 | root <root> | 2022-03-26 16:07 | I, U | 19 - 2 | root <root> | 2022-03-26 16:07 | I, U | 73 - 1 | System <unset> | 2022-03-26 15:59 | Install | 299 -history list -``` - -可以看到ID为5的是执行安装的事务。执行命令卸载(需将XX替换为“5”): - -``` -yum history undo XX -``` - -2.卸载: - -``` -yum remove ivorysql-server -``` - -但该命令卸载并不彻底,只卸载了2个依赖,还有8个依赖未能卸载。可以根据是否保留这些依赖而决定是否使用这种方式卸载。 diff --git a/CN/modules/ROOT/pages/v3.0/9.adoc b/CN/modules/ROOT/pages/v3.0/9.adoc deleted file mode 100644 index 9850d8d..0000000 --- a/CN/modules/ROOT/pages/v3.0/9.adoc +++ /dev/null @@ -1,726 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - - -= 迁移指南 - -== 迁移概述 - -所谓数据库迁移就是这个数据库到另一个数据库之间的任意形式的数据移动,两端的数据库可能是PostgreSql,mysql,Oracle,Sql Server,Highgo DB等。迁移过程是一个具有挑战性的复杂过程,需要对数据库的原理以及各自的特性了如指掌。如果应用已经部署到生产环境并处于正常运行状态,为了保持业务不中断运行,并且不发生数据丢失,数据库迁移后需进行平滑的应用迁移。 - -迁移后数据库和系统应符合以下要求: - -- 迁移后的数据库系统应完全承载原数据库系统的数据。避免迁移过程中数据丢失导致新的数据库系统数据不完整。 - -- 迁移后的数据库系统应完全适配原有数据库的功能。避免迁移后因数据类型或语法、函数的不支持,且无替代方案,导致整个业务系统的无法运行或抛错。 - -- 迁移后的数据库应适配整个业务系统的上下游,稳定可靠的保障整个业务系统的运行。 - -- 迁移后的数据库各方面综合性能不能弱于原数据库,为整个业务系统提供性能保证。 - -== 迁移工具Ora2Pg - -Ora2Pg 是一个免费的工具,用于将 Oracle 数据库迁移到 IvorySQL 兼容的模式。它连接您的 Oracle 数据库,自动扫描并提取它的结构或数据,然后生成可以装载到 IvorySQL 数据库的 SQL 脚本。Ora2Pg 可以从逆向工程 Oracle 数据库到大型企业数据库迁移,或者简单地将一些 Oracle 数据复制到 IvorySQL 数据库中。它非常容易使用,并且不需要任何 Oracle 数据库知识,而不需要提供连接到Oracle数据库所需的参数。 - -Ora2Pg 由一个 Perl 脚本(ora2pg)以及一个 Perl 模块( https://github.com/darold/ora2pg/blob/master/lib/Ora2Pg.pm[Ora2Pg.pm])组成,唯一需要做的事情就是修改它的配置文件 ora2pg.conf,设置连接 Oracle 数据库的 DSN 和一个可选的 SCHEMA 名称。完成之后,只需要设置导出的类型:TABLE(包括约束和索引)、VIEW、MVIEW、TABLESPACE、SEQUENCE、INDEXES、TRIGGER、GRANT、FUNCTION、PROCEDURE、PACKAGE、PARTITION、TYPE、INSERT 或 COPY、FDW、QUERY、KETTLE 以及 SYNONYM。 - -默认情况下,Ora2Pg 导出一个 SQL 文件,可以通过 IvorySQL 客户端工具 psql 执行导出的SQL文件。当进行数据迁移时,可以在配置文件中设置一个目标数据库的 DSN,直接将数据从Oracle导入到 IvorySQL 数据库中。 - -[%autowidth] -|=== -| **对象** | ora2pg是否支持 -| view | 是 -| trigger | 是,某些情况下需要手工修改脚本 -| sequence | 是 -| function | 是 -| procedure | 是,某些情况下需要手工修改脚本 -| type | 是,某些情况下需要手工修改脚本 -| materialized view | 是,某些情况下需要手工修改脚本 -|=== - -== 迁移Oracle数据库至IvorySQL - -=== 环境准备 - -|=== -| linux环境 | Oracle版本 | IvorySQL版本 -| Centos 7.X | 11.2.0.3.0 | 2.1 -|=== - -=== 依赖环境安装 - -==== 安装Perl - -```bash -[root@localhost /]# yum install -y perl perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker -[root@localhost /]# perl -v - - -This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi -(with 44 registered patches, see perl -V for more detail) - - -Copyright 1987-2012, Larry Wall - - -Perl may be copied only under the terms of either the Artistic License or the -GNU General Public License, which may be found in the Perl 5 source kit. - - -Complete documentation for Perl, including FAQ lists, should be found on -this system using "man perl" or "perldoc perl". If you have access to the -Internet, point your browser at http://www.perl.org/, the Perl Home Page. -``` - -==== 安装DBI模块 - -DBI,Database Independent Interface,是 Perl 语言连接数据库的接口 - -下载地址 https://mirrors.sjtug.sjtu.edu.cn/cpan/modules/by-module/Plack/TIMB/DBI-1.643.tar.gz - -```bash -[root@localhost oracle2postgresql]# tar zxvf DBI-1.643.tar.gz -[root@localhost oracle2postgresql]# cd DBI-1.643/ -[root@localhost DBI-1.643]# perl Makefile.PL -[root@localhost DBI-1.643]# make -[root@localhost DBI-1.643]# make install -``` - -==== 安装DBD-Oracle - -下载地址:https://sourceforge.net/projects/ora2pg/ - -设置环境变量; 加载环境变量;因为必须定义ORACLE_HOME环境变量;本例在ivorysql用户下配置环境变量 - -``` -export LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib:$LD_LIBRARY_PATH -export ORACLE_HOME=/usr/lib/oracle/18.3/client64 -# tar -zxvf DBD-Oracle-1.76.tar.gz # source /home/postgres/.bashrc -# cd DBD-Oracle-1.76 -# perl Makefile.PL -# make -# make install -``` - -==== 安装DBD-PG(可选) - -下载地址:https://metacpan.org/release/DBD-Pg/ - -设置环境变量: - -``` -export POSTGRES_HOME=/opt/ivorysql/2.1 -# tar -zxvf DBD-Pg-3.80.tar.gz -# source /home/ivorysql/.bashrc -# cd DBD-Pg-3.8.0 -# perl Makefile.PL -# make -# make install -``` - -=== 安装Ora2pg - -下载地址:https://sourceforge.net/projects/ora2pg/ - -``` -[root@Test01 ~]# tar -xjf ora2pg-20.0.tar.bz2 -[root@Test01 ~]# cd ora2pg-xx/ -[root@Test01 ~]# perl Makefile.PL PREFIX=<your_install_dir> -[root@Test01 ora2pg-18.2]# make && make install -``` - -默认安装在/usr/local/bin/目录下 - -检查软件环境: - -``` -[root@Test01 ~]# vi check.pl -#!/usr/bin/perl -use strict; -use ExtUtils::Installed; -my $inst= ExtUtils::Installed->new(); -my @modules = $inst->modules(); -foreach(@modules) -{ - my $ver = $inst->version($_) || "???"; - printf("%-12s -- %s\n", $_, $ver); - -} -exit; -[root@test01 bin]# perl check.pl -DBD::Oracle -- 1.76 -DBD::Pg -- 3.8.0 -DBI -- 1.642 -Ora2Pg -- 20.0 -Perl -- 5.16.3 -``` - -设置环境变量 - -``` -export PERL5LIB=<your_install_dir> -#export PERL5LIB=/usr/local/bin/ -``` - -=== 源端准备工作 - -更新oracle统计信息 提高性能 - -``` -BEGIN -DBMS_STATS.GATHER_SCHEMA_STATS('SH'); -DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT'); -DBMS_STATS.GATHER_SCHEMA_STATS('HR'); -DBMS_STATS.GATHER_DATABASE_STATS ; -DBMS_STATS.GATHER_DICTIONARY_STATS; -END;/ -``` - -查询源端对像对类型 - -``` -SYS@PROD1>set pagesize 200 -SYS@PROD1>select distinct OBJECT_TYPE from dba_objects where OWNER in ('SH','SCOTT','HR') ; -OBJECT_TYPE -------------------- -INDEX PARTITION -TABLE PARTITION -SEQUENCE -PROCEDURE -LOB X -TRIGGER -DIMENSION X -MATERIALIZED VIEW -TABLE -INDEX -VIEW -11 rows selected. -``` - -=== ora2pg导出表结构 - -**配置ora2pg.conf:** - -默认情况下,Ora2Pg会查找/etc/ora2pg/ora2pg.conf配置文件,如果文件存在,您只需执行:/usr/local/bin/ora2pg - -``` -cat /etc/ora2pg/ora2pg.conf.dist | grep -v ^# |grep -v ^$ >ora2pg.conf -vi ora2pg.conf -[root@test01 ora2pg]# cat ora2pg.conf -ORACLE_HOME /usr/lib/oracle/18.3/client64 -ORACLE_DSN dbi:Oracle:host=10.85.10.6 ;sid=PROD1;port=1521 -ORACLE_USER system -ORACLE_PWD oracle -SCHEMA SH -EXPORT_SCHEMA 1 # 将用户导入到PostgreSQL数据库中 DISABLE_UNLOGGED 1 #避免将NOLOGGING属性设为UNLOGGED -SKIP fkeys ukeys checks #跳过外键 唯一 和检查约束 -TYPE TABLE,VIEW,GRANT,SEQUENCE,TABLESPACE,PROCEDURE,TRIGGER,FUNCTION,PACKAGE,PARTITION,TYPE,MVIEW,QUERY,DBLINK,SYNONYM,DIRECTORY,TEST,TEST_VIEW -NLS_LANG AMERICAN_AMERICA.UTF8 -OUTPUT sh.sql -``` - -> 1. 只能同时执行一种类型的导出,因此TYPE指令必须是唯一的。如果您有多个,则只会在文件中找到最后一个。但我测试就可以同时导出多个类型的。 -> -> 2. 请注意,您可以通过向TYPE指令提供以逗号分隔的导出类型列表来链接多个导出,但在这种情况下,您不能将COPY或INSERT与其他导出类型一起使用。 -> -> 3. 某些导出类型不能或不应该直接加载到 IvorySQL 数据库中,仍然需要很少的手动编辑。GRANT,TABLESPACE,TRIGGER,FUNCTION,PROCEDURE,TYPE,QUERY和PACKAGE导出类型就是这种情况,特别是如果您有PLSQL代码或Oracle特定SQL。 -> 4. 对于TABLESPACE,您必须确保系统上存在文件路径,对于SYNONYM,您可以确保对象的所有者和模式对应于新的PostgreSQL数据库设计。 -> 5. 建议导出表结构时,一个类型一个类型的操作,避免其它错误相互影响。 - -==== **测试连接** - -设置Oracle数据库DSN后,您可以执行ora2pg以查看它是否有效: - -``` -[root@test01 ora2pg]# ora2pg -t SHOW_VERSION -c config/ora2pg.conf - -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 - -Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -``` - -==== 迁移成本评估 - -估算从Oracle到PostgreSQL的迁移过程的成本并不容易。为了获得对此迁移成本的良好评估,Ora2Pg将检查所有数据库对象,所有函数和存储过程,以检测是否仍有一些对象和PL / SQL代码无法由Ora2Pg自动转换。 - -Ora2Pg具有内容分析模式,该模式检查Oracle数据库以生成有关Oracle数据库包含的内容和无法导出的内容的文本报告。 - -``` -[root@test01 ora2pg]# ora2pg -t SHOW_REPORT --estimate_cost -c ora2pg.conf -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 -[========================>] 11/11 tables (100.0%) end of scanning. -[========================>] 11/11 objects types (100.0%) end of objects auditing. -------------------------------------------------------------------------------- -Ora2Pg v20.0 - Database Migration Report -------------------------------------------------------------------------------- -Version Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -Schema SH -Size 287.25 MB -------------------------------------------------------------------------------- -Object Number Invalid Estimated cost Comments Details -------------------------------------------------------------------------------- -DATABASE LINK 0 0 0 Database links will be exported as SQL/MED IvorySQL's Foreign Data Wrapper (FDW) extensions using oracle_fdw. -DIMENSION 5 0 0 -GLOBAL TEMPORARY TABLE 0 0 0 Global temporary table are not supported by PostgreSQL and will not be exported. You will have to rewrite some application code to match the PostgreSQL temporary table behavior. -INDEX 20 0 3.4 14 index(es) are concerned by the export, others are automatically generated and will do so on PostgreSQL. Bitmap will be exported as btree_gin index(es) and hash index(es) will be exported as b-tree index(es) if any. Domain index are exported as b-tree but commented to be edited to mainly use FTS. Cluster, bitmap join and IOT indexes will not be exported at all. Reverse indexes are not exported too, you may use a trigram-based index (see pg_trgm) or a reverse() function based index and search. Use 'varchar_pattern_ops', 'text_pattern_ops' or 'bpchar_pattern_ops' operators in your indexes to improve search with the LIKE operator respectively into varchar, text or char columns. 11 bitmap index(es). 1 domain index(es). 2 b-tree index(es). - -INDEX PARTITION 196 0 0 Only local indexes partition are exported, they are build on the column used for the partitioning. - -JOB 0 0 0 Job are not exported. You may set external cron job with them. - -MATERIALIZED VIEW 2 0 6 All materialized view will be exported as snapshot materialized views, they are only updated when fully refreshed. - -SYNONYM 0 0 0 SYNONYMs will be exported as views. SYNONYMs do not exists with PostgreSQL but a common workaround is to use views or set the PostgreSQL search_path in your session to access object outside the current schema. - -TABLE 11 0 1.1 1 external table(s) will be exported as standard table. See EXTERNAL_TO_FDW configuration directive to export as file_fdw foreign tables or use COPY in your code if you just want to load data from external files. Total number of rows: 1063384. Top 10 of tables sorted by number of rows:. sales has 918843 rows. costs has 82112 rows. customers has 55500 rows. supplementary_demographics has 4500 rows. times has 1826 rows. promotions has 503 rows. products has 72 rows. countries has 23 rows. channels has 5 rows. sales_transactions_ext has 0 rows. Top 10 of largest tables:. - -TABLE PARTITION 56 0 5.6 Partitions are exported using table inheritance and check constraint. Hash and Key partitions are not supported by PostgreSQL and will not be exported. 56 RANGE partitions.. - -VIEW 1 0 1 Views are fully supported but can use specific functions. - -------------------------------------------------------------------------------- - -Total 291 0 17.10 17.10 cost migration units means approximatively 1 man-day(s). The migration unit was set to 5 minute(s) ------------------------------------------------------------------------------- -Migration level : A-1 -------------------------------------------------------------------------------- -Migration levels: - - A - Migration that might be run automatically - - B - Migration with code rewrite and a human-days cost up to 5 days - - C - Migration with code rewrite and a human-days cost above 5 days - -Technical levels: - - 1 = trivial: no stored functions and no triggers - - 2 = easy: no stored functions but with triggers, no manual rewriting - - 3 = simple: stored functions and/or triggers, no manual rewriting - - 4 = manual: no stored functions but with triggers or views with code rewriting - - 5 = difficult: stored functions and/or triggers with code rewriting - -------------------------------------------------------------------------------- -``` - -==== **导出SH表构** - -``` -[root@test01 ora2pg]# ora2pg -c ora2pg.conf -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 -[========================>] 11/11 tables (100.0%) end of scanning. - -[========================>] 12/12 tables (100.0%) end of table export. - -[========================>] 1/1 views (100.0%) end of output. - -[========================>] 0/0 sequences (100.0%) end of output. - -[========================>] 0/0 procedures (100.0%) end of procedures export. - -[========================>] 0/0 triggers (100.0%) end of output. - -[========================>] 0/0 functions (100.0%) end of functions export. - -[========================>] 0/0 packages (100.0%) end of output. - -[========================>] 56/56 partitions (100.0%) end of output. - -[========================>] 0/0 types (100.0%) end of output. - -[========================>] 2/2 materialized views (100.0%) end of output. -[========================>] 0/0 dblink (100.0%) end of output. - -[========================>] 0/0 synonyms (100.0%) end of output. - -[========================>] 2/2 directory (100.0%) end of output. - -Fixing function calls in output files.... -``` - -==== **导出SH用户数据** - -配置ora2pg.conf 的TYPE 为COPY 或 INSERT - -``` -[root@test01 ora2pg]# cp ora2pg.conf sh_data.conf - -[root@test01 ora2pg]# vi sh_data.conf - -ORACLE_HOME /usr/lib/oracle/18.3/client64 - -ORACLE_DSN dbi:Oracle:host=10.85.10.6 ;sid=PROD1;port=1521 - -ORACLE_USER system - -ORACLE_PWD oracle - -SCHEMA SH - -EXPORT_SCHEMA 1 - -DISABLE_UNLOGGED 1 - -SKIP fkeys ukeys checks - -TYPE COPY - -NLS_LANG AMERICAN_AMERICA.UTF8 - -OUTPUT sh_data.sql -``` - -导出数据 - -``` -[root@test01 ora2pg]# ora2pg -c sh_data.conf - -WARNING: target PostgreSQL version must be set in PG_VERSION configuration directive. Using default: 11 - -[========================>] 11/11 tables (100.0%) end of scanning. - -[========================>] 5/5 rows (100.0%) Table CHANNELS (5 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_1995 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_H1_1997 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_1996 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -…………………………………………………………… - -[========================>] 4500/4500 rows (100.0%) Table SUPPLEMENTARY_DEMOGRAPHICS (4500 recs/sec) - -[=======================> ] 1061558/1063384 total rows (99.8%) - (45 sec., avg: 23590 recs/sec). - -[========================>] 1826/1826 rows (100.0%) Table TIMES (1826 recs/sec) - -[========================>] 1063384/1063384 total rows (100.0%) - (45 sec., avg: 23630 recs/sec). - -[========================>] 1063384/1063384 rows (100.0%) on total estimated data (45 sec., avg: 23630 recs/sec) - -Fixing function calls in output files... -``` - -查看导出的文件: - -``` -[root@test01 ora2pg]# ls -lrt *.sql - --rw-r--r-- 1 root root 15716 Jul 2 21:21 TABLE_sh.sql - --rw-r--r-- 1 root root 858 Jul 2 21:21 VIEW_sh.sql - --rw-r--r-- 1 root root 2026 Jul 2 21:21 TABLESPACE_sh.sql - --rw-r--r-- 1 root root 345 Jul 2 21:21 SEQUENCE_sh.sql - --rw-r--r-- 1 root root 2382 Jul 2 21:21 GRANT_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 TRIGGER_sh.sql - --rw-r--r-- 1 root root 346 Jul 2 21:21 PROCEDURE_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 PACKAGE_sh.sql - --rw-r--r-- 1 root root 345 Jul 2 21:21 FUNCTION_sh.sql - --rw-r--r-- 1 root root 6771 Jul 2 21:21 PARTITION_sh.sql - --rw-r--r-- 1 root root 341 Jul 2 21:21 TYPE_sh.sql - --rw-r--r-- 1 root root 342 Jul 2 21:21 QUERY_sh.sql - --rw-r--r-- 1 root root 950 Jul 2 21:21 MVIEW_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 SYNONYM_sh.sql - --rw-r--r-- 1 root root 926 Jul 2 21:21 DIRECTORY_sh.sql - --rw-r--r-- 1 root root 343 Jul 2 21:21 DBLINK_sh.sql - --rw-r--r-- 1 root root 55281235 Jul 2 17:11 sh_data.sql - - -``` - -以同样的方法分别导出HR,SCOTT用户数据。 - -=== 在IvorySQL环境中创建orcl库 - -创建ORCL 数据库 - -``` -[root@test01 ~]# su - ivorysql - -Last login: Tue Jul 2 20:04:30 CST 2019 on pts/3 - -[postgres@test01 ~]$ createdb orcl - -[postgres@test01 ~]$ psql - -psql (11.2) - -Type "help" for help. - - - -ivorysql=# \l - - List of databases - - Name | Owner | Encoding | Collate | Ctype | Access privileges - ------------+----------+----------+------------+------------+----------------------- - - orcl | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - pgdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + - - | | | | | postgres=CTc/postgres - - template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + - - | | | | | postgres=CTc/postgres - -(5 rows) - -ivorysql=# -``` - - 创建SH,HR,SCOTT 用户: - -``` -[postgres@test01 ~]$ psql orcl - -psql (11.2) - -Type "help" for help. - -orcl=# - -orcl=# create user sh with password 'sh'; - -CREATE ROLE -``` - -== 迁移门户 - -=== 导入表结构 - -由于有物化视图,在TABLE_sh.sql 里包含了物化视图的索引,会创建失败。需先创建表,在创建物化视图,最后创建索引。 - -取消物化视图索引,后面单独创建: - -``` -CREATE INDEX fw_psc_s_mv_chan_bix ON fweek_pscat_sales_mv (channel_id); - -CREATE INDEX fw_psc_s_mv_promo_bix ON fweek_pscat_sales_mv (promo_id); - -CREATE INDEX fw_psc_s_mv_subcat_bix ON fweek_pscat_sales_mv (prod_subcategory); - -CREATE INDEX fw_psc_s_mv_wd_bix ON fweek_pscat_sales_mv (week_ending_day); - -CREATE TEXT SEARCH CONFIGURATION en (COPY = pg_catalog.english); -ALTER TEXT SEARCH CONFIGURATION en ALTER MAPPING FOR hword, hword_part, word WITH unaccent, english_stem; -``` - -``` -psql orcl -f tab.sql.sql - -ALTER TABLE PARTITION sh.sales OWNER TO sh; -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -ALTER TABLE -ALTER TABLE -ALTER TABLE -……………………………… -``` - -=== 给对象授权 - -``` -cat psql orcl -f GRANT_sh.sql -CREATE USER SH WITH PASSWORD 'change_my_secret' LOGIN; -ALTER TABLE sh.fweek_pscat_sales_mv OWNER TO sh; -GRANT ALL ON sh.fweek_pscat_sales_mv TO sh; -``` - -=== 导入物化视图结构 - -物化视图需要相关查询权限,所以导入权限,注意这里要跟上用户 - -``` - [ivorysql@test01 ora2pg]$ psql orcl sh -f MVIEW_sh.sql -SELECT 0 -SELECT 0 -CREATE INDEX -CREATE INDEX -CREATE INDEX -CREATE INDEX -``` - -=== 导入视图 - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f VIEW_sh.sql -SET -SET -SET -CREATE VIEW - -``` - -=== 导入分区表 - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f PARTITION_sh.sql -SET -SET -SET -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -………………………… -``` - -=== 导入数据 - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f sh_data.sql -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 4500 -SET -COPY 1826 -COMMIT -``` - -== 数据验证 - -源库,目标端抽取部份对象对比: - -``` -SYS@PROD1>select count(*) from sh.products; - COUNT(*) ----------- - 72 - -orcl=# select count(*) from sh.products; - count -------- - 72 -(1 row) ---------------------------------------------------------------------------- - -SYS@PROD1>select count(*) from sh.channels; - - COUNT(*) - ----------- - - 5 - -orcl=# select count(*) from sh.channels; - count -------- - - 5 - -(1 row) - --------------------------------------------------------------------------- - -SYS@PROD1>select count(*) from sh.customers ; - - COUNT(*) ----------- - - 55500 -orcl=# select count(*) from sh.customers ; - count -------- - 55500 -(1 row) -``` - -== 生成迁移模板 - -使用时,两个选项--project_base和--init_project向ora2pg表明他必须创建一个项目模板,其中包含工作树,配置文件和从Oracle数据库导出所有对象的脚本。 生成通用配置文件。 1.创建脚本export_schema.sh以自动执行所有导出。2.创建脚本import_all.sh以自动执行所有导入。例: - -``` -mkdir -p /ora2pg/migration - -[root@test01 ora2pg-20.0]# ora2pg --project_base /ora2pg/migration/ --init_project test_project -Creating project test_project. -/ora2pg/migration//test_project/ - schema/ - dblinks/ - directories/ - functions/ - grants/ - mviews/ - packages/ - partitions/ - procedures/ - sequences/ - synonyms/ - tables/ - tablespaces/ - triggers/ - types/ - views/ - sources/ - functions/ - mviews/ - packages/ - partitions/ - procedures/ - triggers/ - types/ - views/ - data/ - config/ - reports/ -Generating generic configuration file -Creating script export_schema.sh to automate all exports. -Creating script import_all.sh to automate all imports. -``` diff --git a/EN/antora.yml b/EN/antora.yml index b940083..9736f2c 100644 --- a/EN/antora.yml +++ b/EN/antora.yml @@ -1,7 +1,7 @@ name: ivorysql-doc title: IvorySQL -version: v3.0 -start_page: v3.0/welcome.adoc +version: v1.17 +start_page: v1.17/welcome.adoc asciidoc: attributes: source-language: asciidoc@ diff --git a/EN/modules/ROOT/images/p19.png b/EN/modules/ROOT/images/p19.png new file mode 100644 index 0000000..68012c6 Binary files /dev/null and b/EN/modules/ROOT/images/p19.png differ diff --git a/EN/modules/ROOT/images/p20.jpg b/EN/modules/ROOT/images/p20.jpg new file mode 100644 index 0000000..b200c5a Binary files /dev/null and b/EN/modules/ROOT/images/p20.jpg differ diff --git a/EN/modules/ROOT/images/p21.jpg b/EN/modules/ROOT/images/p21.jpg new file mode 100644 index 0000000..a0c62a6 Binary files /dev/null and b/EN/modules/ROOT/images/p21.jpg differ diff --git a/EN/modules/ROOT/images/p22.jpg b/EN/modules/ROOT/images/p22.jpg new file mode 100644 index 0000000..1736f47 Binary files /dev/null and b/EN/modules/ROOT/images/p22.jpg differ diff --git a/EN/modules/ROOT/images/p31.png b/EN/modules/ROOT/images/p31.png new file mode 100644 index 0000000..51e0e02 Binary files /dev/null and b/EN/modules/ROOT/images/p31.png differ diff --git a/EN/modules/ROOT/images/p32.png b/EN/modules/ROOT/images/p32.png new file mode 100644 index 0000000..d8cc211 Binary files /dev/null and b/EN/modules/ROOT/images/p32.png differ diff --git a/EN/modules/ROOT/nav.adoc b/EN/modules/ROOT/nav.adoc index 30dcbac..d224e77 100644 --- a/EN/modules/ROOT/nav.adoc +++ b/EN/modules/ROOT/nav.adoc @@ -1,24 +1,38 @@ -* xref:v3.0/welcome.adoc[Welcome] -* xref:v3.0/1.adoc[Release] -* xref:v3.0/2.adoc[About] +* xref:v1.17/welcome.adoc[Welcome] +* xref:v1.17/1.adoc[Release] +* xref:v1.17/2.adoc[About] * Getting Started with IvorySQL -** xref:v3.0/3.adoc[User manual] -** xref:v3.0/4.adoc[Administrator] -** xref:v3.0/5.adoc[Operating personnel] -* xref:v3.0/6.adoc[Installation Deployment] -* xref:v3.0/7.adoc[Developer] -* xref:v3.0/8.adoc[Operation Management] -* xref:v3.0/9.adoc[Migration] -* xref:v3.0/10.adoc[Community contribution] -* xref:v3.0/11.adoc[Tool Reference] -* xref:v3.0/12.adoc[FAQ] -* List of features -** xref:v3.0/14.adoc[1、Ivorysql frame design] -** xref:v3.0/15.adoc[2、GUC Framework] -** xref:v3.0/16.adoc[3、Case conversion] -** xref:v3.0/17.adoc[4、Dual-mode design] -** xref:v3.0/18.adoc[5、Compatible with oracle like] -** xref:v3.0/19.adoc[6、Compatible with oracle anonymous block] -** xref:v3.0/20.adoc[7、Compatible with Oracle functions and stored procedures] -** xref:v3.0/21.adoc[8、Built-in data types and built-in functions] -** xref:v3.0/22.adoc[9、Added Oracle compatibility mode ports and IP] +** xref:v1.17/3.adoc[Quick Start] +** xref:v1.17/4.adoc[Monitoring] +** xref:v1.17/5.adoc[Maintenance] +* IvorySQL Advanced Feature +** xref:v1.17/6.adoc[Installation] +** xref:v1.17/7.adoc[Developer] +** xref:v1.17/8.adoc[Operation Management] +* IvorySQL Ecosystem +** xref:v1.17/33.adoc[Overview] +** xref:v1.17/9.adoc[PostGIS] +** xref:v1.17/10.adoc[pgvector] +** xref:v1.17/34.adoc[PGroonga] +** xref:v1.17/35.adoc[pgddl (DDL Extractor)] +** xref:v1.17/36.adoc[pgRouting] +** xref:v1.17/37.adoc[pg_cron] +** xref:v1.17/38.adoc[pgsql-http] +** xref:v1.17/40.adoc[pgvectorscale] +* List of Oracle compatible features +** xref:v1.17/11.adoc[1、Ivorysql frame design] +** xref:v1.17/12.adoc[2、GUC Framework] +** xref:v1.17/13.adoc[3、Case conversion] +** xref:v1.17/14.adoc[4、Dual-mode design] +** xref:v1.17/15.adoc[5、Compatible with Oracle like] +** xref:v1.17/16.adoc[6、Compatible with Oracle anonymous block] +** xref:v1.17/17.adoc[7、Compatible with Oracle functions and stored procedures] +** xref:v1.17/18.adoc[8、Built-in data types and built-in functions] +** xref:v1.17/19.adoc[9、Added Oracle compatibility mode ports and IP] +* IvorySQL Experimental Features +** xref:v1.17/41.adoc[1、Global Unique Index] +** xref:v1.17/42.adoc[2、Default Logical Replication Support for Tables Without Primary Key] +** xref:v1.17/43.adoc[3、Rebuild View After Column Type Changed] +* xref:v1.17/20.adoc[Community contribution] +* xref:v1.17/21.adoc[Tool Reference] +* xref:v1.17/22.adoc[FAQ] diff --git a/EN/modules/ROOT/pages/v1.17/1.adoc b/EN/modules/ROOT/pages/v1.17/1.adoc new file mode 100644 index 0000000..36c492e --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/1.adoc @@ -0,0 +1,57 @@ + +:sectnums: +:sectnumlevels: 5 + + +== Version Introduction + +[**Release date: Mar 26, 2025**] + +IvorySQL 1.17, based on PostgreSQL 14.17 and includes a variety of bug fixes. For a comprehensive list of updates, please https://docs.ivorysql.org/[visit our documentation site]. + +== Known Issues + +* None + +== Enhancements + +* PostgreSQL 14.17 +1. Disallow substituting a schema or owner name into an extension script if the name contains a quote, backslash, or dollar sign. +2. Fix handling of unknown-type arguments in DISTINCT "any" aggregate functions. +3. Tighten security restrictions within REFRESH MATERIALIZED VIEW CONCURRENTLY. +4. Restrict visibility of pg_stats_ext and pg_stats_ext_exprs entries to the table owner. +5. Prevent unauthorized code execution during pg_dump. +6. Ensure cached plans are marked as dependent on the calling role when RLS applies to a non-top-level table reference. +7. Repair ABI break for extensions that work with struct ResultRelInfo. +8. Harden PQescapeString and allied functions against invalidly-encoded input strings. +9. Improve behavior of libpq's quoting functions. + +For further details, please visit PostgreSQL's release notes. + +* IvorySQL 1.17 +1. ARM64 Packaging for All Platforms: + +Provides multi-platform media packages for ARM architecture, supporting both domestic and international mainstream operating systems, including Red Hat, Debian, Kylin, UOS, and NSAR OS, etc. +2. X86 Packaging for All Platforms + +Provides multi-platform media packages for X86 architecture, supporting both domestic and international mainstream operating systems, including Red Hat, Debian, Kylin, UOS, and NSAR OS, etc. +3. Support for more open source plugins + +Such as ddlx0.20, pgvector v0.8.0, PGroonga 3.0.0, PostGIS 3.4.0 and pgRouting3.5.1. + +== Source Code + +IvorySQL's development is maintained across two main repositories: + +* IvorySQL database source code: https://github.com/IvorySQL/IvorySQL[https://github.com/IvorySQL/IvorySQL] +* IvorySQL official website: https://github.com/IvorySQL/Ivory-www[https://github.com/IvorySQL/Ivory-www] + +== Contributors + +The following individuals (in alphabetical order) have contributed to this release as patch authors, committers, reviewers, testers, or reporters of issues. + +- Dapeng Wang +- Grant Zhou +- Shiji Niu +- Shuntian Jiao +- Xinjie Lv +- Xueyu Gao +- Zhenhao Pan +- Zheng Tao diff --git a/EN/modules/ROOT/pages/v1.17/10.adoc b/EN/modules/ROOT/pages/v1.17/10.adoc new file mode 100644 index 0000000..54247d8 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/10.adoc @@ -0,0 +1,126 @@ +:sectnums: +:sectnumlevels: 5 + += pgvector + +== Overview + +The vector database is an important component of Generative Artificial Intelligence (GenAI). As a significant extension of PostgreSQL, pgvector not only supports vector calculations of up to 16000 dimensions but also provides powerful vector operations and indexing capabilities, enabling PostgreSQL to directly transform into an efficient vector database. IvorySQL, being developed based on PostgreSQL, inherits the seamless integration capability with pgvector extension, thereby offering users a wider range of data processing and analysis options. Additionally, in Oracle compatibility mode, the pgvector extension is also available, providing great convenience for Oracle users to use vector databases, allowing for easy migration and management of data and achieving more efficient business operations. + + +== Principles + +PGVector has two indexing algorithms, IVFFLAT and HNSW. + +=== IVFFLAT + +The working principle of IVFFLAT is to cluster similar vectors into regions and build an inverted index mapping each region to its vectors. This allows queries to focus on a subset of the data, enabling fast searches. By adjusting the parameters of lists and probes, IVFFLAT can balance the speed and accuracy of the dataset, enabling PostgreSQL to perform rapid semantic similarity searches on complex data. Through simple queries, applications can find the nearest neighbors to a query vector among millions of high-dimensional vectors. For tasks such as natural language processing and information retrieval, IVFFLAT provides an effective solution. + +When building an IVFFLAT index, you need to decide how many lists to include in the index. Each list represents a "center" which are computed using the k-means algorithm. Once all centers are determined, IVFFLAT determines which center each vector is closest to and adds it to the index. When querying vector data, you can decide how many centers to check, which is determined by the ivfflat.probes parameter. This results in a trade-off between ANN performance/recall: the more centers accessed, the more accurate the results, but at the expense of performance. + +=== HNSW + + +HNSW (Hierarchical Navigating Small World) is a graph-based indexing algorithm consisting of multiple layers of neighborhood graphs, hence the name "hierarchical" NSW method. It constructs multiple layers of navigation graphs for a given graph according to certain rules, with the upper layers of the graph being sparser and the distances between nodes farther apart; and the lower layers of the graph being denser and the distances between nodes closer together. HNSW algorithm is a classic trade-off between space and time, as it achieves high search quality and speed, but at the cost of significant memory overhead. This is because it not only requires storing all vectors in memory but also maintaining the structure of the graph, which also needs to be stored. + +== Installation +[TIP] +==== +The IvorySQL 4.2(above version) has been installed in the environment, and the installation path is /usr/local/ivorysql/ivorysql-4 +==== + +=== Source Code Installation + +** Setting PG_CONFIG +``` +export PG_CONFIG=/usr/local/ivorysql/ivorysql-4/bin/pg_config +``` + +** Pull pg_vector source code +``` +git clone --branch v0.8.0 https://github.com/pgvector/pgvector.git +``` + +** Install pgvector +``` +cd pgvector + +sudo --preserve-env=PG_CONFIG make +sudo --preserve-env=PG_CONFIG make install +``` + +** Create pgvector extension +``` +[ivorysql@localhost ivorysql-4]$ psql +psql (17.2) +Type "help" for help. + +ivorysql=# create extension vector; +CREATE EXTENSION +``` +Now, pgvector is installed completely. +For more usage cases, please refer to https://github.com/pgvector/pgvector?tab=readme-ov-file#getting-started[pgvector document] + +== Oracle Compatible +In IvorySQL's Oracle compatibility mode, the pgvector extension can also work correctly. +[TIP] +We suggest users to test using port 1521, using the command: psql -p 1521. + +=== Data Type + +``` +ivorysql=# CREATE TABLE items5 (id bigserial PRIMARY KEY, name varchar2(20), num number(20), embedding bit(3)); +CREATE TABLE +ivorysql=# INSERT INTO items5 (name, num, embedding) VALUES ('1st oracle data',0, '000'), ('2nd oracle data', 111, '111'); +INSERT 0 2 +ivorysql=# SELECT * FROM items5 ORDER BY bit_count(embedding # '101') LIMIT 5; + id | name | num | embedding +----+-----------------+-----+----------- + 2 | 2nd oracle data | 111 | 111 + 1 | 1st oracle data | 0 | 000 +``` + +=== Anonymous Block + +``` +ivorysql=# declare +i vector(3) := '[1,2,3]'; +begin +raise notice '%', i; +end; +ivorysql-# / +NOTICE: [1,2,3] +DO +``` + +=== PROCEDURE +``` +ivorysql=# CREATE OR REPLACE PROCEDURE ora_procedure() +AS +p vector(3) := '[4,5,6]'; +begin +raise notice '%', p; +end; +/ +CREATE PROCEDURE +ivorysql=# call ora_procedure(); +NOTICE: [4,5,6] +CALL +``` + +==== FUNCTION +``` +ivorysql=# CREATE OR REPLACE FUNCTION AddVector(a vector(3), b vector(3)) +RETURN vector(3) +IS +BEGIN +RETURN a + b; +END; +/ +CREATE FUNCTION +ivorysql=# SELECT AddVector('[1,2,3]','[4,5,6]') FROM DUAL; + addvector +---------------- + [5,7,9] +(1 row) +``` \ No newline at end of file diff --git a/EN/modules/ROOT/pages/v3.0/14.adoc b/EN/modules/ROOT/pages/v1.17/11.adoc similarity index 100% rename from EN/modules/ROOT/pages/v3.0/14.adoc rename to EN/modules/ROOT/pages/v1.17/11.adoc diff --git a/EN/modules/ROOT/pages/v3.0/15.adoc b/EN/modules/ROOT/pages/v1.17/12.adoc similarity index 97% rename from EN/modules/ROOT/pages/v3.0/15.adoc rename to EN/modules/ROOT/pages/v1.17/12.adoc index 5c2a82d..8c098c8 100644 --- a/EN/modules/ROOT/pages/v3.0/15.adoc +++ b/EN/modules/ROOT/pages/v1.17/12.adoc @@ -3,6 +3,8 @@ :imagesdir: ./_images += GUC Framework + == New GUC variables In order to be compatible with Oracle, it is necessary to add some variables for controlling the database execution results on the basis of the original GUC variables, so as to achieve the same behavior as Oracle. @@ -23,7 +25,6 @@ When adding guc parameters, we need to add them uniformly in the *ivy_guc.c*. Wh | ivorysql.database_mode | Indicates the current database schema (pg/oracle), which can be viewed through the show command. The set/reset/reset all command does not affect this variable | ivorysql.datetime_ignore_nls_mask | Indicates whether the date format will be affected by the NLS parameter. The default value is 0, which can be set using the set command. The reset command resets the date format, and the reset all command resets the variable | ivorysql.enable_emptystring_to_NULL | The value is (on/off), and when this variable is on, it will convert the inserted empty string into a NULL value for storage -| ivorysql.identifier_case_switch | Set character case conversion mode | ivorysql.listen_address | Indicates the address for compatibility mode listening. When initializing the database, read the configuration from the ivorysql.conf file, modify the value in the configuration file, and restart the database to take effect. This can be viewed through the show command | ivorysql.port | Indicates the port number for connecting in compatibility mode. When initializing the database, read the configuration from the ivorysql.conf file and modify the value in the configuration file. To take effect, restart the database and view it through the show command | nls_date_format | Represents the default date format, which can be viewed through the show command and defaults to 'YYYY-MM-DD'. It can be set through the set command and reset back to the default value through the reset command. The reset all command will reset this variable diff --git a/EN/modules/ROOT/pages/v1.17/13.adoc b/EN/modules/ROOT/pages/v1.17/13.adoc new file mode 100644 index 0000000..96d9236 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/13.adoc @@ -0,0 +1,293 @@ + +:sectnums: +:sectnumlevels: 5 + += Reference identifier case conversion design + +== Objective + +- In order to meet the case compatibility of PG and Oracle's reference identifiers, ivorysql has designed three case conversion modes for reference identifiers. Select the conversion mode via the GUC parameter "identifier_case_switch"; + +== Function + +=== Three modes of case conversion (interchange by default) + +- If the value of the guc parameter "identifier_case_switch" is "normal": + + 1). The letters in the identifier referenced by the double quotation mark are left unchanged. + +- If the value of the guc parameter "identifier_case_switch" is "interchange": + + 1). If the letters in the identifier referenced by the double quotation mark are all uppercase, uppercase is converted to lowercase. + + 2). If the letters in the identifier referenced by the double quotation mark are all lowercase, lowercase is converted to uppercase. + + 3). If the letters in the identifier enclosed in double quotation marks are mixed-case, the identifier is left unchanged. + +- If the value of the guc parameter "identifier_case_switch" is "lowercase": + + 1). If the letters in the identifier referenced by the double quotation mark are all uppercase, uppercase is converted to lowercase. + + 2). If the letters in the identifier enclosed in double quotation marks are mixed-case, the identifier is left unchanged. + +=== When the database cluster is initialized + +- Add the -C option to the initdb program to set the case conversion mode, and the corresponding value of -C is: + + "normal" ------ "0"synonymy + + "interchange" ------ "1"synonymy + + "lowercase" ------ "2"synonymy + +During initialization of the database cluster, the case conversion pattern is saved to the global/pg_control file in the data directory; + + +=== Use Cases + +**normal** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = normal; +SET + +ivorysql=# CREATE TABLE "NORMAL_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Normal_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "normal_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "NORMAL_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Normal_1"; +ERROR: relation "Normal_1" does not exist +LINE 1: select * from "Normal_1"; + +ivorysql=# select * from "normal_1"; +ERROR: relation "normal" does not exist +LINE 1: select * from "normal"; + +ivorysql=# select * from NORMAL_1; +ERROR: relation "normal_1" does not exist +LINE 1: select * from NORMAL_1; + +ivorysql=# select * from "Normal_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "NORMAL_2"; +ERROR: relation "NORMAL_2" does not exist +LINE 1: select * from "NORMAL_2"; + +ivorysql=# select * from "normal_2"; +ERROR: relation "normal_2" does not exist +LINE 1: select * from "normal_2"; + +ivorysql=# select * from Normal_2; +ERROR: relation "normal_2" does not exist +LINE 1: select * from Normal_2; + +ivorysql=# select * from "normal_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "NORMAL_3"; +ERROR: relation "NORMAL_3" does not exist +LINE 1: select * from "NORMAL_3"; + +ivorysql=# select * from "Normal_3"; +ERROR: relation "Normal_3" does not exist +LINE 1: select * from "Normal_3"; + +ivorysql=# drop table "NORMAL_1"; +DROP TABLE +ivorysql=# drop table "Normal_2"; +DROP TABLE +ivorysql=# drop table "normal_3"; +DROP TABLE +``` + +**interchange** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = interchange; +SET + +ivorysql=# CREATE TABLE "INTER_CHANGE_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Inter_Change_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "inter_change_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "INTER_CHANGE_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Inter_Change_1"; +ERROR: relation "Inter_Change_1" does not exist +LINE 1: select * from "Inter_Change_1"; + +ivorysql=# select * from "inter_change_1"; +ERROR: relation "INTER_CHANGE_1" does not exist +LINE 1: select * from "inter_change_1"; + +ivorysql=# select * from INTER_CHANGE_1; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Inter_Change_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "INTER_CHANGE_2"; +ERROR: relation "inter_change_2" does not exist +LINE 1: select * from "INTER_CHANGE_2"; + +ivorysql=# select * from "inter_change_2"; +ERROR: relation "INTER_CHANGE_2" does not exist +LINE 1: select * from "inter_change_2"; + +ivorysql=# select * from Inter_Change_2; +ERROR: relation "inter_change_2" does not exist +LINE 1: select * from Inter_Change_2; + +ivorysql=# select * from "inter_change_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "INTER_CHANGE_3"; +ERROR: relation "inter_change_3" does not exist +LINE 1: select * from "INTER_CHANGE_3"; + +ivorysql=# select * from "Inter_Change_3"; +ERROR: relation "Inter_Change_3" does not exist +LINE 1: select * from "Inter_Change_3"; + +ivorysql=# select * from inter_change_3; +ERROR: relation "inter_change_3" does not exist +LINE 1: select * from "INTER_CHANGE_3"; + +ivorysql=# drop table "INTER_CHANGE_1"; +DROP TABLE +ivorysql=# drop table "Inter_Change_2"; +DROP TABLE +ivorysql=# drop table "inter_change_3"; +DROP TABLE +``` + +**lowercase** +``` +ivorysql=# SET ivorysql.compatible_mode to oracle; +SET + +ivorysql=# SET ivorysql.enable_case_switch = true; +SET + +ivorysql=# SET ivorysql.identifier_case_switch = lowercase; +SET + +ivorysql=# CREATE TABLE "LOWER_CASE_1"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "Lower_Case_2"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# CREATE TABLE "lower_case_3"(c1 int, c2 int); +CREATE TABLE + +ivorysql=# select * from "LOWER_CASE_1"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Lower_Case_1"; +ERROR: relation "Lower_Case_1" does not exist +LINE 1: select * from "Lower_Case_1"; + +ivorysql=# select * from "lower_case_1"; + c1 | c2 +----+---- +(0 rows) + + +ivorysql=# select * from LOWER_CASE_1; + c1 | c2 +----+---- +(0 rows) + + +ivorysql=# select * from "Lower_Case_2"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "LOWER_CASE_2"; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from "LOWER_CASE_2"; + +ivorysql=# select * from "lower_case_2"; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from "lower_case_2"; + +ivorysql=# select * from Lower_Case_2; +ERROR: relation "lower_case_2" does not exist +LINE 1: select * from Lower_Case_2; + +ivorysql=# select * from "lower_case_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "LOWER_CASE_3"; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# select * from "Lower_Case_3"; +ERROR: relation "Lower_Case_3" does not exist +LINE 1: select * from "Lower_Case_3"; + +ivorysql=# select * from LOWER_CASE_3; + c1 | c2 +----+---- +(0 rows) + +ivorysql=# drop table "NORMAL_1"; +DROP TABLE +ivorysql=# drop table "Normal_2"; +DROP TABLE +ivorysql=# drop table "normal_3"; +DROP TABLE +``` + + + + + + + diff --git a/EN/modules/ROOT/pages/v3.0/17.adoc b/EN/modules/ROOT/pages/v1.17/14.adoc similarity index 94% rename from EN/modules/ROOT/pages/v3.0/17.adoc rename to EN/modules/ROOT/pages/v1.17/14.adoc index 3817d9e..aa19841 100644 --- a/EN/modules/ROOT/pages/v3.0/17.adoc +++ b/EN/modules/ROOT/pages/v1.17/14.adoc @@ -1,52 +1,52 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Dual-mode design - -== Objective - -- In order to meet the PG mode and the compatible Oracle mode, IVORYSQL designed two modes: PG and Oracle. And the schema can be specified at initdb time; - -== Function - -- Initdb -m initialization requires judgment of different modes, among which oracle mode requires the execution of SQL statements postgres_oracle.bki. The default is Oracle compatibility mode, and the process is as follows: - -- Startup: When starting, it determines whether it is an Oracle compatibility mode based on the initialization mode; - -``` -Description: -database_mode: Used to indicate initialization mode; -database_mode=DB_PG,PG mode, and cannot be switched; -database_mode=DB_ORACLE, oracle compatibility mode; -``` - -== Test cases - -``` -Initialize the PG mode: -./initdb -D ../data -m pg - -Initialize the Oracle compatibility mode: -./initdb -D ../data -m oracle - -or -./initdb -D ../data -``` - - - - - - - - - - - - - - - - +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Dual-mode design + +== Objective + +- In order to meet the PG mode and the compatible Oracle mode, IVORYSQL designed two modes: PG and Oracle. And the schema can be specified at initdb time; + +== Function + +- Initdb -m initialization requires judgment of different modes, among which oracle mode requires the execution of SQL statements postgres_oracle.bki. The default is Oracle compatibility mode, and the process is as follows: + +- Startup: When starting, it determines whether it is an Oracle compatibility mode based on the initialization mode; + +``` +Description: +database_mode: Used to indicate initialization mode; +database_mode=DB_PG,PG mode, and cannot be switched; +database_mode=DB_ORACLE, oracle compatibility mode; +``` + +== Test cases + +``` +Initialize the PG mode: +./initdb -D ../data -m pg + +Initialize the Oracle compatibility mode: +./initdb -D ../data -m oracle + +or +./initdb -D ../data +``` + + + + + + + + + + + + + + + + diff --git a/EN/modules/ROOT/pages/v3.0/18.adoc b/EN/modules/ROOT/pages/v1.17/15.adoc similarity index 98% rename from EN/modules/ROOT/pages/v3.0/18.adoc rename to EN/modules/ROOT/pages/v1.17/15.adoc index 733b5dc..4018f9d 100644 --- a/EN/modules/ROOT/pages/v3.0/18.adoc +++ b/EN/modules/ROOT/pages/v1.17/15.adoc @@ -1,69 +1,69 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Compatible with Oracle Like - -== Objective - -- This document is intended to provide people using like fuzzy queries with an in-depth understanding of Oracle-compatible fuzzy query like implementations. - -== Function description -|==== -|Database name|Like fuzzy queries -|oracle|oracle's string type is varchar2, which supports fuzzy queries using the Like keyword with wildcards for columns of number, date, and string field types -|IvorySQL|The basic type of IvorySQL's string is text, so like is based on text, and other IvorySQL types can be implicitly converted to text, so that they can be automatically converted without creating opeartor -|==== - -== Test cases - -``` - -create table t_ora_like (id int ,str1 varchar(8), date1 timestamp with time zone, date2 time with time zone, num int, str2 varchar(8)); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123456,'test1','2022-09-26 16:39:20','2022-09-26 16:39:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123457,'test2','2022-09-26 16:40:20','2022-09-26 16:40:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (223456,'test3','2022-09-26 16:41:20','2022-09-26 16:41:20'); -insert into t_ora_like (id ,str1 ,date1 ,date2) values (123458,'test4','2022-09-26 16:42:20','2022-09-26 16:42:20'); - -select * from t_ora_like where str1 like 'test%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where date1 like '2022%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where date2 like '16%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(4 rows) - -select * from t_ora_like where id like '123%'; - id | str1 | date1 | date2 | num | str2 ---------+-------+-----------------------------------+-------------+-----+------ - 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | - 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | - 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | -(3 rows) - -select * from t_ora_like where id like null; - id | str1 | date1 | date2 | num | str2 -----+------+-------+-------+-----+------ -(0 rows) - -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Compatible with Oracle Like + +== Objective + +- This document is intended to provide people using like fuzzy queries with an in-depth understanding of Oracle-compatible fuzzy query like implementations. + +== Function description +|==== +|Database name|Like fuzzy queries +|oracle|oracle's string type is varchar2, which supports fuzzy queries using the Like keyword with wildcards for columns of number, date, and string field types +|IvorySQL|The basic type of IvorySQL's string is text, so like is based on text, and other IvorySQL types can be implicitly converted to text, so that they can be automatically converted without creating opeartor +|==== + +== Test cases + +``` + +create table t_ora_like (id int ,str1 varchar(8), date1 timestamp with time zone, date2 time with time zone, num int, str2 varchar(8)); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123456,'test1','2022-09-26 16:39:20','2022-09-26 16:39:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123457,'test2','2022-09-26 16:40:20','2022-09-26 16:40:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (223456,'test3','2022-09-26 16:41:20','2022-09-26 16:41:20'); +insert into t_ora_like (id ,str1 ,date1 ,date2) values (123458,'test4','2022-09-26 16:42:20','2022-09-26 16:42:20'); + +select * from t_ora_like where str1 like 'test%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where date1 like '2022%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where date2 like '16%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 223456 | test3 | 2022-09-26 16:41:20.000000 +08:00 | 16:41:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(4 rows) + +select * from t_ora_like where id like '123%'; + id | str1 | date1 | date2 | num | str2 +--------+-------+-----------------------------------+-------------+-----+------ + 123456 | test1 | 2022-09-26 16:39:20.000000 +08:00 | 16:39:20+08 | | + 123457 | test2 | 2022-09-26 16:40:20.000000 +08:00 | 16:40:20+08 | | + 123458 | test4 | 2022-09-26 16:42:20.000000 +08:00 | 16:42:20+08 | | +(3 rows) + +select * from t_ora_like where id like null; + id | str1 | date1 | date2 | num | str2 +----+------+-------+-------+-----+------ +(0 rows) + +``` diff --git a/EN/modules/ROOT/pages/v3.0/19.adoc b/EN/modules/ROOT/pages/v1.17/16.adoc similarity index 92% rename from EN/modules/ROOT/pages/v3.0/19.adoc rename to EN/modules/ROOT/pages/v1.17/16.adoc index 4fe7242..8bd1db7 100644 --- a/EN/modules/ROOT/pages/v3.0/19.adoc +++ b/EN/modules/ROOT/pages/v1.17/16.adoc @@ -1,49 +1,47 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Compatible with Oracle anonymous block - -== Objective - -- This document is a design document for the PLSQL anonymous block compatible Oracle syntax function, in order to be compatible with Oracle's anonymous block statements in IvorySQL. - -== Function description - -- Anonymous blocks are PLSQL structures that dynamically create and execute procedural code without the need to persistently store the code as database objects in the system directory. In this implementation, IvorySQL is mainly compatible with the syntax format of PLSQL anonymous blocks, and the parts we mainly deal with include client tool psql, master server and PSQL side support. - -== Test cases - -``` - -declare -i integer := 10; -begin - raise notice '%', i; - raise notice '%', main.i; -end; -/ -NOTICE: 10 -NOTICE: 10 - -``` - -``` - -DECLARE - grade CHAR(1); -BEGIN - grade := 'B'; - CASE grade - WHEN 'A' THEN raise notice 'Excellent'; - WHEN 'B' THEN raise notice 'Very Good'; - END CASE; -EXCEPTION - WHEN CASE_NOT_FOUND THEN - raise notice 'No such grade'; -END; -/ -NOTICE: Very Good - -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Compatible with Oracle anonymous block + +== Objective + +- This document is a design document for the PLSQL anonymous block compatible Oracle syntax function, in order to be compatible with Oracle's anonymous block statements in IvorySQL. + +== Function description + +- Anonymous blocks are PLSQL structures that dynamically create and execute procedural code without the need to persistently store the code as database objects in the system directory. In this implementation, IvorySQL is mainly compatible with the syntax format of PLSQL anonymous blocks, and the parts we mainly deal with include client tool psql, master server and PSQL side support. + +== Test cases + +``` + +declare +i integer := 10; +begin + raise notice '%', i; +end; +/ +NOTICE: 10 + +``` + +``` + +DECLARE + grade CHAR(1); +BEGIN + grade := 'B'; + CASE grade + WHEN 'A' THEN raise notice 'Excellent'; + WHEN 'B' THEN raise notice 'Very Good'; + END CASE; +EXCEPTION + WHEN CASE_NOT_FOUND THEN + raise notice 'No such grade'; +END; +/ +NOTICE: Very Good + +``` diff --git a/EN/modules/ROOT/pages/v3.0/20.adoc b/EN/modules/ROOT/pages/v1.17/17.adoc similarity index 96% rename from EN/modules/ROOT/pages/v3.0/20.adoc rename to EN/modules/ROOT/pages/v1.17/17.adoc index 0357616..9b01d61 100644 --- a/EN/modules/ROOT/pages/v3.0/20.adoc +++ b/EN/modules/ROOT/pages/v1.17/17.adoc @@ -1,85 +1,85 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Compatible with Oracle functions and stored procedures - -== Objective - -- This document is intended to be compatible with the syntax of Oracle PLSQL functions and stored procedures, which we call PLISQL in IvorySQL. - -== Function description - -.FUNCTION -|==== -|THE FUNCTION SYNTAX SUPPORTS EDITIONABLE/NONEDITIONABLE -|THE FUNCTION syntax supports the RETURN, IS keywords, and does not specify language -|THE FUNCTION syntax functions have no arguments, and the function name does not follow () -|The maximum number of CREATE FUNCTION parameters is 32767 -|THE CREATE FUNCTION in END; End with / in psql -|THE CREATE FUNCTION syntax variable declaration is not preceded by the DECLARE keyword -|THE CREATE FUNCTION SYNTAX SUPPORTS THE OUT PARAMETER NOCOPY -|THE CREATE FUNCTION syntax supports sharing_clause -|THE CREATE FUNCTION syntax supports invoker_rights_clause, and the default permission is changed to DR (DEFINER) -|THE CREATE FUNCTION syntax supports ACCESSIBLE BY  -|THE CREATE FUNCTION SYNTAX SUPPORTS DEFAULT COLLATION -|THE CREATE FUNCTION syntax supports result_cache_clause  -|THE CREATE FUNCTION syntax supports aggregate_clause -|THE CREATE FUNCTION syntax supports pipelined_clause -|THE CREATE FUNCTION syntax supports sql_macro_clause -|ALTER FUNCTION syntax -|Functions and stored procedure-related views -|==== - -.Stored procedures -|==== -|THE CREATE PROCEDURE SYNTAX SUPPORTS EDITIONABLE/NONEDITIONABLE -|THE CREATE PROCEDURE syntax function has no arguments, no () after the function name -|The maximum number of CREATE PROCEDURE parameters is 32767 -|THE CREATE PROCEDURE in END; End with / in psql -|THE CREATE PROCEDURE syntax supports sharing_clause -|THE CREATE PROCEDURE SYNTAX SUPPORTS DEFAULT COLLATION -|THE CREATE PROCEDURE syntax supports invoker_rights_clause -|THE CREATE PROCEDURE syntax supports ACCESSIBLE BY  -|ALTER PROCEDURE syntax -|Stored procedures have no parameters, and invocation support is not carried out with () -|Stored procedure calls support EXEC -|When calling a stored procedure in PL/SQL, you can omit CALL and use the stored procedure name directly -|Both annotation methods are supported -- and /**/ -|==== - -== Test cases - -``` - -declare -i integer := 10; -begin - raise notice '%', i; - raise notice '%', main.i; -end; -/ -NOTICE: 10 -NOTICE: 10 - -``` - -``` - -DECLARE - grade CHAR(1); -BEGIN - grade := 'B'; - CASE grade - WHEN 'A' THEN raise notice 'Excellent'; - WHEN 'B' THEN raise notice 'Very Good'; - END CASE; -EXCEPTION - WHEN CASE_NOT_FOUND THEN - raise notice 'No such grade'; -END; -/ -NOTICE: Very Good - -``` +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Compatible with Oracle functions and stored procedures + +== Objective + +- This document is intended to be compatible with the syntax of Oracle PLSQL functions and stored procedures, which we call PLISQL in IvorySQL. + +== Function description + +.FUNCTION +|==== +|THE FUNCTION SYNTAX SUPPORTS EDITIONABLE/NONEDITIONABLE +|THE FUNCTION syntax supports the RETURN, IS keywords, and does not specify language +|THE FUNCTION syntax functions have no arguments, and the function name does not follow () +|The maximum number of CREATE FUNCTION parameters is 32767 +|THE CREATE FUNCTION in END; End with / in psql +|THE CREATE FUNCTION syntax variable declaration is not preceded by the DECLARE keyword +|THE CREATE FUNCTION SYNTAX SUPPORTS THE OUT PARAMETER NOCOPY +|THE CREATE FUNCTION syntax supports sharing_clause +|THE CREATE FUNCTION syntax supports invoker_rights_clause, and the default permission is changed to DR (DEFINER) +|THE CREATE FUNCTION syntax supports ACCESSIBLE BY  +|THE CREATE FUNCTION SYNTAX SUPPORTS DEFAULT COLLATION +|THE CREATE FUNCTION syntax supports result_cache_clause  +|THE CREATE FUNCTION syntax supports aggregate_clause +|THE CREATE FUNCTION syntax supports pipelined_clause +|THE CREATE FUNCTION syntax supports sql_macro_clause +|ALTER FUNCTION syntax +|Functions and stored procedure-related views +|==== + +.Stored procedures +|==== +|THE CREATE PROCEDURE SYNTAX SUPPORTS EDITIONABLE/NONEDITIONABLE +|THE CREATE PROCEDURE syntax function has no arguments, no () after the function name +|The maximum number of CREATE PROCEDURE parameters is 32767 +|THE CREATE PROCEDURE in END; End with / in psql +|THE CREATE PROCEDURE syntax supports sharing_clause +|THE CREATE PROCEDURE SYNTAX SUPPORTS DEFAULT COLLATION +|THE CREATE PROCEDURE syntax supports invoker_rights_clause +|THE CREATE PROCEDURE syntax supports ACCESSIBLE BY  +|ALTER PROCEDURE syntax +|Stored procedures have no parameters, and invocation support is not carried out with () +|Stored procedure calls support EXEC +|When calling a stored procedure in PL/SQL, you can omit CALL and use the stored procedure name directly +|Both annotation methods are supported -- and /**/ +|==== + +== Test cases + +``` + +declare +i integer := 10; +begin + raise notice '%', i; + raise notice '%', main.i; +end; +/ +NOTICE: 10 +NOTICE: 10 + +``` + +``` + +DECLARE + grade CHAR(1); +BEGIN + grade := 'B'; + CASE grade + WHEN 'A' THEN raise notice 'Excellent'; + WHEN 'B' THEN raise notice 'Very Good'; + END CASE; +EXCEPTION + WHEN CASE_NOT_FOUND THEN + raise notice 'No such grade'; +END; +/ +NOTICE: Very Good + +``` diff --git a/EN/modules/ROOT/pages/v3.0/21.adoc b/EN/modules/ROOT/pages/v1.17/18.adoc similarity index 92% rename from EN/modules/ROOT/pages/v3.0/21.adoc rename to EN/modules/ROOT/pages/v1.17/18.adoc index 7d9f952..14d43f6 100644 --- a/EN/modules/ROOT/pages/v3.0/21.adoc +++ b/EN/modules/ROOT/pages/v1.17/18.adoc @@ -1,963 +1,1031 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Built-in data types and built-in functions - -== Built-in data types - -|==== -|char -|varchar -|varchar2 -|number -|binary_float -|binary_double -|date -|timestamp -|timestamp with time zone -|timestamp with local time zone -|interval year to month -|interval day to second -|raw -|long -|==== - -== Built-in functions - -|==== -|sysdate -|systimestamp -|add_months -|last_day -|next_day -|months_between -|current_date -|current_timestamp -|new_time -|tz_offset -|trunc -|instrb -|substr -|substrb -|trim -|ltrim -|rtrim -|length -|lengthb -|rawtohex -|replace -|regexp_replace -|regexp_substr -|regexp_instr -|regexp_like -|to_number -|to_char -|to_date -|to_timestamp -|to_timestamp_tz -|to_yminterval -|to_dsinterval -|numtodsinterval -|numtoyminterval -|localtimestamp -|from_tz -|sys_extract_utc -|sessiontimezone -|hextoraw -|uid -|USERENV -|==== - -== Built-in function descriptions - -1、Compatible with sysdate function, function: view the corresponding date and time, the test cases are as follows: -Query the date of the current system: - -``` -select sysdate() from dual; - sysdate ------------- - 2023-07-06 -(1 row) -``` - -Check the date pushed forward by 1 day: - -``` -select sysdate()-1 from dual; - ?column? ------------- - 2023-07-05 -(1 row) -``` - -2、Compatible with the systimestamp function, function: return the current system date and time (including microseconds and time zone) on the local database, the test cases are as follows: -Date and time to query the current date: - -``` -select systimestamp() from dual; - systimestamp ------------------------------------ - 2023-07-06 10:18:31.674322 +08:00 -(1 row) -``` - -3、Compatible with add_months functions, function: the function adds a date to the number of months (n), and returns the same day that is n months apart, supporting parameters: date, number; The test cases are as follows: -Check the same day of the following month on the current date (July 6): - -``` -select add_months(sysdate(),1) from dual; - add_months ------------- - 2023-08-06 -(1 row) -``` - -Query the same day of the previous month for the current date: - -``` -select add_months(sysdate(),-1) from dual; - add_months ------------- - 2023-06-06 -(1 row) -``` - -4、Compatible with last_day functions, function: return the last day of the month where the specified date is located, support parameters: date, the test cases are as follows: -Check the last day of the month in which the day is located: - -``` -select last_day(sysdate())from dual; - last_day ------------- - 2023-07-31 -(1 row) -``` - -Query the last day of the month on which a day falls: - -``` -select last_day(to_date('2019-09-01'))from dual; - last_day ------------- - 2019-09-30 -(1 row) -``` - -5、 Compatible with next_day functions, function: return the next date of the specified date. Supported parameters: date, integer /date, text, Note: When the second parameter in the function passes the number of weeks more hours than the existing week, the date of the next week will be returned; When the date passed by the second parameter in the function is greater than the existing number of weeks, the corresponding day of the week of the week is returned. The test cases are as follows: -Query the next day of the current date: - -``` -select next_day(sysdate(),1) from dual; - next_day ------------- - 2023-07-07 -(1 row) -``` - -Next Friday for the current date: - -``` -select next_day(sysdate(),'FRIDAY') from dual; - next_day ------------- - 2023-07-07 -(1 row) -``` - -6、Compatible with months_between functions, function: return the month of difference between date1 and date2 of date type, support parameters: date, date, description: if date1 is later than date2, return a positive number; If date1 is earlier than date2, a negative number is returned; If date1 and date2 are the same day of a month, the return result is an integer; If not the same day, results with decimal parts are returned on a monthly basis of 31 days. The test cases are as follows: -To find the month that differs between the same day in different months: - -``` -select months_between(to_date('2023-07-06'),to_date('2023-08-06')) from dual; - months_between ----------------- - -1 -(1 row) -``` - -Query the month that differs between different days of different months: - -``` -select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; - months_between --------------------- - -0.967741935483871 -(1 row) -``` - -7、Compatible with current_date functions, functions: return the current date of the current time zone, the test cases are as follows: -To query the current date in the current time zone: - -``` -select current_date from dual; - current_date --------------- - 2023-07-06 -(1 row) -``` - -8、Compatible with current_timestamp functions, function: return the current date and current time of the current time zone, including the current time zone information. Support parameters: integer, Note: The returned time can be adjusted with precision. The test cases are as follows: -To query the current date and time in the current time zone: - -``` -select current_timestamp from dual; - current_timestamp ------------------------------------ - 2023-07-06 10:27:01.440600 +08:00 -(1 row) -``` - -Query the current date and time in the current time zone (the precision is adjusted to the first three decimal places): - -``` -select current_timestamp(3) from dual; - current_timestamp ------------------------------------ - 2023-07-06 10:27:14.182000 +08:00 -(1 row) -``` - -9、Compatible with new_time functions, function: return the date in another time zone corresponding to a certain time zone, support parameters: date, text, text, the test case is as follows: -Returns the date for the current date in another time zone: - -``` -select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; - bj_time | los_angles -------------+------------ - 2023-07-06 | 2023-07-06 -(1 row) -``` - -10、Compatible with tz_offset functions, function: return the offset of the given time zone and the standard time zone, support parameters: text, the test case is as follows: -Returns the offset of a given time zone from the standard time zone: - -``` -select tz_offset('US/Eastern') from dual; - tz_offset ------------ - -04:00 -(1 row) -``` - -11、Compatible with trunc function, function: you can intercept the date to get the desired value, such as year, month, day, hour, minute, support parameters: date/date, text, the test case is as follows: -Intercept the current date: - -``` -select trunc(sysdate()) from dual; - trunc ------------- - 2023-07-06 -(1 row) -``` - -Truncating the year, only the year is correct, and the month and day are not accurate values: - -``` -select trunc(sysdate(),'yyyy') from dual; - trunc ------------- - 2023-01-01 -(1 row) -``` - -Intercept the month, the return value only the month is correct, the year and day are not accurate values: - -``` -select trunc(sysdate(),'mm') from dual; - trunc ------------- - 2023-07-01 -(1 row) -``` - -12、Compatible with instrb function, function: string lookup function, return the position of the string, support parameters: varchar2, text, number DEFAULT 1, number DEFAULT 1, the following are test cases: -RETURNS THE POSITION OF THE STRING IN CORPORATE FLOOR WHEN THE FIRST OR OCCURS BY DEFAULT: - -``` -SELECT INSTRB('CORPORATE FLOOR','OR') "Instring in bytes" FROM DUAL; - Instring in bytes -------------------- - 2 -(1 row) -``` - -Returns the position of the string in the corporate floor where the query starts with the fifth character and the second occurrence of or: - -``` -SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; - Instring in bytes -------------------- - 14 -(1 row) -``` - -13、Compatible with substr function, function: intercept string function, truncated in characters, support parameters: text, integer, test cases are as follows: -Intercept the string from the fifth character in 'It is nice today', followed by: - -``` -SELECT SUBSTR('It is nice today',5) "Substring with bytes" FROM DUAL; - - Substring with bytes ----------------------- - s nice today -(1 row) -``` - -14、Compatible with substrb function, function: intercept string function, intercept in bytes, support parameters: varchar2, number/varchar2, number, number, the test cases are as follows: -Intercept the string starting with the fifth byte in 'It's nice today' and then onwards: - -``` -SELECT SUBSTRB('It is nice today',5) "Substring with bytes" FROM DUAL; - Substring with bytes ----------------------- - s nice today -(1 row) -``` - -Intercept the string in 'It is nice today' starting with the fifth byte and ending with the eighth byte: - -``` -SELECT SUBSTRB('It is nice today',5,8) "Substring with bytes" FROM DUAL; - Substring with bytes ----------------------- - s nice t - -(1 row) -``` - -15、Compatible with trim function, function: remove the left and right spaces or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: -Remove the left and right spaces of ' aaa bbb ccc ': -``` -select trim(' aaa bbb ccc ')trim from dual; - trim -------------- - aaa bbb ccc -(1 row) -``` - -Remove aaa from 'aaa bbb ccc': - -``` -select trim('aaa bbb ccc','aaa')trim from dual; - trim ----------- - bbb ccc -(1 row) -``` - -16、Compatible with ltrim function, function: remove the left space or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: -Remove the space to the left of ' abcdefg ': - -``` -select ltrim(' abcdefg ')ltrim from dual; - ltrim ------------- - abcdefg -(1 row) -``` - -Traverse from the left side of 'abcdefg', remove it as soon as a character appears in 'fegab', and return the result if it is absent: - -``` -select ltrim('abcdefg','fegab')ltrim from dual; - ltrim -------- - cdefg -(1 row) -``` - -17、Compatible with rtrim function, function: remove the space on the right side of the specified string, the test case is as follows: -Remove the space to the right of ' abcdefg ': - -``` -select rtrim(' abcdefg ')rtrim from dual; - rtrim ----------------- - abcdefg -(1 row) -``` - -Traverse from the right side of 'abcdefg', remove it as soon as a character appears in 'fegab', and return the result if it is absent: - -``` -select rtrim('abcdefg','fegab')rtrim from dual; - rtrim -------- - abcd -(1 row) -``` - -18、Compatible with the length function, function: find the length of the specified string character, support parameters: char/integer/varchar2 The test cases are as follows: -Query the character length of 223: - -``` -select length(223) from dual; - length --------- - 3 -(1 row) -``` - -Query the character length of '223': - -``` -select length('223') from dual; - length --------- - 3 -(1 row) -``` - -To query the character length of 'ivorysql database' : - -``` -select length('ivorysql database') from dual; - length --------- - 17 -(1 row) -``` - -19、Compatible with lengthb function: find the length of the specified string byte, support parameters: char/bytea/varchar2 test cases are as follows: -Query the byte lengthb of 'ivorysql': - - -``` -select lengthb('ivorysq'::char) from dual; - lengthb ---------- - 1 -(1 row) -``` - -Query the byte lengthb of '0x2C': - -``` -select lengthb('0x2C'::bytea) from dual; - lengthb ---------- - 4 -(1 row) -``` - -Query the byte lengthb of the 'ivorysql database': - -``` -select lengthb('ivorysql database') from dual; - lengthb ---------- - 17 -(1 row) -``` - -20、compatible with replace function, function: replace the character in the specified string or delete the character, support parameters: text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, test for example: -Replace 'j' in 'jack and jue' with 'bl' : - -``` -select replace('jack and jue','j','bl') from dual; - replace ----------------- - black and blue -(1 row) -``` - -Remove the 'j' in 'jack and jue' : - -``` -select replace('jack and jue','j') from dual; - replace ------------- - ack and ue -(1 row) -``` - -21、compatible with the regexp_replace function, which is an extension of the replace function. Function: Used to perform matching and replacement through regular expressions. Supported parameters: text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, varchar2 varchar2, for example: -Replace the matched number with *#: - -``` -select regexp_replace('01234abcd56789','[0-9]','*#')from dual; - regexp_replace --------------------------- - *#*#*#*#*#abcd*#*#*#*#*# -(1 row) -``` - -Start with the second number by replacing the matched number with *#: - -``` -select regexp_replace('01234abcd56789','[0-9]','*#',2)from dual; - regexp_replace -------------------------- - 0*#*#*#*#abcd*#*#*#*#*# -``` - -Delete '01' from '01234abcd56789': - -``` -select regexp_replace('01234abcd56789','01')from dual; - regexp_replace ----------------- - 234abcd56789 -(1 row) -``` - -Replace 01234abcd56789' with 'xxx': - -``` -select regexp_replace('01234abcd56789','012','xxx')from dual; - regexp_replace ----------------- - xxx34abcd56789 -(1 row) -``` - -22、Compatible with regexp_substr functions, function: pick up the character substring described by the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text /varchar2, varchar2, the test cases are as follows: -Query the 012 string starting with the first number in '012ab34': - -``` -select regexp_substr('012ab34', '012',1) from dual; - regexp_substr ---------------- - 012 -(1 row) -``` - -Query the 012 string in '012ab34' starting from the first number of the first group: -``` -select regexp_substr('012ab34', '012',1,1) from dual; - regexp_substr ---------------- - 012 -(1 row) -``` - -Query '012a012Ab34' for case-insensitive 012 strings starting from the first number of the first group: - -``` -select regexp_substr('012a012Ab34', '012A',1,1,'i') from dual; - regexp_substr ---------------- - 012a -(1 row) -``` - -Query '012a012Ab34' for case-sensitive 012 strings starting from the first group of numbers: - -``` -select regexp_substr('012a012Ab34', '012A',1,1,'c') from dual; - regexp_substr ---------------- - 012A -(1 row) -``` - -Query the 'Database' substring in 'Data': - -``` -select regexp_substr('Database' , 'Data') from dual; - regexp_substr ---------------- - Data -(1 row)s -``` - -23、Compatible with regexp_instr functions, function: used to calibrate the start position of the character substring that conforms to the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text, integer / varchar2, varchar2, the test case is as follows: -Query 'abcaBcabc' for the position of the abc substring starting from the first character: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1); - regexp_instr --------------- - 1 -(1 row) -``` - -Query 'abcaBcabc' starting from the first character, where the abc substring appears for the third time: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1, 3); - regexp_instr --------------- - 7 -(1 row) -``` - -Query 'abcabcabc' starting from the first character and occurring after the second occurrence of the abc substring: - -``` -SELECT regexp_instr('abcaBcabc', 'abc', 1, 2,1); - regexp_instr --------------- - 7 -(1 row) -``` - -Query 'abcaBcabc' from the first character, where it occurs after the first occurrence of the abc substring (case sensitive): - -``` -SELECT regexp_instr('abcaBcabc', 'abc',1,2,1,'c'); - regexp_instr --------------- - 7 -(1 row) -``` - -Query the 'Database' substring in 'Data': - -``` -SELECT regexp_instr('Database', 'Data'); - regexp_instr --------------- - 1 -(1 row) -``` - -24、Compatible with regexp_like functions, function: similar to like, used for fuzzy queries. Supported parameters: varchar2, varchar2 /varchar2, varchar2 varchar2, -First create a regexp_like table for the test case query: - -``` -create table t_regexp_like -( - id varchar(4), - value varchar(10) - -); -insert into t_regexp_like values ('1','1234560'); -insert into t_regexp_like values ('2','1234560'); -insert into t_regexp_like values ('3','1b3b560'); -insert into t_regexp_like values ('4','abc'); -insert into t_regexp_like values ('5','abcde'); -insert into t_regexp_like values ('6','ADREasx'); -insert into t_regexp_like values ('7','123 45'); -insert into t_regexp_like values ('8','adc de'); -insert into t_regexp_like values ('9','adc,.de'); -insert into t_regexp_like values ('10','abcbvbnb'); -insert into t_regexp_like values ('11','11114560'); -``` - -The test cases are as follows: -Query t_regexp_like columns with abc in the table: - -``` -select * from t_regexp_like where regexp_like(value,'abc'); - id | value -----+---------- - 4 | abc - 5 | abcde - 10 | abcbvbnb -(3 rows) - -``` - -Query t_regexp_like columns with ABC in the table (not case sensitive): - -``` -select * from t_regexp_like where regexp_like(value,'ABC','i'); - id | value -----+---------- - 4 | abc - 5 | abcde - 10 | abcbvbnb -(3 rows) - -``` - -25、Compatible with to_number functions, function: is to change some processed strings arranged in a certain format back to a numeric format, support parameters: text/text, text test cases are as follows: -Convert the string '-34,338,492' to numeric format: - -``` -SELECT to_number('-34,338,492', '99,999,999') from dual; - to_number ------------ - -34338492 -(1 row) -``` - -Convert the string '5.01-' to numeric format: - -``` -SELECT to_number('5.01-', '9.99S'); - - to_number ------------ - -5.01 -(1 row) -``` - -26、Compatible with to_char functions, functions: convert numbers or dates to character types, support parameters: date/date, text/timestamp/timestamp, text test cases are as follows: -To convert the current system date to character format: - -``` -select to_char(sysdate()) from dual; - to_char ------------- - 2023-07-10 -(1 row) -``` - -Convert current system date to month/day/year character format: - -``` -select to_char(sysdate(),'mm/dd/yyyy') from dual; - to_char ------------- - 07/10/2023 -(1 row) -``` - -Converts the timestamp format of the current date to character format - -``` -SELECT to_char(sysdate()::timestamp); - to_char ----------------------------- - 2023-07-10 09:46:44.000000 -``` - -Convert timestamp format of current date to month/date/year character format: - -``` -SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); - to_char ------------- - 07-2023-10 -(1 row) -``` - -27、Compatible with to_date functions, function: convert character type to date type, support parameters: text/text, text test cases are as follows: -Convert '2023/07/06' to date type: - -``` -select to_date('20230706') from dual; - to_date ------------- - 2023-07-06 -(1 row) -``` - -Convert '-44-02-01' to date type: - -``` -SELECT to_date('-44,0201','YYYY-MM-DD'); - to_date ------------- - 0044-02-01 -(1 row) -``` - -28、Compatible with to_timestamp functions, functions: can store year, month, day, hour, minute, second, and can also store fractional parts of seconds. Supported parameters: text/text, text test cases are as follows: -Query '2018-11-02 12:34:56.025' output as a date: -``` -SELECT to_timestamp('20181102.12.34.56.025'); - to_timestamp ----------------------------- - 2018-11-02 12:34:56.025000 -(1 row) -``` - -Query '2011,12,18 11:38' output as a date: - -``` -SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ----------------------------- - 2011-12-18 11:38:00.000000 -(1 row) -``` - -29、Compatible with to_timestamp_tz functions, functions: according to the time query, the time string has T, Z and milliseconds, time zone. The test cases are as follows: -Query '2016-10-9 14:10:10.123000' output as a date: - - -``` - SELECT to_timestamp_tz('2016-10-9 14:10:10.123000') FROM DUAL; - to_timestamp_tz ------------------------------------ - 2016-10-09 14:10:10.123000 +08:00 -(1 row) -``` - -Query '10-9-2016 14:10:10.123000 +8:30' output as a date: - -``` - SELECT to_timestamp_tz('10-9-2016 14:10:10.123000 +8:30', 'DD-MM-YYYY HH24:MI:SS.FF TZH:TZM') FROM DUAL; - to_timestamp_tz ------------------------------------ - 2016-09-10 13:40:10.123000 +08:00 -(1 row) -``` - -30、Compatible with to_yminterval functions, function: convert a string type to a year and month time difference type, support parameters: text, The test cases are as follows: -Query the date after two years and eight months after '20110101': -``` -select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; - ?column? ------------- - 2013-09-01 -(1 row) -``` - -31、Compatible with to_dsinterval functions, function: add a date plus a certain hour or number of days into another date, support parameters: text, test cases are as follows: -Query the current system time plus the date in 9 and a half hours (currently 2023-07-06, 18:00): - -``` -select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; - newdate ------------- - 2023-07-07 -(1 row) -``` - -32、compatible with numtodsinterval function, function: convert numbers into time interval type data. The supporting parameters: double precision, text test cases are as follows: -Convert 100.00 hours to interval type data: -``` -SELECT NUMTODSINTERVAL(100.00, 'hour'); - numtodsinterval -------------------------------- - +000000004 04:00:00.000000000 -(1 row) -``` - -Convert 100 minutes to interval type data: - -``` -SELECT NUMTODSINTERVAL(100, 'minute'); - numtodsinterval -------------------------------- - +000000000 01:40:00.000000000 -(1 row) -``` - -33、Compatible with the numtoyminterval function, function: convert numbers into date interval type data. -Convert 1, year to date interval: double precision, text, the test case is as follows: - -``` -SELECT NUMTOYMINTERVAL(1.00,'year'); - numtoyminterval ------------------ - +000000001-00 -(1 row) -``` - -Convert 1, mouth to date interval: - -``` -SELECT NUMTOYMINTERVAL(1,'month'); - numtoyminterval ------------------ - +000000000-01 -(1 row) -``` - -34、Compatible with the localtimestamp function, function: return the date and time in the session, support parameters: integer, add parameters to the function as precision, the test cases are as follows: -To return the date and time in the current session: - -``` -select localtimestamp from dual; - localtimestamp ----------------------------- - 2023-07-07 09:18:15.896472 -(1 row) -``` - -Returns the date and time in the current session with a precision of 1: - -``` -select localtimestamp(1) from dual; - localtimestamp ----------------------------- - 2023-07-07 09:18:16.100000 -(1 row) -``` - -35、Compatible with from_tz functions, functions: convert time from one time zone to another, support parameters; timestamp, text, the test case is as follows: -Convert '2000-03-28 08:00:00', '3:00' to the current time zone: - -``` -SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; - from_tz ------------------------------------ - 2000-03-28 13:00:00.000000 +08:00 -(1 row) -``` - -36、Compatible with sys_extract_utc functions, function: convert a timestamptz to UTC time zone time. Supported parameters: timestamp with time zone The test cases are as follows: -Query conversion timestamp '2000-03-28 11:30:00.00 -8:00' to the time after UTC time zone: - -``` -select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; - sys_extract_utc ----------------------------- - 2000-03-28 19:30:00.000000 -(1 row) -``` - -37、Compatible with sessiontimezone function, function: view time zone details, test cases are as follows: -To view the details of the current time zone: -``` -select sessiontimezone() from dual; - sessiontimezone ------------------ - Asia/Shanghai -(1 row) -``` - -After modifying the timezone, check the time zone belief information: - -``` -set timezone = 'Asia/Hong_Kong'; -SET -select sessiontimezone() from dual; - sessiontimezone ------------------ - Asia/Hong_Kong -(1 row) -``` - -38、compatible with hextoraw function, function: convert the binary value represented by the string into a RAW value. Support parameters: text, the test cases are as follows: -Convert the string 'abcdef' to a raw value: - - -``` -select hextoraw('abcdef')from dual; - hextoraw ----------- - \xabcdef -(1 row) -``` - -39、Compatible with uid function, function: get the instance name of the database. The test cases are as follows: -Get the instance name of the current database: - -``` -select uid() from dual; - uid ------ - 10 -(1 row) -``` - -40、Compatible with USERENV function, function: return the information of the current user environment, the test cases are as follows: -Check whether the current user is DBA, and if so, return ture: - -``` -select userenv('isdba')from dual; - get_isdba ------------ - TRUE -(1 row) -``` - -To view the session flag: - -``` -select userenv('sessionid')from dual; - get_sessionid ---------------- - 1 -(1 row) -``` - +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Built-in data types and built-in functions + +== Built-in data types + +|==== +|char +|varchar +|varchar2 +|number +|binary_float +|binary_double +|date +|timestamp +|timestamp with time zone +|timestamp with local time zone +|interval year to month +|interval day to second +|raw +|long +|==== + +== Built-in functions + +|==== +|sysdate +|systimestamp +|add_months +|last_day +|next_day +|months_between +|current_date +|current_timestamp +|new_time +|tz_offset +|trunc +|instrb +|substr +|substrb +|trim +|ltrim +|rtrim +|length +|lengthb +|replace +|regexp_replace +|regexp_substr +|regexp_instr +|regexp_like +|to_number +|to_char +|to_date +|to_timestamp +|to_timestamp_tz +|to_yminterval +|to_dsinterval +|numtodsinterval +|numtoyminterval +|localtimestamp +|from_tz +|sys_extract_utc +|sessiontimezone +|hextoraw +|uid +|USERENV +|asciistr +|to_multi_byte +|to_single_byte +|compose +|decompose +|==== + +== Built-in function descriptions + +1、Compatible with sysdate function, function: view the corresponding date and time, the test cases are as follows: +Query the date of the current system: + +``` +select sysdate() from dual; + sysdate +------------ + 2023-07-06 +(1 row) +``` + +Check the date pushed forward by 1 day: + +``` +select sysdate()-1 from dual; + ?column? +------------ + 2023-07-05 +(1 row) +``` + +2、Compatible with the systimestamp function, function: return the current system date and time (including microseconds and time zone) on the local database, the test cases are as follows: +Date and time to query the current date: + +``` +select systimestamp() from dual; + systimestamp +----------------------------------- + 2023-07-06 10:18:31.674322 +08:00 +(1 row) +``` + +3、Compatible with add_months functions, function: the function adds a date to the number of months (n), and returns the same day that is n months apart, supporting parameters: date, number; The test cases are as follows: +Check the same day of the following month on the current date (July 6): + +``` +select add_months(sysdate(),1) from dual; + add_months +------------ + 2023-08-06 +(1 row) +``` + +Query the same day of the previous month for the current date: + +``` +select add_months(sysdate(),-1) from dual; + add_months +------------ + 2023-06-06 +(1 row) +``` + +4、Compatible with last_day functions, function: return the last day of the month where the specified date is located, support parameters: date, the test cases are as follows: +Check the last day of the month in which the day is located: + +``` +select last_day(sysdate())from dual; + last_day +------------ + 2023-07-31 +(1 row) +``` + +Query the last day of the month on which a day falls: + +``` +select last_day(to_date('2019-09-01'))from dual; + last_day +------------ + 2019-09-30 +(1 row) +``` + +5、 Compatible with next_day functions, function: return the next date of the specified date. Supported parameters: date, integer /date, text, Note: When the second parameter in the function passes the number of weeks more hours than the existing week, the date of the next week will be returned; When the date passed by the second parameter in the function is greater than the existing number of weeks, the corresponding day of the week of the week is returned. The test cases are as follows: +Query the next day of the current date: + +``` +select next_day(sysdate(),1) from dual; + next_day +------------ + 2023-07-07 +(1 row) +``` + +Next Friday for the current date: + +``` +select next_day(sysdate(),'FRIDAY') from dual; + next_day +------------ + 2023-07-07 +(1 row) +``` + +6、Compatible with months_between functions, function: return the month of difference between date1 and date2 of date type, support parameters: date, date, description: if date1 is later than date2, return a positive number; If date1 is earlier than date2, a negative number is returned; If date1 and date2 are the same day of a month, the return result is an integer; If not the same day, results with decimal parts are returned on a monthly basis of 31 days. The test cases are as follows: +To find the month that differs between the same day in different months: + +``` +select months_between(to_date('2023-07-06'),to_date('2023-08-06')) from dual; + months_between +---------------- + -1 +(1 row) +``` + +Query the month that differs between different days of different months: + +``` +select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; + months_between +-------------------- + -0.967741935483871 +(1 row) +``` + +7、Compatible with current_date functions, functions: return the current date of the current time zone, the test cases are as follows: +To query the current date in the current time zone: + +``` +select current_date from dual; + current_date +-------------- + 2023-07-06 +(1 row) +``` + +8、Compatible with current_timestamp functions, function: return the current date and current time of the current time zone, including the current time zone information. Support parameters: integer, Note: The returned time can be adjusted with precision. The test cases are as follows: +To query the current date and time in the current time zone: + +``` +select current_timestamp from dual; + current_timestamp +----------------------------------- + 2023-07-06 10:27:01.440600 +08:00 +(1 row) +``` + +Query the current date and time in the current time zone (the precision is adjusted to the first three decimal places): + +``` +select current_timestamp(3) from dual; + current_timestamp +----------------------------------- + 2023-07-06 10:27:14.182000 +08:00 +(1 row) +``` + +9、Compatible with new_time functions, function: return the date in another time zone corresponding to a certain time zone, support parameters: date, text, text, the test case is as follows: +Returns the date for the current date in another time zone: + +``` +select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; + bj_time | los_angles +------------+------------ + 2023-07-06 | 2023-07-06 +(1 row) +``` + +10、Compatible with tz_offset functions, function: return the offset of the given time zone and the standard time zone, support parameters: text, the test case is as follows: +Returns the offset of a given time zone from the standard time zone: + +``` +select tz_offset('US/Eastern') from dual; + tz_offset +----------- + -04:00 +(1 row) +``` + +11、Compatible with trunc function, function: you can intercept the date to get the desired value, such as year, month, day, hour, minute, support parameters: date/date, text, the test case is as follows: +Intercept the current date: + +``` +select trunc(sysdate()) from dual; + trunc +------------ + 2023-07-06 +(1 row) +``` + +Truncating the year, only the year is correct, and the month and day are not accurate values: + +``` +select trunc(sysdate(),'yyyy') from dual; + trunc +------------ + 2023-01-01 +(1 row) +``` + +Intercept the month, the return value only the month is correct, the year and day are not accurate values: + +``` +select trunc(sysdate(),'mm') from dual; + trunc +------------ + 2023-07-01 +(1 row) +``` + +12、Compatible with instrb function, function: string lookup function, return the position of the string, support parameters: varchar2, text, number DEFAULT 1, number DEFAULT 1, the following are test cases: +RETURNS THE POSITION OF THE STRING IN CORPORATE FLOOR WHEN THE FIRST OR OCCURS BY DEFAULT: + +``` +SELECT INSTRB('CORPORATE FLOOR','OR') "Instring in bytes" FROM DUAL; + Instring in bytes +------------------- + 2 +(1 row) +``` + +Returns the position of the string in the corporate floor where the query starts with the fifth character and the second occurrence of or: + +``` +SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; + Instring in bytes +------------------- + 14 +(1 row) +``` + +13、Compatible with substr function, function: intercept string function, truncated in characters, support parameters: text, integer, test cases are as follows: +Intercept the string from the fifth character in 'It is nice today', followed by: + +``` +SELECT SUBSTR('It is nice today',5) "Substring with bytes" FROM DUAL; + + Substring with bytes +---------------------- + s nice today +(1 row) +``` + +14、Compatible with substrb function, function: intercept string function, intercept in bytes, support parameters: varchar2, number/varchar2, number, number, the test cases are as follows: +Intercept the string starting with the fifth byte in 'It's nice today' and then onwards: + +``` +SELECT SUBSTRB('It is nice today',5) "Substring with bytes" FROM DUAL; + Substring with bytes +---------------------- + s nice today +(1 row) +``` + +Intercept the string in 'It is nice today' starting with the fifth byte and ending with the eighth byte: + +``` +SELECT SUBSTRB('It is nice today',5,8) "Substring with bytes" FROM DUAL; + Substring with bytes +---------------------- + s nice t + +(1 row) +``` + +15、Compatible with trim function, function: remove the left and right spaces or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: +Remove the left and right spaces of ' aaa bbb ccc ': +``` +select trim(' aaa bbb ccc ')trim from dual; + trim +------------- + aaa bbb ccc +(1 row) +``` + +Remove aaa from 'aaa bbb ccc': + +``` +select trim('aaa bbb ccc','aaa')trim from dual; + trim +---------- + bbb ccc +(1 row) +``` + +16、Compatible with ltrim function, function: remove the left space or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: +Remove the space to the left of ' abcdefg ': + +``` +select ltrim(' abcdefg ')ltrim from dual; + ltrim +------------ + abcdefg +(1 row) +``` + +Traverse from the left side of 'abcdefg', remove it as soon as a character appears in 'fegab', and return the result if it is absent: + +``` +select ltrim('abcdefg','fegab')ltrim from dual; + ltrim +------- + cdefg +(1 row) +``` + +17、Compatible with rtrim function, function: remove the space on the right side of the specified string, the test case is as follows: +Remove the space to the right of ' abcdefg ': + +``` +select rtrim(' abcdefg ')rtrim from dual; + rtrim +---------------- + abcdefg +(1 row) +``` + +Traverse from the right side of 'abcdefg', remove it as soon as a character appears in 'fegab', and return the result if it is absent: + +``` +select rtrim('abcdefg','fegab')rtrim from dual; + rtrim +------- + abcd +(1 row) +``` + +18、Compatible with the length function, function: find the length of the specified string character, support parameters: char/integer/varchar2 The test cases are as follows: +Query the character length of 223: + +``` +select length(223) from dual; + length +-------- + 3 +(1 row) +``` + +Query the character length of '223': + +``` +select length('223') from dual; + length +-------- + 3 +(1 row) +``` + +To query the character length of 'ivorysql database' : + +``` +select length('ivorysql database') from dual; + length +-------- + 17 +(1 row) +``` + +19、Compatible with lengthb function: find the length of the specified string byte, support parameters: char/bytea/varchar2 test cases are as follows: +Query the byte lengthb of 'ivorysql': + + +``` +select lengthb('ivorysq'::char) from dual; + lengthb +--------- + 1 +(1 row) +``` + +Query the byte lengthb of '0x2C': + +``` +select lengthb('0x2C'::bytea) from dual; + lengthb +--------- + 4 +(1 row) +``` + +Query the byte lengthb of the 'ivorysql database': + +``` +select lengthb('ivorysql database') from dual; + lengthb +--------- + 17 +(1 row) +``` + +20、compatible with replace function, function: replace the character in the specified string or delete the character, support parameters: text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, test for example: +Replace 'j' in 'jack and jue' with 'bl' : + +``` +select replace('jack and jue','j','bl') from dual; + replace +---------------- + black and blue +(1 row) +``` + +Remove the 'j' in 'jack and jue' : + +``` +select replace('jack and jue','j') from dual; + replace +------------ + ack and ue +(1 row) +``` + +21、compatible with the regexp_replace function, which is an extension of the replace function. Function: Used to perform matching and replacement through regular expressions. Supported parameters: text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, varchar2 varchar2, for example: +Replace the matched number with *#: + +``` +select regexp_replace('01234abcd56789','[0-9]','*#')from dual; + regexp_replace +-------------------------- + *#*#*#*#*#abcd*#*#*#*#*# +(1 row) +``` + +Start with the second number by replacing the matched number with *#: + +``` +select regexp_replace('01234abcd56789','[0-9]','*#',2)from dual; + regexp_replace +------------------------- + 0*#*#*#*#abcd*#*#*#*#*# +``` + +Delete '01' from '01234abcd56789': + +``` +select regexp_replace('01234abcd56789','01')from dual; + regexp_replace +---------------- + 234abcd56789 +(1 row) +``` + +Replace 01234abcd56789' with 'xxx': + +``` +select regexp_replace('01234abcd56789','012','xxx')from dual; + regexp_replace +---------------- + xxx34abcd56789 +(1 row) +``` + +22、Compatible with regexp_substr functions, function: pick up the character substring described by the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text /varchar2, varchar2, the test cases are as follows: +Query the 012 string starting with the first number in '012ab34': + +``` +select regexp_substr('012ab34', '012',1) from dual; + regexp_substr +--------------- + 012 +(1 row) +``` + +Query the 012 string in '012ab34' starting from the first number of the first group: +``` +select regexp_substr('012ab34', '012',1,1) from dual; + regexp_substr +--------------- + 012 +(1 row) +``` + +Query '012a012Ab34' for case-insensitive 012 strings starting from the first number of the first group: + +``` +select regexp_substr('012a012Ab34', '012A',1,1,'i') from dual; + regexp_substr +--------------- + 012a +(1 row) +``` + +Query '012a012Ab34' for case-sensitive 012 strings starting from the first group of numbers: + +``` +select regexp_substr('012a012Ab34', '012A',1,1,'c') from dual; + regexp_substr +--------------- + 012A +(1 row) +``` + +Query the 'Database' substring in 'Data': + +``` +select regexp_substr('Database' , 'Data') from dual; + regexp_substr +--------------- + Data +(1 row)s +``` + +23、Compatible with regexp_instr functions, function: used to calibrate the start position of the character substring that conforms to the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text, integer / varchar2, varchar2, the test case is as follows: +Query 'abcaBcabc' for the position of the abc substring starting from the first character: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1); + regexp_instr +-------------- + 1 +(1 row) +``` + +Query 'abcaBcabc' starting from the first character, where the abc substring appears for the third time: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1, 3); + regexp_instr +-------------- + 7 +(1 row) +``` + +Query 'abcabcabc' starting from the first character and occurring after the second occurrence of the abc substring: + +``` +SELECT regexp_instr('abcaBcabc', 'abc', 1, 2,1); + regexp_instr +-------------- + 7 +(1 row) +``` + +Query 'abcaBcabc' from the first character, where it occurs after the first occurrence of the abc substring (case sensitive): + +``` +SELECT regexp_instr('abcaBcabc', 'abc',1,2,1,'c'); + regexp_instr +-------------- + 7 +(1 row) +``` + +Query the 'Database' substring in 'Data': + +``` +SELECT regexp_instr('Database', 'Data'); + regexp_instr +-------------- + 1 +(1 row) +``` + +24、Compatible with regexp_like functions, function: similar to like, used for fuzzy queries. Supported parameters: varchar2, varchar2 /varchar2, varchar2 varchar2, +First create a regexp_like table for the test case query: + +``` +create table t_regexp_like +( + id varchar(4), + value varchar(10) + +); +insert into t_regexp_like values ('1','1234560'); +insert into t_regexp_like values ('2','1234560'); +insert into t_regexp_like values ('3','1b3b560'); +insert into t_regexp_like values ('4','abc'); +insert into t_regexp_like values ('5','abcde'); +insert into t_regexp_like values ('6','ADREasx'); +insert into t_regexp_like values ('7','123 45'); +insert into t_regexp_like values ('8','adc de'); +insert into t_regexp_like values ('9','adc,.de'); +insert into t_regexp_like values ('10','abcbvbnb'); +insert into t_regexp_like values ('11','11114560'); +``` + +The test cases are as follows: +Query t_regexp_like columns with abc in the table: + +``` +select * from t_regexp_like where regexp_like(value,'abc'); + id | value +----+---------- + 4 | abc + 5 | abcde + 10 | abcbvbnb +(3 rows) + +``` + +Query t_regexp_like columns with ABC in the table (not case sensitive): + +``` +select * from t_regexp_like where regexp_like(value,'ABC','i'); + id | value +----+---------- + 4 | abc + 5 | abcde + 10 | abcbvbnb +(3 rows) + +``` + +25、Compatible with to_number functions, function: is to change some processed strings arranged in a certain format back to a numeric format, support parameters: text/text, text test cases are as follows: +Convert the string '-34,338,492' to numeric format: + +``` +SELECT to_number('-34,338,492', '99,999,999') from dual; + to_number +----------- + -34338492 +(1 row) +``` + +Convert the string '5.01-' to numeric format: + +``` +SELECT to_number('5.01-', '9.99S'); + + to_number +----------- + -5.01 +(1 row) +``` + +26、Compatible with to_char functions, functions: convert numbers or dates to character types, support parameters: date/date, text/timestamp/timestamp, text test cases are as follows: +To convert the current system date to character format: + +``` +select to_char(sysdate()) from dual; + to_char +------------ + 2023-07-10 +(1 row) +``` + +Convert current system date to month/day/year character format: + +``` +select to_char(sysdate(),'mm/dd/yyyy') from dual; + to_char +------------ + 07/10/2023 +(1 row) +``` + +Converts the timestamp format of the current date to character format + +``` +SELECT to_char(sysdate()::timestamp); + to_char +---------------------------- + 2023-07-10 09:46:44.000000 +``` + +Convert timestamp format of current date to month/date/year character format: + +``` +SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); + to_char +------------ + 07-2023-10 +(1 row) +``` + +27、Compatible with to_date functions, function: convert character type to date type, support parameters: text/text, text test cases are as follows: +Convert '2023/07/06' to date type: + +``` +select to_date('20230706') from dual; + to_date +------------ + 2023-07-06 +(1 row) +``` + +Convert '-44-02-01' to date type: + +``` +SELECT to_date('-44,0201','YYYY-MM-DD'); + to_date +------------ + 0044-02-01 +(1 row) +``` + +28、Compatible with to_timestamp functions, functions: can store year, month, day, hour, minute, second, and can also store fractional parts of seconds. Supported parameters: text/text, text test cases are as follows: +Query '2018-11-02 12:34:56.025' output as a date: +``` +SELECT to_timestamp('20181102.12.34.56.025'); + to_timestamp +---------------------------- + 2018-11-02 12:34:56.025000 +(1 row) +``` + +Query '2011,12,18 11:38' output as a date: + +``` +SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); + to_timestamp +---------------------------- + 2011-12-18 11:38:00.000000 +(1 row) +``` + +29、Compatible with to_timestamp_tz functions, functions: according to the time query, the time string has T, Z and milliseconds, time zone. The test cases are as follows: +Query '2016-10-9 14:10:10.123000' output as a date: + + +``` + SELECT to_timestamp_tz('2016-10-9 14:10:10.123000') FROM DUAL; + to_timestamp_tz +----------------------------------- + 2016-10-09 14:10:10.123000 +08:00 +(1 row) +``` + +Query '10-9-2016 14:10:10.123000 +8:30' output as a date: + +``` + SELECT to_timestamp_tz('10-9-2016 14:10:10.123000 +8:30', 'DD-MM-YYYY HH24:MI:SS.FF TZH:TZM') FROM DUAL; + to_timestamp_tz +----------------------------------- + 2016-09-10 13:40:10.123000 +08:00 +(1 row) +``` + +30、Compatible with to_yminterval functions, function: convert a string type to a year and month time difference type, support parameters: text, The test cases are as follows: +Query the date after two years and eight months after '20110101': +``` +select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; + ?column? +------------ + 2013-09-01 +(1 row) +``` + +31、Compatible with to_dsinterval functions, function: add a date plus a certain hour or number of days into another date, support parameters: text, test cases are as follows: +Query the current system time plus the date in 9 and a half hours (currently 2023-07-06, 18:00): + +``` +select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; + newdate +------------ + 2023-07-07 +(1 row) +``` + +32、compatible with numtodsinterval function, function: convert numbers into time interval type data. The supporting parameters: double precision, text test cases are as follows: +Convert 100.00 hours to interval type data: +``` +SELECT NUMTODSINTERVAL(100.00, 'hour'); + numtodsinterval +------------------------------- + +000000004 04:00:00.000000000 +(1 row) +``` + +Convert 100 minutes to interval type data: + +``` +SELECT NUMTODSINTERVAL(100, 'minute'); + numtodsinterval +------------------------------- + +000000000 01:40:00.000000000 +(1 row) +``` + +33、Compatible with the numtoyminterval function, function: convert numbers into date interval type data. +Convert 1, year to date interval: double precision, text, the test case is as follows: + +``` +SELECT NUMTOYMINTERVAL(1.00,'year'); + numtoyminterval +----------------- + +000000001-00 +(1 row) +``` + +Convert 1, mouth to date interval: + +``` +SELECT NUMTOYMINTERVAL(1,'month'); + numtoyminterval +----------------- + +000000000-01 +(1 row) +``` + +34、Compatible with the localtimestamp function, function: return the date and time in the session, support parameters: integer, add parameters to the function as precision, the test cases are as follows: +To return the date and time in the current session: + +``` +select localtimestamp from dual; + localtimestamp +---------------------------- + 2023-07-07 09:18:15.896472 +(1 row) +``` + +Returns the date and time in the current session with a precision of 1: + +``` +select localtimestamp(1) from dual; + localtimestamp +---------------------------- + 2023-07-07 09:18:16.100000 +(1 row) +``` + +35、Compatible with from_tz functions, functions: convert time from one time zone to another, support parameters; timestamp, text, the test case is as follows: +Convert '2000-03-28 08:00:00', '3:00' to the current time zone: + +``` +SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; + from_tz +----------------------------------- + 2000-03-28 13:00:00.000000 +08:00 +(1 row) +``` + +36、Compatible with sys_extract_utc functions, function: convert a timestamptz to UTC time zone time. Supported parameters: timestamp with time zone The test cases are as follows: +Query conversion timestamp '2000-03-28 11:30:00.00 -8:00' to the time after UTC time zone: + +``` +select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; + sys_extract_utc +---------------------------- + 2000-03-28 19:30:00.000000 +(1 row) +``` + +37、Compatible with sessiontimezone function, function: view time zone details, test cases are as follows: +To view the details of the current time zone: +``` +select sessiontimezone() from dual; + sessiontimezone +----------------- + Asia/Shanghai +(1 row) +``` + +After modifying the timezone, check the time zone belief information: + +``` +set timezone = 'Asia/Hong_Kong'; +SET +select sessiontimezone() from dual; + sessiontimezone +----------------- + Asia/Hong_Kong +(1 row) +``` + +38、compatible with hextoraw function, function: convert the binary value represented by the string into a RAW value. Support parameters: text, the test cases are as follows: +Convert the string 'abcdef' to a raw value: + + +``` +select hextoraw('abcdef')from dual; + hextoraw +---------- + \xabcdef +(1 row) +``` + +39、Compatible with uid function, function: get the instance name of the database. The test cases are as follows: +Get the instance name of the current database: + +``` +select uid() from dual; + uid +----- + 10 +(1 row) +``` + +40、Compatible with USERENV function, function: return the information of the current user environment, the test cases are as follows: +Check whether the current user is DBA, and if so, return ture: + +``` +select userenv('isdba')from dual; + get_isdba +----------- + TRUE +(1 row) +``` + +To view the session flag: + +``` +select userenv('sessionid')from dual; + get_sessionid +--------------- + 1 +(1 row) +``` + +41、Compatible with ASCIISTR function, function: input string, return ASCII characters, the test cases are as follows: +string with only ascii chars: +``` + select asciistr('Hello, World!') from dual; + asciistr +--------------- + Hello, World! +(1 row) +``` + +string with non-ascii chars: +``` + select asciistr('你好') from dual; + asciistr +------------ + \4F60\597D +``` + +string with mixed ascii and non-ascii: +``` + select asciistr('ABÄCDE') from dual; + asciistr +------------ + AB\00C4CDE +(1 row) +``` + +42、Compatible with TO_MULTI_BYTE function, function: Convert half-width characters in a string to full-width characters: +input half-width characters, Convert to full-width characters: +``` +select to_multi_byte('1.2'::text) ; + to_multi_byte +--------------- + 1.2 +``` + +43、Compatible with TO_SINGLE_BYTE function, function: Convert full-width characters in a string to half-width characters: +input full-width characters, Convert to half-width characters: 输入全角字符,转换为半角字符: +``` +select to_single_byte('1.2'); + to_single_byte +---------------- + 1.2 +``` + +44、Compatible with COMPOSE function,function: Combine base characters and combining marks into a composite Unicode character: +input base character 'a' with a combining mark '768', return à: +``` +select compose('a'||chr(768)) from dual; + compose +--------- + à +(1 row) +``` + + +45、ompatible with DECOMPOSE function, function: Decompose composite Unicode characters (like those with accents or special symbols) into their base characters and combining marks. +input é, return a base character 'e' with a combining mark '301': +``` +select asciistr(decompose('é')) from dual; + asciistr +---------- + e\0301 +``` diff --git a/EN/modules/ROOT/pages/v3.0/22.adoc b/EN/modules/ROOT/pages/v1.17/19.adoc similarity index 96% rename from EN/modules/ROOT/pages/v3.0/22.adoc rename to EN/modules/ROOT/pages/v1.17/19.adoc index 4c1b138..64f8221 100644 --- a/EN/modules/ROOT/pages/v3.0/22.adoc +++ b/EN/modules/ROOT/pages/v1.17/19.adoc @@ -1,28 +1,28 @@ -:sectnums: -:sectnumlevels: 5 - -:imagesdir: ./_images - -= Added Oracle compatibility mode ports and IP - -== Objective - -- In order to distinguish the Oracle port, IP and PG port IP. THERE IS NOW A NEED TO INCREASE THE PROCESSING OF ORAPORT AND ORAHOST; - -== Function - -- Add ivoryhost: You need to add the parameter ivoryhost when connecting, and its function is similar to host; - -- New ivoryport: Compared to host, the function of port is relatively complex. It involves specifying ports in the configure phase and connection phase; - -== Test method: -``` - ./configure --with-oraport=5555 - ./initdb .... - ./pg_ctl -D ../data start - - ./pg_ctl -o “-p 5433 -o 1522” -D ../data -``` - - -​ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Added Oracle compatibility mode ports and IP + +== Objective + +- In order to distinguish the Oracle port, IP and PG port IP. THERE IS NOW A NEED TO INCREASE THE PROCESSING OF ORAPORT AND ORAHOST; + +== Function + +- Add ivoryhost: You need to add the parameter ivoryhost when connecting, and its function is similar to host; + +- New ivoryport: Compared to host, the function of port is relatively complex. It involves specifying ports in the configure phase and connection phase; + +== Test method: +``` + ./configure --with-oraport=5555 + ./initdb .... + ./pg_ctl -D ../data start + + ./pg_ctl -o “-p 5433 -o 1522” -D ../data +``` + + +​ diff --git a/EN/modules/ROOT/pages/v3.0/2.adoc b/EN/modules/ROOT/pages/v1.17/2.adoc similarity index 76% rename from EN/modules/ROOT/pages/v3.0/2.adoc rename to EN/modules/ROOT/pages/v1.17/2.adoc index b141de1..f8022fc 100644 --- a/EN/modules/ROOT/pages/v3.0/2.adoc +++ b/EN/modules/ROOT/pages/v1.17/2.adoc @@ -9,7 +9,6 @@ IvorySQL is an advanced, full-featured, Oracle open source compatible PostgreSQL with a firm commitment to always remain 100% compatible and a direct replacement for the latest PostgreSQL. IvorySQL adds a GUC parameter called 'ivorysql.compatible_mode' to control the compatibility mode of IvorySQL, which has two values: 'oracle' and 'pg'.When initializing the data directory, specify the compatibility mode of the data directory by specifying the '-m' parameter, and '-m pg' then the data directory is PostgreSQL mode.In this mode, the 'ivorysql.compatible_mode' parameter will be invalidated, and the '-m oracle' or if the '-m' parameter is not specified, the data directory will be compatible with Oracle mode.In this mode, the initial value of the 'ivorysql.compatible_mode' parameter is 'oracle' and does not support some PostgreSQL syntax, and the database can support 100% of PostgreSQL syntax and functions by 'set ivorysql.compatible_mode to pg'. -One of the highlights of IvorySQL is the PL/iSQL procedural language, which supports Oracle's PL/SQL syntax. At the same time, IvorySQL implements Oracle-compatible functions by adding plug-ins *ivorysql_ora* bound to the kernel, and the functions currently implemented include built-in functions, data types, system views, merges, and the addition of GUC parameters, and will continue to implement new compatible functions in the form of plug-ins bound to the kernel in the future. === Product Goals and Scope @@ -61,14 +60,12 @@ Ivory database's main application scenarios. IvorySQL is a powerful open source object-relational database management system (ORDBMS). Used to store data securely, support best practices, and allow them to be retrieved when requests are processed. In addition, it is also compatible with Oracle's syntax, which is suitable for scenarios where Oracle is used. -== Compatibility with Oracle - -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/14[1、Ivorysql frame design] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/15[2、GUC Framework] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/16[3、Case conversion] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/17[4、Dual-mode design] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/18[5、Compatible with Oracle like] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/19[6、Compatible with Oracle anonymous block] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/20[7、Compatible with Oracle functions and stored procedures] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/21[8、Built-in data types and built-in functions] -* https://docs.ivorysql.org/cn/ivorysql-doc/v3.0/v3.0/22[9、Added Oracle compatibility mode ports and IP] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/11[1. Ivorysql frame design] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/12[2. GUC Framework] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/13[3. Case conversion] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/14[4. Dual-mode design] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/15[5. Compatible with Oracle like] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/16[6. Compatible with Oracle anonymous block] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/17[7. Compatible with Oracle functions and stored procedures] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/18[8. Built-in data types and built-in functions] +* https://docs.ivorysql.org/en/ivorysql-doc/v1.17/v1.17/19[9. Added Oracle compatibility mode ports and IP] diff --git a/EN/modules/ROOT/pages/v3.0/10.adoc b/EN/modules/ROOT/pages/v1.17/20.adoc similarity index 100% rename from EN/modules/ROOT/pages/v3.0/10.adoc rename to EN/modules/ROOT/pages/v1.17/20.adoc diff --git a/EN/modules/ROOT/pages/v3.0/11.adoc b/EN/modules/ROOT/pages/v1.17/21.adoc similarity index 100% rename from EN/modules/ROOT/pages/v3.0/11.adoc rename to EN/modules/ROOT/pages/v1.17/21.adoc diff --git a/EN/modules/ROOT/pages/v3.0/12.adoc b/EN/modules/ROOT/pages/v1.17/22.adoc similarity index 100% rename from EN/modules/ROOT/pages/v3.0/12.adoc rename to EN/modules/ROOT/pages/v1.17/22.adoc diff --git a/EN/modules/ROOT/pages/v3.0/3.adoc b/EN/modules/ROOT/pages/v1.17/3.adoc similarity index 76% rename from EN/modules/ROOT/pages/v3.0/3.adoc rename to EN/modules/ROOT/pages/v1.17/3.adoc index 23c4c72..2f0acf5 100644 --- a/EN/modules/ROOT/pages/v3.0/3.adoc +++ b/EN/modules/ROOT/pages/v1.17/3.adoc @@ -3,14 +3,12 @@ :sectnumlevels: 5 :imagesdir: ./_images -== User manual +== **Quick Start** === getting started guide ==== Beginners -If you are new to IvorySQL, you can click https://deploy-preview-83--ivorysql.netlify.app/zh-CN/[here] to learn about features of IvorySQL in the beginning.Also, you can download our source code through [Github](https://github.com/IvorySQL/IvorySQL).By the way, don't forget to give our IvorySQL community a star. - You can refer to the following contents to install IvorySQL quickly. OS version of the demo: @@ -30,7 +28,9 @@ Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc v **Getting the source** [source,] ---- -[highgo@ivorysql ~]$ ls +[highgo@ivorysql ~]$ wget https://github.com/IvorySQL/IvorySQL/archive/refs/tags/IvorySQL_1.17.tar.gz +[highgo@ivorysql ~]$ tar -zxvf IvorySQL_1.17.tar.gz +[highgo@ivorysql ~]$ mv IvorySQL-IvorySQL_1.17 IvorySQL; ls IvorySQL [highgo@ivorysql ~]$ cd IvorySQL/ ---- @@ -51,7 +51,7 @@ To compile the IvorySQL from the source code, you have to ensure that prerequisi * libreadline - The GNU Readline library is used by default. * zlib - zlib compression library is used by default. * Flex - (Flex 2.5.31 or later) -* Bison - (Bison 1.875 or later) +* Bison - (Bison 1.1775 or later) **Install** @@ -59,7 +59,6 @@ To compile the IvorySQL from the source code, you have to ensure that prerequisi ---- [highgo@ivorysql IvorySQL]$ make [highgo@ivorysql IvorySQL]$ make install ----- **Installation completed** @@ -100,7 +99,7 @@ image::p19.png[] **Connection** ---- [highgo@ivorysql ~]$ psql -d postgres - psql (16devel) + psql (14.17) Type "help" for help. postgres=# @@ -124,7 +123,7 @@ undefined [root@localhost ~]# su - ivorysql Last login: Wed Feb 24 10:47:32 CST 2023 on pts/0 -bash-4.2$ psql -psql (14.2) +psql (14.17) Type "help" for help. ivorysql=# @@ -155,24 +154,19 @@ environment:**CentOS 7.X** Installation package:rpm -Download YUM source: Use wget to download on Centos7 - -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm - +Download RPM source: Use wget to download on Centos7 +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -installation source - yum install ivorysql-release-1.0-2.noarch.rpm -install library +installation library - yum install -y ivorysql2-server + yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm Initialize the database - cd /usr/local/ivorysql/ivorysql-2/bin - ./initdb -D ../data + /opt/IvorySQL-1.17/bin/initdb -D data/ === cluster installation @@ -180,23 +174,19 @@ environment:**CentOS 7.X** Installation package:rpm -Download YUM source: Use wget to download on Centos7 - -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm +Download RPM source: Use wget to download on Centos7 -installation source +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm - yum install ivorysql-release-1.0-2.noarch.rpm - -install library +installation library - yum install -y ivorysql2-server + yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm **master node** Initialize the database - cd /usr/local/ivorysql/ivorysql-2/bin + /opt/IvorySQL-1.17/bin/initdb -D data/ ./initdb ../data-primary -U postgres Start the service and create a user @@ -221,7 +211,7 @@ restart service ---- shell -cd /usr/local/ivorysql/ivorysql-2/bin +cd /opt/IvorySQL-1.17/bin ./pg_basebackup -h 127.0.0.1 -p 5333 -U repl -W -Fp -Xs -Pv -R -D ../data-standby01 ---- @@ -242,25 +232,20 @@ environment:**CentOS 7.X** Installation package:rpm -Download YUM source: Use wget to download on Centos7 +Download RPM source: Use wget to download on Centos7 -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -installation source +install library ---- -yum install ivorysql-release-1.0-2.noarch.rpm +yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm ---- -install library - - yum install -y ivorysql2-server - Initialize the master node - cd /usr/local/ivorysql/ivorysql-2/bin - ./initdb ../data-primary -U postgres + /opt/IvorySQL-1.17/bin/initdb -D data/ Start the service and create a user ---- @@ -293,24 +278,20 @@ environment:**CentOS 7.X** Installation package:rpm -Download YUM source: Use wget to download on Centos7 - -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-2.noarch.rpm - +Download RPM source: Use wget to download on Centos7 +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm -installation source - yum install ivorysql-release-1.0-2.noarch.rpm install library - yum install -y ivorysql2-server + yum install IvorySQL-1.17-fde5539-20250326.x86_64.rpm 1、basic backup ---- shell -cd /usr/local/ivorysql/ivorysql-2/bin +cd /opt/IvorySQL-1.17/bin ./pg_basebackup -h 192.168.xx.xx -p 5333 -U repl -W -Fp -Xs -Pv -R -D ../data-standby01 ---- diff --git a/EN/modules/ROOT/pages/v1.17/33.adoc b/EN/modules/ROOT/pages/v1.17/33.adoc new file mode 100644 index 0000000..5c9236d --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/33.adoc @@ -0,0 +1,27 @@ +:sectnums: +:sectnumlevels: 5 + + +[discrete] +== IvorySQL Ecosystem Plugin Compatibility List + +IvorySQL, as an advanced open-source database compatible with Oracle and based on PostgreSQL, has powerful extension capabilities and supports a rich ecosystem of plugins. These plugins can help users enhance database functionality in different scenarios, including geospatial information processing, vector retrieval, full-text search, data definition extraction, and path planning. The following is a list of major plugins currently officially compatible with and supported by IvorySQL: + ++ + +[cols="2,1,3,3"] +|==== +|*Plugin Name*|*Version*|*Function Description*|*Use Cases* +| xref:v1.17/9.adoc[PostGIS] | 3.4.0 | Provides geospatial data support for IvorySQL, including spatial indexes, spatial functions, and geographic object storage | Geographic Information Systems (GIS), map services, location data analysis +| xref:v1.17/10.adoc[pgvector] | 0.8.0 | Supports vector similarity search, can be used to store and retrieve high-dimensional vector data| AI applications, image retrieval, recommendation systems, semantic search +| xref:v1.17/34.adoc[PGroonga] | 4.0.1 | Provides multilingual full-text search functionality, supports ultra-fast text retrieval and fuzzy matching | Log analysis, multilingual content search, real-time search engines +| xref:v1.17/35.adoc[pgddl (DDL Extractor)] | 0.20 | Extracts DDL (Data Definition Language) statements from databases, facilitating version management and migration | Database version control, CI/CD integration, structure comparison and synchronization +| xref:v1.17/36.adoc[pgRouting] | 3.5.1 | Geographic data-based path planning extension, supports shortest path, traveling salesman problem and other algorithms | Logistics planning, traffic network analysis, path optimization services +| xref:v1.17/37.adoc[pg_cron]​ | 1.6.0 | Provides database-internal scheduled task scheduling functionality, supports regular SQL statement execution | Data cleanup, regular statistics, automated maintenance tasks +| xref:v1.17/38.adoc[pgsql-http]​ | 1.7.0 | Allows HTTP requests to be initiated in SQL, interacting with external web services | Data collection, API integration, microservice calls +| xref:v1.17/40.adoc[pgvectorscale] | 0.8.0 | Provides sharding and distributed extension support for vector data, improving large-scale vector processing performance | Distributed vector databases, high-concurrency vector queries +|==== + +These plugins have all been tested and adapted by the IvorySQL team to ensure stable operation in the IvorySQL environment. Users can select appropriate plugins based on business needs to further enhance the capabilities and flexibility of the database system. + +We will continue to expand and enrich the IvorySQL plugin ecosystem. Community developers are welcome to submit new plugin adaptation suggestions or code contributions. For more detailed usage methods and the latest compatible versions of each plugin, please refer to the corresponding documentation chapters for each plugin. diff --git a/EN/modules/ROOT/pages/v1.17/34.adoc b/EN/modules/ROOT/pages/v1.17/34.adoc new file mode 100644 index 0000000..fec0b59 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/34.adoc @@ -0,0 +1,113 @@ +:sectnums: +:sectnumlevels: 5 + += PGroonga + +== Overview +PostgreSQL has built-in full-text search functionality, but when dealing with large-scale data, complex queries, and non-English languages (especially CJK languages like Chinese, Japanese, and Korean), its functionality and performance may not meet the requirements of high-performance applications. + +PGroonga was created to address this need. It is a PostgreSQL extension that deeply integrates Groonga, a high-performance full-featured full-text search engine, with the PostgreSQL database. Groonga itself is an excellent open-source search engine, renowned for its extreme speed and rich functionality, particularly excelling at handling multilingual text. PGroonga's mission is to seamlessly bring Groonga's powerful capabilities into the PostgreSQL world, providing users with an experience that far exceeds native full-text search. + +== Installation + +Based on the development environment, users can choose the appropriate installation method for PGroonga from the https://pgroonga.github.io/install[PGroonga Installation] page. + +[NOTE] +PGroonga plugin is already integrated in the IvorySQL installation package. If you use the installation package to install IvorySQL, you typically do not need to manually install PGroonga and can use it directly. + +=== Source Installation +In addition to the installation methods provided by the PGroonga community, the IvorySQL community also provides source installation methods. The source installation environment is Ubuntu 24.04 (x86_64). + +[TIP] +IvorySQL 1.17 or higher version is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +==== Install groonga + +** Install dependency kytea +[literal] +---- +git clone https://github.com/neubig/kytea.git +autoreconf -i +./configure +make +sudo make install +---- + +** Install dependency libzmq +[literal] +---- +Download zeromq-4.3.5.tar.gz from https://github.com/zeromq/libzmq/releases/tag/v4.3.5 +tar xvf zeromq-4.3.5.tar.gz +cd zeromq-4.3.5/ +./configure +make +sudo make install +---- + +** Download groonga package and install specified dependencies +[literal] +---- +wget https://packages.groonga.org/source/groonga/groonga-latest.tar.gz +tar xvf groonga-15.1.5.tar.gz +cd groonga-15.1.5 +# Run this script to install dependencies, supporting apt and dnf package managers +./ setup.sh +---- + +** Compile and install +[literal] +---- +# -S specifies the groonga source directory, -B specifies the build directory, which is a directory outside the source directory used only for building +cmake -S /home/ivorysql/groonga-15.1.5 -B /home/ivorysql/groonga_build --preset=release-maximum +cmake --build /home/ivorysql/groonga_build +sudo cmake --install /home/ivorysql/groonga_build +# Update dynamic library cache +sudo ldconfig +---- + +** Verify groonga installation success +[literal] +---- +$ groonga --version +Groonga 15.1.5 [Linux,x86_64,utf8,match-escalation-threshold=0,nfkc,mecab,message-pack,mruby,onigmo,zlib,lz4,zstandard,epoll,apache-arrow,xxhash,blosc,bfloat16,h3,simdjson,llama.cpp] +---- + +==== Install pgroonga +[literal] +---- +wget https://packages.groonga.org/source/pgroonga/pgroonga-4.0.1.tar.gz +tar xvf pgroonga-4.0.1.tar.gz +cd pgroonga-4.0.1 +---- + +When compiling PGroonga, there is an option: HAVE_MSGPACK=1, which is used to support WAL. Using this option requires installing msgpack-c 1.4.1 or higher. On Debian-based platforms, use the libmsgpack-dev package, and on CentOS 7, use msgpack-devel. +[literal] +---- +# Install dependencies +sudo apt install libmsgpack-dev +---- + +Before running make, ensure that the path of the pg_config command is in the PATH environment variable. +[literal] +---- +make HAVE_MSGPACK=1 +make install +---- + +== Create Extension and Confirm PGroonga Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE extension pgroonga; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pgroonga'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+------------------------------------------------------------------------------- + pgroonga| 4.0.1 | 4.0.1 | Super fast and all languages supported full text search index based on Groonga +(1 row) +---- + +== Usage +For PGroonga usage, please refer to the https://pgroonga.github.io/tutorial[PGroonga Official Documentation] diff --git a/EN/modules/ROOT/pages/v1.17/35.adoc b/EN/modules/ROOT/pages/v1.17/35.adoc new file mode 100644 index 0000000..2f78bab --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/35.adoc @@ -0,0 +1,45 @@ +:sectnums: +:sectnumlevels: 5 + += pgddl (DDL Extractor) + +== Overview +pgddl is a SQL function extension specifically designed for PostgreSQL databases. It can generate clear, formatted SQL DDL (Data Definition Language) scripts directly from the database system catalog, such as CREATE TABLE or ALTER FUNCTION. It solves the problem that PostgreSQL natively lacks commands like SHOW CREATE TABLE, allowing users to easily obtain object creation statements in a pure SQL environment without relying on external tools (such as pg_dump). + +This extension provides a complete solution through a set of simple SQL functions, with advantages including: requiring only SQL queries to operate, supporting flexible object filtering through WHERE clauses, and intelligently handling dependencies between objects to generate complete scripts including Drop and Create steps. This makes it particularly suitable for scenarios such as database change management, upgrade script writing, and structural auditing. + +It should be noted that ddlx is still under development and may not yet cover all PostgreSQL object types and advanced options. Generated scripts should always be checked and tested in non-production environments first to ensure their correctness and safety. + +== Installation + +[TIP] +The source installation environment is Ubuntu 24.04 (x86_64). IvorySQL 1.17 or higher version is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +=== Source Installation +Download pgddl-0.20.tar.gz from https://github.com/lacanoid/pgddl/releases/tag/0.20 and extract it. + +[literal] +---- +cd pgddl-0.20 +# Set the PG_CONFIG environment variable to the pg_config path, e.g.: /usr/local/ivorysql/ivorysql-4/bin/pg_config +make PG_CONFIG=/path/to/pg_config +make PG_CONFIG=/path/to/pg_config install +---- + +== Create Extension and Confirm ddlx Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE extension ddlx; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'ddlx'; + name | default_version | installed_version | comment +------+-----------------+-------------------+------------------------- + ddlx | 0.20 | 0.20 | DDL eXtractor functions +(1 row) +---- + +== Usage +For pgddl usage, please refer to the https://github.com/lacanoid/pgddl[ddlx Official Documentation] diff --git a/EN/modules/ROOT/pages/v1.17/36.adoc b/EN/modules/ROOT/pages/v1.17/36.adoc new file mode 100644 index 0000000..c1ca860 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/36.adoc @@ -0,0 +1,59 @@ +:sectnums: +:sectnumlevels: 5 + += pgRouting + +== Overview +pgRouting is an open-source geospatial routing extension library built on PostgreSQL/PostGIS databases. It endows databases with powerful network analysis capabilities, enabling them to handle complex path planning and graph theory computation problems, such as calculating the shortest path between two points, performing Traveling Salesman Problem (TSP) analysis, or computing service area coverage. It embeds routing algorithms directly into the database, thereby avoiding complex data transfer and computation at the application layer. + +The core advantage of this extension lies in its ability to leverage PostgreSQL's powerful data management capabilities and PostGIS's rich spatial functions to perform efficient computation on spatial network data directly within the database. This not only simplifies application development processes but also significantly improves the performance of large-scale network analysis by reducing data movement. + +pgRouting is widely used in logistics and distribution, traffic navigation, network analysis, urban planning, and supply chain management, among other fields. Its open-source nature has attracted continuous contributions and improvements from developers worldwide, making it one of the preferred tools for path analysis and network solving in the spatial database domain. + +== Installation + +[TIP] +The source installation environment is Ubuntu 24.04 (x86_64). IvorySQL 1.17 or higher version is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +=== Source Installation + +** Install dependencies + +It depends on perl, which is generally already installed when installing IvorySQL, so no need to install it here. +CMake version requirement >= 3.12, Boost version >= 1.56 +[literal] +---- +# Install dependencies +sudo apt install cmake libboost-all-dev +---- + +** Compile and install +[literal] +---- +wget https://github.com/pgRouting/pgrouting/releases/download/v3.5.1/pgrouting-3.5.1.tar.gz +tar xvf pgrouting-3.5.1.tar.gz +cd pgrouting-3.5.1 +mkdir build +cd build +cmake .. -DPOSTGRESQL_PG_CONFIG=/path/to/pg_config # eg: /usr/local/ivorysql/ivorysql-4/bin/pg_config +make +sudo make install +---- + +== Create Extension and Confirm pgRouting Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE extension pgrouting; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pgrouting'; + name | default_version | installed_version | comment +-----------+-----------------+-------------------+--------------------- + pgrouting | 3.5.1 | | pgRouting Extension +(1 row) +---- + +== Usage +For pgRouting usage, please refer to the https://docs.pgrouting.org/[pgRouting Official Documentation] diff --git a/EN/modules/ROOT/pages/v1.17/37.adoc b/EN/modules/ROOT/pages/v1.17/37.adoc new file mode 100644 index 0000000..5bb3976 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/37.adoc @@ -0,0 +1,117 @@ +:sectnums: +:sectnumlevels: 5 +:imagesdir: ./_images + += pg_cron + +== Overview +Running periodic tasks in PostgreSQL, such as executing VACUUM or deleting old data, is a common requirement. A simple way to achieve this is to configure cron or other external daemons to periodically connect to the database and run commands. However, as databases increasingly run as managed services or standalone containers, configuring and running a separate daemon often becomes impractical. Additionally, it's difficult to make your cron jobs aware of failover or schedule tasks across cluster nodes. + +pg_cron is an open-source scheduled task extension for PostgreSQL that allows setting up cron-style task scheduling directly within the database for automating data maintenance tasks (cleanup, aggregation), database health checks, executing stored procedures and custom functions, and other operations. It stores cron jobs in tables, and periodic tasks automatically fail over with the PostgreSQL server. For more details, see https://github.com/citusdata/pg_cron[pg_cron documentation]. + +== Installation and Configuration + +[TIP] +The source installation environment is Ubuntu 24.04 (x86_64). IvorySQL 1.17 and above is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +=== Source Installation + +[literal] +---- +# Clone pg_cron source code +git clone https://github.com/citusdata/pg_cron.git +cd pg_cron +# Set pg_config path to PATH environment variable, e.g.: +export PATH=/usr/local/ivorysql/ivorysql-1/bin/:$PATH +make +make install +---- + +=== Configuration File (ivorysql.conf) + +[literal] +---- +# Shared preload extensions +shared_preload_libraries = 'pg_cron' + +# Specify task metadata storage database (default current database) +cron.database_name = 'ivorysql' + +# Maximum number of concurrent tasks allowed +cron.max_running_jobs = 5 +---- + +=== Restart Service + +[literal] +---- +pg_ctl restart -D ./data -l logfile +---- + +=== Create Extension and Confirm pg_cron Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE extension pg_cron; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pg_cron'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+--------------------------- + pg_cron | 1.6 | |Job scheduler for PostgreSQL +(1 row) +---- + +== Core Functionality Usage + +=== Creating Scheduled Tasks + +[literal] +---- +SELECT cron.schedule( + 'nightly-data-cleanup', -- Task name (unique identifier) + '0 3 * * *', -- Cron expression (daily at UTC 3:00) + $$DELETE FROM logs + WHERE created_at < now() - interval '30 days'$$ -- SQL to execute +); +---- + +Cron expression quick reference: + +|==== +|Example|Meaning +|'0 * * * *'|Execute every hour on the hour +|'*/15 * * * *'|Execute every 15 minutes +|'0 9 * * 1-5'|Execute at 9 AM on weekdays +|'0 1 1 * *'|Execute at 1 AM on the 1st of every month +|==== + +pg_cron also allows using '$' to represent the last day of the month. + +=== Task Management + +[literal] +---- +# View all tasks +SELECT * FROM cron.job; +---- + +image::p31.png[] + +[literal] +---- +# View task execution history +SELECT * FROM cron.job_run_details ORDER BY start_time DESC LIMIT 10; +---- + +image::p32.png[] + +[literal] +---- +# Delete task +SELECT cron.unschedule('nightly-data-cleanup'); + +# Pause task (update status) +UPDATE cron.job SET active = false WHERE jobname = 'delete-job-run-details'; +---- diff --git a/EN/modules/ROOT/pages/v1.17/38.adoc b/EN/modules/ROOT/pages/v1.17/38.adoc new file mode 100644 index 0000000..82a28a9 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/38.adoc @@ -0,0 +1,58 @@ +:sectnums: +:sectnumlevels: 5 + += pgsql-http + +== Overview +pgsql-http is an open-source extension designed for PostgreSQL databases that allows users to initiate HTTP requests directly within the database, acting as a built-in web client. The core purpose of this extension is to bridge the gap between databases and external web services, enabling interaction with external web services and API endpoints through simple SQL function calls without relying on external applications or middleware. + +With this extension, developers can directly retrieve network data (GET), submit data (POST/PUT), update (PATCH), or delete (DELETE) remote resources in SQL queries, triggers, or stored procedures. It provides rich functionality, including setting request headers, automatic URL encoding, sending JSON data, and parsing response status, headers, and content, greatly simplifying the process of integrating external data into database operations. + +Typical application scenarios include: real-time retrieval of external data (such as exchange rates, weather information) and storing it in tables; automatic notification of microservices through triggers when data changes; cleaning data in the database and directly submitting it to external APIs. It provides a powerful and flexible solution for building database-centric integrated applications. + +== Installation +The pgsql-http plugin has been integrated into the IvorySQL installation package. If IvorySQL is installed using the installation package, pgsql-http can usually be used without manual installation. Other installation methods can refer to the source code installation steps below. + +[TIP] +The source installation environment is Ubuntu 24.04 (x86_64). IvorySQL 1.17 and above is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +=== Source Installation + +** Install Dependencies + +It depends on libcurl, and libcurl development files (such as libcurl4-openssl-dev) need to be installed in advance +[literal] +---- +# Install dependencies +sudo apt install libcurl4-openssl-dev +---- + +** Compile and Install + +Download the 1.7.0 source package pgsql-http-1.7.0.tar.gz from https://github.com/pramsey/pgsql-http/releases/tag/v1.7.0 +[literal] +---- +tar xvf pgsql-http-1.7.0.tar.gz +cd pgsql-http-1.7.0 +# Ensure pg_config is accessible in PATH, e.g.: /usr/local/ivorysql/ivorysql-1/bin/pg_config +make +sudo make install +---- + +== Create Extension and Confirm http Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE extension http; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'http'; + name | default_version | installed_version | comment +-----------+-----------------+-------------------+------------------------------------------------------------------------- + http | 1.7 | 1.7 | HTTP client for PostgreSQL, allows web page retrieval inside the database. +(1 row) +---- + +== Usage +For pgsql-http usage, please refer to https://github.com/pramsey/pgsql-http[pgsql-http official documentation] diff --git a/EN/modules/ROOT/pages/v3.0/4.adoc b/EN/modules/ROOT/pages/v1.17/4.adoc similarity index 99% rename from EN/modules/ROOT/pages/v3.0/4.adoc rename to EN/modules/ROOT/pages/v1.17/4.adoc index 712e471..cabb53b 100644 --- a/EN/modules/ROOT/pages/v3.0/4.adoc +++ b/EN/modules/ROOT/pages/v1.17/4.adoc @@ -3,7 +3,7 @@ :sectnumlevels: 5 -= Administrator Guide += **Monitoring** == Monitoring Database Activity diff --git a/EN/modules/ROOT/pages/v1.17/40.adoc b/EN/modules/ROOT/pages/v1.17/40.adoc new file mode 100644 index 0000000..d7cfa49 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/40.adoc @@ -0,0 +1,68 @@ +:sectnums: +:sectnumlevels: 5 + += pgvectorscale + +== Overview +pgvectorscale is a PostgreSQL extension launched by Timescale, designed to provide high-performance, cost-effective supplementation to the popular pgvector extension. It is specifically designed for large-scale vector workloads in AI applications, significantly improving the performance of vector similarity search and reducing storage costs through innovative indexing algorithms and compression techniques. + +The core features of this extension include the new index type StreamingDiskANN based on Microsoft's DiskANN research, improved Statistical Binary Quantization (SBQ) compression methods, and vector search functionality with label filtering support. In benchmark tests, it demonstrates exceptional performance when handling large-scale embedding vectors: compared to dedicated vector database services, it can achieve up to 28x lower latency and 16x query throughput while saving approximately 75% in costs. + +pgvectorscale is fully compatible with pgvector's data types and query syntax, ensuring seamless integration and migration experience. It is developed using Rust language and PGRX framework, making it very suitable for production-level applications that require efficient massive vector search within PostgreSQL. + +== Installation +The pgvectorscale plugin has been integrated into the IvorySQL installation package. If IvorySQL is installed using the installation package, pgvectorscale can usually be used without manual installation. Other installation methods can refer to the source code installation steps below. + +[TIP] +The source installation environment is Ubuntu 24.04 (x86_64). IvorySQL 1.17 and above is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 + +=== Source Installation + +** Install Rust Toolchain + +[literal] +---- +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +---- + +** Download pgvectorscale Source Code + +Download the 0.8.0 source package pgvectorscale-0.8.0.tar.gz from https://github.com/timescale/pgvectorscale/releases/tag/0.8.0 +[literal] +---- +tar xvf pgvectorscale-0.8.0.tar.gz +cd pgvectorscale-0.8.0/pgvectorscale +---- + +** Install cargo-pgrx + +[literal] +---- +cargo install --locked cargo-pgrx --version $(cargo metadata --format-version 1 | jq -r '.packages[] | select(.name == "pgrx") | .version') +cargo pgrx init --pg14 pg_config +---- + +** Compile and Install Extension + +[literal] +---- +cargo pgrx install --release +---- + +== Create Extension and Confirm pgvectorscale Version + +Connect to the database with psql and execute the following commands: +[literal] +---- +ivorysql=# CREATE EXTENSION IF NOT EXISTS vectorscale CASCADE; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'vectorscale'; + name | default_version | installed_version | comment +----------- +-----------------+-------------------+-------------------------------------------- + vectorscale | 0.8.0 | 0.8.0 | diskann access method for vector search. +(1 row) +---- + +== Usage +For pgvectorscale usage, please refer to https://github.com/timescale/pgvectorscale[pgvectorscale official documentation] diff --git a/EN/modules/ROOT/pages/v1.17/41.adoc b/EN/modules/ROOT/pages/v1.17/41.adoc new file mode 100644 index 0000000..9c12d2c --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/41.adoc @@ -0,0 +1,106 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Global Unique Index + +== Overview + +The Global Unique Index is a cross-partition uniqueness constraint feature provided by IvorySQL for partitioned tables. + +Standard PostgreSQL unique indexes only enforce uniqueness within a single partition and cannot guarantee uniqueness across partitions. IvorySQL introduces the `GLOBAL` keyword: when specified during unique index creation, the database scans all partitions on every INSERT or UPDATE to ensure no duplicate values exist across the entire partitioned table. + +This feature is supported in both PG-compatible mode and Oracle-compatible mode. + +== Syntax + +[source,sql] +---- +CREATE UNIQUE INDEX [ index_name ] ON partitioned_table ( column [, ...] ) GLOBAL; +---- + +Parameter description: + +- `UNIQUE`: must be used together with `GLOBAL` to specify the uniqueness constraint; +- `GLOBAL`: enables cross-partition uniqueness checking; only valid on partitioned tables; +- `index_name`: optional; if omitted, the database generates an index name automatically. + +== Test Cases + +=== Create a Partitioned Table and Global Unique Index + +[source,sql] +---- +-- Create a partitioned table +CREATE TABLE gidxpart (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE gidxpart1 PARTITION OF gidxpart FOR VALUES FROM (1) TO (10); +CREATE TABLE gidxpart2 PARTITION OF gidxpart FOR VALUES FROM (10) TO (100); +CREATE TABLE gidxpart3 PARTITION OF gidxpart FOR VALUES FROM (100) TO (200); + +-- Create a global unique index with an explicit name +CREATE UNIQUE INDEX gidx_u ON gidxpart USING btree(b) GLOBAL; + +-- Create a global unique index without specifying a name +CREATE UNIQUE INDEX ON gidxpart (b) GLOBAL; +---- + +=== INSERT: Cross-Partition Uniqueness Validation + +[source,sql] +---- +-- These inserts succeed (no duplicate values in column b across partitions) +INSERT INTO gidxpart VALUES (1, 1, 'first'); +INSERT INTO gidxpart VALUES (11, 11, 'eleventh'); +INSERT INTO gidxpart VALUES (2, 120, 'second'); +INSERT INTO gidxpart VALUES (12, 2, 'twelfth'); +INSERT INTO gidxpart VALUES (150, 13, 'no duplicate b'); + +-- These inserts fail: b=11 already exists in another partition +INSERT INTO gidxpart VALUES (2, 11, 'duplicated (b)=(11) on other partition'); +-- ERROR: duplicate key value violates unique constraint + +INSERT INTO gidxpart VALUES (12, 1, 'duplicated (b)=(1) on other partition'); +-- ERROR: duplicate key value violates unique constraint + +INSERT INTO gidxpart VALUES (150, 11, 'duplicated (b)=(11) on other partition'); +-- ERROR: duplicate key value violates unique constraint +---- + +=== UPDATE: Cross-Partition Uniqueness Validation + +[source,sql] +---- +-- UPDATE operations are also subject to the global unique index +UPDATE gidxpart SET b = 2 WHERE a = 2; +-- ERROR: duplicate key value violates unique constraint (b=2 already exists) + +UPDATE gidxpart SET b = 12 WHERE a = 12; +-- Succeeds (b=12 is unique across all partitions) +---- + +=== Partition ATTACH and DETACH + +[source,sql] +---- +-- Create a standalone table for ATTACH testing +CREATE TABLE gidxpart_new (a int, b int, c text); +INSERT INTO gidxpart_new VALUES (100001, 11, 'conflict with gidxpart1'); + +-- ATTACH fails if the new partition contains values that duplicate existing ones +ALTER TABLE gidxpart ATTACH PARTITION gidxpart_new + FOR VALUES FROM (100000) TO (199999); +-- ERROR: duplicate key value violates unique constraint + +-- DETACH is allowed; the partition's global index reverts to a regular local index +ALTER TABLE gidxpart DETACH PARTITION gidxpart2; +---- + +== Limitations + +. The `GLOBAL` keyword must be used together with `UNIQUE`; global non-unique indexes are not supported; +. Global unique indexes are only applicable to **partitioned tables**; the keyword is not valid on regular tables; +. Every INSERT or UPDATE requires scanning all partitions to verify uniqueness, which introduces **performance overhead** when the number of partitions or data volume is large; +. When attaching a partition via `ATTACH PARTITION`, the operation will fail if the new partition contains data that duplicates values in existing partitions; +. After a partition is detached with `DETACH PARTITION`, the corresponding global index automatically reverts to a regular local (partition-level) index; +. Creating a global unique index independently on a sub-partition (second-level partition) is not supported; cross-partition uniqueness is managed exclusively at the top-level partitioned table. diff --git a/EN/modules/ROOT/pages/v1.17/42.adoc b/EN/modules/ROOT/pages/v1.17/42.adoc new file mode 100644 index 0000000..79ed59e --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/42.adoc @@ -0,0 +1,129 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Default Logical Replication Support for Tables Without Primary Key + +== Overview + +In PostgreSQL/IvorySQL logical replication, UPDATE and DELETE operations rely on the Replica Identity to locate target rows on the subscriber side. By default, tables use `REPLICA IDENTITY DEFAULT`, where the system relies on the Primary Key to locate rows. If a table has no primary key, the replication strategy falls back to `REPLICA IDENTITY NOTHING`, causing UPDATE and DELETE operations to fail because the target rows cannot be located. + +IvorySQL introduces the GUC parameter `logical_replication_fallback_to_full_identity`. When this parameter is enabled, if a table's replica identity is `DEFAULT` and it has no primary key, the system automatically falls back to `REPLICA IDENTITY FULL` — recording the complete old row data in the WAL, allowing UPDATE and DELETE operations on tables without a primary key to work correctly through logical replication. + +This feature only takes effect on the publisher side; no additional configuration is required on the subscriber side. + +== Parameter Description + +[source,sql] +---- +# postgresql.conf +logical_replication_fallback_to_full_identity = on +---- + +Parameter description: + +- Type: `boolean`; +- Default value: `off`; +- Scope: `sighup`; takes effect by modifying `postgresql.conf` and executing `SELECT pg_reload_conf();`, no database restart required; +- Applicable node: only takes effect on the publisher side; no configuration needed on the subscriber side. + +== Test Cases + +=== Without the Parameter Enabled, UPDATE and DELETE Replication Fails for Tables Without Primary Key + +[source,sql] +---- +-- Publisher: create a table without a primary key +CREATE TABLE test_no_pk (id int, name text); + +-- Subscriber: create the same table structure +CREATE TABLE test_no_pk (id int, name text); + +-- Publisher: create a publication and add the table +CREATE PUBLICATION tap_pub FOR TABLE test_no_pk; + +-- Subscriber: create a subscription +CREATE SUBSCRIPTION tap_sub CONNECTION 'host=publisher dbname=postgres' PUBLICATION tap_pub; + +-- Publisher: INSERT operations always work (do not depend on replica identity) +INSERT INTO test_no_pk VALUES (1, 'alice'); + +-- Publisher: UPDATE fails (no primary key, cannot locate the target row) +UPDATE test_no_pk SET name = 'bob' WHERE id = 1; +-- ERROR: cannot update table "test_no_pk" because it does not have a replica identity and publishes updates + +-- Publisher: DELETE also fails +DELETE FROM test_no_pk WHERE id = 1; +-- ERROR: cannot delete from table "test_no_pk" because it does not have a replica identity and publishes deletes +---- + +=== With the Parameter Enabled, UPDATE and DELETE Replication Works for Tables Without Primary Key + +[source,sql] +---- +-- Publisher: enable the parameter and reload the configuration +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = on; +SELECT pg_reload_conf(); + +-- Publisher: INSERT works +INSERT INTO test_no_pk VALUES (1, 'alice'); + +-- Publisher: UPDATE works (automatically records the complete old row data in FULL mode) +UPDATE test_no_pk SET name = 'bob' WHERE id = 1; + +-- Publisher: DELETE works +DELETE FROM test_no_pk WHERE id = 1; +---- + +=== The Parameter Does Not Affect Tables With a Primary Key + +[source,sql] +---- +-- Tables with a primary key always use the primary key to locate rows, regardless of this parameter +CREATE TABLE test_with_pk (id int PRIMARY KEY, name text); + +-- Whether the parameter is enabled or not, UPDATE and DELETE work normally +INSERT INTO test_with_pk VALUES (1, 'alice'); +UPDATE test_with_pk SET name = 'bob' WHERE id = 1; +DELETE FROM test_with_pk WHERE id = 1; +---- + +=== The Parameter Does Not Affect Tables Explicitly Set to REPLICA IDENTITY NOTHING + +[source,sql] +---- +-- Create a table and explicitly set it to REPLICA IDENTITY NOTHING +CREATE TABLE test_nothing (id int, data text); +ALTER TABLE test_nothing REPLICA IDENTITY NOTHING; + +-- Even with logical_replication_fallback_to_full_identity enabled, +-- UPDATE and DELETE still fail (the parameter does not override an explicit NOTHING setting) +INSERT INTO test_nothing VALUES (1, 'test'); +UPDATE test_nothing SET data = 'modified' WHERE id = 1; +-- ERROR: cannot update table "test_nothing" because it does not have a replica identity and publishes updates + +DELETE FROM test_nothing WHERE id = 1; +-- ERROR: cannot delete from table "test_nothing" because it does not have a replica identity and publishes deletes +---- + +=== Dynamically Switching the Parameter at Runtime + +[source,sql] +---- +-- Disable the parameter: UPDATE/DELETE on tables without a primary key will revert to error behavior +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = off; +SELECT pg_reload_conf(); + +-- Enable the parameter: UPDATE/DELETE on tables without a primary key will work normally +ALTER SYSTEM SET logical_replication_fallback_to_full_identity = on; +SELECT pg_reload_conf(); +---- + +== Limitations + +. This parameter only takes effect for tables whose replica identity is `REPLICA IDENTITY DEFAULT` and that have no primary key; tables explicitly set to `FULL`, `USING INDEX`, or `NOTHING` are not affected; +. When this parameter is enabled, UPDATE and DELETE on tables without a primary key will record the complete old row data in the WAL (same effect as `REPLICA IDENTITY FULL`), which increases WAL size and network traffic compared to recording only primary key columns when a primary key exists; +. This parameter only takes effect on the publisher side; no configuration is needed on the subscriber side; +. INSERT operations do not depend on replica identity and can always be replicated normally, regardless of whether this parameter is enabled; +. This parameter does not replace an explicit `ALTER TABLE ... REPLICA IDENTITY FULL` setting, nor does it override tables explicitly set to `NOTHING`. diff --git a/EN/modules/ROOT/pages/v1.17/43.adoc b/EN/modules/ROOT/pages/v1.17/43.adoc new file mode 100644 index 0000000..0d6ff59 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/43.adoc @@ -0,0 +1,171 @@ +:sectnums: +:sectnumlevels: 5 + +:imagesdir: ./_images + += Rebuild View After Column Type Changed + +== Feature Overview + +In standard PostgreSQL, if a column is referenced by a view, attempting to change its data type via `ALTER TABLE ... ALTER COLUMN ... TYPE` results + in an immediate error: + +---- +ERROR: cannot alter type of a column used by a view or rule +---- + +Users are required to manually drop all dependent views, perform the column type change, and then recreate each view one by one — a tedious and +error-prone process that becomes particularly difficult when multiple levels of cascaded view dependencies exist. + +IvorySQL enhances this behavior: when a column type change is executed, the database automatically saves the definitions of all dependent views +(including indirectly dependent cascaded views), and after completing the type change, rebuilds those views in the correct dependency order — +entirely transparent to the user. If an error occurs during rebuilding (for example, a view uses an operator not supported by the new type), the +entire `ALTER TABLE` operation is rolled back, ensuring data consistency. + +This feature is supported in both PG-compatible mode and Oracle-compatible mode. + +== Syntax + +The syntax is identical to the standard `ALTER TABLE` — no additional keywords are required: + +[source,sql] +---- +ALTER TABLE table_name ALTER COLUMN column_name TYPE new_type; +---- + +Parameter description: + +- `table_name`: The target table name, optionally schema-qualified; +- `column_name`: The name of the column whose type is to be changed; +- `new_type`: The target data type, which must be compatible with the original type or implicitly castable. + +== Test Cases + +=== Single View Dependency: Automatic Rebuild + +[source,sql] +---- +-- Create the base table +CREATE TABLE t (a int, b text); + +-- Create a view that references column a +CREATE VIEW v AS SELECT a, b FROM t; + +-- Standard PostgreSQL would error here; IvorySQL rebuilds the view automatically +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- Verify the view is still valid and the column type has been updated +SELECT pg_typeof(a) FROM v LIMIT 1; +-- Returns: bigint + +\d v + View "public.v" + Column | Type | Collation | Nullable | Default +--------+--------+-----------+----------+--------- + a | bigint | | | + b | text | | | +---- + +=== Cascaded View Dependencies: Ordered Automatic Rebuild + +[source,sql] +---- +-- Create the base table +CREATE TABLE t (a int, b text); + +-- Create two levels of view dependency: v2 depends on v1, v1 depends on t +CREATE VIEW v1 AS SELECT a, b FROM t; +CREATE VIEW v2 AS SELECT a FROM v1; + +-- Change the column type; v1 and v2 are automatically rebuilt in dependency order +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- Verify both views have been correctly rebuilt +SELECT pg_typeof(a) FROM v1 LIMIT 1; +-- Returns: bigint + pg_typeof +----------- +(0 rows) + +SELECT pg_typeof(a) FROM v2 LIMIT 1; +-- Returns: bigint + pg_typeof +----------- +(0 rows) +---- + +=== Preserving View Options: security_barrier + +[source,sql] +---- +-- Create a view with the security_barrier option +CREATE VIEW v WITH (security_barrier) AS SELECT a, b FROM t; + +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- Verify the security_barrier option is correctly preserved after rebuild +SELECT relname, reloptions FROM pg_class WHERE relname = 'v'; +-- reloptions: {security_barrier=true} + relname | reloptions +---------+------------------------- + v | {security_barrier=true} +(1 row) +---- + +=== Preserving View Options: WITH CHECK OPTION + +[source,sql] +---- +-- Create a view with WITH LOCAL CHECK OPTION +CREATE VIEW v AS SELECT a, b FROM t WHERE a > 0 + WITH LOCAL CHECK OPTION; + +ALTER TABLE t ALTER COLUMN a TYPE bigint; + +-- Verify the CHECK OPTION is correctly preserved after rebuild +\d+ v + View "public.v" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+--------+-----------+----------+---------+----------+------------- + a | bigint | | | | plain | + b | text | | | | extended | +View definition: + SELECT t.a, + t.b + FROM t + WHERE t.a > 0; +Options: check_option=local +---- + +=== Full Rollback on Rebuild Failure + +[source,sql] +---- +CREATE TABLE t (a int, b text); +CREATE VIEW v AS SELECT a::integer + 1 AS a_plus FROM t; + +-- If the new type is incompatible with expressions in the view, the entire operation rolls back. +-- For example, changing a to type text makes the expression a::integer + 1 invalid. +ALTER TABLE t ALTER COLUMN a TYPE text; +-- ERROR: operator does not exist: text + integer +-- HINT: ... +-- ROLLBACK + +-- Confirm that the table structure and view are both unaffected +\d t + Table "public.t" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | text | | | +---- + +== Limitations + +. If a view uses an operator or function incompatible with the new column type (e.g., arithmetic on a `text` column), the rebuild will fail and the + entire `ALTER TABLE` operation will be rolled back; +. Only **views** are automatically rebuilt; **rules** that depend on the affected column will still cause an error; +. The column type change must satisfy PostgreSQL's type casting rules; arbitrary conversions between unrelated types are not supported; +. Views are rebuilt in topological dependency order; circular dependencies (normally prevented by the database) are not handled; +. The rebuild process runs within the same transaction, meaning dependent views are unavailable during the operation — this may affect concurrent +queries in high-concurrency environments. diff --git a/EN/modules/ROOT/pages/v3.0/5.adoc b/EN/modules/ROOT/pages/v1.17/5.adoc similarity index 99% rename from EN/modules/ROOT/pages/v3.0/5.adoc rename to EN/modules/ROOT/pages/v1.17/5.adoc index 2671596..3941656 100644 --- a/EN/modules/ROOT/pages/v3.0/5.adoc +++ b/EN/modules/ROOT/pages/v1.17/5.adoc @@ -3,7 +3,7 @@ :sectnumlevels: 5 -= Operators Guide += **Maintenance** == Routine Vacuuming diff --git a/EN/modules/ROOT/pages/v1.17/6.adoc b/EN/modules/ROOT/pages/v1.17/6.adoc new file mode 100644 index 0000000..ae1c48f --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/6.adoc @@ -0,0 +1,601 @@ + +:sectnums: +:sectnumlevels: 5 + + +# **Installation Deployment** + +## CentOS Installation overview + +This article introduces the installation process and precautions of IvorySQL on Linux platform. This article mainly demonstrates rpm package installation steps, and source code installation steps of the database under the Centos 7 environment. + + +=== Software and hardware requirements + +==== Introduction to software resources +|==== +| operating system | Yum source download address +| CentOS 7 | https://github.com/IvorySQL/IvorySQL/releases +|==== + +==== Hardware resource preparation + +|==== +| Configuration parameters | **Minimum configuration** | **Recommended configuration** +| **CPU** | 4 cores | 16 cores +| **Memory** | 4GB | 64GB +| **Storage** | 800MB,mechanical hard disk | Above 5GB,SSD or NvMe +| **Network** | gigabit lan | 10 Gigabit network +|==== + +=== Environment and configuration check + +Before deploying the IvorySQL database, you need to check the system environment and configuration + +==== View resources + +The IvorySQL database supports CentOS 7. X, operating systems. For details, refer to <<#_software_and_hardware_requirements>>. + +==== View the operating system + +Run the following command to view the operating system information: + +``` +cat /etc/redhat-release +``` + +==== View kernel parameters + +``` +uname -r +``` + +==== View memory and clear cache + +``` +free -g + +echo 3 > /proc/sys/vm/drop_caches +``` + +=== Get installation package + +You can install the IvorySql database or RPM package through the source code. + +==== Use source code to build IvorySQL database + +1.Get the source code: Run the following command to clone the source code of the IvorySQL database to your build machine: + +``` +git clone https://github.com/IvorySQL/IvorySQL.git +``` + +> Note: To clone code, you need to install and configure Git first. For details, refer to https://git-scm.com/doc[Git doc]. + +2.Install dependent packages: To compile IvorySQL from source code, you must ensure that prerequisite packages are available on the system. Execute the following command to install related packages: + +``` +sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget +sudo yum groupinstall -y 'Development Tools' +``` + +> Note: "Development Tools" includes gcc, make, flex, bison. + +3.Self-compilation and installation: The source code obtained previously is in the folder IvorySQL. Next, we will enter this folder for operation. + +Configuration: Root users execute the following commands to configure: + +``` + git checkout tags/Ivory_REL_1_17 + ./configure --prefix=/usr/local/ivorysql/ivorysql-1.17 +``` + +> Note: If the `--prefix` option is not provided, the default installation path will be `/usr/local/ivorysql`. + +> Note: We should remember the specified directory, because the system cannot find out where the compiled and installed programs are. More configure parameters can be viewed through "./configure -- help". You can also view the PostgreSQL manual + +Compile and install: After the configuration is completed, execute make to compile: + +``` +make +``` + +Perform a regression test before installing the newly compiled service (the following commands can be used): + +``` +make check +make all-check-world +``` + +Installation: + +``` +make install +``` + +==== Install the IvorySql database using the RPM package + +1. Run the following command to download the IvorySQL installation package. + +``` +wget https://github.com/IvorySQL/IvorySQL/releases/download/Ivory_REL_1_17/IvorySQL-1.17-fde5539-20250326.x86_64.rpm +``` + +> Note: The installation package in the example may not be the latest version. It is recommended that you download the latest installation package. + +2.Run the following command to install IvorySQL. + +``` +yum install -y libicu libxslt python3 --Install dependencies first +rpm -ivh IvorySQL-1.17-fde5539-20250326.x86_64.rpm +``` + + + +=== Initialize database service + +==== Initialize database + +1.Create an operating system user: under the user root session, create a new user ivorysql: + +``` +/usr/sbin/groupadd ivorysql +/usr/sbin/useradd -g ivorysql ivorysql -c "IvorySQL1.17" +passwd ivorysql +``` + +2.Environment variable: switch to user ivorysql, modify the file "/home/ivorysql/.bash_profile", and configure the environment variable: + +``` +umask 022 +export LD_LIBRARY_PATH=/opt/IvorySQL-1.17/lib:$LD_LIBRARY_PATH +export PATH=/opt/IvorySQL-1.17/bin:$PATH +export PGDATA=/home/ivorysql/data +``` + +Make the environment variable effective in the current ivorysql user session: + +``` +source .bash_profile +``` + +You can also log in again or open a new user ivorysql session. + +3.Set the firewall: If the firewall is enabled, port 5333 needs to be opened: + +``` +firewall-cmd --zone=public --add-port=5333/tcp --permanent +firewall-cmd --reload +``` + +> Note: The default port is 5333. If the port is not opened, the external client will fail to connect via IP. + +4.Initialization: Under user ivorysql, simply execute initdb to complete initialization: + +``` +initdb +``` + +> Note: The initdb operation is the same as PostgreSQL. It can be initialized according to the habits of PG. + +5.Start database: use pg_ Ctl starts the database service: + +``` +pg_ctl start +``` + +View the status and start successfully: + +``` +pg_ctl status +``` + +=== Configure service + +1.Client authentication: modify /home/ivorysql/data/pg_hba.conf, add the following: + +``` +host all all 0.0.0.0/0 trust +``` + +> Note: This is trust, which means that you can log in without password. + +Execute the following command to load the configuration: + +``` +pg_ctl reload +``` + +2.Basic parameters + +Connect to the database through psql: + +``` +psql +``` + +Modify listening address + +``` +alter system set listen_addresses = '*'; +``` + +> Note: The default is listening at 127.0.0.1. The service cannot be connected outside the host. + +3.Guard service + +Create a service file: + +``` +touch /usr/lib/systemd/system/ivorysql.service +``` + +The editing contents are as follows: + +``` +[Unit] +Description=IvorySQL 1.17 database server +Documentation=https://www.ivorysql.org +Requires=network.target local-fs.target +After=network.target local-fs.target + +[Service] +Type=forking + +User=ivorysql +Group=ivorysql + +Environment=PGDATA=/home/ivorysql/data + +OOMScoreAdjust=-1000 + +ExecStart=/opt/IvorySQL-1.17/bin/pg_ctl start -D ${PGDATA} +ExecStop=/opt/IvorySQL-1.17/bin/pg_ctl stop -D ${PGDATA} +ExecReload=/opt/IvorySQL-1.17/bin/pg_ctl reload -D ${PGDATA} + +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target +``` + +> Note: There are many ways to write a service. Be careful when using it in a production environment. Please repeat the test several times. + +Stop pg_ The database service started by ctl enables the systemd service and starts: + +``` +systemctl enable --now ivorysql.service +``` + +IvorSQL database service operation command: + +``` +systemctl start ivorysql.service +systemctl stop ivorysql.service +systemctl restart ivorysql.service +systemctl status ivorysql.service +systemctl reload ivorysql.service +``` + +=== Uninstall the IvorySQL database + +==== Compile Uninstall + +1.Backup data: we can protect the directory. It is better to stop the database service and make a backup. + +``` +systemctl stop ivorysql.service +``` + +2.Compile and uninstall: switch the root session to the source directory and execute the following commands respectively: + +``` +make uninstall +make clean +``` + +3.Delete residual directories and files: + +``` +systemctl disable ivorysql.servicemake --disable Service +mv /usr/lib/systemd/system/ivorysql.service /tmp/ --the service file can be moved to/tmp or deleted +rm -fr /opt/IvorySQL-1.17 --remove residual installation directory +``` + +> Note: There are also user ivorysql and corresponding environment variables, which can be cleaned according to the situation. Please make sure to make a backup before processing. There are also installed dependent packages, which can be uninstalled according to the situation. + +## Ubuntu Installation overview + +This article introduces the installation process and precautions of IvorySQL on Linux platform. This article mainly demonstrates rpm package installation steps, and source code installation steps of the database under the Ubuntu 2404 environment. + + +=== Software and hardware requirements + +==== Introduction to software resources +|==== +| operating system | Yum source download address +|Ubuntu 2404|https://github.com/IvorySQL/IvorySQL/releases +|==== + +==== Hardware resource preparation + +|==== +| Configuration parameters | **Minimum configuration** | **Recommended configuration** +| **CPU** | 4 cores | 16 cores +| **Memory** | 4GB | 64GB +| **Storage** | 800MB,mechanical hard disk | Above 5GB,SSD or NvMe +| **Network** | gigabit lan | 10 Gigabit network +|==== + +=== Environment and configuration check + +Before deploying the IvorySQL database, you need to check the system environment and configuration + +==== View resources + +The IvorySQL database supports CentOS 7. X, operating systems. For details, refer to <<#_software_and_hardware_requirements>>. + +==== View the operating system + +Run the following command to view the operating system information: + +``` +cat /etc/os-release +``` + +==== View kernel parameters + +``` +uname -r +``` + +=== Get installation package + +You can install the IvorySql database or DEB package through the source code. + +==== Use source code to build IvorySQL database + +1.Get the source code: Run the following command to clone the source code of the IvorySQL database to your build machine: + +``` +git clone https://github.com/IvorySQL/IvorySQL.git +``` + +> Note: To clone code, you need to install and configure Git first. For details, refer to https://git-scm.com/doc[Git doc]. + +2.Install dependent packages: To compile IvorySQL from source code, you must ensure that prerequisite packages are available on the system. Execute the following command to install related packages: + +``` +sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget +sudo apt install -y gcc make flex bison +``` + +3.Self-compilation and installation: The source code obtained previously is in the folder IvorySQL. Next, we will enter this folder for operation. + +Configuration: Root users execute the following commands to configure: + +``` +git checkout tags/Ivory_REL_1_17 +./configure --prefix=/usr/local/ivorysql/ivorysql-1.17 +``` + +> Note: If the `--prefix` option is not provided, the default installation path will be `/usr/local/ivorysql`. + +> Note: We should remember the specified directory, because the system cannot find out where the compiled and installed programs are. More configure parameters can be viewed through "./configure -- help". You can also view the PostgreSQL manual + +Compile and install: After the configuration is completed, execute make to compile: + +``` +make +``` + +Perform a regression test before installing the newly compiled service (the following commands can be used): + +``` +make check +make all-check-world +``` + +Installation: + +``` +make install +``` + +==== Install the IvorySQL database using the DEB package + +1. Run the following command to download the IvorySQL installation package. + +``` +wget https://github.com/IvorySQL/IvorySQL/releases/download/IvorySQL_1.17/IvorySQL-1.17-fde5539-20250326.amd64.deb +``` + +> Note: The installation package in the example may not be the latest version. It is recommended that you download the latest installation package. + +2.Run the following command to install IvorySQL. + +``` +sudo apt install ./IvorySQL-1.17-fde5539-20250326.amd64.deb +``` + + + +=== Initialize database service + +==== Initialize database + +1.Create an operating system user: under the user root session, create a new user ivorysql: + +``` +/usr/sbin/groupadd ivorysql +/usr/sbin/useradd -m -g ivorysql -s /bin/bash -c "IvorySQL1.17" ivorysql +usermod -a -G sudo ivorysql +passwd ivorysql + +mkdir /home/ivorysql +chown -R ivorysql:ivorysql /home/ivorysql +chmod 755 /home/ivorysql +``` + +2.Environment variable: switch to user ivorysql, modify the file "/home/ivorysql/.bashrc", and configure the environment variable: + +``` +umask 022 +export LD_LIBRARY_PATH=/opt/IvorySQL-1.17/lib:$LD_LIBRARY_PATH +export PATH=/opt/IvorySQL-1.17/bin:/usr/local/ivorysql/ivorysql-1.17/bin:$PATH #depend on your install path +export PGDATA=/home/ivorysql/data +``` + +Make the environment variable effective in the current ivorysql user session: + +``` +source .bashrc +``` + +You can also log in again or open a new user ivorysql session. + +3.Set the firewall: If the firewall is enabled, port 1521 needs to be opened: + +``` +firewall-cmd --zone=public --add-port=1521/tcp --permanent +firewall-cmd --reload +``` + +> Note: The default port is 1521. If the port is not opened, the external client will fail to connect via port. + +4.Initialization: Under user ivorysql, simply execute initdb to complete initialization: + +``` +initdb -D $PGDATA +``` + +> Note: The initdb operation is the same as PostgreSQL. It can be initialized according to the habits of PG. + +5.Start database: use pg_ Ctl starts the database service: + +``` +pg_ctl -D $PGDATA -l logfile start +``` + +View the status and start successfully: + +``` +pg_ctl -D $PGDATA status +pg_ctl: server is running (PID: 2273) +``` + +=== Configure service + +1.Client authentication: modify /home/ivorysql/data/pg_hba.conf, add the following: + +``` +host all all 0.0.0.0/0 trust +``` + +> Note: This is trust, which means that you can log in without password. + +Modify listening address: + +modify /home/ivorysql/data/postgresql.conf, add the following: + +``` +listen_addresses = '*' +``` +> Note: The default is listening at 127.0.0.1. The service cannot be connected outside the host. + +Execute the following command to load the configuration: + +``` +pg_ctl reload +``` + +2.Basic parameters + +Connect to the database through psql: + +``` +psql +``` + +3.Guard service + +Create a service file: + +``` +sudo vi /etc/systemd/system/ivorysql.service +``` + +The editing contents are as follows: + +``` +[Unit] +Description=IvorySQL 1.17 database server +Documentation=https://www.ivorysql.org +Requires=network.target local-fs.target +After=network.target local-fs.target + +[Service] +Type=forking + +User=ivorysql +Group=ivorysql + +Environment=PGDATA=/home/ivorysql/data + +OOMScoreAdjust=-1000 + +ExecStart=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl start -D ${PGDATA} +ExecStop=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl stop -D ${PGDATA} +ExecReload=/usr/local/ivorysql/ivorysql-1.17/bin/pg_ctl reload -D ${PGDATA} + +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target + +``` + +> Note: There are many ways to write a service. Be careful when using it in a production environment. Please repeat the test several times. + +Stop pg_ The database service started by ctl enables the systemd service and starts: + +``` +systemctl enable --now ivorysql.service +``` + +IvorSQL database service operation command: + +``` +systemctl start ivorysql.service +systemctl stop ivorysql.service +systemctl restart ivorysql.service +systemctl status ivorysql.service +systemctl reload ivorysql.service +``` + +=== Uninstall the IvorySQL database + +==== Compile Uninstall + +1.Backup data: we can protect the directory. It is better to stop the database service and make a backup. + +``` +systemctl stop ivorysql.service +``` + +2.Compile and uninstall: switch the root session to the source directory and execute the following commands respectively: + +``` +make uninstall +make clean +``` + +3.Delete residual directories and files: + +``` +systemctl disable ivorysql.service --disable Service +mv /usr/lib/systemd/system/ivorysql.service /tmp/ --the service file can be moved to/tmp or deleted +rm -fr /usr/local/ivorysql/ivorysql-1.17 --remove residual installation directory +``` + +> Note: There are also user ivorysql and corresponding environment variables, which can be cleaned according to the situation. Please make sure to make a backup before processing. There are also installed dependent packages, which can be uninstalled according to the situation. \ No newline at end of file diff --git a/EN/modules/ROOT/pages/v3.0/7.adoc b/EN/modules/ROOT/pages/v1.17/7.adoc similarity index 90% rename from EN/modules/ROOT/pages/v3.0/7.adoc rename to EN/modules/ROOT/pages/v1.17/7.adoc index 1d1768b..56d271b 100644 --- a/EN/modules/ROOT/pages/v3.0/7.adoc +++ b/EN/modules/ROOT/pages/v1.17/7.adoc @@ -1102,7 +1102,7 @@ It is your responsibility that the byte sequences you create, especially when us .Caution **** -If the configuration parameter https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings] is `off`, then IvorySQL recognizes backslash escapes in both regular and escape string constants. However, as of IvorySQL 9.1, the default is `on`, meaning that backslash escapes are recognized only in escape string constants. This behavior is more standards-compliant, but might break applications which rely on the historical behavior, where backslash escapes were always recognized. As a workaround, you can set this parameter to `off`, but it is better to migrate away from using backslash escapes. If you need to use a backslash escape to represent a special character, write the string constant with an `E`.In addition to `standard_conforming_strings`, the configuration parameters https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-ESCAPE-STRING-WARNING[escape_string_warning] and https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-BACKSLASH-QUOTE[backslash_quote] govern treatment of backslashes in string constants.The character with the code zero cannot be in a string constant. +If the configuration parameter https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS[standard_conforming_strings] is `off`, then IvorySQL recognizes backslash escapes in both regular and escape string constants. However, as of IvorySQL, the default is `on`, meaning that backslash escapes are recognized only in escape string constants. This behavior is more standards-compliant, but might break applications which rely on the historical behavior, where backslash escapes were always recognized. As a workaround, you can set this parameter to `off`, but it is better to migrate away from using backslash escapes. If you need to use a backslash escape to represent a special character, write the string constant with an `E`.In addition to `standard_conforming_strings`, the configuration parameters https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-ESCAPE-STRING-WARNING[escape_string_warning] and https://www.postgresql.org/docs/current/runtime-config-compatible.html#GUC-BACKSLASH-QUOTE[backslash_quote] govern treatment of backslashes in string constants.The character with the code zero cannot be in a string constant. **** ===== String Constants With Unicode Escapes @@ -1859,7 +1859,7 @@ SELECT ROW(t.f1, t.f2, 42) FROM t; .Note **** -Before IvorySQL 8.2, the `.*` syntax was not expanded in row constructors, so that writing `ROW(t.*, 42)` created a two-field row whose first field was another row value. The new behavior is usually more useful. If you need the old behavior of nested row values, write the inner row value without `.*`, for instance `ROW(t, 42)`. +Before PostgreSQL 8.2, the `.*` syntax was not expanded in row constructors, so that writing `ROW(t.*, 42)` created a two-field row whose first field was another row value. The new behavior is usually more useful. If you need the old behavior of nested row values, write the inner row value without `.*`, for instance `ROW(t, 42)`. **** By default, the value created by a `ROW` expression is of an anonymous record type. If necessary, it can be cast to a named composite type — either the row type of a table, or a composite type created with `CREATE TYPE AS`. An explicit cast might be needed to avoid ambiguity. For example: @@ -2082,409 +2082,12 @@ Named and mixed call notations currently cannot be used when calling an aggregat Parameters are set in the same way as in native IvorySQL. All parameter names are case-insensitive. Each parameter takes a value of one of the following five types: boolean, string, integer, floating point, or enum. -==== `compatible_mode (enum)` +==== `ivorysql.compatible_mode (enum)` -This parameter controls the behavior of the database server. The default value is `postgres`, which means it is a native installation and the server will be installed as a native PG. If it is set to `oracle`, then the query output and overall system behavior will change, as it will be more Oracle-like. +This parameter controls the behavior of the database server. If it is set to `pg`, which means it is a native installation and the server will be installed as a native PG. If it is set to `oracle`, then the query output and overall system behavior will change, as it will be more Oracle-like. When set to `oracle`, this parameter will implicitly add a Schema with the same name to `search_path`. so that Oracle-compatible objects can be located. -This parameter can be set via the `postgresql.conf` configuration file to take effect for the entire database. Or it can be set on the session by the client using the `set` command. - -=== Packages - -1.This section introduces IvorySQL's "Oracle-style packages". By definition, a package is an object or group of objects packaged together. In the case of a database, this translates into a named schema object that packages within itself a collection of procedures, functions, variables, cursors, user-defined record types, and logical groupings of referenced records. It is expected that users are familiar with IvorySQL and have a good understanding of the SQL language in order to better understand these packages and use them more effectively. - -==== Requirements for packages - -As with similar constructs in various other programming languages, there are many benefits to using packages with SQL. In this section, we are going to talk about a few. - -1.Reliability and reusability of code packages - - Packages enable you to create modular objects that encapsulate code. This makes the overall design and implementation much easier. By encapsulating variables and related types, stored procedures/functions, and cursors, it allows you to create a stand-alone module that is simple, easy to understand, and easy to maintain and use. Encapsulation works by exposing the package interface rather than the implementation details of the package body. As a result, this is beneficial in many ways. It allows applications and users to reference a consistent interface without having to worry about the content of its body. In addition, it prevents users from making any decisions based on the code implementation, which is never exposed to them. - -2.Ease of use - - The ability to create consistent functional interfaces in IvorySQL helps simplify application development because it allows packages to be compiled without a body. After the development phase, packages allow users to manage access control for the entire package, rather than individual objects. This is very valuable, especially when the package contains many schema objects. - -3.Performance - - Packages are loaded into memory for maintenance, and therefore use minimal I/O resources. Recompilation is simple and limited to changed objects; no recompilation of slave objects. - -4.Additional Features - - In addition to performance and ease of use, the package provides session-wide persistence for variables and cursors. This means that variables and cursors have the same lifetime as the database session and are destroyed when the session is destroyed. - -==== Package Components - -A package has an interface and a body, which are the main components that make up the package. - -1.Package specification - - The package specification specifies any objects within the package that are used from the outside. This refers to interfaces that are publicly accessible. It does not contain their definitions or implementations, i.e., functions and procedures. It defines only the title, not the body definition. Variables can be initialized. The following is a list of objects that can be listed in the specification. - - - Functions - - Procedures - - Cursors - - Types - - Variables - - Constants - - Record types - -2.Package Bodies - - The package body contains all the implementation code of the package, including public interfaces and private objects. If the specification does not contain any subroutines or cursors, the package body is optional. - - It must contain the definitions of the subroutines declared in the specification, and the corresponding definitions must match. - - A package body may contain its own subroutines and type declarations for any internal objects not specified in the specification. These objects are considered private. It is not possible to access private objects outside the package. - - In addition to the subroutine definition, it may optionally contain an initialization block that initializes the variables declared in the specification and is executed only once when the package is first invoked in a session. - -.**Note** -**** -If the specification changes, the package body will be invalidated. Care must be taken when identifying public and private interfaces to avoid exposing critical functions and variables outside of the package. -**** - -==== Package Syntax - -##### Package Specification Syntax - -```SQL -CREATE [ OR REPLACE ] PACKAGE [schema.] *package_name* [invoker_rights_clause] [IS | AS] - item_list[, item_list ...] -END [*package_name*]; - - -invoker_rights_clause: - AUTHID [CURRENT_USER | DEFINER] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - - -function_declaration: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype; - -procedure_declaration: - PROCEDURE procedure_name [(parameter_declaration[, ...])] - -type_definition: - record_type_definition | - ref_cursor_type_definition - -cursor_declaration: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype; - -item_declaration: - cursor_declaration | - cursor_variable_declaration | - record_variable_declaration | - variable_declaration | - -record_type_definition: - TYPE record_type IS RECORD ( variable_declaration [, variable_declaration]... ) ; - -ref_cursor_type_definition: - TYPE type IS REF CURSOR [ RETURN type%ROWTYPE ]; - -cursor_variable_declaration: - curvar curtype; - -record_variable_declaration: - recvar { record_type | rowtype_attribute | record_type%TYPE }; - -variable_declaration: - varname datatype [ [ NOT NULL ] := expr ] - -parameter_declaration: - parameter_name [IN] datatype [[:= | DEFAULT] expr] -``` - -##### Package Body Syntax - -```SQL -CREATE [ OR REPLACE ] PACKAGE BODY [schema.] package_name [IS | AS] - [item_list[, item_list ...]] | - item_list_2 [, item_list_2 ...] - [initialize_section] -END [package_name]; - - -initialize_section: - BEGIN statement[, ...] - -item_list: -[ - function_declaration | - procedure_declaration | - type_definition | - cursor_declaration | - item_declaration -] - -item_list_2: -[ - function_declaration - function_definition - procedure_declaration - procedure_definition - cursor_definition -] - -function_definition: - FUNCTION function_name [(parameter_declaration[, ...])] RETURN datatype [IS | AS] - [declare_section] body; - -procedure_definition: - PROCEDURE procedure_name [(parameter_declaration[, ...])] [IS | AS] - [declare_section] body; - -cursor_definition: - CURSOR name [(cur_param_decl[, ...])] RETURN rowtype IS select_statement; - -body: - BEGIN statement[, ...] END [name]; - -statement: - [<<LABEL>>] pl_statments[, ...]; -``` - -##### **Description** - -Create Package defines a new package. Creating or replacing a package will create a new package or replace an existing definition. - -If the architecture name is included, the package is created in the specified architecture. Otherwise, it will be created in the current architecture. The name of the new package must be unique within the architecture. - -When replacing an existing package with "Create or Replace Package", the ownership and permissions of the package are not changed. All other package properties are specified as specified or implied in the command. You must own the package in order to replace it (this includes being a member of the role to which it belongs). - -The user who created the package becomes the owner of the package. - -##### **parameters** - -`package_name` The name of the package to be created (optionally architecture qualified). - -`invoker_rights_clause` Caller permissions define the package's access to database objects. The available options are. - -- *CURRENT_USER* The access rights of the current user executing the package will be used. -- *DEFINER* will use the access rights of the package creator. - -`item_list` This is the list of items that can be part of the package. - -`procedure_declaration` Specifies the procedure name and its argument list. This is just a declaration and does not define the procedure. - -When this declaration is part of the package specification, it is a public procedure and its definition must be added to the package body. - -When it is part of the package body, it acts as a forwarding declaration and is a private procedure accessible only to package elements. - -The `procedure_definition` procedure is defined in the package body. This defines the previously declared procedure. It is also possible to define a procedure without any previous declarations, which would make it a private procedure. - -` function_declaration` defines the function name, its arguments and its return type. It is just a declaration and will not define a function. - -When this declaration is part of the package specification, it is a public function and its definition must be added to the package body. - -When it is part of the package body, it acts as a forwarding declaration and is a private function accessible only to package elements. - -`function_definition` These functions are defined in the package body. This defines the function declared earlier. It can also define a function without any previous declarations, which would make it a private function. - -`type_definition` suggests that you can define record or cursor types. - -`cursor_declaration` defines that a cursor declaration must include its arguments and return type as the required line type. - -`item_declaration` allows declarations: - -- Cursors -- Cursor variables -- Record variables -- Variables - -`parameter_declaration` defines the syntax for declaring parameters. If the keyword "IN" is specified, it means that this is an input parameter. The default keyword followed by an expression (or value) can only be specific to the input parameter. - -`declare_section` It contains all elements local to the function or procedure and can be referenced in its body. - -`body` The body consists of the SQL statements or PL control structures supported by the PL/iSQL language. - -==== Creating and Accessing Packages - -===== Creating Packages - -In this section, we will learn more about the package construction process and how to access its public elements. - -When a package is created, IvorySQL will compile it and report any issues it may find. Once the package is successfully compiled, it will be removed ready for use. - -##### Accessing Package Elements - -When a package is first referenced in a session, it will be instantiated and initialized. The following actions perform this process in the procedure. - -- Assigning initial values to public constants and variables -- Execute the initial value setting item block for the package - -There are several ways to access package elements. - -- Package functions can be used like any other function in a SELECT statement or other PL block - -- Package procedures can be called directly using CALL or from other PL blocks - -- Package variables can be read and written directly using the package name qualification in the PL block or from the SQL prompt. - -- Direct access using dot notation: In the dot representation, elements can be accessed by - - - package_name.func('foo'); - - - package_name.proc('foo'); - - - package_name.variable; - - - package_name.constant; - - - package_name.other_package.func('foo'); - - These statements can be used from inside a PL block, or in a SELECT statement if the elements are not type declarations or procedures. - -- SQL call statements: Another way is to use the CALL statement. the CALL statement executes a standalone procedure, or a function defined in a type or package. - - - CALL package_name.func('foo'); - - CALL package_name.proc('foo'); - -==== Understanding the Scope of Visibility - -The scope of a variable declared in a PL/SQL block is limited to that block. If it has nested blocks, it will be a global variable of the nested block. - -Similarly, if both blocks declare variables with the same name, then within the nested block, its own declared variable is visible and the parent variable is invisible. To access the parent variable, the variable must be fully qualified. - -Consider the following code snippet. - -==== **Example: Visibility and Qualified Variable Names** - -```SQL -<<blk_1>> -DECLARE - x INT; - y INT; -BEGIN - -- both blk_1.x and blk_1.y are visible - <<blk_2>> - DECLARE - x INT; - z INT; - BEGIN - -- blk_2.x, y and z are visible - -- to access blk_1.x it has to be a qualified name. blk_1.x := 0; NULL; - END; - -- both x and y are visible -END; -``` - -The above example shows how variable names must be fully qualified when nested packages contain variables with the same name. - -Variable name qualification helps to resolve possible confusion introduced by scope precedence in the following cases. - -- Package and nested package variables: if unqualified, nested takes precedence -- Package variables and column names: if unqualified, column names take precedence -- Function or program variables and package variables: if unqualified, package variables take precedence. - -Type qualification is required for fields or methods in the following types - -- Record type - -**Example: Record type visibility and access** - -```SQL -DECLARE - x INT; - TYPE xRec IS RECORD (x char, y INT); -BEGIN - x := 1; -- will always refer to x(INT) type. - xRec.x := '2'; -- to refer the CHAR type, it will have to be -qualified name -END; -``` - -==== Package Example - -##### Package Specifications - -```SQL -CREATE TABLE test(x INT, y VARCHAR2(100)); -INSERT INTO test VALUES (1, 'One'); -INSERT INTO test VALUES (2, 'Two'); -INSERT INTO test VALUES (3, 'Three'); - --- Package specification: -CREATE OR REPLACE PACKAGE example AUTHID DEFINER AS - -- Declare public type, cursor, and exception: - TYPE rectype IS RECORD (a INT, b VARCHAR2(100)); - CURSOR curtype RETURN rectype%rowtype; - - rec rectype; - - -- Declare public subprograms: - FUNCTION somefunc ( - last_name VARCHAR2, - first_name VARCHAR2, - email VARCHAR2 - ) RETURN NUMBER; - - -- Overload preceding public subprogram: - PROCEDURE xfunc (emp_id NUMBER); - PROCEDURE xfunc (emp_email VARCHAR2); -END example; -/ -``` - -##### Package body - -```SQL --- Package body: -CREATE OR REPLACE PACKAGE BODY example AS - nelems NUMBER; -- private variable, visible only in this package - - -- Define cursor declared in package specification: - CURSOR curtype RETURN rectype%rowtype IS SELECT x, y - FROM test - ORDER BY x; - -- Define subprograms declared in package specification: - FUNCTION somefunc ( - last_name VARCHAR2, - first_name VARCHAR2, - email VARCHAR2 - ) RETURN NUMBER IS - id NUMBER := 0; - BEGIN - OPEN curtype; - LOOP - FETCH curtype INTO rec; - EXIT WHEN NOT FOUND; - END LOOP; - RETURN rec.a; - END; - - PROCEDURE xfunc (emp_id NUMBER) IS - BEGIN - NULL; - END; - - PROCEDURE xfunc (emp_email VARCHAR2) IS - BEGIN - NULL; - END; - -BEGIN -- initialization part of package body - nelems := 0; -END example; -/ -SELECT example.somefunc('Joe', 'M.', 'email@example.com'); -``` - -#### Limitations - -Record types are supported as package variables, but they can only be used within package elements, i.e. package functions/procedures can use them. They cannot be accessed outside the package, a restriction that will be addressed in the next update of IvorySQL. - === Changing tables #### syntax @@ -2665,7 +2268,7 @@ Id | flg #### Example ```undefined -set compatible_mode to oracle; +set ivorysql.compatible_mode to oracle; create table students(student_id varchar(20) primary key , student_name varchar(40), diff --git a/EN/modules/ROOT/pages/v3.0/8.adoc b/EN/modules/ROOT/pages/v1.17/8.adoc similarity index 96% rename from EN/modules/ROOT/pages/v3.0/8.adoc rename to EN/modules/ROOT/pages/v1.17/8.adoc index 0f1cc81..16e54b1 100644 --- a/EN/modules/ROOT/pages/v3.0/8.adoc +++ b/EN/modules/ROOT/pages/v1.17/8.adoc @@ -5,17 +5,17 @@ = Operation and maintenance management guide -Since IvorySQL is based on PostgreSQL, it is recommended that when reading and understanding this section, O&M staff also refer to https://www.postgresql.org/docs/15/index.html[doc]。 +Since IvorySQL is based on PostgreSQL, it is recommended that when reading and understanding this section, O&M staff also refer to https://www.postgresql.org/docs/17/index.html[doc]。 == Upgrade IvorySQL version === Overview of upgrade scheme -The IvorySQL version number consists of a major version and a minor version. For example, 1 in IvorySQL 1.3 is the major version and 3 is the minor version. +The IvorySQL version number consists of a major version and a minor version. For example, 3 in IvorySQL 3.2 is the major version and 2 is the minor version. -Releasing a minor version is not going to change the in-memory storage format, so it is always compatible with the same major version. For example, IvorySQL 1.3 is compatible with Ivory SQL 1.0 and the subsequent Ivory SQL 1.x. Upgrading for these compatible versions is as simple as shutting down the database service, installing a replacement binary executable, and restarting the service. +Releasing a minor version is not going to change the internal storage format, so it is always compatible with the same major version. For example, IvorySQL 3.4 is compatible with Ivory SQL 3.0 and the subsequent Ivory SQL 3.x. Upgrading for these compatible versions is as simple as shutting down the database service, installing a replacement binary executable, and restarting the service. -​ Next, we focus on cross-version upgrades of IvorySQL, for example, from IvorySQL 1.3 to IvorySQL 2.1. Major version upgrades may modify the internal data storage format and therefore require additional operations to be performed. The common cross-version upgrade methods and applicable scenarios are as follows. +​ Next, we focus on cross-version upgrades of IvorySQL, for example, from IvorySQL 2.3 to IvorySQL 3.2. Major version upgrades may modify the internal data storage format and therefore require additional operations to be performed. The common cross-version upgrade methods and applicable scenarios are as follows. |==== | Upgrade method | Applicable scenarios | Shutdown time @@ -29,9 +29,9 @@ Releasing a minor version is not going to change the in-memory storage format, s === Upgrade data via pg_dumpall -The traditional cross-version upgrade method uses pg_dump/pg_dumpall to logically backup the database everywhere and then restore it in the new version via pg_restore. It is recommended to use the new version of pg_dump/pg_dumpall tool when exporting the old version of the database.You can take advantage of its latest parallel export and restore features, while reducing database bloat problems. +The traditional cross-version upgrade method uses pg_dump/pg_dumpall to logically backup the database and then restore it in the new version via pg_restore. It is recommended to use the new version of pg_dump/pg_dumpall tool when exporting the old version of the database. You can take advantage of its latest parallel export and restore features, while reducing database bloat problems. -Logical backup and restore is very simple but slow, downtime depends on the size of the database, so it is suitable for small to medium sized database upgrades. +Logical backup and restore is very simple but slow. Downtime depends on the size of the database, so it is suitable for small to medium sized database upgrades. ​The following describes how this upgrade method works. If the current IvorySQL software installation directory is located in /usr/local/pgsql and the data directory is located in /usr/local/pgsql/data, we do the upgrade on the same server. @@ -87,7 +87,7 @@ This upgrade method can be used with built-in logical replication tools and exte == Managing IvorySQL Versions -IvorySQL is based on PostgreSQL and is updated at the same frequency as PostgreSQL, with one major release per year and one minor release per quarter. IvorySQL 3.0 is based on PostgreSQL 16.0, and all versions of IvorySQL are backward compatible.The relevant version features can be viewed by looking at https://deploy-preview-83--ivorysql.netlify.app/zh-CN/releases-page[Official Website]。 +IvorySQL is based on PostgreSQL and is updated at the same frequency as PostgreSQL, with one major release per year and one minor release per quarter. IvorySQL 4.2 is based on PostgreSQL 17.2, and all versions of IvorySQL are backward compatible.The relevant version features can be viewed by looking at https://www.ivorysql.org/en/releases-page/[Official Website]。 == Managing IvorySQL database access @@ -127,7 +127,7 @@ It is often convenient to group users together to facilitate the management of p Since roles can own database objects and hold privileges to access other objects, deleting a role is often not a one-time DROP ROLE solution. Any objects owned by that user must first be deleted or transferred to another owner, and any privileges that have been granted to that role must be withdrawn. -For more details on database access management, refers to https://www.postgresql.org/docs/15/user-manag.html[doc]. +For more details on database access management, refers to https://www.postgresql.org/docs/17/user-manag.html[doc]. == Defining Data Objects @@ -197,7 +197,7 @@ The idea behind this dump method is to generate a file with SQL commands that, w As you see, pg_dump writes its result to the standard output. We will see below how this can be useful. While the above command creates a text file, pg_dump can create files in other formats that allow for parallelism and more fine-grained control of object restoration. -pg_dump is a regular IvorySQL client application (albeit a particularly clever one). This means that you can perform this backup procedure from any remote host that has access to the database. But remember that pg_dump does not operate with special permissions. In particular, it must have read access to all tables that you want to back up, so in order to back up the entire database you almost always have to run it as a database superuser. (If you do not have sufficient privileges to back up the entire database, you can still back up portions of the database to which you do have access using options such as `-n *`schema`*` or `-t *`table`*`.) +pg_dump is a regular IvorySQL client application (albeit a particularly clever one). This means that you can perform this backup procedure from any remote host that has access to the database. pg_dump must have read access to all tables that you want to back up, so in order to back up the entire database you almost always have to run it as a database superuser. (If you do not have sufficient privileges to back up the entire database, you can still back up portions of the database to which you do have access using options such as `-n *`schema`*` or `-t *`table`*`.) ​To specify which database server pg_dump should contact, use the command line options `-h *`host`*` and `-p *`port`*`. The default host is the local host or whatever your `HOST` environment variable specifies. Similarly, the default port is indicated by the `PORT` environment variable or, failing that, by the compiled-in default. (Conveniently, the server will normally have the same compiled-in default.) @@ -332,7 +332,7 @@ At all times,IvorySQLmaintains a *write ahead log* (WAL) in the `pg_wal/` subdir ​ As with the plain file-system-backup technique, this method can only support restoration of an entire database cluster, not a subset. Also, it requires a lot of archival storage: the base backup might be bulky, and a busy system will generate many megabytes of WAL traffic that have to be archived. Still, it is the preferred backup technique in many situations where high reliability is needed. -​ To recover successfully using continuous archiving (also called “online backup” by many database vendors), you need a continuous sequence of archived WAL files that extends back at least as far as the start time of your backup. So to get started, you should set up and test your procedure for archiving WAL files *before* you take your first base backup. Accordingly, we first discuss the mechanics of archiving WAL files.For more information on how to create archives and backups and the key points during operation, please refer to https://www.postgresql.org/docs/15/backup.html[doc]。 +​ To recover successfully using continuous archiving (also called “online backup” by many database vendors), you need a continuous sequence of archived WAL files that extends back at least as far as the start time of your backup. So to get started, you should set up and test your procedure for archiving WAL files *before* you take your first base backup. Accordingly, we first discuss the mechanics of archiving WAL files.For more information on how to create archives and backups and the key points during operation, please refer to https://www.postgresql.org/docs/17/backup.html[doc]。 == Loading and unloading data @@ -372,7 +372,7 @@ where option can be one of: ENCODING 'encoding_name' ---- -For detailed parameter settings, please refer to https://www.postgresql.org/docs/15/sql-copy.html[doc]. +For detailed parameter settings, please refer to https://www.postgresql.org/docs/17/sql-copy.html[doc]. === Outputs @@ -578,7 +578,7 @@ ZW ZIMBABWE 0000200 M B A B W E 377 377 377 377 377 377 ---- -The remaining details can see https://www.postgresql.org/docs/15/sql-copy.html[doc]. +The remaining details can see https://www.postgresql.org/docs/17/sql-copy.html[doc]. == Performance Tips @@ -586,7 +586,7 @@ Query performance can be affected by a variety of factors. Some of these factors === Using EXPLAIN -IvorySQL devises a *query plan* for each query it receives. Choosing the right plan to match the query structure and the properties of the data is absolutely critical for good performance, so the system includes a complex *planner* that tries to choose good plans. You can use the https://www.postgresql.org/docs/15/sql-explain.html[`EXPLAIN`] command to see what query plan the planner creates for any query. Plan-reading is an art that requires some experience to master, but this section attempts to cover the basics. +IvorySQL devises a *query plan* for each query it receives. Choosing the right plan to match the query structure and the properties of the data is absolutely critical for good performance, so the system includes a complex *planner* that tries to choose good plans. You can use the https://www.postgresql.org/docs/17/sql-explain.html[`EXPLAIN`] command to see what query plan the planner creates for any query. Plan-reading is an art that requires some experience to master, but this section attempts to cover the basics. ​ The examples use `EXPLAIN`'s default “text” output format, which is compact and convenient for humans to read. If you want to feed `EXPLAIN`'s output to a program for further analysis, you should use one of its machine-readable output formats (XML, JSON, or YAML) instead. @@ -612,7 +612,7 @@ Since this query has no `WHERE` clause, it must scan all the rows of the table, * Estimated number of rows output by this plan node. Again, the node is assumed to be run to completion. * Estimated average width of rows output by this plan node (in bytes). -​ The costs are measured in arbitrary units determined by the planner's cost parameters .Traditional practice is to measure the costs in units of disk page fetches; that is, https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-SEQ-PAGE-COST[seq_page_cost] is conventionally set to `1.0` and the other cost parameters are set relative to that. The examples in this section are run with the default cost parameters. +​ The costs are measured in arbitrary units determined by the planner's cost parameters .Traditional practice is to measure the costs in units of disk page fetches; that is, https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-SEQ-PAGE-COST[seq_page_cost] is conventionally set to `1.0` and the other cost parameters are set relative to that. The examples in this section are run with the default cost parameters. ​ It's important to understand that the cost of an upper-level node includes the cost of all its child nodes. It's also important to realize that the cost only reflects things that the planner cares about. In particular, the cost does not consider the time spent transmitting result rows to the client, which could be an important factor in the real elapsed time; but the planner ignores it because it cannot change it by altering the plan. (Every correct plan will output the same row set, we trust.) @@ -634,7 +634,7 @@ EXPLAIN SELECT * FROM tenk1; SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1'; ---- -​ you will find that `tenk1` has 358 disk pages and 10000 rows. The estimated cost is computed as (disk pages read * https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-SEQ-PAGE-COST[seq_page_cost]) + (rows scanned * https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-CPU-TUPLE-COST[cpu_tuple_cost]). By default, `seq_page_cost` is 1.0 and `cpu_tuple_cost` is 0.01, so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458. +​ you will find that `tenk1` has 358 disk pages and 10000 rows. The estimated cost is computed as (disk pages read * https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-SEQ-PAGE-COST[seq_page_cost]) + (rows scanned * https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-CPU-TUPLE-COST[cpu_tuple_cost]). By default, `seq_page_cost` is 1.0 and `cpu_tuple_cost` is 0.01, so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458. Now let's modify the query to add a `WHERE` condition: @@ -647,7 +647,7 @@ EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 7000; Filter: (unique1 < 7000) ---- -​ Notice that the `EXPLAIN` output shows the `WHERE` clause being applied as a “filter” condition attached to the Seq Scan plan node. This means that the plan node checks the condition for each row it scans, and outputs only the ones that pass the condition. The estimate of output rows has been reduced because of the `WHERE` clause. However, the scan will still have to visit all 10000 rows, so the cost hasn't decreased; in fact it has gone up a bit (by 10000 * https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-CPU-OPERATOR-COST[cpu_operator_cost], to be exact) to reflect the extra CPU time spent checking the `WHERE` condition. +​ Notice that the `EXPLAIN` output shows the `WHERE` clause being applied as a “filter” condition attached to the Seq Scan plan node. This means that the plan node checks the condition for each row it scans, and outputs only the ones that pass the condition. The estimate of output rows has been reduced because of the `WHERE` clause. However, the scan will still have to visit all 10000 rows, so the cost hasn't decreased; in fact it has gone up a bit (by 10000 * https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-CPU-OPERATOR-COST[cpu_operator_cost], to be exact) to reflect the extra CPU time spent checking the `WHERE` condition. The actual number of rows this query would select is 7000, but the `rows` estimate is only approximate. If you try to duplicate this experiment, you will probably get a slightly different estimate; moreover, it can change after each `ANALYZE` command, because the statistics produced by `ANALYZE` are taken from a randomized sample of the table. @@ -1040,7 +1040,7 @@ The `Execution time` shown by `EXPLAIN ANALYZE` includes executor start-up and s ==== Caveats -There are two significant ways in which run times measured by `EXPLAIN ANALYZE` can deviate from normal execution of the same query. First, since no output rows are delivered to the client, network transmission costs and I/O conversion costs are not included. Second, the measurement overhead added by `EXPLAIN ANALYZE` can be significant, especially on machines with slow `gettimeofday()` operating-system calls. You can use the https://www.postgresql.org/docs/15/pgtesttiming.html[pg_test_timing] tool to measure the overhead of timing on your system. +There are two significant ways in which run times measured by `EXPLAIN ANALYZE` can deviate from normal execution of the same query. First, since no output rows are delivered to the client, network transmission costs and I/O conversion costs are not included. Second, the measurement overhead added by `EXPLAIN ANALYZE` can be significant, especially on machines with slow `gettimeofday()` operating-system calls. You can use the https://www.postgresql.org/docs/17/pgtesttiming.html[pg_test_timing] tool to measure the overhead of timing on your system. `EXPLAIN` results should not be extrapolated to situations much different from the one you are actually testing; for example, results on a toy-sized table cannot be assumed to apply to large tables. The planner's cost estimates are not linear and so it might choose a different plan for a larger or smaller table. An extreme example is that on a table that only occupies one disk page, you'll nearly always get a sequential scan plan whether indexes are available or not. The planner realizes that it's going to take one disk page read to process the table in any case, so there's no value in expending additional page reads to look at an index. (We saw this happening in the `polygon_tbl` example above.) @@ -1075,7 +1075,7 @@ Normally, `EXPLAIN` will display every plan node created by the planner. However As we saw in the previous section, the query planner needs to estimate the number of rows retrieved by a query in order to make good choices of query plans. This section provides a quick look at the statistics that the system uses for these estimates. -One component of the statistics is the total number of entries in each table and index, as well as the number of disk blocks occupied by each table and index. This information is kept in the table https://www.postgresql.org/docs/15/catalog-pg-class.html[`pg_class`], in the columns `reltuples` and `relpages`. We can look at it with queries similar to this one: +One component of the statistics is the total number of entries in each table and index, as well as the number of disk blocks occupied by each table and index. This information is kept in the table https://www.postgresql.org/docs/17/catalog-pg-class.html[`pg_class`], in the columns `reltuples` and `relpages`. We can look at it with queries similar to this one: ---- SELECT relname, relkind, reltuples, relpages @@ -1098,11 +1098,11 @@ For efficiency reasons, `reltuples` and `relpages` are not updated on-the-fly, a -Most queries retrieve only a fraction of the rows in a table, due to `WHERE` clauses that restrict the rows to be examined. The planner thus needs to make an estimate of the *selectivity* of `WHERE` clauses, that is, the fraction of rows that match each condition in the `WHERE` clause. The information used for this task is stored in the https://www.postgresql.org/docs/15/catalog-pg-statistic.html[`pg_statistic`] system catalog. Entries in `pg_statistic` are updated by the `ANALYZE` and `VACUUM ANALYZE` commands, and are always approximate even when freshly updated. +Most queries retrieve only a fraction of the rows in a table, due to `WHERE` clauses that restrict the rows to be examined. The planner thus needs to make an estimate of the *selectivity* of `WHERE` clauses, that is, the fraction of rows that match each condition in the `WHERE` clause. The information used for this task is stored in the https://www.postgresql.org/docs/17/catalog-pg-statistic.html[`pg_statistic`] system catalog. Entries in `pg_statistic` are updated by the `ANALYZE` and `VACUUM ANALYZE` commands, and are always approximate even when freshly updated. -Rather than look at `pg_statistic` directly, it's better to look at its view https://www.postgresql.org/docs/15/view-pg-stats.html[`pg_stats`] when examining the statistics manually. `pg_stats` is designed to be more easily readable. Furthermore, `pg_stats` is readable by all, whereas `pg_statistic` is only readable by a superuser. (This prevents unprivileged users from learning something about the contents of other people's tables from the statistics. The `pg_stats` view is restricted to show only rows about tables that the current user can read.) For example, we might do: +Rather than look at `pg_statistic` directly, it's better to look at its view https://www.postgresql.org/docs/17/view-pg-stats.html[`pg_stats`] when examining the statistics manually. `pg_stats` is designed to be more easily readable. Furthermore, `pg_stats` is readable by all, whereas `pg_statistic` is only readable by a superuser. (This prevents unprivileged users from learning something about the contents of other people's tables from the statistics. The `pg_stats` view is restricted to show only rows about tables that the current user can read.) For example, we might do: ---- SELECT attname, inherited, n_distinct, @@ -1127,9 +1127,9 @@ WHERE tablename = 'road'; Note that two rows are displayed for the same column, one corresponding to the complete inheritance hierarchy starting at the `road` table (`inherited`=`t`), and another one including only the `road` table itself (`inherited`=`f`). -The amount of information stored in `pg_statistic` by `ANALYZE`, in particular the maximum number of entries in the `most_common_vals` and `histogram_bounds` arrays for each column, can be set on a column-by-column basis using the `ALTER TABLE SET STATISTICS` command, or globally by setting the https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET[default_statistics_target] configuration variable. The default limit is presently 100 entries. Raising the limit might allow more accurate planner estimates to be made, particularly for columns with irregular data distributions, at the price of consuming more space in `pg_statistic` and slightly more time to compute the estimates. Conversely, a lower limit might be sufficient for columns with simple data distributions. +The amount of information stored in `pg_statistic` by `ANALYZE`, in particular the maximum number of entries in the `most_common_vals` and `histogram_bounds` arrays for each column, can be set on a column-by-column basis using the `ALTER TABLE SET STATISTICS` command, or globally by setting the https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET[default_statistics_target] configuration variable. The default limit is presently 100 entries. Raising the limit might allow more accurate planner estimates to be made, particularly for columns with irregular data distributions, at the price of consuming more space in `pg_statistic` and slightly more time to compute the estimates. Conversely, a lower limit might be sufficient for columns with simple data distributions. -Further details about the planner's use of statistics can be found in https://www.postgresql.org/docs/15/planner-stats-details.html[doc]. +Further details about the planner's use of statistics can be found in https://www.postgresql.org/docs/17/planner-stats-details.html[doc]. ==== Extended Statistics @@ -1137,7 +1137,7 @@ It is common to see slow queries running bad execution plans because multiple co Because the number of possible column combinations is very large, it's impractical to compute multivariate statistics automatically. Instead, *extended statistics objects*, more often called just *statistics objects*, can be created to instruct the server to obtain statistics across interesting sets of columns. -Statistics objects are created using the https://www.postgresql.org/docs/15/sql-createstatistics.html[`CREATE STATISTICS`] command. Creation of such an object merely creates a catalog entry expressing interest in the statistics. Actual data collection is performed by `ANALYZE` (either a manual command, or background auto-analyze). The collected values can be examined in the https://www.postgresql.org/docs/15/catalog-pg-statistic-ext-data.html[`pg_statistic_ext_data`] catalog. +Statistics objects are created using the https://www.postgresql.org/docs/17/sql-createstatistics.html[`CREATE STATISTICS`] command. Creation of such an object merely creates a catalog entry expressing interest in the statistics. Actual data collection is performed by `ANALYZE` (either a manual command, or background auto-analyze). The collected values can be examined in the https://www.postgresql.org/docs/17/catalog-pg-statistic-ext-data.html[`pg_statistic_ext_data`] catalog. `ANALYZE` computes extended statistics based on the same sample of table rows that it takes for computing regular single-column statistics. Since the sample size is increased by increasing the statistics target for the table or any of its columns (as described in the previous section), a larger statistics target will normally result in more accurate extended statistics, as well as more time spent calculating them. @@ -1269,7 +1269,7 @@ SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id; ​ the planner is free to join the given tables in any order. For example, it could generate a query plan that joins A to B, using the `WHERE` condition `a.id = b.id`, and then joins C to this joined table, using the other `WHERE` condition. Or it could join B to C and then join A to that result. Or it could join A to C and then join them with B — but that would be inefficient, since the full Cartesian product of A and C would have to be formed, there being no applicable condition in the `WHERE` clause to allow optimization of the join. (All joins in the IvorySQL executor happen between two input tables, so it's necessary to build up the result in one or another of these fashions.) The important point is that these different join possibilities give semantically equivalent results but might have hugely different execution costs. Therefore, the planner will explore all of them to try to find the most efficient query plan. -When a query only involves two or three tables, there aren't many join orders to worry about. But the number of possible join orders grows exponentially as the number of tables expands. Beyond ten or so input tables it's no longer practical to do an exhaustive search of all the possibilities, and even for six or seven tables planning might take an annoyingly long time. When there are too many input tables, the IvorySQL planner will switch from exhaustive search to a *genetic* probabilistic search through a limited number of possibilities. (The switch-over threshold is set by the https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-GEQO-THRESHOLD[geqo_threshold] run-time parameter.) The genetic search takes less time, but it won't necessarily find the best possible plan. +When a query only involves two or three tables, there aren't many join orders to worry about. But the number of possible join orders grows exponentially as the number of tables expands. Beyond ten or so input tables it's no longer practical to do an exhaustive search of all the possibilities, and even for six or seven tables planning might take an annoyingly long time. When there are too many input tables, the IvorySQL planner will switch from exhaustive search to a *genetic* probabilistic search through a limited number of possibilities. (The switch-over threshold is set by the https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-GEQO-THRESHOLD[geqo_threshold] run-time parameter.) The genetic search takes less time, but it won't necessarily find the best possible plan. When the query involves outer joins, the planner has less freedom than it does for plain (inner) joins. For example, consider: @@ -1297,7 +1297,7 @@ SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id); ​ But if we tell the planner to honor the `JOIN` order, the second and third take less time to plan than the first. This effect is not worth worrying about for only three tables, but it can be a lifesaver with many tables. -To force the planner to follow the join order laid out by explicit `JOIN`s, set the https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT[join_collapse_limit] run-time parameter to 1. (Other possible values are discussed below.) +To force the planner to follow the join order laid out by explicit `JOIN`s, set the https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT[join_collapse_limit] run-time parameter to 1. (Other possible values are discussed below.) You do not need to constrain the join order completely in order to cut search time, because it's OK to use `JOIN` operators within items of a plain `FROM` list. For example, consider: @@ -1326,7 +1326,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; ​ This usually results in a better plan than planning the subquery separately. (For example, the outer `WHERE` conditions might be such that joining X to A first eliminates many rows of A, thus avoiding the need to form the full logical output of the subquery.) But at the same time, we have increased the planning time; here, we have a five-way join problem replacing two separate three-way join problems. Because of the exponential growth of the number of possibilities, this makes a big difference. The planner tries to avoid getting stuck in huge join search problems by not collapsing a subquery if more than `from_collapse_limit` `FROM` items would result in the parent query. You can trade off planning time against quality of plan by adjusting this run-time parameter up or down. -https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-FROM-COLLAPSE-LIMIT[from_collapse_limit] and https://www.postgresql.org/docs/15/runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT[join_collapse_limit] are similarly named because they do almost the same thing: one controls when the planner will “flatten out” subqueries, and the other controls when it will flatten out explicit joins. Typically you would either set `join_collapse_limit` equal to `from_collapse_limit` (so that explicit joins and subqueries act similarly) or set `join_collapse_limit` to 1 (if you want to control join order with explicit joins). But you might set them differently if you are trying to fine-tune the trade-off between planning time and run time. +https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-FROM-COLLAPSE-LIMIT[from_collapse_limit] and https://www.postgresql.org/docs/17/runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT[join_collapse_limit] are similarly named because they do almost the same thing: one controls when the planner will “flatten out” subqueries, and the other controls when it will flatten out explicit joins. Typically you would either set `join_collapse_limit` equal to `from_collapse_limit` (so that explicit joins and subqueries act similarly) or set `join_collapse_limit` to 1 (if you want to control join order with explicit joins). But you might set them differently if you are trying to fine-tune the trade-off between planning time and run time. === Populating a Database @@ -1338,13 +1338,13 @@ When using multiple `INSERT`s, turn off autocommit and just do one commit at the ==== Use COPY -Use https://www.postgresql.org/docs/15/sql-copy.html[`COPY`] to load all the rows in one command, instead of using a series of `INSERT` commands. The `COPY` command is optimized for loading large numbers of rows; it is less flexible than `INSERT`, but incurs significantly less overhead for large data loads. Since `COPY` is a single command, there is no need to disable autocommit if you use this method to populate a table. +Use https://www.postgresql.org/docs/17/sql-copy.html[`COPY`] to load all the rows in one command, instead of using a series of `INSERT` commands. The `COPY` command is optimized for loading large numbers of rows; it is less flexible than `INSERT`, but incurs significantly less overhead for large data loads. Since `COPY` is a single command, there is no need to disable autocommit if you use this method to populate a table. -If you cannot use `COPY`, it might help to use https://www.postgresql.org/docs/15/sql-prepare.html[`PREPARE`] to create a prepared `INSERT` statement, and then use `EXECUTE` as many times as required. This avoids some of the overhead of repeatedly parsing and planning `INSERT`. Different interfaces provide this facility in different ways; look for “prepared statements” in the interface documentation. +If you cannot use `COPY`, it might help to use https://www.postgresql.org/docs/17/sql-prepare.html[`PREPARE`] to create a prepared `INSERT` statement, and then use `EXECUTE` as many times as required. This avoids some of the overhead of repeatedly parsing and planning `INSERT`. Different interfaces provide this facility in different ways; look for “prepared statements” in the interface documentation. Note that loading a large number of rows using `COPY` is almost always faster than using `INSERT`, even if `PREPARE` is used and multiple insertions are batched into a single transaction. -`COPY` is fastest when used within the same transaction as an earlier `CREATE TABLE` or `TRUNCATE` command. In such cases no WAL needs to be written, because in case of an error, the files containing the newly loaded data will be removed anyway. However, this consideration only applies when https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-WAL-LEVEL[wal_level] is `minimal` as all commands must write WAL otherwise. +`COPY` is fastest when used within the same transaction as an earlier `CREATE TABLE` or `TRUNCATE` command. In such cases no WAL needs to be written, because in case of an error, the files containing the newly loaded data will be removed anyway. However, this consideration only applies when https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-WAL-LEVEL[wal_level] is `minimal` as all commands must write WAL otherwise. ==== Remove Indexes @@ -1362,22 +1362,22 @@ What's more, when you load data into a table with existing foreign key constrain ==== Increase maintenance_work_mem -Temporarily increasing the https://www.postgresql.org/docs/15/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM[maintenance_work_mem] configuration variable when loading large amounts of data can lead to improved performance. This will help to speed up `CREATE INDEX` commands and `ALTER TABLE ADD FOREIGN KEY` commands. It won't do much for `COPY` itself, so this advice is only useful when you are using one or both of the above techniques. +Temporarily increasing the https://www.postgresql.org/docs/17/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM[maintenance_work_mem] configuration variable when loading large amounts of data can lead to improved performance. This will help to speed up `CREATE INDEX` commands and `ALTER TABLE ADD FOREIGN KEY` commands. It won't do much for `COPY` itself, so this advice is only useful when you are using one or both of the above techniques. ==== Increase max_wal_size -Temporarily increasing the https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-MAX-WAL-SIZE[max_wal_size] configuration variable can also make large data loads faster. This is because loading a large amount of data into IvorySQL will cause checkpoints to occur more often than the normal checkpoint frequency (specified by the `checkpoint_timeout` configuration variable). Whenever a checkpoint occurs, all dirty pages must be flushed to disk. By increasing `max_wal_size` temporarily during bulk data loads, the number of checkpoints that are required can be reduced. +Temporarily increasing the https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-MAX-WAL-SIZE[max_wal_size] configuration variable can also make large data loads faster. This is because loading a large amount of data into IvorySQL will cause checkpoints to occur more often than the normal checkpoint frequency (specified by the `checkpoint_timeout` configuration variable). Whenever a checkpoint occurs, all dirty pages must be flushed to disk. By increasing `max_wal_size` temporarily during bulk data loads, the number of checkpoints that are required can be reduced. ==== Disable WAL Archival and Streaming Replication -When loading large amounts of data into an installation that uses WAL archiving or streaming replication, it might be faster to take a new base backup after the load has completed than to process a large amount of incremental WAL data. To prevent incremental WAL logging while loading, disable archiving and streaming replication, by setting https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-WAL-LEVEL[wal_level] to `minimal`, https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-ARCHIVE-MODE[archive_mode] to `off`, and https://www.postgresql.org/docs/15/runtime-config-replication.html#GUC-MAX-WAL-SENDERS[max_wal_senders] to zero. But note that changing these settings requires a server restart, and makes any base backups taken before unavailable for archive recovery and standby server, which may lead to data loss. +When loading large amounts of data into an installation that uses WAL archiving or streaming replication, it might be faster to take a new base backup after the load has completed than to process a large amount of incremental WAL data. To prevent incremental WAL logging while loading, disable archiving and streaming replication, by setting https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-WAL-LEVEL[wal_level] to `minimal`, https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-ARCHIVE-MODE[archive_mode] to `off`, and https://www.postgresql.org/docs/17/runtime-config-replication.html#GUC-MAX-WAL-SENDERS[max_wal_senders] to zero. But note that changing these settings requires a server restart, and makes any base backups taken before unavailable for archive recovery and standby server, which may lead to data loss. Aside from avoiding the time for the archiver or WAL sender to process the WAL data, doing this will actually make certain commands faster, because they do not to write WAL at all if `wal_level` is `minimal` and the current subtransaction (or top-level transaction) created or truncated the table or index they change. (They can guarantee crash safety more cheaply by doing an `fsync` at the end than by writing WAL.) ==== Run ANALYZE Afterwards -Whenever you have significantly altered the distribution of data within a table, running https://www.postgresql.org/docs/15/sql-analyze.html[`ANALYZE`] is strongly recommended. This includes bulk loading large amounts of data into the table. Running `ANALYZE` (or `VACUUM ANALYZE`) ensures that the planner has up-to-date statistics about the table. With no statistics or obsolete statistics, the planner might make poor decisions during query planning, leading to poor performance on any tables with inaccurate or nonexistent statistics. Note that if the autovacuum daemon is enabled, it might run `ANALYZE` automatically. +Whenever you have significantly altered the distribution of data within a table, running https://www.postgresql.org/docs/17/sql-analyze.html[`ANALYZE`] is strongly recommended. This includes bulk loading large amounts of data into the table. Running `ANALYZE` (or `VACUUM ANALYZE`) ensures that the planner has up-to-date statistics about the table. With no statistics or obsolete statistics, the planner might make poor decisions during query planning, leading to poor performance on any tables with inaccurate or nonexistent statistics. Note that if the autovacuum daemon is enabled, it might run `ANALYZE` automatically. ==== Some Notes about pg_dump @@ -1397,8 +1397,8 @@ By default, pg_dump uses `COPY`, and when it is generating a complete schema-and Durability is a database feature that guarantees the recording of committed transactions even if the server crashes or loses power. However, durability adds significant database overhead, so if your site does not require such a guarantee, IvorySQL can be configured to run much faster. The following are configuration changes you can make to improve performance in such cases. Except as noted below, durability is still guaranteed in case of a crash of the database software; only an abrupt operating system crash creates a risk of data loss or corruption when these settings are used. * Place the database cluster's data directory in a memory-backed file system (i.e., RAM disk). This eliminates all database disk I/O, but limits data storage to the amount of available memory (and perhaps swap). -* Turn off https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-FSYNC[fsync]; there is no need to flush data to disk. -* Turn off https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT[synchronous_commit]; there might be no need to force WAL writes to disk on every commit. This setting does risk transaction loss (though not data corruption) in case of a crash of the *database*. -* Turn off https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-FULL-PAGE-WRITES[full_page_writes]; there is no need to guard against partial page writes. -* Increase https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-MAX-WAL-SIZE[max_wal_size] and https://www.postgresql.org/docs/15/runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT[checkpoint_timeout]; this reduces the frequency of checkpoints, but increases the storage requirements of `/pg_wal`. -* Create https://www.postgresql.org/docs/15/sql-createtable.html#SQL-CREATETABLE-UNLOGGED[unlogged tables] to avoid WAL writes, though it makes the tables non-crash-safe. +* Turn off https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-FSYNC[fsync]; there is no need to flush data to disk. +* Turn off https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT[synchronous_commit]; there might be no need to force WAL writes to disk on every commit. This setting does risk transaction loss (though not data corruption) in case of a crash of the *database*. +* Turn off https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-FULL-PAGE-WRITES[full_page_writes]; there is no need to guard against partial page writes. +* Increase https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-MAX-WAL-SIZE[max_wal_size] and https://www.postgresql.org/docs/17/runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT[checkpoint_timeout]; this reduces the frequency of checkpoints, but increases the storage requirements of `/pg_wal`. +* Create https://www.postgresql.org/docs/17/sql-createtable.html#SQL-CREATETABLE-UNLOGGED[unlogged tables] to avoid WAL writes, though it makes the tables non-crash-safe. diff --git a/EN/modules/ROOT/pages/v1.17/9.adoc b/EN/modules/ROOT/pages/v1.17/9.adoc new file mode 100644 index 0000000..3de0d29 --- /dev/null +++ b/EN/modules/ROOT/pages/v1.17/9.adoc @@ -0,0 +1,118 @@ + +:sectnums: +:sectnumlevels: 5 + += PostGIS + +== Overview +IvorySQL is fully compatible with PostgreSQL, allowing for seamless integration with PostGIS. + +== Installation +Users can select the installation method for PostGIS that best suits their development environment from the https://postgis.net/documentation/getting_started/#installing-postgis[PostGIS installation page]. + +=== Source Code Installation +Apart from the installation methods provided by the PostGIS community, the IvorySQL community also offers a source code installation method, with CentOS Stream 9 (x86_64) as the environment for source code installation. + +[NOTE] +Please make sure that IvorySQL version 3.0 or newer is installed in the environment. + +** Install dependencies +``` +dnf install -y gcc gcc-c++ libtiff libtiff-devel.x86_64 libcurl-devel.x86_64 libtool libxml2-devel redhat-rpm-config clang llvm geos311 automake protobuf-c-devel +``` + +** Install SQLITE +``` +$ wget https://www.sqlite.org/2022/sqlite-autoconf-3400000.tar.gz +$ tar -xvf sqlite-autoconf-3400000.tar.gz +$ cd sqlite-autoconf-3400000 +$ sed -n '1i\#define SQLITE_ENABLE_COLUMN_METADATA 1' sqlite3.c +$ ./configure --prefix=/usr/local/sqlite +$ make && make install +$ rm usr/bin/sqlite3 && ln -s /usr/local/sqlite/bin/sqlite3 /usr/bin/sqlite3 +$ sqlite3 -version +$ export PKG_CONFIG_PATH=/usr/local/sqlite/lib/pkgconfig:$PKG_CONFIG_PATH +``` + +** Install PROJ +``` +$ wget https://download.osgeo.org/proj/proj-8.2.1.tar.gz +$ tar -xvf proj-8.2.1.tar.gz +$ cd proj-8.2.1 +$ ./configure --prefix=/usr/local/proj-8.2.1 +$ make && make install +``` + +** Install GDAL +``` +$ wget https://github.com/OSGeo/gdal/releases/download/v3.4.3/gdal-3.4.3.tar.gz +$ tar -xvf gdal-3.4.3.tar.gz +$ cd gdal-3.4.3 +$ sh autogen.sh +$ ./configure --prefix=/usr/local/gdal-3.4.3 --with-proj=/usr/local/proj-8.2.1 +$ make && make install +``` + +** Install GEOS +``` +$ wget https://download.osgeo.org/geos/geos-3.9.2.tar.bz2 +$ tar -xvf geos-3.9.2.tar.bz2 +$ cd geos-3.9.2 +$ ./configure --prefix=/usr/local/geos-3.9.2 +$ make && make install +``` + +** Install Protobuf +``` +$ wget https://plug-neomirror.rcac.purdue.edu/adelie/source/archive/protobuf-3.20.1/protobuf-3.20.1.tar.gz +$ tar -xvf protobuf-3.20.1.tar.gz +$ cd protobuf-3.20.1 +$ sh autogen.sh +$ ./configure --prefix=/usr/local/protobuf-3.20.1 +$ make && make install +$ export PROTOBUF_HOME=/usr/local/protobuf-3.20.1 +$ export PATH=$PROTOBUF_HOME/bin:$PATH +$ export PKG_CONFIG_PATH=$PROTOBUF_HOME/lib/pkgconfig:$PKG_CONFIG_PATH +``` + +** Install Protobuf-c +``` +$ wget --no-check-certificate https://sources.buildroot.net/protobuf-c/protobuf-c-1.4.1.tar.gz +$ tar -xvf protobuf-c-1.4.1.tar.gz +$ cd protobuf-c-1.4.1 +$ ./configure --prefix=/usr/local/protobuf-c-1.4.1 +$ make && make install +$ export PROTOBUFC_HOME=/usr/local/protobuf-c-1.4.1 +$ export PATH=$PROTOBUF_HOME/bin:$PROTOBUFC_HOME/bin:$PATH +$ export PKG_CONFIG_PATH=$PROTOBUFC_HOME/lib:$PKG_CONFIG_PATH +``` + +** Install PostGIS +``` +$ wget https://download.osgeo.org/postgis/source/postgis-3.4.0.tar.gz +$ tar -xvf postgis-3.4.0.tar.gz +$ cd postgis-3.4.0 +$ sh autogen.sh +$ ./configure --with-geosconfig=/usr/local/geos-3.9.2/bin/geos-config --with-projdir=/usr/local/proj-8.2.1 --with-gdalconfig=/usr/local/gdal-3.4.3/bin/gdal-config --with-protobufdir=/usr/local/protobuf-c-1.4.1 --with-pgconfig=/usr/local/ivorysql/ivorysql-4/bin/pg_config +$ make && make install +``` +[TIP] +If configure reports PGXS error, please change --with-pgconfig parameter value and confirm the parameter value based on the installation path of IvorySQL in the environment. + +== Create the extension and verify the PostGIS version. + +Connect to the database with psql and execute the following command: + +``` +ivorysql=# CREATE extension postgis; +CREATE EXTENSION + +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'postgis'; + name | default_version | installed_version | comment +---------+-----------------+-------------------+------------------------------------------------------------ + postgis | 3.4.0 | 3.4.0 | PostGIS geometry and geography spatial types and functions +(1 row) +``` + +== Using +To learn more about using PostGIS, please consult the official https://postgis.net/docs/manual-3.4[documentation for PostGIS 3.4]. \ No newline at end of file diff --git a/EN/modules/ROOT/pages/v3.0/welcome.adoc b/EN/modules/ROOT/pages/v1.17/welcome.adoc similarity index 84% rename from EN/modules/ROOT/pages/v3.0/welcome.adoc rename to EN/modules/ROOT/pages/v1.17/welcome.adoc index 03e4b98..081c83a 100644 --- a/EN/modules/ROOT/pages/v3.0/welcome.adoc +++ b/EN/modules/ROOT/pages/v1.17/welcome.adoc @@ -12,4 +12,4 @@ Go to https://www.ivorysql.org/releases-page[IvorySQL Release Page]. == About IvorySQL IvorySQL project is an open source project proposed by Highgo Software to add the Oracle compatibility features into the popular PostgreSQL database. -It is open source and free to use, any comments please contact contact@highgo.ca +It is open source and free to use, any comments please contact support@ivorysql.org diff --git a/EN/modules/ROOT/pages/v3.0/1.adoc b/EN/modules/ROOT/pages/v3.0/1.adoc deleted file mode 100644 index 4c99511..0000000 --- a/EN/modules/ROOT/pages/v3.0/1.adoc +++ /dev/null @@ -1,200 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - - -== Version Introduction - -[**Release date: November 17, 2023**] - -IvorySQL 3.0 is based on PostgreSQL 16.0 and includes various fixes from PostgreSQL 16.0, for more detailed updates and bug fixes in PostgreSQL 16.0, see the official https://www.postgresql.org/docs/release/16/[PostgreSQL 16.0 Release Notes]. - -== Updates on Version 3.0 vs 2.3 - -IvorySQL 3.0 signifies a major shift in its architectural design, diverging from the operational patterns established in version 2.3. It's crucial to recognize that certain features present in version 2.3 have not been incorporated into the new version. The following is an overview highlighting the primary distinctions in features between these two iterations: - -|==== -| Functional modules | function|IvorySQL-2.3|IvorySQL-3.0 -.14+|Built-in data types|char|not support|support -|varchar|support|support -|varchar2|support|support -|number|not support|support -|binary_float|not support|support -|binary_double|not support|support -|date|support|support -|timestamp|not support|support -|timestamp with time zone|not support|support -|timestamp with local time zone|not support|support -|interval year to month|not support|support -|interval day to second|not support|support -|raw|not support|support -|long|not support|support -.44+|Built-in functions|char|not support|support -|sysdate|support|support -|systimestamp|support|support -|add_months|support|support -|last_day|support|support -|next_day|support|support -|months_between|support|support -|current_date | not support|support -|current_timestamp | not support|support -|new_time |support|support -|tz_offset | not support|support -|trunc | support|support -|instr | not support|support -|instrb | not support|support -|substr | not support|support -|substrb |support|support -|trim | not support|support -|ltrim | not support|support -|rtrim | not support|support -|length | not support|support -|lengthb | not support|support -|rawtohex | not support|support -|replace | not support|support -|regexp_replace | not support|support -|regexp_substr | not support|support -|regexp_instr | not support|support -|regexp_like |not support|support -|to_number | support|support -|to_char | support|support -|to_date | support|support -|to_timestamp | support|support -|to_timestamp_tz | support|support -|to_yminterval |not support|support -|to_dsinterval | support|support -|numtodsinterval | support|support -|numtoyminterval | support|support -|localtimestamp | not support|support -|new_time | not support|support -|from_tz | support|support -|sys_extract_utc | support|support -|sessiontimezone |support|support -|hextoraw |not support|support -|uid | not support|support -|USERENV | not support|support -.4+|NLS parameter|NLS_LENGTH_SEMANTICS|not support|support -|NLS_DATE_FORMAT|not support|support -|NLS_TIMESTAMP_FORMAT|not support|support -|NLS_TIMESTAMP_TZ_FORMAT|not support|support -|Function|Syntax compatibility is supported, and the OUT parameter is supported|support|support -|Procedure|Syntax compatibility is supported, and the OUT parameter is supported|support|support -|Anonymous block|Syntax compatibility is supported, and the OUT parameter is supported|not support|support -|Nested subroutines|Nested stored procedures, functions, and so on are supported|not support|support -|Merge|The Merge function of PG and the Merge function compatible with Oracle syntax are supported|not support|support -|q`|Compatible escapes are supported|support|support -|Keyword processing|Supports the processing of keywords in the database|not support|support -.4+|Object case conversion|All uppercase plus double quotation marks are converted to lowercase|not support|support -|All lowercase plus double quotation marks are converted to uppercase|not support|support -|The mixed case plus double quotation marks remain the same|not support|support -|Without double quotation marks (default), all are lowercase|not support|support -|Search Path|In compatibility mode, the default search is sys mode, and then the pg_catalog mode|not support|support -|Empty strings|Oracle-compatible conversion of empty strings to NULL is supported|not support|support -|Lexical parser separation|Part of the 3.0 framework|not support|support -|package||support|not support -|Globally unique indexes||support|support -|GUC Switch to oracle or pg||support|support -|Hierarchical queries||support|not support -|NANVL ||support|not support -|GREATEST||support|not support -|LEAST||support|not support -|ADD_DAYS_TO_TIMESTAMP||support|not support -|DAYS_BETWEEN ||support|not support -|DAYS_BETWEEN_TMTZ ||support|not support -|DBTIMEZONE||support|not support -|TO_MULTI_BYTE||support|not support -|TO_SINGLE_BYTE||support|not support -|INTERVAL_TO_SECONDS||support|not support -|HEX_TO_DECIMAL||support|not support -|TO_BINARY_DOUBLE||support|not support -|TO_BINARY_FLOAT||support|not support -|BIN_TO_NUM||support|not support -|==== - -== Known Issues - -* None - -== Enhancements - -=== IvorySQL core framework - -* Add dual parser functionality to support different database parsers https://github.com/IvorySQL/IvorySQL/issues/208[Problem details] -* Added dual ports to support different database port numbers https://github.com/IvorySQL/IvorySQL/issues/200[Problem details] -* Add initdb -m to support postgres mode or oracle mode https://github.com/IvorySQL/IvorySQL/issues/212[Problem details] - -=== Compatible with SQL - -* Compatible with Oracle Merge Command https://github.com/IvorySQL/IvorySQL/issues/262[Problem details] -* Compatible with Oracle Q escaping https://github.com/IvorySQL/IvorySQL/issues/293[Problem details] -* Compatible with oracle like https://github.com/IvorySQL/IvorySQL/issues/291[Problem details] - -=== Compatible with PL/SQL - -* Addresses an issue with PL/SQL creation functions/stored procedures https://github.com/IvorySQL/IvorySQL/issues/477[Problem details] -* Compatible with Oracle anonymous blocks https://github.com/IvorySQL/IvorySQL/issues/304[Problem details] -* Creating a function or procedure in SQL parser supports nested subprocedures https://github.com/IvorySQL/IvorySQL/issues/312[Problem details] -* Nested child processes and functions IS/AS do not need to be declared https://github.com/IvorySQL/IvorySQL/issues/303[Problem details] - -=== Others -* Add meson compilation to action https://github.com/IvorySQL/IvorySQL/issues/512[Problem details] -* Support for meson compilation https://github.com/IvorySQL/IvorySQL/issues/325[Problem details] -* Add compatible test cases https://github.com/IvorySQL/IvorySQL/issues/479[Problem details] -* Add contrib regression https://github.com/IvorySQL/IvorySQL/issues/452[Problem details] -* Compatible with btree_gist indexes https://github.com/IvorySQL/IvorySQL/issues/354[Problem details] -* Compatible with btree_gin indexes https://github.com/IvorySQL/IvorySQL/issues/353[Problem details] -* Add Oracle data type GIN indexing operations https://github.com/IvorySQL/IvorySQL/issues/347[Problem details] -* Add the Oracle data type Gist Index Operation https://github.com/IvorySQL/IvorySQL/issues/341[Problem details] -* Compatible with Oracle built-in data types and built-in functions https://github.com/IvorySQL/IvorySQL/issues/239[Problem details] -* Add the plisql extension https://github.com/IvorySQL/IvorySQL/issues/211[Problem details] - -> Description: For more information about the new features, please refer to the feature list in this document center - -== Fixed issue - -* After compiling with meson, the initdb execution fails https://github.com/IvorySQL/IvorySQL/issues/520[Problem details] -* The operator result for a character type null value is incorrect https://github.com/IvorySQL/IvorySQL/issues/499[Problem details] -* An error occurred while restoring the backup https://github.com/IvorySQL/IvorySQL/issues/483[Problem details] -* ivorysql_ora some test cases fail https://github.com/IvorySQL/IvorySQL/issues/461[Problem details] -* The NLS parameter specifies that under the three relationships between the ff precision and the accuracy specified in the table, the data processing exceeding the length is inconsistent https://github.com/IvorySQL/IvorySQL/issues/436[Problem details] -* The data processing after special symbols appear in the data in DD HH.MI and SS AM in the date format is inconsistent with Oracle https://github.com/IvorySQL/IvorySQL/issues/435[Problem details] -* For the date format, there are problems with the digit verification of each part https://github.com/IvorySQL/IvorySQL/issues/434[Problem details] -* NLS related parameter verification issues https://github.com/IvorySQL/IvorySQL/issues/433[Problem details] -* Solve the problem that the NLS parameter is set to 12-hour clock, and the default rule for completing AM/PM keywords is inconsistent with Oracle https://github.com/IvorySQL/IvorySQL/issues/405[Problem details] -* The problem that the DEFAULTED field value in the xx_arguments view of a function/stored procedure created with a default value is N https://github.com/IvorySQL/IvorySQL/issues/379[Problem details] -* Functions/stored procedures without permissions can be viewed in all_procedures/all_arguments/all_source views https://github.com/IvorySQL/IvorySQL/issues/378[Problem details] -* When the self-incrementing column type is number type and the precision is specified, when a null value is inserted by default on null, it is not the inserted concrete sequence value, but the inserted null value https://github.com/IvorySQL/IvorySQL/issues/386[Problem details] - -== Source Code - -IvorySQL contains 2 main code repositories, the database IvorySQL code bin, and the IvorySQL web bin. - -* IvorySQL code bin: https://github.com/IvorySQL/IvorySQL[https://github.com/IvorySQL/IvorySQL] -* IvorySQL web bin: https://github.com/IvorySQL/Ivory-www[https://github.com/IvorySQL/Ivory-www] - -== Contributors - -The following individuals have contributed to this release as patch authors, committers, reviewers, testers, or issue reporters. - -- IvorySQL Pro development & testing team -- Yang Tan -- Jie Wang -- Shuainan Mu -- Hongyuan Zhang -- Cary Huang -- Grant Zhou -- David Zhang -- Shoubo Wang -- Jiao Ren -- Zheng Liu -- Zhekai Xiao -- Huajian Jin -- Lily Wang -- Jinzhou Song -- Leo X.M. Zeng -- Shaoan Yan -- M.Imran Zaheer -- Yunhe Xu -- Hao Wang -- Miss Dong -- Weibo Han diff --git a/EN/modules/ROOT/pages/v3.0/16.adoc b/EN/modules/ROOT/pages/v3.0/16.adoc deleted file mode 100644 index 2ba81c4..0000000 --- a/EN/modules/ROOT/pages/v3.0/16.adoc +++ /dev/null @@ -1,69 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - -= Reference identifier case conversion design - -== Objective - -- In order to meet the case compatibility of PG and Oracle's reference identifiers, ivorysql has designed three case conversion modes for reference identifiers. Select the conversion mode via the GUC parameter "identifier_case_switch"; - -== Function - -=== Three modes of case conversion (interchange by default) - -- If the value of the guc parameter "identifier_case_switch" is "interchange": - - 1). If the letters in the identifier referenced by the double quotation mark are all uppercase, uppercase is converted to lowercase. - - 2). If the letters in the identifier referenced by the double quotation mark are all lowercase, lowercase is converted to uppercase. - - 3). If the letters in the identifier enclosed in double quotation marks are mixed-case, the identifier is left unchanged. - -=== When the database cluster is initialized - -- Add the -C option to the initdb program to set the case conversion mode, and the corresponding value of -C is: - - "normal" ------ "0"synonymy - - "interchange" ------ "1"synonymy - - "lowercase" ------ "2"synonymy - -During initialization of the database cluster, the case conversion pattern is saved to the global/pg_control file in the data directory; - - -=== Test cases - -``` -SET ivorysql.enable_case_switch = true; -SET ivorysql.identifier_case_switch = interchange; -CREATE TABLE "ABC"(c1 int, c2 int); -SELECT relname FROM pg_class WHERE relname = 'ABC'; -SELECT relname FROM pg_class WHERE relname = 'abc'; -SELECT * FROM "ABC"; -SELECT * FROM ABC; -SELECT * FROM abc; -SELECT * FROM Abc; -SELECT * FROM "Abc"; -- ERROR -DROP TABLE abc; - -CREATE TABLE "Abc"(c1 int, c2 int); -SELECT relname FROM pg_class WHERE relname = 'ABC'; -SELECT relname FROM pg_class WHERE relname = 'abc'; -SELECT relname FROM pg_class WHERE relname = 'Abc'; -SELECT * FROM "ABC"; -- ERROR -SELECT * FROM ABC; -- ERROR -SELECT * FROM abc; -- ERROR -SELECT * FROM Abc; -- ERROR -SELECT * FROM "Abc"; -DROP TABLE "Abc"; - -``` - - - - - - - diff --git a/EN/modules/ROOT/pages/v3.0/6.adoc b/EN/modules/ROOT/pages/v3.0/6.adoc deleted file mode 100644 index 684fbda..0000000 --- a/EN/modules/ROOT/pages/v3.0/6.adoc +++ /dev/null @@ -1,469 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - - -# **Installation Deployment** - -## Installation overview - -This article introduces the installation process and precautions of Ivorysql on Linux platform. This article mainly demonstrates the yum source installation steps, rpm package installation steps, and source code installation steps of the database under the Centos 7 environment. - - -=== Software and hardware requirements - -==== Introduction to software resources -|==== -| operating system | Yum source download address -| CentOS 7、CentOS 8 | https://yum.highgo.ca/ivorysql.html -|==== - -==== Hardware resource preparation - -|==== -| Configuration parameters | **Minimum configuration** | **Recommended configuration** -| **CPU** | 4 cores | 16 cores -| **Memory** | 4GB | 64GB -| **Storage** | 800MB,mechanical hard disk | Above 5GB,SSD or NvMe -| **Network** | gigabit lan | 10 Gigabit network -|==== - -=== Environment and configuration check - -Before deploying the IvorySQL database, you need to check the system environment and configuration - -==== View resources - -The IvorySQL database supports CentOS 7. X, 8. X operating systems. For details, refer to <<#_software_and_hardware_requirements>>. - -==== View the operating system - -Run the following command to view the operating system information: - -``` -cat /etc/redhat-release -``` - -==== View kernel parameters - -``` -uname -r -``` - -==== View memory and clear cache - -``` -free -g - -echo 3 > /proc/sys/vm/drop_caches -``` - -=== Get installation package - -You can install the IvorySql database or RPM package through the source code. - -==== Use source code to build IvorySQL database - -1.Get the source code: Run the following command to clone the source code of the IvorySQL database to your build machine: - -``` -git clone https://github.com/IvorySQL/IvorySQL.git -``` - -> Note: To clone code, you need to install and configure Git first. For details, refer to https://git-scm.com/doc[Git doc]. - -2.Install dependent packages: To compile IvorySQL from source code, you must ensure that prerequisite packages are available on the system. Execute the following command to install related packages: - -``` -sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget -sudo yum groupinstall -y 'Development Tools' -``` - -> Note: "Development Tools" includes gcc, make, flex, bison. - -3.Self-compilation and installation: The source code obtained previously is in the folder IvorySQL. Next, we will enter this folder for operation. - -Configuration: Root users execute the following commands to configure: - -``` -./configure --prefix=/usr/local/ivorysql/ivorysql-3 -``` - -> Note: Because -- prefix is not provided, it is installed in/usr/local/pgsql by default, so you need to specify the path - -> Note: We should remember the specified directory, because the system cannot find out where the compiled and installed programs are. More configure parameters can be viewed through "./configure -- help". You can also view the PostgreSQL manual - -Compile and install: After the configuration is completed, execute make to compile: - -``` -make -``` - -Perform a regression test before installing the newly compiled service (the following commands can be used): - -``` -make check -make all-check-world -``` - -Installation: - -``` -make install -``` - -==== Install the IvorySql database using the RPM package - -1. Run the following command to download the IvorySQL installation package. - -``` -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-contrib-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-libs-3.0-1.rhel7.x86_64.rpm - -wget https://github.com/IvorySQL/IvorySQL/releases/tag/Ivorysql_3.0_Beta/ivorysql3-server-3.0-1.rhel7.x86_64.rpm -``` - -> Note: The installation package in the example may not be the latest version. It is recommended that you download the latest installation package. - -2.Run the following command to install IvorySQL. - -``` -yum install -y libicu libxslt python3 --Install dependencies first -rpm -ivh ivorysql3-libs-3.0-1.rhel7.x86_64.rpm -rpm -ivh ivorysql3-3.0-1.rhel7.x86_64.rpm -rpm -ivh ivorysql3-contrib-3.0-1.rhel7.x86_64.rpm --nodeps -rpm -ivh ivorysql3-server-3.0-1.rhel7.x86_64.rpm -``` - - - -=== Initialize database service - -==== Initialize database - -1.Create an operating system user: under the user root session, create a new user ivorysql: - -``` -/usr/sbin/groupadd ivorysql -/usr/sbin/useradd -g ivorysql ivorysql -c "IvorySQL3.0 Server" -passwd ivorysql -``` - -2.Create a data directory and modify permissions: Execute the following command in the root session: - -``` -chown -R ivorysql.ivorysql /var/lib/ivorysql/ivorysql-3 -``` - -> Note: The data directory is not placed in "/var/lib/ivorysql/ivorysql-3/data" according to RPM installation. - -3.Environment variable: switch to user ivorysql, modify the file "/home/ivorysql/. bash_profile", and configure the environment variable: - -``` -umask 022 -export LD_LIBRARY_PATH=/usr/local/ivorysql/ivorysql-3/lib:$LD_LIBRARY_PATH -export PATH=/usr/local/ivorysql/ivorysql-3/bin:$PATH -export PGDATA=/var/lib/ivorysql/ivorysql-3/data -``` - -Make the environment variable effective in the current ivorysql user session: - -``` -source .bash_profile -``` - -You can also log in again or open a new user ivorysql session. - -4.Set the firewall: If the firewall is enabled, port 5333 needs to be opened: - -``` -firewall-cmd --zone=public --add-port=5333/tcp --permanent -firewall-cmd --reload -``` - -> Note: The default port is 5333. If the port is not opened, the external client will fail to connect via IP. - -5.Initialization: Under user ivorysql, simply execute initdb to complete initialization: - -``` -initdb -``` - -> Note: The initdb operation is the same as PostgreSQL. It can be initialized according to the habits of PG. - -6.Start database: use pg_ Ctl starts the database service: - -``` -pg_ctl start -``` - -View the status and start successfully: - -``` -pg_ctl status -``` - -=== Configure service - -1.Client authentication: modify/ivorysql/1.2/data/pg_ Hba.conf, add the following: - -``` -host all all 0.0.0.0/0 trust -``` - -> Note: This is trust, which means that you can log in without password. - -Execute the following command to load the configuration: - -``` -pg_ctl reload -``` - -2.Basic parameters - -Connect to the database through psql: - -``` -psql -``` - -Modify listening address - -``` -alter system set listen_addresses = '*'; -``` - -> Note: The default is listening at 127.0.0.1. The service cannot be connected outside the host. - -3.Guard service - -Create a service file: - -``` -touch /usr/lib/systemd/system/ivorysql.service -``` - -The editing contents are as follows: - -``` -[Unit] -Description=IvorySQL 3.0 database server -Documentation=https://www.ivorysql.org -Requires=network.target local-fs.target -After=network.target local-fs.target - -[Service] -Type=forking - -User=ivorysql -Group=ivorysql - -Environment=PGDATA=/ivorysql/1.2/data/ - -OOMScoreAdjust=-1000 - -ExecStart=/usr/local/ivorysql/bin/pg_ctl start -D ${PGDATA} -ExecStop=/usr/local/ivorysql/bin/pg_ctl stop -D ${PGDATA} -ExecReload=/usr/local/ivorysql/bin/pg_ctl reload -D ${PGDATA} -A} - -TimeoutSec=0 - -[Install] -WantedBy=multi-user.target -``` - -> Note: There are many ways to write a service. Be careful when using it in a production environment. Please repeat the test several times. - -Stop pg_ The database service started by ctl enables the systemd service and starts: - -``` -systemctl enable --now ivorysql.service -``` - -IvorSQL database service operation command: - -``` -systemctl start ivorysql.service -systemctl stop ivorysql.service -systemctl restart ivorysql.service -systemctl status ivorysql.service -systemctl reload ivorysql.service -``` - -=== installation - -==== Yum source - -1.Download YUM source: use wget to download on Centos7 - -``` -wget https://yum.highgo.ca/dists/ivorysql-rpms/repo/ivorysql-release-1.0-1.noarch.rpm -``` - -Install ivorysql-release-1.0-1.noarch.rpm: - -``` -rpm -ivh ivorysql-release-1.0-1.noarch.rpm -``` - -After installation, the YUM source profile will be created:/etc/yum.repos.d/ivorysql.repo。 - -Search to view relevant installation packages: - -``` -yum search ivorysql -``` - -Table 1 for the description of search results: - -.YUM source description -|==== -| **serial number** | **Package name** | **description** -|1| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-1.2-1.rhel7.x86_64.rpm[ivorysql1.x86_64] | IvorySQL client program and library files -|2| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-contrib-1.2-1.rhel7.x86_64.rpm[ivorysql1-contrib.x86_64] | Contributed source code and binaries released with IvorySQL -|3| ivorysql1-devel.x86_64 | IvorySQL develops header files and libraries -|4| ivorysql1-docs.x86_64 | Additional documentation for IvorySQL -|5| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-libs-1.2-1.rhel7.x86_64.rpm[ivorysql1-libs.x86_64] | Shared libraries required by all IvorySQL clients -|6| ivorysql1-llvmjit.x86_64 | Just-in-time compilation support for IvorySQL -|7| ivorysql1-plperl.x86_64 | Perl, the procedural language used for IvorySQL -|8| ivorysql1-plpython3.x86_64 | Python3, the procedural language for IvorySQL -|9| ivorysql1-pltcl.x86_64 | Tcl, the procedural language used for IvorySQL -|10| https://yum.highgo.ca/dists/ivorysql-rpms/1/redhat/rhel-7-x86_64/ivorysql1-server-1.2-1.rhel7.x86_64.rpm[ivorysql1-server.x86_64] | The programs required to create and run the IvorySQL server -|11| ivorysql1-test.x86_64 | Test suite released with IvorySQL -|12| vorysql-release.noarch | The Yum source configuration RPM package of Hanco Basic Software Co., Ltd -|==== - -2.Install IvorySQL -To install the database service, you need to install ivorysql1-server. Execute the following command in the user root session: - -``` -yum install -y ivorysql1-server -``` - -**Installation list::** - -``` -ivorysql1-server.x86_64 0:1.2-1.rhel7 -``` - -**Dependencies Installation: ** - -``` -ivorysql1.x86_64 0:1.2-1.rhel7 ivorysql1-contrib.x86_64 0:1.2-1.rhel7 -ivorysql1-libs.x86_64 0:1.2-1.rhel7 libicu.x86_64 0:50.2-4.el7_7 -libtirpc.x86_64 0:0.2.4-0.16.el7 libxslt.x86_64 0:1.1.28-6.el7 -python3.x86_64 0:3.6.8-18.el7 python3-libs.x86_64 0:3.6.8-18.el7 -python3-pip.noarch 0:9.0.3-8.el7 python3-setuptools.noarch 0:39.2.0-10.el7 -``` - -3.Installed directory -Table 2 describes the file directories generated during YUM installation. - - -.Description of installation directory file -|==== -|**serial number** | **File path** | **description** -|1| /usr/local/ivorysql/ivorysql-1 | Software installation directory -|2| /var/lib/ivorysql/ivorysql-1/data | Data directory (default) -|3| /usr/bin/ivorysql-1-setup | Helps system administrators with basic database cluster management -|4| /usr/lib/systemd/system/ivorysql-1.service | Guardian services -|==== - -==== deb pckage - -Verification environment: Linux 20.04.1-Ubuntu - -1、Get deb from the official website - -explain:ivorysql.deb is not currently available - -2、Install deb package - -``` -dpkg -i ivorysql.deb -``` - -3、Configure environment variables - -``` -vi ~/.bashrc - export PATH=/xxx/ivorysql/bin:$PATH - export LD_LIBRARY_PATH=/xxx/ivorysql/lib - -source .bashrc -``` - -4、Uninstall deb package - -``` -dpkg -r ivorysql -``` - -=== Uninstall the IvorySQL database - -==== Compile Uninstall - -1.Backup data: The data directory is under "/ivorysql/1.2/data", so we can protect the directory. It is better to stop the database service and make a backup. - -``` -systemctl stop ivorysql-1.service -``` - -2.Compile and uninstall: switch the root session to the source directory and execute the following commands respectively: - -``` -make uninstall -make clean -``` - -3.Delete residual directories and files: - -``` -systemctl disable ivorysql.servicemake --disable Service -mv /usr/lib/systemd/system/ivorysql.service /tmp/ --the service file can be moved to/tmp or deleted -rm -fr /usr/local/ivorysql/ivorysql-3 --remove residual installation directory -``` - -> Note: There are also user ivorysql and corresponding environment variables, which can be cleaned according to the situation. The rest is the data directory "/var/lib/ivorysql/ivorysql-3/data". Please make sure to make a backup before processing. There are also installed dependent packages, which can be uninstalled according to the situation. - - -==== YUM Uninstall - -1.Stop database service: - -``` -systemctl stop ivorysql-1.service -``` - -First use "yum history list" to determine the transaction ID of yum installation: - -``` -[root@Node02 ~]# yum history list -Loaded plugins: fastestmirror -ID | Login user | Date and time | Action(s) | Altered -------------------------------------------------------------------------------- - 5 | root <root> | 2022-04-27 12:38 | Install | 11 < - 4 | root <root> | 2022-03-26 16:08 | Install | 35 > - 3 | root <root> | 2022-03-26 16:07 | I, U | 19 - 2 | root <root> | 2022-03-26 16:07 | I, U | 73 - 1 | System <unset> | 2022-03-26 15:59 | Install | 299 -history list -``` - -You can see that the transaction with ID 5 is to execute the installation. Execute the command to uninstall (replace XX with "5"): - -``` -yum history undo XX -``` - -2.unload: - -``` -yum remove ivorysql-server -``` - -However, this command is not completely uninstalled. Only 2 dependencies have been uninstalled, and 8 dependencies have not been uninstalled. You can decide whether to uninstall in this way based on whether to retain these dependencies. diff --git a/EN/modules/ROOT/pages/v3.0/9.adoc b/EN/modules/ROOT/pages/v3.0/9.adoc deleted file mode 100644 index b523b75..0000000 --- a/EN/modules/ROOT/pages/v3.0/9.adoc +++ /dev/null @@ -1,719 +0,0 @@ - -:sectnums: -:sectnumlevels: 5 - - -= Migration guide - -== Migration overview - -The so-called database migration is any form of data movement between this database and another database, and the databases at both ends may be PostgreSql, mySQL, oracle, Sql Server, Highgo DB, etc. The migration process is a challenging, complex process that requires a thorough understanding of how databases work and their characteristics. If the application has been deployed to the production environment and is in a normal operating state, a smooth application migration is required after database migration to maintain uninterrupted business operation and no data loss. - -After migration, databases and systems should meet the following requirements: - -- The migrated database system should fully host the data of the original database system. Avoid data loss during migration that causes incomplete data to the new database system. - -- The migrated database system should fully adapt to the functions of the original database. Avoid the inability to run or throw errors of the entire business system due to data types, syntax, and functions that are not supported after migration, and there is no alternative. - -- The migrated database should be adapted to the upstream and downstream of the entire business system to ensure the stable and reliable operation of the entire business system. - -- The comprehensive performance of the migrated database cannot be weaker than that of the original database, providing performance guarantee for the entire business system. - -== Migration tool——Ora2Pg - -Ora2Pg is a free tool for migrating Oracle databases to an IvorySQL-compatible schema. It connects to your Oracle database, automatically scans and extracts its structure or data, and then generates SQL scripts that can be loaded into an IvorySQL database. Ora2Pg can migrate from a reverse-engineered Oracle database to a large enterprise database, or simply copy some Oracle data into an IvorySQL database. It is very easy to use and does not require any Oracle database knowledge without providing the parameters required to connect to Oracle Database. - -Ora2Pg consists of a Perl script (ora2pg) and a Perl module (https://link.zhihu.com/?target=http%3A//ora2pg.pm/[Ora2Pg.pm]), the only thing that needs to be done is to modify its configuration file, ora2pg.conf, set the DSN to connect to the Oracle database, and an optional SCHEMA name. ONCE THAT'S DONE, YOU ONLY NEED TO SET THE EXPORTED TYPE: TABLE (INCLUDING CONSTRAINTS AND INDEXES), VIEW, MVIEW, TABLESPACE, SEQUENCE, INDEXES, TRIGGER, GRANT, FUNCTION, PROCEDURE, PACKAGE, PARTITION, TYPE, INSERT OR COPY, FDW, QUERY, KETTLE, AND SYNONYM. - -By default, Ora2Pg exports an SQL file, which can be executed through the IvorySQL client tool psql. When performing data migration, you can set the DSN of the target database in the configuration file to import data directly from Oracle into the IvorySQL database. - -|=== -| Object | Whether ora2pg is supported -| view | yes -| trigger | yes,In some cases, you need to modify the script manually -| sequence | yes -| function | yes -| procedure | yes,In some cases, you need to modify the script manually -| type | yes,In some cases, you need to modify the script manually -| materialized view | yes,In some cases, you need to modify the script manually -|=== - -== Migrate Oracle Database to IvorySQL - -=== Environment preparation - -|=== -| linux | Oracle Version | IvorySQL Version -| Centos 7.X | 11.2.0.3.0 | 2.1 -|=== - -=== Environment-dependent installation - -==== Install Perl - -```bash -[root@localhost /]# yum install -y perl perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker -[root@localhost /]# perl -v - - -This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi -(with 44 registered patches, see perl -V for more detail) - - -Copyright 1987-2012, Larry Wall - - -Perl may be copied only under the terms of either the Artistic License or the -GNU General Public License, which may be found in the Perl 5 source kit. - - -Complete documentation for Perl, including FAQ lists, should be found on -this system using "man perl" or "perldoc perl". If you have access to the -Internet, point your browser at http://www.perl.org/, the Perl Home Page. -``` - -==== Install the DBI module - -DBI,Database Independent Interface,is the interface of the Perl language to connect to the database - -Download address: https://link.zhihu.com/?target=https%3A//cpan.metacpan.org/authors/id/T/TI/TIMB/DBI-1.643.tar.gz[https://cpan.metacpan.org/authors/id/T/TI/TIMB/DBI-1.643.tar.gz] - -```bash -[root@localhost oracle2postgresql]# tar zxvf DBI-1.643.tar.gz -[root@localhost oracle2postgresql]# cd DBI-1.643/ -[root@localhost DBI-1.643]# perl Makefile.PL -[root@localhost DBI-1.643]# make -[root@localhost DBI-1.643]# make install -``` - -==== Install DBD-Oracle - -Download address:https://sourceforge.net/projects/ora2pg/ - -Set environment variables; Load environment variables; Because ORACLE must be defined_ HOME environment variable; This example configures environment variables under the ivorysql user - -``` -export LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib:$LD_LIBRARY_PATH -export ORACLE_HOME=/usr/lib/oracle/18.3/client64 -# tar -zxvf DBD-Oracle-1.76.tar.gz # source /home/postgres/.bashrc -# cd DBD-Oracle-1.76 -# perl Makefile.PL -# make -# make install -``` - -==== Install DBD-PG (optional) - -Download address:https://metacpan.org/release/DBD-Pg/ - -Set environment variables: - -``` -export POSTGRES_HOME=/opt/ivorysql/2.1 -# tar -zxvf DBD-Pg-3.80.tar.gz -# source /home/ivorysql/.bashrc -# cd DBD-Pg-3.8.0 -# perl Makefile.PL -# make -# make install -``` - -=== Install Ora2pg - -Download address:https://sourceforge.net/projects/ora2pg/ - -``` -[root@Test01 ~]# tar -xjf ora2pg-20.0.tar.bz2 -[root@Test01 ~]# cd ora2pg-xx/ -[root@Test01 ~]# perl Makefile.PL PREFIX=<your_install_dir> -[root@Test01 ora2pg-18.2]# make && make install -``` - -Installed in/usr/local/bin/directory by default -Check the software environment: - -``` -[root@Test01 ~]# vi check.pl -#!/usr/bin/perl -use strict; -use ExtUtils::Installed; -my $inst= ExtUtils::Installed->new(); -my @modules = $inst->modules(); -foreach(@modules) -{ - my $ver = $inst->version($_) || "???"; - printf("%-12s -- %s\n", $_, $ver); - -} -exit; -[root@test01 bin]# perl check.pl -DBD::Oracle -- 1.76 -DBD::Pg -- 3.8.0 -DBI -- 1.642 -Ora2Pg -- 20.0 -Perl -- 5.16.3 -``` - -Set environment variables - -``` -export PERL5LIB=<your_install_dir> -#export PERL5LIB=/usr/local/bin/ -``` - -=== Source side preparation - -Update oracle statistics to improve performance - -``` -BEGIN -DBMS_STATS.GATHER_SCHEMA_STATS('SH'); -DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT'); -DBMS_STATS.GATHER_SCHEMA_STATS('HR'); -DBMS_STATS.GATHER_DATABASE_STATS ; -DBMS_STATS.GATHER_DICTIONARY_STATS; -END;/ -``` - -Query the source end object pair type - -``` -SYS@PROD1>set pagesize 200 -SYS@PROD1>select distinct OBJECT_TYPE from dba_objects where OWNER in ('SH','SCOTT','HR') ; -OBJECT_TYPE -------------------- -INDEX PARTITION -TABLE PARTITION -SEQUENCE -PROCEDURE -LOB X -TRIGGER -DIMENSION X -MATERIALIZED VIEW -TABLE -INDEX -VIEW -11 rows selected. -``` -=== Ora2pg export table structure - -Configure ora2pg.conf - -By default, Ora2Pg will find the/etc/ora2pg/ora2pg.conf configuration file. If the file exists, you only need to execute:/usr/local/bin/ora2pg - -``` -cat /etc/ora2pg/ora2pg.conf.dist | grep -v ^# |grep -v ^$ >ora2pg.conf -vi ora2pg.conf -[root@test01 ora2pg]# cat ora2pg.conf -ORACLE_HOME /usr/lib/oracle/18.3/client64 -ORACLE_DSN dbi:Oracle:host=10.85.10.6 ;sid=PROD1;port=1521 -ORACLE_USER system -ORACLE_PWD oracle -SCHEMA SH -EXPORT_SCHEMA 1 -SKIP fkeys ukeys checks -TYPE TABLE,VIEW,GRANT,SEQUENCE,TABLESPACE,PROCEDURE,TRIGGER,FUNCTION,PACKAGE,PARTITION,TYPE,MVIEW,QUERY,DBLINK,SYNONYM,DIRECTORY,TEST,TEST_VIEW -NLS_LANG AMERICAN_AMERICA.UTF8 -OUTPUT sh.sql -``` - -> 1. Only one type of export can be executed at the same time, so the TYPE instruction must be unique. If you have more than one, only the last one will be found in the file. But I can export multiple types at the same time. -> 2. Please note that you can link multiple exports by providing a comma-separated list of export types to the TYPE directive, but in this case, you cannot use COPY or INSERT with other export types. -> 3. Some export types cannot or should not be directly loaded into the IvorySQL database, and still require little manual editing. This is the case for GRANT, TABLESPACE, TRIGGER, FUNCTION, PROCEDURE, TYPE, QUERY and PACKAGE export types, especially if you have PLSQL code or Oracle specific SQL. -> 4. For TABLESPACE, you must ensure that the file path exists on the system. For SYNONYM, you can ensure that the owner and schema of the object correspond to the new PostgreSQL database design. -> 5. It is recommended to export the table structure one type at a time to avoid other errors affecting each other. - -==== **Test connection** - -After setting the Oracle database DSN, you can execute ora2pg to check whether it is valid: - -``` -[root@test01 ora2pg]# ora2pg -t SHOW_VERSION -c config/ora2pg.conf - -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 - -Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -``` - -==== Migration cost assessment - -It is not easy to estimate the cost of the migration process from Oracle to PostgreSQL. In order to obtain a good evaluation of the migration cost, Ora2Pg will check all database objects, all functions and stored procedures to detect whether there are still some objects and PL/SQL code that cannot be automatically converted by Ora2Pg. -Ora2Pg has a content analysis mode, which checks the Oracle database to generate a text report about the content contained in the Oracle database and the content that cannot be exported. - -``` -[root@test01 ora2pg]# ora2pg -t SHOW_REPORT --estimate_cost -c ora2pg.conf -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 -[========================>] 11/11 tables (100.0%) end of scanning. -[========================>] 11/11 objects types (100.0%) end of objects auditing. -------------------------------------------------------------------------------- -Ora2Pg v20.0 - Database Migration Report -------------------------------------------------------------------------------- -Version Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -Schema SH -Size 287.25 MB -------------------------------------------------------------------------------- -Object Number Invalid Estimated cost Comments Details -------------------------------------------------------------------------------- -DATABASE LINK 0 0 0 Database links will be exported as SQL/MED IvorySQL's Foreign Data Wrapper (FDW) extensions using oracle_fdw. -DIMENSION 5 0 0 -GLOBAL TEMPORARY TABLE 0 0 0 Global temporary table are not supported by PostgreSQL and will not be exported. You will have to rewrite some application code to match the PostgreSQL temporary table behavior. -INDEX 20 0 3.4 14 index(es) are concerned by the export, others are automatically generated and will do so on PostgreSQL. Bitmap will be exported as btree_gin index(es) and hash index(es) will be exported as b-tree index(es) if any. Domain index are exported as b-tree but commented to be edited to mainly use FTS. Cluster, bitmap join and IOT indexes will not be exported at all. Reverse indexes are not exported too, you may use a trigram-based index (see pg_trgm) or a reverse() function based index and search. Use 'varchar_pattern_ops', 'text_pattern_ops' or 'bpchar_pattern_ops' operators in your indexes to improve search with the LIKE operator respectively into varchar, text or char columns. 11 bitmap index(es). 1 domain index(es). 2 b-tree index(es). - -INDEX PARTITION 196 0 0 Only local indexes partition are exported, they are build on the column used for the partitioning. - -JOB 0 0 0 Job are not exported. You may set external cron job with them. - -MATERIALIZED VIEW 2 0 6 All materialized view will be exported as snapshot materialized views, they are only updated when fully refreshed. - -SYNONYM 0 0 0 SYNONYMs will be exported as views. SYNONYMs do not exists with PostgreSQL but a common workaround is to use views or set the PostgreSQL search_path in your session to access object outside the current schema. - -TABLE 11 0 1.1 1 external table(s) will be exported as standard table. See EXTERNAL_TO_FDW configuration directive to export as file_fdw foreign tables or use COPY in your code if you just want to load data from external files. Total number of rows: 1063384. Top 10 of tables sorted by number of rows:. sales has 918843 rows. costs has 82112 rows. customers has 55500 rows. supplementary_demographics has 4500 rows. times has 1826 rows. promotions has 503 rows. products has 72 rows. countries has 23 rows. channels has 5 rows. sales_transactions_ext has 0 rows. Top 10 of largest tables:. - -TABLE PARTITION 56 0 5.6 Partitions are exported using table inheritance and check constraint. Hash and Key partitions are not supported by PostgreSQL and will not be exported. 56 RANGE partitions.. - -VIEW 1 0 1 Views are fully supported but can use specific functions. - -------------------------------------------------------------------------------- - -Total 291 0 17.10 17.10 cost migration units means approximatively 1 man-day(s). The migration unit was set to 5 minute(s) ------------------------------------------------------------------------------- -Migration level : A-1 -------------------------------------------------------------------------------- -Migration levels: - - A - Migration that might be run automatically - - B - Migration with code rewrite and a human-days cost up to 5 days - - C - Migration with code rewrite and a human-days cost above 5 days - -Technical levels: - - 1 = trivial: no stored functions and no triggers - - 2 = easy: no stored functions but with triggers, no manual rewriting - - 3 = simple: stored functions and/or triggers, no manual rewriting - - 4 = manual: no stored functions but with triggers or views with code rewriting - - 5 = difficult: stored functions and/or triggers with code rewriting - -------------------------------------------------------------------------------- -``` - -==== **Export SH table structure** - -``` -[root@test01 ora2pg]# ora2pg -c ora2pg.conf -WARNING: target IvorySQL version must be set in PG_VERSION configuration directive. Using default: 11 -[========================>] 11/11 tables (100.0%) end of scanning. - -[========================>] 12/12 tables (100.0%) end of table export. - -[========================>] 1/1 views (100.0%) end of output. - -[========================>] 0/0 sequences (100.0%) end of output. - -[========================>] 0/0 procedures (100.0%) end of procedures export. - -[========================>] 0/0 triggers (100.0%) end of output. - -[========================>] 0/0 functions (100.0%) end of functions export. - -[========================>] 0/0 packages (100.0%) end of output. - -[========================>] 56/56 partitions (100.0%) end of output. - -[========================>] 0/0 types (100.0%) end of output. - -[========================>] 2/2 materialized views (100.0%) end of output. -[========================>] 0/0 dblink (100.0%) end of output. - -[========================>] 0/0 synonyms (100.0%) end of output. - -[========================>] 2/2 directory (100.0%) end of output. - -Fixing function calls in output files.... -``` - -==== **Export SH user data** - -Configure the type of ora2pg.conf as COPY or INSERT - -``` -[root@test01 ora2pg]# cp ora2pg.conf sh_data.conf - -[root@test01 ora2pg]# vi sh_data.conf - -ORACLE_HOME /usr/lib/oracle/18.3/client64 - -ORACLE_DSN dbi:Oracle:host=10.85.10.6 ;sid=PROD1;port=1521 - -ORACLE_USER system - -ORACLE_PWD oracle - -SCHEMA SH - -EXPORT_SCHEMA 1 - -DISABLE_UNLOGGED 1 - -SKIP fkeys ukeys checks - -TYPE COPY - -NLS_LANG AMERICAN_AMERICA.UTF8 - -OUTPUT sh_data.sql -``` - -Export Data - -``` -[root@test01 ora2pg]# ora2pg -c sh_data.conf - -WARNING: target PostgreSQL version must be set in PG_VERSION configuration directive. Using default: 11 - -[========================>] 11/11 tables (100.0%) end of scanning. - -[========================>] 5/5 rows (100.0%) Table CHANNELS (5 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_1995 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_H1_1997 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -[> ] 0/82112 rows (0.0%) Table COSTS_1996 (0 recs/sec) - -[> ] 5/1063384 total rows (0.0%) - (0 sec., avg: 5 recs/sec). - -…………………………………………………………… - -[========================>] 4500/4500 rows (100.0%) Table SUPPLEMENTARY_DEMOGRAPHICS (4500 recs/sec) - -[=======================> ] 1061558/1063384 total rows (99.8%) - (45 sec., avg: 23590 recs/sec). - -[========================>] 1826/1826 rows (100.0%) Table TIMES (1826 recs/sec) - -[========================>] 1063384/1063384 total rows (100.0%) - (45 sec., avg: 23630 recs/sec). - -[========================>] 1063384/1063384 rows (100.0%) on total estimated data (45 sec., avg: 23630 recs/sec) - -Fixing function calls in output files... -``` - -To view the exported file: - -``` -[root@test01 ora2pg]# ls -lrt *.sql - --rw-r--r-- 1 root root 15716 Jul 2 21:21 TABLE_sh.sql - --rw-r--r-- 1 root root 858 Jul 2 21:21 VIEW_sh.sql - --rw-r--r-- 1 root root 2026 Jul 2 21:21 TABLESPACE_sh.sql - --rw-r--r-- 1 root root 345 Jul 2 21:21 SEQUENCE_sh.sql - --rw-r--r-- 1 root root 2382 Jul 2 21:21 GRANT_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 TRIGGER_sh.sql - --rw-r--r-- 1 root root 346 Jul 2 21:21 PROCEDURE_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 PACKAGE_sh.sql - --rw-r--r-- 1 root root 345 Jul 2 21:21 FUNCTION_sh.sql - --rw-r--r-- 1 root root 6771 Jul 2 21:21 PARTITION_sh.sql - --rw-r--r-- 1 root root 341 Jul 2 21:21 TYPE_sh.sql - --rw-r--r-- 1 root root 342 Jul 2 21:21 QUERY_sh.sql - --rw-r--r-- 1 root root 950 Jul 2 21:21 MVIEW_sh.sql - --rw-r--r-- 1 root root 344 Jul 2 21:21 SYNONYM_sh.sql - --rw-r--r-- 1 root root 926 Jul 2 21:21 DIRECTORY_sh.sql - --rw-r--r-- 1 root root 343 Jul 2 21:21 DBLINK_sh.sql - --rw-r--r-- 1 root root 55281235 Jul 2 17:11 sh_data.sql - - -``` - -Export HR and SCOTT user data in the same way. - -=== Create orcl library in IvorySQL environment - -Create ORCL database - -``` -[root@test01 ~]# su - ivorysql - -Last login: Tue Jul 2 20:04:30 CST 2019 on pts/3 - -[postgres@test01 ~]$ createdb orcl - -[postgres@test01 ~]$ psql - -psql (11.2) - -Type "help" for help. - - - -ivorysql=# \l - - List of databases - - Name | Owner | Encoding | Collate | Ctype | Access privileges - ------------+----------+----------+------------+------------+----------------------- - - orcl | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - pgdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | - - template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + - - | | | | | postgres=CTc/postgres - - template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + - - | | | | | postgres=CTc/postgres - -(5 rows) - -ivorysql=# -``` - -Create SH, HR, SCOTT users: - -``` -[postgres@test01 ~]$ psql orcl - -psql (11.2) - -Type "help" for help. - -orcl=# - -orcl=# create user sh with password 'sh'; - -CREATE ROLE -``` - -== Migration Portal - -=== Import table structure - -Because of the materialized view, in TABLE_ The sh.sql contains the index of the materialized view, which will fail to create. You need to first create a table, then create a materialized view, and finally create an index. -Cancel the materialized view index and create it separately later: - -``` -CREATE INDEX fw_psc_s_mv_chan_bix ON fweek_pscat_sales_mv (channel_id); - -CREATE INDEX fw_psc_s_mv_promo_bix ON fweek_pscat_sales_mv (promo_id); - -CREATE INDEX fw_psc_s_mv_subcat_bix ON fweek_pscat_sales_mv (prod_subcategory); - -CREATE INDEX fw_psc_s_mv_wd_bix ON fweek_pscat_sales_mv (week_ending_day); - -CREATE TEXT SEARCH CONFIGURATION en (COPY = pg_catalog.english); -ALTER TEXT SEARCH CONFIGURATION en ALTER MAPPING FOR hword, hword_part, word WITH unaccent, english_stem; -``` - -``` -psql orcl -f tab.sql.sql - -ALTER TABLE PARTITION sh.sales OWNER TO sh; -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -COMMENT -ALTER TABLE -ALTER TABLE -ALTER TABLE -……………………………… -``` - -=== Authorize objects - -``` -cat psql orcl -f GRANT_sh.sql -CREATE USER SH WITH PASSWORD 'change_my_secret' LOGIN; -ALTER TABLE sh.fweek_pscat_sales_mv OWNER TO sh; -GRANT ALL ON sh.fweek_pscat_sales_mv TO sh; -``` - -=== Import materialized view structure - -Materialized views require relevant query permissions, so import permissions. Please keep up with users here - -``` - [ivorysql@test01 ora2pg]$ psql orcl sh -f MVIEW_sh.sql -SELECT 0 -SELECT 0 -CREATE INDEX -CREATE INDEX -CREATE INDEX -CREATE INDEX -``` - -=== Import View - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f VIEW_sh.sql -SET -SET -SET -CREATE VIEW - -``` - -=== Import partition table - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f PARTITION_sh.sql -SET -SET -SET -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -CREATE TABLE -………………………… -``` - -=== Import data - -``` -[ivorysql@test01 ora2pg]$ psql orcl -f sh_data.sql -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 0 -SET -COPY 4500 -SET -COPY 1826 -COMMIT -``` - -== Data validation - -Source database and target side extract part of objects for comparison: - -``` -SYS@PROD1>select count(*) from sh.products; - COUNT(*) ----------- - 72 - -orcl=# select count(*) from sh.products; - count -------- - 72 -(1 row) ---------------------------------------------------------------------------- - -SYS@PROD1>select count(*) from sh.channels; - - COUNT(*) - ----------- - - 5 - -orcl=# select count(*) from sh.channels; - count -------- - - 5 - -(1 row) - --------------------------------------------------------------------------- - -SYS@PROD1>select count(*) from sh.customers ; - - COUNT(*) ----------- - - 55500 -orcl=# select count(*) from sh.customers ; - count -------- - 55500 -(1 row) -``` - -== Generate migration template - -When using, there are two options -- project_ Base and -- init_ Project indicates to ora2pg that he must create a project template, which contains the work tree, configuration files and scripts for exporting all objects from the Oracle database. Generate a generic configuration file. 1. Create script export_ Schema.sh to automatically perform all exports. 2. Create script import_ All.sh to automatically perform all imports. example: - -``` -mkdir -p /ora2pg/migration - -[root@test01 ora2pg-20.0]# ora2pg --project_base /ora2pg/migration/ --init_project test_project -Creating project test_project. -/ora2pg/migration//test_project/ - schema/ - dblinks/ - directories/ - functions/ - grants/ - mviews/ - packages/ - partitions/ - procedures/ - sequences/ - synonyms/ - tables/ - tablespaces/ - triggers/ - types/ - views/ - sources/ - functions/ - mviews/ - packages/ - partitions/ - procedures/ - triggers/ - types/ - views/ - data/ - config/ - reports/ -Generating generic configuration file -Creating script export_schema.sh to automate all exports. -Creating script import_all.sh to automate all imports. -```