You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by "FlyingZC (via GitHub)" <gi...@apache.org> on 2023/08/02 09:59:53 UTC

[GitHub] [shardingsphere] FlyingZC opened a new issue, #27791: Support parsing openGauss /********************************************************************** * sql

FlyingZC opened a new issue, #27791:
URL: https://github.com/apache/shardingsphere/issues/27791

   # Background
   Hi community,
   
   ShardingSphere parser engine helps users parse a SQL to get the AST (Abstract Syntax Tree) and visit this tree to get SQLStatement (Java Object). Currently, we are planning to enhance the support for openGauss SQL parsing in ShardingSphere.
   
   More details:
   https://shardingsphere.apache.org/document/current/en/reference/sharding/parse/
   
   # Task
   This issue is to support more openGauss sql parse, as follows:
   ```sql
   /**********************************************************************
   * 请在数据源中打开UseBatchProtocol,同时指定数据库中参数support_batch_bind
   * 为on
   * CHECK_ERROR的作用是检查并打印错误信息。
   * 此示例将与用户交互式获取DSN、模拟的数据量,忽略的数据量,并将最终数据入库到test_odbc_batch_insert中
   ***********************************************************************/
   #include <stdio.h>
   #include <stdlib.h>
   #include <sql.h>
   #include <sqlext.h>
   #include <string.h>
   
   void Exec(SQLHDBC hdbc, SQLCHAR* sql)
   {
       SQLRETURN retcode;                  // Return status
       SQLHSTMT hstmt = SQL_NULL_HSTMT;    // Statement handle
       SQLCHAR     loginfo[2048];
   
       // Allocate Statement Handle
       retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLAllocHandle(SQL_HANDLE_STMT) failed");
           return;
       }
   
       // Prepare Statement
       retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS);
       sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS) failed");
           return;
       }
   
       // Execute Statement
       retcode = SQLExecute(hstmt);
       sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLExecute(hstmt) failed");
           return;
       }
       // Free Handle
       retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
       sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLFreeHandle(SQL_HANDLE_STMT, hstmt) failed");
           return;
       }
   }
   
   int main () 
   {
       SQLHENV  henv  = SQL_NULL_HENV;
       SQLHDBC  hdbc  = SQL_NULL_HDBC; 
       long int      batchCount = 1000; // 批量绑定的数据量
       SQLLEN   rowsCount = 0;
       int      ignoreCount = 0; // 批量绑定的数据中,不要入库的数据量
   
       SQLRETURN   retcode;
       SQLCHAR     dsn[1024] = {'\0'};
       SQLCHAR     loginfo[2048];
   
       do 
       {
           if (ignoreCount > batchCount)
           {
               printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount);
           }
       }while(ignoreCount > batchCount);
   
       retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLAllocHandle failed");
           goto exit;
       }
   
       // Set ODBC Verion
       retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
                                           (SQLPOINTER*)SQL_OV_ODBC3, 0);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLSetEnvAttr failed");
           goto exit;
       }
   
       // Allocate Connection
       retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLAllocHandle failed");
           goto exit;
       }
   
   
       // Set Login Timeout
       retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLSetConnectAttr failed");
           goto exit;
       }
   
   
       // Set Auto Commit
       retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
                                           (SQLPOINTER)(1), 0);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLSetConnectAttr failed");
           goto exit;
       }
   
   
       // Connect to DSN
       // gaussdb替换成用户所使用的数据源名称
       sprintf(loginfo, "SQLConnect(DSN:%s)", dsn);
       retcode = SQLConnect(hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
                                  (SQLCHAR*) NULL, 0, NULL, 0);
       
       if (!SQL_SUCCEEDED(retcode)) {
           printf("SQLConnect failed");
           goto exit;
       }
   
       // init table info.
       Exec(hdbc, "drop table if exists test_odbc_batch_insert");
       Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))");
   
       // 下面的代码根据用户输入的数据量,构造出将要入库的数据:
       {
           SQLRETURN retcode; 
           SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT;
           int          i;
           SQLCHAR      *sql = NULL;
           SQLINTEGER   *ids  = NULL;
           SQLCHAR      *cols = NULL;
           SQLLEN       *bufLenIds = NULL;
           SQLLEN       *bufLenCols = NULL;
           SQLUSMALLINT *operptr = NULL;
           SQLUSMALLINT *statusptr = NULL;
           SQLULEN      process = 0;
   
           // 这里是按列构造,每个字段的内存连续存放在一起。
           ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount);
           cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50);
           // 这里是每个字段中,每一行数据的内存长度。
           bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount);
           bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount);
           // 该行是否需要被处理,SQL_PARAM_IGNORE 或 SQL_PARAM_PROCEED
           operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount);
           memset(operptr, 0, sizeof(operptr[0]) * batchCount);
           // 该行的处理结果。
           // 注:由于数据库中处理方式是同一语句隶属同一事务中,所以如果出错,那么待处理数据都将是出错的,并不会部分入库。
           statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount);
           memset(statusptr, 88, sizeof(statusptr[0]) * batchCount);
   
           if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds)
           {
               fprintf(stderr, "FAILED:\tmalloc data memory failed\n");
               goto exit;
           }
   
           for (int i = 0; i < batchCount; i++)
           {
               ids[i] = i;
               sprintf(cols + 50 * i, "column test value %d", i);
               bufLenIds[i] = sizeof(ids[i]);
               bufLenCols[i] = strlen(cols + 50 * i);
               operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED;
           }
   
           // Allocate Statement Handle
           retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLAllocHandle failed");
               goto exit;
           }
   
           // Prepare Statement
           sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)";
           retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS);
           sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLPrepare failed");
               goto exit;
           }
   
           retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount));
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLSetStmtAttr failed");
               goto exit;
           }
   
           retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLBindParameter failed");
               goto exit;
           }
   
           retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLBindParameter failed");
               goto exit;
           }
   
           retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process));
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLSetStmtAttr failed");
               goto exit;
           }
   
           retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLSetStmtAttr failed");
               goto exit;
           }
   
           retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLSetStmtAttr failed");
               goto exit;
           }
   
           retcode = SQLExecute(hstmtinesrt);
           sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLExecute(hstmtinesrt) failed");
               goto exit;
   
           retcode = SQLRowCount(hstmtinesrt, &rowsCount);
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLRowCount failed");
               goto exit;
           }
   
           if (rowsCount != (batchCount - ignoreCount))
           {
               sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
               
               if (!SQL_SUCCEEDED(retcode)) {
                   printf("SQLExecute failed");
                   goto exit;
               }
           }
           else
           {
               sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
               
               if (!SQL_SUCCEEDED(retcode)) {
                   printf("SQLExecute failed");
                   goto exit;
               }
           }
   
           // check row number returned
           if (rowsCount != process)
           {
               sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount);
               
               if (!SQL_SUCCEEDED(retcode)) {
                   printf("SQLExecute failed");
                   goto exit;
               }
           }
           else
           {
               sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount);
               
               if (!SQL_SUCCEEDED(retcode)) {
                   printf("SQLExecute failed");
                   goto exit;
               }
           }
   
           for (int i = 0; i < batchCount; i++)
           {
               if (i < ignoreCount)
               {
                   if (statusptr[i] != SQL_PARAM_UNUSED)
                   {
                       sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]);
                       
                       if (!SQL_SUCCEEDED(retcode)) {
                           printf("SQLExecute failed");
                           goto exit;
                       }
                   }
               }
               else if (statusptr[i] != SQL_PARAM_SUCCESS)
               {
                   sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]);
                   
                   if (!SQL_SUCCEEDED(retcode)) {
                       printf("SQLExecute failed");
                       goto exit;
                   }
               }
           }
   
           retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt);
           sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt");
           
           if (!SQL_SUCCEEDED(retcode)) {
               printf("SQLFreeHandle failed");
               goto exit;
           }
       }
   
   
   exit:
       (void) printf ("\nComplete.\n");
   
       // Connection
       if (hdbc != SQL_NULL_HDBC) {
           SQLDisconnect(hdbc);
           SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
       }
   
       // Environment
       if (henv != SQL_NULL_HENV)
           SQLFreeHandle(SQL_HANDLE_ENV, henv);
   
       return 0;
   ```
   
   ```sql
    CREATE TABLESPACE example1 RELATIVE LOCATION 'tablespace1/tablespace_1';
   
   ```
   
   ```sql
    CREATE TABLESPACE example2 RELATIVE LOCATION 'tablespace2/tablespace_2';
   
   ```
   
   ```sql
    CREATE TABLESPACE example3 RELATIVE LOCATION 'tablespace3/tablespace_3';
   
   ```
   
   ```sql
    CREATE TABLESPACE example4 RELATIVE LOCATION 'tablespace4/tablespace_4';
   
   
   ```
   
   # Process
   1. First confirm that this is a correct openGauss sql syntax, if not please leave a message under the issue and ignore it;
   2. Compare SQL definitions in Official SQL Doc and ShardingSphere SQL Doc;
   3. If there is any difference in ShardingSphere SQL Doc, please correct them by referring to the Official SQL Doc;
   4. Run mvn install the current_file_module;
   5. Check whether there are any exceptions. If indeed, please fix them. (Especially xxxVisitor.class);
   6. Add new corresponding SQL case in SQL Cases and expected parsed result in Expected Statement XML;
   7. Run SQLParserParameterizedTest to make sure no exceptions.
   
   # Relevant Skills
   1. Master JAVA language
   2. Have a basic understanding of Antlr `g4` file
   3. Be familiar with openGauss SQLs


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Support parsing openGauss CREATE TABLESPACE sql [shardingsphere]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on issue #27791:
URL: https://github.com/apache/shardingsphere/issues/27791#issuecomment-1783911573

   There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [shardingsphere] github-actions[bot] commented on issue #27791: Support parsing openGauss CREATE TABLESPACE sql

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on issue #27791:
URL: https://github.com/apache/shardingsphere/issues/27791#issuecomment-1703267302

   There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Support parsing openGauss CREATE TABLESPACE sql [shardingsphere]

Posted by "FlyingZC (via GitHub)" <gi...@apache.org>.
FlyingZC closed issue #27791: Support parsing openGauss  CREATE TABLESPACE sql
URL: https://github.com/apache/shardingsphere/issues/27791


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org