Re: How to properly use TRIM()? - Mailing list pgsql-general
| From | Igor Korot |
|---|---|
| Subject | Re: How to properly use TRIM()? |
| Date | |
| Msg-id | CA+FnnTzn8UkgaFzujzFcQzLP9JdJC5zJX52+kzCvWn1sAJ1VXA@mail.gmail.com Whole thread |
| In response to | Re: How to properly use TRIM()? ("David G. Johnston" <david.g.johnston@gmail.com>) |
| List | pgsql-general |
Hi, David,
On Sat, Mar 7, 2026 at 2:27 PM David G. Johnston <david.g.johnston@gmail.com> wrote:
On Sat, Mar 7, 2026 at 2:46 PM Igor Korot <ikorot01@gmail.com> wrote:Hi, Adrian,
On Sat, Mar 7, 2026 at 3:29 PM Adrian Klaver <adrian.klaver@aklaver.com> wrote:
>
> On 3/7/26 12:46 PM, Igor Korot wrote:
> > Hi, David,
> >
> > On Sat, Mar 7, 2026 at 12:03 PM David G. Johnston
> > <david.g.johnston@gmail.com <mailto:david.g.johnston@gmail.com>> wrote:
> >
> > On Sat, Mar 7, 2026 at 12:58 PM Igor Korot <ikorot01@gmail.com
> > <mailto:ikorot01@gmail.com>> wrote:
> >
> > So I started looking for a way to return SQL_NO_DATA
> > on that 4th column...
> >
> >
> > Doesn't "No Data" refer to the result set as a whole, not individual
> > columns? I'd assume NULL is detected some other way.
> >
> >
> > No, I think it’s column based.
>
> 1) My knowledge of ODBC is limited.
>
> 2) This:
>
> https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/return-codes-odbc?view=sql-server-ver17
>
> "SQL_NO_DATA No more data was available. The application calls
> SQLGetDiagRec or SQLGetDiagField to retrieve additional information. One
> or more driver-defined status records in class 02xxx may be returned.
> Note: In ODBC 2.x, this return code was named SQL_NO_DATA_FOUND."
>
> would seem to indicate that David Johnston is correct:
From the SQLGetData() ODBC documentation
(https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdata-function?view=sql-server-ver17):
[quote]
When it returns the last part of the data, SQLGetData returns
SQL_SUCCESS. Neither SQL_NO_TOTAL nor zero can be returned on the last
valid call to retrieve data from a column, because the application
would then have no way of knowing how much of the data in the
application buffer is valid. If SQLGetData is called after this, it
returns SQL_NO_DATA. For more information, see the next section,
"Retrieving Data with SQLGetData."
[/quote]
However it looks like the driver does not behave as expected.
It keeps returning SQL_SUCCESS continuously...
Or am I misinterpreting the docs?Ok, you are indeed performing an iteration of SQLGetData that does return SQL_NO_DATA when you've exhausted the contents of the field being retrieved.You still need to check ind[3] for:Step 2
I have no idea why you would end up in an infinite loop there though. I suppose maybe step 2's lack of describing the flow when the data is null means you need to break out of the loop manually
3754 while( ( ret = SQLGetData( m_hstmt, 3, SQL_C_WCHAR, included.get(), 255, &ind[2] ) ) != SQL_NO_DATA )
(gdb) n
3756 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[2]
$1 = 4
(gdb) n
3758 auto numBytes = ind[2];
(gdb)
3759 if( ind[2] == SQL_NO_TOTAL )
(gdb)
3761 else if( ind[2] > 255 )
(gdb)
3763 str_to_uc_cpy( includedCol, included.get() );
(gdb)
3764 }
(gdb)
3754 while( ( ret = SQLGetData( m_hstmt, 3, SQL_C_WCHAR, included.get(), 255, &ind[2] ) ) != SQL_NO_DATA )
(gdb)
3771 includedCol.erase( 0, 1 );
(gdb) p ind[2]
$2 = 4
(gdb) p ret
$3 = 100
(gdb) n
(gdb) n
3756 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[2]
$1 = 4
(gdb) n
3758 auto numBytes = ind[2];
(gdb)
3759 if( ind[2] == SQL_NO_TOTAL )
(gdb)
3761 else if( ind[2] > 255 )
(gdb)
3763 str_to_uc_cpy( includedCol, included.get() );
(gdb)
3764 }
(gdb)
3754 while( ( ret = SQLGetData( m_hstmt, 3, SQL_C_WCHAR, included.get(), 255, &ind[2] ) ) != SQL_NO_DATA )
(gdb)
3771 includedCol.erase( 0, 1 );
(gdb) p ind[2]
$2 = 4
(gdb) p ret
$3 = 100
(gdb) n
This is what happens with column 3 when the array is empty.
3779 while( ( ret = SQLGetData( m_hstmt, pos, SQL_C_WCHAR, index_param.get(), 255, &ind[3] ) ) != SQL_NO_DATA )
(gdb)
3781 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[3]
$4 = -1
(gdb) p ret
$5 = 0
(gdb) n
3783 auto numBytes = ind[3];
(gdb)
3784 if( ind[3] == SQL_NO_TOTAL )
(gdb)
3786 else if( ind[3] > 255 )
(gdb)
3788 str_to_uc_cpy( options, index_param.get() );
(gdb)
3789 }
(gdb)
3779 while( ( ret = SQLGetData( m_hstmt, pos, SQL_C_WCHAR, index_param.get(), 255, &ind[3] ) ) != SQL_NO_DATA )
(gdb)
3781 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[3]
$6 = -1
(gdb) p ret
$7 = 0
(gdb)
(gdb)
3781 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[3]
$4 = -1
(gdb) p ret
$5 = 0
(gdb) n
3783 auto numBytes = ind[3];
(gdb)
3784 if( ind[3] == SQL_NO_TOTAL )
(gdb)
3786 else if( ind[3] > 255 )
(gdb)
3788 str_to_uc_cpy( options, index_param.get() );
(gdb)
3789 }
(gdb)
3779 while( ( ret = SQLGetData( m_hstmt, pos, SQL_C_WCHAR, index_param.get(), 255, &ind[3] ) ) != SQL_NO_DATA )
(gdb)
3781 if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO )
(gdb) p ind[3]
$6 = -1
(gdb) p ret
$7 = 0
(gdb)
And this one is for column 4 of the query.
As you can see both calls return SQL_SUCCESS, but the
indicator does contain SQL_NULL_DATA (-1).
I think this is the bug in the driver, as it should return SQL_NO_DATA.
I'll confirm with the ODBC list.
Thx.
after dealing with the null value in some manner.David J.
pgsql-general by date: