}
}
+/*
+** If the single column in pData->a[] with pData->n entries can be
+** laid out as nCol columns with a 2-space gap between each such
+** that all columns fit within nSW, then return a pointer to an array
+** of integers which is the width of each column from left to right.
+**
+** If the layout is not possible, return a NULL pointer.
+**
+** Space to hold the returned array is from sqlite_malloc64().
+*/
+static int *qrfValidLayout(
+ qrfColData *pData, /* Collected query results */
+ Qrf *p, /* On which to report an OOM */
+ int nCol, /* Attempt this many columns */
+ int nSW /* Screen width */
+){
+ int i; /* Loop counter */
+ int nr; /* Number of rows */
+ int w = 0; /* Width of the current column */
+ int t; /* Total width of all columns */
+ int *aw; /* Array of individual column widths */
+
+ aw = sqlite3_malloc64( sizeof(int)*nCol );
+ if( aw==0 ){
+ qrfOom(p);
+ return 0;
+ }
+ nr = (pData->n + nCol - 1)/nCol;
+ for(i=0; i<pData->n; i++){
+ if( (i%nr)==0 ){
+ if( i>0 ) aw[i/nr-1] = w;
+ w = pData->aiWth[i];
+ }else if( pData->aiWth[i]>w ){
+ w = pData->aiWth[i];
+ }
+ }
+ aw[nCol-1] = w;
+ for(t=i=0; i<nCol; i++) t += aw[i];
+ t += 2*(nCol-1);
+ if( t>nSW ){
+ sqlite3_free(aw);
+ return 0;
+ }
+ return aw;
+}
+
/*
** The output is single-column and the bWrapSnglCol flag is set.
** Check to see if the single-column output can be split into multiple
** columns that appear side-by-side. Adjust pData appropriately.
*/
static void qrfWrapSingleColumn(qrfColData *pData, Qrf *p){
+ int nCol = 1;
+ int *aw = 0;
+ char **az = 0;
+ int *aiWth = 0;
+ int nColNext = 2;
+ struct qrfPerCol *a = 0;
+ sqlite3_int64 nRow = 1;
+ sqlite3_int64 i;
+ while( 1/*exit-by-break*/ ){
+ int *awNew = qrfValidLayout(pData, p, nColNext, p->spec.nScreenWidth);
+ if( awNew==0 ) break;
+ sqlite3_free(aw);
+ aw = awNew;
+ nCol = nColNext;
+ nRow = (pData->n + nCol - 1)/nCol;
+ if( nRow==1 ) break;
+ nColNext++;
+ while( (pData->n + nColNext - 1)/nColNext == nRow ) nColNext++;
+ }
+ if( nCol==1 ){
+ sqlite3_free(aw);
+ return; /* Cannot do better than 1 column */
+ }
+ az = sqlite3_malloc64( nRow*nCol*sizeof(char*) );
+ if( az==0 ){
+ qrfOom(p);
+ return;
+ }
+ aiWth = sqlite3_malloc64( nRow*nCol*sizeof(int) );
+ if( aiWth==0 ){
+ sqlite3_free(az);
+ qrfOom(p);
+ return;
+ }
+ a = sqlite3_malloc64( nCol*sizeof(struct qrfPerCol) );
+ if( a==0 ){
+ sqlite3_free(az);
+ sqlite3_free(aiWth);
+ qrfOom(p);
+ return;
+ }
+ for(i=0; i<pData->n; i++){
+ sqlite3_int64 j = (i%nRow)*nCol + (i/nRow);
+ az[j] = pData->az[i];
+ pData->az[i] = 0;
+ aiWth[j] = pData->aiWth[i];
+ }
+ while( i<nRow*nCol ){
+ sqlite3_int64 j = (i%nRow)*nCol + (i/nRow);
+ az[j] = sqlite3_mprintf("");
+ if( az[j]==0 ) qrfOom(p);
+ aiWth[j] = 0;
+ i++;
+ }
+ for(i=0; i<nCol; i++){
+ a[i].fx = a[i].mxW = a[i].w = aw[i];
+ a[i].e = pData->a[0].e;
+ }
+ sqlite3_free(pData->az);
+ sqlite3_free(pData->aiWth);
+ sqlite3_free(pData->a);
+ sqlite3_free(aw);
+ pData->az = az;
+ pData->aiWth = aiWth;
+ pData->a = a;
+ pData->nCol = nCol;
+ pData->n = pData->nAlloc = nRow*nCol;
+ pData->nMargin = 2;
}
/*
}
if( nColumn==1
- && p->spec.bWrapSnglCol
+ && p->spec.bWrapSnglCol==QRF_Yes
&& p->spec.eStyle==QRF_STYLE_Column
&& p->spec.bTitles==QRF_No
&& p->spec.nScreenWidth>data.a[0].w+3
** verticle wrapping, if the screen is wide enough and if the
** bWrapSnglCol flag is set. */
qrfWrapSingleColumn(&data, p);
+ nColumn = data.nCol;
}else{
/* Adjust the column widths due to screen width restrictions */
qrfRestrictScreenWidth(&data, p);
nWS = data.a[j].w - nWide;
qrfPrintAligned(p->pOut, data.a[j].z, nThis, nWS, data.a[j].e);
data.a[j].z += iNext;
- if( data.a[j].z[0]!=0 ) bMore = 1;
+ if( data.a[j].z[0]!=0 ){
+ bMore = 1;
+ }
if( j<nColumn-1 ){
sqlite3_str_append(p->pOut, colSep, szColSep);
}else{
-C Add\sthe\sbWrapSnglCol\sflag\sto\sthe\sQRF\sspec,\sthough\sit\sis\snot\syet\sdocumented\nand\sdoes\snot\syet\swork.\s\sFix\scolumn\soutput\sso\sthat\sit\somits\strailing\sspace.
-D 2025-11-21T20:10:12.657
+C Implementation\sof\sbWrapSnglCol\sin\sQRF.
+D 2025-11-22T00:38:17.646
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
F ext/qrf/README.md dd565fd1ca0c46ea37dbf4d496e368b9ecade768c92669640bc106e039629016
-F ext/qrf/qrf.c 33379ad5044ba63729b204889fd6e59948ed5e80eb3037710d98f146907c4262
+F ext/qrf/qrf.c f388bd56d8f9804511fa0b3d704cca648084d05f716525f48fdaea8be761d7c7
F ext/qrf/qrf.h 116f9d7847c04f6377d40cd22dd2b1c6a1336a26201dfe6d69b1d58ec41d02e7
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
F src/sqliteLimit.h 0a5516b4ec192a205c541e05f67009028a9451dc6678aae4cf8e68596903c246
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
-F src/tclsqlite.c 381384fbe3cf342115f9ad01208fa81092e9a2156a4ea4d44de87852b8df3a8a
+F src/tclsqlite.c caceb8b872d414479a1df3715e565bc9a486cb5763dcf639ad4ff84550d19dc4
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
F src/test1.c 0e71fbcb484a271564e98e0158192c28c24f5521594218c3ba48bcb4cf634f91
F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/pushdown.test 46a626ef1c0ca79b85296ff2e078b9da20a50e9b804b38f441590c3987580ddd
-F test/qrf01.test e76be7da90e9c40010fd08336461c4fdc9825875167ee17170442c1e23631342
+F test/qrf01.test 92334aaf93e0b96dbb117c9592f2ec7385e9077e65db16a175ec352f4d754ef3
F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92
F test/qrf03.test 9de53aea459f5a127283db03cbb6011500757685646d21aa3c29c44c6ef23e86
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 04394387e626cd99ff98df978c4b7f2d32f65760e0c26e53f1ef4f59e4e91a4f
-R c2811c2ce4ec10183543473b397451a5
+P a858027fc92727c680b7e984303df7f9e0a2d90c860c547176f290b113a69390
+R a51fa5dfb24a3bcee8421313d1d3bb87
U drh
-Z 7925dda900ed8e83a9a5d4713fd7d290
+Z a16fb45a4bab603e7bb9dd853cb499d3
# Remove this line to create a well-formed Fossil manifest.
-a858027fc92727c680b7e984303df7f9e0a2d90c860c547176f290b113a69390
+4bbd3f7ead50c0babd7843f58972e2e1762a84866cc4ed88a2a74375b13da11c
** -wordwrap ("auto"|"off"|"on") Try to wrap at word boundry?
** -textjsonb ("auto"|"off"|"on") Auto-convert JSONB to text?
** -textnull ("auto"|"off"|"on") Use text encoding for -null.
+** -wrapsnglcol ("auto"|"off"|"on") Enable wrap-single-column
** -defaultalign ("auto"|"left"|...) Default alignment
** -titalalign ("auto"|"left"|"right"|...) Default column name alignment
** -wrap NUMBER Max width of any single column
** -wordwrap bWordWrap
** -textjsonb bTextJsonb
** -textnull bTestNull
+** -wrapsnglcol bWrapSnglCol
** -defaultalign eDfltAlign
** -titlealign eTitleAlign
** -wrap nWrap
if( rc ) goto format_failed;
qrf.bWordWrap = aBoolMap[v];
i++;
- }else if( strcmp(zArg,"-textjsonb")==0 || strcmp(zArg,"-textnull")==0 ){
+ }else if( strcmp(zArg,"-textjsonb")==0
+ || strcmp(zArg,"-textnull")==0
+ || strcmp(zArg,"-wrapsnglcol")==0
+ ){
int v = 0;
rc = Tcl_GetIndexFromObj(pDb->interp, objv[i+1], azBool,
zArg, 0, &v);
if( rc ) goto format_failed;
if( zArg[5]=='j' ){
qrf.bTextJsonb = aBoolMap[v];
- }else{
+ }else if( zArg[5]=='n' ){
qrf.bTextNull = aBoolMap[v];
+ }else{
+ qrf.bWrapSnglCol = aBoolMap[v];
}
i++;
}else if( strcmp(zArg,"-defaultalign")==0 || strcmp(zArg,"-titlealign")==0){
db format -style jobject {SELECT * FROM t9 WHERE rowid<0}
} {}
+do_test 10.1 {
+ db eval {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(x);
+ INSERT INTO t1(x) VALUES
+ ('alice'),
+ ('bob'),
+ ('cinderella-cinderella'),
+ ('daniel'),
+ ('emma'),
+ ('fred'),
+ ('gertrude'),
+ ('harold'),
+ ('ingrid'),
+ ('jake'),
+ ('lisa'),
+ ('mike'),
+ ('nina'),
+ ('octavian'),
+ ('paula'),
+ ('quintus'),
+ ('rita'),
+ ('sam'),
+ ('tammy'),
+ ('ulysses'),
+ ('violet'),
+ ('william'),
+ ('xanthippe'),
+ ('yates'),
+ ('zoe');
+ }
+ set result "\n[db format -style column -title off -screenwidth 41 -wrapsnglcol on \
+ {SELECT x FROM t1}]"
+} {
+alice octavian
+bob paula
+cinderella-cinderella quintus
+daniel rita
+emma sam
+fred tammy
+gertrude ulysses
+harold violet
+ingrid william
+jake xanthippe
+lisa yates
+mike zoe
+nina
+}
+do_test 10.2 {
+ set result "\n[db format -style column -title off -screenwidth 42 -wrapsnglcol on \
+ {SELECT x FROM t1}]"
+} {
+alice jake tammy
+bob lisa ulysses
+cinderella-cinderella mike violet
+daniel nina william
+emma octavian xanthippe
+fred paula yates
+gertrude quintus zoe
+harold rita
+ingrid sam
+}
+do_test 10.3 {
+ set result "\n[db format -style column -title off -screenwidth 51 -wrapsnglcol on \
+ {SELECT x FROM t1}]"
+} {
+alice harold paula william
+bob ingrid quintus xanthippe
+cinderella-cinderella jake rita yates
+daniel lisa sam zoe
+emma mike tammy
+fred nina ulysses
+gertrude octavian violet
+}
+do_test 10.4 {
+ set result "\n[db format -style column -title off -screenwidth 61 -wrapsnglcol on \
+ {SELECT x FROM t1}]"
+} {
+alice fred lisa quintus violet
+bob gertrude mike rita william
+cinderella-cinderella harold nina sam xanthippe
+daniel ingrid octavian tammy yates
+emma jake paula ulysses zoe
+}
+do_test 10.5 {
+ set result "\n[db format -style column -title off -screenwidth 74 -wrapsnglcol on \
+ {SELECT x FROM t1}]"
+} {
+alice emma ingrid nina rita violet zoe
+bob fred jake octavian sam william
+cinderella-cinderella gertrude lisa paula tammy xanthippe
+daniel harold mike quintus ulysses yates
+}
+
db close
finish_test