[MDEV-11954] CONNECT Engine - ODBC: Too long value for SRCDEF Created: 2017-01-31 Updated: 2017-02-02 Resolved: 2017-01-31 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | OTHER |
| Affects Version/s: | 10.1.19 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Minor |
| Reporter: | Juan Telleria | Assignee: | Olivier Bertrand |
| Resolution: | Not a Bug | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Windows 7 |
||
| Issue Links: |
|
||||||||||||
| Description |
|
If I create the following table:
I obtain error when creating the table "Too long value for SRCDEF". Could this limitation be removed by creating (For example) a Server Variable that controls this parameter. Thank you. Kind regards, |
| Comments |
| Comment by Olivier Bertrand [ 2017-01-31 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I have created the table on my machine with no problem but not replacing .... Note that the limitation on string options is not due to CONNECT but is a MariaDB limitation. During the parsing of a query (here the CREATE TABLE statement) there are many places in sql_yacc.cc that raise this message with code such as:
Looking at the declaration of ENGINE_OPTION_MAX_LENGTH I see in create_options.h:
What is strange is that in your create table statement is that the SRCDEF is not as large except if ... of the IN statement contains many more values. I don't know whether it is possible to change this MariaDB limitation. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Of course, the IN clause could contain even more than 100.000 elements. I included only a little extract in the example. My objective is about time efficiency when dealing with Tables which contain big amount of data in the Remote Server. So I have mainly 3 options:
So maybe one possible improvement for CONNECT ODBC Query Efficiency could be the following: This would save the time required to transfer all the Views Data from the Remote Server to the local server for being able to do further filtering in it* The previous example would be now as follows:
So in the example the optimizer would:
*So in summary, my suggestion is that in a table which has a CONNECT Engine (With an SRCDEF Clause), when performing a simple SELECT over it, CONNECT:
With the main advantage that complex joins could be included in the View for being performed and remote server, and further filtering over such new materialized table (Created from joins), is also performed in the remote server. Even more, the results data subset could be saved in our local server into a Temporary Table for working with them, adding indexes into such table and doing further complex joins with our servers data.* | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
However, if CONNECT ODBC is left just as it is now implemented (Without changes), I will still be really satisfied, as it has an awesome implementation and works perfectly. Simply I exposed my time performance concerns to try to give it a twist and make it even better as regards time consumption efficiency. Thank you | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
A third possibility could be to use a "sending command" table. With it you can send any query that will be executed by the remote server. I don't think there is a length limitation to the length of a string included in a query. The problem is to get back the result of the query ("sending command" tables only tell you that the command was executed successfully or not. So the sent query should be something such as:
Just remains to create locally a table based on this foo remote result table and to read it. I did not try it yet but can do it if you are interested and publish an example of how to do it. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Of course, If you want I could take some time at the weekend for doing and example. I also tried yesterday to use an ODBC CONNECT Table for "Sending Queries", but I left it aside for not being able to have the result set back (As my REMOTE Server is Read Only). However, a pretty good and ingenious idea just occurred to me: How about creating a special type of CONNECT ODBC table which can send Foreing Server Queries in the WHERE Clause of the SELECT, but at the same time can return Results Back. This new implementation would be really simple, and would not require to modify any other code (With subsequent bugs that could carry on). A conceptual example would be as follows: Connect Engine Table Create Statement
SELECT Statement to CONNECT Engine Table
Observations:
I would be pleased to do the documentation if required. Kind regards, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I don't understand some of your example. In the observations you say: Anyway, the main problem seems the EXECSRC_Command hidden column. If it is not included in the columns of the table, it will raise a syntax error in the MariaDB parsing process. However, it may perhaps be included as a CONNECT special column. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I just realized that a "sending command" table ¿Might not be feasible? As when we do the following statement:
The SQL Command to be executed in the remote server I suppose (Maybe not) that is subject to the length of the "EXECSRC_Command" column, which has a maximum length for VARCHAR of 65535 characters (Not unlimited). However, a more detailed example would be as follows: Imagine I create the following CONNECT ODBC table:
The SELECT would be:
In the SELECT:
But in case I create a CONNECT Table without Column Definition:
The SELECT would be:
So the CONNECT ODBC Table would return to the local server a table which contains the following columns:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thank you | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2017-02-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I appreciate your suggestion, unfortunately it is not feasible. One reason is that ordinary ODBC (or JDBC or MYSQL) tables and the corresponding "send command" tables are quite distinct objects. They are implemented in C++ by different classes having few things in common. For instance, "send command" tables are written to retrieve just one record made of specific items while ordinary tables are written to fetch in a result set, and bound their columns to the result set values. Mixing both of them in a common class would be a kluge. However, retrieving a result set from an ordinary "send command" table proved to be fairly simple. For example I made and tested this (using MYSQL table type instead of ODBC but that would be almost identical):
This replies:
Now to get the result, simply create the table to read the remote made table:
And you get:
Now if you send another query:
You can still get the result repeating:
To obtain:
Of course the getres table must be re-created to get the new columns, which have not to be specified. They are automatically retrieved from the remote res table. I think all this can also be automized in a procedure. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thank you Oliver, I totally agree that it is not feasible, apart for being far away from Standard SQL. I appreciate your example about how to send & retrieve commands via a "Send Command Table" based on CREATE TABLE Table_Name AS SELECT [...], I'll give it a try by Speaking with my Remote Database Administrator. Last suggestion which might be interesting: What about an implementation similar to that of TRANSACT-SQL's OPENQUERY(): In MariaDB could be::
And:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Olivier Bertrand [ 2017-02-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MariaDB does not accept tables with no columns. When some CONNECT tables seem to be created with no columns, this is because the discovery process is called allowing to retrieve columns definitions from another table or pre defined specifications. In your example the create table would fail saying:
because the target table name is by default the table name. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Juan Telleria [ 2017-02-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Never mind, thank you Oliver I'll give a try to your suggestion |