diff --git a/.github/workflows/Android.yml b/.github/workflows/Android.yml index d513cfce8c48..5f21563101dd 100644 --- a/.github/workflows/Android.yml +++ b/.github/workflows/Android.yml @@ -45,7 +45,7 @@ jobs: android: name: Android runs-on: ubuntu-latest - container: ubuntu:18.04 + container: ubuntu:20.04 if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/feature' }} strategy: diff --git a/data/csv/tpcc_results.csv b/data/csv/tpcc_results.csv new file mode 100644 index 000000000000..780d276599ee --- /dev/null +++ b/data/csv/tpcc_results.csv @@ -0,0 +1,393 @@ +dbsystem,tps,submission_date +SunjeSoft Goldilocks v3.1 Standard Edition,50768.0,2024-02-26 +IBM DB2 11.5.8 Advanced Edition,279185.0,2023-10-02 +SunjeSoft Goldilocks v3.1 Standard Edition,507802.0,2022-09-07 +SunjeSoft Goldilocks v3.1 Standard Edition,190443.0,2022-06-30 +SunjeSoft Goldilocks v3.1 Standard Edition,101550.0,2021-12-20 +SunjeSoft Goldilocks v3.1 Standard Edition,144714.0,2021-09-29 +Tencent TDSQL v10.3 Enterprise Pro Edition with Partitioning and Physical Replication,814854791.0,2023-03-24 +Microsoft SQL Server 2000 Enterprise Edition SP3,66543.0,2006-01-12 +"OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression",707351007.0,2020-05-19 +"OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression",60880800.0,2019-10-01 +IBM DB2 9.5,6085166.0,2008-06-15 +IBM DB2 9.5 Enterprise Edition,629159.0,2008-06-11 +IBM DB2 9.1,1616162.0,2007-12-17 +Oracle Database 10g Enterprise Edition,404462.0,2007-12-17 +Microsoft SQL Server 2000 Enterprise Edition 64bit,175366.24,2004-06-30 +Oracle Database 9i R2 Enterprise Edition,403255.46,2002-06-03 +Oracle Database 9i Enterprise Edition v.9i.0.1,105025.02,2001-09-26 +Oracle Database 9i Enterprise Edition v.9i.0.1,57346.93,2001-07-03 +Oracle 8i Enterprise Edition v. 8.1.7,66750.27,2001-05-28 +Oracle 8i Enterprise Edition v. 8.1.7,220807.27,2001-05-28 +Oracle Database 11g Standard Edition One,1609186.39,2012-09-26 +Oracle Database 11g Release 2 Standard Ed One,1053100.32,2011-12-08 +Oracle Database 11g Standard Edition One,239392.0,2009-11-18 +Oracle Database 11g Standard Edition One,104492.0,2009-02-20 +Oracle Database 11g Standard Edition One,97083.0,2008-06-16 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,126371.0,2007-06-08 +Microsoft SQL Server 2005 Standard Edition,69564.0,2007-03-09 +Microsoft SQL Server 2005 Standard Edition,65833.0,2006-06-30 +Microsoft SQL Server 2005 Workgroup Edition,28244.0,2006-02-09 +Microsoft SQL Server 2005 Standard Edition x64,38622.0,2005-09-26 +Microsoft SQL Server 2000 Enterprise Edition SP3,63646.0,2005-05-10 +Microsoft SQL Server 2000 Workgroup Edition,28122.0,2005-02-24 +Microsoft SQL Server 2000 Enterprise Edition,26410.0,2004-12-10 +Microsoft SQL Server 2000 Enterprise Edition SP3,94172.0,2004-05-27 +Microsoft SQL Server 2000 Enterprise Edition,32185.33,2004-02-23 +Microsoft SQL Server 2000 Standard Edition,22052.0,2004-02-18 +Microsoft SQL Server 2000 Standard Edition,22052.81,2004-02-18 +Microsoft SQL Server 2000 Standard Edition,20108.79,2003-07-14 +Microsoft SQL Server 2000 Enterprise Edition SP3,84595.22,2003-06-30 +Microsoft SQL Server 2000 Enterprise Edition SP3,78116.87,2003-04-21 +Microsoft SQL Server 2000 Enterprise Edition SP3,71313.19,2003-01-06 +Microsoft SQL Server 2000 Enterprise Edition SP3,71586.49,2003-01-06 +Microsoft SQL Server 2000 Enterprise Edition,51069.87,2002-10-30 +Microsoft SQL Server 2000 Enterprise Edition,16756.52,2002-09-11 +Microsoft SQL Server 2000 Standard Edition,12579.04,2002-06-26 +Microsoft SQL Server 2000 Enterprise Edition,34819.03,2002-06-01 +Microsoft SQL Server 2000 Enterprise Edition,34914.92,2002-06-01 +Microsoft SQL Server 2000 Standard Edition,11537.02,2002-03-12 +Microsoft SQL Server 2000 Standard Edition,11537.02,2002-03-12 +Microsoft SQL Server 2000 Enterprise Edition,29860.12,2002-02-08 +Microsoft SQL Server 2000 Standard Edition,11314.11,2001-12-14 +Microsoft SQL Server 2000 Standard Edition,11320.02,2001-10-31 +Microsoft SQL Server 2000 Enterprise Edition,69901.74,2001-08-22 +Microsoft SQL Server 2000,57014.93,2001-04-02 +Microsoft SQL Server 2000,16262.9,2001-03-30 +Microsoft SQL Server 2000,30231.37,2001-03-19 +Microsoft SQL Server 2000,20320.7,2001-03-19 +Microsoft SQL Server 2000,24925.43,2001-03-19 +Microsoft SQL Server 2000,24925.43,2001-03-19 +Microsoft SQL Server 2000,20331.91,2001-03-19 +Microsoft SQL Server 2000,30231.37,2001-03-19 +Oracle Database 10g R2 Enterprise Edition w/Partitioning,2382032.0,2008-12-04 +Oracle Database 10g R2 Enterprise Edition,1354086.0,2008-11-22 +Oracle Database 10g R2 Enterprise Edition w/Partitioning,2196268.0,2007-10-30 +Oracle Database 10g Enterprise Edition,1238579.0,2006-11-30 +Oracle Database 10g Enterprise Edition,792101.96,2006-04-26 +Oracle Database 10g Enterprise Edition,595702.31,2003-10-31 +Microsoft SQL Server 2000 Enterprise Edition SP3,68264.47,2003-01-22 +Microsoft SQL Server 2000 Enterprise Edition SP3,84598.42,2003-01-22 +Microsoft SQL Server 2000 Enterprise Edition SP2,33768.41,2002-07-26 +Microsoft SQL Server 2000 Enterprise Edition,48906.18,2002-05-24 +Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0,455818.2,2001-08-28 +Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0,222772.33,2001-04-13 +Microsoft SQL Server 2000 Enterprise Edition SP4,188761.0,2005-10-28 +Microsoft SQL Server 2000 Enterprise Edition SP3,53691.33,2003-08-11 +Microsoft SQL Server 2000 Enterprise Edition SP3,68264.47,2002-11-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,84598.42,2002-10-07 +Microsoft SQL Server 2000 Enterprise Edition,48906.18,2002-03-12 +Microsoft SQL Server 2000 Enterprise Edition,33768.41,2002-02-25 +Microsoft SQL Server 2000 Enterprise Edition,22007.12,2001-10-25 +Microsoft SQL Server 2000,37383.57,2001-03-27 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,1207982.0,2011-11-15 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,1263599.0,2011-05-23 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,1024380.0,2011-05-05 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,1807347.0,2010-08-30 +Oracle Database 11g Release 2 Standard Ed One,290040.0,2010-08-17 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,1193472.0,2010-06-22 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,803068.0,2010-05-11 +Microsoft SQL Server 2005 Enterprise Edition x64 SP3,705652.0,2010-04-08 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,661475.0,2010-02-01 +Oracle Database 11g Standard Edition One,232002.0,2009-05-21 +Oracle Database 11g Standard Edition One,631766.0,2009-03-30 +Oracle Database 11g Standard Edition,639253.0,2009-01-16 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,579814.0,2008-11-17 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,634825.0,2008-08-19 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,471883.0,2008-07-14 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,402234.0,2008-03-31 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,275149.0,2008-01-07 +Oracle Database 10g Standard Edition One,273666.0,2007-11-09 +Oracle Database 11g Standard Edition One,102454.0,2007-09-12 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,251300.0,2007-09-05 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,407079.0,2007-09-05 +Microsoft SQL Server 2005 Enterprise Edition Itanium,372140.0,2007-06-11 +Oracle Database 10g Standard Edition One,100926.0,2007-06-08 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,82774.0,2007-03-27 +Oracle Database 10g R2 Enterprise Edition w/Partitioning,4092799.0,2007-02-27 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,138979.0,2007-02-13 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,222117.0,2006-11-14 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,240737.0,2006-11-13 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,139693.0,2006-11-09 +Oracle Database 10g R2 Enterprise Edition,359440.0,2006-10-26 +Microsoft SQL Server 2005 Enterprise Edition,318407.0,2006-10-19 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,262989.0,2006-09-25 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,147293.0,2006-09-13 +Oracle Database 10g Enterprise Edition,230569.0,2006-08-01 +Microsoft SQL Server 2005 Enterprise Edition Itanium,344928.0,2006-07-18 +Microsoft SQL Server 2005 Enterprise Edition x64,140246.0,2006-06-26 +Microsoft SQL Server 2005 Enterprise Edition x64,169360.0,2006-05-22 +Microsoft SQL Server 2005 Enterprise Edition x86 SP1,110615.0,2006-05-04 +Microsoft SQL Server 2005 Enterprise Edition Itanium,290644.0,2006-03-27 +Microsoft SQL Server 2005 Enterprise Edition x86 SP1,113628.0,2006-03-20 +Microsoft SQL Server 2005 Enterprise Edition,213986.0,2006-03-20 +Oracle Database 10g Enterprise Edition,200829.0,2006-03-09 +IBM DB2 UDB 8.2,236054.0,2005-12-05 +Microsoft SQL Server 2005 Enterprise Edition SP1,1231433.0,2005-11-28 +Microsoft SQL Server 2005 Enterprise Edition x64,206181.0,2005-11-04 +Microsoft SQL Server 2005 Enterprise Edition,202551.0,2005-09-30 +Microsoft SQL Server 2005 Enterprise Edition,109633.0,2005-09-30 +Microsoft SQL Server 2005 Enterprise Edition,107010.0,2005-09-30 +Microsoft SQL Server 2005 Enterprise Edition,138845.0,2005-09-30 +Microsoft SQL Server 2005 Enterprise Edition,76214.0,2005-09-30 +Microsoft SQL Server 2000 Enterprise Edition SP3,52742.0,2005-08-29 +Microsoft SQL Server 2000 Enterprise Edition 64bit,332265.87,2005-07-15 +Microsoft SQL Server 2000 Enterprise Edition SP3,65453.0,2005-06-24 +Microsoft SQL Server 2000 Enterprise Edition SP3,108574.0,2005-06-24 +Microsoft SQL Server 2005 Enterprise Edition 64bit,1082203.0,2005-06-07 +Microsoft SQL Server 2000 Enterprise Edition SP4,187296.0,2005-04-21 +Microsoft SQL Server 2000 Enterprise Edition SP3,42432.0,2005-03-28 +Microsoft SQL Server 2000 Enterprise Edition SP3,67754.0,2005-02-14 +Microsoft SQL Server 2000 Enterprise Edition SP3,74298.0,2005-02-11 +Microsoft SQL Server 2000 Enterprise Edition SP3,71413.0,2005-02-11 +Microsoft SQL Server 2000 Enterprise Edition QFE,130623.0,2005-02-11 +Microsoft SQL Server 2000 Enterprise Edition SP3,143367.0,2004-12-10 +Oracle Database 10g Standard Edition,161217.4,2004-11-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,123027.0,2004-11-07 +Microsoft SQL Server 2000 Enterprise Edition SP3,68010.0,2004-11-01 +Microsoft SQL Server 2000 Standard Edition SP3,17810.0,2004-10-19 +Microsoft SQL Server 2000 Enterprise Edition SP3,115110.0,2004-10-15 +Oracle Database 10g Standard Edition,51506.4,2004-09-29 +Microsoft SQL Server 2000 Enterprise Edition SP3,85554.0,2004-07-20 +IBM DB2 UDB Express Edition v8.1,18661.0,2004-07-16 +Microsoft SQL Server 2000 Enterprise Edition SP3,105687.0,2004-05-03 +Microsoft SQL Server 2000 Enterprise Edition SP3,123027.0,2004-05-03 +IBM DB2 UDB Express Edition v8.1,18318.24,2004-04-14 +Microsoft SQL Server 2000 Enterprise Edition,28711.0,2004-03-02 +Microsoft SQL Server 2000 Enterprise Edition,35030.0,2004-03-02 +Microsoft SQL Server 2000 Enterprise Edition,60364.0,2004-03-02 +Microsoft SQL Server 2000 Enterprise Edition,95163.0,2004-03-01 +Microsoft SQL Server 2000 Enterprise Edition 64bit,301225.0,2003-12-18 +Microsoft SQL Server 2000 Enterprise Edition SP3,33873.83,2003-12-17 +Microsoft SQL Server 2000 Standard Edition SP3,17192.4,2003-12-17 +Oracle Database 10g Enterprise Edition,1184893.38,2003-12-08 +Microsoft SQL Server 2000 Standard Edition SP3,19814.35,2003-11-24 +Oracle Database 10g Enterprise Edition,1008144.49,2003-11-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,51226.96,2003-10-22 +Microsoft SQL Server 2000 Enterprise Edition SP3,54096.56,2003-10-13 +Microsoft SQL Server 2000 Enterprise Edition SP3,84712.94,2003-09-08 +Oracle Database 10g Standard Edition,136110.98,2003-09-05 +Microsoft SQL Server 2000 Enterprise Edition 64bit,786646.0,2003-08-27 +Oracle Database 10g Standard Edition,131639.8,2003-07-30 +Oracle Database 10g Enterprise Edition,824164.53,2003-07-30 +Oracle Database 10g Enterprise Edition,541673.76,2003-07-30 +Microsoft SQL Server 2000 Standard Edition SP3,19718.01,2003-07-15 +Microsoft SQL Server 2000 Enterprise Edition SP3,52468.48,2003-07-15 +Microsoft SQL Server 2000 Standard Edition SP3,19140.72,2003-05-29 +Microsoft SQL Server 2000 Enterprise Edition SP3,44942.92,2003-05-29 +Microsoft SQL Server 2000 Enterprise Edition SP3,43230.66,2003-05-29 +Microsoft SQL Server 2000 Standard Edition SP3,18818.46,2003-05-29 +Microsoft SQL Server 2000 Enterprise Edition 64bit,707102.0,2003-05-20 +Microsoft SQL Server 2000 Enterprise Edition 64bit,707102.32,2003-05-16 +Microsoft SQL Server 2000,19526.27,2003-05-12 +Microsoft SQL Server 2000 Enterprise Edition SP3,39006.54,2003-05-12 +Microsoft SQL Server 2000 Enterprise Edition 64bit,121065.13,2003-04-24 +Microsoft SQL Server 2000 Enterprise Edition 64bit,658277.74,2003-04-24 +Microsoft SQL Server 2000 Enterprise Edition 64bit,658277.74,2003-04-24 +Microsoft SQL Server 2000 Enterprise Edition SP3,26725.34,2003-01-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,38386.24,2003-01-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,26725.34,2003-01-08 +Microsoft SQL Server 2000 Enterprise Edition 64bit,87741.0,2002-12-16 +Microsoft SQL Server 2000 Enterprise Edition SP3,115025.75,2002-12-06 +Microsoft SQL Server 2000 Enterprise Edition SP3,77905.18,2002-11-19 +Microsoft SQL Server 2000 Standard Edition SP3,18051.65,2002-11-19 +Oracle Database 10i Standard Edition,80570.81,2002-11-13 +Oracle Database 10i Standard Edition,80494.98,2002-11-12 +Microsoft SQL Server 2000 Enterprise Edition SP3,111805.22,2002-11-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,68739.22,2002-11-04 +Oracle Database 9i R2 Enterprise Edition,138362.03,2002-09-16 +Oracle Database 9i Enterprise Server v.9.2.0.1,423414.41,2002-08-26 +Microsoft SQL Server 2000 Enterprise Edition,61564.5,2002-08-23 +Microsoft SQL Server 2000 Standard Edition SP3,10089.76,2002-08-13 +Sybase Adaptive Server Enterprise v12.5,56375.0,2002-08-05 +Microsoft SQL Server 2000 Standard Edition,17659.53,2002-07-25 +Microsoft SQL Server 2000 Enterprise Edition 64bit,78454.76,2002-07-08 +Microsoft SQL Server 2000 Enterprise Edition 64bit,40621.26,2002-07-08 +Oracle Database 9i R2 Enterprise Edition,137260.89,2002-06-04 +Microsoft SQL Server 2000 Enterprise Edition,48911.83,2002-05-17 +Microsoft SQL Server 2000 Enterprise Edition,34473.15,2002-04-23 +Microsoft SQL Server 2000 Enterprise Edition,34473.15,2002-04-23 +Microsoft SQL Server 2000 Enterprise Edition,69169.61,2002-02-25 +Microsoft SQL Server 2000 Standard Edition,17078.88,2002-02-13 +Oracle Database 9i R2 Enterprise Edition for Tru64 Unix,50117.0,2002-01-28 +Oracle 8 Enterprise Edition v8.1.7.1,197024.17,2001-12-21 +Sybase Adaptive Server Enterprise v12.5,140239.97,2001-12-21 +Oracle Database 9i Enterprise Edition,389434.4,2001-12-21 +Microsoft SQL Server 2000 Enterprise Edition,37100.52,2001-11-12 +Microsoft SQL Server 2000 Enterprise Edition,39158.09,2001-09-27 +Microsoft SQL Server 2000 Enterprise Edition,17335.75,2001-09-26 +Microsoft SQL Server 2000,9347.24,2001-09-25 +Microsoft SQL Server 2000 Enterprise Edition,410769.88,2001-09-19 +Microsoft SQL Server 2000 Enterprise Edition,567882.56,2001-09-19 +Microsoft SQL Server 2000 Enterprise Edition,709220.08,2001-09-19 +Microsoft SQL Server 2000 Enterprise Edition,37596.34,2001-08-23 +Microsoft SQL Server 2000 Enterprise Edition,43046.55,2001-08-23 +Microsoft SQL Server 2000,20207.2,2001-07-27 +Oracle Database 9i Enterprise Edition,230533.0,2001-06-18 +Sybase Adaptive Server Enterprise 11.9.3,22422.5,2001-04-05 +Sybase Adaptive Server Enterprise 11.9.3,49308.0,2001-04-05 +Sybase Adaptive Server Enterprise 12.0,60366.82,2001-04-05 +Sybase Adaptive Server Enterprise 12.0,34288.77,2001-04-05 +Oracle 8i Enterprise Edition v. 8.1.7,155179.25,2001-04-03 +Oracle 8 Enterprise Edition v8.1.7.1,71863.02,2001-04-03 +Sybase Adaptive Server Enterprise 12.0.0.3,37274.0,2001-04-03 +Sybase Adaptive Server Enterprise 12.0.0.3,37274.0,2001-04-03 +Sybase Adaptive Server Enterprise 12.0,60366.82,2000-06-21 +IBM DB2 ESE 9.7,1320082.0,2013-02-22 +IBM DB2 ESE 9.7,1503544.0,2012-04-11 +IBM DB2 ESE 9.7,3014684.0,2011-07-11 +IBM DB2 ESE 9.7,2308099.0,2010-11-16 +IBM DB2 9.7,10366254.0,2010-08-17 +IBM DB2 9.5,1200011.0,2010-04-13 +Microsoft SQL Server 2005 Enterprise Edition x64,684508.0,2008-09-15 +IBM DB2 ESE 9.5,1200632.0,2008-08-19 +Sybase Adaptive Server Enterprise 15.0.3,276383.0,2008-06-16 +IBM DB2 9.5,6085166.0,2008-06-10 +IBM DB2 9.5 Enterprise Edition,629159.0,2008-03-20 +Microsoft SQL Server 2005 Enterprise Edition x64,841809.0,2007-10-23 +IBM DB2 9.5 Enterprise Edition,516752.0,2007-10-15 +Oracle Database 10g R2 Enterprise Edition,236271.0,2007-10-04 +Oracle Database 10g Enterprise Edition,404462.0,2007-08-06 +IBM DB2 Enterprise 9,1616162.0,2007-05-21 +Microsoft SQL Server 2005 Enterprise Edition x64 SP2,145180.0,2007-04-26 +IBM DB2 9,511342.0,2007-03-25 +Microsoft SQL Server 2005 Enterprise Edition x64 SP1,510822.0,2007-02-28 +IBM DB2 9,4033378.0,2007-01-22 +IBM DB2 9,331087.0,2006-12-15 +IBM DB2 9,314468.0,2006-09-19 +IBM DB2 9,4016222.19,2006-07-24 +Sybase Adaptive Server Enterprise v.12.5.4,81439.3,2006-06-23 +Microsoft SQL Server 2005 Enterprise Edition x64,340243.0,2006-06-12 +Microsoft SQL Server 2005 Enterprise Edition x64,492307.0,2006-03-21 +IBM DB2 UDB 8.2,273520.0,2006-03-07 +IBM DB2 UDB 8.2,1025169.69,2006-02-14 +Microsoft SQL Server 2005 Enterprise Edition,492307.0,2005-11-22 +IBM DB2 UDB 8.2,221017.0,2005-10-31 +Oracle Database 10g Enterprise Edition,203439.87,2005-10-17 +Microsoft SQL Server 2005 Enterprise Edition 64bit,241300.0,2005-09-14 +IBM DB2 UDB 8.2,197669.0,2005-08-08 +IBM DB2 UDB 8.2,250975.0,2005-05-31 +IBM DB2 UDB 8.2,150704.0,2005-04-21 +Microsoft SQL Server 2000 Enterprise Edition (SP3 w/QFE),141504.0,2005-04-21 +Oracle Database 10g Enterprise Edition,1601784.98,2005-04-20 +IBM DB2 UDB 8.2,3210540.63,2004-11-18 +IBM DB2 UDB 8.1,429899.7,2004-08-31 +Oracle Database 10g,194391.43,2004-07-12 +IBM DB2 UDB 8.1,809144.09,2004-07-12 +Oracle Database 10g,371044.22,2004-07-12 +Microsoft SQL Server 2000 Enterprise Edition SP3,215485.89,2004-03-26 +Microsoft SQL Server 2000 Enterprise Edition,102667.42,2004-03-01 +Microsoft SQL Server 2000 Enterprise Edition,156105.72,2004-03-01 +IBM DB2 UDB 8.1,1025486.07,2004-02-17 +Microsoft SQL Server 2000 Enterprise Edition SP3,89616.32,2003-12-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,31910.24,2003-12-03 +Microsoft SQL Server 2000 Enterprise Edition SP3,90271.76,2003-10-17 +Oracle Database 10g Enterprise Edition,768839.4,2003-09-12 +Microsoft SQL Server 2000 Enterprise Edition SP3,190510.02,2003-07-18 +Microsoft SQL Server 2000 Enterprise Edition,18936.05,2003-07-10 +Microsoft SQL Server 2000 Enterprise Edition SP3,139153.98,2003-06-30 +IBM DB2 UDB 8.1,763898.39,2003-06-30 +IBM DB2 UDB 8.1,680613.12,2003-05-09 +Microsoft SQL Server 2000 Enterprise Edition SP3,119115.16,2003-04-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,151744.13,2003-03-26 +Microsoft SQL Server 2000 Enterprise Edition SP3,151744.13,2003-03-26 +Microsoft SQL Server 2000 Enterprise Edition SP3,52587.46,2003-02-28 +Microsoft SQL Server 2000 Enterprise Edition SP3,50666.11,2003-02-28 +Oracle Database 9i Enterprise Server v.9.2.0.1,427760.83,2002-12-26 +Microsoft SQL Server 2000 Standard Edition SP3,18077.98,2002-12-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,112740.87,2002-11-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,74206.27,2002-11-04 +Microsoft SQL Server 2000 Enterprise Edition SP3,111024.39,2002-11-04 +Microsoft SQL Server 2000 Enterprise Edition SP2,61168.83,2002-08-20 +Microsoft SQL Server 2000 Standard Edition SP3,17559.31,2002-08-16 +Oracle Database 9i R2 Enterprise Edition,403255.46,2002-08-15 +Microsoft SQL Server 2000 Enterprise Edition,92398.49,2002-07-22 +Microsoft SQL Server 2000 Enterprise Edition,45230.03,2002-07-17 +Microsoft SQL Server 2000 Standard Edition,12009.46,2002-06-03 +Microsoft SQL Server 2000 Enterprise Edition,55138.6,2002-03-11 +Microsoft SQL Server 2000 Standard Edition,23027.66,2002-03-11 +Microsoft SQL Server 2000 Standard Edition,15533.72,2001-11-05 +Microsoft SQL Server 2000 Standard Edition,9112.91,2001-10-16 +Microsoft SQL Server 2000,20422.01,2001-10-01 +Oracle Database 9i Enterprise Edition v.9i.0.1,105025.02,2001-09-10 +Oracle 8i Enterprise Edition v. 8.1.7,66750.27,2001-06-22 +Oracle 8i Enterprise Edition v. 8.1.7,220807.27,2001-06-22 +Microsoft SQL Server 2000,136766.67,2001-04-24 +Oracle Database 9i Enterprise Edition v.9.0.1,57346.93,2001-04-23 +Microsoft SQL Server 2000 Enterprise Edition,34264.9,2001-04-12 +Microsoft SQL Server 2000,32377.17,2001-04-12 +IBM DB2 UDB 7.1,440879.95,2001-04-11 +Microsoft SQL Server 2000,363129.75,2001-04-11 +Microsoft SQL Server 2000,688220.9,2001-04-11 +Microsoft SQL Server 2000,688220.9,2001-04-10 +Microsoft SQL Server 2000,121319.23,2001-04-10 +Oracle 8 Enterprise Edition v8.1.7.1,66750.27,2001-03-20 +IBM DB2 for AS/400 V4 R5,163775.8,2001-03-19 +IBM DB2 for AS/400 V4 R5,152346.25,2001-03-19 +IBM DB2 UDB 7.1,440879.95,2001-04-11 +Microsoft SQL Server 2005 Standard Edition,57552.0,2006-04-12 +Microsoft SQL Server 2005 Enterprise Edition,85858.0,2005-12-01 +Microsoft SQL Server 2000 Enterprise Edition SP3,31253.0,2005-06-28 +Microsoft SQL Server 2000 Enterprise Edition SP3,32464.0,2004-10-15 +Microsoft SQL Server 2000 Enterprise Edition SP3,34349.0,2004-08-13 +Microsoft SQL Server 2000 Enterprise Edition SP3,21197.0,2004-05-11 +Microsoft SQL Server 2000 Enterprise Edition SP3,58161.52,2003-11-03 +Microsoft SQL Server 2000 Enterprise Edition SP3,36027.71,2003-09-21 +Microsoft SQL Server 2005 Enterprise Edition x64,125954.0,2006-05-01 +Oracle Database 10g R2 Enterprise Edition w/Partitioning,1245516.0,2008-01-21 +Oracle Database 10g Enterprise Edition,254471.0,2006-01-18 +IBM DB2 UDB 8.2,247650.0,2005-01-25 +IBM DB2 UDB 8.2,247650.0,2005-01-25 +Oracle Database 10g Enterprise Edition,683575.0,2004-06-28 +Oracle Database 10g Enterprise Edition,609467.0,2004-04-06 +Microsoft SQL Server 2000 Enterprise Edition 64bit,577530.77,2003-10-09 +Oracle Database 10g Enterprise Edition,521440.53,2003-09-08 +Microsoft SQL Server 2000 Enterprise Edition 64bit,514034.72,2003-04-23 +Microsoft SQL Server 2000 Enterprise Edition,70653.01,2003-04-09 +Microsoft SQL Server 2000 Enterprise Edition 64bit,433107.77,2003-02-20 +Microsoft SQL Server 2000 Enterprise Edition 64bit,342746.25,2002-12-12 +Microsoft SQL Server 2000 Enterprise Edition,48150.72,2002-06-20 +Microsoft SQL Server 2000 Enterprise Edition,48150.72,2002-06-20 +Microsoft SQL Server 2000 Enterprise Edition,52671.3,2001-05-22 +Sybase Adaptive Server Enterprise v12.5,112286.46,2002-03-12 +Oracle 11g Release 2 Enterprise Edition with Oracle Partitioning,8552523.0,2013-03-26 +Oracle Database 11g R2 Enterprise Edition w/Partitioning,5055888.0,2012-06-20 +Oracle Database 11g R2 Enterprise Edition,4803718.0,2012-01-18 +Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning,30249688.0,2010-12-02 +Oracle Database 11g Enterprise Edition w/RAC w/Partitioning,7646486.0,2009-11-04 +Microsoft SQL Server 2000 Standard Edition SP3,20477.37,2003-09-08 +Microsoft SQL Server 2000 Enterprise Edition SP3,82226.46,2003-07-08 +SQL Anywhere 16,112890.0,2014-11-25 +Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0,67102.53,2001-09-25 +Sybase SQL Anywhere 11.0,20705.0,2008-07-29 +SunjeSoft Goldilocks v3.1 Standard Edition,76174.0,2020-11-23 +SunjeSoft Goldilocks v3.1 Standard Edition,380475.0,2020-08-17 +SunjeSoft Goldilocks v3.1 Standard Edition,152328.0,2019-11-03 +SunjeSoft Goldilocks v3.1 Standard Edition,76168.0,2019-10-14 +SunjeSoft Goldilocks v3.1 Standard Edition,114245.0,2019-10-14 +SunjeSoft Goldilocks v3.1 Standard Edition,76172.0,2018-11-26 +SunjeSoft Goldilocks v3.1 Standard Edition,76168.0,2018-11-26 +SunjeSoft Goldilocks v3.1 Standard Edition,152330.0,2018-11-19 +SunjeSoft Goldilocks v3.1 Standard Edition,139909.0,2017-05-08 +Microsoft SQL Server 2005 Enterprise Edition,520467.0,2007-03-23 +Microsoft SQL Server 2005 Enterprise Edition x64,749839.0,2006-05-08 +Microsoft SQL Server 2005 Enterprise Edition x64,347854.0,2006-02-22 +Microsoft SQL Server 2005 Enterprise Edition x64,251691.0,2005-11-07 +Microsoft SQL Server 2005 Enterprise Edition x64,376045.0,2005-10-24 +Oracle Database 10g Enterprise Edition,327829.0,2005-07-01 +Oracle Database 10g Enterprise Edition,322805.0,2005-06-24 +Microsoft SQL Server 2000 Enterprise Edition,237869.0,2004-06-14 +Microsoft SQL Server 2000 Enterprise Edition,212511.0,2004-06-14 +Oracle Database 10g Enterprise Edition,291413.0,2004-05-11 +Microsoft SQL Server 2000 Enterprise Edition,304148.5,2004-04-28 +Microsoft SQL Server 2000 Enterprise Edition,309036.53,2004-01-20 +Oracle Database 10g Enterprise Edition,291410.61,2003-10-20 +Microsoft SQL Server 2000 Enterprise Edition,252920.49,2003-06-27 +Microsoft SQL Server 2000 Enterprise Edition,161542.04,2003-05-16 +Microsoft SQL Server 2000 Enterprise Edition,181280.45,2003-05-02 +Microsoft SQL Server 2000 Enterprise Edition,118381.38,2003-04-04 +Microsoft SQL Server 2000 Enterprise Edition,234325.1,2002-12-09 +Microsoft SQL Server 2000 Enterprise Edition,203518.03,2002-11-04 +Microsoft SQL Server 2000 Enterprise Edition,165218.71,2001-11-11 +Microsoft SQL Server 2000 Enterprise Edition,165218.71,2001-11-11 +Microsoft SQL Server 2000 Enterprise Edition,141138.44,2001-09-10 diff --git a/scripts/run_tests_one_by_one.py b/scripts/run_tests_one_by_one.py index a424b6cbc2d0..b8980c001fb6 100644 --- a/scripts/run_tests_one_by_one.py +++ b/scripts/run_tests_one_by_one.py @@ -19,7 +19,8 @@ def valid_timeout(value): parser = argparse.ArgumentParser(description='Run tests one by one with optional flags.') parser.add_argument('unittest_program', help='Path to the unittest program') -parser.add_argument('--no-exit', action='store_true', help='Do not exit after running tests') +parser.add_argument('--no-exit', action='store_true', help='Execute all tests, without stopping on first error') +parser.add_argument('--fast-fail', action='store_true', help='Terminate on first error') parser.add_argument('--profile', action='store_true', help='Enable profiling') parser.add_argument('--no-assertions', action='store_false', help='Disable assertions') parser.add_argument('--time_execution', action='store_true', help='Measure and print the execution time of each test') @@ -47,6 +48,13 @@ def valid_timeout(value): # Access the arguments unittest_program = args.unittest_program no_exit = args.no_exit +fast_fail = args.fast_fail + +if no_exit: + if fast_fail: + print("--no-exit and --fast-fail can't be combined") + exit(1) + profile = args.profile assertions = args.no_assertions time_execution = args.time_execution @@ -87,7 +95,7 @@ def valid_timeout(value): def fail(): global all_passed all_passed = False - if not no_exit: + if fast_fail: exit(1) diff --git a/scripts/sqllogictest/result.py b/scripts/sqllogictest/result.py index 537abbd8e0aa..aa4e8158bd47 100644 --- a/scripts/sqllogictest/result.py +++ b/scripts/sqllogictest/result.py @@ -332,9 +332,9 @@ def compare_rows(a, b): hash_compare_error = values[0] != hash_value if hash_compare_error: - expected_result = self.result_label_map.get(query_label) - logger.wrong_result_hash(expected_result, self) - self.fail_query(query) + expected_result = runner.result_label_map.get(query_label) + # logger.wrong_result_hash(expected_result, self) + context.fail(query) assert not hash_compare_error diff --git a/src/common/types.cpp b/src/common/types.cpp index 52002ded47ec..4beade0efaa8 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -988,6 +988,72 @@ static bool CombineUnequalTypes(const LogicalType &left, const LogicalType &righ return false; } +template +static bool CombineStructTypes(const LogicalType &left, const LogicalType &right, LogicalType &result) { + auto &left_children = StructType::GetChildTypes(left); + auto &right_children = StructType::GetChildTypes(right); + + auto left_unnamed = StructType::IsUnnamed(left); + auto is_unnamed = left_unnamed || StructType::IsUnnamed(right); + child_list_t child_types; + + // At least one side is unnamed, so we attempt positional casting. + if (is_unnamed) { + if (left_children.size() != right_children.size()) { + // We can't cast, or create the super-set. + return false; + } + + for (idx_t i = 0; i < left_children.size(); i++) { + LogicalType child_type; + if (!OP::Operation(left_children[i].second, right_children[i].second, child_type)) { + return false; + } + auto &child_name = left_unnamed ? right_children[i].first : left_children[i].first; + child_types.emplace_back(child_name, std::move(child_type)); + } + result = LogicalType::STRUCT(child_types); + return true; + } + + // Create a super-set of the STRUCT fields. + // First, create a name->index map of the right children. + case_insensitive_map_t right_children_map; + for (idx_t i = 0; i < right_children.size(); i++) { + auto &name = right_children[i].first; + right_children_map[name] = i; + } + + for (idx_t i = 0; i < left_children.size(); i++) { + auto &left_child = left_children[i]; + auto right_child_it = right_children_map.find(left_child.first); + + if (right_child_it == right_children_map.end()) { + // We can directly put the left child. + child_types.emplace_back(left_child.first, left_child.second); + continue; + } + + // We need to recurse to ensure the children have a maximum logical type. + LogicalType child_type; + auto &right_child = right_children[right_child_it->second]; + if (!OP::Operation(left_child.second, right_child.second, child_type)) { + return false; + } + child_types.emplace_back(left_child.first, std::move(child_type)); + right_children_map.erase(right_child_it); + } + + // Add all remaining right children. + for (const auto &right_child_it : right_children_map) { + auto &right_child = right_children[right_child_it.second]; + child_types.emplace_back(right_child.first, right_child.second); + } + + result = LogicalType::STRUCT(child_types); + return true; +} + template static bool CombineEqualTypes(const LogicalType &left, const LogicalType &right, LogicalType &result) { // Since both left and right are equal we get the left type as our type_id for checks @@ -1059,31 +1125,7 @@ static bool CombineEqualTypes(const LogicalType &left, const LogicalType &right, return true; } case LogicalTypeId::STRUCT: { - // struct: perform recursively on each child - auto &left_child_types = StructType::GetChildTypes(left); - auto &right_child_types = StructType::GetChildTypes(right); - bool left_unnamed = StructType::IsUnnamed(left); - auto any_unnamed = left_unnamed || StructType::IsUnnamed(right); - if (left_child_types.size() != right_child_types.size()) { - // child types are not of equal size, we can't cast - // return false - return false; - } - child_list_t child_types; - for (idx_t i = 0; i < left_child_types.size(); i++) { - LogicalType child_type; - // Child names must be in the same order OR either one of the structs must be unnamed - if (!any_unnamed && !StringUtil::CIEquals(left_child_types[i].first, right_child_types[i].first)) { - return false; - } - if (!OP::Operation(left_child_types[i].second, right_child_types[i].second, child_type)) { - return false; - } - auto &child_name = left_unnamed ? right_child_types[i].first : left_child_types[i].first; - child_types.emplace_back(child_name, std::move(child_type)); - } - result = LogicalType::STRUCT(child_types); - return true; + return CombineStructTypes(left, right, result); } case LogicalTypeId::UNION: { auto left_member_count = UnionType::GetMemberCount(left); diff --git a/src/common/types/vector.cpp b/src/common/types/vector.cpp index 711872031e09..722b8b69902b 100644 --- a/src/common/types/vector.cpp +++ b/src/common/types/vector.cpp @@ -1374,10 +1374,10 @@ void Vector::Deserialize(Deserializer &deserializer, idx_t count) { } void Vector::SetVectorType(VectorType vector_type_p) { - this->vector_type = vector_type_p; + vector_type = vector_type_p; auto physical_type = GetType().InternalType(); - if (TypeIsConstantSize(physical_type) && - (GetVectorType() == VectorType::CONSTANT_VECTOR || GetVectorType() == VectorType::FLAT_VECTOR)) { + auto flat_or_const = GetVectorType() == VectorType::CONSTANT_VECTOR || GetVectorType() == VectorType::FLAT_VECTOR; + if (TypeIsConstantSize(physical_type) && flat_or_const) { auxiliary.reset(); } if (vector_type == VectorType::CONSTANT_VECTOR && physical_type == PhysicalType::STRUCT) { @@ -1782,23 +1782,29 @@ void Vector::DebugShuffleNestedVector(Vector &vector, idx_t count) { void FlatVector::SetNull(Vector &vector, idx_t idx, bool is_null) { D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR); vector.validity.Set(idx, !is_null); - if (is_null) { - auto &type = vector.GetType(); - auto internal_type = type.InternalType(); - if (internal_type == PhysicalType::STRUCT) { - // set all child entries to null as well - auto &entries = StructVector::GetEntries(vector); - for (auto &entry : entries) { - FlatVector::SetNull(*entry, idx, is_null); - } - } else if (internal_type == PhysicalType::ARRAY) { - // set the child element in the array to null as well - auto &child = ArrayVector::GetEntry(vector); - auto array_size = ArrayType::GetSize(type); - auto child_offset = idx * array_size; - for (idx_t i = 0; i < array_size; i++) { - FlatVector::SetNull(child, child_offset + i, is_null); - } + if (!is_null) { + return; + } + + auto &type = vector.GetType(); + auto internal_type = type.InternalType(); + + // Set all child entries to NULL. + if (internal_type == PhysicalType::STRUCT) { + auto &entries = StructVector::GetEntries(vector); + for (auto &entry : entries) { + FlatVector::SetNull(*entry, idx, is_null); + } + return; + } + + // Set all child entries to NULL. + if (internal_type == PhysicalType::ARRAY) { + auto &child = ArrayVector::GetEntry(vector); + auto array_size = ArrayType::GetSize(type); + auto child_offset = idx * array_size; + for (idx_t i = 0; i < array_size; i++) { + FlatVector::SetNull(child, child_offset + i, is_null); } } } diff --git a/src/execution/physical_plan/plan_cte.cpp b/src/execution/physical_plan/plan_cte.cpp index 190cb9319bc7..9c6596279ca5 100644 --- a/src/execution/physical_plan/plan_cte.cpp +++ b/src/execution/physical_plan/plan_cte.cpp @@ -24,7 +24,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalMaterializ auto right = CreatePlan(*op.children[1]); unique_ptr cte; - cte = make_uniq(op.ctename, op.table_index, op.children[1]->types, std::move(left), std::move(right), + cte = make_uniq(op.ctename, op.table_index, right->types, std::move(left), std::move(right), op.estimated_cardinality); cte->working_table = working_table; cte->cte_scans = materialized_ctes[op.table_index]; diff --git a/src/function/cast/struct_cast.cpp b/src/function/cast/struct_cast.cpp index 94f494c1c7b9..e5902b7522e2 100644 --- a/src/function/cast/struct_cast.cpp +++ b/src/function/cast/struct_cast.cpp @@ -1,3 +1,4 @@ +#include "duckdb/common/exception/binder_exception.hpp" #include "duckdb/function/cast/default_casts.hpp" #include "duckdb/function/cast/cast_function_set.hpp" #include "duckdb/function/cast/bound_cast_data.hpp" @@ -7,51 +8,67 @@ namespace duckdb { unique_ptr StructBoundCastData::BindStructToStructCast(BindCastInput &input, const LogicalType &source, const LogicalType &target) { vector child_cast_info; - auto &source_child_types = StructType::GetChildTypes(source); - auto &result_child_types = StructType::GetChildTypes(target); + auto &source_children = StructType::GetChildTypes(source); + auto &target_children = StructType::GetChildTypes(target); auto target_is_unnamed = StructType::IsUnnamed(target); auto source_is_unnamed = StructType::IsUnnamed(source); - if (source_child_types.size() != result_child_types.size()) { + auto is_unnamed = target_is_unnamed || source_is_unnamed; + if (is_unnamed && source_children.size() != target_children.size()) { throw TypeMismatchException(input.query_location, source, target, "Cannot cast STRUCTs of different size"); } - bool named_struct_cast = !source_is_unnamed && !target_is_unnamed; - case_insensitive_map_t target_members; - if (named_struct_cast) { - for (idx_t i = 0; i < result_child_types.size(); i++) { - auto &target_name = result_child_types[i].first; - if (target_members.find(target_name) != target_members.end()) { - throw NotImplementedException("Error while casting - duplicate name \"%s\" in struct", target_name); + + case_insensitive_map_t target_children_map; + if (!is_unnamed) { + for (idx_t i = 0; i < target_children.size(); i++) { + auto &name = target_children[i].first; + if (target_children_map.find(name) != target_children_map.end()) { + throw NotImplementedException("Error while casting - duplicate name \"%s\" in struct", name); } - target_members[target_name] = i; + target_children_map[name] = i; } } - vector child_member_map; - child_member_map.reserve(source_child_types.size()); - for (idx_t source_idx = 0; source_idx < source_child_types.size(); source_idx++) { - auto &source_child = source_child_types[source_idx]; - idx_t target_idx; - if (named_struct_cast) { - // named struct cast - find corresponding member in target - auto entry = target_members.find(source_child.first); - if (entry == target_members.end()) { - throw TypeMismatchException(input.query_location, source, target, - "Cannot cast STRUCTs - element \"" + source_child.first + - "\" in source struct was not found in target struct"); + + vector source_indexes; + vector target_indexes; + vector target_null_indexes; + bool has_any_match = is_unnamed; + + for (idx_t i = 0; i < source_children.size(); i++) { + auto &source_child = source_children[i]; + auto target_idx = i; + + // Map to the correct index for names structs. + if (!is_unnamed) { + auto target_child = target_children_map.find(source_child.first); + if (target_child == target_children_map.end()) { + // Skip any children that have no target. + continue; } - target_idx = entry->second; - target_members.erase(entry); - } else { - // unnamed struct cast - positionally cast elements - target_idx = source_idx; + target_idx = target_child->second; + target_children_map.erase(target_child); + has_any_match = true; } - child_member_map.push_back(target_idx); - auto child_cast = input.GetCastFunction(source_child.second, result_child_types[target_idx].second); + + source_indexes.push_back(i); + target_indexes.push_back(target_idx); + auto child_cast = input.GetCastFunction(source_child.second, target_children[target_idx].second); child_cast_info.push_back(std::move(child_cast)); } - D_ASSERT(child_member_map.size() == source_child_types.size()); - return make_uniq(std::move(child_cast_info), target, std::move(child_member_map)); + + if (!has_any_match) { + throw BinderException("STRUCT to STRUCT cast must have at least one matching member"); + } + + // The remaining target children have no match in the source struct. + // Thus, they become NULL. + for (const auto &target_child : target_children_map) { + target_null_indexes.push_back(target_child.second); + } + + return make_uniq(std::move(child_cast_info), target, std::move(source_indexes), + std::move(target_indexes), std::move(target_null_indexes)); } unique_ptr StructBoundCastData::InitStructCastLocalState(CastLocalStateParameters ¶meters) { @@ -71,32 +88,46 @@ unique_ptr StructBoundCastData::InitStructCastLocalState(Cas static bool StructToStructCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { auto &cast_data = parameters.cast_data->Cast(); - auto &lstate = parameters.local_state->Cast(); - auto &source_child_types = StructType::GetChildTypes(source.GetType()); - auto &source_children = StructVector::GetEntries(source); - D_ASSERT(source_children.size() == StructType::GetChildTypes(result.GetType()).size()); + auto &l_state = parameters.local_state->Cast(); + + auto &source_vectors = StructVector::GetEntries(source); + auto &target_children = StructVector::GetEntries(result); - auto &result_children = StructVector::GetEntries(result); bool all_converted = true; - for (idx_t c_idx = 0; c_idx < source_child_types.size(); c_idx++) { - auto source_idx = c_idx; - auto target_idx = cast_data.child_member_map[source_idx]; - auto &source_child_vector = *source_children[source_idx]; - auto &result_child_vector = *result_children[target_idx]; - CastParameters child_parameters(parameters, cast_data.child_cast_info[c_idx].cast_data, - lstate.local_states[c_idx]); - if (!cast_data.child_cast_info[c_idx].function(source_child_vector, result_child_vector, count, - child_parameters)) { + for (idx_t i = 0; i < cast_data.source_indexes.size(); i++) { + auto source_idx = cast_data.source_indexes[i]; + auto target_idx = cast_data.target_indexes[i]; + + auto &source_vector = *source_vectors[source_idx]; + auto &target_vector = *target_children[target_idx]; + + auto &child_cast_info = cast_data.child_cast_info[i]; + CastParameters child_parameters(parameters, child_cast_info.cast_data, l_state.local_states[i]); + auto success = child_cast_info.function(source_vector, target_vector, count, child_parameters); + if (!success) { all_converted = false; } } + + if (!cast_data.target_null_indexes.empty()) { + for (idx_t i = 0; i < cast_data.target_null_indexes.size(); i++) { + auto target_idx = cast_data.target_null_indexes[i]; + auto &target_vector = *target_children[target_idx]; + + target_vector.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(target_vector, true); + } + } + if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) { result.SetVectorType(VectorType::CONSTANT_VECTOR); ConstantVector::SetNull(result, ConstantVector::IsNull(source)); - } else { - source.Flatten(count); - FlatVector::Validity(result) = FlatVector::Validity(source); + return all_converted; } + + source.Flatten(count); + auto &result_validity = FlatVector::Validity(result); + result_validity = FlatVector::Validity(source); return all_converted; } diff --git a/src/function/window/window_boundaries_state.cpp b/src/function/window/window_boundaries_state.cpp index 234d0cadc612..7727e2a630f5 100644 --- a/src/function/window/window_boundaries_state.cpp +++ b/src/function/window/window_boundaries_state.cpp @@ -301,51 +301,86 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi WindowBoundsSet result; switch (wexpr.GetExpressionType()) { case ExpressionType::WINDOW_ROW_NUMBER: - result.insert(PARTITION_BEGIN); - if (!wexpr.arg_orders.empty()) { - // Secondary orders need to know how wide the partition is + if (wexpr.arg_orders.empty()) { + result.insert(PARTITION_BEGIN); + } else { + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); + } + break; + case ExpressionType::WINDOW_NTILE: + if (wexpr.arg_orders.empty()) { + result.insert(PARTITION_BEGIN); result.insert(PARTITION_END); + } else { + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); } break; - case ExpressionType::WINDOW_RANK_DENSE: case ExpressionType::WINDOW_RANK: - result.insert(PARTITION_BEGIN); if (wexpr.arg_orders.empty()) { + result.insert(PARTITION_BEGIN); result.insert(PEER_BEGIN); } else { - // Secondary orders need to know how wide the partition is - result.insert(PARTITION_END); + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); } break; - case ExpressionType::WINDOW_PERCENT_RANK: + case ExpressionType::WINDOW_RANK_DENSE: result.insert(PARTITION_BEGIN); - result.insert(PARTITION_END); + result.insert(PEER_BEGIN); + break; + case ExpressionType::WINDOW_PERCENT_RANK: if (wexpr.arg_orders.empty()) { - // Secondary orders need to know where the first peer is + result.insert(PARTITION_BEGIN); + result.insert(PARTITION_END); result.insert(PEER_BEGIN); + } else { + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); } break; case ExpressionType::WINDOW_CUME_DIST: - result.insert(PARTITION_BEGIN); - result.insert(PARTITION_END); if (wexpr.arg_orders.empty()) { + result.insert(PARTITION_BEGIN); + result.insert(PARTITION_END); result.insert(PEER_END); + } else { + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); } break; - case ExpressionType::WINDOW_NTILE: case ExpressionType::WINDOW_LEAD: case ExpressionType::WINDOW_LAG: - result.insert(PARTITION_BEGIN); - result.insert(PARTITION_END); + if (wexpr.arg_orders.empty()) { + result.insert(PARTITION_BEGIN); + result.insert(PARTITION_END); + } else { + // Secondary orders need to know where the frame is + result.insert(FRAME_BEGIN); + result.insert(FRAME_END); + } break; case ExpressionType::WINDOW_FIRST_VALUE: case ExpressionType::WINDOW_LAST_VALUE: case ExpressionType::WINDOW_NTH_VALUE: case ExpressionType::WINDOW_AGGREGATE: - result.insert(PARTITION_BEGIN); - result.insert(PARTITION_END); result.insert(FRAME_BEGIN); result.insert(FRAME_END); + break; + default: + throw InternalException("Window aggregate type %s", ExpressionTypeToString(wexpr.GetExpressionType())); + } + + // Internal dependencies + if (result.count(FRAME_BEGIN) || result.count(FRAME_END)) { + result.insert(PARTITION_BEGIN); + result.insert(PARTITION_END); // if we have EXCLUDE GROUP / TIES, we also need peer boundaries if (wexpr.exclude_clause != WindowExcludeMode::NO_OTHER) { @@ -389,12 +424,8 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi default: break; } - break; - default: - throw InternalException("Window aggregate type %s", ExpressionTypeToString(wexpr.GetExpressionType())); } - // Internal dependencies if (result.count(VALID_END)) { result.insert(PARTITION_END); if (HasFollowingRange(wexpr)) { diff --git a/src/function/window/window_rank_function.cpp b/src/function/window/window_rank_function.cpp index d1299430ace3..b71a4aeacab5 100644 --- a/src/function/window/window_rank_function.cpp +++ b/src/function/window/window_rank_function.cpp @@ -117,18 +117,19 @@ void WindowRankExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, Win DataChunk &eval_chunk, Vector &result, idx_t count, idx_t row_idx) const { auto &gpeer = gstate.Cast(); auto &lpeer = lstate.Cast(); - auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); - auto partition_end = FlatVector::GetData(lpeer.bounds.data[PARTITION_END]); auto rdata = FlatVector::GetData(result); if (gpeer.token_tree) { + auto frame_begin = FlatVector::GetData(lpeer.bounds.data[FRAME_BEGIN]); + auto frame_end = FlatVector::GetData(lpeer.bounds.data[FRAME_END]); for (idx_t i = 0; i < count; ++i, ++row_idx) { - rdata[i] = gpeer.token_tree->Rank(partition_begin[i], partition_end[i], row_idx); + rdata[i] = gpeer.token_tree->Rank(frame_begin[i], frame_end[i], row_idx); } return; } // Reset to "previous" row + auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); auto peer_begin = FlatVector::GetData(lpeer.bounds.data[PEER_BEGIN]); lpeer.rank = (peer_begin[0] - partition_begin[0]) + 1; lpeer.rank_equal = (row_idx - peer_begin[0]); @@ -215,14 +216,14 @@ void WindowPercentRankExecutor::EvaluateInternal(WindowExecutorGlobalState &gsta idx_t row_idx) const { auto &gpeer = gstate.Cast(); auto &lpeer = lstate.Cast(); - auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); - auto partition_end = FlatVector::GetData(lpeer.bounds.data[PARTITION_END]); auto rdata = FlatVector::GetData(result); if (gpeer.token_tree) { + auto frame_begin = FlatVector::GetData(lpeer.bounds.data[FRAME_BEGIN]); + auto frame_end = FlatVector::GetData(lpeer.bounds.data[FRAME_END]); for (idx_t i = 0; i < count; ++i, ++row_idx) { - auto denom = static_cast(NumericCast(partition_end[i] - partition_begin[i] - 1)); - const auto rank = gpeer.token_tree->Rank(partition_begin[i], partition_end[i], row_idx); + auto denom = static_cast(NumericCast(frame_end[i] - frame_begin[i] - 1)); + const auto rank = gpeer.token_tree->Rank(frame_begin[i], frame_end[i], row_idx); double percent_rank = denom > 0 ? ((double)rank - 1) / denom : 0; rdata[i] = percent_rank; } @@ -230,6 +231,8 @@ void WindowPercentRankExecutor::EvaluateInternal(WindowExecutorGlobalState &gsta } // Reset to "previous" row + auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); + auto partition_end = FlatVector::GetData(lpeer.bounds.data[PARTITION_END]); auto peer_begin = FlatVector::GetData(lpeer.bounds.data[PEER_BEGIN]); lpeer.rank = (peer_begin[0] - partition_begin[0]) + 1; lpeer.rank_equal = (row_idx - peer_begin[0]); @@ -254,20 +257,22 @@ void WindowCumeDistExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, DataChunk &eval_chunk, Vector &result, idx_t count, idx_t row_idx) const { auto &gpeer = gstate.Cast(); auto &lpeer = lstate.Cast(); - auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); - auto partition_end = FlatVector::GetData(lpeer.bounds.data[PARTITION_END]); auto rdata = FlatVector::GetData(result); if (gpeer.token_tree) { + auto frame_begin = FlatVector::GetData(lpeer.bounds.data[FRAME_BEGIN]); + auto frame_end = FlatVector::GetData(lpeer.bounds.data[FRAME_END]); for (idx_t i = 0; i < count; ++i, ++row_idx) { - const auto denom = static_cast(NumericCast(partition_end[i] - partition_begin[i])); - const auto peer_end = gpeer.token_tree->PeerEnd(partition_begin[i], partition_end[i], row_idx); - const auto num = static_cast(peer_end - partition_begin[i]); + const auto denom = static_cast(NumericCast(frame_end[i] - frame_begin[i])); + const auto peer_end = gpeer.token_tree->PeerEnd(frame_begin[i], frame_end[i], row_idx); + const auto num = static_cast(peer_end - frame_begin[i]); rdata[i] = denom > 0 ? (num / denom) : 0; } return; } + auto partition_begin = FlatVector::GetData(lpeer.bounds.data[PARTITION_BEGIN]); + auto partition_end = FlatVector::GetData(lpeer.bounds.data[PARTITION_END]); auto peer_end = FlatVector::GetData(lpeer.bounds.data[PEER_END]); for (idx_t i = 0; i < count; ++i, ++row_idx) { const auto denom = static_cast(NumericCast(partition_end[i] - partition_begin[i])); diff --git a/src/function/window/window_rownumber_function.cpp b/src/function/window/window_rownumber_function.cpp index 71f27fa3de03..5d766980ff07 100644 --- a/src/function/window/window_rownumber_function.cpp +++ b/src/function/window/window_rownumber_function.cpp @@ -97,18 +97,19 @@ void WindowRowNumberExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate idx_t row_idx) const { auto &grstate = gstate.Cast(); auto &lrstate = lstate.Cast(); - auto partition_begin = FlatVector::GetData(lrstate.bounds.data[PARTITION_BEGIN]); auto rdata = FlatVector::GetData(result); if (grstate.token_tree) { - auto partition_end = FlatVector::GetData(lrstate.bounds.data[PARTITION_END]); + auto frame_begin = FlatVector::GetData(lrstate.bounds.data[FRAME_BEGIN]); + auto frame_end = FlatVector::GetData(lrstate.bounds.data[FRAME_END]); for (idx_t i = 0; i < count; ++i, ++row_idx) { // Row numbers are unique ranks - rdata[i] = grstate.token_tree->Rank(partition_begin[i], partition_end[i], row_idx); + rdata[i] = grstate.token_tree->Rank(frame_begin[i], frame_end[i], row_idx); } return; } + auto partition_begin = FlatVector::GetData(lrstate.bounds.data[PARTITION_BEGIN]); for (idx_t i = 0; i < count; ++i, ++row_idx) { rdata[i] = row_idx - partition_begin[i] + 1; } @@ -131,6 +132,11 @@ void WindowNtileExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, Wi auto &lrstate = lstate.Cast(); auto partition_begin = FlatVector::GetData(lrstate.bounds.data[PARTITION_BEGIN]); auto partition_end = FlatVector::GetData(lrstate.bounds.data[PARTITION_END]); + if (grstate.token_tree) { + // With secondary sorts, we restrict to the frame boundaries, but everything else should compute the same. + partition_begin = FlatVector::GetData(lrstate.bounds.data[FRAME_BEGIN]); + partition_end = FlatVector::GetData(lrstate.bounds.data[FRAME_END]); + } auto rdata = FlatVector::GetData(result); WindowInputExpression ntile_col(eval_chunk, ntile_idx); for (idx_t i = 0; i < count; ++i, ++row_idx) { diff --git a/src/function/window/window_value_function.cpp b/src/function/window/window_value_function.cpp index d6bd816f28a4..7639b3f16e7d 100644 --- a/src/function/window/window_value_function.cpp +++ b/src/function/window/window_value_function.cpp @@ -273,22 +273,22 @@ WindowLeadLagExecutor::GetLocalState(const WindowExecutorGlobalState &gstate) co void WindowLeadLagExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, WindowExecutorLocalState &lstate, DataChunk &eval_chunk, Vector &result, idx_t count, idx_t row_idx) const { auto &glstate = gstate.Cast(); - auto &ignore_nulls = glstate.ignore_nulls; auto &llstate = lstate.Cast(); auto &cursor = *llstate.cursor; WindowInputExpression leadlag_offset(eval_chunk, offset_idx); WindowInputExpression leadlag_default(eval_chunk, default_idx); - auto partition_begin = FlatVector::GetData(llstate.bounds.data[PARTITION_BEGIN]); - auto partition_end = FlatVector::GetData(llstate.bounds.data[PARTITION_END]); if (glstate.row_tree) { + auto frame_begin = FlatVector::GetData(llstate.bounds.data[FRAME_BEGIN]); + auto frame_end = FlatVector::GetData(llstate.bounds.data[FRAME_END]); + // TODO: Handle subframes. auto &frames = llstate.frames; frames.resize(1); auto &frame = frames[0]; for (idx_t i = 0; i < count; ++i, ++row_idx) { // (1) compute the ROW_NUMBER of the own row - frame = FrameBounds(partition_begin[i], partition_end[i]); + frame = FrameBounds(frame_begin[i], frame_end[i]); const auto own_row = glstate.row_tree->Rank(frame.start, frame.end, row_idx) - 1; // (2) adjust the row number by adding or subtracting an offset auto val_idx = NumericCast(own_row); @@ -317,6 +317,10 @@ void WindowLeadLagExecutor::EvaluateInternal(WindowExecutorGlobalState &gstate, return; } + auto partition_begin = FlatVector::GetData(llstate.bounds.data[PARTITION_BEGIN]); + auto partition_end = FlatVector::GetData(llstate.bounds.data[PARTITION_END]); + + auto &ignore_nulls = glstate.ignore_nulls; bool can_shift = ignore_nulls->AllValid(); if (wexpr.offset_expr) { can_shift = can_shift && wexpr.offset_expr->IsFoldable(); diff --git a/src/include/duckdb/function/cast/bound_cast_data.hpp b/src/include/duckdb/function/cast/bound_cast_data.hpp index 50b4c70abba7..fe950d0d1606 100644 --- a/src/include/duckdb/function/cast/bound_cast_data.hpp +++ b/src/include/duckdb/function/cast/bound_cast_data.hpp @@ -48,21 +48,27 @@ struct ListCast { }; struct StructBoundCastData : public BoundCastData { - StructBoundCastData(vector child_casts, LogicalType target_p, vector child_member_map_p) + StructBoundCastData(vector child_casts, LogicalType target_p, vector source_indexes_p, + vector target_indexes_p, vector target_null_indexes_p) : child_cast_info(std::move(child_casts)), target(std::move(target_p)), - child_member_map(std::move(child_member_map_p)) { - D_ASSERT(child_cast_info.size() == child_member_map.size()); + source_indexes(std::move(source_indexes_p)), target_indexes(std::move(target_indexes_p)), + target_null_indexes(std::move(target_null_indexes_p)) { + D_ASSERT(child_cast_info.size() == source_indexes.size()); + D_ASSERT(source_indexes.size() == target_indexes.size()); } StructBoundCastData(vector child_casts, LogicalType target_p) : child_cast_info(std::move(child_casts)), target(std::move(target_p)) { for (idx_t i = 0; i < child_cast_info.size(); i++) { - child_member_map.push_back(i); + source_indexes.push_back(i); + target_indexes.push_back(i); } } vector child_cast_info; LogicalType target; - vector child_member_map; + vector source_indexes; + vector target_indexes; + vector target_null_indexes; static unique_ptr BindStructToStructCast(BindCastInput &input, const LogicalType &source, const LogicalType &target); @@ -74,7 +80,8 @@ struct StructBoundCastData : public BoundCastData { for (auto &info : child_cast_info) { copy_info.push_back(info.Copy()); } - return make_uniq(std::move(copy_info), target, child_member_map); + return make_uniq(std::move(copy_info), target, source_indexes, target_indexes, + target_null_indexes); } }; diff --git a/src/optimizer/build_probe_side_optimizer.cpp b/src/optimizer/build_probe_side_optimizer.cpp index efd21ed20a44..3847605944a2 100644 --- a/src/optimizer/build_probe_side_optimizer.cpp +++ b/src/optimizer/build_probe_side_optimizer.cpp @@ -54,8 +54,7 @@ static void FlipChildren(LogicalOperator &op) { std::swap(op.children[0], op.children[1]); switch (op.type) { case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: - case LogicalOperatorType::LOGICAL_DELIM_JOIN: - case LogicalOperatorType::LOGICAL_ASOF_JOIN: { + case LogicalOperatorType::LOGICAL_DELIM_JOIN: { auto &join = op.Cast(); join.join_type = InverseJoinType(join.join_type); for (auto &cond : join.conditions) { @@ -242,8 +241,7 @@ void BuildProbeSideOptimizer::VisitOperator(LogicalOperator &op) { } break; } - case LogicalOperatorType::LOGICAL_ANY_JOIN: - case LogicalOperatorType::LOGICAL_ASOF_JOIN: { + case LogicalOperatorType::LOGICAL_ANY_JOIN: { auto &join = op.Cast(); // We do not yet support the RIGHT_SEMI or RIGHT_ANTI join types for these, so don't try to flip switch (join.join_type) { diff --git a/src/optimizer/filter_combiner.cpp b/src/optimizer/filter_combiner.cpp index 2b360c9c6da9..a72354d7df91 100644 --- a/src/optimizer/filter_combiner.cpp +++ b/src/optimizer/filter_combiner.cpp @@ -705,8 +705,26 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(const vector(comparison_type, const_val->value); - conj_filter->child_filters.push_back(std::move(const_filter)); + if (const_val->value.IsNull()) { + switch (comparison_type) { + case ExpressionType::COMPARE_DISTINCT_FROM: { + auto null_filter = make_uniq(); + conj_filter->child_filters.push_back(std::move(null_filter)); + break; + } + case ExpressionType::COMPARE_NOT_DISTINCT_FROM: { + auto null_filter = make_uniq(); + conj_filter->child_filters.push_back(std::move(null_filter)); + break; + } + // if any other comparison type (i.e EQUAL, NOT_EQUAL) do not push a table filter + default: + break; + } + } else { + auto const_filter = make_uniq(comparison_type, const_val->value); + conj_filter->child_filters.push_back(std::move(const_filter)); + } } if (column_id.IsValid()) { optional_filter->child_filter = std::move(conj_filter); @@ -716,8 +734,6 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(const vectorschema); - auto &table = schema.GetEntry(transaction, CatalogType::TABLE_ENTRY, info.table)->Cast(); + auto catalog_table = schema.GetEntry(transaction, CatalogType::TABLE_ENTRY, info.table); + if (!catalog_table) { + // See internal issue 3663. + throw IOException("corrupt database file - index entry without table entry"); + } + auto &table = catalog_table->Cast(); // we also need to make sure the index type is loaded // backwards compatibility: @@ -462,6 +467,7 @@ void CheckpointReader::ReadIndex(CatalogTransaction transaction, Deserializer &d // now we can look for the index in the catalog and assign the table info auto &index = schema.CreateIndex(transaction, info, table)->Cast(); auto &data_table = table.GetStorage(); + auto &table_info = data_table.GetDataTableInfo(); IndexStorageInfo index_storage_info; if (root_block_pointer.IsValid()) { @@ -471,7 +477,7 @@ void CheckpointReader::ReadIndex(CatalogTransaction transaction, Deserializer &d } else { // Read the matching index storage info. - for (auto const &elem : data_table.GetDataTableInfo()->GetIndexStorageInfo()) { + for (auto const &elem : table_info->GetIndexStorageInfo()) { if (elem.name == index.name) { index_storage_info = elem; break; @@ -479,12 +485,13 @@ void CheckpointReader::ReadIndex(CatalogTransaction transaction, Deserializer &d } } - D_ASSERT(index_storage_info.IsValid() && !index_storage_info.name.empty()); + D_ASSERT(index_storage_info.IsValid()); + D_ASSERT(!index_storage_info.name.empty()); // Create an unbound index and add it to the table. auto unbound_index = make_uniq(std::move(create_info), index_storage_info, TableIOManager::Get(data_table), data_table.db); - data_table.GetDataTableInfo()->GetIndexes().AddIndex(std::move(unbound_index)); + table_info->GetIndexes().AddIndex(std::move(unbound_index)); } //===--------------------------------------------------------------------===// diff --git a/test/common/test_cast_struct.test b/test/common/test_cast_struct.test index f1b5eaaa09fb..d3d7f69e09e3 100644 --- a/test/common/test_cast_struct.test +++ b/test/common/test_cast_struct.test @@ -5,106 +5,108 @@ statement ok PRAGMA enable_verification -# struct to struct casts with different names doesn't work statement error -select struct_extract(struct_pack(b=>42)::struct(a integer), 'a'); +SELECT struct_pack(b => 42)::STRUCT(a INT); ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* + +statement error +SELECT struct_extract(struct_pack(b => 42)::STRUCT(a INT), 'a'); +---- +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* query I -select struct_extract(struct_pack(a=>42)::struct(a string), 'a'); +SELECT struct_extract(struct_pack(a => 42)::STRUCT(a STRING), 'a'); ---- 42 -# this all also doesn't works with the row type statement error -select struct_extract(struct_pack(b=>42)::row(a integer), 'a'); +SELECT struct_extract(struct_pack(b => 42)::ROW(a INT), 'a'); ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* query I -select struct_extract(struct_pack(a=>42)::row(a integer), 'a'); +SELECT struct_extract(struct_pack(a => 42)::ROW(a INT), 'a'); ---- 42 -# struct to struct casts with different names AND different types statement error -select struct_extract(struct_pack(b=>42::double)::struct(a integer), 'a'); +SELECT struct_extract(struct_pack(b => 42::DOUBLE)::STRUCT(a INT), 'a'); ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* query I -select struct_extract(struct_pack(a=>42::double)::struct(a integer), 'a'); +SELECT struct_extract(struct_pack(a => 42::DOUBLE)::STRUCT(a INT), 'a'); ---- 42 statement error -select struct_extract(struct_pack(b=>'42'::double)::struct(a integer), 'a'); +SELECT struct_extract(struct_pack(b => '42'::DOUBLE)::STRUCT(a INT), 'a'); ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* query I -select struct_extract(struct_pack(a=>'42'::double)::struct(a integer), 'a'); +SELECT struct_extract(struct_pack(a => '42'::DOUBLE)::STRUCT(a INT), 'a'); ---- 42 statement error -select struct_pack(b=>'42'::double)::struct(a integer, c string) +SELECT struct_pack(b => '42'::DOUBLE)::STRUCT(a INT, c STRING) ---- -Type STRUCT(b DOUBLE) does not match with STRUCT(a INTEGER, c VARCHAR). Cannot cast STRUCTs of different size +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* statement error -select struct_pack(b=>'hello'::string)::struct(b integer) +SELECT struct_pack(b => 'hello'::STRING)::STRUCT(b INT) ---- Could not convert string 'hello' to INT32 statement error -select struct_pack(a=>'hello'::string, b=>'world'::string)::struct(a string, b integer) +SELECT struct_pack(a => 'hello'::STRING, b => 'world'::STRING)::STRUCT(a STRING, b INT) ---- Could not convert string 'world' to INT32 statement error -select struct_pack(a=>[1,2,3])::struct(a integer) +SELECT struct_pack(a => [1, 2, 3])::STRUCT(a INT) ---- Unimplemented type for cast (INTEGER[] -> INTEGER) statement error -select struct_pack(a=>struct_pack(b=>42)::struct(b integer))::struct(a integer) +SELECT struct_pack(a => struct_pack(b => 42)::STRUCT(b INT))::STRUCT(a INT) ---- Unimplemented type for cast (STRUCT(b INTEGER) -> INTEGER) statement error -select struct_pack(b=>'hello'::string)::struct(a integer) +SELECT struct_pack(b => 'hello'::STRING)::STRUCT(a INT) ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* statement error -select struct_pack(b=>'42'::double, c => 'asdf'::string)::struct(a1 integer, a2 string); +SELECT struct_pack(b => '42'::DOUBLE, c => 'asdf'::STRING)::STRUCT(a1 INT, a2 STRING); ---- -element "b" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* query I -select struct_pack(a1 =>'42'::double, a2 => 'asdf'::string)::struct(a1 integer, a2 string); +SELECT struct_pack(a1 => '42'::DOUBLE, a2 => 'asdf'::STRING)::STRUCT(a1 INT, a2 STRING); ---- {'a1': 42, 'a2': asdf} query I -select ROW(42, 'asdf'); +SELECT ROW(42, 'asdf'); ---- (42, asdf) statement error -select ROW(); +SELECT ROW(); ---- -Can't pack nothing into a struct +pack nothing into a struct query I -select ROW(NULL); +SELECT ROW(NULL); ---- (NULL) query I -select ROW(NULL, NULL); +SELECT ROW(NULL, NULL); ---- (NULL, NULL) @@ -115,51 +117,52 @@ SELECT CAST(ROW(1, 2) AS ROW(a INTEGER, b INTEGER)) {'a': 1, 'b': 2} query I -select a::row(a integer, b string) r from (VALUES (ROW(1, 'asdf')), (ROW(4, 'fdsa'))) s(a); +SELECT a::ROW(a INT, b STRING) r FROM (VALUES (ROW(1, 'asdf')), (ROW(4, 'fdsa'))) s(a); ---- {'a': 1, 'b': asdf} {'a': 4, 'b': fdsa} statement error -select struct_extract({'a': a}, a) from (select a::varchar as a from range(10) tbl(a)); +SELECT struct_extract({'a': a}, a) FROM (SELECT a::VARCHAR AS a FROM range(10) tbl(a)); ---- Key name for struct_extract needs to be a constant string statement error -select struct_extract({'a': 42}, 42) +SELECT struct_extract({'a': 42}, 42) ---- can only be used on unnamed structs query I -select struct_extract_at({'a': 42}, 1) +SELECT struct_extract_at({'a': 42}, 1) ---- 42 statement error -select struct_extract_at({'a': 42}, 0) +SELECT struct_extract_at({'a': 42}, 0) ---- out of range statement error -select struct_extract_at({'a': 42}, 42) +SELECT struct_extract_at({'a': 42}, 42) ---- out of range - -# test string to struct within struct casting +# Test string to struct cast within struct casting. query I -SELECT {a:{b:'{a:3, b: "Hello World"}'}}::STRUCT(a STRUCT(b STRUCT(a INT, b VARCHAR))); +SELECT {a: {b: '{a: 3, b: "Hello World"}'}}::STRUCT(a STRUCT(b STRUCT(a INT, b VARCHAR))); ---- {'a': {'b': {'a': 3, 'b': Hello World}}} -# test if try_cast continues after encountering error +# Test if try_cast continues after encountering error. query I -SELECT TRY_CAST(struct_pack(a=>4, b=> 'Ducky', c=>'1964-06-15') AS STRUCT(a INT, b DOUBLE, c DATE)); +SELECT TRY_CAST(struct_pack(a => 4, b => 'Ducky', c => '1964-06-15') +AS STRUCT(a INT, b DOUBLE, c DATE)); ---- {'a': 4, 'b': NULL, 'c': 1964-06-15} query I -SELECT TRY_CAST(struct_pack(a=>4, b=> 'Ducky', c=>'Tommorow', d=>{a:3.0}) AS STRUCT(a VARCHAR[], b VARCHAR, c DATE, d STRUCT(a INT))); +SELECT TRY_CAST(struct_pack(a => 4, b => 'Ducky', c => 'Tommorow', d => {a:3.0}) +AS STRUCT(a VARCHAR[], b VARCHAR, c DATE, d STRUCT(a INT))); ---- {'a': NULL, 'b': Ducky, 'c': NULL, 'd': {'a': 3}} diff --git a/test/fuzzer/public/lateral_join_subquery.test b/test/fuzzer/public/lateral_join_subquery.test index 30a2ce2f3acc..0c47325298d8 100644 --- a/test/fuzzer/public/lateral_join_subquery.test +++ b/test/fuzzer/public/lateral_join_subquery.test @@ -12,3 +12,6 @@ statement error FROM t1 INNER JOIN (SELECT t1.c1) ON (SELECT 42); ---- Subqueries are not supported in LATERAL join conditions + +statement ok +SELECT c01 from values('string') as _(c01), LATERAL ( WITH ta02 AS MATERIALIZED ( SELECT 'string' ) ( SELECT 'string' ) INTERSECT ALL ( SELECT 'string' ) ); diff --git a/test/optimizer/joins/asof_join_adds_rows.test b/test/optimizer/joins/asof_join_adds_rows.test new file mode 100644 index 000000000000..2b15fbcb45a3 --- /dev/null +++ b/test/optimizer/joins/asof_join_adds_rows.test @@ -0,0 +1,112 @@ +# name: test/optimizer/joins/asof_join_adds_rows.test +# description: In the join order optimizer queries need to have the correct bindings +# group: [joins] + +require json + + +statement ok +create table child_join as from values (1) t(c); + +statement ok +create table small_probe as from values +(1, '1992-03-22 01:02:03'::TIMESTAMP), +(1, '1992-03-22 01:02:04'::TIMESTAMP), +(1, '1992-03-22 01:02:05'::TIMESTAMP), +(1, '1992-03-22 01:02:06'::TIMESTAMP), +(1, '1992-03-22 01:02:07'::TIMESTAMP), +(1, '1992-03-22 01:02:08'::TIMESTAMP) t(sp_const, a); + +statement ok +create table large_build as from values +(1, '1992-03-22 01:02:04'::TIMESTAMP), +(1, '1992-03-22 01:02:05'::TIMESTAMP), +(1, '1992-03-22 01:02:06'::TIMESTAMP), +(1, '1992-03-22 01:02:07'::TIMESTAMP), +(1, '1992-03-22 01:02:08'::TIMESTAMP), +(1, '1992-03-22 01:02:09'::TIMESTAMP), +(1, '1992-03-22 01:02:10'::TIMESTAMP), +(1, '1992-03-22 01:02:11'::TIMESTAMP), +(1, '1992-03-22 01:02:12'::TIMESTAMP), +(1, '1992-03-22 01:02:13'::TIMESTAMP), +(1, '1992-03-22 01:02:14'::TIMESTAMP), +(1, '1992-03-22 01:02:15'::TIMESTAMP), +(1, '1992-03-22 01:02:16'::TIMESTAMP), +(1, '1992-03-22 01:02:17'::TIMESTAMP), +(1, '1992-03-22 01:02:18'::TIMESTAMP), +(1, '1992-03-22 01:02:19'::TIMESTAMP), +(1, '1992-03-22 01:02:20'::TIMESTAMP) t(lb_const, b); + +query I +select a from (select * from small_probe, child_join where c=sp_const) asof join large_build on (lb_const = sp_const and a < b) order by a; +---- +1992-03-22 01:02:03 +1992-03-22 01:02:04 +1992-03-22 01:02:05 +1992-03-22 01:02:06 +1992-03-22 01:02:07 +1992-03-22 01:02:08 + + +query IIII +WITH + id_with_timepoint AS ( + SELECT + 'ID1' AS user_id, + '2024-12-23'::TIMESTAMP AS lastSeen + ), + id_and_payload_with_timepoint AS ( + SELECT + 'ID1' AS user_id, + '2024-02-11'::TIMESTAMP AS timepoint, + '{ "amp": [ {"k": "fqn1"}, {"k": "fqn2"}]}'::VARCHAR AS payload + ), + id_with_payload_intermediate AS ( + SELECT + id_with_timepoint.user_id, + id_with_timepoint.lastSeen, + id_and_payload_with_timepoint.payload, + FROM + id_with_timepoint ASOF + LEFT JOIN id_and_payload_with_timepoint ON ( + id_with_timepoint.user_id = id_and_payload_with_timepoint.user_id + AND id_and_payload_with_timepoint.timepoint < id_with_timepoint.lastSeen + ) + ), + id_with_fqn AS ( + SELECT + user_id, + lastSeen, + t.k_fqn + FROM + id_with_payload_intermediate + LEFT JOIN LATERAL UNNEST(payload ->> '$.amp[*].k') AS t (k_fqn) ON TRUE + ), + fqn_table AS ( + SELECT + * + FROM + ( + VALUES + ('fqn2', '2021-03-03'::TIMESTAMP), + ('fqn2', '2021-02-02'::TIMESTAMP), + ('fqn1', '2021-01-01'::TIMESTAMP) + ) AS data (ap_fqn, timepoint) + ) +SELECT + id_with_fqn.user_id, + id_with_fqn.k_fqn, + fqn_table.ap_fqn, + fqn_table.timepoint::TIMESTAMP +FROM + id_with_fqn ASOF + LEFT JOIN fqn_table ON ( + id_with_fqn.k_fqn = fqn_table.ap_fqn + AND fqn_table.timepoint < id_with_fqn.lastSeen + ) +ORDER BY + k_fqn, + timepoint; +---- +ID1 fqn1 fqn1 2021-01-01 00:00:00 +ID1 fqn2 fqn2 2021-03-03 00:00:00 \ No newline at end of file diff --git a/test/optimizer/joins/cross_join_and_unnest_dont_work.test b/test/optimizer/joins/cross_join_and_unnest_dont_work.test index b217d5a53582..ee1eee4acd87 100644 --- a/test/optimizer/joins/cross_join_and_unnest_dont_work.test +++ b/test/optimizer/joins/cross_join_and_unnest_dont_work.test @@ -1,13 +1,112 @@ # name: test/optimizer/joins/cross_join_and_unnest_dont_work.test -# description: Internal issue +# description: In the join order optimizer queries need to have the correct bindings # group: [joins] +require json + + statement ok -SELECT y + z AS c -FROM ( - SELECT y, unnest([x]) AS z - FROM - (SELECT 1 as x), - (SELECT 1 as y) - ) - WHERE c > 0; \ No newline at end of file +create table child_join as from values (1) t(c); + +statement ok +create table small_probe as from values +(1, '1992-03-22 01:02:03'::TIMESTAMP), +(1, '1992-03-22 01:02:04'::TIMESTAMP), +(1, '1992-03-22 01:02:05'::TIMESTAMP), +(1, '1992-03-22 01:02:06'::TIMESTAMP), +(1, '1992-03-22 01:02:07'::TIMESTAMP), +(1, '1992-03-22 01:02:08'::TIMESTAMP) t(sp_const, a); + +statement ok +create table large_build as from values +(1, '1992-03-22 01:02:04'::TIMESTAMP), +(1, '1992-03-22 01:02:05'::TIMESTAMP), +(1, '1992-03-22 01:02:06'::TIMESTAMP), +(1, '1992-03-22 01:02:07'::TIMESTAMP), +(1, '1992-03-22 01:02:08'::TIMESTAMP), +(1, '1992-03-22 01:02:09'::TIMESTAMP), +(1, '1992-03-22 01:02:10'::TIMESTAMP), +(1, '1992-03-22 01:02:11'::TIMESTAMP), +(1, '1992-03-22 01:02:12'::TIMESTAMP), +(1, '1992-03-22 01:02:13'::TIMESTAMP), +(1, '1992-03-22 01:02:14'::TIMESTAMP), +(1, '1992-03-22 01:02:15'::TIMESTAMP), +(1, '1992-03-22 01:02:16'::TIMESTAMP), +(1, '1992-03-22 01:02:17'::TIMESTAMP), +(1, '1992-03-22 01:02:18'::TIMESTAMP), +(1, '1992-03-22 01:02:19'::TIMESTAMP), +(1, '1992-03-22 01:02:20'::TIMESTAMP) t(lb_const, b); + +query I +select a from (select * from small_probe, child_join where c=sp_const) asof join large_build on (lb_const = sp_const and a < b) order by a; +---- +1992-03-22 01:02:03 +1992-03-22 01:02:04 +1992-03-22 01:02:05 +1992-03-22 01:02:06 +1992-03-22 01:02:07 +1992-03-22 01:02:08 + + +query IIII +WITH + id_with_timepoint AS ( + SELECT + 'ID1' AS user_id, + '2024-12-23'::TIMESTAMP AS lastSeen + ), + id_and_payload_with_timepoint AS ( + SELECT + 'ID1' AS user_id, + '2024-02-11'::TIMESTAMP AS timepoint, + '{ "amp": [ {"k": "fqn1"}, {"k": "fqn2"}]}'::VARCHAR AS payload + ), + id_with_payload_intermediate AS ( + SELECT + id_with_timepoint.user_id, + id_with_timepoint.lastSeen, + id_and_payload_with_timepoint.payload, + FROM + id_with_timepoint ASOF + LEFT JOIN id_and_payload_with_timepoint ON ( + id_with_timepoint.user_id = id_and_payload_with_timepoint.user_id + AND id_and_payload_with_timepoint.timepoint < id_with_timepoint.lastSeen + ) + ), + id_with_fqn AS ( + SELECT + user_id, + lastSeen, + t.k_fqn + FROM + id_with_payload_intermediate + LEFT JOIN LATERAL UNNEST(payload ->> '$.amp[*].k') AS t (k_fqn) ON TRUE + ), + fqn_table AS ( + SELECT + * + FROM + ( + VALUES + ('fqn2', '2021-03-03'::TIMESTAMP), + ('fqn2', '2021-02-02'::TIMESTAMP), + ('fqn1', '2021-01-01'::TIMESTAMP) + ) AS data (ap_fqn, timepoint) + ) +SELECT + id_with_fqn.user_id, + id_with_fqn.k_fqn, + fqn_table.ap_fqn, + fqn_table.timepoint::TIMESTAMP +FROM + id_with_fqn ASOF + LEFT JOIN fqn_table ON ( + id_with_fqn.k_fqn = fqn_table.ap_fqn + AND fqn_table.timepoint < id_with_fqn.lastSeen + ) +ORDER BY + k_fqn, + timepoint; +---- +ID1 fqn1 fqn1 2021-01-01 00:00:00 +ID1 fqn2 fqn2 2021-03-03 00:00:00 \ No newline at end of file diff --git a/test/optimizer/pushdown/table_or_pushdown.test b/test/optimizer/pushdown/table_or_pushdown.test index a6433f86782c..769464d37f25 100644 --- a/test/optimizer/pushdown/table_or_pushdown.test +++ b/test/optimizer/pushdown/table_or_pushdown.test @@ -300,6 +300,45 @@ SELECT * FROM integers WHERE a!=1 OR a>3 OR a<2 ORDER by a 4 4 5 5 +# test comparison with null in OR conjunctions uses ISNULL/ISNOTNULL table filter +statement ok +CREATE TABLE t0 as from values (1), (2), (2), (0), (NULL) t(c1); + +# is distinct from NULL +query I +SELECT * FROM t0 WHERE ((t0.c1 IS DISTINCT FROM NULL) OR (NULL)); +---- +1 +2 +2 +0 + +# is not distinct from NULL +query I +SELECT * FROM t0 WHERE ((t0.c1 IS NOT DISTINCT FROM NULL) OR (NULL)); +---- +NULL + +# = NULL in conjunction or +query I +SELECT * FROM t0 WHERE ((t0.c1 = NULL) OR (NULL)); +---- + +query I +SELECT * FROM t0 WHERE ((t0.c1 != NULL) OR (NULL)); +---- + +statement ok +SELECT * FROM t0 WHERE ((t0.c1 = NULL) OR (NOT NULL) OR (t0.c1 = 1)); + +query I +select * from t0 where (NULL OR cast(t0.c1 as bool)) order by all; +---- +1 +2 +2 + + mode skip #### numeric statistics diff --git a/test/sql/cast/cast_error_location.test b/test/sql/cast/cast_error_location.test index eec6206331ab..97a1d5b39339 100644 --- a/test/sql/cast/cast_error_location.test +++ b/test/sql/cast/cast_error_location.test @@ -137,13 +137,13 @@ SELECT l::utinyint[] FROM cast_table ---- ^ -# struct cast statement error -SELECT int_struct::row(x tinyint) FROM cast_table +SELECT int_struct::ROW(x TINYINT) FROM cast_table ---- -^ +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* + +# DOUBLE to FLOAT cast. -# double -> float statement error select dbl::float FROM cast_table ---- diff --git a/test/sql/catalog/dependencies/test_concurrent_index_creation.test b/test/sql/catalog/dependencies/test_concurrent_index_creation.test index 7c008bb96fea..81fa940dcf2f 100644 --- a/test/sql/catalog/dependencies/test_concurrent_index_creation.test +++ b/test/sql/catalog/dependencies/test_concurrent_index_creation.test @@ -4,21 +4,29 @@ require skip_reload +statement ok +ATTACH '__TEST_DIR__/concurrent_index_creation.db' AS source; + concurrentloop i 0 10 -# Create the table statement maybe -create table if not exists tbl (i integer); +CREATE TABLE IF NOT EXISTS source.tbl (i INT); ---- -# Create an index on the table +# Create an index on the table. statement maybe -create index index${i} on tbl (i); +CREATE INDEX index${i} ON source.tbl (i); ---- -# Drop the table (implicitly dropping the index) +# Drop the table and its indexes. statement maybe -drop table tbl; +DROP TABLE source.tbl; ---- endloop + +statement ok +DETACH source; + +statement ok +ATTACH '__TEST_DIR__/concurrent_index_creation.db' AS source; diff --git a/test/sql/setops/test_union_by_name.test b/test/sql/setops/test_union_by_name.test index cf0e0bd751d9..cf468a1a45b5 100644 --- a/test/sql/setops/test_union_by_name.test +++ b/test/sql/setops/test_union_by_name.test @@ -165,12 +165,19 @@ select {'a': '0'} as c union all by name select {'a': 0} as c {'a': 0} {'a': 0} -statement error -select {'a': 'hello'} as c union all by name select {'b': 'hello'} as c; +query I +SELECT {'a': 'hello'} AS c UNION ALL BY NAME SELECT {'b': 'hello'} AS c; ---- -:Mismatch Type Error.*Type STRUCT\(b VARCHAR\) does not match with STRUCT\(a VARCHAR\).* +{'a': hello, 'b': NULL} +{'a': NULL, 'b': hello} -statement error -select {'a': 'hello'} as c union all by name select {'a': 'hello', 'b': 'world'} as c; +query I +SELECT {'a': 'hello'} AS c UNION ALL BY NAME SELECT {'a': 'hello', 'b': 'world'} AS c; +---- +{'a': hello, 'b': NULL} +{'a': hello, 'b': world} + +query I +SELECT [{'a': 42}, {'b': 84}]; ---- -:Mismatch Type Error.*Type STRUCT\(a VARCHAR, b VARCHAR\).*with STRUCT\(a VARCHAR\).* +[{'a': 42, 'b': NULL}, {'a': NULL, 'b': 84}] \ No newline at end of file diff --git a/test/sql/types/struct/struct_cast.test b/test/sql/types/struct/struct_cast.test index 2046e00a3929..94d32f40a1b9 100644 --- a/test/sql/types/struct/struct_cast.test +++ b/test/sql/types/struct/struct_cast.test @@ -152,3 +152,20 @@ AS tab(col) {'duck': NULL} {'duck': NULL} {'duck': NULL} + +# Allow missing / additional STRUCT fields. + +query I +SELECT {'i': 42, 'j': 84}::STRUCT(i INT) AS result; +---- +{'i': 42} + +query I +SELECT {'i': 42}::STRUCT(i INT, j INT) AS result; +---- +{'i': 42, 'j': NULL} + +query I +SELECT {'a': 7, 'i': 42, 'j': 84, 'k': 42}::STRUCT(m INT, k INT, l INT) AS result; +---- +{'m': NULL, 'k': 42, 'l': NULL} diff --git a/test/sql/types/struct/struct_cast_superset.test b/test/sql/types/struct/struct_cast_superset.test new file mode 100644 index 000000000000..ecbf12e684e4 --- /dev/null +++ b/test/sql/types/struct/struct_cast_superset.test @@ -0,0 +1,39 @@ +# name: test/sql/types/struct/struct_cast_superset.test +# description: Test STRUCT cast + UNION BY NAME +# group: [struct] + +require parquet + +statement ok +PRAGMA enable_verification + +statement ok +CREATE TABLE t1 (s1 STRUCT(a INT, b INT)); + +statement ok +INSERT INTO t1 VALUES ({a: 42, b: 43}); + +statement ok +CREATE TABLE t2 (s1 STRUCT(a INT, c INT)); + +statement ok +INSERT INTO t2 VALUES ({a: 100, c: 101}); + +statement ok +COPY t1 TO '__TEST_DIR__/struct_cast_t1.parquet' (FORMAT 'parquet'); + +statement ok +COPY t2 TO '__TEST_DIR__/struct_cast_t2.parquet' (FORMAT 'parquet'); + +query I +SELECT * FROM read_parquet('__TEST_DIR__/struct_cast_*.parquet', union_by_name = TRUE); +---- +{'a': 42, 'b': 43, 'c': NULL} +{'a': 100, 'b': NULL, 'c': 101} + +query I +SELECT {'a': {'e1': 42, 'e2': 42}} AS c +UNION ALL BY NAME SELECT {'a': {'e2': 'hello', 'e3': 'world'}, 'b': '100'} AS c; +---- +{'a': {'e1': 42, 'e2': 42, 'e3': NULL}, 'b': NULL} +{'a': {'e1': NULL, 'e2': hello, 'e3': world}, 'b': 100} \ No newline at end of file diff --git a/test/sql/types/struct/struct_different_names.test b/test/sql/types/struct/struct_different_names.test index e1543bbe3b5c..ce1da2074840 100644 --- a/test/sql/types/struct/struct_different_names.test +++ b/test/sql/types/struct/struct_different_names.test @@ -5,45 +5,50 @@ statement ok PRAGMA enable_verification +statement error +CREATE TABLE wrong AS FROM (VALUES (ROW(3))); +---- +:Invalid Input Error.*A table cannot be created from an unnamed struct.* + statement ok CREATE TABLE t1 (s STRUCT(v VARCHAR)); statement ok INSERT INTO t1 VALUES (ROW(NULL)); +statement error +INSERT INTO t1 VALUES ({c: 34}); +---- +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* + +query I +SELECT s FROM t1 ORDER BY ALL; +---- +{'v': NULL} + statement ok CREATE TABLE foo (bar struct(pip int)); statement error INSERT INTO foo VALUES ({'ignoreme': 3}); ---- -element "ignoreme" in source struct was not found in target struct - -statement error -create table wrong as from (VALUES (ROW(3))); ----- -Invalid Input Error: A table cannot be created from an unnamed struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* statement ok INSERT INTO foo VALUES (ROW(42)); query I -SELECT * FROM foo; +SELECT bar FROM foo ORDER BY ALL; ---- {'pip': 42} statement ok -CREATE OR REPLACE TABLE T AS SELECT [{'a': 'A', 'b':'B'}] as x, [{'b':'BB','a':'AA'}] as y; +CREATE OR REPLACE TABLE T AS SELECT [{'a': 'A', 'b':'B'}] AS x, [{'b':'BB','a':'AA'}] AS y; -statement error +query III SELECT x, y, ARRAY_CONCAT(x, y) FROM T; ---- -an explicit cast is required - -statement error -INSERT INTO t1 VALUES ({c: 34}); ----- -element "c" in source struct was not found in target struct +[{'a': A, 'b': B}] [{'b': BB, 'a': AA}] [{'a': A, 'b': B}, {'a': AA, 'b': BB}] statement ok CREATE OR REPLACE TABLE T (s STRUCT(a INT, b INT)); @@ -51,34 +56,37 @@ CREATE OR REPLACE TABLE T (s STRUCT(a INT, b INT)); statement error INSERT INTO T VALUES ({l: 1, m: 2}), ({x: 3, y: 4}); ---- -element "l" in source struct was not found in target struct +:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.* + +query I +SELECT s FROM T ORDER BY ALL; +---- -# Can insert unnamed struct into named struct +# Can insert an unnamed STRUCT into a named STRUCT. statement ok -create table tbl (a STRUCT(a int, b varchar)); +CREATE TABLE tbl (a STRUCT(a INT, b VARCHAR)); statement ok -insert into tbl VALUES(ROW(5, 'hello')); +INSERT INTO tbl VALUES (ROW(5, 'hello')); -# Can insert named struct into unnamed struct statement error -create table tbl2 as select ROW(42, 'world') a; +CREATE TABLE tbl2 AS SELECT ROW(42, 'world') a; ---- -Invalid Input Error: A table cannot be created from an unnamed struct +:Invalid Input Error.*A table cannot be created from an unnamed struct.* -statement error +query I SELECT [{'foo': True}, {'bar': False}, {'foobar': NULL}]; ---- -an explicit cast is required +[{'foo': true, 'bar': NULL, 'foobar': NULL}, {'foo': NULL, 'bar': false, 'foobar': NULL}, {'foo': NULL, 'bar': NULL, 'foobar': NULL}] -statement error -select [(13,24), {'a': 42, 'b': 84}, (43, 85), {'b':10, 'a':123123}] as res; +query I +select [(13, 24), {'a': 42, 'b': 84}, (43, 85), {'b': 10, 'a': 123123}] AS res; ---- -an explicit cast is required +[{'a': 13, 'b': 24}, {'a': 42, 'b': 84}, {'a': 43, 'b': 85}, {'a': 123123, 'b': 10}] statement ok -PREPARE v1 as SELECT ROW(?); +PREPARE v1 AS SELECT ROW(?); statement ok EXECUTE v1(42); diff --git a/test/sql/types/struct/struct_named_cast.test b/test/sql/types/struct/struct_named_cast.test index f64d0c514137..868f8555127d 100644 --- a/test/sql/types/struct/struct_named_cast.test +++ b/test/sql/types/struct/struct_named_cast.test @@ -22,11 +22,10 @@ SELECT {'a': ['1', '2', '3'], 'b': 84}::STRUCT(b INT, A INT[]) ---- {'b': 84, 'A': [1, 2, 3]} -# name mismatch -statement error +query I SELECT {'a': ['1', '2', '3'], 'b': 84}::STRUCT(b INT, c INT[]) ---- -element "a" in source struct was not found in target struct +{'b': 84, 'c': NULL} # unnamed struct cast query I diff --git a/test/sql/window/test_cume_dist_orderby.test b/test/sql/window/test_cume_dist_orderby.test index cbc1f3ec57e7..ee91b0d712e6 100644 --- a/test/sql/window/test_cume_dist_orderby.test +++ b/test/sql/window/test_cume_dist_orderby.test @@ -17,13 +17,13 @@ WINDOW w AS ( ) ORDER BY inside DESC, i ---- -8 1 4 0.2 -9 8 4 0.2 -6 9 3 0.4 +8 1 4 0.5 +9 8 4 0.25 +6 9 3 0.4444444444444444 7 5 3 0.4 -4 6 2 0.6 -5 2 2 0.6 -2 3 1 0.8 +4 6 2 0.6666666666666666 +5 2 2 0.6666666666666666 +2 3 1 0.75 3 10 1 0.8 0 0 0 1.0 1 7 0 1.0 diff --git a/test/sql/window/test_leadlag_orderby.test b/test/sql/window/test_leadlag_orderby.test index 562fee22b88b..0e1ddae5c713 100644 --- a/test/sql/window/test_leadlag_orderby.test +++ b/test/sql/window/test_leadlag_orderby.test @@ -18,13 +18,13 @@ WINDOW w AS ( ) ORDER BY inside DESC, i ---- -8 1 4 9 NULL -9 8 4 6 8 +8 1 4 0 NULL +9 8 4 7 8 6 9 3 7 9 -7 5 3 4 6 +7 5 3 5 8 4 6 2 5 7 -5 2 2 2 4 -2 3 1 3 5 +5 2 2 0 8 +2 3 1 0 5 3 10 1 0 2 -0 0 0 1 3 +0 0 0 NULL NULL 1 7 0 NULL 0 diff --git a/test/sql/window/test_rank_orderby.test b/test/sql/window/test_rank_orderby.test index 6b483d726291..c8edf5c93a7f 100644 --- a/test/sql/window/test_rank_orderby.test +++ b/test/sql/window/test_rank_orderby.test @@ -17,15 +17,15 @@ WINDOW w AS ( ) ORDER BY 2 ---- -0 0 9 0.8888888888888888 +0 0 1 0.0 8 1 1 0.0 -5 2 5 0.4444444444444444 -2 3 7 0.6666666666666666 -7 5 3 0.2222222222222222 -4 6 5 0.4444444444444444 -1 7 9 0.8888888888888888 +5 2 2 0.5 +2 3 3 0.6666666666666666 +7 5 2 0.25 +4 6 3 0.4 +1 7 6 0.8333333333333334 9 8 1 0.0 -6 9 3 0.2222222222222222 +6 9 3 0.25 3 10 7 0.6666666666666666 # Test parallel token construction (uses 4 threads) @@ -41,6 +41,7 @@ WITH ranked AS ( WINDOW w AS ( PARTITION BY i // 100 ORDER BY i + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) ) SELECT * diff --git a/test/sql/window/test_rownumber_orderby.test b/test/sql/window/test_rownumber_orderby.test index 0854efd61c92..43dec858f062 100644 --- a/test/sql/window/test_rownumber_orderby.test +++ b/test/sql/window/test_rownumber_orderby.test @@ -17,13 +17,13 @@ WINDOW w AS ( ) ORDER BY 2 ---- -0 0 9 4 +0 0 1 1 8 1 1 1 -5 2 5 2 -2 3 7 3 -7 5 3 1 -4 6 6 2 -1 7 10 4 +5 2 2 2 +2 3 3 3 +7 5 2 1 +4 6 4 2 +1 7 7 4 9 8 2 1 6 9 4 2 3 10 8 3 diff --git a/test/sql/window/test_tpcc_results.test b/test/sql/window/test_tpcc_results.test new file mode 100644 index 000000000000..e45918a8cb2a --- /dev/null +++ b/test/sql/window/test_tpcc_results.test @@ -0,0 +1,419 @@ +# name: test/sql/window/test_tpcc_results.test +# description: Framed secondary ordering test from Vogelsgesang et al. §2.4 +# group: [window] + +statement ok +PRAGMA enable_verification + +# Version 5 Results As of 23-Dec-2024 at 7:54 PM [GMT] +# https://www.tpc.org/tpcc/results/tpcc_results5.asp +query IIIIIIIII +select + submission_date, + dbsystem, + tps, + count(distinct dbsystem) over w AS competing, + rank(order by tps desc) over w AS new_rank, + first_value(tps order by tps desc) over w AS best_performance, + first_value(dbsystem order by tps desc) over w AS best_system, + lead(tps order by tps desc) over w AS second_performance, + lead(dbsystem order by tps desc) over w AS second_system, +from 'data/csv/tpcc_results.csv' +window w as ( + order by submission_date + range between unbounded preceding and current row +) +ORDER BY submission_date; +---- +2000-06-21 Sybase Adaptive Server Enterprise 12.0 60366.82 1 1 60366.82 Sybase Adaptive Server Enterprise 12.0 NULL NULL +2001-03-19 Microsoft SQL Server 2000 30231.37 3 4 163775.8 IBM DB2 for AS/400 V4 R5 30231.37 Microsoft SQL Server 2000 +2001-03-19 Microsoft SQL Server 2000 20320.7 3 9 163775.8 IBM DB2 for AS/400 V4 R5 NULL NULL +2001-03-19 Microsoft SQL Server 2000 24925.43 3 6 163775.8 IBM DB2 for AS/400 V4 R5 24925.43 Microsoft SQL Server 2000 +2001-03-19 Microsoft SQL Server 2000 24925.43 3 6 163775.8 IBM DB2 for AS/400 V4 R5 20331.91 Microsoft SQL Server 2000 +2001-03-19 Microsoft SQL Server 2000 20331.91 3 8 163775.8 IBM DB2 for AS/400 V4 R5 20320.7 Microsoft SQL Server 2000 +2001-03-19 Microsoft SQL Server 2000 30231.37 3 4 163775.8 IBM DB2 for AS/400 V4 R5 24925.43 Microsoft SQL Server 2000 +2001-03-19 IBM DB2 for AS/400 V4 R5 163775.8 3 1 163775.8 IBM DB2 for AS/400 V4 R5 152346.25 IBM DB2 for AS/400 V4 R5 +2001-03-19 IBM DB2 for AS/400 V4 R5 152346.25 3 2 163775.8 IBM DB2 for AS/400 V4 R5 60366.82 Sybase Adaptive Server Enterprise 12.0 +2001-03-20 Oracle 8 Enterprise Edition v8.1.7.1 66750.27 4 3 163775.8 IBM DB2 for AS/400 V4 R5 60366.82 Sybase Adaptive Server Enterprise 12.0 +2001-03-27 Microsoft SQL Server 2000 37383.57 4 5 163775.8 IBM DB2 for AS/400 V4 R5 30231.37 Microsoft SQL Server 2000 +2001-03-30 Microsoft SQL Server 2000 16262.9 4 12 163775.8 IBM DB2 for AS/400 V4 R5 NULL NULL +2001-04-02 Microsoft SQL Server 2000 57014.93 4 5 163775.8 IBM DB2 for AS/400 V4 R5 37383.57 Microsoft SQL Server 2000 +2001-04-03 Oracle 8i Enterprise Edition v. 8.1.7 155179.25 6 2 163775.8 IBM DB2 for AS/400 V4 R5 152346.25 IBM DB2 for AS/400 V4 R5 +2001-04-03 Oracle 8 Enterprise Edition v8.1.7.1 71863.02 6 4 163775.8 IBM DB2 for AS/400 V4 R5 66750.27 Oracle 8 Enterprise Edition v8.1.7.1 +2001-04-03 Sybase Adaptive Server Enterprise 12.0.0.3 37274.0 6 9 163775.8 IBM DB2 for AS/400 V4 R5 37274.0 Sybase Adaptive Server Enterprise 12.0.0.3 +2001-04-03 Sybase Adaptive Server Enterprise 12.0.0.3 37274.0 6 9 163775.8 IBM DB2 for AS/400 V4 R5 30231.37 Microsoft SQL Server 2000 +2001-04-05 Sybase Adaptive Server Enterprise 11.9.3 22422.5 7 18 163775.8 IBM DB2 for AS/400 V4 R5 20331.91 Microsoft SQL Server 2000 +2001-04-05 Sybase Adaptive Server Enterprise 11.9.3 49308.0 7 9 163775.8 IBM DB2 for AS/400 V4 R5 37383.57 Microsoft SQL Server 2000 +2001-04-05 Sybase Adaptive Server Enterprise 12.0 60366.82 7 6 163775.8 IBM DB2 for AS/400 V4 R5 57014.93 Microsoft SQL Server 2000 +2001-04-05 Sybase Adaptive Server Enterprise 12.0 34288.77 7 13 163775.8 IBM DB2 for AS/400 V4 R5 30231.37 Microsoft SQL Server 2000 +2001-04-10 Microsoft SQL Server 2000 688220.9 7 1 688220.9 Microsoft SQL Server 2000 163775.8 IBM DB2 for AS/400 V4 R5 +2001-04-10 Microsoft SQL Server 2000 121319.23 7 5 688220.9 Microsoft SQL Server 2000 71863.02 Oracle 8 Enterprise Edition v8.1.7.1 +2001-04-11 IBM DB2 UDB 7.1 440879.95 8 3 688220.9 Microsoft SQL Server 2000 440879.95 IBM DB2 UDB 7.1 +2001-04-11 Microsoft SQL Server 2000 363129.75 8 5 688220.9 Microsoft SQL Server 2000 163775.8 IBM DB2 for AS/400 V4 R5 +2001-04-11 Microsoft SQL Server 2000 688220.9 8 1 688220.9 Microsoft SQL Server 2000 440879.95 IBM DB2 UDB 7.1 +2001-04-11 IBM DB2 UDB 7.1 440879.95 8 3 688220.9 Microsoft SQL Server 2000 363129.75 Microsoft SQL Server 2000 +2001-04-12 Microsoft SQL Server 2000 Enterprise Edition 34264.9 9 20 688220.9 Microsoft SQL Server 2000 32377.17 Microsoft SQL Server 2000 +2001-04-12 Microsoft SQL Server 2000 32377.17 9 21 688220.9 Microsoft SQL Server 2000 30231.37 Microsoft SQL Server 2000 +2001-04-13 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 222772.33 10 6 688220.9 Microsoft SQL Server 2000 163775.8 IBM DB2 for AS/400 V4 R5 +2001-04-23 Oracle Database 9i Enterprise Edition v.9.0.1 57346.93 11 15 688220.9 Microsoft SQL Server 2000 57014.93 Microsoft SQL Server 2000 +2001-04-24 Microsoft SQL Server 2000 136766.67 11 10 688220.9 Microsoft SQL Server 2000 121319.23 Microsoft SQL Server 2000 +2001-05-22 Microsoft SQL Server 2000 Enterprise Edition 52671.3 11 18 688220.9 Microsoft SQL Server 2000 49308.0 Sybase Adaptive Server Enterprise 11.9.3 +2001-05-28 Oracle 8i Enterprise Edition v. 8.1.7 66750.27 11 14 688220.9 Microsoft SQL Server 2000 60366.82 Sybase Adaptive Server Enterprise 12.0 +2001-05-28 Oracle 8i Enterprise Edition v. 8.1.7 220807.27 11 7 688220.9 Microsoft SQL Server 2000 163775.8 IBM DB2 for AS/400 V4 R5 +2001-06-18 Oracle Database 9i Enterprise Edition 230533.0 12 6 688220.9 Microsoft SQL Server 2000 222772.33 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2001-06-22 Oracle 8i Enterprise Edition v. 8.1.7 66750.27 12 16 688220.9 Microsoft SQL Server 2000 60366.82 Sybase Adaptive Server Enterprise 12.0 +2001-06-22 Oracle 8i Enterprise Edition v. 8.1.7 220807.27 12 8 688220.9 Microsoft SQL Server 2000 163775.8 IBM DB2 for AS/400 V4 R5 +2001-07-03 Oracle Database 9i Enterprise Edition v.9i.0.1 57346.93 13 21 688220.9 Microsoft SQL Server 2000 57014.93 Microsoft SQL Server 2000 +2001-07-27 Microsoft SQL Server 2000 20207.2 13 39 688220.9 Microsoft SQL Server 2000 16262.9 Microsoft SQL Server 2000 +2001-08-22 Microsoft SQL Server 2000 Enterprise Edition 69901.74 13 16 688220.9 Microsoft SQL Server 2000 66750.27 Oracle 8 Enterprise Edition v8.1.7.1 +2001-08-23 Microsoft SQL Server 2000 Enterprise Edition 37596.34 13 28 688220.9 Microsoft SQL Server 2000 37383.57 Microsoft SQL Server 2000 +2001-08-23 Microsoft SQL Server 2000 Enterprise Edition 43046.55 13 27 688220.9 Microsoft SQL Server 2000 37596.34 Microsoft SQL Server 2000 Enterprise Edition +2001-08-28 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 455818.2 13 3 688220.9 Microsoft SQL Server 2000 440879.95 IBM DB2 UDB 7.1 +2001-09-10 Oracle Database 9i Enterprise Edition v.9i.0.1 105025.02 13 17 688220.9 Microsoft SQL Server 2000 71863.02 Oracle 8 Enterprise Edition v8.1.7.1 +2001-09-10 Microsoft SQL Server 2000 Enterprise Edition 141138.44 13 14 688220.9 Microsoft SQL Server 2000 136766.67 Microsoft SQL Server 2000 +2001-09-19 Microsoft SQL Server 2000 Enterprise Edition 410769.88 13 8 709220.08 Microsoft SQL Server 2000 Enterprise Edition 363129.75 Microsoft SQL Server 2000 +2001-09-19 Microsoft SQL Server 2000 Enterprise Edition 567882.56 13 4 709220.08 Microsoft SQL Server 2000 Enterprise Edition 455818.2 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2001-09-19 Microsoft SQL Server 2000 Enterprise Edition 709220.08 13 1 709220.08 Microsoft SQL Server 2000 Enterprise Edition 688220.9 Microsoft SQL Server 2000 +2001-09-25 Microsoft SQL Server 2000 9347.24 13 51 709220.08 Microsoft SQL Server 2000 Enterprise Edition NULL NULL +2001-09-25 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 67102.53 13 23 709220.08 Microsoft SQL Server 2000 Enterprise Edition 66750.27 Oracle 8 Enterprise Edition v8.1.7.1 +2001-09-26 Oracle Database 9i Enterprise Edition v.9i.0.1 105025.02 13 20 709220.08 Microsoft SQL Server 2000 Enterprise Edition 71863.02 Oracle 8 Enterprise Edition v8.1.7.1 +2001-09-26 Microsoft SQL Server 2000 Enterprise Edition 17335.75 13 51 709220.08 Microsoft SQL Server 2000 Enterprise Edition 16262.9 Microsoft SQL Server 2000 +2001-09-27 Microsoft SQL Server 2000 Enterprise Edition 39158.09 13 36 709220.08 Microsoft SQL Server 2000 Enterprise Edition 37596.34 Microsoft SQL Server 2000 Enterprise Edition +2001-10-01 Microsoft SQL Server 2000 20422.01 13 49 709220.08 Microsoft SQL Server 2000 Enterprise Edition 20331.91 Microsoft SQL Server 2000 +2001-10-16 Microsoft SQL Server 2000 Standard Edition 9112.91 14 56 709220.08 Microsoft SQL Server 2000 Enterprise Edition NULL NULL +2001-10-25 Microsoft SQL Server 2000 Enterprise Edition 22007.12 14 49 709220.08 Microsoft SQL Server 2000 Enterprise Edition 20422.01 Microsoft SQL Server 2000 +2001-10-31 Microsoft SQL Server 2000 Standard Edition 11320.02 14 56 709220.08 Microsoft SQL Server 2000 Enterprise Edition 9347.24 Microsoft SQL Server 2000 +2001-11-05 Microsoft SQL Server 2000 Standard Edition 15533.72 14 56 709220.08 Microsoft SQL Server 2000 Enterprise Edition 11320.02 Microsoft SQL Server 2000 Standard Edition +2001-11-11 Microsoft SQL Server 2000 Enterprise Edition 165218.71 14 14 709220.08 Microsoft SQL Server 2000 Enterprise Edition 165218.71 Microsoft SQL Server 2000 Enterprise Edition +2001-11-11 Microsoft SQL Server 2000 Enterprise Edition 165218.71 14 14 709220.08 Microsoft SQL Server 2000 Enterprise Edition 163775.8 IBM DB2 for AS/400 V4 R5 +2001-11-12 Microsoft SQL Server 2000 Enterprise Edition 37100.52 14 43 709220.08 Microsoft SQL Server 2000 Enterprise Edition 34288.77 Sybase Adaptive Server Enterprise 12.0 +2001-12-14 Microsoft SQL Server 2000 Standard Edition 11314.11 14 61 709220.08 Microsoft SQL Server 2000 Enterprise Edition 9347.24 Microsoft SQL Server 2000 +2001-12-21 Oracle 8 Enterprise Edition v8.1.7.1 197024.17 15 15 709220.08 Microsoft SQL Server 2000 Enterprise Edition 165218.71 Microsoft SQL Server 2000 Enterprise Edition +2001-12-21 Sybase Adaptive Server Enterprise v12.5 140239.97 15 22 709220.08 Microsoft SQL Server 2000 Enterprise Edition 136766.67 Microsoft SQL Server 2000 +2001-12-21 Oracle Database 9i Enterprise Edition 389434.4 15 9 709220.08 Microsoft SQL Server 2000 Enterprise Edition 363129.75 Microsoft SQL Server 2000 +2002-01-28 Oracle Database 9i R2 Enterprise Edition for Tru64 Unix 50117.0 16 39 709220.08 Microsoft SQL Server 2000 Enterprise Edition 49308.0 Sybase Adaptive Server Enterprise 11.9.3 +2002-02-08 Microsoft SQL Server 2000 Enterprise Edition 29860.12 16 53 709220.08 Microsoft SQL Server 2000 Enterprise Edition 24925.43 Microsoft SQL Server 2000 +2002-02-13 Microsoft SQL Server 2000 Standard Edition 17078.88 16 63 709220.08 Microsoft SQL Server 2000 Enterprise Edition 16262.9 Microsoft SQL Server 2000 +2002-02-25 Microsoft SQL Server 2000 Enterprise Edition 33768.41 16 51 709220.08 Microsoft SQL Server 2000 Enterprise Edition 32377.17 Microsoft SQL Server 2000 +2002-02-25 Microsoft SQL Server 2000 Enterprise Edition 69169.61 16 29 709220.08 Microsoft SQL Server 2000 Enterprise Edition 67102.53 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2002-03-11 Microsoft SQL Server 2000 Enterprise Edition 55138.6 16 39 709220.08 Microsoft SQL Server 2000 Enterprise Edition 52671.3 Microsoft SQL Server 2000 Enterprise Edition +2002-03-11 Microsoft SQL Server 2000 Standard Edition 23027.66 16 59 709220.08 Microsoft SQL Server 2000 Enterprise Edition 22422.5 Sybase Adaptive Server Enterprise 11.9.3 +2002-03-12 Microsoft SQL Server 2000 Standard Edition 11537.02 16 72 709220.08 Microsoft SQL Server 2000 Enterprise Edition 11537.02 Microsoft SQL Server 2000 Standard Edition +2002-03-12 Microsoft SQL Server 2000 Standard Edition 11537.02 16 72 709220.08 Microsoft SQL Server 2000 Enterprise Edition 11320.02 Microsoft SQL Server 2000 Standard Edition +2002-03-12 Microsoft SQL Server 2000 Enterprise Edition 48906.18 16 44 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43046.55 Microsoft SQL Server 2000 Enterprise Edition +2002-03-12 Sybase Adaptive Server Enterprise v12.5 112286.46 16 25 709220.08 Microsoft SQL Server 2000 Enterprise Edition 105025.02 Oracle Database 9i Enterprise Edition v.9i.0.1 +2002-04-23 Microsoft SQL Server 2000 Enterprise Edition 34473.15 16 52 709220.08 Microsoft SQL Server 2000 Enterprise Edition 34473.15 Microsoft SQL Server 2000 Enterprise Edition +2002-04-23 Microsoft SQL Server 2000 Enterprise Edition 34473.15 16 52 709220.08 Microsoft SQL Server 2000 Enterprise Edition 34288.77 Sybase Adaptive Server Enterprise 12.0 +2002-05-17 Microsoft SQL Server 2000 Enterprise Edition 48911.83 16 44 709220.08 Microsoft SQL Server 2000 Enterprise Edition 48906.18 Microsoft SQL Server 2000 Enterprise Edition +2002-05-24 Microsoft SQL Server 2000 Enterprise Edition 48906.18 16 45 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43046.55 Microsoft SQL Server 2000 Enterprise Edition +2002-06-01 Microsoft SQL Server 2000 Enterprise Edition 34819.03 16 55 709220.08 Microsoft SQL Server 2000 Enterprise Edition 34473.15 Microsoft SQL Server 2000 Enterprise Edition +2002-06-01 Microsoft SQL Server 2000 Enterprise Edition 34914.92 16 54 709220.08 Microsoft SQL Server 2000 Enterprise Edition 34819.03 Microsoft SQL Server 2000 Enterprise Edition +2002-06-03 Oracle Database 9i R2 Enterprise Edition 403255.46 17 9 709220.08 Microsoft SQL Server 2000 Enterprise Edition 389434.4 Oracle Database 9i Enterprise Edition +2002-06-03 Microsoft SQL Server 2000 Standard Edition 12009.46 17 79 709220.08 Microsoft SQL Server 2000 Enterprise Edition 11537.02 Microsoft SQL Server 2000 Standard Edition +2002-06-04 Oracle Database 9i R2 Enterprise Edition 137260.89 17 24 709220.08 Microsoft SQL Server 2000 Enterprise Edition 136766.67 Microsoft SQL Server 2000 +2002-06-20 Microsoft SQL Server 2000 Enterprise Edition 48150.72 17 49 709220.08 Microsoft SQL Server 2000 Enterprise Edition 48150.72 Microsoft SQL Server 2000 Enterprise Edition +2002-06-20 Microsoft SQL Server 2000 Enterprise Edition 48150.72 17 49 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43046.55 Microsoft SQL Server 2000 Enterprise Edition +2002-06-26 Microsoft SQL Server 2000 Standard Edition 12579.04 17 82 709220.08 Microsoft SQL Server 2000 Enterprise Edition 12009.46 Microsoft SQL Server 2000 Standard Edition +2002-07-08 Microsoft SQL Server 2000 Enterprise Edition 64bit 78454.76 18 30 709220.08 Microsoft SQL Server 2000 Enterprise Edition 71863.02 Oracle 8 Enterprise Edition v8.1.7.1 +2002-07-08 Microsoft SQL Server 2000 Enterprise Edition 64bit 40621.26 18 53 709220.08 Microsoft SQL Server 2000 Enterprise Edition 39158.09 Microsoft SQL Server 2000 Enterprise Edition +2002-07-17 Microsoft SQL Server 2000 Enterprise Edition 45230.03 18 52 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43046.55 Microsoft SQL Server 2000 Enterprise Edition +2002-07-22 Microsoft SQL Server 2000 Enterprise Edition 92398.49 18 30 709220.08 Microsoft SQL Server 2000 Enterprise Edition 78454.76 Microsoft SQL Server 2000 Enterprise Edition 64bit +2002-07-25 Microsoft SQL Server 2000 Standard Edition 17659.53 18 82 709220.08 Microsoft SQL Server 2000 Enterprise Edition 17335.75 Microsoft SQL Server 2000 Enterprise Edition +2002-07-26 Microsoft SQL Server 2000 Enterprise Edition SP2 33768.41 19 68 709220.08 Microsoft SQL Server 2000 Enterprise Edition 32377.17 Microsoft SQL Server 2000 +2002-08-05 Sybase Adaptive Server Enterprise v12.5 56375.0 19 44 709220.08 Microsoft SQL Server 2000 Enterprise Edition 55138.6 Microsoft SQL Server 2000 Enterprise Edition +2002-08-13 Microsoft SQL Server 2000 Standard Edition SP3 10089.76 20 95 709220.08 Microsoft SQL Server 2000 Enterprise Edition 9347.24 Microsoft SQL Server 2000 +2002-08-15 Oracle Database 9i R2 Enterprise Edition 403255.46 20 9 709220.08 Microsoft SQL Server 2000 Enterprise Edition 389434.4 Oracle Database 9i Enterprise Edition +2002-08-16 Microsoft SQL Server 2000 Standard Edition SP3 17559.31 20 86 709220.08 Microsoft SQL Server 2000 Enterprise Edition 17335.75 Microsoft SQL Server 2000 Enterprise Edition +2002-08-20 Microsoft SQL Server 2000 Enterprise Edition SP2 61168.83 20 40 709220.08 Microsoft SQL Server 2000 Enterprise Edition 60366.82 Sybase Adaptive Server Enterprise 12.0 +2002-08-23 Microsoft SQL Server 2000 Enterprise Edition 61564.5 20 40 709220.08 Microsoft SQL Server 2000 Enterprise Edition 61168.83 Microsoft SQL Server 2000 Enterprise Edition SP2 +2002-08-26 Oracle Database 9i Enterprise Server v.9.2.0.1 423414.41 21 8 709220.08 Microsoft SQL Server 2000 Enterprise Edition 410769.88 Microsoft SQL Server 2000 Enterprise Edition +2002-09-11 Microsoft SQL Server 2000 Enterprise Edition 16756.52 21 92 709220.08 Microsoft SQL Server 2000 Enterprise Edition 16262.9 Microsoft SQL Server 2000 +2002-09-16 Oracle Database 9i R2 Enterprise Edition 138362.03 21 26 709220.08 Microsoft SQL Server 2000 Enterprise Edition 137260.89 Oracle Database 9i R2 Enterprise Edition +2002-10-07 Microsoft SQL Server 2000 Enterprise Edition SP3 84598.42 22 34 709220.08 Microsoft SQL Server 2000 Enterprise Edition 78454.76 Microsoft SQL Server 2000 Enterprise Edition 64bit +2002-10-30 Microsoft SQL Server 2000 Enterprise Edition 51069.87 22 53 709220.08 Microsoft SQL Server 2000 Enterprise Edition 50117.0 Oracle Database 9i R2 Enterprise Edition for Tru64 Unix +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition SP3 68264.47 22 44 709220.08 Microsoft SQL Server 2000 Enterprise Edition 67102.53 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition SP3 111805.22 22 32 709220.08 Microsoft SQL Server 2000 Enterprise Edition 111024.39 Microsoft SQL Server 2000 Enterprise Edition SP3 +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition SP3 68739.22 22 43 709220.08 Microsoft SQL Server 2000 Enterprise Edition 68264.47 Microsoft SQL Server 2000 Enterprise Edition SP3 +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition SP3 74206.27 22 39 709220.08 Microsoft SQL Server 2000 Enterprise Edition 71863.02 Oracle 8 Enterprise Edition v8.1.7.1 +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition SP3 111024.39 22 33 709220.08 Microsoft SQL Server 2000 Enterprise Edition 105025.02 Oracle Database 9i Enterprise Edition v.9i.0.1 +2002-11-04 Microsoft SQL Server 2000 Enterprise Edition 203518.03 22 18 709220.08 Microsoft SQL Server 2000 Enterprise Edition 197024.17 Oracle 8 Enterprise Edition v8.1.7.1 +2002-11-08 Microsoft SQL Server 2000 Enterprise Edition SP3 112740.87 22 31 709220.08 Microsoft SQL Server 2000 Enterprise Edition 112286.46 Sybase Adaptive Server Enterprise v12.5 +2002-11-12 Oracle Database 10i Standard Edition 80494.98 23 39 709220.08 Microsoft SQL Server 2000 Enterprise Edition 78454.76 Microsoft SQL Server 2000 Enterprise Edition 64bit +2002-11-13 Oracle Database 10i Standard Edition 80570.81 23 39 709220.08 Microsoft SQL Server 2000 Enterprise Edition 80494.98 Oracle Database 10i Standard Edition +2002-11-19 Microsoft SQL Server 2000 Enterprise Edition SP3 77905.18 23 42 709220.08 Microsoft SQL Server 2000 Enterprise Edition 74206.27 Microsoft SQL Server 2000 Enterprise Edition SP3 +2002-11-19 Microsoft SQL Server 2000 Standard Edition SP3 18051.65 23 101 709220.08 Microsoft SQL Server 2000 Enterprise Edition 17659.53 Microsoft SQL Server 2000 Standard Edition +2002-12-04 Microsoft SQL Server 2000 Standard Edition SP3 18077.98 23 101 709220.08 Microsoft SQL Server 2000 Enterprise Edition 18051.65 Microsoft SQL Server 2000 Standard Edition SP3 +2002-12-06 Microsoft SQL Server 2000 Enterprise Edition SP3 115025.75 23 31 709220.08 Microsoft SQL Server 2000 Enterprise Edition 112740.87 Microsoft SQL Server 2000 Enterprise Edition SP3 +2002-12-09 Microsoft SQL Server 2000 Enterprise Edition 234325.1 23 14 709220.08 Microsoft SQL Server 2000 Enterprise Edition 230533.0 Oracle Database 9i Enterprise Edition +2002-12-12 Microsoft SQL Server 2000 Enterprise Edition 64bit 342746.25 23 14 709220.08 Microsoft SQL Server 2000 Enterprise Edition 234325.1 Microsoft SQL Server 2000 Enterprise Edition +2002-12-16 Microsoft SQL Server 2000 Enterprise Edition 64bit 87741.0 23 41 709220.08 Microsoft SQL Server 2000 Enterprise Edition 84598.42 Microsoft SQL Server 2000 Enterprise Edition SP3 +2002-12-26 Oracle Database 9i Enterprise Server v.9.2.0.1 427760.83 23 8 709220.08 Microsoft SQL Server 2000 Enterprise Edition 423414.41 Oracle Database 9i Enterprise Server v.9.2.0.1 +2003-01-06 Microsoft SQL Server 2000 Enterprise Edition SP3 71313.19 23 51 709220.08 Microsoft SQL Server 2000 Enterprise Edition 69901.74 Microsoft SQL Server 2000 Enterprise Edition +2003-01-06 Microsoft SQL Server 2000 Enterprise Edition SP3 71586.49 23 50 709220.08 Microsoft SQL Server 2000 Enterprise Edition 71313.19 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-01-08 Microsoft SQL Server 2000 Enterprise Edition SP3 26725.34 23 100 709220.08 Microsoft SQL Server 2000 Enterprise Edition 26725.34 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-01-08 Microsoft SQL Server 2000 Enterprise Edition SP3 38386.24 23 82 709220.08 Microsoft SQL Server 2000 Enterprise Edition 37596.34 Microsoft SQL Server 2000 Enterprise Edition +2003-01-08 Microsoft SQL Server 2000 Enterprise Edition SP3 26725.34 23 100 709220.08 Microsoft SQL Server 2000 Enterprise Edition 24925.43 Microsoft SQL Server 2000 +2003-01-22 Microsoft SQL Server 2000 Enterprise Edition SP3 68264.47 23 56 709220.08 Microsoft SQL Server 2000 Enterprise Edition 67102.53 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2003-01-22 Microsoft SQL Server 2000 Enterprise Edition SP3 84598.42 23 43 709220.08 Microsoft SQL Server 2000 Enterprise Edition 80570.81 Oracle Database 10i Standard Edition +2003-02-20 Microsoft SQL Server 2000 Enterprise Edition 64bit 433107.77 23 8 709220.08 Microsoft SQL Server 2000 Enterprise Edition 427760.83 Oracle Database 9i Enterprise Server v.9.2.0.1 +2003-02-28 Microsoft SQL Server 2000 Enterprise Edition SP3 52587.46 23 73 709220.08 Microsoft SQL Server 2000 Enterprise Edition 51069.87 Microsoft SQL Server 2000 Enterprise Edition +2003-02-28 Microsoft SQL Server 2000 Enterprise Edition SP3 50666.11 23 75 709220.08 Microsoft SQL Server 2000 Enterprise Edition 50117.0 Oracle Database 9i R2 Enterprise Edition for Tru64 Unix +2003-03-26 Microsoft SQL Server 2000 Enterprise Edition SP3 151744.13 23 29 709220.08 Microsoft SQL Server 2000 Enterprise Edition 151744.13 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-03-26 Microsoft SQL Server 2000 Enterprise Edition SP3 151744.13 23 29 709220.08 Microsoft SQL Server 2000 Enterprise Edition 141138.44 Microsoft SQL Server 2000 Enterprise Edition +2003-04-04 Microsoft SQL Server 2000 Enterprise Edition SP3 119115.16 23 37 709220.08 Microsoft SQL Server 2000 Enterprise Edition 118381.38 Microsoft SQL Server 2000 Enterprise Edition +2003-04-04 Microsoft SQL Server 2000 Enterprise Edition 118381.38 23 38 709220.08 Microsoft SQL Server 2000 Enterprise Edition 115025.75 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-04-09 Microsoft SQL Server 2000 Enterprise Edition 70653.01 23 58 709220.08 Microsoft SQL Server 2000 Enterprise Edition 69901.74 Microsoft SQL Server 2000 Enterprise Edition +2003-04-21 Microsoft SQL Server 2000 Enterprise Edition SP3 78116.87 23 53 709220.08 Microsoft SQL Server 2000 Enterprise Edition 77905.18 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-04-23 Microsoft SQL Server 2000 Enterprise Edition 64bit 514034.72 23 5 709220.08 Microsoft SQL Server 2000 Enterprise Edition 455818.2 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2003-04-24 Microsoft SQL Server 2000 Enterprise Edition 64bit 121065.13 23 40 709220.08 Microsoft SQL Server 2000 Enterprise Edition 119115.16 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-04-24 Microsoft SQL Server 2000 Enterprise Edition 64bit 658277.74 23 4 709220.08 Microsoft SQL Server 2000 Enterprise Edition 658277.74 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-04-24 Microsoft SQL Server 2000 Enterprise Edition 64bit 658277.74 23 4 709220.08 Microsoft SQL Server 2000 Enterprise Edition 567882.56 Microsoft SQL Server 2000 Enterprise Edition +2003-05-02 Microsoft SQL Server 2000 Enterprise Edition 181280.45 23 27 709220.08 Microsoft SQL Server 2000 Enterprise Edition 165218.71 Microsoft SQL Server 2000 Enterprise Edition +2003-05-09 IBM DB2 UDB 8.1 680613.12 24 4 709220.08 Microsoft SQL Server 2000 Enterprise Edition 658277.74 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-05-12 Microsoft SQL Server 2000 19526.27 24 129 709220.08 Microsoft SQL Server 2000 Enterprise Edition 18077.98 Microsoft SQL Server 2000 Standard Edition SP3 +2003-05-12 Microsoft SQL Server 2000 Enterprise Edition SP3 39006.54 24 99 709220.08 Microsoft SQL Server 2000 Enterprise Edition 38386.24 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-05-16 Microsoft SQL Server 2000 Enterprise Edition 64bit 707102.32 24 2 709220.08 Microsoft SQL Server 2000 Enterprise Edition 688220.9 Microsoft SQL Server 2000 +2003-05-16 Microsoft SQL Server 2000 Enterprise Edition 161542.04 24 33 709220.08 Microsoft SQL Server 2000 Enterprise Edition 155179.25 Oracle 8i Enterprise Edition v. 8.1.7 +2003-05-20 Microsoft SQL Server 2000 Enterprise Edition 64bit 707102.0 24 3 709220.08 Microsoft SQL Server 2000 Enterprise Edition 688220.9 Microsoft SQL Server 2000 +2003-05-29 Microsoft SQL Server 2000 Standard Edition SP3 19140.72 24 135 709220.08 Microsoft SQL Server 2000 Enterprise Edition 18818.46 Microsoft SQL Server 2000 Standard Edition SP3 +2003-05-29 Microsoft SQL Server 2000 Enterprise Edition SP3 44942.92 24 99 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43230.66 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-05-29 Microsoft SQL Server 2000 Enterprise Edition SP3 43230.66 24 100 709220.08 Microsoft SQL Server 2000 Enterprise Edition 43046.55 Microsoft SQL Server 2000 Enterprise Edition +2003-05-29 Microsoft SQL Server 2000 Standard Edition SP3 18818.46 24 136 709220.08 Microsoft SQL Server 2000 Enterprise Edition 18077.98 Microsoft SQL Server 2000 Standard Edition SP3 +2003-06-27 Microsoft SQL Server 2000 Enterprise Edition 252920.49 24 23 709220.08 Microsoft SQL Server 2000 Enterprise Edition 234325.1 Microsoft SQL Server 2000 Enterprise Edition +2003-06-30 Microsoft SQL Server 2000 Enterprise Edition SP3 84595.22 24 62 763898.39 IBM DB2 UDB 8.1 80570.81 Oracle Database 10i Standard Edition +2003-06-30 Microsoft SQL Server 2000 Enterprise Edition SP3 139153.98 24 43 763898.39 IBM DB2 UDB 8.1 138362.03 Oracle Database 9i R2 Enterprise Edition +2003-06-30 IBM DB2 UDB 8.1 763898.39 24 1 763898.39 IBM DB2 UDB 8.1 709220.08 Microsoft SQL Server 2000 Enterprise Edition +2003-07-08 Microsoft SQL Server 2000 Enterprise Edition SP3 82226.46 24 63 763898.39 IBM DB2 UDB 8.1 80570.81 Oracle Database 10i Standard Edition +2003-07-10 Microsoft SQL Server 2000 Enterprise Edition 18936.05 24 141 763898.39 IBM DB2 UDB 8.1 18818.46 Microsoft SQL Server 2000 Standard Edition SP3 +2003-07-14 Microsoft SQL Server 2000 Standard Edition 20108.79 24 139 763898.39 IBM DB2 UDB 8.1 19526.27 Microsoft SQL Server 2000 +2003-07-15 Microsoft SQL Server 2000 Standard Edition SP3 19718.01 24 141 763898.39 IBM DB2 UDB 8.1 19526.27 Microsoft SQL Server 2000 +2003-07-15 Microsoft SQL Server 2000 Enterprise Edition SP3 52468.48 24 94 763898.39 IBM DB2 UDB 8.1 51069.87 Microsoft SQL Server 2000 Enterprise Edition +2003-07-18 Microsoft SQL Server 2000 Enterprise Edition SP3 190510.02 24 32 763898.39 IBM DB2 UDB 8.1 181280.45 Microsoft SQL Server 2000 Enterprise Edition +2003-07-30 Oracle Database 10g Standard Edition 131639.8 26 50 824164.53 Oracle Database 10g Enterprise Edition 121319.23 Microsoft SQL Server 2000 +2003-07-30 Oracle Database 10g Enterprise Edition 824164.53 26 1 824164.53 Oracle Database 10g Enterprise Edition 763898.39 IBM DB2 UDB 8.1 +2003-07-30 Oracle Database 10g Enterprise Edition 541673.76 26 12 824164.53 Oracle Database 10g Enterprise Edition 514034.72 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-08-11 Microsoft SQL Server 2000 Enterprise Edition SP3 53691.33 26 96 824164.53 Oracle Database 10g Enterprise Edition 52671.3 Microsoft SQL Server 2000 Enterprise Edition +2003-08-27 Microsoft SQL Server 2000 Enterprise Edition 64bit 786646.0 26 2 824164.53 Oracle Database 10g Enterprise Edition 763898.39 IBM DB2 UDB 8.1 +2003-09-05 Oracle Database 10g Standard Edition 136110.98 26 51 824164.53 Oracle Database 10g Enterprise Edition 131639.8 Oracle Database 10g Standard Edition +2003-09-08 Microsoft SQL Server 2000 Enterprise Edition SP3 84712.94 26 67 824164.53 Oracle Database 10g Enterprise Edition 84598.42 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-09-08 Oracle Database 10g Enterprise Edition 521440.53 26 14 824164.53 Oracle Database 10g Enterprise Edition 514034.72 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-09-08 Microsoft SQL Server 2000 Standard Edition SP3 20477.37 26 145 824164.53 Oracle Database 10g Enterprise Edition 20422.01 Microsoft SQL Server 2000 +2003-09-12 Oracle Database 10g Enterprise Edition 768839.4 26 3 824164.53 Oracle Database 10g Enterprise Edition 763898.39 IBM DB2 UDB 8.1 +2003-09-21 Microsoft SQL Server 2000 Enterprise Edition SP3 36027.71 26 127 824164.53 Oracle Database 10g Enterprise Edition 34914.92 Microsoft SQL Server 2000 Enterprise Edition +2003-10-09 Microsoft SQL Server 2000 Enterprise Edition 64bit 577530.77 26 13 824164.53 Oracle Database 10g Enterprise Edition 567882.56 Microsoft SQL Server 2000 Enterprise Edition +2003-10-13 Microsoft SQL Server 2000 Enterprise Edition SP3 54096.56 26 102 824164.53 Oracle Database 10g Enterprise Edition 53691.33 Microsoft SQL Server 2000 Enterprise Edition SP3 +2003-10-17 Microsoft SQL Server 2000 Enterprise Edition SP3 90271.76 26 68 824164.53 Oracle Database 10g Enterprise Edition 87741.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-10-20 Oracle Database 10g Enterprise Edition 291410.61 26 30 824164.53 Oracle Database 10g Enterprise Edition 252920.49 Microsoft SQL Server 2000 Enterprise Edition +2003-10-22 Microsoft SQL Server 2000 Enterprise Edition SP3 51226.96 26 109 824164.53 Oracle Database 10g Enterprise Edition 51069.87 Microsoft SQL Server 2000 Enterprise Edition +2003-10-31 Oracle Database 10g Enterprise Edition 595702.31 26 13 824164.53 Oracle Database 10g Enterprise Edition 577530.77 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-11-03 Microsoft SQL Server 2000 Enterprise Edition SP3 58161.52 26 100 824164.53 Oracle Database 10g Enterprise Edition 57346.93 Oracle Database 9i Enterprise Edition v.9.0.1 +2003-11-04 Oracle Database 10g Enterprise Edition 1008144.49 26 1 1008144.49 Oracle Database 10g Enterprise Edition 824164.53 Oracle Database 10g Enterprise Edition +2003-11-24 Microsoft SQL Server 2000 Standard Edition SP3 19814.35 26 161 1008144.49 Oracle Database 10g Enterprise Edition 19718.01 Microsoft SQL Server 2000 Standard Edition SP3 +2003-12-03 Microsoft SQL Server 2000 Enterprise Edition SP3 31910.24 26 145 1008144.49 Oracle Database 10g Enterprise Edition 30231.37 Microsoft SQL Server 2000 +2003-12-08 Oracle Database 10g Enterprise Edition 1184893.38 26 1 1184893.38 Oracle Database 10g Enterprise Edition 1008144.49 Oracle Database 10g Enterprise Edition +2003-12-08 Microsoft SQL Server 2000 Enterprise Edition SP3 89616.32 26 73 1184893.38 Oracle Database 10g Enterprise Edition 87741.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2003-12-17 Microsoft SQL Server 2000 Enterprise Edition SP3 33873.83 26 144 1184893.38 Oracle Database 10g Enterprise Edition 33768.41 Microsoft SQL Server 2000 Enterprise Edition +2003-12-17 Microsoft SQL Server 2000 Standard Edition SP3 17192.4 26 176 1184893.38 Oracle Database 10g Enterprise Edition 17078.88 Microsoft SQL Server 2000 Standard Edition +2003-12-18 Microsoft SQL Server 2000 Enterprise Edition 64bit 301225.0 26 33 1184893.38 Oracle Database 10g Enterprise Edition 291410.61 Oracle Database 10g Enterprise Edition +2004-01-20 Microsoft SQL Server 2000 Enterprise Edition 309036.53 26 33 1184893.38 Oracle Database 10g Enterprise Edition 301225.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2004-02-17 IBM DB2 UDB 8.1 1025486.07 26 2 1184893.38 Oracle Database 10g Enterprise Edition 1008144.49 Oracle Database 10g Enterprise Edition +2004-02-18 Microsoft SQL Server 2000 Standard Edition 22052.0 26 162 1184893.38 Oracle Database 10g Enterprise Edition 22007.12 Microsoft SQL Server 2000 Enterprise Edition +2004-02-18 Microsoft SQL Server 2000 Standard Edition 22052.81 26 161 1184893.38 Oracle Database 10g Enterprise Edition 22052.0 Microsoft SQL Server 2000 Standard Edition +2004-02-23 Microsoft SQL Server 2000 Enterprise Edition 32185.33 26 151 1184893.38 Oracle Database 10g Enterprise Edition 31910.24 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-03-01 Microsoft SQL Server 2000 Enterprise Edition 95163.0 26 76 1184893.38 Oracle Database 10g Enterprise Edition 92398.49 Microsoft SQL Server 2000 Enterprise Edition +2004-03-01 Microsoft SQL Server 2000 Enterprise Edition 102667.42 26 75 1184893.38 Oracle Database 10g Enterprise Edition 95163.0 Microsoft SQL Server 2000 Enterprise Edition +2004-03-01 Microsoft SQL Server 2000 Enterprise Edition 156105.72 26 51 1184893.38 Oracle Database 10g Enterprise Edition 155179.25 Oracle 8i Enterprise Edition v. 8.1.7 +2004-03-02 Microsoft SQL Server 2000 Enterprise Edition 28711.0 26 161 1184893.38 Oracle Database 10g Enterprise Edition 26725.34 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-03-02 Microsoft SQL Server 2000 Enterprise Edition 35030.0 26 145 1184893.38 Oracle Database 10g Enterprise Edition 34914.92 Microsoft SQL Server 2000 Enterprise Edition +2004-03-02 Microsoft SQL Server 2000 Enterprise Edition 60364.0 26 109 1184893.38 Oracle Database 10g Enterprise Edition 58161.52 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-03-26 Microsoft SQL Server 2000 Enterprise Edition SP3 215485.89 26 43 1184893.38 Oracle Database 10g Enterprise Edition 203518.03 Microsoft SQL Server 2000 Enterprise Edition +2004-04-06 Oracle Database 10g Enterprise Edition 609467.0 26 16 1184893.38 Oracle Database 10g Enterprise Edition 595702.31 Oracle Database 10g Enterprise Edition +2004-04-14 IBM DB2 UDB Express Edition v8.1 18318.24 27 185 1184893.38 Oracle Database 10g Enterprise Edition 18077.98 Microsoft SQL Server 2000 Standard Edition SP3 +2004-04-28 Microsoft SQL Server 2000 Enterprise Edition 304148.5 27 36 1184893.38 Oracle Database 10g Enterprise Edition 301225.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2004-05-03 Microsoft SQL Server 2000 Enterprise Edition SP3 105687.0 27 77 1184893.38 Oracle Database 10g Enterprise Edition 105025.02 Oracle Database 9i Enterprise Edition v.9i.0.1 +2004-05-03 Microsoft SQL Server 2000 Enterprise Edition SP3 123027.0 27 67 1184893.38 Oracle Database 10g Enterprise Edition 121319.23 Microsoft SQL Server 2000 +2004-05-11 Microsoft SQL Server 2000 Enterprise Edition SP3 21197.0 27 177 1184893.38 Oracle Database 10g Enterprise Edition 20477.37 Microsoft SQL Server 2000 Standard Edition SP3 +2004-05-11 Oracle Database 10g Enterprise Edition 291413.0 27 38 1184893.38 Oracle Database 10g Enterprise Edition 291410.61 Oracle Database 10g Enterprise Edition +2004-05-27 Microsoft SQL Server 2000 Enterprise Edition SP3 94172.0 27 83 1184893.38 Oracle Database 10g Enterprise Edition 92398.49 Microsoft SQL Server 2000 Enterprise Edition +2004-06-14 Microsoft SQL Server 2000 Enterprise Edition 237869.0 27 41 1184893.38 Oracle Database 10g Enterprise Edition 234325.1 Microsoft SQL Server 2000 Enterprise Edition +2004-06-14 Microsoft SQL Server 2000 Enterprise Edition 212511.0 27 48 1184893.38 Oracle Database 10g Enterprise Edition 203518.03 Microsoft SQL Server 2000 Enterprise Edition +2004-06-28 Oracle Database 10g Enterprise Edition 683575.0 27 13 1184893.38 Oracle Database 10g Enterprise Edition 680613.12 IBM DB2 UDB 8.1 +2004-06-30 Microsoft SQL Server 2000 Enterprise Edition 64bit 175366.24 27 54 1184893.38 Oracle Database 10g Enterprise Edition 165218.71 Microsoft SQL Server 2000 Enterprise Edition +2004-07-12 Oracle Database 10g 194391.43 28 54 1184893.38 Oracle Database 10g Enterprise Edition 190510.02 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-07-12 IBM DB2 UDB 8.1 809144.09 28 5 1184893.38 Oracle Database 10g Enterprise Edition 786646.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2004-07-12 Oracle Database 10g 371044.22 28 35 1184893.38 Oracle Database 10g Enterprise Edition 363129.75 Microsoft SQL Server 2000 +2004-07-16 IBM DB2 UDB Express Edition v8.1 18661.0 28 198 1184893.38 Oracle Database 10g Enterprise Edition 18318.24 IBM DB2 UDB Express Edition v8.1 +2004-07-20 Microsoft SQL Server 2000 Enterprise Edition SP3 85554.0 28 95 1184893.38 Oracle Database 10g Enterprise Edition 84712.94 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-08-13 Microsoft SQL Server 2000 Enterprise Edition SP3 34349.0 28 165 1184893.38 Oracle Database 10g Enterprise Edition 34288.77 Sybase Adaptive Server Enterprise 12.0 +2004-08-31 IBM DB2 UDB 8.1 429899.7 28 29 1184893.38 Oracle Database 10g Enterprise Edition 427760.83 Oracle Database 9i Enterprise Server v.9.2.0.1 +2004-09-29 Oracle Database 10g Standard Edition 51506.4 28 137 1184893.38 Oracle Database 10g Enterprise Edition 51226.96 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-10-15 Microsoft SQL Server 2000 Enterprise Edition SP3 115110.0 28 81 1184893.38 Oracle Database 10g Enterprise Edition 115025.75 Microsoft SQL Server 2000 Enterprise Edition SP3 +2004-10-15 Microsoft SQL Server 2000 Enterprise Edition SP3 32464.0 28 174 1184893.38 Oracle Database 10g Enterprise Edition 32377.17 Microsoft SQL Server 2000 +2004-10-19 Microsoft SQL Server 2000 Standard Edition SP3 17810.0 28 208 1184893.38 Oracle Database 10g Enterprise Edition 17659.53 Microsoft SQL Server 2000 Standard Edition +2004-11-01 Microsoft SQL Server 2000 Enterprise Edition SP3 68010.0 28 118 1184893.38 Oracle Database 10g Enterprise Edition 67102.53 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2004-11-07 Microsoft SQL Server 2000 Enterprise Edition SP3 123027.0 28 76 1184893.38 Oracle Database 10g Enterprise Edition 121319.23 Microsoft SQL Server 2000 +2004-11-08 Oracle Database 10g Standard Edition 161217.4 28 63 1184893.38 Oracle Database 10g Enterprise Edition 156105.72 Microsoft SQL Server 2000 Enterprise Edition +2004-11-18 IBM DB2 UDB 8.2 3210540.63 29 1 3210540.63 IBM DB2 UDB 8.2 1184893.38 Oracle Database 10g Enterprise Edition +2004-12-10 Microsoft SQL Server 2000 Enterprise Edition 26410.0 29 189 3210540.63 IBM DB2 UDB 8.2 24925.43 Microsoft SQL Server 2000 +2004-12-10 Microsoft SQL Server 2000 Enterprise Edition SP3 143367.0 29 70 3210540.63 IBM DB2 UDB 8.2 141138.44 Microsoft SQL Server 2000 Enterprise Edition +2005-01-25 IBM DB2 UDB 8.2 247650.0 29 46 3210540.63 IBM DB2 UDB 8.2 247650.0 IBM DB2 UDB 8.2 +2005-01-25 IBM DB2 UDB 8.2 247650.0 29 46 3210540.63 IBM DB2 UDB 8.2 237869.0 Microsoft SQL Server 2000 Enterprise Edition +2005-02-11 Microsoft SQL Server 2000 Enterprise Edition SP3 74298.0 30 115 3210540.63 IBM DB2 UDB 8.2 74206.27 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-02-11 Microsoft SQL Server 2000 Enterprise Edition SP3 71413.0 30 119 3210540.63 IBM DB2 UDB 8.2 71313.19 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-02-11 Microsoft SQL Server 2000 Enterprise Edition QFE 130623.0 30 81 3210540.63 IBM DB2 UDB 8.2 123027.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-02-14 Microsoft SQL Server 2000 Enterprise Edition SP3 67754.0 30 128 3210540.63 IBM DB2 UDB 8.2 67102.53 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2005-02-24 Microsoft SQL Server 2000 Workgroup Edition 28122.0 31 193 3210540.63 IBM DB2 UDB 8.2 26725.34 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-03-28 Microsoft SQL Server 2000 Enterprise Edition SP3 42432.0 31 164 3210540.63 IBM DB2 UDB 8.2 40621.26 Microsoft SQL Server 2000 Enterprise Edition 64bit +2005-04-20 Oracle Database 10g Enterprise Edition 1601784.98 31 2 3210540.63 IBM DB2 UDB 8.2 1184893.38 Oracle Database 10g Enterprise Edition +2005-04-21 Microsoft SQL Server 2000 Enterprise Edition SP4 187296.0 33 61 3210540.63 IBM DB2 UDB 8.2 181280.45 Microsoft SQL Server 2000 Enterprise Edition +2005-04-21 IBM DB2 UDB 8.2 150704.0 33 74 3210540.63 IBM DB2 UDB 8.2 143367.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-04-21 Microsoft SQL Server 2000 Enterprise Edition (SP3 w/QFE) 141504.0 33 76 3210540.63 IBM DB2 UDB 8.2 141138.44 Microsoft SQL Server 2000 Enterprise Edition +2005-05-10 Microsoft SQL Server 2000 Enterprise Edition SP3 63646.0 33 137 3210540.63 IBM DB2 UDB 8.2 61564.5 Microsoft SQL Server 2000 Enterprise Edition +2005-05-31 IBM DB2 UDB 8.2 250975.0 33 47 3210540.63 IBM DB2 UDB 8.2 247650.0 IBM DB2 UDB 8.2 +2005-06-07 Microsoft SQL Server 2005 Enterprise Edition 64bit 1082203.0 34 4 3210540.63 IBM DB2 UDB 8.2 1025486.07 IBM DB2 UDB 8.1 +2005-06-24 Microsoft SQL Server 2000 Enterprise Edition SP3 65453.0 34 141 3210540.63 IBM DB2 UDB 8.2 63646.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-06-24 Microsoft SQL Server 2000 Enterprise Edition SP3 108574.0 34 101 3210540.63 IBM DB2 UDB 8.2 105687.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-06-24 Oracle Database 10g Enterprise Edition 322805.0 34 42 3210540.63 IBM DB2 UDB 8.2 309036.53 Microsoft SQL Server 2000 Enterprise Edition +2005-06-28 Microsoft SQL Server 2000 Enterprise Edition SP3 31253.0 34 200 3210540.63 IBM DB2 UDB 8.2 30231.37 Microsoft SQL Server 2000 +2005-07-01 Oracle Database 10g Enterprise Edition 327829.0 34 42 3210540.63 IBM DB2 UDB 8.2 322805.0 Oracle Database 10g Enterprise Edition +2005-07-15 Microsoft SQL Server 2000 Enterprise Edition 64bit 332265.87 34 42 3210540.63 IBM DB2 UDB 8.2 327829.0 Oracle Database 10g Enterprise Edition +2005-08-08 IBM DB2 UDB 8.2 197669.0 34 63 3210540.63 IBM DB2 UDB 8.2 197024.17 Oracle 8 Enterprise Edition v8.1.7.1 +2005-08-29 Microsoft SQL Server 2000 Enterprise Edition SP3 52742.0 34 159 3210540.63 IBM DB2 UDB 8.2 52671.3 Microsoft SQL Server 2000 Enterprise Edition +2005-09-14 Microsoft SQL Server 2005 Enterprise Edition 64bit 241300.0 34 54 3210540.63 IBM DB2 UDB 8.2 237869.0 Microsoft SQL Server 2000 Enterprise Edition +2005-09-26 Microsoft SQL Server 2005 Standard Edition x64 38622.0 35 183 3210540.63 IBM DB2 UDB 8.2 38386.24 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-09-30 Microsoft SQL Server 2005 Enterprise Edition 202551.0 36 64 3210540.63 IBM DB2 UDB 8.2 197669.0 IBM DB2 UDB 8.2 +2005-09-30 Microsoft SQL Server 2005 Enterprise Edition 109633.0 36 107 3210540.63 IBM DB2 UDB 8.2 108574.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-09-30 Microsoft SQL Server 2005 Enterprise Edition 107010.0 36 109 3210540.63 IBM DB2 UDB 8.2 105687.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-09-30 Microsoft SQL Server 2005 Enterprise Edition 138845.0 36 88 3210540.63 IBM DB2 UDB 8.2 138362.03 Oracle Database 9i R2 Enterprise Edition +2005-09-30 Microsoft SQL Server 2005 Enterprise Edition 76214.0 36 131 3210540.63 IBM DB2 UDB 8.2 74298.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-10-17 Oracle Database 10g Enterprise Edition 203439.87 36 64 3210540.63 IBM DB2 UDB 8.2 202551.0 Microsoft SQL Server 2005 Enterprise Edition +2005-10-24 Microsoft SQL Server 2005 Enterprise Edition x64 376045.0 37 39 3210540.63 IBM DB2 UDB 8.2 371044.22 Oracle Database 10g +2005-10-28 Microsoft SQL Server 2000 Enterprise Edition SP4 188761.0 37 71 3210540.63 IBM DB2 UDB 8.2 187296.0 Microsoft SQL Server 2000 Enterprise Edition SP4 +2005-10-31 IBM DB2 UDB 8.2 221017.0 37 60 3210540.63 IBM DB2 UDB 8.2 220807.27 Oracle 8i Enterprise Edition v. 8.1.7 +2005-11-04 Microsoft SQL Server 2005 Enterprise Edition x64 206181.0 37 65 3210540.63 IBM DB2 UDB 8.2 203518.03 Microsoft SQL Server 2000 Enterprise Edition +2005-11-07 Microsoft SQL Server 2005 Enterprise Edition x64 251691.0 37 52 3210540.63 IBM DB2 UDB 8.2 250975.0 IBM DB2 UDB 8.2 +2005-11-22 Microsoft SQL Server 2005 Enterprise Edition 492307.0 37 28 3210540.63 IBM DB2 UDB 8.2 455818.2 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2005-11-28 Microsoft SQL Server 2005 Enterprise Edition SP1 1231433.0 38 3 3210540.63 IBM DB2 UDB 8.2 1184893.38 Oracle Database 10g Enterprise Edition +2005-12-01 Microsoft SQL Server 2005 Enterprise Edition 85858.0 38 128 3210540.63 IBM DB2 UDB 8.2 85554.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2005-12-05 IBM DB2 UDB 8.2 236054.0 38 60 3210540.63 IBM DB2 UDB 8.2 234325.1 Microsoft SQL Server 2000 Enterprise Edition +2006-01-12 Microsoft SQL Server 2000 Enterprise Edition SP3 66543.0 38 160 3210540.63 IBM DB2 UDB 8.2 65453.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-01-18 Oracle Database 10g Enterprise Edition 254471.0 38 53 3210540.63 IBM DB2 UDB 8.2 252920.49 Microsoft SQL Server 2000 Enterprise Edition +2006-02-09 Microsoft SQL Server 2005 Workgroup Edition 28244.0 39 228 3210540.63 IBM DB2 UDB 8.2 28122.0 Microsoft SQL Server 2000 Workgroup Edition +2006-02-14 IBM DB2 UDB 8.2 1025169.69 39 7 3210540.63 IBM DB2 UDB 8.2 1008144.49 Oracle Database 10g Enterprise Edition +2006-02-22 Microsoft SQL Server 2005 Enterprise Edition x64 347854.0 39 45 3210540.63 IBM DB2 UDB 8.2 342746.25 Microsoft SQL Server 2000 Enterprise Edition 64bit +2006-03-07 IBM DB2 UDB 8.2 273520.0 39 55 3210540.63 IBM DB2 UDB 8.2 254471.0 Oracle Database 10g Enterprise Edition +2006-03-09 Oracle Database 10g Enterprise Edition 200829.0 39 77 3210540.63 IBM DB2 UDB 8.2 197669.0 IBM DB2 UDB 8.2 +2006-03-20 Microsoft SQL Server 2005 Enterprise Edition x86 SP1 113628.0 40 118 3210540.63 IBM DB2 UDB 8.2 112740.87 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-03-20 Microsoft SQL Server 2005 Enterprise Edition 213986.0 40 72 3210540.63 IBM DB2 UDB 8.2 212511.0 Microsoft SQL Server 2000 Enterprise Edition +2006-03-21 Microsoft SQL Server 2005 Enterprise Edition x64 492307.0 40 30 3210540.63 IBM DB2 UDB 8.2 455818.2 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2006-03-27 Microsoft SQL Server 2005 Enterprise Edition Itanium 290644.0 41 56 3210540.63 IBM DB2 UDB 8.2 273520.0 IBM DB2 UDB 8.2 +2006-04-12 Microsoft SQL Server 2005 Standard Edition 57552.0 42 178 3210540.63 IBM DB2 UDB 8.2 57346.93 Oracle Database 9i Enterprise Edition v.9.0.1 +2006-04-26 Oracle Database 10g Enterprise Edition 792101.96 42 11 3210540.63 IBM DB2 UDB 8.2 786646.0 Microsoft SQL Server 2000 Enterprise Edition 64bit +2006-05-01 Microsoft SQL Server 2005 Enterprise Edition x64 125954.0 42 113 3210540.63 IBM DB2 UDB 8.2 123027.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-05-04 Microsoft SQL Server 2005 Enterprise Edition x86 SP1 110615.0 42 127 3210540.63 IBM DB2 UDB 8.2 109633.0 Microsoft SQL Server 2005 Enterprise Edition +2006-05-08 Microsoft SQL Server 2005 Enterprise Edition x64 749839.0 42 15 3210540.63 IBM DB2 UDB 8.2 709220.08 Microsoft SQL Server 2000 Enterprise Edition +2006-05-22 Microsoft SQL Server 2005 Enterprise Edition x64 169360.0 42 91 3210540.63 IBM DB2 UDB 8.2 165218.71 Microsoft SQL Server 2000 Enterprise Edition +2006-06-12 Microsoft SQL Server 2005 Enterprise Edition x64 340243.0 42 50 3210540.63 IBM DB2 UDB 8.2 332265.87 Microsoft SQL Server 2000 Enterprise Edition 64bit +2006-06-23 Sybase Adaptive Server Enterprise v.12.5.4 81439.3 43 151 3210540.63 IBM DB2 UDB 8.2 80570.81 Oracle Database 10i Standard Edition +2006-06-26 Microsoft SQL Server 2005 Enterprise Edition x64 140246.0 43 107 3210540.63 IBM DB2 UDB 8.2 140239.97 Sybase Adaptive Server Enterprise v12.5 +2006-06-30 Microsoft SQL Server 2005 Standard Edition 65833.0 43 178 3210540.63 IBM DB2 UDB 8.2 65453.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-07-18 Microsoft SQL Server 2005 Enterprise Edition Itanium 344928.0 43 49 3210540.63 IBM DB2 UDB 8.2 342746.25 Microsoft SQL Server 2000 Enterprise Edition 64bit +2006-07-24 IBM DB2 9 4016222.19 44 1 4016222.19 IBM DB2 9 3210540.63 IBM DB2 UDB 8.2 +2006-08-01 Oracle Database 10g Enterprise Edition 230569.0 44 73 4016222.19 IBM DB2 9 230533.0 Oracle Database 9i Enterprise Edition +2006-09-13 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 147293.0 45 107 4016222.19 IBM DB2 9 143367.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-09-19 IBM DB2 9 314468.0 45 56 4016222.19 IBM DB2 9 309036.53 Microsoft SQL Server 2000 Enterprise Edition +2006-09-25 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 262989.0 45 64 4016222.19 IBM DB2 9 254471.0 Oracle Database 10g Enterprise Edition +2006-10-19 Microsoft SQL Server 2005 Enterprise Edition 318407.0 45 56 4016222.19 IBM DB2 9 314468.0 IBM DB2 9 +2006-10-26 Oracle Database 10g R2 Enterprise Edition 359440.0 46 49 4016222.19 IBM DB2 9 347854.0 Microsoft SQL Server 2005 Enterprise Edition x64 +2006-11-09 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 139693.0 46 117 4016222.19 IBM DB2 9 139153.98 Microsoft SQL Server 2000 Enterprise Edition SP3 +2006-11-13 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 240737.0 46 74 4016222.19 IBM DB2 9 237869.0 Microsoft SQL Server 2000 Enterprise Edition +2006-11-14 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 222117.0 46 81 4016222.19 IBM DB2 9 221017.0 IBM DB2 UDB 8.2 +2006-11-30 Oracle Database 10g Enterprise Edition 1238579.0 46 4 4016222.19 IBM DB2 9 1231433.0 Microsoft SQL Server 2005 Enterprise Edition SP1 +2006-12-15 IBM DB2 9 331087.0 46 56 4016222.19 IBM DB2 9 327829.0 Oracle Database 10g Enterprise Edition +2007-01-22 IBM DB2 9 4033378.0 46 1 4033378.0 IBM DB2 9 4016222.19 IBM DB2 9 +2007-02-13 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 138979.0 46 124 4033378.0 IBM DB2 9 138845.0 Microsoft SQL Server 2005 Enterprise Edition +2007-02-27 Oracle Database 10g R2 Enterprise Edition w/Partitioning 4092799.0 47 1 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 4033378.0 IBM DB2 9 +2007-02-28 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 510822.0 47 36 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 492307.0 Microsoft SQL Server 2005 Enterprise Edition +2007-03-09 Microsoft SQL Server 2005 Standard Edition 69564.0 47 184 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 69169.61 Microsoft SQL Server 2000 Enterprise Edition +2007-03-23 Microsoft SQL Server 2005 Enterprise Edition 520467.0 47 35 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 514034.72 Microsoft SQL Server 2000 Enterprise Edition 64bit +2007-03-25 IBM DB2 9 511342.0 47 37 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 510822.0 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 +2007-03-27 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 82774.0 47 170 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 82226.46 Microsoft SQL Server 2000 Enterprise Edition SP3 +2007-04-26 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 145180.0 48 121 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 143367.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2007-05-21 IBM DB2 Enterprise 9 1616162.0 49 5 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 1601784.98 Oracle Database 10g Enterprise Edition +2007-06-08 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 126371.0 50 138 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 125954.0 Microsoft SQL Server 2005 Enterprise Edition x64 +2007-06-08 Oracle Database 10g Standard Edition One 100926.0 50 161 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 95163.0 Microsoft SQL Server 2000 Enterprise Edition +2007-06-11 Microsoft SQL Server 2005 Enterprise Edition Itanium 372140.0 50 54 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 371044.22 Oracle Database 10g +2007-08-06 Oracle Database 10g Enterprise Edition 404462.0 50 50 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 403255.46 Oracle Database 9i R2 Enterprise Edition +2007-09-05 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 251300.0 50 81 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 250975.0 IBM DB2 UDB 8.2 +2007-09-05 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 407079.0 50 50 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 404462.0 Oracle Database 10g Enterprise Edition +2007-09-12 Oracle Database 11g Standard Edition One 102454.0 51 165 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 100926.0 Oracle Database 10g Standard Edition One +2007-10-04 Oracle Database 10g R2 Enterprise Edition 236271.0 51 88 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 236054.0 IBM DB2 UDB 8.2 +2007-10-15 IBM DB2 9.5 Enterprise Edition 516752.0 52 37 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 514034.72 Microsoft SQL Server 2000 Enterprise Edition 64bit +2007-10-23 Microsoft SQL Server 2005 Enterprise Edition x64 841809.0 52 14 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 824164.53 Oracle Database 10g Enterprise Edition +2007-10-30 Oracle Database 10g R2 Enterprise Edition w/Partitioning 2196268.0 52 5 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 1616162.0 IBM DB2 Enterprise 9 +2007-11-09 Oracle Database 10g Standard Edition One 273666.0 52 79 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 273520.0 IBM DB2 UDB 8.2 +2007-12-17 IBM DB2 9.1 1616162.0 53 6 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 1601784.98 Oracle Database 10g Enterprise Edition +2007-12-17 Oracle Database 10g Enterprise Edition 404462.0 53 55 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 403255.46 Oracle Database 9i R2 Enterprise Edition +2008-01-07 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 275149.0 53 81 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 273666.0 Oracle Database 10g Standard Edition One +2008-01-21 Oracle Database 10g R2 Enterprise Edition w/Partitioning 1245516.0 53 9 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 1238579.0 Oracle Database 10g Enterprise Edition +2008-03-20 IBM DB2 9.5 Enterprise Edition 629159.0 53 34 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 609467.0 Oracle Database 10g Enterprise Edition +2008-03-31 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 402234.0 53 61 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning 389434.4 Oracle Database 9i Enterprise Edition +2008-06-10 IBM DB2 9.5 6085166.0 54 1 6085166.0 IBM DB2 9.5 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2008-06-11 IBM DB2 9.5 Enterprise Edition 629159.0 54 35 6085166.0 IBM DB2 9.5 609467.0 Oracle Database 10g Enterprise Edition +2008-06-15 IBM DB2 9.5 6085166.0 54 1 6085166.0 IBM DB2 9.5 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2008-06-16 Oracle Database 11g Standard Edition One 97083.0 55 182 6085166.0 IBM DB2 9.5 95163.0 Microsoft SQL Server 2000 Enterprise Edition +2008-06-16 Sybase Adaptive Server Enterprise 15.0.3 276383.0 55 87 6085166.0 IBM DB2 9.5 275149.0 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 +2008-07-14 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 471883.0 55 51 6085166.0 IBM DB2 9.5 455818.2 Fujitsu SymfoWARE Server Enterp. Ed. VLM 3.0 +2008-07-29 Sybase SQL Anywhere 11.0 20705.0 56 306 6085166.0 IBM DB2 9.5 20477.37 Microsoft SQL Server 2000 Standard Edition SP3 +2008-08-19 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 634825.0 57 37 6085166.0 IBM DB2 9.5 629159.0 IBM DB2 9.5 Enterprise Edition +2008-08-19 IBM DB2 ESE 9.5 1200632.0 57 14 6085166.0 IBM DB2 9.5 1184893.38 Oracle Database 10g Enterprise Edition +2008-09-15 Microsoft SQL Server 2005 Enterprise Edition x64 684508.0 57 33 6085166.0 IBM DB2 9.5 683575.0 Oracle Database 10g Enterprise Edition +2008-11-17 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 579814.0 57 43 6085166.0 IBM DB2 9.5 577530.77 Microsoft SQL Server 2000 Enterprise Edition 64bit +2008-11-22 Oracle Database 10g R2 Enterprise Edition 1354086.0 57 11 6085166.0 IBM DB2 9.5 1245516.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2008-12-04 Oracle Database 10g R2 Enterprise Edition w/Partitioning 2382032.0 57 7 6085166.0 IBM DB2 9.5 2196268.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2009-01-16 Oracle Database 11g Standard Edition 639253.0 58 40 6085166.0 IBM DB2 9.5 634825.0 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 +2009-02-20 Oracle Database 11g Standard Edition One 104492.0 58 187 6085166.0 IBM DB2 9.5 102667.42 Microsoft SQL Server 2000 Enterprise Edition +2009-03-30 Oracle Database 11g Standard Edition One 631766.0 58 42 6085166.0 IBM DB2 9.5 629159.0 IBM DB2 9.5 Enterprise Edition +2009-05-21 Oracle Database 11g Standard Edition One 232002.0 58 114 6085166.0 IBM DB2 9.5 230569.0 Oracle Database 10g Enterprise Edition +2009-11-04 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 7646486.0 59 1 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 6085166.0 IBM DB2 9.5 +2009-11-18 Oracle Database 11g Standard Edition One 239392.0 59 111 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 237869.0 Microsoft SQL Server 2000 Enterprise Edition +2010-02-01 Microsoft SQL Server 2005 Enterprise Edition x64 SP2 661475.0 59 39 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 658277.74 Microsoft SQL Server 2000 Enterprise Edition 64bit +2010-04-08 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 705652.0 60 34 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 688220.9 Microsoft SQL Server 2000 +2010-04-13 IBM DB2 9.5 1200011.0 60 18 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 1184893.38 Oracle Database 10g Enterprise Edition +2010-05-11 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 803068.0 60 27 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 792101.96 Oracle Database 10g Enterprise Edition +2010-06-22 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 1193472.0 60 19 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning 1184893.38 Oracle Database 10g Enterprise Edition +2010-08-17 Oracle Database 11g Release 2 Standard Ed One 290040.0 62 103 10366254.0 IBM DB2 9.7 276383.0 Sybase Adaptive Server Enterprise 15.0.3 +2010-08-17 IBM DB2 9.7 10366254.0 62 1 10366254.0 IBM DB2 9.7 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning +2010-08-30 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 1807347.0 62 11 10366254.0 IBM DB2 9.7 1616162.0 IBM DB2 Enterprise 9 +2010-11-16 IBM DB2 ESE 9.7 2308099.0 63 10 10366254.0 IBM DB2 9.7 2196268.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2010-12-02 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 30249688.0 64 1 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 10366254.0 IBM DB2 9.7 +2011-05-05 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 1024380.0 64 28 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1008144.49 Oracle Database 10g Enterprise Edition +2011-05-23 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 1263599.0 64 18 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1245516.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2011-07-11 IBM DB2 ESE 9.7 3014684.0 64 10 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 2382032.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2011-11-15 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 1207982.0 64 23 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1200632.0 IBM DB2 ESE 9.5 +2011-12-08 Oracle Database 11g Release 2 Standard Ed One 1053100.32 64 29 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1025486.07 IBM DB2 UDB 8.1 +2012-01-18 Oracle Database 11g R2 Enterprise Edition 4803718.0 65 6 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 4092799.0 Oracle Database 10g R2 Enterprise Edition w/Partitioning +2012-04-11 IBM DB2 ESE 9.7 1503544.0 65 19 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1354086.0 Oracle Database 10g R2 Enterprise Edition +2012-06-20 Oracle Database 11g R2 Enterprise Edition w/Partitioning 5055888.0 66 6 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 4803718.0 Oracle Database 11g R2 Enterprise Edition +2012-09-26 Oracle Database 11g Standard Edition One 1609186.39 66 19 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1601784.98 Oracle Database 10g Enterprise Edition +2013-02-22 IBM DB2 ESE 9.7 1320082.0 66 23 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 1263599.0 Microsoft SQL Server 2005 Enterprise Edition x64 SP3 +2013-03-26 Oracle 11g Release 2 Enterprise Edition with Oracle Partitioning 8552523.0 67 3 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 7646486.0 Oracle Database 11g Enterprise Edition w/RAC w/Partitioning +2014-11-25 SQL Anywhere 16 112890.0 68 201 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 112740.87 Microsoft SQL Server 2000 Enterprise Edition SP3 +2017-05-08 SunjeSoft Goldilocks v3.1 Standard Edition 139909.0 69 180 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 139693.0 Microsoft SQL Server 2005 Enterprise Edition x64 SP1 +2018-11-19 SunjeSoft Goldilocks v3.1 Standard Edition 152330.0 69 170 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 151744.13 Microsoft SQL Server 2000 Enterprise Edition SP3 +2018-11-26 SunjeSoft Goldilocks v3.1 Standard Edition 76172.0 69 241 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 76168.0 SunjeSoft Goldilocks v3.1 Standard Edition +2018-11-26 SunjeSoft Goldilocks v3.1 Standard Edition 76168.0 69 242 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning 74298.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2019-10-01 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 60880800.0 70 1 60880800.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 30249688.0 Oracle Database 11g R2 Enterprise Edition w/RAC w/Partitioning +2019-10-14 SunjeSoft Goldilocks v3.1 Standard Edition 76168.0 70 244 60880800.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 74298.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2019-10-14 SunjeSoft Goldilocks v3.1 Standard Edition 114245.0 70 203 60880800.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 113628.0 Microsoft SQL Server 2005 Enterprise Edition x86 SP1 +2019-11-03 SunjeSoft Goldilocks v3.1 Standard Edition 152328.0 70 172 60880800.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 151744.13 Microsoft SQL Server 2000 Enterprise Edition SP3 +2020-05-19 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 707351007.0 70 1 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 60880800.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression +2020-08-17 SunjeSoft Goldilocks v3.1 Standard Edition 380475.0 70 98 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 376045.0 Microsoft SQL Server 2005 Enterprise Edition x64 +2020-11-23 SunjeSoft Goldilocks v3.1 Standard Edition 76174.0 70 246 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 76172.0 SunjeSoft Goldilocks v3.1 Standard Edition +2021-09-29 SunjeSoft Goldilocks v3.1 Standard Edition 144714.0 70 180 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 143367.0 Microsoft SQL Server 2000 Enterprise Edition SP3 +2021-12-20 SunjeSoft Goldilocks v3.1 Standard Edition 101550.0 70 224 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 100926.0 Oracle Database 10g Standard Edition One +2022-06-30 SunjeSoft Goldilocks v3.1 Standard Edition 190443.0 70 160 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 188761.0 Microsoft SQL Server 2000 Enterprise Edition SP4 +2022-09-07 SunjeSoft Goldilocks v3.1 Standard Edition 507802.0 70 80 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression 492307.0 Microsoft SQL Server 2005 Enterprise Edition +2023-03-24 Tencent TDSQL v10.3 Enterprise Pro Edition with Partitioning and Physical Replication 814854791.0 71 1 814854791.0 Tencent TDSQL v10.3 Enterprise Pro Edition with Partitioning and Physical Replication 707351007.0 OceanBase v2.2 Enterprise Edition with Partitioning, Horizontal Scalability and Advanced Compression +2023-10-02 IBM DB2 11.5.8 Advanced Edition 279185.0 72 123 814854791.0 Tencent TDSQL v10.3 Enterprise Pro Edition with Partitioning and Physical Replication 276383.0 Sybase Adaptive Server Enterprise 15.0.3 +2024-02-26 SunjeSoft Goldilocks v3.1 Standard Edition 50768.0 72 300 814854791.0 Tencent TDSQL v10.3 Enterprise Pro Edition with Partitioning and Physical Replication 50666.11 Microsoft SQL Server 2000 Enterprise Edition SP3 diff --git a/test/sqlite/result_helper.cpp b/test/sqlite/result_helper.cpp index 713b439bb2a5..a767a9c86eae 100644 --- a/test/sqlite/result_helper.cpp +++ b/test/sqlite/result_helper.cpp @@ -263,20 +263,14 @@ bool TestResultHelper::CheckStatementResult(const Statement &statement, ExecuteC // internal errors are never expected // neither are "unoptimized result differs from original result" errors - bool internal_error = false; - if (result.HasError()) { - if (TestIsInternalError(runner.always_fail_error_messages, result.GetError())) { - internal_error = true; - } + if (result.HasError() && TestIsInternalError(runner.always_fail_error_messages, result.GetError())) { + logger.InternalException(result); + return false; } - if (!internal_error) { - if (expected_result == ExpectedResult::RESULT_UNKNOWN) { - error = false; - } else { - error = !error; - } + if (expected_result == ExpectedResult::RESULT_UNKNOWN) { + error = false; } else { - expected_result = ExpectedResult::RESULT_SUCCESS; + error = !error; } if (result.HasError() && !statement.expected_error.empty()) { if (!StringUtil::Contains(result.GetError(), statement.expected_error)) { diff --git a/test/sqlite/sqllogic_test_logger.cpp b/test/sqlite/sqllogic_test_logger.cpp index abe6ab1b06af..335d233ea744 100644 --- a/test/sqlite/sqllogic_test_logger.cpp +++ b/test/sqlite/sqllogic_test_logger.cpp @@ -277,6 +277,15 @@ void SQLLogicTestLogger::ExpectedErrorMismatch(const string &expected_error, Mat result.Print(); } +void SQLLogicTestLogger::InternalException(MaterializedQueryResult &result) { + PrintErrorHeader("Query failed with internal exception!"); + PrintLineSep(); + PrintSQL(); + PrintHeader("Actual result:"); + PrintLineSep(); + result.Print(); +} + void SQLLogicTestLogger::LoadDatabaseFail(const string &dbpath, const string &message) { PrintErrorHeader(string(), 0, "Failed to load database " + dbpath); PrintLineSep(); diff --git a/test/sqlite/sqllogic_test_logger.hpp b/test/sqlite/sqllogic_test_logger.hpp index 487935a1d929..5afb4c3b283c 100644 --- a/test/sqlite/sqllogic_test_logger.hpp +++ b/test/sqlite/sqllogic_test_logger.hpp @@ -49,6 +49,7 @@ class SQLLogicTestLogger { void WrongResultHash(QueryResult *expected_result, MaterializedQueryResult &result); void UnexpectedStatement(bool expect_ok, MaterializedQueryResult &result); void ExpectedErrorMismatch(const string &expected_error, MaterializedQueryResult &result); + void InternalException(MaterializedQueryResult &result); static void LoadDatabaseFail(const string &dbpath, const string &message); private: diff --git a/tools/juliapkg/README.md b/tools/juliapkg/README.md index 9ccc7c80de5a..e320c8d63060 100644 --- a/tools/juliapkg/README.md +++ b/tools/juliapkg/README.md @@ -134,6 +134,15 @@ julia -e "import Pkg; Pkg.activate(\".\"); include(\"test/runtests.jl\")" "test_ Just as mentioned before, to attach lldb to this, you'll have to replace the `julia` part with the absolute path. +### Automatic API generation + +A base Julia wrapper around the C-API is generated using the `update_api.sh` script (which internally calls the python script `scripts/generate_c_api_julia.py`). This script uses the definitions of DuckDB C-API to automatically generate the Julia wrapper that is complete and consistent with the C-API. To generate the wrapper, just run: + +```bash +./update_api.sh +``` + + ### Submitting a New Package The DuckDB Julia package depends on the [DuckDB_jll package](https://github.com/JuliaBinaryWrappers/DuckDB_jll.jl), which can be updated by sending a PR to [Yggdrassil](https://github.com/JuliaPackaging/Yggdrasil/pull/5049). diff --git a/tools/juliapkg/scripts/generate_c_api.py b/tools/juliapkg/scripts/generate_c_api.py new file mode 100644 index 000000000000..48a04d25d20b --- /dev/null +++ b/tools/juliapkg/scripts/generate_c_api.py @@ -0,0 +1,142 @@ +import os +import json +import re +import glob +import copy +from packaging.version import Version +from functools import reduce +from pathlib import Path + + +EXT_API_DEFINITION_PATTERN = "src/include/duckdb/main/capi/header_generation/apis/v1/*/*.json" + +# The JSON files that define all available CAPI functions +CAPI_FUNCTION_DEFINITION_FILES = 'src/include/duckdb/main/capi/header_generation/functions/**/*.json' + + +# The original order of the function groups in the duckdb.h files. We maintain this for easier PR reviews. +# TODO: replace this with alphabetical ordering in a separate PR +ORIGINAL_FUNCTION_GROUP_ORDER = [ + 'open_connect', + 'configuration', + 'query_execution', + 'result_functions', + 'safe_fetch_functions', + 'helpers', + 'date_time_timestamp_helpers', + 'hugeint_helpers', + 'unsigned_hugeint_helpers', + 'decimal_helpers', + 'prepared_statements', + 'bind_values_to_prepared_statements', + 'execute_prepared_statements', + 'extract_statements', + 'pending_result_interface', + 'value_interface', + 'logical_type_interface', + 'data_chunk_interface', + 'vector_interface', + 'validity_mask_functions', + 'scalar_functions', + 'aggregate_functions', + 'table_functions', + 'table_function_bind', + 'table_function_init', + 'table_function', + 'replacement_scans', + 'profiling_info', + 'appender', + 'table_description', + 'arrow_interface', + 'threading_information', + 'streaming_result_interface', + 'cast_functions', +] + + +def get_extension_api_version(ext_api_definitions): + latest_version = "" + + for version_entry in ext_api_definitions: + if version_entry["version"].startswith("v"): + latest_version = version_entry["version"] + if version_entry["version"].startswith("unstable_"): + break + + return latest_version + + +# Parse the CAPI_FUNCTION_DEFINITION_FILES to get the full list of functions +def parse_capi_function_definitions(function_definition_file_pattern): + # Collect all functions + # function_files = glob.glob(CAPI_FUNCTION_DEFINITION_FILES, recursive=True) + function_files = glob.glob(function_definition_file_pattern, recursive=True) + + function_groups = [] + function_map = {} + + # Read functions + for file in function_files: + with open(file, "r") as f: + try: + json_data = json.loads(f.read()) + except json.decoder.JSONDecodeError as err: + print(f"Invalid JSON found in {file}: {err}") + exit(1) + + function_groups.append(json_data) + for function in json_data["entries"]: + if function["name"] in function_map: + print(f"Duplicate symbol found when parsing C API file {file}: {function['name']}") + exit(1) + + function["group"] = json_data["group"] + if "deprecated" in json_data: + function["group_deprecated"] = json_data["deprecated"] + + function_map[function["name"]] = function + + # Reorder to match original order: purely intended to keep the PR review sane + function_groups_ordered = [] + + if len(function_groups) != len(ORIGINAL_FUNCTION_GROUP_ORDER): + print( + "The list used to match the original order of function groups in the original the duckdb.h file does not match the new one. Did you add a new function group? please also add it to ORIGINAL_FUNCTION_GROUP_ORDER for now." + ) + + for order_group in ORIGINAL_FUNCTION_GROUP_ORDER: + curr_group = next(group for group in function_groups if group["group"] == order_group) + function_groups.remove(curr_group) + function_groups_ordered.append(curr_group) + + return (function_groups_ordered, function_map) + + +# Read extension API +def parse_ext_api_definitions(ext_api_definition): + api_definitions = {} + versions = [] + dev_versions = [] + for file in list(glob.glob(ext_api_definition)): + with open(file, "r") as f: + try: + obj = json.loads(f.read()) + api_definitions[obj["version"]] = obj + if obj["version"].startswith("unstable_"): + dev_versions.append(obj["version"]) + else: + if Path(file).stem != obj["version"]: + print( + f"\nMismatch between filename and version in file for {file}. Note that unstable versions should have a version starting with 'unstable_' and that stable versions should have the version as their filename" + ) + exit(1) + versions.append(obj["version"]) + + except json.decoder.JSONDecodeError as err: + print(f"\nInvalid JSON found in {file}: {err}") + exit(1) + + versions.sort(key=Version) + dev_versions.sort() + + return [api_definitions[x] for x in (versions + dev_versions)] diff --git a/tools/juliapkg/scripts/generate_c_api_julia.py b/tools/juliapkg/scripts/generate_c_api_julia.py new file mode 100644 index 000000000000..ddd13b1b2f4a --- /dev/null +++ b/tools/juliapkg/scripts/generate_c_api_julia.py @@ -0,0 +1,882 @@ +import argparse +import logging +import os +import pathlib +import re +from types import NoneType +from typing import Dict, List, NotRequired, TypedDict, Union + +from generate_c_api import ( + EXT_API_DEFINITION_PATTERN, + get_extension_api_version, + parse_capi_function_definitions, + parse_ext_api_definitions, +) + + +class FunctionDefParam(TypedDict): + type: str + name: str + + +class FunctionDefComment(TypedDict): + description: str + param_comments: dict[str, str] + return_value: str + + +class FunctionDef(TypedDict): + name: str + group: str + deprecated: bool + group_deprecated: bool + return_type: str + params: list[FunctionDefParam] + comment: FunctionDefComment + + +class FunctionGroup(TypedDict): + group: str + deprecated: bool + entries: list[FunctionDef] + + +class DuckDBApiInfo(TypedDict): + version: str + commit: NotRequired[str] + + +def parse_c_type(type_str: str, type: list[str] = []): + """Parses simple C types (no function pointer or array types) and returns a list of the type components. + + Args: + type_str: A C type string to parse, e.g.: "const char* const" + type: List to track components, used for recursion. Defaults to []. + + Returns: + list: A list of the type components, e.g.: "const char* const" -> ["Const Ptr", "const char"] + """ + type_str = type_str.strip() + ptr_pattern = r"^(.*)\*(\s*const\s*)?$" + + if (m1 := re.match(ptr_pattern, type_str)) is not None: + before_ptr = m1.group(1) + is_const = bool(m1.group(2)) + type.append("Const Ptr" if is_const else "Ptr") + return parse_c_type(before_ptr, type) + + type.append(type_str) + return type + + +JULIA_RESERVED_KEYWORDS = { + "function", + "if", + "else", + "while", + "for", + "try", + "catch", + "finally", + "return", + "break", + "continue", + "end", + "begin", + "quote", + "let", + "local", + "global", + "const", + "do", + "struct", + "mutable", + "abstract", + "type", + "module", + "using", + "import", + "export", + "public", +} + +JULIA_BASE_TYPE_MAP = { + # Julia Standard Types + "char": "Char", + "int": "Int", + "int8_t": "Int8", + "int16_t": "Int16", + "int32_t": "Int32", + "int64_t": "Int64", + "uint8_t": "UInt8", + "uint16_t": "UInt16", + "uint32_t": "UInt32", + "uint64_t": "UInt64", + "double": "Float64", + "float": "Float32", + "bool": "Bool", + "void": "Cvoid", + "size_t": "Csize_t", + # DuckDB specific types + "idx_t": "idx_t", + "duckdb_type": "DUCKDB_TYPE", + "duckdb_string_t": "duckdb_string_t", # INLINE prefix with pointer string type + "duckdb_string": "duckdb_string", # Pointer + size type + "duckdb_table_function": "duckdb_table_function", # actually struct pointer + "duckdb_table_function_t": "duckdb_table_function_ptr", # function pointer type + "duckdb_cast_function": "duckdb_cast_function", # actually struct pointer + "duckdb_cast_function_t": "duckdb_cast_function_ptr", # function pointer type +} + + +# TODO this the original order of the functions in `api.jl` and is only used to keep the PR review small +JULIA_API_ORIGINAL_ORDER = [ + "duckdb_open", + "duckdb_open_ext", + "duckdb_close", + "duckdb_connect", + "duckdb_disconnect", + "duckdb_create_config", + "duckdb_config_count", + "duckdb_get_config_flag", + "duckdb_set_config", + "duckdb_destroy_config", + "duckdb_query", + "duckdb_destroy_result", + "duckdb_column_name", + "duckdb_column_type", + "duckdb_column_logical_type", + "duckdb_column_count", + "duckdb_row_count", + "duckdb_rows_changed", + "duckdb_column_data", + "duckdb_nullmask_data", + "duckdb_result_error", + "duckdb_result_get_chunk", + "duckdb_result_is_streaming", + "duckdb_stream_fetch_chunk", + "duckdb_result_chunk_count", + "duckdb_value_boolean", + "duckdb_value_int8", + "duckdb_value_int16", + "duckdb_value_int32", + "duckdb_value_int64", + "duckdb_value_hugeint", + "duckdb_value_uhugeint", + "duckdb_value_uint8", + "duckdb_value_uint16", + "duckdb_value_uint32", + "duckdb_value_uint64", + "duckdb_value_float", + "duckdb_value_double", + "duckdb_value_date", + "duckdb_value_time", + "duckdb_value_timestamp", + "duckdb_value_interval", + "duckdb_value_varchar", + "duckdb_value_varchar_internal", + "duckdb_value_is_null", + "duckdb_malloc", + "duckdb_free", + "duckdb_vector_size", + "duckdb_from_time_tz", + "duckdb_prepare", + "duckdb_destroy_prepare", + "duckdb_prepare_error", + "duckdb_nparams", + "duckdb_param_type", + "duckdb_bind_boolean", + "duckdb_bind_int8", + "duckdb_bind_int16", + "duckdb_bind_int32", + "duckdb_bind_int64", + "duckdb_bind_hugeint", + "duckdb_bind_uhugeint", + "duckdb_bind_uint8", + "duckdb_bind_uint16", + "duckdb_bind_uint32", + "duckdb_bind_uint64", + "duckdb_bind_float", + "duckdb_bind_double", + "duckdb_bind_date", + "duckdb_bind_time", + "duckdb_bind_timestamp", + "duckdb_bind_interval", + "duckdb_bind_varchar", + "duckdb_bind_varchar_length", + "duckdb_bind_blob", + "duckdb_bind_null", + "duckdb_execute_prepared", + "duckdb_pending_prepared", + "duckdb_pending_prepared_streaming", + "duckdb_pending_execute_check_state", + "duckdb_destroy_pending", + "duckdb_pending_error", + "duckdb_pending_execute_task", + "duckdb_execute_pending", + "duckdb_pending_execution_is_finished", + "duckdb_destroy_value", + "duckdb_create_varchar", + "duckdb_create_varchar_length", + "duckdb_create_int64", + "duckdb_get_varchar", + "duckdb_get_int64", + "duckdb_create_logical_type", + "duckdb_create_decimal_type", + "duckdb_get_type_id", + "duckdb_decimal_width", + "duckdb_decimal_scale", + "duckdb_decimal_internal_type", + "duckdb_enum_internal_type", + "duckdb_enum_dictionary_size", + "duckdb_enum_dictionary_value", + "duckdb_list_type_child_type", + "duckdb_struct_type_child_count", + "duckdb_union_type_member_count", + "duckdb_struct_type_child_name", + "duckdb_union_type_member_name", + "duckdb_struct_type_child_type", + "duckdb_union_type_member_type", + "duckdb_destroy_logical_type", + "duckdb_create_data_chunk", + "duckdb_destroy_data_chunk", + "duckdb_data_chunk_reset", + "duckdb_data_chunk_get_column_count", + "duckdb_data_chunk_get_size", + "duckdb_data_chunk_set_size", + "duckdb_data_chunk_get_vector", + "duckdb_vector_get_column_type", + "duckdb_vector_get_data", + "duckdb_vector_get_validity", + "duckdb_vector_ensure_validity_writable", + "duckdb_list_vector_get_child", + "duckdb_list_vector_get_size", + "duckdb_struct_vector_get_child", + "duckdb_union_vector_get_member", + "duckdb_vector_assign_string_element", + "duckdb_vector_assign_string_element_len", + "duckdb_create_table_function", + "duckdb_destroy_table_function", + "duckdb_table_function_set_name", + "duckdb_table_function_add_parameter", + "duckdb_table_function_set_extra_info", + "duckdb_table_function_set_bind", + "duckdb_table_function_set_init", + "duckdb_table_function_set_local_init", + "duckdb_table_function_set_function", + "duckdb_table_function_supports_projection_pushdown", + "duckdb_register_table_function", + "duckdb_bind_get_extra_info", + "duckdb_bind_add_result_column", + "duckdb_bind_get_parameter_count", + "duckdb_bind_get_parameter", + "duckdb_bind_set_bind_data", + "duckdb_bind_set_cardinality", + "duckdb_bind_set_error", + "duckdb_init_get_extra_info", + "duckdb_init_get_bind_data", + "duckdb_init_set_init_data", + "duckdb_init_get_column_count", + "duckdb_init_get_column_index", + "duckdb_init_set_max_threads", + "duckdb_init_set_error", + "duckdb_function_get_extra_info", + "duckdb_function_get_bind_data", + "duckdb_function_get_init_data", + "duckdb_function_get_local_init_data", + "duckdb_function_set_error", + "duckdb_add_replacement_scan", + "duckdb_replacement_scan_set_function_name", + "duckdb_replacement_scan_add_parameter", + "duckdb_replacement_scan_set_error", + "duckdb_appender_create", + "duckdb_appender_error", + "duckdb_appender_flush", + "duckdb_appender_close", + "duckdb_appender_destroy", + "duckdb_appender_begin_row", + "duckdb_appender_end_row", + "duckdb_append_bool", + "duckdb_append_int8", + "duckdb_append_int16", + "duckdb_append_int32", + "duckdb_append_int64", + "duckdb_append_hugeint", + "duckdb_append_uhugeint", + "duckdb_append_uint8", + "duckdb_append_uint16", + "duckdb_append_uint32", + "duckdb_append_uint64", + "duckdb_append_float", + "duckdb_append_double", + "duckdb_append_date", + "duckdb_append_time", + "duckdb_append_timestamp", + "duckdb_append_interval", + "duckdb_append_varchar", + "duckdb_append_varchar_length", + "duckdb_append_blob", + "duckdb_append_null", + "duckdb_execute_tasks", + "duckdb_create_task_state", + "duckdb_execute_tasks_state", + "duckdb_execute_n_tasks_state", + "duckdb_finish_execution", + "duckdb_task_state_is_finished", + "duckdb_destroy_task_state", + "duckdb_execution_is_finished", + "duckdb_create_scalar_function", + "duckdb_destroy_scalar_function", + "duckdb_scalar_function_set_name", + "duckdb_scalar_function_add_parameter", + "duckdb_scalar_function_set_return_type", + "duckdb_scalar_function_set_function", + "duckdb_register_scalar_function", +] + + +class JuliaApiTarget: + indent: int = 0 + linesep: str = os.linesep + type_maps: dict[str, str] = {} # C to Julia + inverse_type_maps: dict[str, list[str]] = {} # Julia to C + deprecated_functions: list[str] = [] + type_map: dict[str, str] + + # Functions to skip + skipped_functions = set() + skip_deprecated_functions = False + + # Explicit function order + manual_order: Union[List[str], NoneType] = None + + overwrite_function_signatures = {} + + # Functions that use indices either as ARG or RETURN and should be converted to 1-based indexing + auto_1base_index: bool + auto_1base_index_return_functions = set() + auto_1base_index_ignore_functions = set() + + def __init__( + self, + file, + indent=0, + auto_1base_index=True, + auto_1base_index_return_functions=set(), + auto_1base_index_ignore_functions=set(), + skipped_functions=set(), + skip_deprecated_functions=False, + type_map={}, + overwrite_function_signatures={}, + ): + # check if file is a string or a file object + if isinstance(file, str) or isinstance(file, pathlib.Path): + self.filename = pathlib.Path(file) + else: + raise ValueError("file must be a string or a path object") + self.indent = indent + self.auto_1base_index = auto_1base_index + self.auto_1base_index_return_functions = auto_1base_index_return_functions + self.auto_1base_index_ignore_functions = auto_1base_index_ignore_functions + self.linesep = os.linesep + self.type_map = type_map + self.skipped_functions = skipped_functions + self.skip_deprecated_functions = skip_deprecated_functions + self.overwrite_function_signatures = overwrite_function_signatures + super().__init__() + + def __enter__(self): + self.file = open(self.filename, "w") + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.file.close() + + def write_empty_line(self, n=1) -> None: + """Writes an empty line to the output file.""" + for i in range(n): + self.file.write(self.linesep) + + def _get_casted_type(self, type_str: str, is_return_arg=False, auto_remove_t_suffix=True): + type_str = type_str.strip() + type_definition = parse_c_type(type_str, []) + + def reduce_type(type_list: list[str]): + if len(type_list) == 0: + return "" + + t = type_list[0] + if len(type_list) == 1: + is_const = False # Track that the type is const, even though we cannot use it in Julia + if t.startswith("const "): + t, is_const = t.removeprefix("const "), True + + if t in self.type_map: + return self.type_map[t] + else: + if auto_remove_t_suffix and t.endswith("_t"): + t = t.removesuffix("_t") + if " " in t: + raise (ValueError(f"Unknown type: {t}")) + return t + + # Handle Pointer types + if t not in ("Ptr", "Const Ptr"): + raise ValueError(f"Unexpected non-pointer type: {t}") + + if len(type_list) >= 2 and type_list[1].strip() in ( + "char", + "const char", + ): + return "Cstring" + else: + if is_return_arg: + # Use Ptr for return types, because they are not tracked by the Julia GC + return "Ptr{" + reduce_type(type_list[1:]) + "}" + else: + # Prefer Ref over Ptr for arguments + return "Ref{" + reduce_type(type_list[1:]) + "}" + + return reduce_type(type_definition) + + def _is_index_argument(self, name: str, function_obj: FunctionDef): + # Check if the argument is (likely) an index + if name not in ( + "index", + "idx", + "i", + "row", + "col", + "column", + "col_idx", + "column_idx", + "column_index", + "row_idx", + "row_index", + "chunk_index", + # "param_idx", # TODO creates errors in bind_param + ): + return False + + x = None + for param in function_obj["params"]: + if param["name"] == name: + x = param + break + + arg_type = self._get_casted_type(x["type"]) + if arg_type not in ( + "Int", + "Int64", + "UInt", + "UInt64", + "idx_t", + "idx" "Int32", + "UInt32", + "Csize_t", + ): + return False + + return True + + def get_argument_names_and_types(self, function_obj: FunctionDef): + def _get_arg_name(name: str): + if name in JULIA_RESERVED_KEYWORDS: + return f"_{name}" + return name + + arg_names = [_get_arg_name(param["name"]) for param in function_obj["params"]] + + if function_obj["name"] in self.overwrite_function_signatures: + return_type, arg_types = self.overwrite_function_signatures[function_obj["name"]] + return arg_names, arg_types + + arg_types = [self._get_casted_type(param["type"]) for param in function_obj["params"]] + return arg_names, arg_types + + def _write_function_docstring(self, function_obj: FunctionDef): + r"""_create_function_docstring + + + Example: + ```julia + \"\"\" + duckdb_get_int64(value) + + Obtains an int64 of the given value. + + # Arguments + - `value`: The value + + Returns: The int64 value, or 0 if no conversion is possible + \"\"\" + ``` + + Args: + function_obj: _description_ + """ + + description = function_obj.get("comment", {}).get("description", "").strip() + description = description.replace('"', '\\"') # escape double quotes + arg_names, arg_types = self.get_argument_names_and_types(function_obj) + arg_names_s = ", ".join(arg_names) + arg_comments = [ + function_obj.get("comment", {}).get("param_comments", {}).get(param["name"], "") + for param in function_obj["params"] + ] + + return_value_comment = function_obj.get("comment", {}).get("return_value", "nothing") + + self.file.write(f"{' ' * self.indent}\"\"\"\n") + self.file.write(f"{' ' * self.indent} {function_obj['name']}({arg_names_s})\n") + self.file.write(f"{' ' * self.indent}\n") + self.file.write(f"{' ' * self.indent}{description}\n") + self.file.write(f"{' ' * self.indent}\n") + self.file.write(f"{' ' * self.indent}# Arguments\n") + for i, arg_name in enumerate(arg_names): + self.file.write(f"{' ' * self.indent}- `{arg_name}`: {arg_comments[i]}\n") + self.file.write(f"{' ' * self.indent}\n") + self.file.write(f"{' ' * self.indent}Returns: {return_value_comment}\n") + self.file.write(f"{' ' * self.indent}\"\"\"\n") + + def _get_depwarning_message(self, function_obj: FunctionDef): + description = function_obj.get("comment", {}).get("description", "") + if not description.startswith("**DEPRECATION NOTICE**:"): + description = f"**DEPRECATION NOTICE**: {description}" + + # Only use the first line of the description + notice = description.split("\n")[0] + notice = notice.replace("\n", " ").replace('"', '\\"').strip() + return notice + + def _write_function_depwarn(self, function_obj: FunctionDef, indent: int = 0): + """ + Writes a deprecation warning for a function. + + Example: + ```julia + Base.depwarn( + "The `G` type parameter will be deprecated in a future release. " * + "Please use `MyType(args...)` instead of `MyType{$G}(args...)`.", + :MyType, + ) + ``` + """ + indent = self.indent + indent # total indent + + notice = self._get_depwarning_message(function_obj) + + self.file.write(f"{' ' * indent}Base.depwarn(\n") + self.file.write(f"{' ' * indent} \"{notice}\",\n") + self.file.write(f"{' ' * indent} :{function_obj['name']},\n") + self.file.write(f"{' ' * indent})\n") + + def _list_to_julia_tuple(self, lst): + if len(lst) == 0: + return "()" + elif len(lst) == 1: + return f"({lst[0]},)" + else: + return f"({', '.join(lst)})" + + def _write_function_definition(self, function_obj: FunctionDef): + fname = function_obj["name"] + arg_names, arg_types = self.get_argument_names_and_types(function_obj) + arg_types_tuple = self._list_to_julia_tuple(arg_types) + arg_names_definition = ", ".join(arg_names) + arg_names_call = ", ".join( + [ + ( + f"{arg_name} - 1" # 1-based index + if self.auto_1base_index + and fname not in self.auto_1base_index_ignore_functions + and self._is_index_argument(arg_name, function_obj) + else arg_name + ) + for arg_name in arg_names + ] + ) + + return_type = self._get_casted_type(function_obj["return_type"], is_return_arg=True) + + is_index1_function = ( + fname not in self.auto_1base_index_ignore_functions + and self.auto_1base_index + and fname in self.auto_1base_index_return_functions + ) + + self.file.write(f"{' ' * self.indent}function {fname}({arg_names_definition})\n") + + if function_obj.get("group_deprecated", False) or function_obj.get("deprecated", False): + self._write_function_depwarn(function_obj, indent=1) + + self.file.write( + f"{' ' * self.indent} return ccall((:{fname}, libduckdb), {return_type}, {arg_types_tuple}, {arg_names_call}){' + 1' if is_index1_function else ''}\n" + ) + self.file.write(f"{' ' * self.indent}end\n") + + def write_function(self, function_obj: FunctionDef): + if function_obj["name"] in self.skipped_functions: + return + + if function_obj.get("group_deprecated", False) or function_obj.get("deprecated", False): + self.deprecated_functions.append(function_obj["name"]) + + self._write_function_docstring(function_obj) + self._write_function_definition(function_obj) + + def write_footer(self): + self.write_empty_line(n=1) + s = """ +# !!!!!!!!!!!! +# WARNING: this file is autogenerated by scripts/generate_c_api_julia.py, manual changes will be overwritten +# !!!!!!!!!!!! +""" + self.file.write(s) + self.write_empty_line() + + def write_header(self, version=""): + s = """ +############################################################################### +# +# DuckDB Julia API +# +# !!!!!!!!!!!! +# WARNING: this file is autogenerated by scripts/generate_c_api_julia.py, manual changes will be overwritten +# !!!!!!!!!!!! +# +############################################################################### + +using Base.Libc + +if "JULIA_DUCKDB_LIBRARY" in keys(ENV) + libduckdb = ENV["JULIA_DUCKDB_LIBRARY"] +else + using DuckDB_jll +end +""" + if version[0] == "v": + # remove the v prefix and use Julia Version String + version = version[1:] + + self.file.write(s) + self.file.write("\n") + self.file.write(f'DUCKDB_API_VERSION = v"{version}"\n') + self.file.write("\n") + + def write_functions( + self, + version, + function_groups: List[FunctionGroup], + function_map: Dict[str, FunctionDef], + ): + self._analyze_types(function_groups) # Create the julia type map + self.write_header(version) + self.write_empty_line() + if self.manual_order is not None: + current_group = None + for f in self.manual_order: + if f not in function_map: + print(f"WARNING: Function {f} not found in function_map") + continue + + if current_group != function_map[f]["group"]: + current_group = function_map[f]["group"] + self.write_group_start(current_group) + self.write_empty_line() + + self.write_function(function_map[f]) + self.write_empty_line() + + # Write new functions + self.write_empty_line(n=1) + self.write_group_start("New Functions") + self.write_empty_line(n=2) + current_group = None + for group in function_groups: + for fn in group["entries"]: + if fn["name"] in self.manual_order: + continue + if current_group != group["group"]: + current_group = group["group"] + self.write_group_start(current_group) + self.write_empty_line() + + self.write_function(fn) + self.write_empty_line() + + else: + for group in function_groups: + self.write_group_start(group["group"]) + self.write_empty_line() + for fn in group["entries"]: + self.write_function(fn) + self.write_empty_line() + self.write_empty_line() + self.write_empty_line() + + self.write_footer() + + def _analyze_types(self, groups: List[FunctionGroup]): + for group in groups: + for fn in group["entries"]: + for param in fn["params"]: + if param["type"] not in self.type_maps: + self.type_maps[param["type"]] = self._get_casted_type(param["type"]) + if fn["return_type"] not in self.type_maps: + self.type_maps[fn["return_type"]] = self._get_casted_type(fn["return_type"]) + + for k, v in self.type_maps.items(): + if v not in self.inverse_type_maps: + self.inverse_type_maps[v] = [] + self.inverse_type_maps[v].append(k) + return + + def write_group_start(self, group): + group = group.replace("_", " ").strip() + # make group title uppercase + group = " ".join([x.capitalize() for x in group.split(" ")]) + self.file.write(f"# {'-' * 80}\n") + self.file.write(f"# {group}\n") + self.file.write(f"# {'-' * 80}\n") + + @staticmethod + def get_function_order(filepath): + path = pathlib.Path(filepath) + if not path.exists() or not path.is_file(): + raise FileNotFoundError(f"File {path} does not exist") + + with open(path, "r") as f: + lines = f.readlines() + + is_julia_file = path.suffix == ".jl" + + if not is_julia_file: + # read the file and assume that we have a function name per line + return [x.strip() for x in lines if x.strip() != ""] + + # find the function definitions + # TODO this a very simple regex that only supports the long function form `function name(...)` + function_regex = r"^function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(" + function_order = [] + for line in lines: + line = line.strip() + if line.startswith("#"): + continue + + m = re.match(function_regex, line) + if m is not None: + function_order.append(m.group(1)) + return function_order + + +def main(): + """Main function to generate the Julia API.""" + + print("Creating Julia API") + + parser = configure_parser() + args = parser.parse_args() + print("Arguments:") + for k, v in vars(args).items(): + print(f" {k}: {v}") + + julia_path = pathlib.Path(args.output) + enable_auto_1base_index = args.auto_1_index + enable_original_order = args.use_original_order + + capi_defintions_dir = pathlib.Path(args.capi_dir) + ext_api_definition_pattern = str(capi_defintions_dir) + "/apis/v1/*/*.json" + capi_function_definition_pattern = str(capi_defintions_dir) + "/functions/**/*.json" + ext_api_definitions = parse_ext_api_definitions(ext_api_definition_pattern) + ext_api_version = get_extension_api_version(ext_api_definitions) + function_groups, function_map = parse_capi_function_definitions(capi_function_definition_pattern) + + overwrite_function_signatures = { + # Must be Ptr{Cvoid} and not Ref + "duckdb_free": ( + "Cvoid", + ("Ptr{Cvoid}",), + ), + "duckdb_bind_blob": ( + "duckdb_state", + ("duckdb_prepared_statement", "idx_t", "Ptr{Cvoid}", "idx_t"), + ), + } + + with JuliaApiTarget( + julia_path, + indent=0, + auto_1base_index=enable_auto_1base_index, # WARNING: every arg named "col/row/index" or similar will be 1-based indexed, so the argument is subtracted by 1 + auto_1base_index_return_functions={"duckdb_init_get_column_index"}, + auto_1base_index_ignore_functions={ + "duckdb_parameter_name", # Parameter names start at 1 + "duckdb_param_type", # Parameter types (like names) start at 1 + "duckdb_param_logical_type", # ... + "duckdb_bind_get_parameter", # Would be breaking API change + }, + skipped_functions={}, + type_map=JULIA_BASE_TYPE_MAP, + overwrite_function_signatures=overwrite_function_signatures, + ) as printer: + if enable_original_order: + print("INFO: Using the original order of the functions from the old API file.") + printer.manual_order = JULIA_API_ORIGINAL_ORDER + + printer.write_functions(ext_api_version, function_groups, function_map) + + if args.print_type_mapping: + print("Type maps: (Julia Type -> C Type)") + K = list(printer.inverse_type_maps.keys()) + K.sort() + for k in K: + if k.startswith("Ptr") or k.startswith("Ref"): + continue + v = ", ".join(printer.inverse_type_maps[k]) + print(f" {k} -> {v}") + + print("Julia API generated successfully!") + print("Please review the mapped types and check the generated file:") + print("Hint: also run './format.sh' to format the file and reduce the diff.") + print(f"Output: {julia_path}") + + +def configure_parser(): + parser = argparse.ArgumentParser(description="Generate the DuckDB Julia API") + parser.add_argument( + "--auto-1-index", + action="store_true", + default=True, + help="Automatically convert 0-based indices to 1-based indices", + ) + parser.add_argument( + "--use-original-order", + action="store_true", + default=False, + help="Use the original order of the functions from the old API file. New functions will be appended at the end.", + ) + + parser.add_argument( + "--print-type-mapping", + action="store_true", + default=False, + help="Print the type mapping from C to Julia", + ) + + parser.add_argument( + "--capi-dir", + type=str, + required=True, + help="Path to the input C API definitions. Should be a directory containing JSON files.", + ) + parser.add_argument( + "output", + type=str, + # default="src/api.jl", + help="Path to the output file", + ) + return parser + + +if __name__ == "__main__": + main() diff --git a/tools/juliapkg/src/DuckDB.jl b/tools/juliapkg/src/DuckDB.jl index 429c36efc4cb..0f9afa2209b2 100644 --- a/tools/juliapkg/src/DuckDB.jl +++ b/tools/juliapkg/src/DuckDB.jl @@ -19,6 +19,7 @@ include("helper.jl") include("exceptions.jl") include("ctypes.jl") include("api.jl") +include("api_helper.jl") include("logical_type.jl") include("value.jl") include("validity_mask.jl") diff --git a/tools/juliapkg/src/api.jl b/tools/juliapkg/src/api.jl index 0fb2b425d603..8f0ae931e221 100644 --- a/tools/juliapkg/src/api.jl +++ b/tools/juliapkg/src/api.jl @@ -1,3 +1,14 @@ + +############################################################################### +# +# DuckDB Julia API +# +# !!!!!!!!!!!! +# WARNING: this file is autogenerated by scripts/generate_c_api_julia.py, manual changes will be overwritten +# !!!!!!!!!!!! +# +############################################################################### + using Base.Libc if "JULIA_DUCKDB_LIBRARY" in keys(ENV) @@ -6,60 +17,86 @@ else using DuckDB_jll end -#=//===--------------------------------------------------------------------===// -// Open/Connect -//===--------------------------------------------------------------------===// -=# +DUCKDB_API_VERSION = v"1.2.0" + + +# -------------------------------------------------------------------------------- +# Open Connect +# -------------------------------------------------------------------------------- + """ - duckdb_open(path, out_database) + duckdb_open(path, out_database) + Creates a new database or opens an existing database file stored at the given path. If no path is given a new in-memory database is created instead. -* `path`: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. -* `out_database`: The result database object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +The instantiated database should be closed with 'duckdb_close'. + +# Arguments +- `path`: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. +- `out_database`: The result database object. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_open(path, out_database) - return ccall((:duckdb_open, libduckdb), duckdb_state, (Ptr{UInt8}, Ref{duckdb_database}), path, out_database) + return ccall((:duckdb_open, libduckdb), duckdb_state, (Cstring, Ref{duckdb_database}), path, out_database) end + """ - Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the given path. + duckdb_open_ext(path, out_database, config, out_error) + +Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the given path. +The instantiated database should be closed with 'duckdb_close'. + +# Arguments +- `path`: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. +- `out_database`: The result database object. +- `config`: (Optional) configuration used to start up the database system. +- `out_error`: If set and the function returns DuckDBError, this will contain the reason why the start-up failed. +Note that the error must be freed using `duckdb_free`. - * path: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. - * out_database: The result database object. - * config: (Optional) configuration used to start up the database system. - * out_error: If set and the function returns DuckDBError, this will contain the reason why the start-up failed. - Note that the error must be freed using `duckdb_free`. - * returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_open_ext(path, out_database, config, out_error) return ccall( (:duckdb_open_ext, libduckdb), duckdb_state, - (Ptr{UInt8}, Ref{duckdb_database}, duckdb_config, Ptr{Ptr{UInt8}}), + (Cstring, Ref{duckdb_database}, duckdb_config, Ref{Cstring}), path, out_database, config, out_error ) end + """ - duckdb_close(database) + duckdb_close(database) + Closes the specified database and de-allocates all memory allocated for that database. -This should be called after you are done with any database allocated through `duckdb_open`. +This should be called after you are done with any database allocated through `duckdb_open` or `duckdb_open_ext`. Note that failing to call `duckdb_close` (in case of e.g. a program crash) will not cause data corruption. -Still it is recommended to always correctly close a database object after you are done with it. -* `database`: The database object to shut down. +Still, it is recommended to always correctly close a database object after you are done with it. + +# Arguments +- `database`: The database object to shut down. + +Returns: nothing """ function duckdb_close(database) return ccall((:duckdb_close, libduckdb), Cvoid, (Ref{duckdb_database},), database) end + """ - duckdb_connect(database, out_connection) + duckdb_connect(database, out_connection) + Opens a connection to a database. Connections are required to query the database, and store transactional state associated with the connection. -* `database`: The database file to connect to. -* `out_connection`: The result connection object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +The instantiated connection should be closed using 'duckdb_disconnect'. + +# Arguments +- `database`: The database file to connect to. +- `out_connection`: The result connection object. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_connect(database, out_connection) return ccall( @@ -72,117 +109,193 @@ function duckdb_connect(database, out_connection) end """ - duckdb_disconnect(connection) + duckdb_interrupt(connection) + +Interrupt running query + +# Arguments +- `connection`: The connection to interrupt + +Returns: nothing +""" +function duckdb_interrupt(connection) + return ccall((:duckdb_interrupt, libduckdb), Cvoid, (duckdb_connection,), connection) +end + +""" + duckdb_query_progress(connection) + +Get progress of the running query + +# Arguments +- `connection`: The working connection + +Returns: -1 if no progress or a percentage of the progress +""" +function duckdb_query_progress(connection) + return ccall((:duckdb_query_progress, libduckdb), duckdb_query_progress_type, (duckdb_connection,), connection) +end + +""" + duckdb_disconnect(connection) + Closes the specified connection and de-allocates all memory allocated for that connection. -* `connection`: The connection to close. + +# Arguments +- `connection`: The connection to close. + +Returns: nothing """ function duckdb_disconnect(connection) return ccall((:duckdb_disconnect, libduckdb), Cvoid, (Ref{duckdb_connection},), connection) end -#= -//===--------------------------------------------------------------------===// -// Configuration -//===--------------------------------------------------------------------===// -=# +""" + duckdb_library_version() + +Returns the version of the linked DuckDB, with a version postfix for dev versions + +Usually used for developing C extensions that must return this for a compatibility check. + +# Arguments + +Returns: nothing +""" +function duckdb_library_version() + return ccall((:duckdb_library_version, libduckdb), Cstring, ()) +end + + + +# -------------------------------------------------------------------------------- +# Configuration +# -------------------------------------------------------------------------------- """ - duckdb_create_config(config) + duckdb_create_config(out_config) + Initializes an empty configuration object that can be used to provide start-up options for the DuckDB instance through `duckdb_open_ext`. +The duckdb_config must be destroyed using 'duckdb_destroy_config' + This will always succeed unless there is a malloc failure. -* `out_config`: The result configuration object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. + +Note that `duckdb_destroy_config` should always be called on the resulting config, even if the function returns +`DuckDBError`. + +# Arguments +- `out_config`: The result configuration object. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ -function duckdb_create_config(config) - return ccall((:duckdb_create_config, libduckdb), duckdb_state, (Ref{duckdb_config},), config) +function duckdb_create_config(out_config) + return ccall((:duckdb_create_config, libduckdb), duckdb_state, (Ref{duckdb_config},), out_config) end """ - duckdb_config_count() + duckdb_config_count() + This returns the total amount of configuration options available for usage with `duckdb_get_config_flag`. + This should not be called in a loop as it internally loops over all the options. -* returns: The amount of config options available. + +# Arguments + +Returns: The amount of config options available. """ function duckdb_config_count() - return ccall((:duckdb_config_count, libduckdb), Int32, ()) + return ccall((:duckdb_config_count, libduckdb), Csize_t, ()) end """ - duckdb_get_config_flag(index,out_name,out_description) + duckdb_get_config_flag(index, out_name, out_description) + Obtains a human-readable name and description of a specific configuration option. This can be used to e.g. display configuration options. This will succeed unless `index` is out of range (i.e. `>= duckdb_config_count`). + The result name or description MUST NOT be freed. -* `index`: The index of the configuration option (between 0 and `duckdb_config_count`) -* `out_name`: A name of the configuration flag. -* `out_description`: A description of the configuration flag. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. + +# Arguments +- `index`: The index of the configuration option (between 0 and `duckdb_config_count`) +- `out_name`: A name of the configuration flag. +- `out_description`: A description of the configuration flag. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_get_config_flag(index, out_name, out_description) return ccall( (:duckdb_get_config_flag, libduckdb), duckdb_state, - (Int32, Ptr{Ptr{UInt8}}, Ptr{Ptr{UInt8}}), - index, + (Csize_t, Ref{Cstring}, Ref{Cstring}), + index - 1, out_name, out_description ) end """ - duckdb_set_config(config,name,option) + duckdb_set_config(config, name, option) + Sets the specified option for the specified configuration. The configuration option is indicated by name. To obtain a list of config options, see `duckdb_get_config_flag`. + In the source code, configuration options are defined in `config.cpp`. + This can fail if either the name is invalid, or if the value provided for the option is invalid. -* `duckdb_config`: The configuration object to set the option on. -* `name`: The name of the configuration flag to set. -* `option`: The value to set the configuration flag to. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. + +# Arguments +- `config`: The configuration object to set the option on. +- `name`: The name of the configuration flag to set. +- `option`: The value to set the configuration flag to. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_set_config(config, name, option) - return ccall( - (:duckdb_set_config, libduckdb), - duckdb_state, - (duckdb_config, Ptr{UInt8}, Ptr{UInt8}), - config, - name, - option - ) + return ccall((:duckdb_set_config, libduckdb), duckdb_state, (duckdb_config, Cstring, Cstring), config, name, option) end """ - duckdb_destroy_config(config) -Destroys the specified configuration option and de-allocates all memory allocated for the object. -* `config`: The configuration object to destroy. + duckdb_destroy_config(config) + +Destroys the specified configuration object and de-allocates all memory allocated for the object. + +# Arguments +- `config`: The configuration object to destroy. + +Returns: nothing """ function duckdb_destroy_config(config) return ccall((:duckdb_destroy_config, libduckdb), Cvoid, (Ref{duckdb_config},), config) end -#= -//===--------------------------------------------------------------------===// -// Query Execution -//===--------------------------------------------------------------------===// -=# + + +# -------------------------------------------------------------------------------- +# Query Execution +# -------------------------------------------------------------------------------- """ - duckdb_query(connection,query,out_result) + duckdb_query(connection, query, out_result) + Executes a SQL query within a connection and stores the full (materialized) result in the out_result pointer. If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling `duckdb_result_error`. + Note that after running `duckdb_query`, `duckdb_destroy_result` must be called on the result object even if the query fails, otherwise the error stored within the result will not be freed correctly. -* `connection`: The connection to perform the query in. -* `query`: The SQL query to run. -* `out_result`: The query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. + +# Arguments +- `connection`: The connection to perform the query in. +- `query`: The SQL query to run. +- `out_result`: The query result. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. """ function duckdb_query(connection, query, out_result) return ccall( (:duckdb_query, libduckdb), duckdb_state, - (duckdb_connection, Ptr{UInt8}, Ref{duckdb_result}), + (duckdb_connection, Cstring, Ref{duckdb_result}), connection, query, out_result @@ -190,275 +303,458 @@ function duckdb_query(connection, query, out_result) end """ - duckdb_destroy_result(result) + duckdb_destroy_result(result) + Closes the result and de-allocates all memory allocated for that connection. -* `result`: The result to destroy. + +# Arguments +- `result`: The result to destroy. + +Returns: nothing """ function duckdb_destroy_result(result) return ccall((:duckdb_destroy_result, libduckdb), Cvoid, (Ref{duckdb_result},), result) end """ - duckdb_column_name(result,col) -Returns the column name of the specified column. The result should not need be freed; the column names will + duckdb_column_name(result, col) + +Returns the column name of the specified column. The result should not need to be freed; the column names will automatically be destroyed when the result is destroyed. + Returns `NULL` if the column is out of range. -* `result`: The result object to fetch the column name from. -* `col`: The column index. -* returns: The column name of the specified column. + +# Arguments +- `result`: The result object to fetch the column name from. +- `col`: The column index. + +Returns: The column name of the specified column. """ function duckdb_column_name(result, col) - return ccall((:duckdb_column_name, libduckdb), Ptr{UInt8}, (Ref{duckdb_result}, Int32), result, col - 1) + return ccall((:duckdb_column_name, libduckdb), Cstring, (Ref{duckdb_result}, idx_t), result, col - 1) end """ - duckdb_column_type(result,col) + duckdb_column_type(result, col) + Returns the column type of the specified column. + Returns `DUCKDB_TYPE_INVALID` if the column is out of range. -* `result`: The result object to fetch the column type from. -* `col`: The column index. -* returns: The column type of the specified column. + +# Arguments +- `result`: The result object to fetch the column type from. +- `col`: The column index. + +Returns: The column type of the specified column. """ function duckdb_column_type(result, col) - return ccall((:duckdb_column_type, libduckdb), DUCKDB_TYPE, (Ref{duckdb_result}, Int32), result, col - 1) + return ccall((:duckdb_column_type, libduckdb), DUCKDB_TYPE, (Ref{duckdb_result}, idx_t), result, col - 1) +end + +""" + duckdb_result_statement_type(result) + +Returns the statement type of the statement that was executed + +# Arguments +- `result`: The result object to fetch the statement type from. + +Returns: duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID +""" +function duckdb_result_statement_type(result) + return ccall((:duckdb_result_statement_type, libduckdb), duckdb_statement_type, (duckdb_result,), result) end """ + duckdb_column_logical_type(result, col) + Returns the logical column type of the specified column. The return type of this call should be destroyed with `duckdb_destroy_logical_type`. Returns `NULL` if the column is out of range. -* result: The result object to fetch the column type from. -* col: The column index. -* returns: The logical column type of the specified column. +# Arguments +- `result`: The result object to fetch the column type from. +- `col`: The column index. + +Returns: The logical column type of the specified column. """ function duckdb_column_logical_type(result, col) return ccall( (:duckdb_column_logical_type, libduckdb), duckdb_logical_type, - (Ref{duckdb_result}, Int32), + (Ref{duckdb_result}, idx_t), result, col - 1 ) end """ - duckdb_column_count(result) + duckdb_column_count(result) + Returns the number of columns present in a the result object. -* `result`: The result object. -* returns: The number of columns present in the result object. + +# Arguments +- `result`: The result object. + +Returns: The number of columns present in the result object. """ function duckdb_column_count(result) - return ccall((:duckdb_column_count, libduckdb), Int32, (Ref{duckdb_result},), result) + return ccall((:duckdb_column_count, libduckdb), idx_t, (Ref{duckdb_result},), result) end """ - duckdb_row_count(result) -Returns the number of rows present in a the result object. -* `result`: The result object. -* returns: The number of rows present in the result object. + duckdb_row_count(result) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +Returns the number of rows present in the result object. + +# Arguments +- `result`: The result object. + +Returns: The number of rows present in the result object. """ function duckdb_row_count(result) - return ccall((:duckdb_row_count, libduckdb), Int64, (Ref{duckdb_result},), result) + Base.depwarn("**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", :duckdb_row_count) + return ccall((:duckdb_row_count, libduckdb), idx_t, (Ref{duckdb_result},), result) end """ - duckdb_rows_changed(result) + duckdb_rows_changed(result) + Returns the number of rows changed by the query stored in the result. This is relevant only for INSERT/UPDATE/DELETE queries. For other queries the rows_changed will be 0. -* `result`: The result object. -* returns: The number of rows changed. + +# Arguments +- `result`: The result object. + +Returns: The number of rows changed. """ function duckdb_rows_changed(result) - return ccall((:duckdb_rows_changed, libduckdb), Int64, (Ptr{Cvoid},), result) + return ccall((:duckdb_rows_changed, libduckdb), idx_t, (Ref{duckdb_result},), result) end """ - duckdb_column_data(result,col) -Returns the data of a specific column of a result in columnar format. This is the fastest way of accessing data in a -query result, as no conversion or type checking must be performed (outside of the original switch). If performance -is a concern, it is recommended to use this API over the `duckdb_value` functions. + duckdb_column_data(result, col) + +**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. + +Returns the data of a specific column of a result in columnar format. + The function returns a dense array which contains the result data. The exact type stored in the array depends on the corresponding duckdb_type (as provided by `duckdb_column_type`). For the exact type by which the data should be accessed, see the comments in [the types section](types) or the `DUCKDB_TYPE` enum. + For example, for a column of type `DUCKDB_TYPE_INTEGER`, rows can be accessed in the following manner: ```c int32_t *data = (int32_t *) duckdb_column_data(&result, 0); -printf("Data for row %d: %d\\n", row, data[row]); +printf(\"Data for row %d: %d\n\", row, data[row]); ``` -* `result`: The result object to fetch the column data from. -* `col`: The column index. -* returns: The column data of the specified column. + +# Arguments +- `result`: The result object to fetch the column data from. +- `col`: The column index. + +Returns: The column data of the specified column. """ function duckdb_column_data(result, col) - return ccall((:duckdb_column_data, libduckdb), Ptr{Cvoid}, (Ref{duckdb_result}, Int32), result, col - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: **DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead.", + :duckdb_column_data + ) + return ccall((:duckdb_column_data, libduckdb), Ptr{Cvoid}, (Ref{duckdb_result}, idx_t), result, col - 1) end """ - duckdb_nullmask_data(result,col) + duckdb_nullmask_data(result, col) + +**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. + Returns the nullmask of a specific column of a result in columnar format. The nullmask indicates for every row whether or not the corresponding row is `NULL`. If a row is `NULL`, the values present in the array provided by `duckdb_column_data` are undefined. + ```c int32_t *data = (int32_t *) duckdb_column_data(&result, 0); bool *nullmask = duckdb_nullmask_data(&result, 0); if (nullmask[row]) { - printf("Data for row %d: NULL\n", row); + printf(\"Data for row %d: NULL\n\", row); } else { - printf("Data for row %d: %d\n", row, data[row]); + printf(\"Data for row %d: %d\n\", row, data[row]); } ``` -* `result`: The result object to fetch the nullmask from. -* `col`: The column index. -* returns: The nullmask of the specified column. + +# Arguments +- `result`: The result object to fetch the nullmask from. +- `col`: The column index. + +Returns: The nullmask of the specified column. """ function duckdb_nullmask_data(result, col) - return ccall((:duckdb_nullmask_data, libduckdb), Ptr{Int32}, (Ref{duckdb_result}, Int32), result, col - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: **DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead.", + :duckdb_nullmask_data + ) + return ccall((:duckdb_nullmask_data, libduckdb), Ptr{Bool}, (Ref{duckdb_result}, idx_t), result, col - 1) end """ - duckdb_result_error(result) + duckdb_result_error(result) + Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. + The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. -* `result`: The result object to fetch the nullmask from. -* returns: The error of the result. + +# Arguments +- `result`: The result object to fetch the error from. + +Returns: The error of the result. """ function duckdb_result_error(result) - return ccall((:duckdb_result_error, libduckdb), Ptr{UInt8}, (Ref{duckdb_result},), result) + return ccall((:duckdb_result_error, libduckdb), Cstring, (Ref{duckdb_result},), result) +end + +""" + duckdb_result_error_type(result) + +Returns the result error type contained within the result. The error is only set if `duckdb_query` returns +`DuckDBError`. + +# Arguments +- `result`: The result object to fetch the error from. + +Returns: The error type of the result. +""" +function duckdb_result_error_type(result) + return ccall((:duckdb_result_error_type, libduckdb), duckdb_error_type, (Ref{duckdb_result},), result) end -#= -//===--------------------------------------------------------------------===// -// Result Functions -//===--------------------------------------------------------------------===// -=# + + +# -------------------------------------------------------------------------------- +# Result Functions +# -------------------------------------------------------------------------------- """ + duckdb_result_get_chunk(result, chunk_index) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + Fetches a data chunk from the duckdb_result. This function should be called repeatedly until the result is exhausted. -This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` functions. -It results in significantly better performance, and should be preferred in newer code-bases. +The result must be destroyed with `duckdb_destroy_data_chunk`. -If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be mixed with the legacy result functions). +This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` +functions. It results in significantly better performance, and should be preferred in newer code-bases. + +If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be +mixed with the legacy result functions). Use `duckdb_result_chunk_count` to figure out how many chunks there are in the result. -* result: The result object to fetch the data chunk from. -* chunk_index: The chunk index to fetch from. -* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. +# Arguments +- `result`: The result object to fetch the data chunk from. +- `chunk_index`: The chunk index to fetch from. + +Returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. """ function duckdb_result_get_chunk(result, chunk_index) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_result_get_chunk + ) return ccall( (:duckdb_result_get_chunk, libduckdb), duckdb_data_chunk, - (duckdb_result, UInt64), + (duckdb_result, idx_t), result, chunk_index - 1 ) end """ - Checks if the type of the internal result is StreamQueryResult. + duckdb_result_is_streaming(result) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +Checks if the type of the internal result is StreamQueryResult. + +# Arguments +- `result`: The result object to check. - * result: The result object to check. - * returns: Whether or not the result object is of the type StreamQueryResult +Returns: Whether or not the result object is of the type StreamQueryResult """ function duckdb_result_is_streaming(result) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_result_is_streaming + ) return ccall((:duckdb_result_is_streaming, libduckdb), Bool, (duckdb_result,), result) end """ - Fetches a data chunk from the (streaming) duckdb_result. This function should be called repeatedly until the result is - exhausted. - - The result must be destroyed with `duckdb_destroy_data_chunk`. + duckdb_result_chunk_count(result) - This function can only be used on duckdb_results created with 'duckdb_pending_prepared_streaming' +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. - If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be - mixed with the legacy result functions or the materialized result functions). +Returns the number of data chunks present in the result. - It is not known beforehand how many chunks will be returned by this result. +# Arguments +- `result`: The result object - * result: The result object to fetch the data chunk from. - * returns: The resulting data chunk. Returns `NULL` if the result has an error. +Returns: Number of data chunks present in the result. """ -function duckdb_stream_fetch_chunk(result) - return ccall((:duckdb_stream_fetch_chunk, libduckdb), duckdb_data_chunk, (duckdb_result,), result) +function duckdb_result_chunk_count(result) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_result_chunk_count + ) + return ccall((:duckdb_result_chunk_count, libduckdb), idx_t, (duckdb_result,), result) end +""" + duckdb_result_return_type(result) +Returns the return_type of the given result, or DUCKDB_RETURN_TYPE_INVALID on error +# Arguments +- `result`: The result object +Returns: The return_type """ -Returns the number of data chunks present in the result. - -* result: The result object -* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. -""" -function duckdb_result_chunk_count(result) - return ccall((:duckdb_result_chunk_count, libduckdb), UInt64, (duckdb_result,), result) +function duckdb_result_return_type(result) + return ccall((:duckdb_result_return_type, libduckdb), duckdb_result_type, (duckdb_result,), result) end + +# -------------------------------------------------------------------------------- +# Safe Fetch Functions +# -------------------------------------------------------------------------------- + """ - duckdb_value_boolean(result,col,row) -* returns: The boolean value at the specified location, or false if the value cannot be converted. + duckdb_value_boolean(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The boolean value at the specified location, or false if the value cannot be converted. """ function duckdb_value_boolean(result, col, row) - return ccall( - (:duckdb_value_boolean, libduckdb), - Int32, - (Ref{duckdb_result}, Int32, Int32), - result, - col - 1, - row - 1 + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_boolean ) + return ccall((:duckdb_value_boolean, libduckdb), Bool, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_int8(result,col,row) -* returns: The int8_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_int8(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The int8_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_int8(result, col, row) - return ccall((:duckdb_value_int8, libduckdb), Int8, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_int8 + ) + return ccall((:duckdb_value_int8, libduckdb), Int8, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_int16(result,col,row) - * returns: The int16_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_int16(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The int16_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_int16(result, col, row) - return ccall((:duckdb_value_int16, libduckdb), Int16, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_int16 + ) + return ccall((:duckdb_value_int16, libduckdb), Int16, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_int32(result,col,row) - * returns: The int32_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_int32(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The int32_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_int32(result, col, row) - return ccall((:duckdb_value_int32, libduckdb), Int32, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_int32 + ) + return ccall((:duckdb_value_int32, libduckdb), Int32, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_int64(result,col,row) - * returns: The int64_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_int64(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The int64_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_int64(result, col, row) - return ccall((:duckdb_value_int64, libduckdb), Int64, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_int64 + ) + return ccall((:duckdb_value_int64, libduckdb), Int64, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_hugeint(result,col,row) - * returns: The duckdb_hugeint value at the specified location, or 0 if the value cannot be converted. + duckdb_value_hugeint(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_hugeint value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_hugeint(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_hugeint + ) return ccall( (:duckdb_value_hugeint, libduckdb), - Int64, - (Ref{duckdb_result}, Int32, Int32), + duckdb_hugeint, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -466,14 +762,53 @@ function duckdb_value_hugeint(result, col, row) end """ - duckdb_value_uhugeint(result,col,row) - * returns: The duckdb_uhugeint value at the specified location, or 0 if the value cannot be converted. + duckdb_value_uhugeint(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_uhugeint value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_uhugeint(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_uhugeint + ) return ccall( (:duckdb_value_uhugeint, libduckdb), - UInt64, - (Ref{duckdb_result}, Int32, Int32), + duckdb_uhugeint, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) +end + +""" + duckdb_value_decimal(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_decimal value at the specified location, or 0 if the value cannot be converted. +""" +function duckdb_value_decimal(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_decimal + ) + return ccall( + (:duckdb_value_decimal, libduckdb), + duckdb_decimal, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -481,23 +816,46 @@ function duckdb_value_uhugeint(result, col, row) end """ - duckdb_value_uint8(result,col,row) - * returns: The uint8_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_uint8(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The uint8_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_uint8(result, col, row) - return ccall((:duckdb_value_uint8, libduckdb), UInt8, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_uint8 + ) + return ccall((:duckdb_value_uint8, libduckdb), UInt8, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end """ - duckdb_value_uint16(result,col,row) - * returns: The uint16_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_uint16(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The uint16_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_uint16(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_uint16 + ) return ccall( (:duckdb_value_uint16, libduckdb), UInt16, - (Ref{duckdb_result}, Int32, Int32), + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -505,14 +863,26 @@ function duckdb_value_uint16(result, col, row) end """ - duckdb_value_uint32(result,col,row) - * returns: The uint32_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_uint32(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The uint32_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_uint32(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_uint32 + ) return ccall( (:duckdb_value_uint32, libduckdb), UInt32, - (Ref{duckdb_result}, Int32, Int32), + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -520,14 +890,26 @@ function duckdb_value_uint32(result, col, row) end """ - duckdb_value_uint64(result,col,row) -* returns: The uint64_t value at the specified location, or 0 if the value cannot be converted. + duckdb_value_uint64(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The uint64_t value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_uint64(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_uint64 + ) return ccall( (:duckdb_value_uint64, libduckdb), UInt64, - (Ref{duckdb_result}, Int32, Int32), + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -535,14 +917,26 @@ function duckdb_value_uint64(result, col, row) end """ - duckdb_value_float(result,col,row) - * returns: The float value at the specified location, or 0 if the value cannot be converted. + duckdb_value_float(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The float value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_float(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_float + ) return ccall( (:duckdb_value_float, libduckdb), Float32, - (Ref{duckdb_result}, Int32, Int32), + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -550,14 +944,26 @@ function duckdb_value_float(result, col, row) end """ - duckdb_value_double(result,col,row) - * returns: The double value at the specified location, or 0 if the value cannot be converted. + duckdb_value_double(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The double value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_double(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_double + ) return ccall( (:duckdb_value_double, libduckdb), Float64, - (Ref{duckdb_result}, Int32, Int32), + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -565,33 +971,80 @@ function duckdb_value_double(result, col, row) end """ -duckdb_value_date(result,col,row) - * returns: The duckdb_date value at the specified location, or 0 if the value cannot be converted. -DUCKDB_API duckdb_date duckdb_value_date(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_date(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_date value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_date(result, col, row) - return ccall((:duckdb_value_date, libduckdb), Int32, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_date + ) + return ccall( + (:duckdb_value_date, libduckdb), + duckdb_date, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) end """ -duckdb_value_time(result,col,row) - * returns: The duckdb_time value at the specified location, or 0 if the value cannot be converted. -DUCKDB_API duckdb_time duckdb_value_time(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_time(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_time value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_time(result, col, row) - return ccall((:duckdb_value_time, libduckdb), Int32, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_time + ) + return ccall( + (:duckdb_value_time, libduckdb), + duckdb_time, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) end """ -duckdb_value_timestamp(result,col,row) - * returns: The duckdb_timestamp value at the specified location, or 0 if the value cannot be converted. -DUCKDB_API duckdb_timestamp duckdb_value_timestamp(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_timestamp(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_timestamp value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_timestamp(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_timestamp + ) return ccall( (:duckdb_value_timestamp, libduckdb), - Int32, - (Ref{duckdb_result}, Int32, Int32), + duckdb_timestamp, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -599,15 +1052,26 @@ function duckdb_value_timestamp(result, col, row) end """ -duckdb_value_interval(result,col,row) - * returns: The duckdb_interval value at the specified location, or 0 if the value cannot be converted. -DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_interval(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_interval value at the specified location, or 0 if the value cannot be converted. """ function duckdb_value_interval(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_interval + ) return ccall( (:duckdb_value_interval, libduckdb), - Int32, - (Ref{duckdb_result}, Int32, Int32), + duckdb_interval, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -615,16 +1079,57 @@ function duckdb_value_interval(result, col, row) end """ -duckdb_value_varchar(result,col,row) -* returns: The char* value at the specified location, or nullptr if the value cannot be converted. -The result must be freed with `duckdb_free`. -DUCKDB_API char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_varchar(result, col, row) + +**DEPRECATED**: Use duckdb_value_string instead. This function does not work correctly if the string contains null bytes. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The text value at the specified location as a null-terminated string, or nullptr if the value cannot be +converted. The result must be freed with `duckdb_free`. """ function duckdb_value_varchar(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: **DEPRECATED**: Use duckdb_value_string instead. This function does not work correctly if the string contains null bytes.", + :duckdb_value_varchar + ) return ccall( (:duckdb_value_varchar, libduckdb), - Ptr{UInt8}, - (Ref{duckdb_result}, Int32, Int32), + Cstring, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) +end + +""" + duckdb_value_string(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +No support for nested types, and for other complex types. +The resulting field \"string.data\" must be freed with `duckdb_free.` + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The string value at the specified location. Attempts to cast the result value to string. +""" +function duckdb_value_string(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_string + ) + return ccall( + (:duckdb_value_string, libduckdb), + duckdb_string, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 @@ -632,459 +1137,833 @@ function duckdb_value_varchar(result, col, row) end """ -duckdb_value_varchar_internal(result,col,row) -* returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. + duckdb_value_varchar_internal(result, col, row) + +**DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains +null bytes. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. If the column is NOT a VARCHAR column this function will return NULL. + The result must NOT be freed. -DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); """ function duckdb_value_varchar_internal(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: **DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains", + :duckdb_value_varchar_internal + ) return ccall( (:duckdb_value_varchar_internal, libduckdb), - Ptr{UInt8}, - (Ref{duckdb_result}, Int32, Int32), + Cstring, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) +end + +""" + duckdb_value_string_internal(result, col, row) + +**DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains +null bytes. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. +If the column is NOT a VARCHAR column this function will return NULL. + +The result must NOT be freed. +""" +function duckdb_value_string_internal(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: **DEPRECATED**: Use duckdb_value_string_internal instead. This function does not work correctly if the string contains", + :duckdb_value_string_internal + ) + return ccall( + (:duckdb_value_string_internal, libduckdb), + duckdb_string, + (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1 ) end -# """ -# duckdb_value_blob(result,col,row) -# * returns: The duckdb_blob value at the specified location. Returns a blob with blob.data set to nullptr if the -# value cannot be converted. The resulting "blob.data" must be freed with `duckdb_free.` -# DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row); -# """ -# function duckdb_value_blob(result, col, row) -# return ccall( -# (:duckdb_value_blob, libduckdb), -# Ptr{Cvoid}, -# (Ptr{Cvoid}, Int32, Int32), -# result, -# col - 1, -# row - 1, -# ) -# end +""" + duckdb_value_blob(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: The duckdb_blob value at the specified location. Returns a blob with blob.data set to nullptr if the +value cannot be converted. The resulting field "blob.data" must be freed with `duckdb_free.` +""" +function duckdb_value_blob(result, col, row) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_blob + ) + return ccall( + (:duckdb_value_blob, libduckdb), + duckdb_blob, + (Ref{duckdb_result}, idx_t, idx_t), + result, + col - 1, + row - 1 + ) +end """ -duckdb_value_is_null(result,col,row) - * returns: Returns true if the value at the specified index is NULL, and false otherwise. -DUCKDB_API bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row); + duckdb_value_is_null(result, col, row) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +# Arguments +- `result`: +- `col`: +- `row`: + +Returns: Returns true if the value at the specified index is NULL, and false otherwise. """ function duckdb_value_is_null(result, col, row) - return ccall((:duckdb_value_is_null, libduckdb), Bool, (Ref{duckdb_result}, Int32, Int32), result, col - 1, row - 1) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_value_is_null + ) + return ccall((:duckdb_value_is_null, libduckdb), Bool, (Ref{duckdb_result}, idx_t, idx_t), result, col - 1, row - 1) end -#= -//===--------------------------------------------------------------------===// -// Helpers -//===--------------------------------------------------------------------===// -=# +# -------------------------------------------------------------------------------- +# Helpers +# -------------------------------------------------------------------------------- + """ -duckdb_malloc(size) + duckdb_malloc(size) Allocate `size` bytes of memory using the duckdb internal malloc function. Any memory allocated in this manner should be freed using `duckdb_free`. -* size: The number of bytes to allocate. -* returns: A pointer to the allocated memory region. -DUCKDB_API void *duckdb_malloc(size_t size); + +# Arguments +- `size`: The number of bytes to allocate. + +Returns: A pointer to the allocated memory region. """ function duckdb_malloc(size) - return ccall((:duckdb_malloc, libduckdb), Cvoid, (Csize_t,), size) + return ccall((:duckdb_malloc, libduckdb), Ptr{Cvoid}, (Csize_t,), size) end """ -duckdb_free(ptr) -Free a value returned from `duckdb_malloc`, `duckdb_value_varchar` or `duckdb_value_blob`. -* ptr: The memory region to de-allocate. -DUCKDB_API void duckdb_free(void *ptr); + duckdb_free(ptr) + +Free a value returned from `duckdb_malloc`, `duckdb_value_varchar`, `duckdb_value_blob`, or +`duckdb_value_string`. + +# Arguments +- `ptr`: The memory region to de-allocate. + +Returns: nothing """ function duckdb_free(ptr) return ccall((:duckdb_free, libduckdb), Cvoid, (Ptr{Cvoid},), ptr) end """ + duckdb_vector_size() + The internal vector size used by DuckDB. This is the amount of tuples that will fit into a data chunk created by `duckdb_create_data_chunk`. -* returns: The vector size. +# Arguments + +Returns: The vector size. """ function duckdb_vector_size() - return ccall((:duckdb_vector_size, libduckdb), UInt64, ()) + return ccall((:duckdb_vector_size, libduckdb), idx_t, ()) end -# #= -# //===--------------------------------------------------------------------===// -# // Date/Time/Timestamp Helpers -# //===--------------------------------------------------------------------===// -# =# -# -# -# """ -# duckdb_from_date(date) -# Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`). -# * date: The date object, as obtained from a `DUCKDB_TYPE_DATE` column. -# * returns: The `duckdb_date_struct` with the decomposed elements. -# DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date); -# """ -# function duckdb_from_date(date) -# return ccall((:duckdb_from_date, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), date) -# end -# -# """ -# duckdb_to_date(date) -# Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`). -# * date: The year, month and date stored in a `duckdb_date_struct`. -# * returns: The `duckdb_date` element. -# DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date); -# """ -# function duckdb_to_date(date) -# return ccall((:duckdb_to_date, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), date) -# end -# -# """ -# duckdb_from_time(time) -# Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`). -# * time: The time object, as obtained from a `DUCKDB_TYPE_TIME` column. -# * returns: The `duckdb_time_struct` with the decomposed elements. -# DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time); -# """ -# function duckdb_from_time(time) -# return ccall((:duckdb_from_time, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), time) -# end -# -# """ -# duckdb_to_time(time) -# Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`). -# * time: The hour, minute, second and microsecond in a `duckdb_time_struct`. -# * returns: The `duckdb_time` element. -# DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time); -# """ -# function duckdb_to_time(time) -# return ccall((:duckdb_to_time, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), time) -# end -# -# """ -# duckdb_from_timestamp(ts) -# Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`. -# * ts: The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. -# * returns: The `duckdb_timestamp_struct` with the decomposed elements. -# DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts); -# """ -# function duckdb_from_timestamp(ts) -# return ccall((:duckdb_from_timestamp, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), ts) -# end -# - """ -Decompose a TIME_TZ objects into micros and a timezone offset. + duckdb_string_is_inlined(string) -Use `duckdb_from_time` to further decompose the micros into hour, minute, second and microsecond. +Whether or not the duckdb_string_t value is inlined. +This means that the data of the string does not have a separate allocation. -* micros: The time object, as obtained from a `DUCKDB_TYPE_TIME_TZ` column. -* out_micros: The microsecond component of the time. -* out_offset: The timezone offset component of the time. +# Arguments +- `string`: + +Returns: nothing """ -function duckdb_from_time_tz(val) - return ccall((:duckdb_from_time_tz, libduckdb), duckdb_time_tz, (UInt64,), val) +function duckdb_string_is_inlined(string) + return ccall((:duckdb_string_is_inlined, libduckdb), Bool, (duckdb_string_t,), string) end -# -# """ -# duckdb_to_timestamp(ts) -# Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct. -# * ts: The de-composed elements in a `duckdb_timestamp_struct`. -# * returns: The `duckdb_timestamp` element. -# */ -# DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts); -# """ -# function duckdb_to_timestamp(ts) -# return ccall((:duckdb_to_timestamp, libduckdb), Ptr{Cvoid}, (Ptr{Cvoid},), ts) -# end -# -# #= -# //===--------------------------------------------------------------------===// -# // Hugeint Helpers -# //===--------------------------------------------------------------------===// -# =# -# -# -# """ -# duckdb_hugeint_to_double(val) -# Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. -# * val: The hugeint value. -# * returns: The converted `double` element. -# DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); -# """ -# function duckdb_hugeint_to_double(val) -# return ccall((:duckdb_hugeint_to_double, libduckdb), Float64, (Int64,), val) -# end -# -# """ -# duckdb_double_to_hugeint(val) -# Converts a double value to a duckdb_hugeint object. -# If the conversion fails because the double value is too big the result will be 0. -# * val: The double value. -# * returns: The converted `duckdb_hugeint` element. -# DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); -# """ -# function duckdb_double_to_hugeint(val) -# return ccall((:duckdb_double_to_hugeint, libduckdb), Int64, (Float64,), val) -# end -# -# #= -# //===--------------------------------------------------------------------===// -# // Prepared Statements -# //===--------------------------------------------------------------------===// -# // A prepared statement is a parameterized query that allows you to bind parameters to it. -# // * This is useful to easily supply parameters to functions and avoid SQL injection attacks. -# // * This is useful to speed up queries that you will execute several times with different parameters. -# // Because the query will only be parsed, bound, optimized and planned once during the prepare stage, -# // rather than once per execution. -# // For example: -# // SELECT * FROM tbl WHERE id=? -# // Or a query with multiple parameters: -# // SELECT * FROM tbl WHERE id=$1 OR name=$2 -# =# +""" + duckdb_string_t_length(string) +Get the string length of a string_t +# Arguments +- `string`: The string to get the length of. + +Returns: The length. """ -Create a prepared statement object from a query. -Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using -`duckdb_destroy_prepare`, even if the prepare fails. -If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. -* connection: The connection object -* query: The SQL query to prepare -* out_prepared_statement: The resulting prepared statement object -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -DUCKDB_API duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, - duckdb_prepared_statement *out_prepared_statement); -""" -function duckdb_prepare(connection, query, out_prepared_statement) - return ccall( - (:duckdb_prepare, libduckdb), - duckdb_state, - (duckdb_connection, Ptr{UInt8}, Ref{duckdb_prepared_statement}), - connection, - query, - out_prepared_statement - ) +function duckdb_string_t_length(string) + return ccall((:duckdb_string_t_length, libduckdb), UInt32, (duckdb_string_t,), string) end """ -Closes the prepared statement and de-allocates all memory allocated for that connection. -* prepared_statement: The prepared statement to destroy. -DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); + duckdb_string_t_data(string) + +Get a pointer to the string data of a string_t + +# Arguments +- `string`: The string to get the pointer to. + +Returns: The pointer. """ -function duckdb_destroy_prepare(prepared_statement) - return ccall((:duckdb_destroy_prepare, libduckdb), Cvoid, (Ref{duckdb_prepared_statement},), prepared_statement) +function duckdb_string_t_data(string) + return ccall((:duckdb_string_t_data, libduckdb), Cstring, (Ref{duckdb_string_t},), string) end + + +# -------------------------------------------------------------------------------- +# Date Time Timestamp Helpers +# -------------------------------------------------------------------------------- + """ -Returns the error message associated with the given prepared statement. -If the prepared statement has no error message, this returns `nullptr` instead. -The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. -* prepared_statement: The prepared statement to obtain the error from. -* returns: The error message, or `nullptr` if there is none. -DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement); + duckdb_from_date(date) + +Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`). + +# Arguments +- `date`: The date object, as obtained from a `DUCKDB_TYPE_DATE` column. + +Returns: The `duckdb_date_struct` with the decomposed elements. """ -function duckdb_prepare_error(prepared_statement) - return ccall((:duckdb_prepare_error, libduckdb), Ptr{UInt8}, (duckdb_prepared_statement,), prepared_statement[]) +function duckdb_from_date(date) + return ccall((:duckdb_from_date, libduckdb), duckdb_date_struct, (duckdb_date,), date) end """ -Returns the number of parameters that can be provided to the given prepared statement. -Returns 0 if the query was not successfully prepared. -* prepared_statement: The prepared statement to obtain the number of parameters for. -DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement); + duckdb_to_date(date) + +Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`). + +# Arguments +- `date`: The year, month and date stored in a `duckdb_date_struct`. + +Returns: The `duckdb_date` element. """ -function duckdb_nparams(prepared_statement) - return ccall((:duckdb_nparams, libduckdb), Int32, (duckdb_prepared_statement,), prepared_statement) +function duckdb_to_date(date) + return ccall((:duckdb_to_date, libduckdb), duckdb_date, (duckdb_date_struct,), date) end """ -Returns the parameter type for the parameter at the given index. -Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. -* prepared_statement: The prepared statement. -* param_idx: The parameter index. -* returns: The parameter type -DUCKDB_API duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx); + duckdb_is_finite_date(date) + +Test a `duckdb_date` to see if it is a finite value. + +# Arguments +- `date`: The date object, as obtained from a `DUCKDB_TYPE_DATE` column. + +Returns: True if the date is finite, false if it is ±infinity. """ -function duckdb_param_type(prepared_statement, param_idx) - return ccall( - (:duckdb_param_type, libduckdb), - Int32, - (duckdb_prepared_statement, Int32), - prepared_statement, - param_idx - ) +function duckdb_is_finite_date(date) + return ccall((:duckdb_is_finite_date, libduckdb), Bool, (duckdb_date,), date) end """ -Binds a bool value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val); + duckdb_from_time(time) + +Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`). + +# Arguments +- `time`: The time object, as obtained from a `DUCKDB_TYPE_TIME` column. + +Returns: The `duckdb_time_struct` with the decomposed elements. """ -function duckdb_bind_boolean(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_boolean, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, Int32), - prepared_statement, - param_idx, - val - ) +function duckdb_from_time(time) + return ccall((:duckdb_from_time, libduckdb), duckdb_time_struct, (duckdb_time,), time) end """ -Binds an int8_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val); + duckdb_create_time_tz(micros, offset) + +Create a `duckdb_time_tz` object from micros and a timezone offset. + +# Arguments +- `micros`: The microsecond component of the time. +- `offset`: The timezone offset component of the time. + +Returns: The `duckdb_time_tz` element. """ -function duckdb_bind_int8(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_int8, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, Int8), - prepared_statement, - param_idx, - val - ) +function duckdb_create_time_tz(micros, offset) + return ccall((:duckdb_create_time_tz, libduckdb), duckdb_time_tz, (Int64, Int32), micros, offset) end """ -Binds an int16_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val); + duckdb_from_time_tz(micros) + +Decompose a TIME_TZ objects into micros and a timezone offset. + +Use `duckdb_from_time` to further decompose the micros into hour, minute, second and microsecond. + +# Arguments +- `micros`: The time object, as obtained from a `DUCKDB_TYPE_TIME_TZ` column. + +Returns: nothing """ -function duckdb_bind_int16(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_int16, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, Int16), - prepared_statement, - param_idx, - val - ) +function duckdb_from_time_tz(micros) + return ccall((:duckdb_from_time_tz, libduckdb), duckdb_time_tz_struct, (duckdb_time_tz,), micros) end """ -Binds an int32_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val); + duckdb_to_time(time) + +Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`). + +# Arguments +- `time`: The hour, minute, second and microsecond in a `duckdb_time_struct`. + +Returns: The `duckdb_time` element. """ -function duckdb_bind_int32(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_int32, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, Int32), - prepared_statement, - param_idx, - val - ) +function duckdb_to_time(time) + return ccall((:duckdb_to_time, libduckdb), duckdb_time, (duckdb_time_struct,), time) end """ -Binds an int64_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val); + duckdb_from_timestamp(ts) + +Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`. + +# Arguments +- `ts`: The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. + +Returns: The `duckdb_timestamp_struct` with the decomposed elements. """ -function duckdb_bind_int64(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_int64, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, Int64), - prepared_statement, - param_idx, - val - ) +function duckdb_from_timestamp(ts) + return ccall((:duckdb_from_timestamp, libduckdb), duckdb_timestamp_struct, (duckdb_timestamp,), ts) end """ -Binds a duckdb_hugeint value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_hugeint val); + duckdb_to_timestamp(ts) + +Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct. + +# Arguments +- `ts`: The de-composed elements in a `duckdb_timestamp_struct`. + +Returns: The `duckdb_timestamp` element. """ -function duckdb_bind_hugeint(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_hugeint, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, duckdb_hugeint), - prepared_statement, - param_idx, - val - ) +function duckdb_to_timestamp(ts) + return ccall((:duckdb_to_timestamp, libduckdb), duckdb_timestamp, (duckdb_timestamp_struct,), ts) end """ -Binds an duckdb_uhugeint value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_uhugeint val); + duckdb_is_finite_timestamp(ts) + +Test a `duckdb_timestamp` to see if it is a finite value. + +# Arguments +- `ts`: The duckdb_timestamp object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. + +Returns: True if the timestamp is finite, false if it is ±infinity. """ -function duckdb_bind_uhugeint(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_uhugeint, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, duckdb_uhugeint), - prepared_statement, - param_idx, - val - ) +function duckdb_is_finite_timestamp(ts) + return ccall((:duckdb_is_finite_timestamp, libduckdb), Bool, (duckdb_timestamp,), ts) end """ -Binds an uint8_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val); + duckdb_is_finite_timestamp_s(ts) + +Test a `duckdb_timestamp_s` to see if it is a finite value. + +# Arguments +- `ts`: The duckdb_timestamp_s object, as obtained from a `DUCKDB_TYPE_TIMESTAMP_S` column. + +Returns: True if the timestamp is finite, false if it is ±infinity. """ -function duckdb_bind_uint8(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_uint8, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, UInt8), - prepared_statement, - param_idx, - val - ) +function duckdb_is_finite_timestamp_s(ts) + return ccall((:duckdb_is_finite_timestamp_s, libduckdb), Bool, (duckdb_timestamp_s,), ts) end """ -Binds an uint16_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_uint16(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint16_t val); + duckdb_is_finite_timestamp_ms(ts) + +Test a `duckdb_timestamp_ms` to see if it is a finite value. + +# Arguments +- `ts`: The duckdb_timestamp_ms object, as obtained from a `DUCKDB_TYPE_TIMESTAMP_MS` column. + +Returns: True if the timestamp is finite, false if it is ±infinity. """ -function duckdb_bind_uint16(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_uint16, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, UInt16), - prepared_statement, - param_idx, - val - ) +function duckdb_is_finite_timestamp_ms(ts) + return ccall((:duckdb_is_finite_timestamp_ms, libduckdb), Bool, (duckdb_timestamp_ms,), ts) end """ -Binds an uint32_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_uint32(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint32_t val); + duckdb_is_finite_timestamp_ns(ts) + +Test a `duckdb_timestamp_ns` to see if it is a finite value. + +# Arguments +- `ts`: The duckdb_timestamp_ns object, as obtained from a `DUCKDB_TYPE_TIMESTAMP_NS` column. + +Returns: True if the timestamp is finite, false if it is ±infinity. """ -function duckdb_bind_uint32(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_uint32, libduckdb), - duckdb_state, - (duckdb_prepared_statement, Int32, UInt32), - prepared_statement, - param_idx, - val - ) +function duckdb_is_finite_timestamp_ns(ts) + return ccall((:duckdb_is_finite_timestamp_ns, libduckdb), Bool, (duckdb_timestamp_ns,), ts) end + + +# -------------------------------------------------------------------------------- +# Hugeint Helpers +# -------------------------------------------------------------------------------- + """ -Binds an uint64_t value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint64_t val); + duckdb_hugeint_to_double(val) + +Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. + +# Arguments +- `val`: The hugeint value. + +Returns: The converted `double` element. """ -function duckdb_bind_uint64(prepared_statement, param_idx, val) - return ccall( - (:duckdb_bind_uint64, libduckdb), +function duckdb_hugeint_to_double(val) + return ccall((:duckdb_hugeint_to_double, libduckdb), Float64, (duckdb_hugeint,), val) +end + +""" + duckdb_double_to_hugeint(val) + +Converts a double value to a duckdb_hugeint object. + +If the conversion fails because the double value is too big the result will be 0. + +# Arguments +- `val`: The double value. + +Returns: The converted `duckdb_hugeint` element. +""" +function duckdb_double_to_hugeint(val) + return ccall((:duckdb_double_to_hugeint, libduckdb), duckdb_hugeint, (Float64,), val) +end + + + +# -------------------------------------------------------------------------------- +# Unsigned Hugeint Helpers +# -------------------------------------------------------------------------------- + +""" + duckdb_uhugeint_to_double(val) + +Converts a duckdb_uhugeint object (as obtained from a `DUCKDB_TYPE_UHUGEINT` column) into a double. + +# Arguments +- `val`: The uhugeint value. + +Returns: The converted `double` element. +""" +function duckdb_uhugeint_to_double(val) + return ccall((:duckdb_uhugeint_to_double, libduckdb), Float64, (duckdb_uhugeint,), val) +end + +""" + duckdb_double_to_uhugeint(val) + +Converts a double value to a duckdb_uhugeint object. + +If the conversion fails because the double value is too big the result will be 0. + +# Arguments +- `val`: The double value. + +Returns: The converted `duckdb_uhugeint` element. +""" +function duckdb_double_to_uhugeint(val) + return ccall((:duckdb_double_to_uhugeint, libduckdb), duckdb_uhugeint, (Float64,), val) +end + + + +# -------------------------------------------------------------------------------- +# Decimal Helpers +# -------------------------------------------------------------------------------- + +""" + duckdb_double_to_decimal(val, width, scale) + +Converts a double value to a duckdb_decimal object. + +If the conversion fails because the double value is too big, or the width/scale are invalid the result will be 0. + +# Arguments +- `val`: The double value. +- `width`: +- `scale`: + +Returns: The converted `duckdb_decimal` element. +""" +function duckdb_double_to_decimal(val, width, scale) + return ccall((:duckdb_double_to_decimal, libduckdb), duckdb_decimal, (Float64, UInt8, UInt8), val, width, scale) +end + +""" + duckdb_decimal_to_double(val) + +Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double. + +# Arguments +- `val`: The decimal value. + +Returns: The converted `double` element. +""" +function duckdb_decimal_to_double(val) + return ccall((:duckdb_decimal_to_double, libduckdb), Float64, (duckdb_decimal,), val) +end + + + +# -------------------------------------------------------------------------------- +# Prepared Statements +# -------------------------------------------------------------------------------- + +""" + duckdb_prepare(connection, query, out_prepared_statement) + +Create a prepared statement object from a query. + +Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using +`duckdb_destroy_prepare`, even if the prepare fails. + +If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. + +# Arguments +- `connection`: The connection object +- `query`: The SQL query to prepare +- `out_prepared_statement`: The resulting prepared statement object + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_prepare(connection, query, out_prepared_statement) + return ccall( + (:duckdb_prepare, libduckdb), + duckdb_state, + (duckdb_connection, Cstring, Ref{duckdb_prepared_statement}), + connection, + query, + out_prepared_statement + ) +end + +""" + duckdb_destroy_prepare(prepared_statement) + +Closes the prepared statement and de-allocates all memory allocated for the statement. + +# Arguments +- `prepared_statement`: The prepared statement to destroy. + +Returns: nothing +""" +function duckdb_destroy_prepare(prepared_statement) + return ccall((:duckdb_destroy_prepare, libduckdb), Cvoid, (Ref{duckdb_prepared_statement},), prepared_statement) +end + +""" + duckdb_prepare_error(prepared_statement) + +Returns the error message associated with the given prepared statement. +If the prepared statement has no error message, this returns `nullptr` instead. + +The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. + +# Arguments +- `prepared_statement`: The prepared statement to obtain the error from. + +Returns: The error message, or `nullptr` if there is none. +""" +function duckdb_prepare_error(prepared_statement) + return ccall((:duckdb_prepare_error, libduckdb), Cstring, (duckdb_prepared_statement,), prepared_statement) +end + +""" + duckdb_nparams(prepared_statement) + +Returns the number of parameters that can be provided to the given prepared statement. + +Returns 0 if the query was not successfully prepared. + +# Arguments +- `prepared_statement`: The prepared statement to obtain the number of parameters for. + +Returns: nothing +""" +function duckdb_nparams(prepared_statement) + return ccall((:duckdb_nparams, libduckdb), idx_t, (duckdb_prepared_statement,), prepared_statement) +end + +""" + duckdb_parameter_name(prepared_statement, index) + +Returns the name used to identify the parameter +The returned string should be freed using `duckdb_free`. + +Returns NULL if the index is out of range for the provided prepared statement. + +# Arguments +- `prepared_statement`: The prepared statement for which to get the parameter name from. +- `index`: + +Returns: nothing +""" +function duckdb_parameter_name(prepared_statement, index) + return ccall( + (:duckdb_parameter_name, libduckdb), + Cstring, + (duckdb_prepared_statement, idx_t), + prepared_statement, + index + ) +end + +""" + duckdb_param_type(prepared_statement, param_idx) + +Returns the parameter type for the parameter at the given index. + +Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. + +# Arguments +- `prepared_statement`: The prepared statement. +- `param_idx`: The parameter index. + +Returns: The parameter type +""" +function duckdb_param_type(prepared_statement, param_idx) + return ccall( + (:duckdb_param_type, libduckdb), + DUCKDB_TYPE, + (duckdb_prepared_statement, idx_t), + prepared_statement, + param_idx + ) +end + +""" + duckdb_param_logical_type(prepared_statement, param_idx) + +Returns the logical type for the parameter at the given index. + +Returns `nullptr` if the parameter index is out of range or the statement was not successfully prepared. + +The return type of this call should be destroyed with `duckdb_destroy_logical_type`. + +# Arguments +- `prepared_statement`: The prepared statement. +- `param_idx`: The parameter index. + +Returns: The logical type of the parameter +""" +function duckdb_param_logical_type(prepared_statement, param_idx) + return ccall( + (:duckdb_param_logical_type, libduckdb), + duckdb_logical_type, + (duckdb_prepared_statement, idx_t), + prepared_statement, + param_idx + ) +end + +""" + duckdb_clear_bindings(prepared_statement) + +Clear the params bind to the prepared statement. + +# Arguments +- `prepared_statement`: + +Returns: nothing +""" +function duckdb_clear_bindings(prepared_statement) + return ccall((:duckdb_clear_bindings, libduckdb), duckdb_state, (duckdb_prepared_statement,), prepared_statement) +end + +""" + duckdb_prepared_statement_type(statement) + +Returns the statement type of the statement to be executed + +# Arguments +- `statement`: The prepared statement. + +Returns: duckdb_statement_type value or DUCKDB_STATEMENT_TYPE_INVALID +""" +function duckdb_prepared_statement_type(statement) + return ccall( + (:duckdb_prepared_statement_type, libduckdb), + duckdb_statement_type, + (duckdb_prepared_statement,), + statement + ) +end + + + +# -------------------------------------------------------------------------------- +# Bind Values To Prepared Statements +# -------------------------------------------------------------------------------- + +""" + duckdb_bind_value(prepared_statement, param_idx, val) + +Binds a value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_value(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_value, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_value), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_parameter_index(prepared_statement, param_idx_out, name) + +Retrieve the index of the parameter for the prepared statement, identified by name + +# Arguments +- `prepared_statement`: +- `param_idx_out`: +- `name`: + +Returns: nothing +""" +function duckdb_bind_parameter_index(prepared_statement, param_idx_out, name) + return ccall( + (:duckdb_bind_parameter_index, libduckdb), + duckdb_state, + (duckdb_prepared_statement, Ref{idx_t}, Cstring), + prepared_statement, + param_idx_out, + name + ) +end + +""" + duckdb_bind_boolean(prepared_statement, param_idx, val) + +Binds a bool value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_boolean(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_boolean, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Bool), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_int8(prepared_statement, param_idx, val) + +Binds an int8_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_int8(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_int8, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Int8), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_int16(prepared_statement, param_idx, val) + +Binds an int16_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_int16(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_int16, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Int16), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_int32(prepared_statement, param_idx, val) + +Binds an int32_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_int32(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_int32, libduckdb), duckdb_state, - (duckdb_prepared_statement, Int32, UInt64), + (duckdb_prepared_statement, idx_t, Int32), prepared_statement, param_idx, val @@ -1092,2066 +1971,5871 @@ function duckdb_bind_uint64(prepared_statement, param_idx, val) end """ -Binds a float value to the prepared statement at the specified index. -DUCKDB_API duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val); + duckdb_bind_int64(prepared_statement, param_idx, val) + +Binds an int64_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_int64(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_int64, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Int64), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_hugeint(prepared_statement, param_idx, val) + +Binds a duckdb_hugeint value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_hugeint(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_hugeint, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_hugeint), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_uhugeint(prepared_statement, param_idx, val) + +Binds an duckdb_uhugeint value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_uhugeint(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_uhugeint, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_uhugeint), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_decimal(prepared_statement, param_idx, val) + +Binds a duckdb_decimal value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_decimal(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_decimal, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_decimal), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_uint8(prepared_statement, param_idx, val) + +Binds an uint8_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_uint8(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_uint8, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, UInt8), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_uint16(prepared_statement, param_idx, val) + +Binds an uint16_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_uint16(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_uint16, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, UInt16), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_uint32(prepared_statement, param_idx, val) + +Binds an uint32_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_uint32(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_uint32, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, UInt32), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_uint64(prepared_statement, param_idx, val) + +Binds an uint64_t value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_uint64(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_uint64, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, UInt64), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_float(prepared_statement, param_idx, val) + +Binds a float value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_float(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_float, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Float32), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_double(prepared_statement, param_idx, val) + +Binds a double value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_double(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_double, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Float64), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_date(prepared_statement, param_idx, val) + +Binds a duckdb_date value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_date(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_date, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_date), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_time(prepared_statement, param_idx, val) + +Binds a duckdb_time value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_time(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_time, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_time), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_timestamp(prepared_statement, param_idx, val) + +Binds a duckdb_timestamp value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_timestamp(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_timestamp, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_timestamp), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_timestamp_tz(prepared_statement, param_idx, val) + +Binds a duckdb_timestamp value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_timestamp_tz(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_timestamp_tz, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_timestamp), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_interval(prepared_statement, param_idx, val) + +Binds a duckdb_interval value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_interval(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_interval, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, duckdb_interval), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_varchar(prepared_statement, param_idx, val) + +Binds a null-terminated varchar value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: + +Returns: nothing +""" +function duckdb_bind_varchar(prepared_statement, param_idx, val) + return ccall( + (:duckdb_bind_varchar, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Cstring), + prepared_statement, + param_idx, + val + ) +end + +""" + duckdb_bind_varchar_length(prepared_statement, param_idx, val, length) + +Binds a varchar value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `val`: +- `length`: + +Returns: nothing +""" +function duckdb_bind_varchar_length(prepared_statement, param_idx, val, length) + return ccall( + (:duckdb_bind_varchar_length, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Cstring, idx_t), + prepared_statement, + param_idx, + val, + length + ) +end + +""" + duckdb_bind_blob(prepared_statement, param_idx, data, length) + +Binds a blob value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: +- `data`: +- `length`: + +Returns: nothing +""" +function duckdb_bind_blob(prepared_statement, param_idx, data, length) + return ccall( + (:duckdb_bind_blob, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t, Ptr{Cvoid}, idx_t), + prepared_statement, + param_idx, + data, + length + ) +end + +""" + duckdb_bind_null(prepared_statement, param_idx) + +Binds a NULL value to the prepared statement at the specified index. + +# Arguments +- `prepared_statement`: +- `param_idx`: + +Returns: nothing +""" +function duckdb_bind_null(prepared_statement, param_idx) + return ccall( + (:duckdb_bind_null, libduckdb), + duckdb_state, + (duckdb_prepared_statement, idx_t), + prepared_statement, + param_idx + ) +end + + + +# -------------------------------------------------------------------------------- +# Execute Prepared Statements +# -------------------------------------------------------------------------------- + +""" + duckdb_execute_prepared(prepared_statement, out_result) + +Executes the prepared statement with the given bound parameters, and returns a materialized query result. + +This method can be called multiple times for each prepared statement, and the parameters can be modified +between calls to this function. + +Note that the result must be freed with `duckdb_destroy_result`. + +# Arguments +- `prepared_statement`: The prepared statement to execute. +- `out_result`: The query result. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_execute_prepared(prepared_statement, out_result) + return ccall( + (:duckdb_execute_prepared, libduckdb), + duckdb_state, + (duckdb_prepared_statement, Ref{duckdb_result}), + prepared_statement, + out_result + ) +end + +""" + duckdb_execute_prepared_streaming(prepared_statement, out_result) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +Executes the prepared statement with the given bound parameters, and returns an optionally-streaming query result. +To determine if the resulting query was in fact streamed, use `duckdb_result_is_streaming` + +This method can be called multiple times for each prepared statement, and the parameters can be modified +between calls to this function. + +Note that the result must be freed with `duckdb_destroy_result`. + +# Arguments +- `prepared_statement`: The prepared statement to execute. +- `out_result`: The query result. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_execute_prepared_streaming(prepared_statement, out_result) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_execute_prepared_streaming + ) + return ccall( + (:duckdb_execute_prepared_streaming, libduckdb), + duckdb_state, + (duckdb_prepared_statement, Ref{duckdb_result}), + prepared_statement, + out_result + ) +end + + + +# -------------------------------------------------------------------------------- +# Extract Statements +# -------------------------------------------------------------------------------- + +""" + duckdb_extract_statements(connection, query, out_extracted_statements) + +Extract all statements from a query. +Note that after calling `duckdb_extract_statements`, the extracted statements should always be destroyed using +`duckdb_destroy_extracted`, even if no statements were extracted. + +If the extract fails, `duckdb_extract_statements_error` can be called to obtain the reason why the extract failed. + +# Arguments +- `connection`: The connection object +- `query`: The SQL query to extract +- `out_extracted_statements`: The resulting extracted statements object + +Returns: The number of extracted statements or 0 on failure. +""" +function duckdb_extract_statements(connection, query, out_extracted_statements) + return ccall( + (:duckdb_extract_statements, libduckdb), + idx_t, + (duckdb_connection, Cstring, Ref{duckdb_extracted_statements}), + connection, + query, + out_extracted_statements + ) +end + +""" + duckdb_prepare_extracted_statement(connection, extracted_statements, index, out_prepared_statement) + +Prepare an extracted statement. +Note that after calling `duckdb_prepare_extracted_statement`, the prepared statement should always be destroyed using +`duckdb_destroy_prepare`, even if the prepare fails. + +If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. + +# Arguments +- `connection`: The connection object +- `extracted_statements`: The extracted statements object +- `index`: The index of the extracted statement to prepare +- `out_prepared_statement`: The resulting prepared statement object + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_prepare_extracted_statement(connection, extracted_statements, index, out_prepared_statement) + return ccall( + (:duckdb_prepare_extracted_statement, libduckdb), + duckdb_state, + (duckdb_connection, duckdb_extracted_statements, idx_t, Ref{duckdb_prepared_statement}), + connection, + extracted_statements, + index - 1, + out_prepared_statement + ) +end + +""" + duckdb_extract_statements_error(extracted_statements) + +Returns the error message contained within the extracted statements. +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_extracted` is called. + +# Arguments +- `extracted_statements`: The extracted statements to fetch the error from. + +Returns: The error of the extracted statements. +""" +function duckdb_extract_statements_error(extracted_statements) + return ccall( + (:duckdb_extract_statements_error, libduckdb), + Cstring, + (duckdb_extracted_statements,), + extracted_statements + ) +end + +""" + duckdb_destroy_extracted(extracted_statements) + +De-allocates all memory allocated for the extracted statements. + +# Arguments +- `extracted_statements`: The extracted statements to destroy. + +Returns: nothing +""" +function duckdb_destroy_extracted(extracted_statements) + return ccall( + (:duckdb_destroy_extracted, libduckdb), + Cvoid, + (Ref{duckdb_extracted_statements},), + extracted_statements + ) +end + + + +# -------------------------------------------------------------------------------- +# Pending Result Interface +# -------------------------------------------------------------------------------- + +""" + duckdb_pending_prepared(prepared_statement, out_result) + +Executes the prepared statement with the given bound parameters, and returns a pending result. +The pending result represents an intermediate structure for a query that is not yet fully executed. +The pending result can be used to incrementally execute a query, returning control to the client between tasks. + +Note that after calling `duckdb_pending_prepared`, the pending result should always be destroyed using +`duckdb_destroy_pending`, even if this function returns DuckDBError. + +# Arguments +- `prepared_statement`: The prepared statement to execute. +- `out_result`: The pending query result. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_pending_prepared(prepared_statement, out_result) + return ccall( + (:duckdb_pending_prepared, libduckdb), + duckdb_state, + (duckdb_prepared_statement, Ref{duckdb_pending_result}), + prepared_statement, + out_result + ) +end + +""" + duckdb_pending_prepared_streaming(prepared_statement, out_result) + +**DEPRECATION NOTICE**: This method is scheduled for removal in a future release. + +Executes the prepared statement with the given bound parameters, and returns a pending result. +This pending result will create a streaming duckdb_result when executed. +The pending result represents an intermediate structure for a query that is not yet fully executed. + +Note that after calling `duckdb_pending_prepared_streaming`, the pending result should always be destroyed using +`duckdb_destroy_pending`, even if this function returns DuckDBError. + +# Arguments +- `prepared_statement`: The prepared statement to execute. +- `out_result`: The pending query result. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_pending_prepared_streaming(prepared_statement, out_result) + Base.depwarn( + "**DEPRECATION NOTICE**: This method is scheduled for removal in a future release.", + :duckdb_pending_prepared_streaming + ) + return ccall( + (:duckdb_pending_prepared_streaming, libduckdb), + duckdb_state, + (duckdb_prepared_statement, Ref{duckdb_pending_result}), + prepared_statement, + out_result + ) +end + +""" + duckdb_destroy_pending(pending_result) + +Closes the pending result and de-allocates all memory allocated for the result. + +# Arguments +- `pending_result`: The pending result to destroy. + +Returns: nothing +""" +function duckdb_destroy_pending(pending_result) + return ccall((:duckdb_destroy_pending, libduckdb), Cvoid, (Ref{duckdb_pending_result},), pending_result) +end + +""" + duckdb_pending_error(pending_result) + +Returns the error message contained within the pending result. + +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_pending` is called. + +# Arguments +- `pending_result`: The pending result to fetch the error from. + +Returns: The error of the pending result. +""" +function duckdb_pending_error(pending_result) + return ccall((:duckdb_pending_error, libduckdb), Cstring, (duckdb_pending_result,), pending_result) +end + +""" + duckdb_pending_execute_task(pending_result) + +Executes a single task within the query, returning whether or not the query is ready. + +If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. +If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_task function should be called again. +If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. + +The error message can be obtained by calling duckdb_pending_error on the pending_result. + +# Arguments +- `pending_result`: The pending result to execute a task within. + +Returns: The state of the pending result after the execution. +""" +function duckdb_pending_execute_task(pending_result) + return ccall( + (:duckdb_pending_execute_task, libduckdb), + duckdb_pending_state, + (duckdb_pending_result,), + pending_result + ) +end + +""" + duckdb_pending_execute_check_state(pending_result) + +If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. +If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_check_state function should be called again. +If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. + +The error message can be obtained by calling duckdb_pending_error on the pending_result. + +# Arguments +- `pending_result`: The pending result. + +Returns: The state of the pending result. +""" +function duckdb_pending_execute_check_state(pending_result) + return ccall( + (:duckdb_pending_execute_check_state, libduckdb), + duckdb_pending_state, + (duckdb_pending_result,), + pending_result + ) +end + +""" + duckdb_execute_pending(pending_result, out_result) + +Fully execute a pending query result, returning the final query result. + +If duckdb_pending_execute_task has been called until DUCKDB_PENDING_RESULT_READY was returned, this will return fast. +Otherwise, all remaining tasks must be executed first. + +Note that the result must be freed with `duckdb_destroy_result`. + +# Arguments +- `pending_result`: The pending result to execute. +- `out_result`: The result object. + +Returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +""" +function duckdb_execute_pending(pending_result, out_result) + return ccall( + (:duckdb_execute_pending, libduckdb), + duckdb_state, + (duckdb_pending_result, Ref{duckdb_result}), + pending_result, + out_result + ) +end + +""" + duckdb_pending_execution_is_finished(pending_state) + +Returns whether a duckdb_pending_state is finished executing. For example if `pending_state` is +DUCKDB_PENDING_RESULT_READY, this function will return true. + +# Arguments +- `pending_state`: The pending state on which to decide whether to finish execution. + +Returns: Boolean indicating pending execution should be considered finished. +""" +function duckdb_pending_execution_is_finished(pending_state) + return ccall((:duckdb_pending_execution_is_finished, libduckdb), Bool, (duckdb_pending_state,), pending_state) +end + + + +# -------------------------------------------------------------------------------- +# Value Interface +# -------------------------------------------------------------------------------- + +""" + duckdb_destroy_value(value) + +Destroys the value and de-allocates all memory allocated for that type. + +# Arguments +- `value`: The value to destroy. + +Returns: nothing +""" +function duckdb_destroy_value(value) + return ccall((:duckdb_destroy_value, libduckdb), Cvoid, (Ref{duckdb_value},), value) +end + +""" + duckdb_create_varchar(text) + +Creates a value from a null-terminated string + +# Arguments +- `text`: The null-terminated string + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_varchar(text) + return ccall((:duckdb_create_varchar, libduckdb), duckdb_value, (Cstring,), text) +end + +""" + duckdb_create_varchar_length(text, length) + +Creates a value from a string + +# Arguments +- `text`: The text +- `length`: The length of the text + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_varchar_length(text, length) + return ccall((:duckdb_create_varchar_length, libduckdb), duckdb_value, (Cstring, idx_t), text, length) +end + +""" + duckdb_create_bool(input) + +Creates a value from a boolean + +# Arguments +- `input`: The boolean value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_bool(input) + return ccall((:duckdb_create_bool, libduckdb), duckdb_value, (Bool,), input) +end + +""" + duckdb_create_int8(input) + +Creates a value from a int8_t (a tinyint) + +# Arguments +- `input`: The tinyint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_int8(input) + return ccall((:duckdb_create_int8, libduckdb), duckdb_value, (Int8,), input) +end + +""" + duckdb_create_uint8(input) + +Creates a value from a uint8_t (a utinyint) + +# Arguments +- `input`: The utinyint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uint8(input) + return ccall((:duckdb_create_uint8, libduckdb), duckdb_value, (UInt8,), input) +end + +""" + duckdb_create_int16(input) + +Creates a value from a int16_t (a smallint) + +# Arguments +- `input`: The smallint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_int16(input) + return ccall((:duckdb_create_int16, libduckdb), duckdb_value, (Int16,), input) +end + +""" + duckdb_create_uint16(input) + +Creates a value from a uint16_t (a usmallint) + +# Arguments +- `input`: The usmallint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uint16(input) + return ccall((:duckdb_create_uint16, libduckdb), duckdb_value, (UInt16,), input) +end + +""" + duckdb_create_int32(input) + +Creates a value from a int32_t (an integer) + +# Arguments +- `input`: The integer value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_int32(input) + return ccall((:duckdb_create_int32, libduckdb), duckdb_value, (Int32,), input) +end + +""" + duckdb_create_uint32(input) + +Creates a value from a uint32_t (a uinteger) + +# Arguments +- `input`: The uinteger value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uint32(input) + return ccall((:duckdb_create_uint32, libduckdb), duckdb_value, (UInt32,), input) +end + +""" + duckdb_create_uint64(input) + +Creates a value from a uint64_t (a ubigint) + +# Arguments +- `input`: The ubigint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uint64(input) + return ccall((:duckdb_create_uint64, libduckdb), duckdb_value, (UInt64,), input) +end + +""" + duckdb_create_int64(val) + +Creates a value from an int64 + +# Arguments +- `val`: + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_int64(val) + return ccall((:duckdb_create_int64, libduckdb), duckdb_value, (Int64,), val) +end + +""" + duckdb_create_hugeint(input) + +Creates a value from a hugeint + +# Arguments +- `input`: The hugeint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_hugeint(input) + return ccall((:duckdb_create_hugeint, libduckdb), duckdb_value, (duckdb_hugeint,), input) +end + +""" + duckdb_create_uhugeint(input) + +Creates a value from a uhugeint + +# Arguments +- `input`: The uhugeint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uhugeint(input) + return ccall((:duckdb_create_uhugeint, libduckdb), duckdb_value, (duckdb_uhugeint,), input) +end + +""" + duckdb_create_varint(input) + +Creates a VARINT value from a duckdb_varint + +# Arguments +- `input`: The duckdb_varint value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_varint(input) + return ccall((:duckdb_create_varint, libduckdb), duckdb_value, (duckdb_varint,), input) +end + +""" + duckdb_create_decimal(input) + +Creates a DECIMAL value from a duckdb_decimal + +# Arguments +- `input`: The duckdb_decimal value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_decimal(input) + return ccall((:duckdb_create_decimal, libduckdb), duckdb_value, (duckdb_decimal,), input) +end + +""" + duckdb_create_float(input) + +Creates a value from a float + +# Arguments +- `input`: The float value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_float(input) + return ccall((:duckdb_create_float, libduckdb), duckdb_value, (Float32,), input) +end + +""" + duckdb_create_double(input) + +Creates a value from a double + +# Arguments +- `input`: The double value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_double(input) + return ccall((:duckdb_create_double, libduckdb), duckdb_value, (Float64,), input) +end + +""" + duckdb_create_date(input) + +Creates a value from a date + +# Arguments +- `input`: The date value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_date(input) + return ccall((:duckdb_create_date, libduckdb), duckdb_value, (duckdb_date,), input) +end + +""" + duckdb_create_time(input) + +Creates a value from a time + +# Arguments +- `input`: The time value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_time(input) + return ccall((:duckdb_create_time, libduckdb), duckdb_value, (duckdb_time,), input) +end + +""" + duckdb_create_time_tz_value(value) + +Creates a value from a time_tz. +Not to be confused with `duckdb_create_time_tz`, which creates a duckdb_time_tz_t. + +# Arguments +- `value`: The time_tz value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_time_tz_value(value) + return ccall((:duckdb_create_time_tz_value, libduckdb), duckdb_value, (duckdb_time_tz,), value) +end + +""" + duckdb_create_timestamp(input) + +Creates a TIMESTAMP value from a duckdb_timestamp + +# Arguments +- `input`: The duckdb_timestamp value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_timestamp(input) + return ccall((:duckdb_create_timestamp, libduckdb), duckdb_value, (duckdb_timestamp,), input) +end + +""" + duckdb_create_timestamp_tz(input) + +Creates a TIMESTAMP_TZ value from a duckdb_timestamp + +# Arguments +- `input`: The duckdb_timestamp value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_timestamp_tz(input) + return ccall((:duckdb_create_timestamp_tz, libduckdb), duckdb_value, (duckdb_timestamp,), input) +end + +""" + duckdb_create_timestamp_s(input) + +Creates a TIMESTAMP_S value from a duckdb_timestamp_s + +# Arguments +- `input`: The duckdb_timestamp_s value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_timestamp_s(input) + return ccall((:duckdb_create_timestamp_s, libduckdb), duckdb_value, (duckdb_timestamp_s,), input) +end + +""" + duckdb_create_timestamp_ms(input) + +Creates a TIMESTAMP_MS value from a duckdb_timestamp_ms + +# Arguments +- `input`: The duckdb_timestamp_ms value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_timestamp_ms(input) + return ccall((:duckdb_create_timestamp_ms, libduckdb), duckdb_value, (duckdb_timestamp_ms,), input) +end + +""" + duckdb_create_timestamp_ns(input) + +Creates a TIMESTAMP_NS value from a duckdb_timestamp_ns + +# Arguments +- `input`: The duckdb_timestamp_ns value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_timestamp_ns(input) + return ccall((:duckdb_create_timestamp_ns, libduckdb), duckdb_value, (duckdb_timestamp_ns,), input) +end + +""" + duckdb_create_interval(input) + +Creates a value from an interval + +# Arguments +- `input`: The interval value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_interval(input) + return ccall((:duckdb_create_interval, libduckdb), duckdb_value, (duckdb_interval,), input) +end + +""" + duckdb_create_blob(data, length) + +Creates a value from a blob + +# Arguments +- `data`: The blob data +- `length`: The length of the blob data + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_blob(data, length) + return ccall((:duckdb_create_blob, libduckdb), duckdb_value, (Ref{UInt8}, idx_t), data, length) +end + +""" + duckdb_create_bit(input) + +Creates a BIT value from a duckdb_bit + +# Arguments +- `input`: The duckdb_bit value + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_bit(input) + return ccall((:duckdb_create_bit, libduckdb), duckdb_value, (duckdb_bit,), input) +end + +""" + duckdb_create_uuid(input) + +Creates a UUID value from a uhugeint + +# Arguments +- `input`: The duckdb_uhugeint containing the UUID + +Returns: The value. This must be destroyed with `duckdb_destroy_value`. +""" +function duckdb_create_uuid(input) + return ccall((:duckdb_create_uuid, libduckdb), duckdb_value, (duckdb_uhugeint,), input) +end + +""" + duckdb_get_bool(val) + +Returns the boolean value of the given value. + +# Arguments +- `val`: A duckdb_value containing a boolean + +Returns: A boolean, or false if the value cannot be converted +""" +function duckdb_get_bool(val) + return ccall((:duckdb_get_bool, libduckdb), Bool, (duckdb_value,), val) +end + +""" + duckdb_get_int8(val) + +Returns the int8_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a tinyint + +Returns: A int8_t, or MinValue if the value cannot be converted +""" +function duckdb_get_int8(val) + return ccall((:duckdb_get_int8, libduckdb), Int8, (duckdb_value,), val) +end + +""" + duckdb_get_uint8(val) + +Returns the uint8_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a utinyint + +Returns: A uint8_t, or MinValue if the value cannot be converted +""" +function duckdb_get_uint8(val) + return ccall((:duckdb_get_uint8, libduckdb), UInt8, (duckdb_value,), val) +end + +""" + duckdb_get_int16(val) + +Returns the int16_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a smallint + +Returns: A int16_t, or MinValue if the value cannot be converted +""" +function duckdb_get_int16(val) + return ccall((:duckdb_get_int16, libduckdb), Int16, (duckdb_value,), val) +end + +""" + duckdb_get_uint16(val) + +Returns the uint16_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a usmallint + +Returns: A uint16_t, or MinValue if the value cannot be converted +""" +function duckdb_get_uint16(val) + return ccall((:duckdb_get_uint16, libduckdb), UInt16, (duckdb_value,), val) +end + +""" + duckdb_get_int32(val) + +Returns the int32_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a integer + +Returns: A int32_t, or MinValue if the value cannot be converted +""" +function duckdb_get_int32(val) + return ccall((:duckdb_get_int32, libduckdb), Int32, (duckdb_value,), val) +end + +""" + duckdb_get_uint32(val) + +Returns the uint32_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a uinteger + +Returns: A uint32_t, or MinValue if the value cannot be converted +""" +function duckdb_get_uint32(val) + return ccall((:duckdb_get_uint32, libduckdb), UInt32, (duckdb_value,), val) +end + +""" + duckdb_get_int64(val) + +Returns the int64_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a bigint + +Returns: A int64_t, or MinValue if the value cannot be converted +""" +function duckdb_get_int64(val) + return ccall((:duckdb_get_int64, libduckdb), Int64, (duckdb_value,), val) +end + +""" + duckdb_get_uint64(val) + +Returns the uint64_t value of the given value. + +# Arguments +- `val`: A duckdb_value containing a ubigint + +Returns: A uint64_t, or MinValue if the value cannot be converted +""" +function duckdb_get_uint64(val) + return ccall((:duckdb_get_uint64, libduckdb), UInt64, (duckdb_value,), val) +end + +""" + duckdb_get_hugeint(val) + +Returns the hugeint value of the given value. + +# Arguments +- `val`: A duckdb_value containing a hugeint + +Returns: A duckdb_hugeint, or MinValue if the value cannot be converted +""" +function duckdb_get_hugeint(val) + return ccall((:duckdb_get_hugeint, libduckdb), duckdb_hugeint, (duckdb_value,), val) +end + +""" + duckdb_get_uhugeint(val) + +Returns the uhugeint value of the given value. + +# Arguments +- `val`: A duckdb_value containing a uhugeint + +Returns: A duckdb_uhugeint, or MinValue if the value cannot be converted +""" +function duckdb_get_uhugeint(val) + return ccall((:duckdb_get_uhugeint, libduckdb), duckdb_uhugeint, (duckdb_value,), val) +end + +""" + duckdb_get_varint(val) + +Returns the duckdb_varint value of the given value. +The `data` field must be destroyed with `duckdb_free`. + +# Arguments +- `val`: A duckdb_value containing a VARINT + +Returns: A duckdb_varint. The `data` field must be destroyed with `duckdb_free`. +""" +function duckdb_get_varint(val) + return ccall((:duckdb_get_varint, libduckdb), duckdb_varint, (duckdb_value,), val) +end + +""" + duckdb_get_decimal(val) + +Returns the duckdb_decimal value of the given value. + +# Arguments +- `val`: A duckdb_value containing a DECIMAL + +Returns: A duckdb_decimal, or MinValue if the value cannot be converted +""" +function duckdb_get_decimal(val) + return ccall((:duckdb_get_decimal, libduckdb), duckdb_decimal, (duckdb_value,), val) +end + +""" + duckdb_get_float(val) + +Returns the float value of the given value. + +# Arguments +- `val`: A duckdb_value containing a float + +Returns: A float, or NAN if the value cannot be converted +""" +function duckdb_get_float(val) + return ccall((:duckdb_get_float, libduckdb), Float32, (duckdb_value,), val) +end + +""" + duckdb_get_double(val) + +Returns the double value of the given value. + +# Arguments +- `val`: A duckdb_value containing a double + +Returns: A double, or NAN if the value cannot be converted +""" +function duckdb_get_double(val) + return ccall((:duckdb_get_double, libduckdb), Float64, (duckdb_value,), val) +end + +""" + duckdb_get_date(val) + +Returns the date value of the given value. + +# Arguments +- `val`: A duckdb_value containing a date + +Returns: A duckdb_date, or MinValue if the value cannot be converted +""" +function duckdb_get_date(val) + return ccall((:duckdb_get_date, libduckdb), duckdb_date, (duckdb_value,), val) +end + +""" + duckdb_get_time(val) + +Returns the time value of the given value. + +# Arguments +- `val`: A duckdb_value containing a time + +Returns: A duckdb_time, or MinValue