-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JTable Not handling default values correctly in MSSQL 2008+ #11056
Conversation
Default values are not being assigned correctly for data types such as Integer, Date and Datetime. So as a result it is causing the insert query to fail. I have tested this on SQL SERVER 2008-2016. The root cause of this issue lies with the getTableColumns in the SQL server driver class, which relies on using the information_schema views to get the information about the columns. However the default values it gets for the table columns are from the underlying system comments table and as a result it is not in a format that can be injected as is into a INSERT Query. Below is a partial list of how the syscomments table stores default values for the following data types: Datatype Actual default Value Value in syscomments table Int 0 ((0)) Int 10 ((1)) DataTime ‘1900-01-01 00:00:00’ (‘1900-01-01 00:00:00’) DataTime ‘1900-01-01T00:00:00.000’ (‘1900-01-01T00:00:00.000’) DataTime getdate() (getdate()) Date ‘1900-01-01’ (‘1900-01-01’) Varchar ‘’ (’’) Varchar ‘1234’ (‘1234’) Nvarchar N‘’ (N’’) Nvarchar N‘1234’ (N‘1234’) Nvarchar NULL (NULL) You see the general idea that the default value stored in the syscomments table is wrapped around in curly brackets, whether that be single or double depends on the data type. Now the current implementation of the getTableColumns function only deals with nvarchar data types by assuming every default string value will be an empty string so defaults to that value. This works but IMHO is a bit too simplistic in that it does not allow for default string values that is not an empty string value. Also it does not deal with other data types such as datetime, date etc... So as a result the INSERT query will blow up when you try for example to pass the value ‘((0))’ for an integer data type. My change just parses the value by removing the superfluous brackets and returns the actual value for the data type in the correct format. So for example the value ‘((0))’ will be returned as ‘0’ and (N‘1’) will be returned as ‘1’.
Hi Does #11396 resolve this issue? This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/11056. |
Unfortunately no, this is because the fault lies with the getTableColums method of the JDatabaseDriverSqlsrv that tries to get the column details for a given database table. The issue here is it uses this query below to get the default values for the table rows say for example '#__user_notes'--which to be honest you don't really have another way of getting that information. SELECT column_name as Field, data_type as Type, is_nullable as 'Null', column_default as 'Default' [Note 'nqu7n' is the prefix used for my database please change this with the one you are using] If you run this query in any version of MS SQL Server and look at what it is given you for the default values, you will see straight away that this is going to cause issues. Please see my description above which goes in more depth. The SQL Issue arises (Cannot convert value as Int or Cannot convert blah as datetime2 etc..) when you are using JTable to create a new row in a database table, and you don't explicitly supply the default values for every column that has a default value. If you apply my patch, it will filter the default values and return them in a correct format. |
Sorry I don't have mssql to test and to be honest with you it looks like
there are very few <100 users of joomla on mssql
|
Thank you for your reply. I do understand that this is difficult to test if you don’t have MSSQL but the Joomla team clearly have put a lot of effort in making Joomla work on non-MySQL servers, and it would be a shame to see that work go to waste with such a simple fix. On our side, we have thoroughly tested it as we have been working on a live project I also believe that there is a duty of care issue as Joomla states it is MSSQL compliant. We would be more than happy to fix these issues; we just need someone to test our patches so we will be able to fix issues |
Unfortunately the people who did the work to support mssql disappeared as
soon as they committed the code.
Right now my understanding is that the PLT are re-evaluating if Joomla
should continue to support mssql as we don't have the resources to test and
maintain it and the number of users is so small.
Maybe @wilsonge or @rdeutz caan comment
|
We would be more than happy to support more database types. As far as I know then besides PostgreSQL all others are broken. I don't think it is realistic and we don't have the people and knowledge to support more. I would merge it when it has 2 successful tests as we usually do |
I agree with @rdeutz here. I don't have any MSSQL server available, hopefully others have and can check. Although community support for MSSQL is nearly non-existent as we found out. |
Tried to submit a positive test with issues.joomla.org, but that failed.
|
I have tested this item ✅ successfully on 0fba84c This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/11056. |
@waader and @lmcculley Hi gents I am trying to get a fix in for those of us that have MSSQL and I am wondering if you could test this PR so that we can get this fix in |
@Bakual would you be so kind to test the fix? |
I have tested this item ✅ successfully on 0fba84c This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/11056. |
Thanks for testing this, RTC This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/11056. |
@joomla-cms-bot please 😄 |
@zero-24 I am changing ! my name |
hehe 😄 Thanks. |
…1056) * JTable Not handling default values correctly in MSSQL 2008+ Default values are not being assigned correctly for data types such as Integer, Date and Datetime. So as a result it is causing the insert query to fail. I have tested this on SQL SERVER 2008-2016. The root cause of this issue lies with the getTableColumns in the SQL server driver class, which relies on using the information_schema views to get the information about the columns. However the default values it gets for the table columns are from the underlying system comments table and as a result it is not in a format that can be injected as is into a INSERT Query. Below is a partial list of how the syscomments table stores default values for the following data types: Datatype Actual default Value Value in syscomments table Int 0 ((0)) Int 10 ((1)) DataTime ‘1900-01-01 00:00:00’ (‘1900-01-01 00:00:00’) DataTime ‘1900-01-01T00:00:00.000’ (‘1900-01-01T00:00:00.000’) DataTime getdate() (getdate()) Date ‘1900-01-01’ (‘1900-01-01’) Varchar ‘’ (’’) Varchar ‘1234’ (‘1234’) Nvarchar N‘’ (N’’) Nvarchar N‘1234’ (N‘1234’) Nvarchar NULL (NULL) You see the general idea that the default value stored in the syscomments table is wrapped around in curly brackets, whether that be single or double depends on the data type. Now the current implementation of the getTableColumns function only deals with nvarchar data types by assuming every default string value will be an empty string so defaults to that value. This works but IMHO is a bit too simplistic in that it does not allow for default string values that is not an empty string value. Also it does not deal with other data types such as datetime, date etc... So as a result the INSERT query will blow up when you try for example to pass the value ‘((0))’ for an integer data type. My change just parses the value by removing the superfluous brackets and returns the actual value for the data type in the correct format. So for example the value ‘((0))’ will be returned as ‘0’ and (N‘1’) will be returned as ‘1’. * Forgot to add rule for protecting default function computed values
Pull Request for Issue # .
Summary of Changes
Testing Instructions
Default values are not being assigned correctly for data types such as
Integer, Date and Datetime. So as a result it is causing the insert
query to fail. I have tested this on SQL SERVER 2008-2016.
The root cause of this issue lies with the getTableColumns in the SQL
server driver class, which relies on using the information_schema views
to get the information about the columns. The default values it
gets for the table columns are from the underlying system comments table
and as a result it is not in a format that can be injected as is into a
INSERT Query.
Below is a partial list of how the syscomments table stores default
values for the following data types:
Datatype : int
Actual default Value : 0
Value in syscomments table: ((0))
Datatype : int
Actual default Value : 10
Value in syscomments table: ((10))
Datatype : Datetime
Actual default Value : ‘1900-01-01T00:00:00.000’
Value in syscomments table: (‘1900-01-01T00:00:00.000’)
Datatype : Datetime
Actual default Value : getdate()
Value in syscomments table: (getdate())
Datatype : Date
Actual default Value : ‘1900-01-01’
Value in syscomments table: (‘1900-01-01’)
Datatype : Varchar
Actual default Value : ''
Value in syscomments table: ('')
Datatype : Varchar
Actual default Value : '1234'
Value in syscomments table: ('1234')
Datatype : NVarchar
Actual default Value : N''
Value in syscomments table: (N'')
Datatype : NVarchar
Actual default Value : N'1234'
Value in syscomments table: (N'1234')
Datatype : Varchar
Actual default Value : NULL
Value in syscomments table: (NULL)
You see the general pattern that the default value stored in the
syscomments table is wrapped around in curly brackets, whether that be
single or double depends on the data type.
Now the current implementation of the getTableColumns function only
deals with nvarchar data types by assuming every default string value
will be an empty string so defaults to that value ignoring the actual database value. This works but IMHO it is a bit too simplistic in that it does not allow for default string
values that is not an empty string value. Also it does not deal with
other data types such as datetime, date etc... So as a result the INSERT
query will still blow up when you try for example to pass the value ‘((0))’
for an integer data type.
My change just parses the value by removing the superfluous brackets and
returns the actual value for the data type in the correct format.
So for example the value ‘((0))’ will be returned as 0, (N‘1’) will
be returned as ‘1’ and value (getdate()) will be returned as getdate() and so on ....