// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT. //go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64) || (freebsd && arm64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (netbsd && amd64) || (openbsd && amd64) || (openbsd && arm64) package sqlite3 import ( "unsafe" "modernc.org/libc" ) // C documentation // // /* // ** This version of balance() handles the common special case where // ** a new entry is being inserted on the extreme right-end of the // ** tree, in other words, when the new entry will become the largest // ** entry in the tree. // ** // ** Instead of trying to balance the 3 right-most leaf pages, just add // ** a new page to the right-hand side and put the one new entry in // ** that page. This leaves the right side of the tree somewhat // ** unbalanced. But odds are that we will be inserting new entries // ** at the end soon afterwards so the nearly empty page will quickly // ** fill up. On average. // ** // ** pPage is the leaf page which is the right-most page in the tree. // ** pParent is its parent. pPage must have a single overflow entry // ** which is also the right-most entry on the page. // ** // ** The pSpace buffer is used to store a temporary copy of the divider // ** cell that will be inserted into pParent. Such a cell consists of a 4 // ** byte page number followed by a variable length integer. In other // ** words, at most 13 bytes. Hence the pSpace buffer must be at // ** least 13 bytes in size. // */ func _balance_quick(tls *libc.TLS, pParent uintptr, pPage uintptr, pSpace uintptr) (r int32) { bp := tls.Alloc(144) defer tls.Free(144) var pBt, pOut, pStop, v1, v3 uintptr var v2 Tu8 var _ /* b at bp+32 */ TCellArray var _ /* pCell at bp+16 */ uintptr var _ /* pNew at bp+0 */ uintptr var _ /* pgnoNew at bp+12 */ TPgno var _ /* rc at bp+8 */ int32 var _ /* szCell at bp+24 */ Tu16 _, _, _, _, _, _ = pBt, pOut, pStop, v1, v2, v3 pBt = (*TMemPage)(unsafe.Pointer(pPage)).FpBt /* Page number of pNew */ if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) == 0 { return _sqlite3CorruptError(tls, int32(81243)) } /* dbfuzz001.test */ /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell ** may be inserted. If both these operations are successful, proceed. */ **(**int32)(__ccgo_up(bp + 8)) = _allocateBtreePage(tls, pBt, bp, bp+12, uint32(0), uint8(0)) if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK { pOut = pSpace + 4 **(**uintptr)(__ccgo_up(bp + 16)) = **(**uintptr)(__ccgo_up(pPage + 40)) **(**Tu16)(__ccgo_up(bp + 24)) = (*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxCellSize})))(tls, pPage, **(**uintptr)(__ccgo_up(bp + 16))) _zeroPage(tls, **(**uintptr)(__ccgo_up(bp)), libc.Int32FromInt32(PTF_INTKEY)|libc.Int32FromInt32(PTF_LEAFDATA)|libc.Int32FromInt32(PTF_LEAF)) (**(**TCellArray)(__ccgo_up(bp + 32))).FnCell = int32(1) (**(**TCellArray)(__ccgo_up(bp + 32))).FpRef = pPage (**(**TCellArray)(__ccgo_up(bp + 32))).FapCell = bp + 16 (**(**TCellArray)(__ccgo_up(bp + 32))).FszCell = bp + 24 **(**uintptr)(__ccgo_up(bp + 32 + 32)) = (*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd **(**int32)(__ccgo_up(bp + 32 + 80)) = int32(2) **(**int32)(__ccgo_up(bp + 32 + 80 + uintptr(libc.Int32FromInt32(NB)*libc.Int32FromInt32(2)-libc.Int32FromInt32(1))*4)) = int32(0x7fffffff) **(**int32)(__ccgo_up(bp + 8)) = _rebuildPage(tls, bp+32, 0, int32(1), **(**uintptr)(__ccgo_up(bp))) if **(**int32)(__ccgo_up(bp + 8)) != 0 { _releasePage(tls, **(**uintptr)(__ccgo_up(bp))) return **(**int32)(__ccgo_up(bp + 8)) } (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnFree = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FcellOffset) - uint32(2) - uint32(**(**Tu16)(__ccgo_up(bp + 24)))) /* If this is an auto-vacuum database, update the pointer map ** with entries for the new page, and any pointer from the ** cell on the page to an overflow page. If either of these ** operations fails, the return code is set, but the contents ** of the parent page are still manipulated by the code below. ** That is Ok, at this point the parent page is guaranteed to ** be marked as dirty. Returning an error code will cause a ** rollback, undoing any changes made to the parent page. */ if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 { _ptrmapPut(tls, pBt, **(**TPgno)(__ccgo_up(bp + 12)), uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(pParent)).Fpgno, bp+8) if libc.Int32FromUint16(**(**Tu16)(__ccgo_up(bp + 24))) > libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FminLocal) { _ptrmapPutOvflPtr(tls, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 16)), bp+8) } } /* Create a divider cell to insert into pParent. The divider cell ** consists of a 4-byte page number (the page number of pPage) and ** a variable length key value (which must be the same value as the ** largest key on pPage). ** ** To find the largest key value on pPage, first find the right-most ** cell on pPage. The first two fields of this cell are the ** record-length (a variable length integer at most 32-bits in size) ** and the key value (a variable length integer, may have any value). ** The first of the while(...) loops below skips over the record-length ** field. The second while(...) loop copies the key value from the ** cell on pPage into the pSpace buffer. */ **(**uintptr)(__ccgo_up(bp + 16)) = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-int32(1))))))< _btreePagecount(tls, pBt) { return _sqlite3CorruptError(tls, int32(83452)) } **(**int32)(__ccgo_up(bp + 8)) = _getAndInitPage(tls, pBt, pgno, bp, 0) if **(**int32)(__ccgo_up(bp + 8)) != 0 { return **(**int32)(__ccgo_up(bp + 8)) } if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FopenFlags)&int32(BTREE_SINGLE) == 0 && _sqlite3PagerPageRefcount(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage) != int32(1)+libc.BoolInt32(pgno == uint32(1)) { **(**int32)(__ccgo_up(bp + 8)) = _sqlite3CorruptError(tls, int32(83459)) goto cleardatabasepage_out } hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FhdrOffset) i = 0 for { if !(i < libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnCell)) { break } pCell = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaCellIdx + uintptr(int32(2)*i))))<aiIdx[pCur->iPage] value is set to the index of the parent cell ** of the page, or to the number of cells in the page if the next page ** to visit is the right-child of its parent. ** ** If all pages in the tree have been visited, return SQLITE_OK to the ** caller. */ if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 { for cond := true; cond; cond = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell) { if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) == 0 { /* All pages of the b-tree have been visited. Return successfully. */ **(**Ti64)(__ccgo_up(pnEntry)) = nEntry return _moveToRoot(tls, pCur) } _moveToParent(tls, pCur) } (*TBtCursor)(unsafe.Pointer(pCur)).Fix = (*TBtCursor)(unsafe.Pointer(pCur)).Fix + 1 pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage } /* Descend to the child node of the cell that the cursor currently ** points at. This is the right-child if (iIdx==pPage->nCell). */ iIdx = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) if iIdx == libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) { rc = _moveToChild(tls, pCur, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(8)))) } else { rc = _moveToChild(tls, pCur, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iIdx))))<= int32(CURSOR_REQUIRESEEK) { **(**int32)(__ccgo_up(bp)) = _btreeRestoreCursorPosition(tls, pCur) if **(**int32)(__ccgo_up(bp)) != 0 || libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID { return **(**int32)(__ccgo_up(bp)) } } else { return _sqlite3CorruptError(tls, int32(83091)) } } iCellDepth = int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) iCellIdx = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) <= iCellIdx { return _sqlite3CorruptError(tls, int32(83100)) } pCell = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iCellIdx))))< libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize*libc.Uint32FromInt32(2)/libc.Uint32FromInt32(3)) || libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) == int32(1) { /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ **(**int32)(__ccgo_up(bp)) = _saveCursorKey(tls, pCur) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } } else { bPreserve = uint8(2) } } /* If the page containing the entry to delete is not a leaf page, move ** the cursor to the largest entry in the tree that is smaller than ** the entry being deleted. This cell will replace the cell being deleted ** from the internal node. The 'previous' entry is used for this instead ** of the 'next' entry, as the previous entry is always a part of the ** sub-tree headed by the child page of the cell being deleted. This makes ** balancing the tree following the delete operation easier. */ if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) { **(**int32)(__ccgo_up(bp)) = _sqlite3BtreePrevious(tls, pCur, 0) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } } /* Save the positions of any other cursors open on this table before ** making any modifications. */ if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_Multiple) != 0 { **(**int32)(__ccgo_up(bp)) = _saveAllCursors(tls, pBt, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, pCur) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } } /* If this is a delete operation to remove a row from a table b-tree, ** invalidate any incrblob cursors open on the row being deleted. */ if (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo == uintptr(0) && (*TBtree)(unsafe.Pointer(p)).FhasIncrblobCur != 0 { _invalidateIncrblobCursors(tls, p, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnKey, 0) } /* Make the page containing the entry to be deleted writable. Then free any ** overflow pages associated with the entry and finally remove the cell ** itself from within the page. */ **(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } (*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxParseCell})))(tls, pPage, pCell, bp+8) if uint32((**(**TCellInfo)(__ccgo_up(bp + 8))).FnLocal) != (**(**TCellInfo)(__ccgo_up(bp + 8))).FnPayload { **(**int32)(__ccgo_up(bp)) = _clearCellOverflow(tls, pPage, pCell, bp+8) } else { **(**int32)(__ccgo_up(bp)) = SQLITE_OK } _dropCell(tls, pPage, iCellIdx, libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 8))).FnSize), bp) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } /* If the cell deleted was not located on a leaf page, then the cursor ** is currently pointing to the largest entry in the sub-tree headed ** by the child-page of the cell that was just deleted from an internal ** node. The cell from the leaf node needs to be moved to the internal ** node to replace the deleted cell. */ if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) { pLeaf = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage if (*TMemPage)(unsafe.Pointer(pLeaf)).FnFree < 0 { **(**int32)(__ccgo_up(bp)) = _btreeComputeFreeSpace(tls, pLeaf) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } } if iCellDepth < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)-int32(1) { n = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pCur + 144 + uintptr(iCellDepth+int32(1))*8)))).Fpgno } else { n = (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).Fpgno } pCell = (*TMemPage)(unsafe.Pointer(pLeaf)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pLeaf)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FnCell)-int32(1))))))< iCellDepth { _releasePageNotNull(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage) (*TBtCursor)(unsafe.Pointer(pCur)).FiPage = (*TBtCursor)(unsafe.Pointer(pCur)).FiPage - 1 for int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) > iCellDepth { v2 = pCur + 84 v1 = *(*Ti8)(unsafe.Pointer(v2)) *(*Ti8)(unsafe.Pointer(v2)) = *(*Ti8)(unsafe.Pointer(v2)) - 1 _releasePage(tls, **(**uintptr)(__ccgo_up(pCur + 144 + uintptr(v1)*8))) } (*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 144 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*8)) **(**int32)(__ccgo_up(bp)) = _balance(tls, pCur) } if **(**int32)(__ccgo_up(bp)) == SQLITE_OK { if libc.Int32FromUint8(bPreserve) > int32(1) { (*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_SKIPNEXT) if iCellIdx >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) { (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = -int32(1) (*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) - int32(1)) } else { (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = int32(1) } } else { **(**int32)(__ccgo_up(bp)) = _moveToRoot(tls, pCur) if bPreserve != 0 { _btreeReleaseAllCursorPages(tls, pCur) (*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_REQUIRESEEK) } if **(**int32)(__ccgo_up(bp)) == int32(SQLITE_EMPTY) { **(**int32)(__ccgo_up(bp)) = SQLITE_OK } } } return **(**int32)(__ccgo_up(bp)) } // C documentation // // /* // ** zIn is a UTF-16 encoded unicode string at least nByte bytes long. // ** Return the number of bytes in the first nChar unicode characters // ** in pZ. nChar must be non-negative. Surrogate pairs count as a single // ** character. // */ func _sqlite3Utf16ByteLen(tls *libc.TLS, zIn uintptr, nByte int32, nChar int32) (r int32) { var c, n int32 var z, zEnd uintptr _, _, _, _ = c, n, z, zEnd z = zIn zEnd = z + uintptr(nByte-int32(1)) n = 0 if true { z = z + 1 } for n < nChar && z <= zEnd { c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) z = z + uintptr(2) if c >= int32(0xd8) && c < int32(0xdc) && z <= zEnd && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) >= int32(0xdc) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) < int32(0xe0) { z = z + uintptr(2) } n = n + 1 } return int32(int64(z)-int64(zIn)) - libc.BoolInt32(true) } // C documentation // // /* // ** Check to see if the frame with header in aFrame[] and content // ** in aData[] is valid. If it is a valid frame, fill *piPage and // ** *pnTruncate and return true. Return if the frame is not valid. // */ func _walDecodeFrame(tls *libc.TLS, pWal uintptr, piPage uintptr, pnTruncate uintptr, aData uintptr, aFrame uintptr) (r int32) { var aCksum uintptr var nativeCksum int32 var pgno Tu32 _, _, _ = aCksum, nativeCksum, pgno /* True for native byte-order checksums */ aCksum = pWal + 72 + 24 /* Page number of the frame */ /* A frame is only valid if the salt values in the frame-header ** match the salt values in the wal-header. */ if libc.Xmemcmp(tls, pWal+72+32, aFrame+8, uint64(8)) != 0 { return 0 } /* A frame is only valid if the page number is greater than zero. */ pgno = _sqlite3Get4byte(tls, aFrame) if pgno == uint32(0) { return 0 } /* Need a valid page size */ if !((*TWal)(unsafe.Pointer(pWal)).FszPage != 0) { return 0 } /* A frame is only valid if a checksum of the WAL header, ** all prior frames, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 ** bytes of this frame-header. */ nativeCksum = libc.BoolInt32(libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).Fhdr.FbigEndCksum) == SQLITE_BIGENDIAN) _walChecksumBytes(tls, nativeCksum, aFrame, int32(8), aCksum, aCksum) _walChecksumBytes(tls, nativeCksum, aData, libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage), aCksum, aCksum) if **(**Tu32)(__ccgo_up(aCksum)) != _sqlite3Get4byte(tls, aFrame+16) || **(**Tu32)(__ccgo_up(aCksum + 1*4)) != _sqlite3Get4byte(tls, aFrame+20) { /* Checksum failed. */ return 0 } /* If we reach this point, the frame is valid. Return the page number ** and the new database size. */ **(**Tu32)(__ccgo_up(piPage)) = pgno **(**Tu32)(__ccgo_up(pnTruncate)) = _sqlite3Get4byte(tls, aFrame+4) return int32(1) }