Enforce mxRowHeight in columnar layouts. Code clean-up. Minimum column with

is 2 if there is wrapping, in case there are double-wide characters.

FossilOrigin-Name: 0ee8fc00af4c82da0d597c65dd3d8590c71ea78d8f4a29653bbb21668c6c530d
This commit is contained in:
drh
2025-11-09 17:25:23 +00:00
parent c1aac60386
commit 7f28c6d64e
4 changed files with 375 additions and 240 deletions

View File

@@ -52,6 +52,8 @@ struct Qrf {
int iErr; /* Error code */
int nCol; /* Number of output columns */
int expMode; /* Original sqlite3_stmt_isexplain() plus 1 */
int mxWidth; /* Screen width */
int mxHeight; /* mxRowHeight */
union {
struct { /* Content for QRF_STYLE_Line */
int mxColWth; /* Maximum display width of any column */
@@ -1243,6 +1245,36 @@ static void qrfLoadAlignment(qrfColData *pData, Qrf *p){
}
}
/*
** Output horizontally justified text into pOut. The text is the
** first nVal bytes of zVal. Include nWS bytes of whitespace, either
** split between both sides, or on the left, or on the right, depending
** on eAlign.
*/
static void qrfPrintAligned(
sqlite3_str *pOut, /* Append text here */
const char *zVal, /* Text to append */
int nVal, /* Use only the first nVal bytes of zVal[] */
int nWS, /* Whitespace for horizonal alignment */
unsigned char eAlign /* Alignment type */
){
eAlign &= QRF_ALIGN_HMASK;
if( eAlign==QRF_ALIGN_Center ){
/* Center the text */
sqlite3_str_appendchar(pOut, nWS/2, ' ');
sqlite3_str_append(pOut, zVal, nVal);
sqlite3_str_appendchar(pOut, nWS - nWS/2, ' ');
}else if( eAlign==QRF_ALIGN_Right){
/* Right justify the text */
sqlite3_str_appendchar(pOut, nWS, ' ');
sqlite3_str_append(pOut, zVal, nVal);
}else{
/* Left justify the next */
sqlite3_str_append(pOut, zVal, nVal);
sqlite3_str_appendchar(pOut, nWS, ' ');
}
}
/*
** Columnar modes require that the entire query be evaluated first, with
** results written into memory, so that we can compute appropriate column
@@ -1357,10 +1389,15 @@ static void qrfColumnar(Qrf *p){
}
}
}
}else if( data.bMultiRow==0 ){
}else if( data.bMultiRow==0 || w==1 ){
for(j=i; j<data.n; j+=nColumn){
if( data.aiWth[j] > w ){
data.bMultiRow = 1;
if( w==1 ){
/* If aiWth[j] is 2 or more, then there might be a double-wide
** character somewhere. So make the column width at least 2. */
w = 2;
}
break;
}
}
@@ -1403,6 +1440,7 @@ static void qrfColumnar(Qrf *p){
bWW = (p->spec.bWordWrap==QRF_Yes && data.bMultiRow);
for(i=0; i<data.n; i+=nColumn){
int bMore;
int nRow = 0;
/* Draw a single row of the table. This might be the title line
** (if there is a title line) or a row in the body of the table.
@@ -1419,20 +1457,7 @@ static void qrfColumnar(Qrf *p){
int nWS;
qrfWrapLine(data.azThis[j], data.aiCol[j], bWW, &nThis, &nWide, &iNext);
nWS = data.aiCol[j] - nWide;
if( (data.aAlign[j] & QRF_ALIGN_HMASK)==QRF_ALIGN_Center ){
/* Center the text */
sqlite3_str_appendchar(p->pOut, nWS/2, ' ');
sqlite3_str_append(p->pOut, data.azThis[j], nThis);
sqlite3_str_appendchar(p->pOut, nWS - nWS/2, ' ');
}else if( (data.aAlign[j] & QRF_ALIGN_HMASK)==QRF_ALIGN_Right){
/* Right justify the text */
sqlite3_str_appendchar(p->pOut, nWS, ' ');
sqlite3_str_append(p->pOut, data.azThis[j], nThis);
}else{
/* Left justify the next */
sqlite3_str_append(p->pOut, data.azThis[j], nThis);
sqlite3_str_appendchar(p->pOut, nWS, ' ');
}
qrfPrintAligned(p->pOut, data.azThis[j], nThis, nWS, data.aAlign[j]);
data.azThis[j] += iNext;
if( data.azThis[j][0]!=0 ) bMore = 1;
if( j<nColumn-1 ){
@@ -1441,7 +1466,25 @@ static void qrfColumnar(Qrf *p){
sqlite3_str_append(p->pOut, rowSep, szRowSep);
}
}
}while( bMore );
}while( bMore && ++nRow < p->mxHeight );
if( bMore ){
/* This row was terminated by mxRowHeight. Show ellipsis. */
sqlite3_str_append(p->pOut, rowStart, szRowStart);
for(j=0; j<nColumn; j++){
if( data.azThis[j][0]==0 ){
sqlite3_str_appendchar(p->pOut, data.aiCol[j], ' ');
}else{
int nE = 3;
if( nE>data.aiCol[j] ) nE = data.aiCol[j];
qrfPrintAligned(p->pOut, "...", nE, data.aiCol[j]-nE, data.aAlign[j]);
}
if( j<nColumn-1 ){
sqlite3_str_append(p->pOut, colSep, szColSep);
}else{
sqlite3_str_append(p->pOut, rowSep, szRowSep);
}
}
}
/* Draw either (1) the separator between the title line and the body
** of the table, or (2) separators between individual rows of the table
@@ -1711,6 +1754,208 @@ static void qrfScanStatusVm(Qrf *p){
p->pStmt = pOrigStmt;
}
/*
** Attempt to determine if identifier zName needs to be quoted, either
** because it contains non-alphanumeric characters, or because it is an
** SQLite keyword. Be conservative in this estimate: When in doubt assume
** that quoting is required.
**
** Return 1 if quoting is required. Return 0 if no quoting is required.
*/
static int qrf_need_quote(const char *zName){
int i;
const unsigned char *z = (const unsigned char*)zName;
if( z==0 ) return 1;
if( !isalpha(z[0]) && z[0]!='_' ) return 1;
for(i=0; z[i]; i++){
if( !isalnum(z[i]) && z[i]!='_' ) return 1;
}
return sqlite3_keyword_check(zName, i)!=0;
}
/*
** Helper function for QRF_STYLE_Json and QRF_STYLE_JsonLine.
** The initial "{" for a JSON object that will contain row content
** has been output. Now output all the content.
*/
static void qrfOneJsonRow(Qrf *p){
int i, nItem;
for(nItem=i=0; i<p->nCol; i++){
const char *zCName;
if( sqlite3_column_type(p->pStmt,i)==SQLITE_NULL ) continue;
zCName = sqlite3_column_name(p->pStmt, i);
if( nItem>0 ) sqlite3_str_append(p->pOut, ",", 1);
nItem++;
qrfEncodeText(p, p->pOut, zCName);
sqlite3_str_append(p->pOut, ":", 1);
qrfRenderValue(p, p->pOut, i);
}
qrfWrite(p);
}
/*
** Render a single row of output for non-columnar styles - any
** style that lets us render row by row as the content is received
** from the query.
*/
static void qrfOneSimpleRow(Qrf *p){
int i;
switch( p->spec.eStyle ){
case QRF_STYLE_Off:
case QRF_STYLE_Count: {
/* No-op */
break;
}
case QRF_STYLE_Json: {
if( p->nRow==0 ){
sqlite3_str_append(p->pOut, "[{", 2);
}else{
sqlite3_str_append(p->pOut, "},\n{", 4);
}
qrfOneJsonRow(p);
break;
}
case QRF_STYLE_JsonLine: {
if( p->nRow==0 ){
sqlite3_str_append(p->pOut, "{", 1);
}else{
sqlite3_str_append(p->pOut, "}\n{", 3);
}
qrfOneJsonRow(p);
break;
}
case QRF_STYLE_Html: {
if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){
sqlite3_str_append(p->pOut, "<TR>", 4);
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
sqlite3_str_append(p->pOut, "\n<TH>", 5);
qrfEncodeText(p, p->pOut, zCName);
}
sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
}
sqlite3_str_append(p->pOut, "<TR>", 4);
for(i=0; i<p->nCol; i++){
sqlite3_str_append(p->pOut, "\n<TD>", 5);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
qrfWrite(p);
break;
}
case QRF_STYLE_Insert: {
if( qrf_need_quote(p->spec.zTableName) ){
sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
}else{
sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
}
if( p->spec.bColumnNames==QRF_Yes ){
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
if( qrf_need_quote(zCName) ){
sqlite3_str_appendf(p->pOut, "%c\"%w\"",
i==0 ? '(' : ',', zCName);
}else{
sqlite3_str_appendf(p->pOut, "%c%s",
i==0 ? '(' : ',', zCName);
}
}
sqlite3_str_append(p->pOut, ")", 1);
}
sqlite3_str_append(p->pOut," VALUES(", 8);
for(i=0; i<p->nCol; i++){
if( i>0 ) sqlite3_str_append(p->pOut, ",", 1);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_append(p->pOut, ");\n", 3);
qrfWrite(p);
break;
}
case QRF_STYLE_Line: {
sqlite3_str *pVal;
int mxW;
int bWW;
if( p->u.sLine.azCol==0 ){
p->u.sLine.azCol = sqlite3_malloc64( p->nCol*sizeof(char*) );
if( p->u.sLine.azCol==0 ){
qrfOom(p);
break;
}
p->u.sLine.mxColWth = 0;
for(i=0; i<p->nCol; i++){
int sz;
p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i);
if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown";
sz = qrfDisplayLength(p->u.sLine.azCol[i]);
if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz;
}
}
if( p->nRow ) sqlite3_str_append(p->pOut, "\n", 1);
pVal = sqlite3_str_new(p->db);
mxW = p->mxWidth - (3 + p->u.sLine.mxColWth);
bWW = p->spec.bWordWrap==QRF_Yes;
for(i=0; i<p->nCol; i++){
const char *zVal;
int cnt = 0;
qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth, p->u.sLine.azCol[i]);
sqlite3_str_append(p->pOut, " = ", 3);
qrfRenderValue(p, pVal, i);
zVal = sqlite3_str_value(pVal);
if( zVal==0 ) zVal = "";
do{
int nThis, nWide, iNext;
qrfWrapLine(zVal, mxW, bWW, &nThis, &nWide, &iNext);
if( cnt ) sqlite3_str_appendchar(p->pOut,p->u.sLine.mxColWth+3,' ');
cnt++;
if( cnt>p->mxHeight ){
zVal = "...";
nThis = iNext = 3;
}
sqlite3_str_append(p->pOut, zVal, nThis);
sqlite3_str_append(p->pOut, "\n", 1);
zVal += iNext;
}while( zVal[0] );
sqlite3_str_reset(pVal);
}
sqlite3_free(sqlite3_str_finish(pVal));
qrfWrite(p);
break;
}
case QRF_STYLE_Eqp: {
const char *zEqpLine = (const char*)sqlite3_column_text(p->pStmt,3);
int iEqpId = sqlite3_column_int(p->pStmt, 0);
int iParentId = sqlite3_column_int(p->pStmt, 1);
if( zEqpLine==0 ) zEqpLine = "";
if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
break;
}
default: { /* QRF_STYLE_List */
if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){
int saved_eText = p->spec.eText;
p->spec.eText = p->spec.eTitle;
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
qrfEncodeText(p, p->pOut, zCName);
}
sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
qrfWrite(p);
p->spec.eText = saved_eText;
}
for(i=0; i<p->nCol; i++){
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
qrfWrite(p);
break;
}
}
p->nRow++;
}
/*
** Initialize the internal Qrf object.
*/
@@ -1742,6 +1987,10 @@ static void qrfInitialize(
sz = sizeof(sqlite3_qrf_spec);
memcpy(&p->spec, pSpec, sz);
if( p->spec.zNull==0 ) p->spec.zNull = "";
p->mxWidth = p->spec.nScreenWidth;
if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH;
p->mxHeight = p->spec.mxRowHeight;
if( p->mxHeight<=0 ) p->mxHeight = 2147483647;
qrf_reinit:
switch( p->spec.eStyle ){
case QRF_Auto: {
@@ -1862,207 +2111,6 @@ qrf_reinit:
if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
}
/*
** Attempt to determine if identifier zName needs to be quoted, either
** because it contains non-alphanumeric characters, or because it is an
** SQLite keyword. Be conservative in this estimate: When in doubt assume
** that quoting is required.
**
** Return 1 if quoting is required. Return 0 if no quoting is required.
*/
static int qrf_need_quote(const char *zName){
int i;
const unsigned char *z = (const unsigned char*)zName;
if( z==0 ) return 1;
if( !isalpha(z[0]) && z[0]!='_' ) return 1;
for(i=0; z[i]; i++){
if( !isalnum(z[i]) && z[i]!='_' ) return 1;
}
return sqlite3_keyword_check(zName, i)!=0;
}
/*
** Helper function for QRF_STYLE_Json and QRF_STYLE_JsonLine.
** The initial "{" for a JSON object that will contain row content
** has been output. Now output all the content.
*/
static void qrfOneJsonRow(Qrf *p){
int i, nItem;
for(nItem=i=0; i<p->nCol; i++){
const char *zCName;
if( sqlite3_column_type(p->pStmt,i)==SQLITE_NULL ) continue;
zCName = sqlite3_column_name(p->pStmt, i);
if( nItem>0 ) sqlite3_str_append(p->pOut, ",", 1);
nItem++;
qrfEncodeText(p, p->pOut, zCName);
sqlite3_str_append(p->pOut, ":", 1);
qrfRenderValue(p, p->pOut, i);
}
qrfWrite(p);
}
/*
** Render a single row of output.
*/
static void qrfOneSimpleRow(Qrf *p){
int i;
switch( p->spec.eStyle ){
case QRF_STYLE_Off:
case QRF_STYLE_Count: {
/* No-op */
break;
}
case QRF_STYLE_Json: {
if( p->nRow==0 ){
sqlite3_str_append(p->pOut, "[{", 2);
}else{
sqlite3_str_append(p->pOut, "},\n{", 4);
}
qrfOneJsonRow(p);
break;
}
case QRF_STYLE_JsonLine: {
if( p->nRow==0 ){
sqlite3_str_append(p->pOut, "{", 1);
}else{
sqlite3_str_append(p->pOut, "}\n{", 3);
}
qrfOneJsonRow(p);
break;
}
case QRF_STYLE_Html: {
if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){
sqlite3_str_append(p->pOut, "<TR>", 4);
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
sqlite3_str_append(p->pOut, "\n<TH>", 5);
qrfEncodeText(p, p->pOut, zCName);
}
sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
}
sqlite3_str_append(p->pOut, "<TR>", 4);
for(i=0; i<p->nCol; i++){
sqlite3_str_append(p->pOut, "\n<TD>", 5);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_append(p->pOut, "\n</TR>\n", 7);
qrfWrite(p);
break;
}
case QRF_STYLE_Insert: {
if( qrf_need_quote(p->spec.zTableName) ){
sqlite3_str_appendf(p->pOut,"INSERT INTO \"%w\"",p->spec.zTableName);
}else{
sqlite3_str_appendf(p->pOut,"INSERT INTO %s",p->spec.zTableName);
}
if( p->spec.bColumnNames==QRF_Yes ){
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
if( qrf_need_quote(zCName) ){
sqlite3_str_appendf(p->pOut, "%c\"%w\"",
i==0 ? '(' : ',', zCName);
}else{
sqlite3_str_appendf(p->pOut, "%c%s",
i==0 ? '(' : ',', zCName);
}
}
sqlite3_str_append(p->pOut, ")", 1);
}
sqlite3_str_append(p->pOut," VALUES(", 8);
for(i=0; i<p->nCol; i++){
if( i>0 ) sqlite3_str_append(p->pOut, ",", 1);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_append(p->pOut, ");\n", 3);
qrfWrite(p);
break;
}
case QRF_STYLE_Line: {
sqlite3_str *pVal;
int mxW;
int bWW;
if( p->u.sLine.azCol==0 ){
p->u.sLine.azCol = sqlite3_malloc64( p->nCol*sizeof(char*) );
if( p->u.sLine.azCol==0 ){
qrfOom(p);
break;
}
p->u.sLine.mxColWth = 0;
for(i=0; i<p->nCol; i++){
int sz;
p->u.sLine.azCol[i] = sqlite3_column_name(p->pStmt, i);
if( p->u.sLine.azCol[i]==0 ) p->u.sLine.azCol[i] = "unknown";
sz = qrfDisplayLength(p->u.sLine.azCol[i]);
if( sz > p->u.sLine.mxColWth ) p->u.sLine.mxColWth = sz;
}
}
if( p->nRow ) sqlite3_str_append(p->pOut, "\n", 1);
pVal = sqlite3_str_new(p->db);
mxW = p->spec.nScreenWidth ? p->spec.nScreenWidth : QRF_MAX_WIDTH;
mxW -= 3 + p->u.sLine.mxColWth;
bWW = p->spec.bWordWrap==QRF_Yes;
for(i=0; i<p->nCol; i++){
const char *zVal;
int cnt = 0;
qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth, p->u.sLine.azCol[i]);
sqlite3_str_append(p->pOut, " = ", 3);
qrfRenderValue(p, pVal, i);
zVal = sqlite3_str_value(pVal);
if( zVal==0 ) zVal = "";
do{
int nThis, nWide, iNext;
qrfWrapLine(zVal, mxW, bWW, &nThis, &nWide, &iNext);
if( cnt ) sqlite3_str_appendchar(p->pOut,p->u.sLine.mxColWth+3,' ');
cnt++;
if( p->spec.mxRowHeight>0 && cnt>p->spec.mxRowHeight ){
zVal = "...";
nThis = iNext = 3;
}
sqlite3_str_append(p->pOut, zVal, nThis);
sqlite3_str_append(p->pOut, "\n", 1);
zVal += iNext;
}while( zVal[0] );
sqlite3_str_reset(pVal);
}
sqlite3_free(sqlite3_str_finish(pVal));
qrfWrite(p);
break;
}
case QRF_STYLE_Eqp: {
const char *zEqpLine = (const char*)sqlite3_column_text(p->pStmt,3);
int iEqpId = sqlite3_column_int(p->pStmt, 0);
int iParentId = sqlite3_column_int(p->pStmt, 1);
if( zEqpLine==0 ) zEqpLine = "";
if( zEqpLine[0]=='-' ) qrfEqpRender(p, 0);
qrfEqpAppend(p, iEqpId, iParentId, zEqpLine);
break;
}
default: { /* QRF_STYLE_List */
if( p->nRow==0 && p->spec.bColumnNames==QRF_Yes ){
int saved_eText = p->spec.eText;
p->spec.eText = p->spec.eTitle;
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
qrfEncodeText(p, p->pOut, zCName);
}
sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
qrfWrite(p);
p->spec.eText = saved_eText;
}
for(i=0; i<p->nCol; i++){
if( i>0 ) sqlite3_str_appendall(p->pOut, p->spec.zColumnSep);
qrfRenderValue(p, p->pOut, i);
}
sqlite3_str_appendall(p->pOut, p->spec.zRowSep);
qrfWrite(p);
break;
}
}
p->nRow++;
}
/*
** Finish rendering the results
*/

View File

@@ -1,5 +1,5 @@
C Fixes\sfor\sharmless\sstatic\sanalyzer\swarnings.
D 2025-11-09T00:37:29.108
C Enforce\smxRowHeight\sin\scolumnar\slayouts.\s\sCode\sclean-up.\s\sMinimum\scolumn\swith\nis\s2\sif\sthere\sis\swrapping,\sin\scase\sthere\sare\sdouble-wide\scharacters.
D 2025-11-09T17:25:23.259
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -417,7 +417,7 @@ F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6
F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
F ext/qrf/README.md 5011393a53bfb26b59488e5d8d8576de521058876b61318d4fe476375a4ae9a2
F ext/qrf/qrf.c d7e7bcc6d70478002daecbd32a352f76a1de8fef2b032a73ff698bc2e0c37ffe
F ext/qrf/qrf.c 7d3c500a73e8185a3ae097b0c47a3609ef96e0f9bc6b8b7d2f0db8c2e5330fd9
F ext/qrf/qrf.h 49a106a7484c9761bb66bebe0043fbf43302624734a9f9734e0fa410a908e525
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
@@ -1506,7 +1506,7 @@ F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224c
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/pushdown.test 46a626ef1c0ca79b85296ff2e078b9da20a50e9b804b38f441590c3987580ddd
F test/qrf01.test 8553f38836e3ea3320dd0ff908ee166e48ec6c1d7fc9ee81fd10c865fdc7e393
F test/qrf01.test f229fcfe7c9907a1c0471ab2b0beed2fac01a69407d45248b490425716849603
F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
@@ -2173,8 +2173,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 9de3e1d3fb0b2127e983aa455cda2f38646891da65eb9ac39bb5b00d8488f52f
R 82e4d367a67dea25cb5537608e6abc45
P 37bd136ae842c8f8110c10b0834c804a8af133ce0caff492f37bd567a56ac6c6
R b230166f53990d22a4280416c83ac02d
U drh
Z d5ab0a376a02936b9e254f6a39cd4a97
Z 545297433252d44682281bbfa2a0dfdd
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
37bd136ae842c8f8110c10b0834c804a8af133ce0caff492f37bd567a56ac6c6
0ee8fc00af4c82da0d597c65dd3d8590c71ea78d8f4a29653bbb21668c6c530d

View File

@@ -550,7 +550,7 @@ do_execsql_test 5.0 {
INSERT INTO t1 VALUES
('entry-one',1708791504,zeroblob(300)),
(unistr('one\u000atwo\u000athree'),1333206973,NULL),
('sample-jsonb',1333206973,jsonb('{
('sample-jsonb',1333101221,jsonb('{
"alpha":53.11688723,
"beta":"qrfWidthPrint(p, p->pOut, -p->u.sLine.mxColWth);",
"zeta":[15,null,1333206973,"fd8ffe000104a46494600010101"]}'));
@@ -561,20 +561,20 @@ do_test 5.1 {
set result "\n[db format -style line -screenwidth 60 -blob sql \
-text sql -wordwrap off -maxrowheight 77 $sql]"
} {
name = unistr('one\u000atwo\u000athree')
mtime = 1333206973
time = '2012-03-31 15:16:13'
value =
name = 'sample-jsonb'
mtime = 1333206973
time = '2012-03-31 15:16:13'
mtime = 1333101221
time = '2012-03-30 09:53:41'
value = x'cc7c57616c706861b535332e31313638383732334762657461
c73071726657696474685072696e7428702c20702d3e704f7574
2c202d702d3e752e734c696e652e6d78436f6c577468293b477a
657461cb2c23313500a331333333323036393733c71b66643866
6665303030313034613436343934363030303130313031'
name = unistr('one\u000atwo\u000athree')
mtime = 1333206973
time = '2012-03-31 15:16:13'
value =
name = 'entry-one'
mtime = 1708791504
time = '2024-02-24 16:18:24'
@@ -598,6 +598,13 @@ do_test 5.2 {
-text plain -esc off -textjsonb yes \
-wordwrap yes -maxrowheight 3 $sql]"
} {
name = sample-jsonb
mtime = 1333101221
time = 2012-03-30 09:53:41
value = {"alpha":53.11688723,"beta":"qrfWidthPrint(p,
p->pOut, -p->u.sLine.mxColWth);","zeta":[15,null,
1333206973,"fd8ffe000104a46494600010101"]}
name = one
two
three
@@ -605,13 +612,6 @@ mtime = 1333206973
time = 2012-03-31 15:16:13
value =
name = sample-jsonb
mtime = 1333206973
time = 2012-03-31 15:16:13
value = {"alpha":53.11688723,"beta":"qrfWidthPrint(p,
p->pOut, -p->u.sLine.mxColWth);","zeta":[15,null,
1333206973,"fd8ffe000104a46494600010101"]}
name = entry-one
mtime = 1708791504
time = 2024-02-24 16:18:24
@@ -620,5 +620,92 @@ value = x'00000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000
...
}
do_test 5.3a {
set result "\n[db format -style box -widths {0 10 10 14}\
-align {left right right center} \
-blob sql \
-text plain -esc off -textjsonb no \
-wordwrap yes -maxrowheight 2 $sql]"
} {
┌──────────────┬────────────┬────────────┬────────────────┐
│ name │ mtime │ time │ value │
├──────────────┼────────────┼────────────┼────────────────┤
│ sample-jsonb │ 1333101221 │ 2012-03-30 │ x'cc7c57616c70 │
│ │ │ 09:53:41 │ 6861b535332e31 │
│ │ │ │ ... │
├──────────────┼────────────┼────────────┼────────────────┤
│ one │ 1333206973 │ 2012-03-31 │ │
│ two │ │ 15:16:13 │ │
│ ... │ │ │ │
├──────────────┼────────────┼────────────┼────────────────┤
│ entry-one │ 1708791504 │ 2024-02-24 │ x'000000000000 │
│ │ │ 16:18:24 │ 00000000000000 │
│ │ │ │ ... │
└──────────────┴────────────┴────────────┴────────────────┘
}
do_test 5.3b {
set result "\n[db format -style table -widths {0 10 10 14}\
-align {center right right right} \
-blob sql \
-text plain -esc off -textjsonb no \
-wordwrap yes -maxrowheight 2 $sql]"
} {
+--------------+------------+------------+----------------+
| name | mtime | time | value |
+--------------+------------+------------+----------------+
| sample-jsonb | 1333101221 | 2012-03-30 | x'cc7c57616c70 |
| | | 09:53:41 | 6861b535332e31 |
| | | | ... |
+--------------+------------+------------+----------------+
| one | 1333206973 | 2012-03-31 | |
| two | | 15:16:13 | |
| ... | | | |
+--------------+------------+------------+----------------+
| entry-one | 1708791504 | 2024-02-24 | x'000000000000 |
| | | 16:18:24 | 00000000000000 |
| | | | ... |
+--------------+------------+------------+----------------+
}
do_test 5.3c {
set result "\n[db format -style column -widths {0 10 10 14}\
-align {center right right right} \
-blob sql \
-text plain -esc off -textjsonb no \
-wordwrap yes -maxrowheight 2 $sql]"
} {
name mtime time value
------------ ---------- ---------- --------------
sample-jsonb 1333101221 2012-03-30 x'cc7c57616c70
09:53:41 6861b535332e31
...
one 1333206973 2012-03-31
two 15:16:13
...
entry-one 1708791504 2024-02-24 x'000000000000
16:18:24 00000000000000
...
}
do_test 5.4 {
db eval {
CREATE TABLE t2(a,b,c,d,e);
WITH v(x) AS (SELECT 'abcdefghijklmnopqrstuvwxyz')
INSERT INTO t2 SELECT x,x,x,x,x FROM v;
}
set sql {SELECT char(0x61,0xa,0x62,0xa,0x63,0xa,0x64) a,
mtime b, mtime c, mtime d, mtime e FROM t1}
set result "\n[db format -style box -widths {1 2 3 4 5}\
-maxrowheight 3 -wordwrap off {SELECT *, 'x' AS x FROM t2}]"
} {
┌────┬────┬─────┬──────┬───────┬───┐
│ a │ b │ c │ d │ e │ x │
├────┼────┼─────┼──────┼───────┼───┤
│ ab │ ab │ abc │ abcd │ abcde │ x │
│ cd │ cd │ def │ efgh │ fghij │ │
│ ef │ ef │ ghi │ ijkl │ klmno │ │
│ .. │ .. │ ... │ ... │ ... │ │
└────┴────┴─────┴──────┴───────┴───┘
}
finish_test